diff --git a/.github/workflows/docs-checks.yaml b/.github/workflows/docs-checks.yaml index 91ab10fc..8a28ff40 100644 --- a/.github/workflows/docs-checks.yaml +++ b/.github/workflows/docs-checks.yaml @@ -5,12 +5,18 @@ on: paths: - "docs/**" - "examples/**" + - "internal/api/**" + - "internal/domain/**" + - "internal/provider/**" - ".github/workflows/docs-checks.yaml" push: branches: [main] paths: - "docs/**" - "examples/**" + - "internal/api/**" + - "internal/domain/**" + - "internal/provider/**" - ".github/workflows/docs-checks.yaml" permissions: @@ -28,6 +34,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - uses: actions/setup-node@v4 with: node-version: 20 @@ -41,6 +49,8 @@ jobs: run: npm run build --prefix docs - name: Verify repository-owned documentation links run: npm run check:links --prefix docs + - name: Check documentation shell examples + run: npm run check:shell --prefix docs - name: Upload GitHub Pages artifact if: github.ref == 'refs/heads/main' uses: actions/upload-pages-artifact@v3 diff --git a/.github/workflows/gh-akf-new-release.yaml b/.github/workflows/gh-akf-new-release.yaml index 0e6cf54c..75401350 100644 --- a/.github/workflows/gh-akf-new-release.yaml +++ b/.github/workflows/gh-akf-new-release.yaml @@ -243,7 +243,7 @@ jobs: AkôFlow Desktop requires Docker Desktop on macOS and Windows, or Docker Engine with the Compose v2 plugin on Linux. Download the matching asset below: - **macOS:** open the universal `.dmg`, drag AkôFlow Desktop to Applications, and launch it. - - **Windows:** run the x64 installer `.exe`, or use the portable `.exe` without installation. + - **Windows:** run the x64 portable `.exe` asset without an installation wizard. - **Linux:** run the x64 `.AppImage` after `chmod +x`, or install the `.deb` with `sudo apt install ./Akoflow-Desktop-*.deb`. The matching source is the Git tag `${{ github.ref_name }}`. The runtime Docker archives in this release are loaded locally by Desktop; AkôFlow does not publish daemon or BuildKit packages to a container registry. diff --git a/docs/docs/concepts.md b/docs/docs/concepts.md index 824be749..0ca435d4 100644 --- a/docs/docs/concepts.md +++ b/docs/docs/concepts.md @@ -1,50 +1,30 @@ --- id: concepts -title: System architecture -sidebar_label: System architecture -description: How AkôFlow keeps infrastructure, workflow intent, planning decisions, and execution evidence separate. +title: Core concepts +sidebar_label: Core concepts +description: Understand workflows, environments, plans, runs, artifacts, and provenance in AkôFlow. --- import useBaseUrl from '@docusaurus/useBaseUrl'; -AkôFlow is a control plane for scientific workflows. It keeps the description of the available infrastructure separate from the workflow definition, the scheduling decision, and the evidence produced by an execution. That separation lets the same immutable workflow version be compared on different infrastructure scopes without rewriting the workflow. +AkôFlow keeps the workflow you define, the resources available to it, the plan you choose, and the result you observe as separate records. That lets you try a different plan without rewriting the workflow. -This is an explanation of the records and their boundaries. For the exact YAML fields, use the [workflow specification](./internal/workflow-spec) and the [environment reference](./reference/environment-yaml). For an end-to-end task, start with [the first simulated workflow](./guides/workflows/first-run). +## From workflow to result -AkôFlow control-plane architecture: Desktop and API clients call the daemon; its workflow, planning, and execution services preserve scientific evidence in SQLite and dispatch work through SimGrid, Kubernetes, SSH/Slurm, cloud, and local adapters. +A workflow and an environment lead to candidate plans; executing a selected plan produces a run, artifacts, and provenance. -*The diagram groups responsibilities rather than deployment units. AkôFlow is one daemon with application services and adapters; the cards do not imply separately deployable microservices.* +A **workflow** is a set of activities with dependencies. For example, `prepare → analyze → summarize` means that analysis waits for preparation and the summary waits for analysis. The workflow describes the work and required data; it does not choose a machine. -## The record chain +An **environment** describes where work could run: a local host, a modeled simulation platform, a Kubernetes cluster, or an HPC system. Its **resources** are the available machines or capacity. An **execution scope** limits which environment versions and network links a planning experiment can use. -Environment definitions become published versions and scopes; immutable workflow versions join planning sessions; selected plans lead to execution runs and observed task, transfer, artifact, provenance and audit records. +A **plan** assigns activities to resources and predicts timing, transfers, and possibly cost. AkôFlow can produce several candidates, or you can supply a manual plan. Selecting one does not start a run; it records the choice you want to execute. -The arrows express references, not a single mutable object. A planning session preserves a snapshot of the workflow, scope, inventory, topology, profiles, constraints, and selected algorithms. A later discovery refresh can create new inventory for future sessions, but it does not change that earlier comparison. +A **run** records what happened after the plan was submitted. It tracks activity status and stores timing, transfers, and output evidence when those observations are available. Compare them with the plan's predictions to see where they differ. -## Infrastructure is a versioned boundary +**Executable artifacts** are the versioned programs or images used by activities. **Scientific data** includes inputs and outputs associated with the work. **Provenance** links the workflow, plan, run, activities, and data so you can trace how a result was produced. Audit separately records connection checks, resource discovery, and console actions. -An **environment** names an infrastructure boundary: a local host, Kubernetes cluster, SSH/SLURM system, modeled SimGrid platform, or cloud configuration. Its published version can contain runtimes, resources and their hierarchy, runtime bindings, storage, connection observations, and capability observations. +## Where to go next -A **resource** is capacity that may be assigned by a plan. A **runtime** says how an activity is launched and observed. A binding states which runtime may use which resource. The [runtime adapters explanation](./runtimes) describes that boundary in more detail. +Start with [the first local workflow in Desktop](/docs/guides/workflows/first-local-run). Then use [Workflow definitions](/docs/guides/workflows/definitions), [Planning](/docs/guides/workflows/planning), and [Execution](/docs/guides/workflows/executions) for the individual tasks. The [SimGrid API tutorial](/docs/guides/workflows/first-run) is a separate simulation example. -An **execution scope** chooses the published environment versions that an algorithm may consider. Its network topology supplies directed links between resources. This means a plan answers a constrained question—"place this workflow on this frozen universe"—rather than a claim about every resource the daemon may ever discover. - -## A workflow describes intent, not placement - -A workflow definition owns identity and namespace. Its immutable version has activities plus control and data dependencies. Activities carry executable and resource requirements and may carry a simulation profile. They do not name a target resource; that is a planning decision. - -Control dependencies establish ordering. Data dependencies identify the producer, consumer, logical data, and byte volume used for movement modeling. In the current portable importer, a data dependency contributes to scheduling only when its producer/consumer pair also has the matching control dependency. This protects the DAG semantics from a data declaration that has no ordering edge. - -## A plan is a prediction and a decision - -A planning session may produce several **candidates**. They are alternatives, not runnable plans in their own right. Selecting a candidate promotes its placement to a canonical **schedule plan** with assignments and predicted ready, start, finish, runtime, transfer, and cost values. Manual and imported plans use the same plan aggregate after validation. - -Planning does not start work. The [planning explanation](./explanations/planning) explains why candidates, objectives, and a selected plan are different records. - -## Execution creates observations - -An **execution run** binds one selected plan to real, simulation, or interactive mode. The supervisor persists task attempts, runtime handles, transfer routes, logs, artifact manifests, and timing. Those records are observations of a run; they do not retroactively alter the plan prediction. - -An executable artifact is immutable runnable input. An artifact manifest is an observed output from an activity. They are deliberately different: an input can be materialized before a task starts, while an output can become a scientific data object only after the activity has been observed. - -Read [execution and control-plane behavior](./engine) for orchestration, [network modeling](./explanations/network-modeling) for movement assumptions, and [evidence and provenance](./explanations/evidence-and-provenance) for the records used to compare a plan with a completed run. +For exact file fields, use the [workflow specification](/docs/internal/workflow-spec) and [environment reference](/docs/reference/environment-yaml). For implementation details, see [Architecture internals](/docs/modules). diff --git a/docs/docs/contributing/documentation-plan.md b/docs/docs/contributing/documentation-plan.md index 1285498f..a2294b66 100644 --- a/docs/docs/contributing/documentation-plan.md +++ b/docs/docs/contributing/documentation-plan.md @@ -5,12 +5,26 @@ sidebar_label: Production plan description: Source-of-truth, media, and review rules for AkôFlow documentation. --- -This plan keeps the documentation aligned with the shipping daemon and Desktop application. It is also the contract for parallel documentation work. +This page defines the editorial and verification rules for the documentation. Apply them whenever a page, example, screenshot, API route, or supported capability changes. + +## Editorial contract + +The documentation should show how AkôFlow simplifies scientific workflow execution, not display the complexity of its implementation. + +1. Explain the task and expected result first. Give each page one main job and reveal details only when the reader needs them. +2. Use workflow, environment, plan, run, artifacts, and provenance in user paths. Put supervisors, handlers, adapters, and persistence in developer architecture pages unless a task requires them. +3. Make support claims only when code and appropriate evidence support them. Label partial features and distinguish code review, local fixtures, and real-environment validation. +4. Prefer a concrete example over a list of capabilities. Remove repeated caveats and text that does not help a reader act or decide. +5. Check whether each page quickly answers what it is for, when to use it, how to use it, and what to expect. + +For each editorial pass, classify passages as **KEEP**, **SIMPLIFY**, **MOVE**, **DELETE**, or **VERIFY**. Resolve P0 (false claims and broken instructions), then P1 (confusing paths and misplaced concepts), then P2 (length and repetition), then P3 (presentation). Repeat audit → edit → build → link check → claim check → first-time-reader review until a full pass finds no P0 or P1 issues. A successful build alone is not the finish line. + +The completion gate is a new user running a first workflow without undocumented knowledge, support claims matching implementation and validation, implementation details outside the basic path, and no P0/P1 findings in the final audit. ## Documentation principles 1. Teach complete user tasks instead of listing screens in isolation. -2. Present **AkôFlow Desktop** and **API** as equivalent paths whenever both exist. +2. Present **AkôFlow Desktop** and **API** paths only where each procedure is documented and verified; state extra prerequisites instead of calling them equivalent by default. 3. Derive behavior from code, tests, and checked-in examples; never infer an endpoint or field from a label alone. 4. Use screenshots to explain spatial relationships and short videos to explain motion or multi-step transitions. 5. Keep a text equivalent for every visual procedure. @@ -20,55 +34,23 @@ This plan keeps the documentation aligned with the shipping daemon and Desktop a | Subject | Primary source | |---|---| -| Desktop navigation | `akoflow-admin/src/App.jsx` and `src/components/AppShell.jsx` | -| Desktop operations | Page, form, and provider components in `akoflow-admin/src` | -| HTTP methods and paths | `akoflow/internal/api/httpserver/httpserver.go` | +| Desktop navigation | `akoflow-desktop/src/App.jsx` and `akoflow-desktop/src/components/AppShell.jsx` in the Desktop repository | +| Desktop operations | Page, form, and provider components in `akoflow-desktop/src` | +| HTTP methods and paths | `internal/api/httpserver/httpserver.go` in this repository | | Request and response contracts | HTTP handlers, application services, and `internal/domain` | -| Runnable scenarios | `akoflow/examples` and integration tests | -| Packaged installation | Root README, `releases/`, Electron bootstrap, and release workflows | +| Runnable scenarios | `examples/` and integration tests in this repository | +| Packaged installation | Root README, `releases/`, the Desktop repository's `electron/` bootstrap, and release workflows | Generated site output and old copied Markdown files are not sources of truth. -## Production waves - -### Wave 1 — foundation - -- Establish the information architecture and sidebar. -- Add reusable screenshot, video, and Desktop/API components. -- Build a feature coverage matrix. -- Define stable demo data and redact all secrets from captures. - -### Wave 2 — task guides - -- Infrastructure and execution scopes. -- Workflow definition, planning, and execution. -- Artifacts, storage, provenance, and audit. -- Installation, instance management, and troubleshooting. +## Review a change -Independent guide groups may be authored in parallel after their source inventory is complete. Each group owns separate files. - -### Wave 3 — reference - -- Replace the legacy workflow specification with the current versioned model. -- Document API conventions and endpoint groups. -- Document runtime capabilities, lifecycle states, and compatibility rules. - -### Wave 4 — media - -- Load a deterministic demonstration instance. -- Capture a fixed desktop viewport in the light theme. -- Add numbered callouts and restrained directional arrows. -- Record one operation per video. -- Prefer WebM for the site; create an optimized GIF only when a fallback is useful. - -### Wave 5 — verification - -- Verify every field against the Go contract. -- Verify every route against the HTTP mux. -- Run or validate checked-in examples. -- Build and type-check Docusaurus. -- Review screenshots for secrets, hostnames, tokens, usernames, and unstable identifiers. -- Search for removed terminology and stale fixed-port instructions. +1. Check page purpose, audience, order of concepts, and whether the example solves a concrete task. +2. Compare affected claims and payloads with current handlers, Desktop behavior, tests, and checked-in examples. +3. Distinguish local fixtures from real-provider validation, and update support limits when evidence changes. +4. Check screenshots for secrets, hostnames, tokens, usernames, and unstable identifiers. +5. Run the documentation type-check, build, and link check; then read the rendered path at desktop and mobile widths. +6. Record unresolved P0/P1 findings and repeat the pass after corrections. ## Link verification @@ -77,15 +59,17 @@ Run the repository-owned link check after a documentation build: ```bash npm run build --prefix docs npm run check:links --prefix docs +npm run check:shell --prefix docs ``` -The check rejects a missing internal documentation route, a missing file below -`docs/static/`, and a Showcase download that no longer has its checked-in -counterpart under `examples/`. It intentionally does not make network requests -or judge third-party URLs: availability of external services belongs to the -reader's environment, while these three classes are artifacts maintained in -this repository. GitHub Actions runs the same type-check, build, and link check -for documentation or example changes. +The link check rejects missing documentation routes, files under `docs/static/`, +and Showcase downloads without a checked-in counterpart under `examples/`. +It checks repository-owned links, not third-party availability. + +The shell check parses fenced Bash/sh examples and Showcase JSX command blocks +without running them. It requires `curl` examples to fail on HTTP errors, but +cannot validate named files or API behavior. GitHub Actions runs the type-check, +build, link check, and shell check for documentation or example changes. ## Media naming @@ -115,7 +99,7 @@ Use the black, white, and neutral-gray visual system established by [`akoflow-co ## Definition of done for a guide -- The task has prerequisites, Desktop steps, API steps, expected result, and next steps. +- The task has prerequisites, a verified procedure for its stated interface, an expected result, and next steps. Add a second interface only when its path has been checked. - Screenshot placeholders or final captures cover only moments where the visual adds information. - API examples include authentication and use the current `/akoflow-api` prefix. - Identifiers in examples are visibly placeholders or come from a documented demo dataset. @@ -126,7 +110,9 @@ Use the black, white, and neutral-gray visual system established by [`akoflow-co Run `npm run generate:api` to rebuild the endpoint catalog from `internal/api/httpserver/httpserver.go`. The Docusaurus `prestart` and `prebuild` hooks run this automatically. Generated pages are intentionally ignored by Git; changes to method, path, or handler appear on the next documentation build without copying the router by hand. -Each generated endpoint page includes its HTTP method, registered path, path parameters, authentication example, request-body indication, owning handler, and a copyable cURL command. Domain guides remain responsible for semantic explanations and complete payload examples. +Each generated endpoint page shows the registered method and path, parameters, owning handler, and request-body indication. HTTP routes include a cURL command or template; the console stream shows a WebSocket connection instead. A template still needs valid IDs and, for a body, a prepared request file. + +The generator shows a request body only when it has a checked example. Otherwise, use the handler-checked notes and linked guide to prepare one. Response JSON shapes are illustrative and may omit fields or show placeholder values. Check a route against its handler and a real response before treating a field-level example as verified. ## Reproducible media capture diff --git a/docs/docs/downloads.md b/docs/docs/downloads.md index 7f1c4c37..69d8a109 100644 --- a/docs/docs/downloads.md +++ b/docs/docs/downloads.md @@ -7,14 +7,14 @@ description: Direct official downloads for AkôFlow Desktop, with platform selec ## Choose your download -These links point to the published **v1.0.8** release, checked on **2026-09-12**. +These links point to the published **v1.0.8** release, rechecked on **2026-09-13**. Choose one package for your workstation. The browser saves it in your configured -download folder; open the completed download and follow [Installation](./installation). +download folder; open the completed download and follow [Installation](/docs/installation). | Platform | Download | What to do next | | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | | macOS, Intel and Apple silicon | [Download universal DMG](https://github.com/UFFeScience/akoflow/releases/download/v1.0.8/Akoflow-Desktop-1.0.8-mac-universal.dmg) | Open it and drag AkôFlow Desktop to Applications | -| Windows x64 | [Download Windows EXE](https://github.com/UFFeScience/akoflow/releases/download/v1.0.8/Akoflow-Desktop-1.0.8-win-x64.exe) | Open the executable and follow its prompts | +| Windows x64 | [Download Windows EXE](https://github.com/UFFeScience/akoflow/releases/download/v1.0.8/Akoflow-Desktop-1.0.8-win-x64.exe) | Run the portable executable directly | | Debian/Ubuntu x64 | [Download DEB](https://github.com/UFFeScience/akoflow/releases/download/v1.0.8/Akoflow-Desktop-1.0.8-linux-amd64.deb) | Install using `sudo apt install ./Akoflow-Desktop-1.0.8-linux-amd64.deb` | | Linux x64 | [Download AppImage](https://github.com/UFFeScience/akoflow/releases/download/v1.0.8/Akoflow-Desktop-1.0.8-linux-x86_64.AppImage) | Give it execute permission and open it | @@ -29,11 +29,13 @@ Do not rename an older installer to match a newer tag. For Desktop installation, choose the package in the table. `.blockmap` and `latest*.yml` files are updater metadata. Source-code ZIP/TAR downloads are for -development. Daemon/BuildKit `.tar` archives and the runtime `.sha256` manifests -are downloaded by Desktop automatically; operators use them in the -[self-managed server guide](./guides/operations/server-instance). +development. Daemon/BuildKit `.tar` archives and runtime `.sha256` manifests are +service assets, not separate Desktop installers. Operators use them in the +[self-managed server guide](/docs/guides/operations/server-instance). -v1.0.8 has a single Windows `.exe`, not separate named installer/portable files. +v1.0.8 has a single Windows `.exe`. The release build generated the portable +target last under the same filename as the installer target, so the published +file is the portable executable; there is no separate installer asset. It has no Linux ARM64 Desktop package. ## Download through the GitHub API @@ -82,4 +84,4 @@ redirect-following range requests. Download availability is separate from operating-system installation validation. The extracted Linux application was also opened with a fresh profile and reached -the successful [daemon, Docker and BuildKit checkup](./installation#3-first-launch-what-happens). +the successful [daemon, Docker and BuildKit checkup](/docs/installation#3-first-launch-what-happens). diff --git a/docs/docs/engine.md b/docs/docs/engine.md index 82a7ecce..68c439db 100644 --- a/docs/docs/engine.md +++ b/docs/docs/engine.md @@ -3,14 +3,14 @@ id: engine title: Execution control plane sidebar_label: Execution control plane -description: How the daemon persists work, dispatches planning and execution, and recovers runtime state. +description: How the server queues work, dispatches planning and execution, and records runtime state. --- import useBaseUrl from '@docusaurus/useBaseUrl'; -AkôFlow's server is a persistent control-plane daemon. The HTTP API validates and stores requests; a durable event loop dispatches work that may take longer than one request. The daemon is therefore responsible for recording intent and state transitions, while runtime adapters perform provider-specific work. +The AkôFlow server stores requests and dispatches longer work through a durable queue. Planning and execution handlers process those jobs; runtime adapters carry out provider-specific operations. -This is an orchestration explanation, not an API contract. Use the [planning and execution state reference](./reference/planning-and-execution-states) for states and endpoints. +This is an orchestration explanation, not an API contract. Use the [planning and execution state reference](/docs/reference/planning-and-execution-states) for states and endpoints. ## From request to durable work @@ -20,7 +20,7 @@ The API can acknowledge a request before its job starts. In particular, an execu ## Planning and execution are separate handlers -A planning handler freezes the inputs for a session, invokes registered algorithms, and persists candidates. A user or API client selects one candidate to create the schedule plan used by execution. The [planning explanation](./explanations/planning) covers the significance of that boundary. +A planning handler freezes the inputs for a session, invokes registered algorithms, and persists candidates. A user or API client selects one candidate to create the schedule plan used by execution. The [planning explanation](/docs/explanations/planning) covers the significance of that boundary. An execution handler validates the selected plan and its bindings, then hands the work to the supervisor. The supervisor follows the workflow DAG: it starts an activity only when its control predecessors have completed and its preparation gate has committed. If incomplete activities remain and nothing can run, the run fails rather than silently assuming a valid schedule. @@ -37,7 +37,7 @@ type RuntimeAdapter interface { } ``` -An `ActivityHandle` carries the provider's external identity, status, endpoints, log, exit result, failure, and artifact observation. This lets the supervisor recover by inspecting a persisted handle instead of starting an uncertain activity again. The [runtime adapters explanation](./runtimes) describes what each current driver does behind this interface. +An `ActivityHandle` carries the provider job ID and the observations needed to follow it, including status, logs, and any failure. The supervisor inspects these handles while a run is active. It does not currently reconstruct an interrupted workflow run from saved handles after a server restart. The [runtime adapters explanation](/docs/runtimes) describes each driver behind this interface. ## Preparation happens before execution @@ -47,6 +47,8 @@ For real runs, cloud lifecycle actions can be prewarmed before an activity is di ## Recovery and failure evidence -Queue jobs retain ownership, attempts, retry timing, and terminal status. Runtime handles, transfers, and materializations are persisted as evidence. When a provider supports stopping work, cancellation calls its `Stop` method. A task failure ends the run when no permitted retry remains. A completed task also records its output observation; a zero exit code is not sufficient if the configured output observation cannot be trusted. +Queue jobs retain their owner, attempts, retry timing, and final status. The server also saves runtime handles, transfers, and materializations as evidence. -The result is an inspectable distinction between what the plan predicted and what the runtime observed. See [evidence and provenance](./explanations/evidence-and-provenance) for that comparison. +A failed activity ends its workflow run; the supervisor does not retry the activity. The activity controller can stop a runtime handle internally, but the API has no workflow-run cancellation endpoint. For a completed task, the server also checks its configured output observation. Exit code zero alone is not enough when that observation fails. + +The result is an inspectable distinction between what the plan predicted and what the runtime observed. See [evidence and provenance](/docs/explanations/evidence-and-provenance) for that comparison. diff --git a/docs/docs/explanations/evidence-and-provenance.md b/docs/docs/explanations/evidence-and-provenance.md index 9f400d2d..be4b0e05 100644 --- a/docs/docs/explanations/evidence-and-provenance.md +++ b/docs/docs/explanations/evidence-and-provenance.md @@ -1,42 +1,42 @@ --- id: evidence-and-provenance -title: Plan-versus-observed evidence and provenance +title: Compare a plan with a completed run sidebar_label: Evidence and provenance description: How AkôFlow preserves predictions, runtime observations, artifacts, lineage, and audit history. --- import useBaseUrl from '@docusaurus/useBaseUrl'; -AkôFlow does not overwrite a plan with a completed run. It preserves the prediction used to choose a placement and records the execution evidence beside it. This makes disagreement inspectable: it can indicate an inaccurate model, an unexpected runtime condition, or a different data-preparation path. +AkôFlow keeps a plan's predictions alongside what happened during the run. Compare them to see whether activities took longer than expected, used different resources, or moved data differently. -Use [Provenance and audit](../guides/data/provenance-and-audit) to query the records. This explanation describes why they remain separate. +Use [Trace a result with provenance](/docs/guides/data/provenance) for the scientific records. [Inspect audit events](/docs/guides/data/audit-events) only when a connection check, resource discovery, or console action is relevant. This explanation shows how those records differ. ## Two timelines for one selected plan A selected plan holds predictions; the execution run produces runtime observations; those observations form the execution trace and provenance records. -The plan retains predicted makespan and cost. Each task attempt records its planned and allocated resource, runtime, queue, transfer, interference, and overhead timing where available. The execution trace combines task and transfer observations into observed metrics. A completed trace marks the observed result feasible; it does not certify that the prediction was accurate. +The plan retains predicted duration and cost. A task attempt can record its planned and actual resource, runtime, queue time, transfers, and startup time, depending on what the runtime reports. The execution trace combines these observations into run metrics. A completed run does not mean the prediction was accurate. -## Evidence follows the runtime boundary +## What the run records -The supervisor persists a runtime handle after starting an activity. The handle can identify a process, Kubernetes Job, Docker container, Slurm job, or simulation event without exposing provider-specific formats to the rest of the control plane. Reinspection uses that saved handle during recovery. +In real execution, a runtime handle identifies a started process, container, Kubernetes Job, or Slurm job for later status checks. A simulated run records modeled task timing without a provider job to inspect. -Data preparation and output observation are evidence too. Transfer records can capture the route and actual bytes moved. Artifact manifests capture created or changed workspace files where the adapter supports observation. An observation failure can make a zero-exit task untrustworthy when outputs are required. +Transfer records can show how data reached a task and how many bytes moved. Where the runtime supports it, artifact records show files created or changed by the task. If required output observation fails, a task's zero exit code alone does not establish a valid result. ## Lineage and audit answer different questions **Provenance** connects scientific entities, produced data, their locations, and the workflow activity that created them. It answers questions such as "which run produced this file?" or "which input lineage fed this result?" -**Audit** records operational and security-relevant actions, such as a user or service changing a record or requesting an operation. It answers "who changed this state and when?" It is not a replacement for data lineage. +**Audit** currently records connection health checks, resource discovery, and console commands or sessions. It helps answer when those actions ran and whether they succeeded. Console events can include an actor ID; connection and discovery events do not identify who initiated them. Credential changes and workflow operations are not recorded here. Their current records and operation details may show status, but a complete change history is not available through Audit. ## Compare before drawing conclusions -Compare a selected plan with a completed run at the same scope and execution mode. Check assignments, transfer records, activity attempts, and provider conditions before attributing a makespan gap to the scheduling algorithm. The execution trace reports both wall-clock makespan and accumulated activity-stage totals; [interpreting observed timing](./observed-timing) defines the distinction. +Compare a selected plan with a completed run at the same scope and execution mode. Check assignments, transfer records, activity attempts, and provider conditions before attributing a makespan gap to the scheduling algorithm. The execution trace reports both wall-clock makespan and accumulated activity-stage totals; [interpreting observed timing](/docs/explanations/observed-timing) defines the distinction. ## Related material -- [Execution control plane](../engine) -- [Planning and plans](./planning) -- [Network modeling](./network-modeling) -- [Planning and execution state reference](../reference/planning-and-execution-states) +- [Execution control plane](/docs/engine) +- [Planning and plans](/docs/explanations/planning) +- [Network modeling](/docs/explanations/network-modeling) +- [Planning and execution state reference](/docs/reference/planning-and-execution-states) diff --git a/docs/docs/explanations/network-modeling.md b/docs/docs/explanations/network-modeling.md index 90591ae6..ba2ac2c2 100644 --- a/docs/docs/explanations/network-modeling.md +++ b/docs/docs/explanations/network-modeling.md @@ -8,9 +8,9 @@ description: How data dependencies, topology links, routes, and observed transfe import useBaseUrl from '@docusaurus/useBaseUrl'; -Network modeling lets planning distinguish a local dependency from data that must cross a resource boundary. It starts with bytes declared by the workflow, but its result depends on the selected resource assignments and the directed topology included in the execution scope. +Network modeling lets planning distinguish a local dependency from data that must cross a resource boundary. It starts with bytes declared by the workflow, but its result depends on the selected resource assignments and the directed topology chosen for the planning session. -This is an explanation of the model. Use [SimGrid modeling](../guides/infrastructure/simgrid) to configure bandwidth and latency, or the [topology reference](../reference/execution-scopes-and-topologies) for the exact document fields. +This is an explanation of the model. Use [SimGrid modeling](/docs/guides/infrastructure/simgrid) to configure bandwidth and latency, or the [topology reference](/docs/reference/execution-scopes-and-topologies) for the exact document fields. ## From dependency to possible flow @@ -18,28 +18,30 @@ This is an explanation of the model. Use [SimGrid modeling](../guides/infrastruc The control dependency makes the consumer wait for the producer. The matching data dependency gives the planner a logical byte volume. If a selected plan puts both activities on the same resource, no network transfer time is added for that edge. If they are on different resources, the topology is consulted for a route. -The portable workflow importer deliberately requires the matching control edge for data bytes to participate in scheduling. A data declaration without that ordering relationship remains data metadata, not an implicit workflow edge. +The portable workflow importer uses declared bytes in scheduling only when the same pair of activities also has a control dependency. A data declaration alone does not order the activities. ## What a topology models A `NetworkLink` is directed. It identifies source and target resources and can carry bandwidth in **bits per second**, latency in seconds, byte price, whether the reverse direction is available, a sharing group, and a transfer concurrency limit. A bidirectional link makes the same link available in reverse; it does not create a second independently configured route. -PRISM precomputes routes from the frozen topology and includes communication in its candidate evaluation. Its shared-network evaluator can account for known overlapping flows on a route. HEFT's baseline scheduling path uses the direct matching link lookup. Neither behavior alone guarantees that one algorithm will produce the better observed run. +PRISM precomputes routes from the frozen topology and includes communication in its candidate evaluation. The SimGrid platform and PRISM choose a route by summing each link's latency plus the time to transmit one byte. They apply the full byte volume afterward, so the chosen route may not be fastest for a large transfer. + +PRISM can model known overlapping flows on the chosen route and rejects a cross-resource data transfer without one. HEFT's baseline uses a direct matching link; when none exists, it currently estimates zero transfer time. Supply the links needed by your placements rather than treating that estimate as evidence of a free transfer. Neither model guarantees the better observed run. ## Planned route versus executed transfer -The plan predicts transfer time for each assignment. At execution, preparation selects a concrete strategy such as a verified existing copy, shared storage, destination pull, source push, gateway, runtime-local, or direct-runtime transfer. The resulting transfer observation can record source, target, logical and network bytes, timing, cost, strategy, and route. +The plan predicts transfer time for each assignment. During execution, AkôFlow may use an existing verified copy, shared storage, or a supported transfer route. The transfer record shows how data became available and, when reported, how many bytes moved and how long it took. That distinction matters: the model describes a possible network penalty for a placement; the observation says how bytes were actually made available. Shared storage or a verified existing copy may satisfy a dependency without a new network transfer. ## Units and a small example -For a 10 GiB data dependency over a 10 Gbit/s link, the raw serialization time is roughly eight seconds before latency and sharing. `10 GiB` is a byte volume; `10 Gbit/s` is a bit rate, so the rate is divided by eight before comparing it with bytes. The observed elapsed time can be higher because of setup, route selection, sharing, or provider behavior. +For a 10 GiB data dependency over a 10 Gbit/s link, the raw serialization time is about 8.6 seconds before latency and sharing. `10 GiB` is a byte volume; `10 Gbit/s` is a bit rate. The observed time can be higher because of setup, routing, sharing, or provider behavior. -Inspect a completed run's transfer records alongside the assignment and plan prediction. The [30 GB network fan-out Showcase](../showcase/network-fanout) provides a checked-in topology and workflow where these effects are intentional. +Inspect a completed run's transfer records alongside the assignment and plan prediction. The [30 GB network fan-out Showcase](/docs/showcase/network-fanout) provides a checked-in topology and workflow where these effects are intentional. ## Related material -- [Workflow simulation semantics](../internal/workflow-spec) -- [Execution scopes and topologies reference](../reference/execution-scopes-and-topologies) -- [Plan-versus-observed evidence](./evidence-and-provenance) +- [Workflow simulation semantics](/docs/internal/workflow-spec) +- [Execution scopes and topologies reference](/docs/reference/execution-scopes-and-topologies) +- [Plan-versus-observed evidence](/docs/explanations/evidence-and-provenance) diff --git a/docs/docs/explanations/observed-timing.md b/docs/docs/explanations/observed-timing.md index 786bbff9..c4202770 100644 --- a/docs/docs/explanations/observed-timing.md +++ b/docs/docs/explanations/observed-timing.md @@ -7,43 +7,34 @@ description: The difference between flows, queue and stage totals, makespan, and import useBaseUrl from '@docusaurus/useBaseUrl'; -Execution evidence contains both a wall-clock result and accumulated activity -measurements. They answer different questions. A large accumulated transfer or -queue total does not by itself mean that the workflow took that many seconds on -the clock, because activities and transfers can overlap. +Execution evidence has a wall-clock result and accumulated activity times. Use +makespan for elapsed workflow time; use the accumulated values to see where work +and waiting occurred. Activities and transfers can overlap, so their totals can +exceed makespan. Use this page when reading a run detail, a planning-versus-execution comparison, or an experiment chart. It explains the current persisted metrics; it does not -replace [network modeling](./network-modeling) or the [execution state reference](../reference/planning-and-execution-states). +replace [network modeling](/docs/explanations/network-modeling) or the [execution state reference](/docs/reference/planning-and-execution-states). ## A flow is a scheduled movement of data -A **network flow** exists when a control dependency also has a data dependency, -the producer and consumer are assigned to different resources, and the selected -route requires movement. It has a producer, consumer, source resource, target -resource, logical byte volume, and a route. During a completed execution, -AkôFlow persists a `DataTransfer` observation with start/finish time, duration, -cost, source/target, strategy, route, logical bytes, and network bytes when the -runtime reports them. +A **network flow** can occur when a producer and consumer have both an ordering +and a data dependency and a plan assigns them to different resources. The run +can record the route, bytes moved, duration, and cost when the runtime reports +them. -The link bandwidth is in bits per second while dependency size is in bytes. For -a single 10 GiB flow over a 10 Gbit/s link, the raw payload time is roughly -eight seconds before latency. A multi-hop route adds latency for its hops and is -limited by its effective available bandwidth. +Link bandwidth is in bits per second while dependency size is in bytes. A +multi-hop route adds latency for its hops and is limited by its effective +available bandwidth. [Network modeling](/docs/explanations/network-modeling#units-and-a-small-example) +works through a concrete transfer estimate. ## Contention means simultaneous users of a bottleneck -Two flows contend when they overlap and use a shared bottleneck. In the current -PRISM complete-state evaluator, that can be a shared route hop, a shared source -resource, or a shared target resource. It divides modeled bandwidth among the -active users. The model is event-based: a flow begins after route latency, then -its remaining bytes progress at the current shared rate until another task or -flow event changes the set of active users. - -This is not a claim that every real runtime reports network contention as a -separate observed number. It is a planning-model effect used by PRISM. Inspect -the actual transfer records to determine whether a completed run moved the -expected bytes and how long that movement lasted. +Two flows contend when they overlap at a shared link or endpoint. PRISM models +that sharing when predicting transfers. A real runtime may not report a separate +contention value, so use the run's transfer records to see how many bytes moved +and how long they took. [Network modeling](/docs/explanations/network-modeling) explains the +routes behind those predictions. ## Four activity-stage timings @@ -63,13 +54,13 @@ That is different from PRISM's predicted CPU-interference slowdown. ## Accumulated stage time is not makespan -For a completed workflow run, the control plane calculates observed makespan as: +For a completed workflow run, AkôFlow calculates observed makespan as: ```text last completed task finish − first completed task start ``` -The run feed separately sums per-task runtime, queue, interference, and +The run summary separately sums per-task runtime, queue, interference, and overhead, and separately sums observed transfer durations and transferred bytes. Those sums are **accumulated stage time**. Parallel work is counted once for each activity that experienced it. @@ -84,14 +75,14 @@ the activity work and waiting occur across the whole run?" For completed execution traces, task cost is task runtime multiplied by the assigned resource's `pricePerSecond`. The trace also includes observed transfer -cost. For an allocated cloud instance, the control plane adds the idle portion +cost. For an allocated cloud instance, AkôFlow adds the idle portion of the resource active window plus persistent-disk price when the resource metadata has `diskPricePerGiBMonth`. This is an internal cost model. A provider invoice can differ because it may use different billing periods, minimum charges, taxes, discounts, network rules, or unmodeled services. Compare a plan's predicted cost with the run's observed -modelled cost only when they use the same resource price and scope. +modeled cost only when they use the same resource price and scope. ## Reading a plan-versus-observed gap @@ -108,6 +99,6 @@ modelled cost only when they use the same resource price and scope. ## Related material -- [PRISM and HEFT: search, objectives, and prediction](./prism-and-heft) -- [Plan-versus-observed evidence and provenance](./evidence-and-provenance) -- [30 GB network fan-out Showcase](../showcase/network-fanout) +- [PRISM and HEFT: search, objectives, and prediction](/docs/explanations/prism-and-heft) +- [Plan-versus-observed evidence and provenance](/docs/explanations/evidence-and-provenance) +- [30 GB network fan-out Showcase](/docs/showcase/network-fanout) diff --git a/docs/docs/explanations/planning.md b/docs/docs/explanations/planning.md index 7d32f76a..f9e4dc91 100644 --- a/docs/docs/explanations/planning.md +++ b/docs/docs/explanations/planning.md @@ -2,40 +2,42 @@ title: Planning, candidates, and selected plans sidebar_label: Planning and plans -description: Why planning sessions produce candidates before one placement becomes executable. +description: Why planning sessions produce candidates before one placement becomes a saved plan. --- import useBaseUrl from '@docusaurus/useBaseUrl'; -Planning answers a bounded placement question: given one workflow version and one execution scope, which feasible assignment should be used for the chosen objective? It is not execution, and it does not reserve or start infrastructure. +A plan records where a workflow's activities should run within an execution scope. You can make one manually or use a planning session to compare predicted placements and costs. Selecting a plan does not start a run or reserve infrastructure. -Use [Plan a workflow](../guides/workflows/planning) for the Desktop or API procedure; this explanation covers the model behind it. +Use [Plan a workflow](/docs/guides/workflows/planning) for the Desktop or API procedure; this explanation covers the model behind it. ## A planning session freezes the question -The session stores the workflow version, execution scope, network topology, environment snapshots, resources, activity profiles, deadline, budget, interference data, and algorithm selection. Freezing these inputs makes a later comparison meaningful: each algorithm evaluates the same recorded infrastructure universe instead of whatever discovery happens to return later. +A planning session records the workflow version, available resources, network topology, deadline, budget, and selected algorithms. It also keeps the profiles and environment data used for prediction. This lets you compare candidates against the same inputs, even if the environment changes later. Frozen workflow and infrastructure input create a planning session. Independent algorithm runs produce candidate sets, from which one candidate becomes a schedule plan. ## Candidates are alternatives, not executions -A candidate has a predicted makespan and cost, feasibility flags, rank and Pareto metadata, and an embedded prospective plan. Several candidates can have the same algorithm and objective. They exist so the user can inspect trade-offs before committing to one placement. +A candidate contains a possible placement with predicted makespan, cost, and feasibility. After the session completes, it receives rank and Pareto metadata for comparison. Several candidates can come from the same algorithm and objective. -Only selection promotes a candidate to the canonical schedule plan. The plan contains assignments to a resource/core/slot and prediction fields such as ready, start, finish, runtime, transfer, and cost. It may also contain cloud lifecycle actions. A manually authored placement and an imported placement use the same schedule-plan representation after validation. +Selecting a candidate saves it as a schedule plan; it does not start a run. The plan records where activities should run and their predicted timing and cost. It can also include cloud setup actions. You can instead supply or import a placement, subject to validation. + +Plan validation checks placement and workflow constraints. The runtime binding for each assignment is checked when execution starts, so a saved plan can still fail to start if its assigned resource has no compatible enabled runtime. ## Objectives and constraints answer different questions -An algorithm objective ranks candidates, while deadline and budget determine whether a candidate is feasible for the request. A candidate can remain visible when it misses a constraint; that preserves the best alternatives discovered even if no candidate meets the SLA. It is not a promise that the option will be recommended for execution. +An algorithm's objective ranks candidates. Deadline and budget determine whether each candidate meets your constraints. A candidate may remain visible even when it misses a limit, so you can inspect the alternatives the planner found. -The current built-ins include HEFT, PRISM Time, and PRISM Cost. Their search and objective behavior is intentionally separate from this record model. The selected plan's prediction is also separate from observed timing: a completed run supplies the evidence needed to assess that prediction. +The built-in schedulers are HEFT, PRISM Time, and PRISM Cost. They rank candidates in different ways; [PRISM and HEFT](/docs/explanations/prism-and-heft) explains those differences. A completed run supplies the evidence needed to assess the selected plan's prediction. ## Why a plan can differ from a completed run -Planning works from snapshots and models. An actual run adds provider queueing, startup behavior, data preparation, runtime availability, and observed transfer behavior. Those are recorded with the execution rather than silently rewritten into the plan. Read [plan-versus-observed evidence](./evidence-and-provenance) for how to interpret the comparison. +Planning works from snapshots and models. An actual run adds provider queueing, startup behavior, data preparation, runtime availability, and observed transfer behavior. Those are recorded with the execution rather than silently rewritten into the plan. Read [plan-versus-observed evidence](/docs/explanations/evidence-and-provenance) for how to interpret the comparison. ## Related material -- [Planning and execution state reference](../reference/planning-and-execution-states) -- [Execution scopes and topologies](../reference/execution-scopes-and-topologies) -- [Network modeling](./network-modeling) -- [Execute and monitor a workflow](../guides/workflows/executions) +- [Planning and execution state reference](/docs/reference/planning-and-execution-states) +- [Execution scopes and topologies](/docs/reference/execution-scopes-and-topologies) +- [Network modeling](/docs/explanations/network-modeling) +- [Execute and monitor a workflow](/docs/guides/workflows/executions) diff --git a/docs/docs/explanations/prism-and-heft.md b/docs/docs/explanations/prism-and-heft.md index 5e26b13c..f209e099 100644 --- a/docs/docs/explanations/prism-and-heft.md +++ b/docs/docs/explanations/prism-and-heft.md @@ -4,15 +4,15 @@ sidebar_label: PRISM and HEFT description: What the built-in schedulers optimize, what each prediction includes, and why neither algorithm is guaranteed to win an observed run. --- -HEFT, PRISM Time, and PRISM Cost are alternatives for generating schedule-plan candidates. They are not measurements of a completed execution. Their output is useful only in the context of the frozen workflow, resources, topology, profiles, deadline, and budget of one planning session. +HEFT, PRISM Time, and PRISM Cost propose different placements for a workflow. Each produces predictions from the same planning-session inputs; none measures a completed run. -This explanation is for readers choosing or interpreting a built-in scheduler. For the procedure, see [Plan a workflow](../guides/workflows/planning). For the meaning of observed timing, see [evidence and provenance](./evidence-and-provenance). +This explanation is for readers choosing or interpreting a built-in scheduler. For the procedure, see [Plan a workflow](/docs/guides/workflows/planning). For the meaning of observed timing, see [evidence and provenance](/docs/explanations/evidence-and-provenance). ## What is shared -All three schedulers receive the same `PlanningRequest`: a workflow version, execution scope, schedulable resources, network topology, activity-resource profiles, deadline, budget, and optional interference matrix. They reject a scope with no schedulable resources and only place an activity on a resource that satisfies its CPU and memory requirements. A resource with multiple cores offers multiple scheduling lanes, except for an opaque batch target such as an HPC partition or batch queue, which is treated as one slot. +All three use the session's workflow, scope, topology, profiles, deadline, and budget. They place activities only where CPU and memory fit. A multicore resource offers several lanes; an HPC partition or batch queue counts as one slot. -The base duration for a placement is selected from an activity-resource profile when one matches. Otherwise the planner uses the activity's `simulation.durationSeconds` when present, falling back to one second and then dividing by the resource's compute speedup. These inputs need to be credible before any comparison of algorithm quality is meaningful. +For each placement, a matching activity-resource profile supplies the base duration. Otherwise the planner uses `simulation.durationSeconds`, or one second if absent, then divides by resource speedup. Poor duration inputs make any scheduler comparison unreliable. ## The three schedulers @@ -22,45 +22,45 @@ The base duration for a placement is selected from an activity-resource profile | PRISM Time | Beam search over ready activities and feasible resource/core placements; complete states are re-evaluated | Predicted makespan, then transfer time, network cost, used resources, and cost | Routed transfers, active-flow sharing, resource active-window cost, optional CPU interference, queue and frozen overhead metadata | | PRISM Cost | The same PRISM search and complete-state re-evaluation | Predicted cost, then network cost, transfer time, used resources, makespan, and queue | The same PRISM model, ranked exclusively for cost | -"Primary" does not mean that later values are ignored. They are deterministic tie-breakers. PRISM also reserves parts of each beam for the other objective and for network-local placements. In a time search, one lane keeps alternatives by concrete earliest finish; this reduces the chance that a tie in the projected critical path discards a low-wait placement too early. It is search diversity, not a promise that every possible placement is retained. +Later values break ties. PRISM retains some alternatives for the other objective and for network-local placements, but its bounded search cannot keep every placement. ## Ranking work before placement -HEFT computes an upward rank from average activity duration and the longest successor rank. It then considers every feasible resource and every core for the next ranked activity, choosing the earliest resulting finish; equal makespans are broken by predicted cost. +HEFT ranks activities by estimated work remaining, then tests feasible resources and cores for each activity. It chooses the earliest predicted finish, using cost to break ties. -PRISM also constructs a rank, but its rank includes average communication time over routes in the frozen topology. Its ready frontier can branch to several ready activities, and each partial state can place the chosen activity on each feasible resource. The beam width and ready-branch limit bound that exploration; the registered defaults are 120 and 3. Larger values can retain more alternatives but increase planning work. The planning-session estimate reports the expected expanded states and calibrated duration before a PRISM run starts. +PRISM's rank also includes estimated communication over topology routes. It can explore several ready activities and placements at once. Beam width and ready-branch limit cap the search; their defaults are 120 and 3. Raising them considers more alternatives but takes more planning work. The session estimate reports expected expanded states and duration before PRISM starts. ## Why PRISM has a detailed second evaluation -The compact PRISM search needs to rank partial schedules quickly. After it reaches complete placement states, it removes duplicate placement signatures and re-evaluates each retained state with an event model. The evaluator starts tasks when their inputs and assigned lane are ready, applies frozen boot and container overhead, models active tasks on a resource with optional pairwise CPU-priority interference, and progresses transfer flows along the cached topology routes. +PRISM ranks partial schedules quickly. For complete placements, it removes duplicates and runs a more detailed evaluation. Tasks start when their inputs and assigned lane are ready. The model includes startup overhead, optional CPU interference, and transfers along topology routes. -For a network flow, the evaluator counts active users of each route hop as well as active flows sharing the sending or receiving resource. Bandwidth is shared among the relevant flows, and link latency is paid before payload movement. This is a prediction model, not an invocation of a real SimGrid process while the candidate is being generated. +Overlapping flows share bandwidth at route links and resource endpoints; each link also adds latency. This predicts transfer behavior without running SimGrid during candidate generation. -The resulting PRISM plan records evaluator metadata including its prediction confidence, network-path model, network-contention model, active-window cost model, and interference model. Prediction confidence reflects the fraction of activities with a simulation definition or matching activity profile; it does not establish that a future run will match the prediction. +The plan records the models used and a confidence value. That value reflects how many activities have a simulation definition or matching profile, not how closely a future run will match. ## Cost and makespan are different quantities -PRISM charges a resource by its active window in the detailed evaluation, then adds modeled transfer byte price. This can differ from HEFT's accumulated per-activity runtime price. Both are estimates derived from the frozen resource prices and assigned placement; neither is an invoice from a cloud provider. +PRISM estimates resource cost from each active window and adds transfer byte cost. HEFT sums per-activity runtime cost. Both use the session's resource prices; neither is a provider invoice. -PRISM Time ranks candidates by predicted makespan. PRISM Cost ranks by predicted cost. Neither objective asserts that the candidate is globally optimal, because beam search intentionally bounds the set of partial schedules that survive. +PRISM Time ranks by predicted makespan; PRISM Cost ranks by predicted cost. Beam search does not guarantee a global optimum. -## Do not infer a winner from the algorithm name +## Compare observed runs -PRISM has a richer current network and interference model, but more modeled inputs do not guarantee a better observed run. A real or simulated execution can differ when activity durations, topology, provider queueing, storage paths, startup overhead, or actual transfer behavior differ from the frozen inputs. HEFT can therefore have a lower observed makespan for a particular scope and workflow. Conversely, PRISM can find a better plan when its additional modeled effects distinguish placements that HEFT treats similarly. +PRISM models more network and interference effects, but a richer prediction need not lead to a faster run. Durations, queues, storage paths, startup, and transfers can differ from the session's inputs. Either scheduler may perform better for a particular workflow and scope. -The current implementation does **not** send HEFT and PRISM candidates through one shared post-search evaluator before ranking across algorithms. Compare their stored predictions as algorithm-specific estimates, then execute selected plans under the same scope and inspect their observed traces. The evidence, rather than the algorithm label, establishes which plan performed better in that experiment. +HEFT and PRISM do **not** pass through one shared evaluator before their predictions are compared. Treat their estimates as algorithm-specific. To compare outcomes, run selected plans under comparable conditions and inspect the observed traces. -## A disciplined comparison +## Compare plans in an experiment 1. Use the same workflow version, scope, topology, activity profiles, deadline, and budget for every algorithm in the session. -2. Inspect candidate assignments and predicted transfer/cost fields before selecting a plan; different placements may explain different outcomes. +2. Inspect assignments, predicted transfers, and cost before selecting a plan. 3. Run the selected alternatives under comparable runtime conditions. 4. Compare observed makespan, task timing, transfers, and cost with the plan. -5. Calibrate the workflow profiles or infrastructure model when a recurring prediction gap has a concrete cause; do not treat a single result as proof of algorithm superiority. +5. Update profiles or infrastructure values when a recurring prediction gap has a known cause. ## Related material -- [Planning, candidates, and selected plans](./planning) -- [Network modeling and data movement](./network-modeling) -- [Execution scopes and topologies reference](../reference/execution-scopes-and-topologies) -- [Planning and execution state reference](../reference/planning-and-execution-states) +- [Planning, candidates, and selected plans](/docs/explanations/planning) +- [Network modeling and data movement](/docs/explanations/network-modeling) +- [Execution scopes and topologies reference](/docs/reference/execution-scopes-and-topologies) +- [Planning and execution state reference](/docs/reference/planning-and-execution-states) diff --git a/docs/docs/getting-started.md b/docs/docs/getting-started.md index 77d5ac4c..c50834db 100644 --- a/docs/docs/getting-started.md +++ b/docs/docs/getting-started.md @@ -1,75 +1,56 @@ --- id: getting-started -title: Choose where to start +title: Getting started with AkôFlow sidebar_label: Getting started slug: /getting-started -description: Choose the shortest AkôFlow documentation path for installation, a first run, operations, concepts, or API integration. +description: Understand AkôFlow, choose a supported path, and find the next workflow task. --- -import useBaseUrl from '@docusaurus/useBaseUrl'; +# Getting started with AkôFlow -# Choose where to start +AkôFlow helps you define a scientific workflow, choose where its activities run, make a plan, and execute it. A workflow describes activities and data dependencies. A run records what happened when you executed the plan. You can compare planning choices after the first run. -AkôFlow plans and executes scientific workflow DAGs on simulated or connected infrastructure, then preserves the plan, observed execution, data movement, artifacts, audit events, and provenance. This page is a map of the documentation; it does not teach an individual workflow. +Start with a local environment to learn the interface. Connecting HPC, Kubernetes, or cloud resources requires the access and checks in their own guides. -You do not need prior AkôFlow experience. Choose the path that matches what you want to accomplish. +## Start with Desktop -## I want to run AkôFlow for the first time +1. [Install AkôFlow Desktop](/docs/installation) and complete its local environment checkup. +2. [Run your first local workflow](/docs/guides/workflows/first-local-run) and inspect its result in Desktop. +3. [Tour the interface](/docs/guides/interface-tour) or continue with [Workflow definitions](/docs/guides/workflows/definitions), [Planning](/docs/guides/workflows/planning), and [Execution](/docs/guides/workflows/executions). -1. [Install AkôFlow](./installation) and verify that its daemon is available. -2. [Run the first simulated workflow](./guides/workflows/first-run). The tutorial uses checked-in files, requires no cluster or cloud account, and ends with concrete activity and transfer checks. -3. Use the [interface tour](./guides/interface-tour) when you want to learn where the same records appear in Desktop. +The [checked-in SimGrid example](/docs/guides/workflows/first-run) verifies three activities and two transfers through a separately managed API endpoint. Use it after the local Desktop run if you want to explore simulation. -Start with the simulation even if your eventual target is Kubernetes or HPC. It separates installation problems from credentials, network access, scheduler policy, and remote storage. +## What is supported today -## Continue after installation +The local Desktop workflow has a verified run on Linux. The [Showcase](/docs/showcase) also has verified SimGrid and Kubernetes-on-Kind examples. The SLURM example exercises a local scheduler fixture; a run on an institutional cluster remains unverified. -Follow [installation result checks](./installation#4-installation-result), then -[register HPC / SLURM](./tutorials/register-hpc) or -[connect Google Cloud](./tutorials/connect-cloud). Each tutorial includes the -actual connection form, an API path, and expected results. For automation, start -with [API connection setup](./tutorials/api-access). +Google Cloud catalog and worker provisioning are implemented, but a complete live provision-and-destroy cycle has not been verified. AWS EC2 discovery and provisioning are unavailable; S3 transfers have local code tests but no verified AWS-account run. Check [cloud provider support](/docs/guides/infrastructure/cloud-support) before choosing a provider. -## I already have AkôFlow running - -| Goal | Continue with | -| --- | --- | -| Define or import an activity DAG | [Workflow definitions](./guides/workflows/definitions) | -| Generate PRISM or HEFT candidates, or place activities manually | [Plan a workflow](./guides/workflows/planning) | -| Start a selected plan and inspect observed evidence | [Execute and monitor a workflow](./guides/workflows/executions) | -| Configure simulated or connected infrastructure | [Environments](./guides/infrastructure/environments) | -| Limit the resources and network offered to planning | [Execution scopes and network topologies](./guides/infrastructure/execution-scopes) | -| Reproduce a complete example | [Workflow Showcase](./showcase/) | -| Query lineage, evidence, or audit records | [Provenance and audit](./guides/data/provenance-and-audit) | - -## I am connecting infrastructure - -Choose the guide for the actual target. Provider and runtime support are not interchangeable. - -- [SimGrid first run](./guides/workflows/first-run): deterministic local simulation. -- [Kubernetes real execution](./showcase/kubernetes-real-execution): container execution on the checked-in Kind example. -- [HPC and SLURM](./guides/infrastructure/hpc-slurm): login nodes, partitions, shared storage, SSH proxies, and batch execution. -- [Google Cloud](./guides/infrastructure/gcp): service-account credentials, catalog discovery, pricing, and Terraform provisioning. -- [AWS](./guides/infrastructure/aws): S3 and S3-compatible data movement. AkôFlow v1.0 does not discover or provision EC2 capacity. +## Connect another environment -Review the [cloud support matrix](./guides/infrastructure/cloud-capacity#provider-support-in-v10) before designing a cloud deployment. +- [Register HPC / SLURM](/docs/tutorials/register-hpc) after receiving site-approved SSH and scheduler access. +- [Connect Google Cloud](/docs/tutorials/connect-cloud) with a service account and a project you can inspect. +- [Configure Kubernetes](/docs/guides/infrastructure/kubernetes) when you have cluster access. -## I am automating through the API +For direct API work, complete [API connection setup](/docs/tutorials/api-access) first. -Read the [API overview](./reference/api-overview) for the base URL, authentication, content types, asynchronous operations, error envelope, and generated endpoint index. Use the [workflow specification](./internal/workflow-spec) for portable YAML authoring. - -The Desktop and HTTP API operate on the same persisted records. The API is preferable for repeatable experiments and integrations; Desktop is preferable for inspecting infrastructure, candidate Gantt charts, live activity state, and plan-versus-observed evidence. - -## I need to understand the model first - -Read [Core concepts](./concepts) for the vocabulary and record relationships. Continue to [Engine](./engine) for control-plane behavior and [Runtimes](./runtimes) for execution-provider boundaries. +## I already have AkôFlow running -The central lifecycle is shown below. +| Goal | Continue with | +| --- | --- | +| Define or import an activity DAG | [Workflow definitions](/docs/guides/workflows/definitions) | +| Generate PRISM or HEFT candidates, or place activities manually | [Plan a workflow](/docs/guides/workflows/planning) | +| Start a selected plan and inspect observed evidence | [Execute and monitor a workflow](/docs/guides/workflows/executions) | +| Configure simulated or connected infrastructure | [Environments](/docs/guides/infrastructure/environments) | +| Limit the resources and network offered to planning | [Execution scopes and network topologies](/docs/guides/infrastructure/execution-scopes) | +| Reproduce a complete example | [Workflow Showcase](/docs/showcase) | +| Trace how a result was produced | [Trace a result with provenance](/docs/guides/data/provenance) | +| Investigate a connection check, resource discovery, or console action | [Inspect audit events](/docs/guides/data/audit-events) | -AkôFlow lifecycle: an infrastructure boundary and workflow version produce candidate plans; one selected plan produces an execution run and observed evidence. +## Understand the records -A plan is not an execution. It predicts an assignment within a frozen workflow and infrastructure boundary. A run records what happened when that plan was dispatched. +Read [Core concepts](/docs/concepts) for workflow, environment, plan, run, artifacts, and provenance. For implementation details, see [Architecture internals](/docs/modules). The [API overview](/docs/reference/api-overview) and [workflow specification](/docs/internal/workflow-spec) are reference material for automation. ## When something fails -Use [Troubleshooting](./guides/operations/troubleshooting) for daemon readiness, authentication, Docker and BuildKit checks, connection failures, and diagnostic collection. For remote targets, validate credentials and the environment connection before debugging the workflow itself. +Use [Troubleshooting](/docs/guides/operations/troubleshooting) for server readiness, authentication, Docker and BuildKit checks, connection failures, and diagnostic collection. For remote targets, validate credentials and the environment connection before debugging the workflow itself. diff --git a/docs/docs/guides/data/artifact-locations.md b/docs/docs/guides/data/artifact-locations.md new file mode 100644 index 00000000..5cb9f090 --- /dev/null +++ b/docs/docs/guides/data/artifact-locations.md @@ -0,0 +1,26 @@ +--- +title: Inspect artifact locations +description: Inspect recorded executable locations and preparation status on a resource. +--- + +# Inspect artifact locations + +Use this guide after registering or building an executable artifact. It shows the catalog locations recorded for its bytes and whether preparation on a run's target resource finished. + +For the API commands below, complete [API connection setup](/docs/tutorials/api-access) first. + +## Find recorded locations and preparation status + +Use **Artifacts** to see executable versions, **Artifact locations** to see their recorded URI, digest, and `available` flag, and **Materializations** to see preparation on target resources. The location list reads saved catalog records; `available: true` does not run a fresh storage or network check. + +A materialization identifies a variant and digest, target resource and destination path, plus its lifecycle status: `planned`, `reconciling`, `transferring`, `verifying`, `committed`, or `failed`. For a prepared copy, check both `status: "committed"` and that `verifiedDigest` matches `digest`. These are saved observations; listing them does not recheck the destination bytes. + +```bash +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/artifact-locations/" + +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/artifact-materializations/" +``` + +Add `--data-urlencode "runId="` and `-G` to the second request when you want one run. Execution detail also shows recorded artifact preparation and transfer activity. Use it to relate a catalog artifact to a run's saved observations. diff --git a/docs/docs/guides/data/artifacts.md b/docs/docs/guides/data/artifacts.md index e9bd7ebe..44398338 100644 --- a/docs/docs/guides/data/artifacts.md +++ b/docs/docs/guides/data/artifacts.md @@ -1,133 +1,14 @@ --- -title: Artifacts, storage, and builds -description: Browse data, register executable artifacts, and follow materialization and build runs in Desktop or through the API. +title: Choose an artifact task +description: Build an executable, inspect its locations, or register an existing file. --- -# Artifacts, storage, and builds +# Choose an artifact task -AkôFlow separates **scientific data** from **executable artifacts**. Files produced by a workflow can be promoted to the scientific record. Executable artifacts are immutable, versioned definitions whose bytes may have verified locations or be materialized on a target resource. +Executable artifacts are versioned definitions that a workflow can use. Choose the task you need: -The Desktop is the easiest way to perform these operations. Every view described below uses the same HTTP API, so the API examples are suitable for scripts and integrations. +- [Build an executable from a Docker image](/docs/guides/data/build-executable) to register an image and produce a SIF file. +- [Inspect artifact locations](/docs/guides/data/artifact-locations) to see recorded locations and preparation on a resource. +- [Browse and manage storage](/docs/guides/infrastructure/storage) to find files, transfer them, or register an existing result or executable. -## Browse storage - -In Desktop, open **Infrastructure**, select an environment, then open **Storage**. Choose a storage card and one of its declared roots. Entries are loaded lazily; opening this view does not scan an entire filesystem. - -The actions offered for an entry depend on the storage capabilities reported by discovery. The current interface can inspect an entry, download a file, archive a directory for download, calculate a checksum, copy to another storage, promote a file, delete an entry, and start or inspect an index run. A storage may be read-only or visible only from a login node. - -List the storage resources for an environment and browse a directory: - -```bash -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/akoflow-api/environments/$ENVIRONMENT_ID/storages/" - -curl -G -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - --data-urlencode "path=/shared/project" \ - --data-urlencode "limit=100" \ - "$AKOFLOW_URL/akoflow-api/storages/$STORAGE_ID/entries/" -``` - -Use the returned `nextCursor` as `cursor` to continue when the response is paginated. Paths are interpreted within a root allowed by the storage adapter; do not assume host filesystem semantics. - -Calculate a digest or queue a copy: - -```bash -curl -X POST -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"path":"/shared/project/result.csv"}' \ - "$AKOFLOW_URL/akoflow-api/storages/$STORAGE_ID/checksum/" - -curl -X POST -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"path":"/shared/project/result.csv","destinationStorageId":"storage-archive"}' \ - "$AKOFLOW_URL/akoflow-api/storages/$STORAGE_ID/copies/" -``` - -Copy and archive operations return `202 Accepted`. Download creation returns a run that can be polled at `/storage-downloads/{downloadId}/`; fetch completed content from `/storage-downloads/{downloadId}/content/`. - -## Promote existing files - -Use the entry menu in **Storage** to promote an existing file. **Promote data** associates it with workflow, run, and activity context. **Promote artifact** registers executable content in the artifact catalog. - -The minimal API calls are: - -```bash -curl -X POST -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "path":"/shared/project/result.csv", - "workflowVersionId":"workflow-version-1", - "runId":"run-1", - "activityId":"analyse" - }' \ - "$AKOFLOW_URL/akoflow-api/storages/$STORAGE_ID/promote-data/" - -curl -X POST -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "path":"/shared/bin/model.sif", - "name":"model", - "version":"1.0.0", - "scope":"project", - "scopeId":"project-1" - }' \ - "$AKOFLOW_URL/akoflow-api/storages/$STORAGE_ID/promote-artifact/" -``` - -If `id` is omitted, the server generates one. Supply meaningful provenance identifiers when promoting scientific data; an anonymous promotion is valid at the transport layer but loses useful context. - -## Build an executable from a Docker image - -Open **Artifacts** and choose **Build artifact**. Enter an artifact ID, semantic version, registry image reference, and architecture. Desktop registers an immutable catalog version, creates a Docker-image-to-SIF build specification, and immediately starts its build run. - -The equivalent two-call API flow is: - -```bash -REGISTERED=$(curl -sS -X POST \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "artifactId":"busybox", - "version":"1.36", - "image":"docker.io/library/busybox:1.36", - "architecture":"amd64" - }' \ - "$AKOFLOW_URL/akoflow-api/artifacts/docker/") - -# Read .build.id from REGISTERED, then start it: -curl -X POST -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/akoflow-api/artifact-builds/$BUILD_ID/runs/" -``` - -The Docker registry pull and SIF conversion run in the build service, not in the browser. Poll `/build-runs/{runId}/`. When complete, `/build-runs/{runId}/output/` streams the SIF file. - -For custom recipes, first upload a build context as multipart form data: - -```bash -curl -X POST -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -F "context=@context.tar.gz" \ - "$AKOFLOW_URL/akoflow-api/build-contexts/" -``` - -Then create an immutable build specification at `/artifact-builds/`. It requires `id`, `artifactVersionId`, `contextDigest`, `recipeDigest`, and `cacheKey`; target and recipe fields describe the desired output. A repeated cache key returns the existing build rather than creating a duplicate. The JSON form of `/build-contexts/` only records metadata for bytes already present in the artifact store and requires `digest`, `storageUri`, and a positive `sizeBytes`. - -## Locations and materializations - -Use **Artifacts** to see executable versions, **Artifact locations** to see verified byte locations, and **Materializations** to see preparation on target resources. - -A materialization identifies a variant and digest, target resource and destination path, plus its lifecycle status: `planned`, `reconciling`, `transferring`, `verifying`, `committed`, or `failed`. A materialization is considered committed only when `verifiedDigest` equals the requested `digest`. - -```bash -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/akoflow-api/artifact-locations/" - -curl -G -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - --data-urlencode "runId=$RUN_ID" \ - "$AKOFLOW_URL/akoflow-api/artifact-materializations/" -``` - -Execution detail also shows prepared artifacts and transfer activity. Use it to relate catalog identity to the bytes actually made available for an activity. - -:::warning Credentials and paths -Do not put registry credentials, SSH secrets, or cloud secrets in artifact payloads. Use configured credential references. Browser-local file paths are not server build contexts; upload the bytes or register artifact-store metadata. -::: +To trace a scientific result back to its workflow activity, use [Trace a result with provenance](/docs/guides/data/provenance). diff --git a/docs/docs/guides/data/audit-events.md b/docs/docs/guides/data/audit-events.md new file mode 100644 index 00000000..96d23f68 --- /dev/null +++ b/docs/docs/guides/data/audit-events.md @@ -0,0 +1,46 @@ +--- +title: Inspect audit events +description: Find recorded connection, discovery, and console events and inspect their outcomes. +--- + +# Inspect audit events + +Use **Audit** to inspect recorded connection checks, resource discovery, and console actions. Each event has a time, target, and outcome. + +Audit does not currently record credential changes, planning, artifact builds, cloud provisioning, or workflow runs. Open the operation's detail page for its status. To trace a scientific result, use [Provenance](/docs/guides/data/provenance). + +## Investigate an operation + +1. Find the connection check, resource discovery, or console action in **Audit** and note its time, target ID, and outcome. +2. Open the target record or use the API filters to narrow events around that ID. +3. For a workflow result, [follow its provenance](/docs/guides/data/provenance). Consult nearby Audit events only when a connection, discovery, or console action may explain the result. + +## Inspect the audit trail + +Open **Audit**. It starts in **All events**. The interface has category tabs for discovery/resources, connections, console sessions, workflows, and credentials. The current daemon writes events only to the first three groups; an empty workflow or credential tab does not prove that no such operation occurred. + +AkôFlow Desktop Audit view showing the All events filter, chronological audit table, event targets, succeeded and failed outcomes, and operational summaries. + +*Each row keeps the event time, its machine-readable type, the persisted target, the outcome, and an operational summary. In this capture, connection health checks show both a failed Kubernetes check and a successful cloud credential check; the colored outcome is a result to investigate, not a diagnosis by itself.* + +### Read the Audit screen + +| Area | Use it for | Important interpretation | +| --- | --- | --- | +| **All events** and category tabs | Narrow the visible list to discovery/resources, connections, console sessions, workflows, or credentials. | The Desktop fetches an audit list and applies these categories in the browser. **All events** removes that local category filter; it does not request a different server-side result set. | +| **Time** | Correlate an operation with a run, connection check, or terminal session. | The value is displayed in the local browser time zone. Use persisted IDs and API filters when an investigation needs exact cross-system correlation. | +| **Event** | Identify the operation class, such as `connection.health.checked`. | Event types are machine-readable, dot-separated names. The category tabs match their leading namespace. | +| **Target** | Locate the connection, environment, resource, session, execution, or system record affected by the event. | This is a persisted target identifier when one is available; it is not necessarily the friendly name shown elsewhere in Desktop. | +| **Outcome** | Quickly distinguish `started`, `succeeded`, and `failed` records. | A failure tells you that the recorded operation did not complete successfully. Read **Summary** and then inspect the target before changing a configuration. | +| **Summary** | Read the service-provided context or error associated with the event. | Treat it as operational evidence. It can include a runtime error returned by an external system, so do not copy it into public reports without reviewing it. | + +For API queries, complete [API connection setup](/docs/tutorials/api-access) first. This request lists recent failures without requiring an environment ID: + +```bash +curl --fail-with-body -G -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + --data-urlencode "outcome=failed" \ + --data-urlencode "limit=100" \ + "$AKOFLOW_API_URL/audit-events/" +``` + +Add `--data-urlencode "environmentId="` when investigating one environment. Other filters are `eventType`, `resourceId`, `connectionId`, `sessionId`, `executionId`, and `limit`. Outcomes include `started`, `succeeded`, and `failed`. Desktop applies its category tabs to the list it has loaded; use API filters when you need a specific server query. diff --git a/docs/docs/guides/data/build-executable.md b/docs/docs/guides/data/build-executable.md new file mode 100644 index 00000000..af71c40d --- /dev/null +++ b/docs/docs/guides/data/build-executable.md @@ -0,0 +1,61 @@ +--- +title: Build an executable from a Docker image +description: Register a Docker image and build a versioned SIF executable for later runs. +--- + +# Build an executable from a Docker image + +Use this guide when a workflow needs a versioned executable built from a Docker image. AkôFlow registers the image as an artifact, then starts a build for a SIF file. A live registry pull and SIF conversion have not yet been verified. To register a SIF file already on storage, use [Browse and manage storage](/docs/guides/infrastructure/storage#register-an-existing-file). + +For the API commands below, complete [API connection setup](/docs/tutorials/api-access) first. + +## Register and build + +Open **Artifacts** and choose **Build artifact**. Enter an artifact ID, semantic version, registry image reference, and architecture. Desktop registers an immutable catalog version, creates a Docker-image-to-SIF build specification, and immediately starts its build run. + +To do the same through the API, the server needs an artifact store and an Apptainer builder that can reach the image registry. Register the image, start the build, and keep the returned IDs: + +```bash +set -o pipefail +curl --fail-with-body -X POST \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "artifactId":"busybox", + "version":"1.36", + "image":"docker.io/library/busybox:1.36", + "architecture":"amd64" + }' \ + "$AKOFLOW_API_URL/artifacts/docker/" -o registered-artifact.json || exit 1 + +BUILD_ID=$(jq -er '.build.id' registered-artifact.json) || exit 1 +curl --fail-with-body -X POST -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/artifact-builds/$BUILD_ID/runs/" -o started-build.json || exit 1 +RUN_ID=$(jq -er '.id' started-build.json) || exit 1 + +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/build-runs/$RUN_ID/" | jq '{id,status,error,logs}' +``` + +The build starts asynchronously. Repeat the last GET until `status` is `completed` or `failed`; if it fails, read `error` and `logs` before retrying. Once completed, download the SIF: + +```bash +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/build-runs/$RUN_ID/output/" -o "$RUN_ID.sif" +``` + +## Use a custom build recipe + +First upload a build context as multipart form data: + +```bash +curl --fail-with-body -X POST -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -F "context=@context.tar.gz" \ + "$AKOFLOW_API_URL/build-contexts/" +``` + +Then create an immutable build specification at `/artifact-builds/`. It requires `id`, `artifactVersionId`, `contextDigest`, `recipeDigest`, and `cacheKey`; target and recipe fields describe the desired output. A repeated cache key returns the existing build rather than creating a duplicate. The JSON form of `/build-contexts/` only records metadata for bytes already present in the artifact store and requires `digest`, `storageUri`, and a positive `sizeBytes`. + +:::warning Credentials and paths +Do not put registry credentials, SSH secrets, or cloud secrets in artifact payloads. Use configured credential references. Browser-local file paths are not server build contexts; upload the bytes or register artifact-store metadata. +::: diff --git a/docs/docs/guides/data/provenance-and-audit.md b/docs/docs/guides/data/provenance-and-audit.md index 512e92af..3623ae3f 100644 --- a/docs/docs/guides/data/provenance-and-audit.md +++ b/docs/docs/guides/data/provenance-and-audit.md @@ -1,155 +1,15 @@ --- -title: Provenance and audit -description: Explore scientific lineage, run safe read-only SQL, and inspect the operational audit trail. +title: Choose provenance or audit +description: Find the right record for a scientific result or an operational action. --- -# Provenance and audit +# Choose provenance or audit -AkôFlow exposes two complementary records: +Choose the record that answers your question: -- **Provenance** connects workflows, plans, runs, activities, transfers, and data as scientific evidence. -- **Audit** records operational actions such as discovery, connection use, console access, credentials, and workflow operations. +| Question | Open | +| --- | --- | +| Which workflow, plan, activity, and data produced this result? | [Trace a result with provenance](/docs/guides/data/provenance) | +| What connection check, resource discovery, or console action happened? | [Inspect audit events](/docs/guides/data/audit-events) | -Use provenance to answer “how was this result produced?” Use audit to answer “what operation happened, when, to which target, and with what outcome?” - -## Explore provenance in Desktop - -Open **Provenance**. The **Explore** tab loads a server-defined entity catalog. Select an entity, search across its safe projection, apply a field filter, sort a column, and page through the result. The current page can be exported as CSV or JSON. - -AkôFlow Desktop Provenance Explore view with the trusted-record catalog, Runs projection, search field, filter control, CSV and JSON exports, and lineage actions for each row. - -*The catalog defines the projections available for exploration. In the **Runs** projection, the row action opens the record details and the lineage action follows its relationship to the selected plan; use the search and export controls only after choosing the record type that answers the question.* - -The API exposes the same server-defined catalog and query: - -```bash -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/akoflow-api/provenance/entities/" - -curl -G -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - --data-urlencode "q=completed" \ - --data-urlencode "filterField=status" \ - --data-urlencode "filterValue=completed" \ - --data-urlencode "page=1" \ - --data-urlencode "pageSize=50" \ - --data-urlencode "sortField=created_at" \ - --data-urlencode "sortOrder=desc" \ - "$AKOFLOW_URL/akoflow-api/provenance/entities/runs/" -``` - -Entity names and fields are supplied by `/provenance/entities/`; clients should not invent them. Query responses include entity metadata, `items`, `page`, `pageSize`, `total`, and `hasNext`. - -## Follow lineage - -From an Explore result, choose **Open lineage**, or open the **Lineage** tab and provide an entity and ID. Select `upstream`, `downstream`, or `both`, choose a depth, then inspect nodes and relationships. Any node can become the new root. - -AkôFlow Desktop Lineage view for the completed SimGrid 30 GB fan-out run, showing record type and ID controls, direction and depth, the grouped lineage graph, graph filters, and the selected run details. - -*The fan-out example starts at the completed run. Distance 1 contains its plan, activity executions, and transfers; distance 2 reaches the workflow version, scope, activities, and allocated resources. Select a card to inspect the fields in the detail panel rather than inferring them from its position in the graph.* - -### Read the Lineage screen - -| Area | Use it for | Important interpretation | -| --- | --- | --- | -| **Record type** and **Record ID** | Define the root record. The current root can also come from **Open lineage** in Explore. | Use the stored ID, not a display name. IDs remain stable when a user changes a label. | -| **Direction** and **Depth** | Choose whether to follow antecedents, descendants, or both, then bound the search. | A larger depth adds relationships; it does not mean a later execution time. Start at 1 or 2 and expand only when the question requires it. | -| **Lineage graph** | Inspect the nodes grouped by graph distance from the root. | The heading reports the returned node and relationship counts. Grouped columns are distance from the root, not workflow stages or chronological lanes. | -| **Find a node** and **node-type filter** | Reduce a large graph to a specific record or entity kind such as transfers or activity executions. | Filtering changes the visible graph only. It does not change the lineage query or delete evidence. | -| **Selected-record panel** | Read the status and persisted fields for the selected card, then use **Open record** for the operational page. | The panel is evidence for that one record. Compare the plan and run IDs deliberately when investigating planned versus observed behavior. | -| **Export JSON** | Preserve the exact lineage response for an investigation or a report. | The export is a snapshot of the current root, direction, and depth; record those choices with the file. | - -```bash -curl -G -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - --data-urlencode "direction=both" \ - --data-urlencode "depth=2" \ - --data-urlencode "maxNodes=300" \ - "$AKOFLOW_URL/akoflow-api/provenance/lineage/runs/$RUN_ID/" -``` - -The response contains a `root` key, `nodes`, directed `edges`, and `truncated`. Increase depth deliberately: the graph may expand quickly, and the interface caps a request at 300 nodes. - -## Query with read-only SQL - -The **SQL** tab presents the queryable schema, templates for common investigations, named JSON parameters, result paging, explain, favorites, and local query history. - -AkôFlow Desktop Provenance SQL view showing the safe schema, a read-only query that compares planned and observed run durations, query controls, and the result summary. - -*This query joins completed execution runs to their schedule plans. The result summary reports the returned row count, current page, elapsed query time, and whether more rows are available; the values are evidence from the connected local database, not fixed example values.* - -### Read the SQL screen - -| Area | Use it for | Important interpretation | -| --- | --- | --- | -| **Safe schema** | Discover the tables and columns that the service makes available to read-only queries. Click a field to insert its name into the editor. | This is the current service schema, not a generic SQLite browser. Start here instead of assuming a column exists. | -| **Query template** | Start a common investigation, then refine it in the editor. | A template is ordinary editable SQL. Review joins, filters, and ordering before relying on its output. | -| **Query editor** | Write a `SELECT` or `WITH` query, including named parameters. | The interface shows the active timeout and row limit. Statements that modify data are rejected. | -| **Run query** and **Query result** | Execute the query and inspect typed columns, rows, page controls, and elapsed milliseconds. | Row limits bound one result page. A “more rows available” message means that the result is not the complete matching set yet. | -| **Explain** | Inspect SQLite's query plan before using a costly investigation repeatedly. | An explanation describes the database's access plan; it does not replace the normal query result or prove a result is scientifically meaningful. | -| **Export CSV** and **Export JSON** | Save the current result page for analysis or a report. | Record the SQL, parameters, page, and time of export with the file so another investigator can reproduce it. | -| **Favorite** and **History** | Reuse a query in the same Desktop browser profile. | They are local conveniences, not shared provenance records. | - -Only read-only `SELECT` and `WITH` queries are accepted. The Desktop communicates the current service limits as a 10-second execution timeout and 200 rows per page. Fetch the runtime schema instead of assuming table or column names: - -```bash -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/akoflow-api/provenance/sql/schema/" - -curl -X POST -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H "Content-Type: application/json" \ - -d '{ - "sql":"SELECT id, status, created_at FROM execution_runs WHERE status = :status ORDER BY created_at DESC", - "parameters":{"status":"completed"}, - "page":1, - "pageSize":200 - }' \ - "$AKOFLOW_URL/akoflow-api/provenance/sql/" -``` - -Send the same payload to `/provenance/sql/explain/` to inspect the query plan without running the ordinary result path. SQL results contain typed `columns`, `items`, pagination information, a `truncated` flag, and elapsed milliseconds. - -:::note Local UI state -SQL favorites and recent-query history are stored in the browser profile. They are conveniences, not provenance records, and are not synchronized through the API. -::: - -## Inspect the audit trail - -Open **Audit** for a chronological record of infrastructure discovery, connections, console access, commands, credentials, and workflow activity. It starts in **All events** and groups the loaded records into discovery/resources, connections, console sessions, workflows, and credentials. - -AkôFlow Desktop Audit view showing the All events filter, chronological audit table, event targets, succeeded and failed outcomes, and operational summaries. - -*Each row keeps the event time, its machine-readable type, the persisted target, the outcome, and an operational summary. In this capture, connection health checks show both a failed Kubernetes check and a successful cloud credential check; the colored outcome is a result to investigate, not a diagnosis by itself.* - -### Read the Audit screen - -| Area | Use it for | Important interpretation | -| --- | --- | --- | -| **All events** and category tabs | Narrow the visible list to discovery/resources, connections, console sessions, workflows, or credentials. | The Desktop fetches an audit list and applies these categories in the browser. **All events** removes that local category filter; it does not request a different server-side result set. | -| **Time** | Correlate an operation with a run, connection check, or terminal session. | The value is displayed in the local browser time zone. Use persisted IDs and API filters when an investigation needs exact cross-system correlation. | -| **Event** | Identify the operation class, such as `connection.health.checked`. | Event types are machine-readable, dot-separated names. The category tabs match their leading namespace. | -| **Target** | Locate the connection, environment, resource, session, execution, or system record affected by the event. | This is a persisted target identifier when one is available; it is not necessarily the friendly name shown elsewhere in Desktop. | -| **Outcome** | Quickly distinguish `started`, `succeeded`, and `failed` records. | A failure tells you that the recorded operation did not complete successfully. Read **Summary** and then inspect the target before changing a configuration. | -| **Summary** | Read the service-provided context or error associated with the event. | Treat it as operational evidence. It can include a runtime error returned by an external system, so do not copy it into public reports without reviewing it. | - -The API supports server-side filtering: - -```bash -curl -G -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - --data-urlencode "environmentId=$ENVIRONMENT_ID" \ - --data-urlencode "outcome=failed" \ - --data-urlencode "limit=100" \ - "$AKOFLOW_URL/akoflow-api/audit-events/" -``` - -Available filter parameters are `eventType`, `environmentId`, `resourceId`, `connectionId`, `sessionId`, `executionId`, `outcome`, and `limit`. Outcomes currently include `started`, `succeeded`, and `failed`. The Desktop currently loads the audit list and applies its category tabs locally; use API filters for precise automation. - -## Investigation workflow - -For a failed or surprising result: - -1. Open the execution and identify the run, activity, plan, and produced data IDs. -2. Open **Provenance > Explore**, find the record, and open its lineage. -3. Use **SQL** when the question crosses multiple entities or compares planned and observed values. -4. Open **Audit** to correlate infrastructure, connection, credential, or console operations around the same time. -5. Export the relevant Explore page when evidence must be shared; preserve IDs so another investigator can reproduce the query. - -Provenance endpoints return `503 Service Unavailable` when the explorer is not configured, `400 Bad Request` for invalid entity, SQL, or lineage requests, and `500 Internal Server Error` if schema discovery fails. +Have a run ID? Start in Provenance. Open Audit when a connection check, discovery, or console action may explain what happened. Audit is not a complete history of workflow changes. For the relationship between these records, read [Compare a plan with a completed run](/docs/explanations/evidence-and-provenance). diff --git a/docs/docs/guides/data/provenance.md b/docs/docs/guides/data/provenance.md new file mode 100644 index 00000000..f5ccdcbe --- /dev/null +++ b/docs/docs/guides/data/provenance.md @@ -0,0 +1,119 @@ +--- +title: Trace a result with provenance +description: Find saved records, follow lineage, and query run evidence with read-only SQL. +--- + +# Trace a result with provenance + +Start with a completed run. Use **Provenance** to follow the workflow, activities, and data behind its result. + +## Investigate a result + +1. Open the execution and copy its run ID and any produced data IDs. +2. Find the run in **Provenance → Explore**, then open its lineage. +3. If lineage does not answer the question, use read-only SQL to compare records or planned and observed values. +4. When sharing an investigation, export the relevant record or query page with its IDs, SQL, parameters, and page number. + +For the API commands below, complete [API connection setup](/docs/tutorials/api-access) first. + +## Explore provenance in Desktop + +Open **Provenance**. The **Explore** tab loads a server-defined entity catalog. Select an entity, search across its safe projection, apply a field filter, sort a column, and page through the result. The current page can be exported as CSV or JSON. + +AkôFlow Desktop Provenance Explore view with the trusted-record catalog, Runs projection, search field, filter control, CSV and JSON exports, and lineage actions for each row. + +*Choose a record type first. In **Runs**, open a row for details or follow its lineage.* + +The API exposes the same server-defined catalog and query: + +```bash +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/provenance/entities/" + +curl --fail-with-body -G -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + --data-urlencode "q=completed" \ + --data-urlencode "filterField=status" \ + --data-urlencode "filterValue=completed" \ + --data-urlencode "page=1" \ + --data-urlencode "pageSize=50" \ + --data-urlencode "sortField=created_at" \ + --data-urlencode "sortOrder=desc" \ + "$AKOFLOW_API_URL/provenance/entities/runs/" +``` + +Entity names and fields are supplied by `/provenance/entities/`; clients should not invent them. Query responses include entity metadata, `items`, `page`, `pageSize`, `total`, and `hasNext`. + +## Follow lineage + +From an Explore result, choose **Open lineage**, or open the **Lineage** tab and provide an entity and ID. Select `upstream`, `downstream`, or `both`, choose a depth, then inspect nodes and relationships. Any node can become the new root. + +AkôFlow Desktop Lineage view for the completed SimGrid 30 GB fan-out run, showing record type and ID controls, direction and depth, the grouped lineage graph, graph filters, and the selected run details. + +*This completed run links to its plan, activity executions, transfers, workflow version, scope, and resources. Select a card to inspect its fields.* + +### Read the Lineage screen + +| Area | Use it for | Important interpretation | +| --- | --- | --- | +| **Record type** and **Record ID** | Define the root record. The current root can also come from **Open lineage** in Explore. | Use the stored ID, not a display name. IDs remain stable when a user changes a label. | +| **Direction** and **Depth** | Choose whether to follow antecedents, descendants, or both, then bound the search. | A larger depth adds relationships; it does not mean a later execution time. Start at 1 or 2 and expand only when the question requires it. | +| **Lineage graph** | Inspect the nodes grouped by graph distance from the root. | The heading reports the returned node and relationship counts. Grouped columns are distance from the root, not workflow stages or chronological lanes. | +| **Find a node** and **node-type filter** | Reduce a large graph to a specific record or entity kind such as transfers or activity executions. | Filtering changes the visible graph only. It does not change the lineage query or delete evidence. | +| **Selected-record panel** | Read the status and saved fields for the selected card, then use **Open record** for its page. | Compare the plan and run IDs when investigating planned versus observed behavior. | +| **Export JSON** | Preserve the exact lineage response for an investigation or a report. | The export is a snapshot of the current root, direction, and depth; record those choices with the file. | + +For the API path, copy a run ID from the **Runs** results in Explore and enter it when prompted: + +```bash +read -r -p 'Run ID: ' RUN_ID || exit 1 +[ -n "$RUN_ID" ] || exit 1 + +curl --fail-with-body -G -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + --data-urlencode "direction=both" \ + --data-urlencode "depth=2" \ + --data-urlencode "maxNodes=300" \ + "$AKOFLOW_API_URL/provenance/lineage/runs/$RUN_ID/" +``` + +The response contains a `root` key, `nodes`, directed `edges`, and `truncated`. Start with a small depth: the graph may expand quickly, and the interface caps a request at 300 nodes. + +## Query with read-only SQL + +The **SQL** tab presents the queryable schema, templates for common investigations, named JSON parameters, result paging, explain, favorites, and local query history. + +AkôFlow Desktop Provenance SQL view showing the safe schema, a read-only query that compares planned and observed run durations, query controls, and the result summary. + +*The query compares completed runs with their plans. The displayed values come from the connected local database.* + +### Read the SQL screen + +| Area | Use it for | Important interpretation | +| --- | --- | --- | +| **Safe schema** | Discover the tables and columns that the service makes available to read-only queries. Click a field to insert its name into the editor. | This is the current service schema, not a generic SQLite browser. Start here instead of assuming a column exists. | +| **Query template** | Start a common investigation, then refine it in the editor. | A template is ordinary editable SQL. Review joins, filters, and ordering before relying on its output. | +| **Query editor** | Write a `SELECT` or `WITH` query, including named parameters. | The interface shows the active timeout and row limit. Statements that modify data are rejected. | +| **Run query** and **Query result** | Execute the query and inspect typed columns, rows, page controls, and elapsed milliseconds. | Row limits bound one result page. A “more rows available” message means that the result is not the complete matching set yet. | +| **Explain** | Inspect SQLite's query plan before using a costly investigation repeatedly. | An explanation describes the database's access plan; it does not replace the normal query result or prove a result is scientifically meaningful. | +| **Export CSV** and **Export JSON** | Save the current result page for analysis or a report. | Record the SQL, parameters, page, and time of export with the file so another investigator can reproduce it. | +| **Favorite** and **History** | Reuse a query in the same Desktop browser profile. | They are local conveniences, not shared provenance records. | + +Only read-only `SELECT` and `WITH` queries are accepted. The Desktop communicates the current service limits as a 10-second execution timeout and 200 rows per page. Fetch the runtime schema instead of assuming table or column names: + +```bash +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/provenance/sql/schema/" + +curl --fail-with-body -X POST -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "sql":"SELECT id, status, created_at FROM execution_runs WHERE status = :status ORDER BY created_at DESC", + "parameters":{"status":"completed"}, + "page":1, + "pageSize":200 + }' \ + "$AKOFLOW_API_URL/provenance/sql/" +``` + +Send the same payload to `/provenance/sql/explain/` to inspect the query plan without running the ordinary result path. SQL results contain typed `columns`, `items`, pagination information, a `truncated` flag, and elapsed milliseconds. + +For recorded connection checks, resource discovery, or console actions around the same time, [inspect audit events](/docs/guides/data/audit-events). Provenance endpoints return `503 Service Unavailable` when the explorer is not configured, `400 Bad Request` for invalid entity, SQL, or lineage requests, and `500 Internal Server Error` if schema discovery fails. diff --git a/docs/docs/guides/infrastructure/aws.md b/docs/docs/guides/infrastructure/aws.md index c8ee2d1c..9cf4bd1b 100644 --- a/docs/docs/guides/infrastructure/aws.md +++ b/docs/docs/guides/infrastructure/aws.md @@ -1,42 +1,22 @@ --- -title: Configure AWS -description: Configure AWS credentials and S3 data transfer without overstating v1.0 compute support. +title: AWS and S3 support +description: What AkôFlow currently implements for S3 transfers and where AWS setup remains incomplete. --- -# Configure AWS +# AWS and S3 support -AkôFlow v1.0 accepts AWS credentials and can move artifacts through Amazon S3 or an S3-compatible service. It does **not** yet discover EC2 machine types or provision EC2 workers. Creating an AWS credential therefore enables storage operations; it does not create schedulable cloud capacity. +AkôFlow can transfer objects to and from an `s3://bucket/prefix` endpoint when its server has `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`. Temporary credentials also require `AWS_SESSION_TOKEN`. You can set an endpoint and region for an S3-compatible service. Local tests cover the transfer code, but a run against an AWS account or test bucket has not yet been verified. -## Configure an S3 credential +This is **partial AWS support**. AkôFlow does not discover or provision EC2 workers. Saving an AWS cloud credential in AkôFlow does not make it available to S3 transfers; the server needs the environment variables above. For a transfer endpoint, omit `configuration.credentialRef` or set it to `env`. Other values fail with the default server credential resolver. -Create a dedicated IAM principal or short-lived credential for the bucket used by AkôFlow. Grant access only to the required bucket and prefix. Typical operations require listing the bucket prefix and reading, writing, and deleting objects that AkôFlow owns. +## Before using S3 transfers -In Desktop, open **Settings → Credentials**, create an AWS cloud credential, and provide the access-key material expected by your deployment. Do not paste credentials into workflow, environment, or plan YAML. For temporary credentials, include the session token and replace the record before it expires. +1. Ask the operator to provide the approved bucket, prefix, region, and server-side credential setup. Limit permissions to the required objects. +2. Confirm that the server process receives the credentials. Avoid placing access keys in workflow or environment files. +3. Use an `s3://bucket/prefix` transfer endpoint and check the resulting transfer and object evidence after a small run. A successful credential save or environment registration alone does not prove that data movement works. -## Register S3 storage +The **Infrastructure → Storage** screen browses storage already registered with an environment; it does not create an S3 storage connection. Its current S3 browser sends unsigned requests, even when the storage record has `credentialReference` or the server has AWS environment variables. Use a small transfer to check the separately configured transfer connector; it does not verify Desktop browsing. -Create storage under **Infrastructure → Storage** and select the S3 adapter. Configure: +For S3-compatible services, set `endpoint`, `region`, and `secure` in the transfer configuration if needed. The default endpoint is `s3.amazonaws.com`, and `secure` defaults to TLS. See the [environment YAML reference](/docs/reference/environment-yaml#connections-and-transfer-connectors) for the fields and [Storage](/docs/guides/infrastructure/storage) for browsing registered storage. -- the bucket and optional AkôFlow prefix; -- the AWS region; -- the stored credential reference; -- `s3.amazonaws.com` for AWS, or the explicit endpoint for an S3-compatible service; -- TLS and path-style addressing according to the selected service. - -Test the storage connection before using it in an environment. A successful credential save only verifies the document shape; a storage test verifies endpoint reachability and authorization. - -## Common failures - -| Symptom | What to inspect | -| --- | --- | -| `AccessDenied` | IAM action, bucket policy, KMS permission, and prefix restriction | -| `SignatureDoesNotMatch` | Region, endpoint, system clock, and access/secret pair | -| Redirect to another region | Bucket region differs from the configured region | -| TLS or hostname failure | Custom endpoint and certificate chain | -| Upload succeeds but execution cannot read | Runtime binding uses a different storage or credential | - -## Compute capacity - -Do not create a nominal AWS execution environment expecting EC2 capacity to appear. Until the EC2 provider is implemented, connect existing AWS-hosted machines through the same SSH/direct-runtime path used for remote workers, or use Kubernetes when those machines belong to a cluster. The scheduler only sees capacity after a real resource and runtime binding are registered. - -See [HPC and SLURM clusters](./hpc-slurm) for the SSH connection pattern and [Storage](./storage) for artifact placement. The cloud support matrix is maintained in [Cloud capacity](./cloud-capacity). +To run compute on existing AWS-hosted machines, connect them through a supported SSH or Kubernetes runtime. [Cloud capacity](/docs/guides/infrastructure/cloud-capacity) lists the provider limits. An end-to-end S3 tutorial remains pending validation with a disposable bucket and cleanup procedure. diff --git a/docs/docs/guides/infrastructure/cloud-capacity.md b/docs/docs/guides/infrastructure/cloud-capacity.md index 6be6cb8e..6c625c5e 100644 --- a/docs/docs/guides/infrastructure/cloud-capacity.md +++ b/docs/docs/guides/infrastructure/cloud-capacity.md @@ -1,24 +1,20 @@ --- -title: Cloud capacity and machine configuration +title: Configure cloud capacity +description: Choose a Google Cloud worker target, save it for planning, and inspect provisioning. --- -A cloud environment separates four concerns: +Use this guide after [connecting Google Cloud](/docs/tutorials/connect-cloud). +Choose a machine from its catalog, save a capacity target for planning, and +provision an instance when a run needs it. Google Cloud is the current compute +provider; check [cloud provider support](/docs/guides/infrastructure/cloud-support) for AWS and object +storage limits. For optional Ansible setup, create a +[machine configuration](/docs/guides/infrastructure/machine-configurations) before saving the target. -1. the cached provider catalog (machines, images, disks, zones, and prices); -2. capacity targets that planners may select; -3. versioned machine configurations expressed as Ansible playbooks; -4. provisioned instances and their asynchronous lifecycle operations. +For the API commands on this page, complete [API connection setup](/docs/tutorials/api-access) and register `research-gcp` through the [Google Cloud connection tutorial](/docs/tutorials/connect-cloud) first. Run the commands in the same Bash session. -## Provider support in v1.0 - -| Capability | Google Cloud | AWS | -| --- | --- | --- | -| Store provider credentials | Yes | Yes | -| Discover compute machines, images, disks, zones, and prices | Yes | Not yet | -| Provision compute capacity with Terraform | Yes | Not yet | -| Transfer artifacts through object storage | GCS through configured storage adapters | S3 and S3-compatible endpoints | - -For a runnable Google Cloud setup, continue with [Configure Google Cloud](./gcp). For AWS, read [Configure AWS](./aws) before creating an environment: v1.0 can use AWS credentials for S3 data movement, but cannot create or discover EC2 workers. This distinction prevents a stored credential from being mistaken for a working compute provider. +This procedure has not yet passed a live provision-and-destroy cycle in a +disposable project. [Configure Google Cloud](/docs/guides/infrastructure/gcp) covers account access and +the checks to perform before a real worker run. ## Synchronize the provider catalog @@ -29,11 +25,11 @@ Open a cloud environment and select **Cloud capacity**. If no cached catalog exi ### Using the API ```bash -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -X POST "$AKOFLOW_URL/environments/gcp-lab/cloud-catalog/refresh/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -X POST "$AKOFLOW_API_URL/environments/research-gcp/cloud-catalog/refresh/" -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/environments/gcp-lab/cloud-catalog/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/environments/research-gcp/cloud-catalog/" ``` The GET endpoint returns `404` until a catalog has been synchronized. Provider credentials must already be stored and referenced by the cloud environment connection. @@ -43,67 +39,67 @@ The GET endpoint returns `404` until a catalog has been synchronized. Provider c ### Using AkôFlow Desktop 1. Choose a catalog machine, image, disk, and disk size. -2. Select a zone policy, provisioning mode, maximum instance count, and lifecycle policy. +2. Select the region, provisioning mode, maximum instance count, and lifecycle policy. 3. Optionally attach an additional machine-configuration version. -4. Save the target. It becomes a provisioned cloud resource available to planning. - -### Using the API - -```bash -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' -X POST \ - "$AKOFLOW_URL/environments/gcp-lab/cloud-capacity-targets/" \ - -d '{ - "name":"E2 standard worker", - "provider":"gcp", - "providerMachineType":"e2-standard-4", - "region":"us-central1", - "zonePolicy":"any", - "imageReference":"projects/debian-cloud/global/images/family/debian-12", - "architecture":"x86_64", - "vcpu":4, - "memoryMiB":16384, - "provisioningMode":"standard", - "maximumInstances":2, - "lifecyclePolicy":"destroy-after-run", - "configuration":{"diskType":"pd-balanced","diskSizeGiB":30,"network":"default"}, - "machineConfigurations":[{"configurationVersionId":"akoflow-scientific-worker-v4","executionOrder":0,"required":true,"enabled":true}] - }' -``` +4. Save the target. It becomes a capacity option available to planning; saving it does not create a VM. -The server supplies the target ID and environment ID when omitted, enables the target, and creates the corresponding provisioned resource. Machine/image identifiers are provider values from the synchronized catalog. +If you need a machine configuration, [create its version](/docs/guides/infrastructure/machine-configurations) before saving the target and attach that version's actual ID. Provisioning needs the referenced version. -## Create and version a machine configuration - -### Using AkôFlow Desktop - -Open **Infrastructure → Machine configurations**. Create a named configuration, edit its Ansible playbook, validate it, and save a version. Existing capacity targets refer to a specific configuration-version ID, not to mutable editor contents. +For a required zone, set `fixedZone` through the target API below. ### Using the API -Validate YAML before saving it: +Keep the `AKOFLOW_GCP_PROJECT` value from the validated [connection tutorial](/docs/tutorials/connect-cloud). Read a compatible Ubuntu image's `providerImageId` from the synchronized catalog. Confirm that `e2-standard-4` is available in the selected region, or replace the machine type and its CPU/memory values with a catalog match. Enter the approved daemon or bastion CIDR before the request is sent. ```bash -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' -X POST \ - "$AKOFLOW_URL/machine-configuration-validations/" \ - -d '{"playbookYaml":"---\n- name: Configure worker\n hosts: all\n become: true\n tasks:\n - name: Install curl\n ansible.builtin.package:\n name: curl\n state: present\n"}' +set -o pipefail +: "${AKOFLOW_GCP_PROJECT:?Complete the GCP connection tutorial first}" +read -r -p 'Ubuntu providerImageId from the catalog: ' AKOFLOW_GCP_IMAGE_ID || exit 1 +read -r -p 'Approved SSH source CIDR: ' AKOFLOW_SSH_CIDR || exit 1 +[ -n "$AKOFLOW_GCP_IMAGE_ID" ] && [ -n "$AKOFLOW_SSH_CIDR" ] || exit 1 + +jq -n --arg project "$AKOFLOW_GCP_PROJECT" \ + --arg image "$AKOFLOW_GCP_IMAGE_ID" --arg cidr "$AKOFLOW_SSH_CIDR" \ + --arg configVersion "${AKOFLOW_MACHINE_CONFIGURATION_VERSION_ID:-}" '{ + name:"E2 standard worker", + provider:"gcp", + providerMachineType:"e2-standard-4", + region:"us-central1", + imageReference:$image, + architecture:"amd64", + vcpu:4, + memoryMiB:16384, + provisioningMode:"standard", + maximumInstances:2, + lifecyclePolicy:"destroy-after-run", + configuration:{ + projectId:$project, + diskType:"pd-balanced", + diskSizeGiB:30, + network:"default", + sshSourceRanges:[$cidr] + } + } + (if $configVersion == "" then {} else { + machineConfigurations:[{ + configurationVersionId:$configVersion, + executionOrder:1, + required:true, + enabled:true + }] + } end)' | curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' --data-binary @- \ + "$AKOFLOW_API_URL/environments/research-gcp/cloud-capacity-targets/" \ + -o cloud-target.json || exit 1 + +AKOFLOW_CAPACITY_TARGET_ID=$(jq -er '.id' cloud-target.json) || exit 1 ``` -Create the configuration and then its first version: +The project ID is required by the current Terraform target; it is not copied from the environment connection. The built-in worker configuration requires `amd64`, even when Google Cloud labels a machine `X86_64`. If the CIDR is omitted, the Terraform target defaults SSH ingress to `0.0.0.0/0`. -```bash -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' -X POST "$AKOFLOW_URL/machine-configurations/" \ - -d '{"id":"analysis-worker","name":"Analysis worker","description":"Packages used by analysis jobs"}' - -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' -X POST \ - "$AKOFLOW_URL/machine-configurations/analysis-worker/versions/" \ - -d '{"version":1,"status":"published","playbookYaml":"---\n- name: Configure worker\n hosts: all\n tasks: []\n","compatibility":{"providers":["gcp"]}}' -``` +Set `fixedZone` in the target if the worker must use a particular zone. Without it, the current Terraform module chooses the first active zone returned for the region. The saved `zonePolicy` field does not currently affect that choice. -Validation checks playbook structure and returns `valid`, a content hash, and errors when present. It does not provision a machine or execute the playbook. +The server supplies the target ID and environment ID when omitted, enables the target, and creates a schedulable capacity record; no VM is created yet. The command saves the returned ID for provisioning. The machine type must also come from the synchronized catalog. ## Provision and follow an instance @@ -114,15 +110,26 @@ Open a cloud resource or the environment **Provisioning** tab and start provisio ### Using the API ```bash -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' -X POST \ - "$AKOFLOW_URL/environments/gcp-lab/cloud-provisioning/" \ - -d '{"capacityTargetId":""}' - -# Follow all operations, then inspect the selected operation and its events -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" "$AKOFLOW_URL/cloud-operations/" -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" "$AKOFLOW_URL/cloud-operations//" -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" "$AKOFLOW_URL/cloud-operations//events/" +set -o pipefail +jq -n --arg id "$AKOFLOW_CAPACITY_TARGET_ID" '{capacityTargetId:$id}' | \ + curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' --data-binary @- \ + "$AKOFLOW_API_URL/environments/research-gcp/cloud-provisioning/" \ + -o cloud-operation.json || exit 1 + +AKOFLOW_CLOUD_OPERATION_ID=$(jq -er '.id' cloud-operation.json) || exit 1 + +# Inspect the operation +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" "$AKOFLOW_API_URL/cloud-operations/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" "$AKOFLOW_API_URL/cloud-operations/$AKOFLOW_CLOUD_OPERATION_ID/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" "$AKOFLOW_API_URL/cloud-operations/$AKOFLOW_CLOUD_OPERATION_ID/events/" ``` -The provisioning request queues an operation; it does not wait for the instance to become ready. Lifecycle endpoints also exist for configure, validate, start, stop, and destroy. Before destructive lifecycle actions, inspect the instance and active operation state in Desktop or through the API. +The provisioning request queues an operation. Read its status, failure reason, +and events until it completes or fails. A `202 Accepted` response does not +confirm that the target belongs to this environment, the credential works, or +the VM is ready; those checks run later. Lifecycle endpoints also exist for +configure, validate, start, stop, and destroy. Before destructive actions, +inspect the instance and active operation state in Desktop or through the API. + +If the worker becomes ready, confirm that its environment version belongs to the [execution scope](/docs/guides/infrastructure/execution-scopes) before planning a run. Use [Configure Google Cloud](/docs/guides/infrastructure/gcp#4-provision-and-verify) to review worker validation and cleanup; a live provision-and-destroy cycle remains unverified. diff --git a/docs/docs/guides/infrastructure/cloud-support.md b/docs/docs/guides/infrastructure/cloud-support.md new file mode 100644 index 00000000..53566d2b --- /dev/null +++ b/docs/docs/guides/infrastructure/cloud-support.md @@ -0,0 +1,25 @@ +--- +title: Cloud provider support +description: Current compute and object-storage support for Google Cloud and AWS. +--- + +Use this page to check what AkôFlow can do with each provider before connecting +an account. Google Cloud has a compute path; AWS currently has a separate, +partially supported S3 transfer path. + +| Capability | Google Cloud | AWS | +| --- | --- | --- | +| Save a provider credential | Yes | The record can be saved, but S3 transfers do not use it | +| Discover compute machines, images, and disks | Yes | No | +| Choose a zone and estimate prices | A fixed zone can be set; otherwise provisioning uses the first active zone returned for the region. Estimates depend on Cloud Billing access | No | +| Provision a compute worker | Terraform path exists | No EC2 provisioning | +| Transfer artifacts through object storage | Direct `gs://` transfer is unavailable in the current server; signed HTTPS may be used when appropriate | S3-compatible transfer uses server environment credentials; live AWS validation is pending | + +The Google Cloud compute path is implemented, but a complete live +provision-and-destroy cycle in a disposable project has not been verified. +Local tests cover the S3 transfer connector; live bucket access has not been +verified. A saved AWS credential does not enable S3 transfers. + +For compute, start with [Connect Google Cloud](/docs/tutorials/connect-cloud), +then [configure cloud capacity](/docs/guides/infrastructure/cloud-capacity). For object transfers, read +[AWS and S3 support](/docs/guides/infrastructure/aws) before planning data movement. diff --git a/docs/docs/guides/infrastructure/environments.md b/docs/docs/guides/infrastructure/environments.md index 56381036..88da52ce 100644 --- a/docs/docs/guides/infrastructure/environments.md +++ b/docs/docs/guides/infrastructure/environments.md @@ -1,16 +1,17 @@ --- -title: Environments +title: Create and inspect environments +description: Register real or simulated environments and inspect their connections and resources. --- An environment describes where AkôFlow can plan or run work. A **real environment** has an execution runtime such as local, SSH, Kubernetes, SLURM, or cloud. A **simulation environment** uses the SimGrid runtime and models resources without connecting to physical infrastructure. -Environment definitions are versioned. Execution scopes and plans refer to an environment **version**, so changing an environment does not silently change existing planning inputs. +Each environment has a version ID that an execution scope uses. If a scope or plan already uses that inventory, register a revised environment with new environment and version IDs so the earlier plan keeps its inputs. ## Create an environment ### Using AkôFlow Desktop -1. Open **Infrastructure → Environments** and select **Create environment**. +1. Open **Infrastructure → Environments** and select **Connect environment** for a real target or **Create simulation** for a modeled platform. 2. Choose the environment type. Use a simulation environment when you need modeled resources only; use a real environment when AkôFlow must connect to infrastructure. 3. Enter the environment name and the fields shown for the selected runtime. 4. For a real remote environment, configure its connection and credential reference. Secrets are stored by the daemon; the environment keeps a reference rather than the secret value. @@ -24,40 +25,25 @@ Simulation creation collects a SimGrid platform model and can also define an exe ### Using the API -Set the daemon address and token once: +Complete [API connection setup](/docs/tutorials/api-access) before running these commands. -```bash -export AKOFLOW_URL='http://127.0.0.1:/akoflow-api' -export AKOFLOW_TOKEN='' -``` - -The creation body is an `EnvironmentDefinition`, not only an environment name. This minimal local example includes one version, runtime, resource, and runtime binding: +The creation body needs more than an environment name. This local example includes a version, runtime, resource, and runtime binding: ```bash curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' \ - -X POST "$AKOFLOW_URL/environments/" \ + -X POST "$AKOFLOW_API_URL/environments/" \ -d '{ "environment":{"id":"local-lab","name":"Local lab","status":"defined"}, - "version":{"id":"local-lab-v1","environmentId":"local-lab","version":1,"status":"published"}, + "version":{"id":"local-lab-v1","environmentId":"local-lab","version":1,"status":"published","networkModel":"local","interferenceModel":"none","costModel":"none","configurationHash":"local-lab-v1"}, "runtimes":[{"environmentVersionId":"local-lab-v1","id":"local-lab-local","name":"Local execution","driver":"local","mode":"execution","capabilities":{"container":true}}], - "resources":[{"id":"local-lab-machine","environmentVersionId":"local-lab-v1","executionTarget":"direct","type":"local_machine","name":"Local machine","cpuCores":4,"memoryBytes":8589934592}], - "resourceRuntimeBindings":[{"resourceId":"local-lab-machine","runtimeId":"local-lab-local"}] + "resources":[{"id":"local-lab-machine","environmentVersionId":"local-lab-v1","executionTarget":"direct","type":"local_machine","name":"Local machine","providerId":"local-lab-machine","cpuCores":4,"cpuCapacity":4,"memoryBytes":8589934592,"computeSpeedup":1,"schedulable":true}], + "resourceRuntimeBindings":[{"resourceId":"local-lab-machine","runtimeId":"local-lab-local","enabled":true}] }' ``` -Before storing a remote connection, test the same connection object independently: - -```bash -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' \ - -X POST "$AKOFLOW_URL/connection-tests/" \ - -d '{"id":"hpc-ssh","name":"HPC login","type":"ssh","endpoint":"login.example.org:22","username":"researcher","credentialRef":""}' -``` - -The response contains `healthy` and `message`. Testing does not create an environment. +For a remote connection, follow the complete [HPC registration](/docs/tutorials/register-hpc) or [Google Cloud connection](/docs/tutorials/connect-cloud) tutorial. Each shows how to obtain a credential reference, test the connection, and save the environment. ## Validate health and discover infrastructure @@ -72,18 +58,21 @@ Health and discovery are different operations: health verifies access; discovery ### Using the API +Use the ID of a connection already saved in the environment. For the HPC tutorial's template, that ID is `research-hpc-connection`. + ```bash -# Persisted connection health check -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -X POST "$AKOFLOW_URL/environment-connections/hpc-ssh/health/" +AKOFLOW_CONNECTION_ID='research-hpc-connection' +# Check the connection +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -X POST "$AKOFLOW_API_URL/environment-connections/$AKOFLOW_CONNECTION_ID/health/" # Discovery through that connection -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -X POST "$AKOFLOW_URL/environment-connections/hpc-ssh/discover/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -X POST "$AKOFLOW_API_URL/environment-connections/$AKOFLOW_CONNECTION_ID/discover/" # Recent health history -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/environment-connections/hpc-ssh/history/?limit=20" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/environment-connections/$AKOFLOW_CONNECTION_ID/history/?limit=20" ``` Discovery returns a `snapshots` array. A successful request does not imply that every possible resource type was found; inspect the returned snapshots and the environment inventory. @@ -97,8 +86,8 @@ The detail page is the hub for the environment map, version, runtimes, connectio ### Using the API ```bash -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/environments/local-lab/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/environments/local-lab/" ``` The response is the full definition, including the current version and related runtimes, resources, connections, and discovered storage when present. diff --git a/docs/docs/guides/infrastructure/execution-scopes.md b/docs/docs/guides/infrastructure/execution-scopes.md index 10a42974..87c14daf 100644 --- a/docs/docs/guides/infrastructure/execution-scopes.md +++ b/docs/docs/guides/infrastructure/execution-scopes.md @@ -1,8 +1,11 @@ --- -title: Execution scopes and network topologies +title: Define execution scopes and network links +description: Limit planning to selected environment versions and model routes between resources. --- -An execution scope is a reusable set of environment versions available to planning. A network topology describes transfer links between resources. The scope stores a `networkTopologyId`; the topology stores its `executionScopeId`. Use stable IDs and create the scope before the topology when building them through the current API. +An execution scope tells the planner which environments it may use. If dependent activities may run on different resources, model the links between them so transfer estimates have a route. For a single-machine workflow, an empty topology is enough. The current Desktop creates an empty topology with a scope; use the API procedure below to register one with links. + +For the API commands on this page, complete [API connection setup](/docs/tutorials/api-access) first. ## Create a scope @@ -23,11 +26,13 @@ A scope is not a copy of its environments and does not create connections or res ### Using the API +Create the scope first. Its optional `networkTopologyId` can name the topology created next; the topology refers back to the scope by `executionScopeId`. Planning selects the topology it will use. The IDs below illustrate the relationship: replace `hpc-v1` and `cloud-v1` with published environment-version IDs in your instance. For a complete runnable set, use the [versioned SimGrid tutorial](/docs/guides/workflows/first-run). + ```bash curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' \ - -X POST "$AKOFLOW_URL/execution-scopes/" \ + -X POST "$AKOFLOW_API_URL/execution-scopes/" \ -d '{ "id":"hybrid-research", "name":"Hybrid research", @@ -39,15 +44,17 @@ curl --fail-with-body \ List or inspect scopes with: ```bash -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" "$AKOFLOW_URL/execution-scopes/" -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" "$AKOFLOW_URL/execution-scopes/hybrid-research/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" "$AKOFLOW_API_URL/execution-scopes/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" "$AKOFLOW_API_URL/execution-scopes/hybrid-research/" ``` ## Add a network topology ### Using AkôFlow Desktop -The current Desktop scope flow can create an empty initial topology, but it does not provide a link editor. Create a topology containing links through the API. Each link identifies source and target **resource IDs**, bandwidth in bits per second, latency in seconds, transfer price per byte, and whether traffic is bidirectional. +The scope form can create an empty initial topology. The current Desktop sidebar does not expose the separate topology-creation form, so use the API to register a topology with links. This creates a new topology; it does not edit the empty one. Select the topology with links when planning. + +Each API link identifies source and target **resource IDs**, bandwidth in bits per second, latency in seconds, transfer price per byte, and whether traffic is bidirectional. Topology values affect transfer estimates. They do not test the physical network and are not produced by a connection health check. @@ -55,9 +62,9 @@ Topology values affect transfer estimates. They do not test the physical network ```bash curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' \ - -X POST "$AKOFLOW_URL/network-topologies/" \ + -X POST "$AKOFLOW_API_URL/network-topologies/" \ -d '{ "id":"hybrid-network-v1", "name":"HPC to cloud", @@ -65,7 +72,6 @@ curl --fail-with-body \ "executionScopeId":"hybrid-research", "links":[{ "id":"hpc-cloud", - "topologyId":"hybrid-network-v1", "sourceResourceId":"hpc-cluster", "targetResourceId":"cloud-capacity-small", "bandwidthBitsPerSecond":1000000000, @@ -79,8 +85,8 @@ curl --fail-with-body \ Retrieve the stored model before using it for planning: ```bash -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/network-topologies/hybrid-network-v1/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/network-topologies/hybrid-network-v1/" ``` -Use resource IDs that belong to environment versions in the scope. The API validates persistence constraints but does not measure whether the bandwidth and latency values match the real infrastructure. +Replace `hpc-cluster` and `cloud-capacity-small` with resource IDs from those environment versions. The API does not check that a link's resources belong to the scope or measure the real bandwidth and latency; verify those values before using the topology for planning. diff --git a/docs/docs/guides/infrastructure/gcp.md b/docs/docs/guides/infrastructure/gcp.md index 55dcfb5a..e2c6cc85 100644 --- a/docs/docs/guides/infrastructure/gcp.md +++ b/docs/docs/guides/infrastructure/gcp.md @@ -1,16 +1,18 @@ --- title: Configure Google Cloud -description: Connect a GCP project, discover capacity, and provision an AkôFlow worker safely. +description: Connect a GCP project and review the current worker-provisioning requirements. --- # Configure Google Cloud For a guided first registration with interface screenshots and complete API steps, -start with [the connection tutorial](../../tutorials/connect-cloud). This page provides +start with [the connection tutorial](/docs/tutorials/connect-cloud). This page provides the detailed operational requirements. AkôFlow uses a service account to read the Compute catalog and, when requested, run Terraform to create a worker. The credential is stored locally by the daemon; the documentation examples never embed the private key in an environment YAML file. +The provider calls and Terraform resources below were checked against the source. A full provision-and-destroy cycle has not yet been verified in a disposable GCP project; confirm permissions, network policy, and cleanup before relying on this procedure. + ## Before you begin You need a GCP project with billing enabled and a service account JSON key. Enable the Compute Engine API. Enable the Cloud Billing API if you want catalog price estimates; without it, machine discovery can still succeed but pricing may be incomplete. @@ -19,7 +21,7 @@ Grant only the permissions needed by your lifecycle policy. The read-only catalo Provisioning uses the Terraform target shipped with the daemon. It lists available zones in the chosen region, creates and manages one Compute Engine instance and its boot disk, and creates a tagged ingress firewall rule for SSH. It references the VPC or subnetwork selected in the capacity target; it does not create a network, attach a service account to the instance, or manage IAM bindings. Confirm the exact least-privilege role set in a disposable project before adopting it as an institutional policy. -## Implementation access inventory +## Permissions to review The following is an inventory of the current daemon behavior, not a claim that one predefined Google role is least privilege. It gives the cloud administrator a concrete review surface before they create a service-account policy. The service-account token requests the broad OAuth scope `cloud-platform`; IAM still controls the operations that token can perform. @@ -37,28 +39,21 @@ The implementation does **not** create a VPC, subnet, Cloud NAT, service-account For an institutional least-privilege policy, first run catalog refresh in a disposable project with audit logging enabled, then provision and destroy one short-lived worker. Export the provider audit entries and derive the policy from the observed permission checks. This is safer than copying a broad owner/editor role from an example, and it is the validation still required before this guide can claim a tested minimal role set. -## 1. Store the service-account credential - -In Desktop, open **Settings → Credentials**, choose **Cloud credential**, select **GCP**, and paste or import the service-account JSON. AkôFlow validates the presence of `project_id`, `client_email`, `private_key`, and `token_uri`. Give the credential a stable name such as `gcp-research-project`; environments refer to this record, not to the JSON file. +## 1. Connect the project -Keep the downloaded key outside the repository, restrict its filesystem permissions, and rotate it according to your institution's policy. A failed validation usually means the JSON is truncated, belongs to a different credential type, or lacks one of the required fields. +In Desktop, open **Infrastructure → Environments → Connect environment**, select **Cloud on demand**, and keep **Google Cloud** as the provider. Enter the project ID, region, and approved service-account JSON. Choose **Test connection** before saving. The [connection tutorial](/docs/tutorials/connect-cloud) shows the current form and its result checks. -## 2. Create the cloud environment +The server stores the credential separately and saves its reference with the environment. Keep the original key outside the repository, restrict its filesystem permissions, and rotate it according to your institution's policy. A failed validation can indicate a malformed key, a disabled API, or missing access; read the returned message before changing settings. -Open **Infrastructure → Environments → New environment** and choose a cloud execution environment. Set: +## 2. Inspect the cloud environment -- **Provider:** `gcp` -- **Project ID:** the service account's GCP project -- **Region:** for example `us-central1` -- **Credential:** the record created above - -After saving, open **Cloud capacity** and select **Refresh catalog**. AkôFlow reads machine types from your project and public images from the project itself plus `ubuntu-os-cloud`, `debian-cloud`, and `rocky-linux-cloud`. +After saving, open the environment's **Cloud capacity** tab. Check that catalog synchronization returned machines, compatible images, and disks. Refresh the catalog if it is absent or stale. AkôFlow reads machine types from your project and public images from the project itself plus `ubuntu-os-cloud`, `debian-cloud`, and `rocky-linux-cloud`. If refresh fails, check the daemon log before changing the credential. A `403` normally identifies a disabled API or missing IAM permission; an empty price field with otherwise valid machines normally points to the Cloud Billing API. ## 3. Define a capacity target -A capacity target is the reproducible template offered to the scheduler. Choose the machine type, image, disk, region/zone policy, maximum instances, provisioning mode, and lifecycle policy. For the first worker, use a standard instance and a common Debian or Ubuntu image. +A capacity target is the template offered to the scheduler. Choose the machine type, image, disk, region, optional fixed zone, maximum instances, provisioning mode, and lifecycle policy. For the first worker, use a standard instance and a common Debian or Ubuntu image. The current Terraform module uses `fixedZone` when set; otherwise it takes the first active zone returned for the region. A saved `zonePolicy` does not change that selection. Network settings deserve explicit review: @@ -83,16 +78,14 @@ Stopping an instance preserves provider resources and can continue to incur disk ## API checkpoints -Use the API when automating onboarding. Store the secret through the credentials endpoint used by your deployment, create the environment with `provider: gcp`, then refresh and inspect the catalog. Set the API base to include the daemon's `/akoflow-api` prefix: +For automation, follow [API connection setup](/docs/tutorials/api-access) and the [cloud connection tutorial](/docs/tutorials/connect-cloud) to validate and store the credential and register the environment. Then refresh and inspect the catalog: ```bash -export AKOFLOW_API_URL="http://127.0.0.1:8080/akoflow-api" - -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -X POST "$AKOFLOW_API_URL/environments/gcp-lab/cloud-catalog/refresh/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -X POST "$AKOFLOW_API_URL/environments/research-gcp/cloud-catalog/refresh/" -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_API_URL/environments/gcp-lab/cloud-catalog/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/environments/research-gcp/cloud-catalog/" ``` -Continue with [Cloud capacity and machine configuration](./cloud-capacity) for the target and provisioning payloads, and [Interactive console and commands](../operations/interactive-console) to open a shell after validation. +Continue with [Configure cloud capacity](/docs/guides/infrastructure/cloud-capacity) for the target and provisioning payloads. Use [Machine configurations](/docs/guides/infrastructure/machine-configurations) if the worker needs an Ansible playbook, and [Interactive console](/docs/guides/operations/interactive-console) to open a shell after validation. diff --git a/docs/docs/guides/infrastructure/hpc-slurm.md b/docs/docs/guides/infrastructure/hpc-slurm.md index 003a3c1c..3c6a7772 100644 --- a/docs/docs/guides/infrastructure/hpc-slurm.md +++ b/docs/docs/guides/infrastructure/hpc-slurm.md @@ -1,17 +1,15 @@ --- title: Connect an HPC and SLURM cluster -description: Configure a proxy-aware SSH connection, discover a SLURM cluster, model partitions and storage, and validate a safe batch submission. +description: Configure SSH access, discover SLURM resources, and prepare a small site-approved batch validation. --- # Connect an HPC and SLURM cluster -For a guided first registration with interface screenshots and complete API steps, -start with [the connection tutorial](../../tutorials/register-hpc). This page provides -the detailed operational requirements. +This guide is for an HPC operator or researcher with an approved SLURM account. AkôFlow connects to the **login node** over SSH and submits workflow activities with `sbatch`. For a guided first registration, start with the [connection tutorial](/docs/tutorials/register-hpc). -This how-to is for an HPC operator or researcher who has an approved account on a SLURM cluster. It connects AkôFlow to the **login node** over SSH and submits workflow activities through `sbatch`. For a safe adapter-only check before involving a cluster, use the [SLURM batch fixture](../../showcase/slurm-local-fixture). The fixture validates AkôFlow's local batch-script, sentinels, and artifact path; it is not a SLURM scheduler emulator and does not validate SSH, allocation, accounting, or site policy. +Use a SLURM environment for work governed by partitions, accounts, QoS, and node allocation. Keep ordinary batch work off the login node. To check the local batch-submission path without a cluster, use the [SLURM batch fixture](/docs/showcase/slurm-local-fixture); it does not verify SSH, allocation, accounting, or site policy. For an infrastructure simulation, use [SimGrid](/docs/guides/infrastructure/simgrid). -Use a SLURM environment for batch work governed by SLURM partitions, accounts, QoS, and node allocation. Do not model a login node as a high-capacity compute resource or send ordinary batch work directly to it. For a no-remote-infrastructure experiment, use [SimGrid](./simgrid) instead. +The YAML blocks below are excerpts for discussion. Use the linked versioned files as a starting catalog, then supply your site's connection, paths, permissions, and scheduler settings. An institutional cluster run has not been verified by this documentation. ## Prerequisites @@ -23,19 +21,19 @@ Use a SLURM environment for batch work governed by SLURM partitions, accounts, Q ## 1. Create the SSH credential and proxy-aware connection -Create or import a service key using [Credentials and SSH service keys](../operations/credentials-and-ssh), then authorize its public key on the login node and any gateway. Store the returned `credentialRef` in the connection; never paste the private key into an environment YAML. +Create or import a service key using [Manage SSH service keys](/docs/guides/operations/credentials-and-ssh), then authorize its public key on the login node and any gateway. Store the returned `credentialRef` in the connection; never paste the private key into an environment YAML. -The SLURM runtime accepts SSH, agent, or local connections. A remote HPC cluster normally uses `type: ssh`. The SSH port belongs in `configuration.port`; keep `endpoint` as the host name so the same record is usable by health checks, discovery, the scheduler adapter, artifact operations, and the interactive terminal. +For a remote cluster, use `type: ssh`. Put the SSH port in `configuration.port` and the login host name in `endpoint`; AkôFlow uses this connection for health checks, discovery, runs, artifacts, and the terminal. Set the fields below in the [HPC registration template](/docs/tutorials/register-hpc), using the credential reference returned by key registration. ```yaml connections: - - id: research-hpc-ssh + - id: research-hpc-connection environmentId: research-hpc name: Research HPC login node type: ssh endpoint: login.example.org username: researcher - credentialRef: file:storage/credentials/ssh/research-hpc + credentialRef: REPLACE_WITH_RETURNED_CREDENTIAL_REF configuration: port: 22 hostKeyAlias: research-hpc-login @@ -44,25 +42,15 @@ connections: scriptDirectory: /scratch/researcher/akoflow/scripts ``` -`proxyCommand` is passed to every SSH-based path that uses this connection. When the site documents `ProxyJump`, express it as an SSH proxy command—for example, `ssh -J bastion.example.org -W login.example.org:22`—and validate the entire route from the **daemon host**, not only from Desktop. AkôFlow records trusted host keys in the configured known-hosts file; do not disable host-key checking for a production cluster. +`proxyCommand` is passed to SSH-based paths that use this connection. If the site requires a jump host, configure and test a complete SSH proxy command from the **server host**, not only from Desktop. SSH uses `accept-new` for the connection test: an unknown host key is saved in the configured known-hosts file on first contact, while a changed key is rejected. Verify the login host's fingerprint against the value supplied by your administrator before treating that saved key as trusted. Do the same for each SSH gateway hop. -In Desktop, add the connection under **Infrastructure → Environments**, assign the managed SSH key, and run the connection health check. Through the API, update the connection after first reading the environment definition so unrelated connection fields remain intact: +In Desktop, add the connection under **Infrastructure → Environments**, assign the managed SSH key, and run the connection health check. For API registration, follow the [complete connection tutorial](/docs/tutorials/register-hpc#using-the-api), which creates and tests the JSON payload before saving the environment. To change a saved connection later, read its current fields before sending a complete `PUT /environment-connections/{connectionId}/` body so unrelated settings remain intact. -```bash -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' \ - -X PUT "$AKOFLOW_URL/environment-connections/research-hpc-ssh/" \ - --data @research-hpc-connection.json -``` - -The exact `PUT` body must contain `id`, `environmentId`, `type`, endpoint, username, credential reference, and the connection configuration above. - -## 2. Define the SLURM runtime and the infrastructure boundary +## 2. Describe the SLURM resources -The versioned [`examples/slurm/environment.yaml`](https://github.com/UFFeScience/akoflow/blob/main/examples/slurm/environment.yaml) provides the catalog portion: runtime, cluster, partition, representative compute node, storage resources, and runtime bindings. Add a real connection like the preceding one before submitting it. +The versioned [`examples/slurm/environment.yaml`](https://github.com/UFFeScience/akoflow/blob/v1.0.8/examples/slurm/environment.yaml) provides the catalog portion: runtime, cluster, partition, representative compute node, storage resources, and runtime bindings. Add a real connection like the preceding one before submitting it. The linked v1.0.8 file opts the login node into direct scheduling; set its `schedulable` field to `false` before institutional registration. The current repository example defaults to `false`. -```yaml title="examples/slurm/environment.yaml" +```yaml title="Runtime and resource excerpt from environment.yaml" runtimes: - id: slurm driver: slurm @@ -95,10 +83,10 @@ resources: providerId: login cpuCores: 1 cpuCapacity: 1 - schedulable: true + schedulable: false ``` -Bind the runtime to the partition and compute resources. The adapter resolves its partition from the selected `hpc_partition` resource's `providerId`, falling back to `configuration.partition`; a selected `hpc_machine` resource becomes an `sbatch` node target. Keep the login node's capacity deliberately small and out of heavy workflow plans. Direct execution is for lightweight approved control or interactive work, not a way to bypass SLURM policy. +Bind the runtime to the partition and compute resources. AkôFlow uses the selected partition's `providerId` for `sbatch`, or `configuration.partition` if that ID is absent. A selected batch `hpc_machine` becomes an `sbatch` node target. The login node in the example has a `direct` execution target; leave it unschedulable for workflow planning unless your site explicitly permits lightweight direct work. Interactive console access does not require scheduling workflow activities there. For a remote SSH connection, AkôFlow submits the batch script through standard input to `sbatch`; it keeps the audit copy in the configured `scriptDirectory` on the daemon host. Ensure that directory exists and is writable by the daemon. The remote login node does not need that local audit path for stdin submission. @@ -111,7 +99,7 @@ Compare discovery with the initial catalog: 1. Confirm the intended partition is available and its name has no trailing `*` in the stored `providerId`. 2. Confirm cores and memory are appropriate for the activities' requests. 3. Confirm the login host is represented separately from compute nodes. -4. Confirm the required scratch, archive, or project path is writable and visible from a compute allocation. +4. Record the required scratch, archive, or project path for the compute-allocation probe in the next step. 5. Review the discovered transfer capabilities before selecting a staging strategy. Discovery is inventory evidence, not a reservation. A partition shown as available can still queue a job because of account, QoS, dependency, priority, or resource constraints. @@ -120,7 +108,7 @@ Discovery is inventory evidence, not a reservation. A partition shown as availab The example registers a Lustre workspace and an NFS archive separately: -```yaml title="examples/slurm/environment.yaml" +```yaml title="Storage excerpt from environment.yaml" storages: - id: slurm-default-lustre name: cluster-scratch @@ -139,7 +127,7 @@ storages: shared: true ``` -These paths must be valid from the allocated compute node, not merely from the login shell. Submit a small site-approved probe that writes a file to the intended workspace and reads it back from a second allocation. Check ownership, quota, purge policy, and the path exposed inside Apptainer before relying on artifacts or inter-activity data. +These paths must be valid from the allocated compute node, not merely from the login shell. Submit a small site-approved probe that writes a file to the intended workspace and reads it back from a second allocation. Check ownership, quota, purge policy, and the path exposed inside Apptainer before relying on artifacts or inter-activity data. The catalog entries alone do not enable Desktop file browsing; that also needs a configured browser and [approved roots](/docs/guides/infrastructure/storage). ## 5. Scope, validate, and submit a small real execution @@ -156,20 +144,20 @@ In Desktop, choose **Infrastructure → Execution scopes**, select the environme The recommended validation sequence is: -1. connection health with the configured host key and proxy route; +1. connection health through the configured proxy route, followed by host-key fingerprint verification; 2. SLURM discovery and partition review; 3. a short `sbatch` probe in the intended partition; 4. a compute-node storage write/read probe; 5. a minimal Apptainer job when containers are required; 6. a one-activity AkôFlow run with persisted logs and artifact evidence. -AkôFlow parses `sbatch --parsable` output, uses `sacct` to observe status, and falls back to `squeue` and `scontrol` when accounting is unavailable. A job that disappears from `squeue` is not automatically failed: completed jobs can leave controller memory before accounting catches up. Inspect the activity's persisted log and status-query warning before retrying or cancelling it. +AkôFlow parses `sbatch --parsable` output, uses `sacct` to observe status, and falls back to `squeue` and `scontrol` when accounting is unavailable. A job that disappears from `squeue` is not automatically failed: completed jobs can leave controller memory before accounting catches up. Inspect the activity's persisted log and status-query warning before submitting a replacement or asking a site operator to stop the job. ## Queue time, cancellation, and interactive sessions For SLURM, queue time is the interval after submission before the allocation starts. It is neither transfer time nor container runtime. Inspect the reason shown by `squeue` or `scontrol`: common reasons include `Resources`, `Priority`, `Dependency`, account limits, and `QOSMax*` limits. -Cancelling an active batch activity calls `scancel `. Do not delete scheduler-owned files as a substitute for cancellation. +The SLURM adapter's internal `Stop` method calls `scancel ` for a batch job. The current API has no workflow-run cancellation endpoint. If you need to stop a job, follow your site's SLURM procedure; do not delete scheduler-owned files as a substitute. The interactive console uses the same connection and trust route. Selecting a partition starts `srun --partition= --pty /bin/bash -l`; selecting a compute machine uses `--nodelist=`. Selecting the login node opens a direct SSH shell. Close the console session when finished so AkôFlow can cancel its named interactive allocation. @@ -184,4 +172,4 @@ The interactive console uses the same connection and trust route. Selecting a pa | Status looks stale after completion | Check the sentinel/log path and wait for `sacct`; AkôFlow preserves a warning rather than converting missing accounting data into a false failure. | | Interactive allocation remains after closing the browser view | Close the AkôFlow console session explicitly; it owns the `srun` allocation and cleanup path. | -Related material: [Credentials and SSH service keys](../operations/credentials-and-ssh), [interactive console and commands](../operations/interactive-console), [execution scopes](./execution-scopes), and [storage](./storage). +After a site-approved run, use [Execute and monitor a workflow](/docs/guides/workflows/executions) to inspect its activity status and evidence. Related setup: [SSH service keys](/docs/guides/operations/credentials-and-ssh), [interactive console and commands](/docs/guides/operations/interactive-console), [execution scopes](/docs/guides/infrastructure/execution-scopes), and [storage](/docs/guides/infrastructure/storage). diff --git a/docs/docs/guides/infrastructure/kubernetes.md b/docs/docs/guides/infrastructure/kubernetes.md index 0a999264..3f0a9a27 100644 --- a/docs/docs/guides/infrastructure/kubernetes.md +++ b/docs/docs/guides/infrastructure/kubernetes.md @@ -5,9 +5,11 @@ description: Configure a Kubernetes runtime, credential, namespace, resources, s # Connect a Kubernetes environment -This how-to connects an existing Kubernetes cluster to AkôFlow for real container execution. It is for an operator who controls a namespace and its service account. The [Kind real-execution Showcase](../../showcase/kubernetes-real-execution) is the reproducible local reference implementation; use it before adapting these steps to a shared cluster. +Use this guide to connect an existing Kubernetes cluster so AkôFlow can run container activities as Jobs. You need access to a namespace and its service account. The [Kind real-execution Showcase](/docs/showcase/kubernetes-real-execution) provides a local example to try before using a shared cluster. -Use this runtime for container workloads that must become Kubernetes Jobs. Do not use it to simulate a cluster: use [SimGrid](./simgrid) for modeled infrastructure. Do not put a bearer token in a workflow, plan, repository, or screenshot. +Use this runtime when container activities must become Kubernetes Jobs. For a +modeled cluster, use [SimGrid](/docs/guides/infrastructure/simgrid). Keep bearer tokens out of workflows, +plans, repositories, and screenshots. ## Prerequisites @@ -81,22 +83,20 @@ For node discovery, a separate `ClusterRole` and `ClusterRoleBinding` granting ` ## 2. Store the API credential outside the environment definition -Generate a short-lived token and send it to the daemon's local Kubernetes-token endpoint. The example below deliberately avoids printing the token after it has been assigned to the shell variable. +Complete [API connection setup](/docs/tutorials/api-access). Generate a short-lived Kubernetes token and stream it to the credential endpoint without placing it in a command argument or a temporary file. Run this in Bash so `pipefail` catches a failed token request: ```bash -export AKOFLOW_API_URL='http://127.0.0.1:8080/akoflow-api' -export AKOFLOW_API_TOKEN='' - -KUBE_TOKEN="$(kubectl -n akoflow create token akoflow-runtime --duration=1h)" -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ - -H 'Content-Type: application/json' \ - --data "{\"id\":\"research-kubernetes\",\"token\":\"$KUBE_TOKEN\"}" \ - "$AKOFLOW_API_URL/kubernetes-tokens/" -unset KUBE_TOKEN +set -o pipefail +kubectl -n akoflow create token akoflow-runtime --duration=1h \ + | jq -R '{id:"research-kubernetes",token:.}' \ + | curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' --data-binary @- \ + "$AKOFLOW_API_URL/kubernetes-tokens/" -o kubernetes-reference.json || exit 1 +jq -e '.credentialRef' kubernetes-reference.json ``` -The Kubernetes client accepts a `credentialRef` using `file:` or `env:`, or a `bearerToken` in connection configuration. Prefer a daemon-managed local file reference such as `file:storage/credentials/kubernetes/research-kubernetes.token`; it keeps the token out of the versioned environment YAML. See [credentials and SSH service keys](../operations/credentials-and-ssh) for the daemon-side credential flow. +Use the returned `credentialRef` in the connection you register. The Kubernetes client accepts `file:` or `env:` references, or a `bearerToken` in connection configuration. The daemon-managed file reference keeps the token out of the versioned environment YAML. For a production cluster, provide the API server certificate through `configuration.caFile`. `insecureSkipTlsVerify: true` is appropriate for the disposable Kind example only; do not copy it to a trusted cluster configuration. @@ -106,7 +106,7 @@ In Desktop, open **Infrastructure → Environments**, create a real Kubernetes e The relevant part of `examples/kind/environment.yaml` is: -```yaml title="examples/kind/environment.yaml" +```yaml title="Connection and resource excerpt from environment.yaml" connections: - id: kind-akoflow-connection type: kubernetes @@ -152,7 +152,7 @@ For a manually maintained resource, set `metadata.kubernetesNode` or `providerId Use a PVC or NFS storage resource when the workflow needs a shared workspace. The Kind example defines a PVC and its runtime mount: -```yaml title="examples/kind/environment.yaml" +```yaml title="Storage excerpt from environment.yaml" storages: - id: kind-akoflow-data type: pvc @@ -177,7 +177,7 @@ Before launching a production workflow, verify image pull access from the select In Desktop, test the connection, run discovery, inspect the resource inventory, then import a small workflow. Create a scope containing the environment version, generate or create a plan, choose **Real execution**, and inspect the completed run's activity logs and artifacts. -For an equivalent API validation, follow the complete [Kind README](https://github.com/UFFeScience/akoflow/tree/main/examples/kind). It applies the cluster access and PVC, stores a short-lived token, and submits the environment, scope, topology, workflow, plan, and execution request in that order. +For an equivalent API validation, follow the complete [Kind README](https://github.com/UFFeScience/akoflow/tree/v1.0.8/examples/kind). It applies the cluster access and PVC, stores a short-lived token, and submits the environment, scope, topology, workflow, plan, and execution request in that order. The exact Kind bundle completed on 2026-09-11 as `kind-dag-run-v8`. It created two Kubernetes Jobs, transferred 9 bytes through its workspace, and produced matching `result.txt` and `consumed.txt` files with checksum `sha256:cb064c1339ffa3d7777bcb0459de3dceddb9146156dde58065a4ac826b029aa7`. @@ -201,4 +201,4 @@ kubectl -n akoflow get jobs,pods,services,pvc \ Delete only the run resources you intend to remove. For the disposable Kind environment, use the Showcase cleanup command: `kind delete cluster --name akoflow`. -Related material: [Kubernetes real execution](../../showcase/kubernetes-real-execution), [execution scopes](./execution-scopes), [storage](./storage), and [interactive console](../operations/interactive-console). +Related material: [Kubernetes real execution](/docs/showcase/kubernetes-real-execution), [execution scopes](/docs/guides/infrastructure/execution-scopes), [storage](/docs/guides/infrastructure/storage), and [interactive console](/docs/guides/operations/interactive-console). diff --git a/docs/docs/guides/infrastructure/machine-configurations.md b/docs/docs/guides/infrastructure/machine-configurations.md new file mode 100644 index 00000000..d0856a27 --- /dev/null +++ b/docs/docs/guides/infrastructure/machine-configurations.md @@ -0,0 +1,43 @@ +--- +title: Prepare a cloud worker with Ansible +description: Validate and version an Ansible playbook for a cloud capacity target. +--- + +# Prepare a cloud worker with Ansible + +Use a machine configuration when a provisioned Google Cloud worker needs packages or setup before a run. Create and validate a playbook, save a version, then attach that version to a [cloud capacity target](/docs/guides/infrastructure/cloud-capacity#create-a-capacity-target). A saved playbook does not provision a VM. + +For the API commands below, complete [API connection setup](/docs/tutorials/api-access) first. + +## Using AkôFlow Desktop + +Open **Infrastructure → Machine configurations**. Create a named configuration, edit its Ansible playbook, validate it, and save a version. Existing capacity targets refer to a specific configuration-version ID, not to mutable editor contents. + +## Using the API + +Validate YAML before saving it: + +```bash +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' -X POST \ + "$AKOFLOW_API_URL/machine-configuration-validations/" \ + -d '{"playbookYaml":"---\n- name: Configure worker\n hosts: all\n become: true\n tasks:\n - name: Install curl\n ansible.builtin.package:\n name: curl\n state: present\n"}' +``` + +Create the configuration and then its first version: + +```bash +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' -X POST "$AKOFLOW_API_URL/machine-configurations/" \ + -d '{"id":"analysis-worker","name":"Analysis worker","description":"Packages used by analysis jobs"}' + +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' -X POST \ + "$AKOFLOW_API_URL/machine-configurations/analysis-worker/versions/" \ + -d '{"version":1,"status":"published","playbookYaml":"---\n- name: Configure worker\n hosts: all\n become: true\n tasks:\n - name: Install curl\n ansible.builtin.package:\n name: curl\n state: present\n","compatibility":{"providers":["gcp"]}}' \ + -o machine-configuration.json || exit 1 + +AKOFLOW_MACHINE_CONFIGURATION_VERSION_ID=$(jq -er '.versions[] | select(.version == 1) | .id' machine-configuration.json) || exit 1 +``` + +Validation checks playbook structure and returns `valid`, a content hash, and errors when present. It does not provision a machine or execute the playbook. The version request returns the configuration with its versions. Run the [capacity-target example](/docs/guides/infrastructure/cloud-capacity#create-a-capacity-target) in the same Bash session: it attaches this saved version when `AKOFLOW_MACHINE_CONFIGURATION_VERSION_ID` is set. Without that variable, it creates a target using only the built-in worker configuration. diff --git a/docs/docs/guides/infrastructure/simgrid.md b/docs/docs/guides/infrastructure/simgrid.md index a272cbec..277c27be 100644 --- a/docs/docs/guides/infrastructure/simgrid.md +++ b/docs/docs/guides/infrastructure/simgrid.md @@ -5,13 +5,15 @@ description: Configure a reproducible simulated environment with resources, netw # Model a SimGrid environment -This how-to is for users who already know how to import a workflow and want to model the infrastructure it will run on. It uses the checked-in [edge-to-cloud bundle](../../showcase/edge-cloud-simulation) because that bundle contains a resource model, a topology, per-activity simulation profiles, a scope, and a runnable plan. +Use this guide to model resources, activity duration, and network transfers for a simulated workflow. It draws on the checked-in [edge-to-cloud bundle](/docs/showcase/edge-cloud-simulation), which includes a complete runnable plan. -Use SimGrid when the question is about a modeled platform: placement, parallel capacity, transfers, latency, and simulated cost. Do not use it to validate an SSH, Kubernetes, cloud, or Slurm connection; a SimGrid environment has no remote endpoint to test. For a first end-to-end execution, start with [Run your first simulated workflow](../workflows/first-run). +Use SimGrid when the question is about a modeled platform: placement, parallel capacity, transfers, latency, and simulated cost. Do not use it to validate an SSH, Kubernetes, cloud, or Slurm connection; a SimGrid environment has no remote endpoint to test. For a first end-to-end execution, start with [Run your first simulated workflow](/docs/guides/workflows/first-run). + +The YAML blocks below show only the fields discussed in each step. Use the [complete versioned files](https://github.com/UFFeScience/akoflow/tree/v1.0.8/examples/simulation) when submitting the example. ## Prerequisites -- A running AkôFlow daemon with the SimGrid runner available. The server image includes it; source builds can follow [`examples/simulation/README.md`](https://github.com/UFFeScience/akoflow/blob/main/examples/simulation/README.md). +- A running AkôFlow server with the SimGrid runner available. The server image includes it; source builds can follow [`examples/simulation/README.md`](https://github.com/UFFeScience/akoflow/blob/v1.0.8/examples/simulation/README.md). - A local checkout of the repository if you will submit the versioned YAML bundle. - A workflow with explicit `simulation.durationSeconds` or `simulation.flops` for every activity whose execution time should be modeled. @@ -19,7 +21,7 @@ Use SimGrid when the question is about a modeled platform: placement, parallel c Create a simulation environment and bind the `simgrid` runtime to every resource that a plan may use. In Desktop, open **Infrastructure → Environments**, create a simulation environment, add its resources and the SimGrid runtime, then enable a runtime binding for each resource. The API equivalent is the `environment.yaml` in the example bundle. -```yaml title="examples/simulation/environment.yaml" +```yaml title="Resource excerpt from environment.yaml" resources: - id: simulated-edge cpuCores: 2 @@ -49,13 +51,15 @@ The fields have different jobs: | `bootOverheadSeconds` and `containerOverheadSeconds` | Add modeled setup time. A plan assignment may override these values when it freezes the selected placement. | | `schedulable` | Makes the resource available to a scope and to planning. Keep non-execution resources out of a placement by setting it to `false`. | -Do not raise `cpuCores` merely to make a predicted makespan smaller. A 50-core resource models 50 simultaneous execution lanes only when the workflow and the resulting plan can use them. The [50-core fan-out Showcase](../../showcase/parallel-50-core) is the worked example for that case. +Do not raise `cpuCores` merely to make a predicted makespan smaller. A 50-core resource models 50 simultaneous execution lanes only when the workflow and the resulting plan can use them. The [50-core fan-out Showcase](/docs/showcase/parallel-50-core) is the worked example for that case. ## 2. Give each activity its own compute profile -The most important input for a meaningful prediction is not the image or command: it is the work associated with each activity. Put the profile on the activity rather than applying one shared default to the workflow. +Give each activity a compute profile based on its own work. That profile drives +the modeled duration; a single workflow-wide default hides differences between +activities. -```yaml title="examples/simulation/workflow.yaml" +```yaml title="Activity excerpt from workflow.yaml" activities: - name: prepare runtime: simgrid @@ -80,9 +84,9 @@ After importing, open the workflow definition and inspect every activity. A miss ## 3. Model the network before planning -Create a topology for the execution scope. In Desktop, select the scope and create or edit its topology; with the API, submit `topology.yaml` after the scope. The example models one bidirectional edge-to-cloud link: +Create a topology for the execution scope. The Desktop scope form creates an empty topology; its current navigation does not expose link creation. Submit `topology.yaml` through the API after creating the scope. The example models one bidirectional edge-to-cloud link: -```yaml title="examples/simulation/topology.yaml" +```yaml title="Link excerpt from topology.yaml" links: - id: edge-cloud sourceResourceId: simulated-edge @@ -100,11 +104,11 @@ Bandwidth is in **bits per second**, while dependency sizes are in **bytes**. Fo For example, 100,000,000 bytes over 100,000,000 bit/s with 50 ms latency has a base transfer time of `8.05 s`. The SimGrid platform uses the same bandwidth and latency values. A data dependency creates a transfer only when its producer and consumer are assigned to different resources. -`bidirectional: true` makes the link usable in both directions. `sharingPolicy: shared` is emitted as a shared SimGrid link; use `independent` or `fatpipe` only when the modeled link should not share bandwidth. A topology can contain several links: AkôFlow derives an available path between resources and uses the lowest-latency path according to the configured link latencies and bandwidths. A missing route is not a zero-cost transfer; fix the topology or keep the dependent activities on the same resource. +`bidirectional: true` makes the link usable in both directions. `sharingPolicy: shared` is emitted as a shared SimGrid link; use `independent` or `fatpipe` only when the modeled link should not share bandwidth. AkôFlow selects a route through the available links using their latency and bandwidth, then models the transfer on that route. If dependent activities may use different resources, provide a route between them: PRISM rejects a missing route, while HEFT's baseline can estimate zero transfer time without a direct link. [Network modeling](/docs/explanations/network-modeling) explains the difference. Declare the data itself in the workflow: -```yaml title="examples/simulation/workflow.yaml" +```yaml title="Data-dependency excerpt from workflow.yaml" dataDependencies: - producerActivity: prepare consumerActivity: analyze @@ -129,11 +133,11 @@ environmentVersionIds: In Desktop, open the workflow, choose **Generate plan**, select **Simulation**, and choose the scope. Use **Generate plans** to compare algorithms, or **Create manually** to reproduce a known placement. Inspect the candidate Gantt before selecting it: the lane count should reflect the selected resource cores, and cross-resource dependency lines should correspond to the modeled data dependencies. -To submit the checked-in manual plan and run it through the API, execute the bundle from the repository root: +To submit the checked-in manual plan and run it through the API, complete [API connection setup](/docs/tutorials/api-access), use a v1.0.8 checkout, and execute the bundle from its root: ```bash -export AKOFLOW_API_URL='http://127.0.0.1:8080/akoflow-api' -export AKOFLOW_API_TOKEN='' +git clone --branch v1.0.8 --depth 1 https://github.com/UFFeScience/akoflow.git akoflow-simgrid +cd akoflow-simgrid sh examples/simulation/run.sh ``` @@ -165,6 +169,6 @@ The run's execution, transfer, queue, and overhead totals are accumulated across | No transfer is reported | Confirm that the data dependency has `sizeBytes > 0`, the selected assignments use different resources, and the scope topology has a route between them. | | A planned transfer is unrealistically fast | Check units: topology bandwidth is bit/s and data dependency size is bytes. Include link latency. | | Parallel activities appear in one lane | Check `cpuCores`, activity CPU requirements, and the plan's `coreId` assignments. Then regenerate the plan. | -| A resource is absent from candidate plans | Confirm `schedulable: true`, an enabled `simgrid` runtime binding, enough CPU/memory for the activity, and that its environment version belongs to the scope. | +| A resource is absent from candidate plans | Confirm `schedulable: true` and that its environment version belongs to the scope; then inspect the activity requirements and algorithm placement. An enabled `simgrid` runtime binding is needed to execute a selected plan, but it is not part of the planning resource filter. | -Related material: [execution scopes](./execution-scopes), [network fan-out](../../showcase/network-fanout), [parallel 50-core fan-out](../../showcase/parallel-50-core), and [the execution evidence guide](../workflows/executions). +Related material: [execution scopes](/docs/guides/infrastructure/execution-scopes), [network fan-out](/docs/showcase/network-fanout), [parallel 50-core fan-out](/docs/showcase/parallel-50-core), and [the execution evidence guide](/docs/guides/workflows/executions). diff --git a/docs/docs/guides/infrastructure/storage.md b/docs/docs/guides/infrastructure/storage.md index 74ee581f..41991248 100644 --- a/docs/docs/guides/infrastructure/storage.md +++ b/docs/docs/guides/infrastructure/storage.md @@ -1,8 +1,15 @@ --- title: Browse and manage storage +description: Browse approved storage paths and perform supported file operations. --- -AkôFlow exposes storage through environment discovery or configured storage connectors. Browsing is constrained to approved roots and operations are capability-driven: a read-only or unavailable storage does not expose the same actions as a healthy writable storage. +Use **Storage** to browse approved roots and act on files. Available actions depend on the driver and storage settings. Try the intended path before relying on a catalog status. + +The current S3 browser sends unsigned requests, so a private bucket may fail to open even when an S3 transfer works with server credentials. See [AWS and S3 support](/docs/guides/infrastructure/aws) for that distinction and the current cloud limits. + +For the API commands on this page, complete [API connection setup](/docs/tutorials/api-access) first. +The IDs `hpc`, `hpc-scratch`, and `archive-store` and the `/scratch/project-a` paths below are examples. Replace them with an environment, storage IDs, and approved paths returned by your own server before running a command. +For a self-managed daemon browsing local files, first configure the root as shown in the [environment YAML reference](/docs/reference/environment-yaml#storage). ## Browse files @@ -13,23 +20,23 @@ AkôFlow exposes storage through environment discovery or configured storage con 3. Select an approved root and navigate folders with the breadcrumb. 4. Use **Refresh** to reload the current listing. Use **Index** only when indexing is enabled for that storage. -Entries are loaded lazily for the selected path; opening Storage does not scan the entire filesystem. The badges report read/write access and whether access from compute nodes was verified. +Entries load for the selected path; opening Storage does not scan the entire filesystem. Read/write badges reflect the available driver and storage settings. Compute-node visibility reflects the `shared` setting or a runtime binding, not a fresh access test on a compute node. ### Using the API ```bash # Discover storage IDs for an environment -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/environments/hpc/storages/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/environments/hpc/storages/" # Inspect approved roots -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/storages/hpc-scratch/roots/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/storages/hpc-scratch/roots/" # Browse one path; preserve nextCursor when the response is paginated -curl --fail-with-body -G -H "Authorization: Bearer $AKOFLOW_TOKEN" \ +curl --fail-with-body -G -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ --data-urlencode 'path=/scratch/project-a' --data-urlencode 'limit=100' \ - "$AKOFLOW_URL/storages/hpc-scratch/entries/" + "$AKOFLOW_API_URL/storages/hpc-scratch/entries/" ``` Do not construct paths outside the returned roots. The server validates the requested path against storage policy. @@ -44,25 +51,51 @@ The actions column can download a file, archive and download a directory, copy a ```bash # Prepare a file download (POST /archives/ for a directory) -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' -X POST \ - "$AKOFLOW_URL/storages/hpc-scratch/downloads/" \ + "$AKOFLOW_API_URL/storages/hpc-scratch/downloads/" \ -d '{"path":"/scratch/project-a/result.csv","id":"download-result-1"}' # Copy to another registered storage -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' -X POST \ - "$AKOFLOW_URL/storages/hpc-scratch/copies/" \ + "$AKOFLOW_API_URL/storages/hpc-scratch/copies/" \ -d '{"path":"/scratch/project-a/result.csv","destinationStorageId":"archive-store","id":"copy-result-1"}' # Calculate a checksum -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' -X POST \ - "$AKOFLOW_URL/storages/hpc-scratch/checksum/" \ + "$AKOFLOW_API_URL/storages/hpc-scratch/checksum/" \ -d '{"path":"/scratch/project-a/result.csv"}' + +# Archive a directory on the same storage +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' -X POST \ + "$AKOFLOW_API_URL/storages/hpc-scratch/archives/" \ + -d '{"path":"/scratch/project-a","id":"archive-project-a-1"}' ``` -Downloads and archives may return queued runs. Read `GET /storage-downloads/{downloadId}/` until the run is ready, then fetch `GET /storage-downloads/{downloadId}/content/`. +The file-download request returns a `ready` record for the path; it does not freeze the file's bytes. The content endpoint opens that path when you fetch it. If the file can change, compare the downloaded file with a fresh checksum from the storage request above. + +```bash +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/storage-downloads/download-result-1/content/" -o result.csv + +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/storage-downloads/copy-result-1/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/storage-downloads/archive-project-a-1/" +``` + +Compare the downloaded file's SHA-256 with the `checksum` returned by the source request: use `sha256sum result.csv` on Linux, `shasum -a 256 result.csv` on macOS, or `Get-FileHash result.csv -Algorithm SHA256` in Windows PowerShell. The API checksum includes a `sha256:` prefix. + +The copy runs in the background at the same path in the destination storage; wait for `completed` before using it. The archive writes a `.tar.gz` beside the directory. When its record reports `ready`, fetch `/storage-downloads/archive-project-a-1/content/` to save the archive. + +```bash +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/storage-downloads/archive-project-a-1/content/" \ + -o project-a.tar.gz +``` ## Register an existing file @@ -73,15 +106,15 @@ Use **Register as DataObject** for a file that should enter the workflow data mo ### Using the API ```bash -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' -X POST \ - "$AKOFLOW_URL/storages/hpc-scratch/promote-data/" \ - -d '{"path":"/scratch/project-a/result.csv","id":"data-result-1","workflowVersionId":"analysis-v3","runId":"run-42","activityId":"aggregate"}' + "$AKOFLOW_API_URL/storages/hpc-scratch/promote-data/" \ + -d '{"path":"/scratch/project-a/result.csv","id":"data-result-1"}' -curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_TOKEN" \ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' -X POST \ - "$AKOFLOW_URL/storages/hpc-scratch/promote-artifact/" \ + "$AKOFLOW_API_URL/storages/hpc-scratch/promote-artifact/" \ -d '{"path":"/scratch/images/solver.sif","id":"solver-sif-1","name":"Solver","version":"1.2.0","scope":"environment","scopeId":"hpc"}' ``` -Promotion registers the existing path; it does not upload or move the file. +Promotion registers the existing path; it does not upload or move the file. Add `workflowVersionId`, `runId`, and `activityId` to the data request only when you have matching existing records and want to associate the file with them. diff --git a/docs/docs/guides/interface-tour.mdx b/docs/docs/guides/interface-tour.mdx index 92d58196..87ac508b 100644 --- a/docs/docs/guides/interface-tour.mdx +++ b/docs/docs/guides/interface-tour.mdx @@ -3,13 +3,13 @@ id: interface-tour title: Tour the AkôFlow interface sidebar_label: Interface tour -description: Learn how the AkôFlow Desktop navigation maps to the control-plane API. +description: Find workflows, environments, plans, runs, and results in AkôFlow Desktop. --- import AnnotatedScreenshot from '@site/src/components/AnnotatedScreenshot'; import useBaseUrl from '@docusaurus/useBaseUrl'; -AkôFlow Desktop is the visual client for the AkôFlow daemon. The application does not run infrastructure commands from the browser renderer: it requests the daemon API, and the daemon performs discovery, planning, execution, data movement, and infrastructure operations. +AkôFlow Desktop lets you see your workflows, environments, plans, runs, and results in one place. Start on **Overview** to check the current instance, then use the sidebar to open the record you need. ## Main areas -| Area | What you do there | Main API domain | -|---|---|---| -| Overview | Check registered environments, workflows, and completed runs | Multiple read endpoints | -| Workflows | Create versioned definitions and inspect activity DAGs | `/workflow-definitions/` | -| Planning sessions | compare algorithms and promote a candidate to a plan | `/planning-sessions/` | -| Infrastructure | Connect environments, discover resources, and define execution scopes | `/environments/`, `/resources/`, `/execution-scopes/` | -| Runs | Start and inspect workflow, standalone, simulated, and interactive runs | `/execution-runs/` | -| Artifacts | Register, build, locate, and materialize executable artifacts | `/artifacts/`, `/artifact-builds/` | -| Provenance | Query evidence and follow lineage | `/provenance/` | -| Audit | Inspect the operational event history | `/audit-events/` | +| Area | What you do there | +|---|---| +| Overview | Check registered environments, workflows, and completed runs | +| Workflows | Create workflows and inspect their activities | +| Planning sessions | Compare candidate plans and select one | +| Infrastructure | Connect environments and inspect available resources | +| Runs | Start and inspect workflow, simulation, and interactive runs | +| Artifacts | Register and build executables for workflows | +| Provenance | [Follow how a result was produced](/docs/guides/data/provenance) | +| Audit | [Inspect connection, discovery, and console events](/docs/guides/data/audit-events) | -## Follow the ownership hierarchy +## Follow a record -AkôFlow pages preserve the relationship between records. An execution belongs to a plan, a plan belongs to a workflow, and a provisioning operation belongs to a cloud resource. Breadcrumbs show that chain; their ancestors are links. +Breadcrumbs connect a run to its plan and workflow. Select an earlier item to return to that record. For example: Workflow pages lead from workflow to plan, execution and activity. Infrastructure pages lead from environment through inventory and resource to provisioning and operation. -Use the back control below the breadcrumb to return to the logical parent. Its destination remains correct even when the page was opened from search or a notification. +Use the back control below the breadcrumb to return to the parent record, including when you arrived through search or a notification. -## Desktop and API are two views of the same operation +## Find a record -Most task guides contain two paths: +Press +K on macOS, Ctrl+K on Windows or Linux, or select the search field. An empty search shows shortcuts to areas such as **Workflow definitions**, **Planning sessions**, and **Runs**. -- **AkôFlow Desktop** explains the controls, validation, progress, and resulting detail page. -- **API** shows the corresponding HTTP request and a minimal payload. +Enter a name or ID to find records. Select a result or press Enter to open the first one; press Escape to close search. See [Find a record](/docs/guides/operations/find-records) for API search and result limits. -The API path is useful for automation and reproducible experiments. The Desktop path is useful for exploration, comparison, and live monitoring. Records created through either path appear in the same interface. - -## Use global search deliberately - -Press +K on macOS, Ctrl+K on Windows or Linux, or select the search field in the title bar. With an empty field, Desktop lists navigation shortcuts such as **Workflow definitions**, **Planning sessions**, **Runs**, and **Provenance**. This is the fastest route when you know the product area but not its sidebar location. - -Once you enter text, the list changes to matching control-plane entities. A result identifies its record by title and ID, and may show a status and type; select it to open the corresponding record. Press Enter to open the first available result, or Escape to close the result list. - -Search is a locator, not an investigation surface. It does not replace the filtered lists or the provenance query tools: use the workflow, run, plan, environment, or provenance page after opening a result when you need status history, evidence, or a precise server-side filter. If Desktop says **Search is temporarily unavailable**, the search request failed; retry after confirming that the daemon connection is healthy. +Open a result's detail page for its status and history. If Desktop says **Search is temporarily unavailable**, check the AkôFlow connection and try again. ## Global terminal -Interactive commands open in the terminal panel fixed to the bottom of the application. The daemon owns the session and streams its output; closing a page does not make the renderer execute or manage a remote shell itself. - -Open an interactive session from a resource or runtime-aware operation, then use the terminal panel to inspect its output. The session detail page provides the durable record and log-export control; the panel is a live view, not a replacement for the persisted session evidence. See [Interactive console](./operations/interactive-console) for prerequisites, connection behavior, and recovery. - -## Read-only instances +Interactive sessions open in the terminal panel at the bottom of the application. Closing a page does not close a remote session; close it from the panel when you finish. -Some instance modes prevent write operations. The interface displays the active mode and guards creation, update, execution, and destructive actions. Read-only exploration, provenance, and audit remain available according to the daemon configuration. +Open a session from a compatible resource, then use the panel to inspect its output. Export the log from the session detail page when you need a saved record. See [Interactive console](/docs/guides/operations/interactive-console) for prerequisites and recovery. ## Continue -Start with [your first end-to-end run](./workflows/first-run), or connect [execution infrastructure](./infrastructure/environments). +To create and run one workflow in Desktop, follow the [first local run](/docs/guides/workflows/first-local-run). For a simulation through a separately managed API, use the [SimGrid tutorial](/docs/guides/workflows/first-run). To connect another target, see [Environments](/docs/guides/infrastructure/environments). diff --git a/docs/docs/guides/operations/credentials-and-ssh.md b/docs/docs/guides/operations/credentials-and-ssh.md index 651c4010..bc98b622 100644 --- a/docs/docs/guides/operations/credentials-and-ssh.md +++ b/docs/docs/guides/operations/credentials-and-ssh.md @@ -1,11 +1,15 @@ --- -title: Credentials and SSH service keys -description: Store credentials in the Engine, assign SSH service keys, and keep private material outside workflow definitions. +title: Manage SSH service keys +description: Generate or import an SSH key and assign it to a saved connection. --- -# Credentials and SSH service keys +# Manage SSH service keys -AkôFlow stores secret material in the Engine and places a `credentialRef` in connection definitions. The renderer sends a secret only when it is first saved or imported; list operations return references or public metadata, never the original private key or bearer token. +Use this guide when an SSH connection needs a key managed by AkôFlow. Generate or import the key, authorize its public half on the remote host, then assign its reference to the saved connection. Keep the private key out of workflow definitions. + +For other providers, use [Configure Kubernetes](/docs/guides/infrastructure/kubernetes) to store a cluster token or [Connect Google Cloud](/docs/tutorials/connect-cloud) to validate and store a service-account credential. + +AkôFlow returns public metadata and a credential reference when you list managed SSH keys; it does not return the original private key. ## Generate an SSH service key @@ -16,18 +20,17 @@ AkôFlow stores secret material in the Engine and places a `credentialRef` in co 3. Select **Generate key**. 4. Copy the public key and authorize it on every SSH hop required by the target—for example, both a gateway and its HPC login node. -The Engine generates an Ed25519 key. IDs must start with an ASCII letter or digit, may then contain letters, digits, `_` or `-`, and may contain at most 64 characters. The private file is stored with mode `0600`. +The AkôFlow server generates an Ed25519 key. IDs must start with an ASCII letter or digit, may then contain letters, digits, `_` or `-`, and may contain at most 64 characters. The private file is stored with mode `0600`. ### Using the API -```bash -export AKOFLOW_URL='http://127.0.0.1:/akoflow-api' -export AKOFLOW_TOKEN='' +Complete [API connection setup](/docs/tutorials/api-access) first. +```bash curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' \ - -X POST "$AKOFLOW_URL/ssh-keys/" \ + -X POST "$AKOFLOW_API_URL/ssh-keys/" \ -d '{"id":"plafrim-service","comment":"akoflow@plafrim"}' ``` @@ -41,36 +44,37 @@ The response contains `id`, `credentialRef`, `publicKey`, and SHA-256 `fingerpri 2. Enter a new **Key ID** under **Import an existing private key**. 3. Paste the OpenSSH private key and select **Import private key**. -The private key is sent once to the Engine, validated with `ssh-keygen`, stored in the credential directory and never displayed again. +The private key is sent once to the AkôFlow server, validated with `ssh-keygen`, stored in the credential directory and never displayed again. ### Using the API -Avoid putting a private key directly in shell history. Create a JSON payload with a tool that reads a protected file: +Avoid putting a private key in shell history or a temporary JSON file. Read the existing protected key file and stream the request: ```bash -jq -n \ - --arg id 'existing-hpc-key' \ - --rawfile privateKey "$HOME/.ssh/id_ed25519" \ - '{id:$id, privateKey:$privateKey}' > /tmp/akoflow-ssh-key.json - -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' \ - -X POST "$AKOFLOW_URL/ssh-keys/import/" \ - --data-binary @/tmp/akoflow-ssh-key.json +( + set -o pipefail + jq -n \ + --arg id 'existing-hpc-key' \ + --rawfile privateKey "$HOME/.ssh/id_ed25519" \ + '{id:$id, privateKey:$privateKey}' | curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' \ + -X POST "$AKOFLOW_API_URL/ssh-keys/import/" \ + --data-binary @- +) ``` -Remove the temporary payload securely according to your operating-system policy. An empty or invalid private key, invalid/duplicate ID, or `ssh-keygen` failure returns `422`. +An empty or invalid private key, invalid/duplicate ID, or `ssh-keygen` failure returns `422`. List public metadata at any time: ```bash curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/ssh-keys/" + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/ssh-keys/" ``` -There is currently no SSH-key deletion endpoint. Manage key lifecycle deliberately and rotate authorization on remote systems when a key should no longer be trusted. +There is currently no SSH-key deletion endpoint. When a key should no longer be trusted, remove its authorization on remote systems and follow your operator's key-rotation procedure. ## Assign a key to a connection @@ -87,46 +91,44 @@ Assignment changes only `credentialRef`; it preserves the connection's endpoint, ### Using the API -Read the current environment definition first so you preserve every connection field. Then update the connection with the `credentialRef` returned above: - -```bash -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' \ - -X PUT "$AKOFLOW_URL/environment-connections/hpc-ssh/" \ - -d '{ - "id":"hpc-ssh", - "environmentId":"plafrim", - "name":"PlaFRIM login", - "type":"ssh", - "endpoint":"plafrim.example.org:22", - "username":"researcher", - "credentialRef":"" - }' -``` - -## Kubernetes bearer tokens - -The Desktop environment connection flow stores a Kubernetes token and retains only its reference. The direct API is: +Read the saved connection from its environment and change only `credentialRef`. +Use the environment ID, connection ID, and reference returned by key registration: ```bash -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' \ - -X POST "$AKOFLOW_URL/kubernetes-tokens/" \ - -d '{"id":"research-cluster","token":""}' +read -r -p 'Environment ID: ' AKOFLOW_ENVIRONMENT_ID || exit 1 +read -r -p 'Connection ID: ' AKOFLOW_CONNECTION_ID || exit 1 +read -r -p 'New credentialRef: ' AKOFLOW_CREDENTIAL_REF || exit 1 +[ -n "$AKOFLOW_ENVIRONMENT_ID" ] && [ -n "$AKOFLOW_CONNECTION_ID" ] && + [ -n "$AKOFLOW_CREDENTIAL_REF" ] || exit 1 + +( + set -o pipefail + curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/environments/$AKOFLOW_ENVIRONMENT_ID/" | + jq -e --arg id "$AKOFLOW_CONNECTION_ID" \ + --arg ref "$AKOFLOW_CREDENTIAL_REF" \ + '.connections[] | select(.id == $id) | .credentialRef = $ref' | + curl --fail-with-body -X PUT \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' \ + --data-binary @- \ + "$AKOFLOW_API_URL/environment-connections/$AKOFLOW_CONNECTION_ID/" +) || exit 1 + +curl --fail-with-body -X POST \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/environment-connections/$AKOFLOW_CONNECTION_ID/health/" ``` -The response is `{"credentialRef":"..."}`. Empty/invalid values return `422`; unavailable credential storage returns `503`. - -## Cloud credentials - -Cloud onboarding similarly sends provider credential JSON to `/cloud-credentials/` and stores only the returned reference. Validation is a separate operation at `/cloud-credentials/validate/`; see [Cloud capacity](../infrastructure/cloud-capacity.md) for provider-specific fields and the complete flow. +The `PUT` replaces stored fields; the separate health request tests the updated +connection. Inspect its returned status before using it. A missing connection ID +makes `jq` fail; correct the ID rather than creating a second connection. -## Security boundaries +## Keep the key private -- Do not place private keys or tokens in workflow YAML, resource metadata, screenshots, logs, or documentation examples. -- API Bearer authentication protects transport to the Engine; `credentialRef` authorizes a provider operation after the request reaches the Engine. +- Do not place private keys in workflow YAML, resource metadata, screenshots, logs, or documentation examples. +- API Bearer authentication protects requests to the server; `credentialRef` identifies the saved credential used for a provider operation. - Instance export redacts credentials and credential references. Imported snapshots therefore cannot reconnect until you return to a writable instance and configure credentials there. -- If SSH uses a gateway or proxy command, authorize and validate every hop. `forwardAgent` and proxy settings are connection configuration, not substitutes for an Engine-managed key. +- If SSH uses a gateway or proxy command, authorize and validate every hop. `forwardAgent` and proxy settings are connection configuration, not substitutes for a server-managed key. - A leaked public key does not reveal the private key, but remote `authorized_keys` entries still determine where that key can authenticate. diff --git a/docs/docs/guides/operations/find-records.md b/docs/docs/guides/operations/find-records.md new file mode 100644 index 00000000..e5fe27e1 --- /dev/null +++ b/docs/docs/guides/operations/find-records.md @@ -0,0 +1,72 @@ +--- +title: Find a record +description: Search AkôFlow records by name or ID in Desktop or through the API. +--- + +# Find a record + +Use search to open a workflow, run, environment, plan, or other saved record by name or ID. For operations that finished in this Desktop profile, [follow notifications](/docs/guides/operations/follow-notifications). + +## Search from Desktop + +1. Focus **Search AkôFlow** in the top bar, press `/`, or press `⌘K`/`Ctrl+K`. +2. Enter an ID, name, state or other indexed value. +3. Select a result, or press Enter to open the first result. +4. Press Escape to close search. + +With an empty query, search shows quick navigation destinations. As you type, it shows matching records; select one to open its detail or list page. + +Search covers: + +| Type | Representative indexed values | +|---|---| +| `workflow` | ID, external ID, name, namespace | +| `execution` | ID, title, resource/runtime IDs, failure and status | +| `artifact` | ID, name and version | +| `environment` | ID, name, description and status | +| `resource` | ID, name, provider, region, zone and type | +| `plan` | ID, algorithm, objective, workflow version and scope | +| `scope` | ID, name, topology and environment versions | +| `materialization` | ID, variant, digest, resource, run, activity, path and status | + +Exact matches appear before partial matches. + +## Search through the API + +Complete [API connection setup](/docs/tutorials/api-access) first. + +```bash +curl --get --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + --data-urlencode 'q=science' \ + --data-urlencode 'types=workflow,execution,artifact' \ + --data-urlencode 'limit=20' \ + "$AKOFLOW_API_URL/search/" +``` + +The response shape is: + +```json +{ + "query": "science", + "results": [ + { + "type": "workflow", + "id": "science-workflow", + "title": "Science workflow", + "subtitle": "default", + "path": "/workflows/science-workflow", + "score": 0.9 + } + ], + "total": 1 +} +``` + +`limit` defaults to 30 and is capped at 100. Omit `types` to search every supported type. Unknown type names are ignored; if every supplied name is unknown, the result is empty. An empty `q` returns an empty result without loading catalogs. A catalog failure returns `500 Internal Server Error`. + +## When search returns nothing + +- Enter at least one non-whitespace character; an empty server query returns no entities. +- Search uses the same catalogs as the list pages. If a catalog request fails, check the server connection and retry. +- Use an exact ID when possible, or limit API results with `types`. diff --git a/docs/docs/guides/operations/follow-notifications.md b/docs/docs/guides/operations/follow-notifications.md new file mode 100644 index 00000000..e62639b1 --- /dev/null +++ b/docs/docs/guides/operations/follow-notifications.md @@ -0,0 +1,77 @@ +--- +title: Follow operation notifications +description: Track recent Desktop operations and find their durable records. +--- + +# Follow operation notifications + +Notifications help you return to an operation started in this Desktop profile. For a saved record from any profile, [search by name or ID](/docs/guides/operations/find-records). Open that record for its lasting status; [Audit](/docs/guides/data/audit-events) covers only some operation types. + +## Using AkôFlow Desktop + +The bell in the top bar reports when these operations, started in this Desktop +profile, finish or fail: + +- planning sessions; +- executions; +- artifact builds; +- interactive terminals; +- cloud provisioning. + +In the packaged Desktop, the same bell also shows an available application +update or its download progress. That update notice is separate from the saved +operation entries below. + +Select an operation notification to mark it read and open its associated page. Use the check control to mark all current items read. The center retains at most 40 entries. + +A saved notification appears when a tracked operation finishes or fails. Closed terminals also leave the active-session list. + +:::note Profile-local state +Notification entries and the list of tracked operations live in browser local storage. They are not audit or provenance records, do not synchronize between Desktop profiles, and may disappear when site data is cleared. Use execution, planning, build, cloud-operation, or console details for lasting status. Audit records connection checks, resource discovery, and console actions. +::: + +Native operating-system notifications are emitted only when the browser/renderer exposes the Notification API and permission has already been granted. The current interface does not prompt for notification permission. + +## Find the operation through the API + +There is no `/notifications/` endpoint. Complete +[API connection setup](/docs/tutorials/api-access), then query the record that +owns the operation: + +```bash +# Planning sessions +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/planning-sessions/" + +# Execution runs +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/execution-runs/" + +# Active interactive sessions +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/console-sessions/" + +# Cloud provisioning and other cloud operations +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/cloud-operations/" +``` + +For an artifact build, use the build ID shown in its detail page: + +```bash +read -r -p 'Artifact build ID: ' AKOFLOW_BUILD_ID || exit 1 +[ -n "$AKOFLOW_BUILD_ID" ] || exit 1 +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/artifact-builds/$AKOFLOW_BUILD_ID/runs/" +``` + +Open a returned run or cloud-operation ID for its status and events. Desktop +application update notices are local to the app; there is no server-side +notification record to query for them. For connection checks, resource +discovery, or console actions, query `/audit-events/` with the relevant +session, connection, resource, or environment filter. It does not reconstruct +the notification history. + +## When a notification is missing + +Notifications only cover operations started and tracked by the current Desktop profile. Opening the app after an operation started elsewhere does not reconstruct its notification history. Open the owning list or detail page, or search its ID. diff --git a/docs/docs/guides/operations/instance-management.md b/docs/docs/guides/operations/instance-management.md index 8bd25aef..976102e7 100644 --- a/docs/docs/guides/operations/instance-management.md +++ b/docs/docs/guides/operations/instance-management.md @@ -1,24 +1,19 @@ --- -title: Instance management -description: Configure an AkôFlow instance, export and import sanitized snapshots, switch instances, and reset local state. +title: Manage an instance +description: Configure an AkôFlow instance, manage sanitized snapshots, and reset its saved catalog. --- -# Instance management +# Manage an instance -An AkôFlow **instance** is one control-plane installation and its catalog. Its identity contains an ID, name, optional description, organization and location, plus the transfer relay buffer. The Engine creates an identity automatically from the machine hostname during startup; the Desktop cannot proceed when `GET /instance/` is unavailable. +An AkôFlow **instance** contains your environments, workflows, plans, runs, and settings. Use this guide to inspect its identity, export a snapshot, open a read-only archive, or return to the writable instance. Export a snapshot before changing versions or resetting local state. -Set these variables for the API examples: - -```bash -export AKOFLOW_URL='http://127.0.0.1:/akoflow-api' -export AKOFLOW_TOKEN='' -``` +For direct API use, complete [API connection setup](/docs/tutorials/api-access) before running the commands below. To change theme or graph animation, use [Personal preferences](/docs/guides/operations/personal-preferences). ## Inspect the active identity ### Using AkôFlow Desktop -Open **Settings → General**. The current interface exposes the workspace transfer relay setting; instance identity fields are read through the Engine but are not currently editable as a separate Desktop form. +Open **Settings → General**. The current interface exposes the workspace transfer relay setting; instance identity fields are read through the server but are not currently editable as a separate Desktop form. The relay is an in-memory buffer per active transfer. It streams source output to destination input and does not persist the transferred payload. The default is 8 MiB; accepted values are 5–64 MiB. @@ -26,57 +21,27 @@ The relay is an in-memory buffer per active transfer. It streams source output t ```bash curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/instance/" + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/instance/" ``` -To change the relay size, first preserve the identity returned by `GET`, then send the complete object: +To change the relay size, read the current instance, update that field, and send the complete object back: ```bash -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' \ - -X PUT "$AKOFLOW_URL/instance/" \ - -d '{ - "id":"akoflow-lab", - "name":"AkôFlow lab", - "description":"Research control plane", - "organization":"Example Lab", - "location":"Niterói", - "transferBufferBytes":8388608 - }' +set -o pipefail +curl --fail-with-body --silent \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/instance/" \ + | jq '.transferBufferBytes = 8388608' \ + | curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' \ + -X PUT "$AKOFLOW_API_URL/instance/" \ + --data-binary @- ``` `id` and `name` are required. A zero buffer selects the 8 MiB default; values outside 5–64 MiB return `422 Unprocessable Entity`. -## Personal preferences - -Theme and graph animation are associated with a stable browser-profile client ID, not with an authenticated user account. Desktop saves them in local storage immediately and attempts to synchronize them with the Engine. If the Engine is offline, local preferences keep the interface usable. - -### Using AkôFlow Desktop - -1. Open **Settings → General**. -2. Select **Light** or **Dark**. -3. Turn **Graph animation** on or off. - -### Using the API - -The client ID must contain 8–128 characters. The only accepted themes are `light` and `dark`. - -```bash -CLIENT_ID='docs-client-01' - -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' \ - -X PUT "$AKOFLOW_URL/user-preferences/$CLIENT_ID/" \ - -d '{"theme":"dark","animationsEnabled":false}' - -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/user-preferences/$CLIENT_ID/" -``` - ## Export a sanitized instance ### Using AkôFlow Desktop @@ -85,14 +50,14 @@ curl --fail-with-body \ 2. Optionally enable **Include artifact files**. Large artifact stores can produce a large ZIP. 3. Select **Export instance ZIP**. -The Engine uses SQLite `VACUUM INTO` to create a consistent database snapshot. Tokens, private keys, credential references and connection secrets are redacted. The ZIP manifest records that credentials were not included. Including artifacts adds artifact files but does not restore credentials. +The server creates a consistent database snapshot and removes tokens, private keys, credential references, and connection secrets. The ZIP manifest records that credentials were not included. Including artifacts adds artifact files but does not restore credentials. ### Using the API ```bash curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/instances/default/export/?includeArtifacts=false" \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/instances/default/export/?includeArtifacts=false" \ --output akoflow-instance.zip ``` @@ -115,22 +80,24 @@ The Desktop waits up to 90 seconds for the daemon after switching. When server-s ```bash curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/zip' \ --data-binary @akoflow-instance.zip \ - "$AKOFLOW_URL/instances/import/" + "$AKOFLOW_API_URL/instances/import/" \ + -o imported-instance.json || exit 1 + +SNAPSHOT_ID=$(jq -er '.id' imported-instance.json) || exit 1 curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/instances/" + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/instances/" -SNAPSHOT_ID='' curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -X POST "$AKOFLOW_URL/instance-activations/$SNAPSHOT_ID/" + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -X POST "$AKOFLOW_API_URL/instance-activations/$SNAPSHOT_ID/" ``` -Import accepts at most 8 GiB compressed data, at most 10,000 archive entries, and at most 64 GiB expanded data. Symbolic links and unsafe or unsupported archives are rejected with `422`. Activation returns `202 Accepted` with `instance` and a `restarting` boolean. +Import accepts at most 8 GiB compressed data, at most 100,000 archive entries, and at most 64 GiB expanded data. Symbolic links and unsafe or unsupported archives are rejected with `422`. Activation returns `202 Accepted` with `instance` and a `restarting` boolean. ## What read-only means @@ -145,9 +112,11 @@ with status `423 Locked`. The sole write exception is `POST /instance-activation ## Factory reset :::danger Permanent local deletion -Factory reset permanently removes the active AkôFlow catalog, environments, workflows, plans, runs, artifacts metadata, managed credentials and personal preferences. Export a snapshot first if any state must be retained. External SSH key files are retained only when they are outside the Engine-managed credential directory; the Desktop specifically notes that external SSH key files remain. +Factory reset deletes the active database catalog, including environments, workflows, plans, runs, artifact metadata, and saved credential references. It also removes the server-managed Kubernetes token directory. It does **not** remove SSH private-key files, saved cloud credential files, or artifact files from disk. Export a snapshot first if any catalog state must be retained, and remove retained files separately when retiring the instance. ::: +The Desktop reset also clears local storage in the current browser profile, including its preferences and saved API token. Calling the API directly does not clear browser storage or other profiles. The Desktop confirmation currently describes all managed credentials as removed; the server behavior above is the limit to rely on. + ### Using AkôFlow Desktop 1. Open **Settings → Danger zone**. @@ -158,8 +127,8 @@ Factory reset permanently removes the active AkôFlow catalog, environments, wor ```bash curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -X POST "$AKOFLOW_URL/factory-reset/" + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -X POST "$AKOFLOW_API_URL/factory-reset/" ``` -Success is `204 No Content`. The endpoint returns `503` when reset support is unavailable and `422` when the reset operation fails. It cannot run while a read-only snapshot is active because the read-only guard returns `423` first. +Success is `204 No Content`. The endpoint returns `503` when reset support is unavailable and `422` when the reset operation fails. The server clears the database before removing managed Kubernetes token files. If that file cleanup fails, a `422` can arrive after the catalog has already been cleared; inspect the instance before retrying. Reset cannot run while a read-only snapshot is active because the read-only guard returns `423` first. diff --git a/docs/docs/guides/operations/interactive-console.md b/docs/docs/guides/operations/interactive-console.md index 76ceb54d..68e6c209 100644 --- a/docs/docs/guides/operations/interactive-console.md +++ b/docs/docs/guides/operations/interactive-console.md @@ -1,18 +1,18 @@ --- -title: Interactive console and commands +title: Use the interactive console description: Run one-shot remote commands and open streamed terminal sessions on AkôFlow resources. --- import {ConnectionPath, TerminalPanelGuide} from '@site/src/components/InfrastructureWalkthrough'; -# Interactive console and commands +# Use the interactive console -AkôFlow exposes two related mechanisms: +Use the console to inspect a connected resource or run a short diagnostic command. Choose the action that fits the task: - a **console command** runs one command, records stdout, stderr and exit status, and returns a durable command record; -- an **interactive session** opens a remote terminal owned by the Engine and streams terminal bytes over WebSocket. +- an **interactive session** opens a remote terminal for a longer conversation. -Both resolve the selected resource to a runtime and connection. They are operational access paths and produce audit events. +Both require a resource configured for interactive access and a working connection. AkôFlow records these operations in the audit trail. @@ -26,43 +26,43 @@ Both resolve the selected resource to a runtime and connection. They are operati -The panel polls active sessions every three seconds. Switching tabs closes only the local WebSocket for the previous view; it does not intentionally close that remote session. If the active stream disappears unexpectedly, Desktop requests session closure so the remote terminal is not left consuming resources. +Switching tabs keeps the remote session open. Use **Close session** when you finish. If the active stream disappears unexpectedly, Desktop requests closure; check the session list before opening a replacement. ### When the terminal action is unavailable -The action appears only after AkôFlow can resolve all three layers: a resource, a runtime binding that supports interactive execution, and a usable connection/credential. Check the resource health and binding first. For an HPC cluster, select the login node rather than an abstract cluster or a batch-only partition. For a proxied site, the daemon must use the connection that contains the proxy route. +The action appears only for a resource configured for interactive access with a usable connection and credential. Check the resource and connection health first. For an HPC cluster, select the login node rather than the cluster or a batch-only partition. For a proxied site, use the connection with the proxy route. ## Open and manage a session through the API +Complete [API connection setup](/docs/tutorials/api-access) first. +Choose an interactive-capable resource in Desktop and use its saved ID below. Keep these commands in the same Bash session. + ```bash -export AKOFLOW_URL='http://127.0.0.1:/akoflow-api' -export AKOFLOW_TOKEN='' +read -r -p 'Interactive resource ID: ' AKOFLOW_CONSOLE_RESOURCE_ID || exit 1 +[ -n "$AKOFLOW_CONSOLE_RESOURCE_ID" ] || exit 1 -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H 'Content-Type: application/json' \ - -X POST "$AKOFLOW_URL/console-sessions/" \ - -d '{"resourceId":"hpc-login","actorId":"researcher@example.org"}' +jq -n --arg id "$AKOFLOW_CONSOLE_RESOURCE_ID" '{resourceId:$id}' | \ + curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' \ + --data-binary @- "$AKOFLOW_API_URL/console-sessions/" \ + -o console-session.json || exit 1 + +SESSION_ID=$(jq -er '.id' console-session.json) || exit 1 ``` -The created session has `starting`, `connected`, `closed`, or `failed` status and returns the resolved `runtimeId` and `connectionId`. `resourceId` is required. Creation returns `422` when resolution or terminal startup fails and `503` when interactive console support is unavailable. +A successful creation returns a `connected` session with its resolved `runtimeId` and `connectionId`. The command saves that response in `console-session.json` and sets `SESSION_ID` for the following requests. `resourceId` is required. Creation returns `422` when resolution or terminal startup fails and `503` when interactive console support is unavailable. Session records can later be `closed` or `failed`. -List and close sessions: +List sessions while you work: ```bash -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/console-sessions/" - -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -X DELETE "$AKOFLOW_URL/console-sessions/$SESSION_ID/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/console-sessions/" ``` -Closure succeeds with `204 No Content`; an unknown session returns `404`. - ### Stream protocol -Connect a WebSocket client to: +Connect a WebSocket client to the daemon, replacing the port and session ID with your values (`SESSION_ID` holds the ID returned above): ```text ws://127.0.0.1:/akoflow-api/console-sessions//stream/ @@ -80,51 +80,59 @@ Download the archived session log: ```bash curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/console-sessions/$SESSION_ID/log/" \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/console-sessions/$SESSION_ID/log/" \ --output "akoflow-$SESSION_ID.log" ``` The response is UTF-8 text. A missing session log returns `404`; unavailable console support returns `503`. +Close the session when finished: + +```bash +curl --fail-with-body -X DELETE \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/console-sessions/$SESSION_ID/" +``` + +Closure succeeds with `204 No Content`; an unknown session returns `404`. + ## Run a one-shot command -The current Desktop focuses on the interactive terminal. Use the HTTP API for repeatable one-shot diagnostics: +The current Desktop focuses on the interactive terminal. Use the same resource ID for a repeatable one-shot diagnostic through the API: ```bash -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ +jq -n --arg id "$AKOFLOW_CONSOLE_RESOURCE_ID" '{ + resourceId:$id, + command:"hostname && uname -a", + workingDirectory:"/tmp", + environment:{LC_ALL:"C"}, + cpuCores:1, + memoryBytes:268435456, + timeoutSeconds:30 +}' | curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' \ - -X POST "$AKOFLOW_URL/console-commands/" \ - -d '{ - "resourceId":"hpc-login", - "actorId":"researcher@example.org", - "command":"hostname && uname -a", - "workingDirectory":"/tmp", - "environment":{"LC_ALL":"C"}, - "cpuCores":1, - "memoryBytes":268435456, - "timeoutSeconds":30 - }' + --data-binary @- "$AKOFLOW_API_URL/console-commands/" ``` -`resourceId` and `command` are required. The default timeout is 30 seconds and the maximum is 3,600 seconds. The returned record has `running`, `completed`, or `failed` status and may include `stdout`, `stderr`, `exitCode`, `failure` and the provider `externalId`. +`resourceId` and `command` are required. The default timeout is 30 seconds and the maximum is 3,600 seconds. The request waits for the runner and returns a `completed` or `failed` record with `stdout`, `stderr`, `exitCode`, `failure`, and provider `externalId` when available. Check the record's `status`; HTTP `201 Created` alone does not mean the command succeeded. List recent commands: ```bash curl --get --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ --data-urlencode 'limit=50' \ - "$AKOFLOW_URL/console-commands/" + "$AKOFLOW_API_URL/console-commands/" ``` -Command creation returns `422` for an unknown/unbound resource, invalid input, an excessive timeout, or runner failure. It returns `503` if console commands are unavailable. +Command creation returns `422` for an unknown or unbound resource, missing input, or an excessive timeout. A runner failure is recorded as `status: failed` in the `201 Created` response. The route returns `503` if console commands are unavailable. ## Access and safety - Authorize the Engine-managed public key on every SSH hop before opening a session. -- Select a resource with a usable runtime binding and connection. A resource existing in inventory is not by itself sufficient. +- Select a resource configured for interactive access with a working connection. An inventory record alone is not sufficient. - Imported instance snapshots are read-only; opening, writing to, or closing a session is blocked with `423 Locked`. - Terminal logs may contain command output and secrets printed by programs. Treat exported logs as sensitive operational data. - Close sessions when finished; closing the detail page alone does not close a daemon-owned session. diff --git a/docs/docs/guides/operations/personal-preferences.md b/docs/docs/guides/operations/personal-preferences.md new file mode 100644 index 00000000..b3e88682 --- /dev/null +++ b/docs/docs/guides/operations/personal-preferences.md @@ -0,0 +1,34 @@ +--- +title: Set personal preferences +description: Change the Desktop theme and graph animation for one browser profile. +--- + +# Set personal preferences + +Use this guide to change AkôFlow Desktop's theme and graph animation. For the API commands below, complete [API connection setup](/docs/tutorials/api-access) first. + +Preferences belong to a browser-profile client ID rather than a user account. Desktop saves changes locally and tries to synchronize them with the server. Your choices remain available in that browser when the server is offline. + +## Using AkôFlow Desktop + +1. Open **Settings → General**. +2. Select **Light** or **Dark**. +3. Turn **Graph animation** on or off. + +## Using the API + +The client ID must contain 8–128 characters. The only accepted themes are `light` and `dark`. + +```bash +CLIENT_ID='docs-client-01' + +curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' \ + -X PUT "$AKOFLOW_API_URL/user-preferences/$CLIENT_ID/" \ + -d '{"theme":"dark","animationsEnabled":false}' + +curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/user-preferences/$CLIENT_ID/" +``` diff --git a/docs/docs/guides/operations/search-and-notifications.md b/docs/docs/guides/operations/search-and-notifications.md index 90dfe96e..0ff1896f 100644 --- a/docs/docs/guides/operations/search-and-notifications.md +++ b/docs/docs/guides/operations/search-and-notifications.md @@ -1,119 +1,13 @@ --- -title: Search and notifications -description: Find control-plane entities and follow long-running operations in AkôFlow Desktop. +title: Choose search or notifications +description: Find a saved record or return to a recent Desktop operation. --- -# Search and notifications +# Choose search or notifications -Global search is backed by the Engine catalogs. Notifications are a Desktop convenience built by tracking operations and polling their existing APIs; there is no notification collection endpoint. +| Need | Open | +| --- | --- | +| Find a workflow, run, environment, or other saved record | [Find a record](/docs/guides/operations/find-records) | +| Return to an operation started in this Desktop profile | [Follow operation notifications](/docs/guides/operations/follow-notifications) | -## Search from Desktop - -1. Focus **Search AkôFlow** in the top bar, press `/`, or press `⌘K`/`Ctrl+K`. -2. Enter an ID, name, state or other indexed value. -3. Select a result, or press Enter to open the first result. -4. Press Escape to close search. - -With an empty query, the field filters quick navigation destinations. A non-empty query waits 220 ms, queries the Engine and shows entity results. Each result includes a direct interface path, so selecting it opens the corresponding detail or filtered list page. - -Search covers: - -| Type | Representative indexed values | -|---|---| -| `workflow` | ID, external ID, name, namespace | -| `execution` | ID, title, resource/runtime IDs, failure and status | -| `artifact` | ID, name and version | -| `environment` | ID, name, description and status | -| `resource` | ID, name, provider, region, zone and type | -| `plan` | ID, algorithm, objective, workflow version and scope | -| `scope` | ID, name, topology and environment versions | -| `materialization` | ID, variant, digest, resource, run, activity, path and status | - -The Engine ranks an exact field match above a prefix match, which ranks above a substring match. Results with equal score preserve catalog order. - -## Search through the API - -```bash -export AKOFLOW_URL='http://127.0.0.1:/akoflow-api' -export AKOFLOW_TOKEN='' - -curl --get --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - --data-urlencode 'q=science' \ - --data-urlencode 'types=workflow,execution,artifact' \ - --data-urlencode 'limit=20' \ - "$AKOFLOW_URL/search/" -``` - -The response shape is: - -```json -{ - "query": "science", - "results": [ - { - "type": "workflow", - "id": "science-workflow", - "title": "Science workflow", - "subtitle": "default", - "path": "/workflows/science-workflow", - "score": 0.9 - } - ], - "total": 1 -} -``` - -`limit` defaults to 30 and is capped at 100. Omit `types` to search every supported type. Unknown type names are ignored; if every supplied name is unknown, the result is empty. An empty `q` returns an empty result without loading catalogs. A catalog failure returns `500 Internal Server Error`. - -## Follow operation notifications - -The bell in the top bar reports completed or terminal states for operations started in this Desktop profile: - -- planning sessions; -- executions; -- artifact builds; -- interactive terminals; -- cloud provisioning; -- Desktop application updates. - -Select an operation notification to mark it read and open its associated page. Use the check control to mark all current items read. The center retains at most 40 entries. - -Tracked operations are polled every five seconds. A notification is created when a tracked operation reaches `completed`, `failed`, `cancelled`, `closed`, `ready`, or `destroyed`, depending on its type. A terminal disappears from the active-session list when closed, which completes its tracked notification. - -:::note Profile-local state -Notification entries and the list of tracked operations live in browser local storage. They are not audit or provenance records, do not synchronize between Desktop profiles, and may disappear when site data is cleared. Use **Audit**, execution details, planning details, or build details for durable operational evidence. -::: - -Native operating-system notifications are emitted only when the browser/renderer exposes the Notification API and permission has already been granted. The current interface does not prompt for notification permission. - -## API equivalents - -There is no `/notifications/` endpoint. Automation should query the resource that owns the operation: - -```bash -# Planning session -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/planning-sessions/$PLANNING_SESSION_ID/" - -# Execution run -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/execution-runs/$RUN_ID/" - -# Active interactive sessions -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/console-sessions/" - -# Provisioned cloud instances for one environment -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/environments/$ENVIRONMENT_ID/cloud-instances/" -``` - -For a durable cross-domain timeline, query `/audit-events/` with the appropriate execution, session, connection, resource or environment filter. - -## When results do not appear - -- Wait until at least one non-whitespace character is entered; an empty server query deliberately returns no entities. -- Search only returns records visible through the same catalogs as their list pages. -- A red error message means the Engine request failed; verify the API token and daemon, then retry. -- Notifications only cover operations started and tracked by the current Desktop profile. Opening the app after an operation was started elsewhere does not reconstruct a notification history. +Notifications are local to the Desktop profile. For a lasting status, open the operation's detail page. [Audit events](/docs/guides/data/audit-events) cover connection checks, resource discovery, and console actions, but not every notified operation. diff --git a/docs/docs/guides/operations/server-instance.md b/docs/docs/guides/operations/server-instance.md index 73ff2592..32b13d02 100644 --- a/docs/docs/guides/operations/server-instance.md +++ b/docs/docs/guides/operations/server-instance.md @@ -2,20 +2,20 @@ id: server-instance title: Run the AkôFlow server on a Linux instance sidebar_label: Server on an instance -description: Install the AkôFlow control plane from a versioned Release on a trusted Linux instance. +description: Install the AkôFlow server from a versioned Release on a trusted Linux instance. --- # Run the AkôFlow server on a Linux instance -Use this how-to when an operator needs an AkôFlow control plane on a trusted -Linux instance, rather than the local control plane installed by AkôFlow -Desktop. It loads the daemon and BuildKit images directly from a versioned +Use this how-to when an operator needs an AkôFlow server on a trusted +Linux instance, separate from the local server installed by AkôFlow +Desktop. It loads the server and BuildKit images directly from a versioned GitHub Release. It does not use a container registry and it does not install the Desktop application. -Use [Install AkôFlow](../../installation) for a personal workstation. Do not +Use [Install AkôFlow](/docs/installation) for a personal workstation. Do not use this procedure for an untrusted or multi-tenant host: the supplied Compose -configuration gives the control plane access to the host Docker socket and runs +configuration gives the server access to the host Docker socket and runs BuildKit with Docker privileges. ## Before you begin @@ -34,7 +34,7 @@ You need: This guide keeps the API bound to `127.0.0.1` on the instance. Reach it through an SSH tunnel or terminate TLS at a separately managed reverse proxy. Do not change the port mapping to `0.0.0.0` merely to make it convenient: bearer-token -authentication protects operations, but the service is a control plane with +authentication protects operations, but the server has access to Docker, workflow credentials, and execution targets. The release must contain matching daemon and BuildKit archives for the instance @@ -64,7 +64,7 @@ akoflow-buildkit--linux-.tar akoflow-runtime--linux-.sha256 ``` -The [Downloads and Releases](../../downloads) page explains the relationship +The [Downloads and Releases](/docs/downloads) page explains the relationship between the Git tag and published artifacts. This procedure deliberately uses the two runtime archives; it does not look for a package or a registry image. @@ -107,7 +107,7 @@ docker image inspect \ The last command must print both versioned image tags. The Compose stack uses only those local tags, so it cannot silently pull a newer image. -## 3. Configure the local control plane +## 3. Configure the local server Download the versioned Compose file supplied with this documentation: @@ -117,8 +117,8 @@ curl --fail-with-body --location --remote-name \ "https://akoflow.com/examples/server-instance/compose.yaml" ``` -Create a private `.env` file. Generate the bearer token on the instance and -store it in the operator's password manager; it is required by every +Create a private `.env` file. Create a long random bearer token in the +operator's password manager, then enter it below; it is required by every operational API request. The shell commands below avoid putting the token in the shell history. @@ -134,7 +134,7 @@ unset AKOFLOW_API_TOKEN The Compose file persists SQLite, managed credentials, simulation workspaces, artifacts, and BuildKit state in named Docker volumes. It disables the interactive console. It also mounts `/var/run/docker.sock`; retain that mount -only on a trusted host where the control plane is allowed to create local +only on a trusted host where the server is allowed to create local containers. If a trusted browser client must call this server directly, set @@ -157,6 +157,7 @@ The server's public preflight endpoint reports the server and local dependency state without exposing operational data: ```bash +set -o pipefail curl --fail-with-body --silent http://127.0.0.1:8080/akoflow-api/preflight/ | jq . ``` @@ -164,6 +165,7 @@ Check that `server.available` is `true`. Then prove that the bearer token is accepted for an operational request: ```bash +set -o pipefail read -r -s -p "AkôFlow API token: " AKOFLOW_API_TOKEN printf '\n' curl --fail-with-body --silent \ @@ -180,21 +182,23 @@ For an operator working from another machine, use a tunnel rather than exposing the API port: ```bash -ssh -N -L 8080:127.0.0.1:8080 @ +read -r -p "SSH user: " AKOFLOW_SSH_USER +read -r -p "Instance hostname: " AKOFLOW_SERVER_HOST +ssh -N -L 8080:127.0.0.1:8080 "${AKOFLOW_SSH_USER}@${AKOFLOW_SERVER_HOST}" ``` Run the same `curl` commands against your local `127.0.0.1:8080` while the -tunnel is open. Continue with the [API overview](../../reference/api-overview) -or register infrastructure and execute the [first simulated workflow](../workflows/first-run). +tunnel is open. Continue with the [API overview](/docs/reference/api-overview) +or register infrastructure and execute the [first simulated workflow](/docs/guides/workflows/first-run). ## Operate, update, and remove -Use the exact same steps with a newer release tag to update: download and -verify its archives, load its versioned images, change only -`AKOFLOW_RELEASE_TAG` in `.env`, then run `docker compose -f compose.yaml up -d`. +To update, download and verify the archives for the newer release, then load +its versioned images. Change only `AKOFLOW_RELEASE_TAG` in `.env` and run +`docker compose -f compose.yaml up -d`. The named volumes remain attached, so plans, runs, artifacts, and managed credentials are retained. Export the instance before changing versions if you -need an additional recovery point; see [Instance management](./instance-management). +need an additional recovery point; see [Instance management](/docs/guides/operations/instance-management). To stop the services while retaining their state: @@ -218,4 +222,4 @@ akoflow`. | A request needs browser CORS access | Configure only the exact trusted origin in `AKOFLOW_API_ALLOWED_ORIGINS`; do not use a wildcard or expose the API port directly. | For server logs, Docker/BuildKit diagnostics, and network checks, see -[Troubleshooting](./troubleshooting). +[Troubleshooting](/docs/guides/operations/troubleshooting). diff --git a/docs/docs/guides/operations/troubleshooting.md b/docs/docs/guides/operations/troubleshooting.md index 7b481620..7e53e898 100644 --- a/docs/docs/guides/operations/troubleshooting.md +++ b/docs/docs/guides/operations/troubleshooting.md @@ -1,53 +1,46 @@ --- -title: Troubleshooting +title: Troubleshoot AkôFlow description: Diagnose daemon access, authentication, connection, discovery, planning, execution, storage, and snapshot problems. --- import useBaseUrl from '@docusaurus/useBaseUrl'; -# Troubleshooting +# Troubleshoot AkôFlow -Start at the first failing boundary. Desktop is a client of the Engine API; the Engine then talks to Docker/BuildKit, runtimes, remote connections, storage and cloud providers. +Start with the first step that failed: opening Desktop, reaching the AkôFlow server, connecting an environment, or running a workflow. Check that step before changing later settings. -Troubleshoot from the Desktop through the Engine API, credentials and connections, then the runtime or provider and workload or data. +Troubleshoot from the Desktop through the AkôFlow server API, credentials and connections, then the runtime or provider and workload or data. -Set the endpoint and token before using the checks below: +For the command-line checks below, complete [API connection setup](/docs/tutorials/api-access) first. -```bash -export AKOFLOW_URL='http://127.0.0.1:' -export AKOFLOW_TOKEN='' -``` - -## 1. Check the Engine and prerequisites +## 1. Check the server and prerequisites -The root endpoint is the basic health check: +The root endpoint is the basic authenticated health check: ```bash -curl --fail-with-body "$AKOFLOW_URL/" +curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "${AKOFLOW_API_URL%/akoflow-api}/" ``` -Then run the authenticated preflight: +Then run the public preflight: ```bash -curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/akoflow-api/preflight/" +curl --fail-with-body "$AKOFLOW_API_URL/preflight/" ``` The first-run Desktop screen performs this check before environment onboarding. It reports the AkôFlow daemon, host Docker daemon, and BuildKit readiness exposed by the current runtime. -If Desktop shows **Instance identity unavailable**, the Engine did not provide `/instance/`. Confirm that the current matching Engine container/version is running, inspect its logs, and retry. Do not create an identity manually just to hide a startup failure; the Engine creates it from the hostname. +If Desktop shows **Instance identity unavailable**, the server did not provide `/instance/`. Confirm that the matching server container is running, inspect its logs, and retry. The server creates its identity from the hostname. ## 2. Fix authentication -`401 Unauthorized` or `403 Forbidden` means the API token is missing or rejected. +For direct API calls, `401 Unauthorized` usually means a missing or invalid bearer token. Set `AKOFLOW_API_TOKEN` to the token configured for the daemon and retry with `Authorization: Bearer `. -1. Open **Settings → General → API access token**. -2. Paste the token configured for this Engine and select **Save token**. -3. Retry the protected request. +The packaged Desktop manages its own local API connection; you do not need to paste its token into the application. In a separate web development client, **Settings → General → API access token** can supply a token for that client. A `403 Forbidden` response can also mean the request is outside a loopback-only access boundary; check the daemon listen address and caller location before changing credentials. -For API calls, send `Authorization: Bearer `. Avoid putting the token in URLs, screenshots, workflow files or shell history committed to source control. +Avoid putting tokens in URLs, screenshots, workflow files, or committed shell history. ## 3. Recognize read-only mode @@ -55,8 +48,8 @@ If a write returns `423 Locked` with `the selected instance is a read-only snaps ```bash curl --fail-with-body \ - -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -X POST "$AKOFLOW_URL/akoflow-api/instance-activations/default/" + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -X POST "$AKOFLOW_API_URL/instance-activations/default/" ``` The daemon may restart. Desktop waits up to 90 seconds; a temporary connection failure is expected during that restart. @@ -75,11 +68,13 @@ Test the credential and endpoint first, then health, then discovery. A healthy c Typical SSH causes are an unauthorized public key, wrong user/port, missing gateway authorization, invalid proxy command, or a key assigned to a different connection. Open **Settings → SSH service keys**, verify the assigned badge and fingerprint, and authorize the displayed public key on every hop. -For historical evidence: +For historical evidence, enter the saved connection ID shown in the environment detail or returned by the registration API: ```bash -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/akoflow-api/environment-connections/$CONNECTION_ID/history/?limit=20" +read -r -p 'Connection ID: ' CONNECTION_ID || exit 1 +[ -n "$CONNECTION_ID" ] || exit 1 +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/environment-connections/$CONNECTION_ID/history/?limit=20" ``` ## 5. Diagnose search and missing data @@ -91,15 +86,15 @@ curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ ## 6. Diagnose terminal access -An interactive terminal needs a resource that resolves to a usable runtime and connection. If opening fails: +An interactive terminal needs a resource configured for interactive access and a working connection. If opening fails: -1. verify the resource exists and has a runtime binding; +1. verify the resource exists and supports interactive access; 2. verify its connection health; 3. verify SSH key assignment and remote authorization; 4. check **Audit** for `console.*` events; 5. retry only after correcting the underlying connection. -`503 interactive console is unavailable` means the Engine was started without terminal support. `422` indicates request/resource/connection/startup failure. `404` on close or log means the session is unknown or its archived log is unavailable. +`503 interactive console is unavailable` means the server was started without terminal support. `422` indicates request/resource/connection/startup failure. `404` on close or log means the session is unknown or its archived log is unavailable. If a WebSocket works over HTTP but not through a reverse proxy, confirm that the proxy supports WebSocket upgrade and preserves the configured origin/authentication boundary. @@ -107,7 +102,7 @@ If a WebSocket works over HTTP but not through a reverse proxy, confirm that the Storage controls are disabled when the selected storage is unhealthy/offline/unauthorized or when its advertised capabilities do not allow the operation. A read-only storage can be browsed/downloaded when healthy but cannot accept upload, copy, rename, removal or other writes. -Check the environment connection before treating a storage error as a file-path problem. Browsing is restricted to roots approved by discovery/configuration; paths outside them are rejected by the Engine. +Check the environment connection before treating a storage error as a file-path problem. Browsing is restricted to roots approved by discovery/configuration; paths outside them are rejected by the server. ## 8. Diagnose planning and execution @@ -119,7 +114,7 @@ For execution: 2. inspect its failure reason, resolved resource/runtime and logs; 3. compare planned and observed transfer, queue and execution timing; 4. check artifact materialization and storage health; -5. correlate IDs and timestamps in **Audit** and **Provenance**. +5. use **Provenance** to follow the run's scientific records; check **Audit** only if a connection check, resource discovery, or console action may explain the failure. Do not assume an HTTP `202 Accepted` means a long-running operation completed; it means the operation was queued or accepted. Follow its detail endpoint until a terminal state. @@ -129,31 +124,31 @@ Import returns `422` for an invalid ZIP, unsupported manifest/version, missing r If switching says the daemon did not return: -- wait for the Engine container to become healthy; +- wait for the server container to become healthy; - call `/instances/` and verify which item is `active`; - restart the daemon manually when the activation response had `"restarting":false`; - return to `default` through the activation endpoint if the snapshot cannot open. ## 10. Gather evidence safely -Collect IDs, timestamps, status/failure fields, relevant execution logs, connection health history, audit events and provenance queries. Redact Bearer tokens, private keys, provider credential JSON, sensitive environment variables and secrets printed by commands. +Collect IDs, timestamps, failure details, and the run or operation logs for the failed step. For connection checks, discovery, or console actions, include the relevant Audit events. Use Provenance for workflow and data evidence. Redact bearer tokens, private keys, provider credentials, and secrets printed by commands. Useful endpoints: ```bash -# Durable operational events -curl --get -H "Authorization: Bearer $AKOFLOW_TOKEN" \ +# Failed connection, discovery, and console events +curl --fail-with-body --get -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ --data-urlencode 'outcome=failed' \ --data-urlencode 'limit=100' \ - "$AKOFLOW_URL/akoflow-api/audit-events/" + "$AKOFLOW_API_URL/audit-events/" # Available instance modes -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/akoflow-api/instances/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/instances/" -# Current Engine identity -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/akoflow-api/instance/" +# Current server identity +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/instance/" ``` -Factory reset is a last resort, not a diagnostic step. Export a sanitized snapshot first and use reset only when loss of local control-plane state is intentional. +Factory reset is a last resort, not a diagnostic step. Export a sanitized snapshot first and use reset only when deleting local AkôFlow data is intentional. diff --git a/docs/docs/guides/workflows/definitions.md b/docs/docs/guides/workflows/definitions.md index b5050b5e..7c518613 100644 --- a/docs/docs/guides/workflows/definitions.md +++ b/docs/docs/guides/workflows/definitions.md @@ -1,29 +1,13 @@ --- -title: Workflow definitions +title: Define a workflow +description: Create a workflow, inspect its activities, and import a definition. --- -# Workflow definitions +# Define a workflow -A workflow definition is the reusable description of a scientific computation. AkôFlow stores a stable definition and an immutable, versioned graph of activities. Plans and runs refer to the workflow **version ID**, so a past execution remains traceable to the graph that produced it. +A workflow lists the activities in a scientific computation and the order in which they run. AkôFlow saves versions of that definition, so a plan or past run always points to the workflow version it used. -The authoring format is intentionally smaller than the persisted domain model. AkôFlow normalizes activity names into IDs, creates the first workflow version, expands dependencies, converts CPU and memory limits, and records execution capabilities. - -## The activity model - -An activity has a `kind`, one or more `capabilities`, a command, resource requirements, a retry/timeout policy, and optional simulation or service settings. - -| Field | Meaning | -| --- | --- | -| `kind` | `task`, `service`, or `interactive` in the persisted model. Portable workflow imports currently create `task` activities. | -| `capabilities` | The modes the activity supports: `real`, `simulation`, or `interactive`. | -| `command` | Executable reference, entrypoint, arguments, environment, and working directory. | -| `resources` | Normalized CPU, memory, storage, and optional GPU demand. In portable input, use `cpuLimit` and `memoryLimit`. | -| `simulation` | Model, duration, FLOPs, and optional parameters. Supplying it makes a portable activity simulation-capable. | -| `policy` | Timeout, maximum attempts, and retry delay in the persisted model. | -| `dependsOn` | Control dependencies, written with activity names in portable input. | -| `dataDependencies` | Producer-to-consumer data edges with a logical name and byte size. | - -For real execution, an activity needs `command.entrypoint` and `command.executable`. An executable can point to an OCI image or another supported artifact source and includes a delivery strategy. The legacy `spec.image`, activity `image`, and `run` shorthands are still accepted, but new definitions should prefer `command` and `command.executable`. +You can create one in Desktop or import portable YAML. Start with the steps below; use the [workflow specification](/docs/internal/workflow-spec) when you need exact fields, limits, and compatibility rules. ## Using AkôFlow Desktop @@ -42,17 +26,14 @@ The import action accepts the same portable YAML format as the API. Export remov ## Using the API -Set the API address and, when API authentication is enabled, its bearer token: +Complete [API connection setup](/docs/tutorials/api-access) before running these commands. -```bash -export AKOFLOW_API_URL="http://127.0.0.1:/akoflow-api" -export AKOFLOW_API_TOKEN="" -``` +In portable YAML, each activity names its command, CPU and memory limits, dependencies, and any simulation model. For real execution, `command.entrypoint` and `command.executable` are required. An executable can point to an OCI image or another supported artifact source. The older `spec.image`, activity `image`, and `run` shorthands remain accepted, but new definitions should use `command` and `command.executable`. -The simulation example in `examples/simulation/workflow.yaml` uses the legacy shorthand. This equivalent command-oriented definition shows the preferred portable shape: +The checked-in SimGrid example uses legacy shorthand. To try the portable simulation fields directly, save this as `workflow.yaml`. The empty `command` means these activities are simulation-only; a real run needs an executable and entrypoint as described in the [workflow specification](/docs/internal/workflow-spec). ```yaml -name: simulation-example-workflow +name: portable-simulation-demo spec: namespace: examples activities: @@ -87,21 +68,21 @@ Useful definition operations are: ```bash # List definitions -curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ "$AKOFLOW_API_URL/workflow-definitions/" # Read one definition -curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ - "$AKOFLOW_API_URL/workflow-definitions/simulation-example-workflow/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/workflow-definitions/portable-simulation-demo/" # Export portable YAML -curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -o exported-workflow.yaml \ - "$AKOFLOW_API_URL/workflow-definitions/simulation-example-workflow/export/" + "$AKOFLOW_API_URL/workflow-definitions/portable-simulation-demo/export/" ``` -The create response is the normalized `WorkflowDefinition`. Use `version.id` from that response when creating a planning session. +The create response contains the saved definition. Use its `version.id` when creating a planning session. ## Next step -Once the workflow, execution scope, resources, and network topology exist, [create a planning session](./planning.md). +Once the workflow, execution scope, resources, and network topology exist, [create a planning session](/docs/guides/workflows/planning). diff --git a/docs/docs/guides/workflows/executions.md b/docs/docs/guides/workflows/executions.md index 455afaff..77305577 100644 --- a/docs/docs/guides/workflows/executions.md +++ b/docs/docs/guides/workflows/executions.md @@ -1,30 +1,32 @@ --- title: Execute and monitor a workflow +description: Start a saved plan, follow its activities, and inspect the run's observations. --- # Execute and monitor a workflow -An execution run applies one immutable schedule plan to the workflow and infrastructure snapshots supplied in its request. Real and simulated runs share the same run, activity, timing, transfer, and cost model, which makes planned-versus-observed comparison possible. +Start a run from a saved plan, follow its activities, and inspect the result. AkôFlow keeps the plan's predictions beside the run's observations so you can compare them when the runtime reports enough data. -## Modes and run types +For the API commands on this page, complete [API connection setup](/docs/tutorials/api-access) first. -- **Real** runs dispatch activities through execution runtimes such as a Kubernetes or SLURM adapter configured by the environment. -- **Simulation** runs dispatch simulation-capable activities through a simulation runtime such as SimGrid. -- **Interactive** sessions open a terminal against a compatible resource. They are represented in the unified run history, but are opened through the console-session API rather than the planned workflow execution request. +## Choose real execution or simulation -The run history distinguishes `workflow`, `interactive`, and `standalone` kinds. +- **Real** runs send activities to resources configured for execution, such as the local machine, Kubernetes, or SLURM. +- **Simulation** runs evaluate a workflow with a simulation environment such as SimGrid. + +To open a terminal on one resource, follow the [interactive console guide](/docs/guides/operations/interactive-console). Terminal sessions also appear in the run history, but they do not start from a workflow plan. ## Status and timing -A workflow run moves through `created`, `running`, and either `completed` or `failed`. Its activities expose the more detailed states `blocked`, `ready`, `preparing`, `running`, `completed`, `failed`, and `cancelled`. +A submitted execution first enters the queue. When AkôFlow starts it, the workflow run becomes `running`, then `completed` or `failed`. The current supervisor records activities as `running`, `completed`, or `failed`; other task states exist in the model but are not a normal progression to wait for. -Runtime handles distinguish `starting`, `running`, `completed`, `failed`, and `stopped`. For real runtimes, submitted time means the control plane handed work to the runtime; started time means the runtime allocated it; container-started time marks when user code could begin inside the container. +For real runs, submitted time marks when AkôFlow handed work to the runtime; started time marks when the runtime allocated it; container-started time marks when user code could begin inside the container. -The completed trace includes: +Depending on the runtime and available observations, the run detail can include: -- makespan and total cost; +- makespan and cost; - compute, transfer, queue, interference, and overhead time; -- activity placement and runtime handles; +- activity placement and runtime job identifiers; - transferred bytes, transfer duration/cost, strategy, and route; - observed task intervals alongside predicted assignments. @@ -46,11 +48,9 @@ The completed trace includes: *In the run detail, **Workflow makespan** is wall-clock completion time. **Accumulated stage time** is the sum of work attributed to stages across activities, so it can be greater than makespan when activities overlap. The decomposition makes transfer, execution, queue, boot and interference visible instead of treating them as a single unexplained duration.* -To open an interactive terminal, use the console action for a compatible resource. The session appears with interactive runs in **Runs** and can be closed or have its log exported. - ## Using the API -`POST /execution-runs/` accepts a complete, reproducible execution envelope. The checked-in files `examples/simulation/execution-request.yaml` and `examples/kind/requests/execution-request.yaml` are canonical examples for simulation and real Kubernetes execution respectively. +`POST /execution-runs/` accepts a complete execution request. The command below assumes you have a v1.0.8 checkout and have registered the environment, scope, topology, workflow, and plan in the [SimGrid first-run tutorial](/docs/guides/workflows/first-run). For Kubernetes, use the separate [Kind example](/docs/showcase/kubernetes-real-execution) and its own execution request. ```bash curl --fail-with-body \ @@ -60,37 +60,25 @@ curl --fail-with-body \ "$AKOFLOW_API_URL/execution-runs/" ``` -The request contains `run`, `plan`, `workflow`, `executionScope`, `resources`, `runtimes`, runtime bindings, the network topology, and activity profiles. Submission is asynchronous and returns `202 Accepted` with the queued job. Read the run by the `run.id` in the request: +This example submits the saved SimGrid plan with the workflow and environment it uses. The [request reference](/docs/api/endpoints/executions/post-execution-runs) lists the full payload. Submission returns `202 Accepted` with a queued job; use the `run.id` from the example to read the run: ```bash -curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ "$AKOFLOW_API_URL/execution-runs/simulation-example-run-v1/" ``` -The detail response contains `run`, `activities`, `dataTransfers`, `handles`, and `events`; it can also include related infrastructure operations. List endpoints support the Desktop's run history and filters: - -```bash -curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ - "$AKOFLOW_API_URL/execution-runs/" -``` +A `404` immediately after submission can mean the queued request has not been +processed yet. Retry after a short wait. If the run never appears, check the +server log and the complete request: worker validation happens before the run +is saved, so an invalid queued request can fail without a run record. -Interactive terminals use the console endpoints: +The detail response contains `run`, `activities`, `dataTransfers`, `handles`, and `events`. It can also include infrastructure operations and saved data or artifact preparation records when those services are configured. List endpoints support the Desktop's run history and filters: ```bash -# Inspect available console commands and their required arguments -curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ - "$AKOFLOW_API_URL/console-commands/" - -# After opening a session, stream it with: -# GET /console-sessions//stream/ -# Close it with: -# DELETE /console-sessions// -# Export its log with: -# GET /console-sessions//log/ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/execution-runs/" ``` -Consult `GET /console-commands/` before constructing an open-session request because compatibility and arguments depend on the resources and runtimes registered in the instance. - ## Investigating a failure -Start with `run.failureReason`, then inspect the failed activity, its handle `failure`, exit code and log, and the ordered run events. If the activity remained in `preparing`, inspect executable/workspace preparation and transfer records before the runtime log. +Start with `run.failureReason`, then inspect the failed activity, its handle `failure`, exit code and log, and the ordered run events. If failure happened during preparation, inspect executable/workspace preparation and transfer records; a runtime log may not exist yet. diff --git a/docs/docs/guides/workflows/first-local-run.md b/docs/docs/guides/workflows/first-local-run.md new file mode 100644 index 00000000..c536698d --- /dev/null +++ b/docs/docs/guides/workflows/first-local-run.md @@ -0,0 +1,52 @@ +--- +title: Run your first workflow in Desktop +description: Create a one-activity local workflow, run it, and inspect its output file. +--- + +# Run your first workflow in Desktop + +This tutorial runs one activity on your local machine. You will create a workflow, choose where it runs, start it, and inspect the recorded output file and checksum. It uses the Desktop interface and does not require a cloud or HPC account. + +## Before you begin + +[Install AkôFlow Desktop](/docs/installation) and complete its first-start checkup. Docker must be available to your user, and Desktop must show **Connected**. The steps below were verified with the extracted v1.0.8 Linux Desktop package and its bundled runtime. A clean `apt` install and other platforms need their own check. + +## 1. Check your local environment + +Open **Infrastructure → Environments**. If the first-start checkup already created a local environment, open it. Otherwise, choose **New environment**, select **Local machine**, give it a name such as `Local check`, select **Test connection**, then **Save environment**. + +On the environment page, select **Check now**. Continue when **Local machine** shows **online**. This check also makes the local resource available for planning. + +## 2. Define a small workflow + +Open **Workflows → New workflow** and enter: + +| Field | Value | +| --- | --- | +| Workflow name | `First local check` | +| Activity name | `write-report` | +| Command | `printf 'Akoflow local check\n' > result.txt` | + +Leave the other activity settings at their defaults and select **Create workflow**. The workflow page should show one activity, `write-report`. + +## 3. Choose the local environment + +Open **Infrastructure → Execution scopes** and choose **New execution scope**. Name it `First local scope`, select your local environment, leave **Create the initial network topology** enabled, and select **Create execution scope**. A one-machine workflow needs no network links. + +## 4. Make and run a plan + +Return to the workflow and select **Generate plan**. Choose **Create manually**, then select `First local scope`. Select `write-report` in the activity graph and set: + +| Setting | Value | +| --- | --- | +| Runtime | Your local machine runtime | +| Expected execution time | `1` second | +| Machine / target | Your local machine resource | + +Select **Generate plan**. On the plan page, select **Execute plan**. Confirm that the execution mode is **Real execution** and the local runtime is listed, then select **Start execution**. + +## 5. Check the result + +Wait for the run to show **completed** and **1/1** activities settled. Open **Activities → write-report → Open activity details**. Expect **Exit code 0** and a **Generated files** row for `result.txt` with a SHA-256 checksum. That row records the file observed in the activity workspace; it does not mean Desktop downloaded the file to your computer. + +If the run fails, inspect the activity output on that page and use [Troubleshooting](/docs/guides/operations/troubleshooting). To understand how the plan and run records relate, read [Compare a plan with a completed run](/docs/explanations/evidence-and-provenance). To try scheduling alternatives or another target, continue with [Plan a workflow](/docs/guides/workflows/planning) and [Environments](/docs/guides/infrastructure/environments). For a reproducible simulation through a separately managed API, use the [SimGrid example](/docs/guides/workflows/first-run). diff --git a/docs/docs/guides/workflows/first-run.md b/docs/docs/guides/workflows/first-run.md index 2312bee3..f053904d 100644 --- a/docs/docs/guides/workflows/first-run.md +++ b/docs/docs/guides/workflows/first-run.md @@ -1,20 +1,20 @@ --- -title: Run your first simulated workflow +title: Run the SimGrid example through the API description: Register the checked-in SimGrid example, execute it, and verify computation and network evidence. --- -# Run your first simulated workflow +# Run the SimGrid example through the API -This tutorial is for a first-time AkôFlow user with a running local daemon. You will submit a three-activity workflow to SimGrid and verify that all activities and both data transfers completed. Nothing is dispatched to Kubernetes, SLURM, or a cloud account. +This tutorial is for a reader with a separately managed AkôFlow API endpoint. You will submit a three-activity workflow to SimGrid and verify that all activities and both data transfers completed. Nothing is dispatched to Kubernetes, SLURM, or a cloud account. -Use this tutorial to confirm a new installation. Do not use it to learn automatic scheduling—the example imports a fixed plan so that the first result is reproducible. Continue to [Plan a workflow](./planning.md) after this run succeeds. +The example imports a fixed plan so the first result is reproducible. After it succeeds, use [Plan a workflow](/docs/guides/workflows/planning) to compare automatic scheduling choices. ## Before you begin -You need Git, Bash, `curl`, `jq`, and a daemon with the SimGrid runner available. -Complete [API connection setup](../../tutorials/api-access) first, using a daemon +You need Git, Bash, `curl`, `jq`, and an AkôFlow server with the SimGrid runner available. +Complete [API connection setup](/docs/tutorials/api-access) first, using a server whose URL and token you manage. The graphical Desktop setup does not expose a -token for these commands; use the [server installation](../operations/server-instance) +token for these commands; use the [server installation](/docs/guides/operations/server-instance) if you need a separately managed API endpoint. Download the matching example source and enter its directory: @@ -28,7 +28,7 @@ If you already have a matching checkout, enter that repository instead. Run the commands below in the same Bash session where you configured `AKOFLOW_API_URL` and `AKOFLOW_API_TOKEN`. -Check the daemon before registering anything: +Check the server before registering anything: ```bash curl --fail-with-body \ @@ -36,7 +36,7 @@ curl --fail-with-body \ "$AKOFLOW_API_URL/preflight/" | jq ``` -Continue only when `server.available` is `true`. For this tutorial, the SimGrid runner must also be present in the daemon container or configured with `AKOFLOW_SIMGRID_BINARY`. +Continue only when `server.available` is `true`. For this tutorial, the SimGrid runner must also be present in the server container or configured with `AKOFLOW_SIMGRID_BINARY`. :::note Fresh identifiers The files use stable IDs such as `simulation-example` and `simulation-example-run-v1`. Run them against a fresh instance. If those IDs already exist, use another instance or change the IDs consistently across all six files; repeating only part of the sequence returns `422` or a foreign-key error. @@ -136,7 +136,7 @@ curl --fail-with-body \ "$AKOFLOW_API_URL/schedule-plans/" ``` -The plan assigns `prepare` and `summarize` to the edge and `analyze` to the cloud. The API reevaluates imported plans using the current model, so stored predicted cost or feasibility can differ from the values written in the source envelope. Treat the returned plan as authoritative. +The plan assigns `prepare` and `summarize` to the edge and `analyze` to the cloud. The API validates the assignments against the registered workflow, scope, topology, and resources, then saves the supplied predicted time, cost, and feasibility. It does not recalculate those predictions on this route. Compare them with the observations in the completed run. ## 5. Start the simulation @@ -218,16 +218,14 @@ sh examples/simulation/run.sh The script stops at the first HTTP failure. It does not erase or overwrite existing catalog objects. -## Follow the same path in Desktop +## Find the records in Desktop -The API sequence above is the verified reference path. The current Desktop exposes the same objects: +After the API sequence completes, Desktop can show its environment, workflow, plan, run, and results on the same server. These steps inspect those records; Desktop-only submission of the full bundle has not been verified. -1. Under **Infrastructure → Environments**, import or recreate the environment and confirm two resources plus the SimGrid runtime. -2. Under **Infrastructure → Execution scopes**, create the scope and associate the network topology. -3. Under **Workflows → Definitions**, choose **Import YAML** and select `workflow.yaml`. Open the workflow and confirm the three-node DAG. -4. Open the workflow's **Plans** tab and create the fixed assignment manually, or choose **Generate plan** to learn automatic planning separately. -5. Start the selected plan. Simulation mode is derived from the selected scope; there is no separate mode or seed choice in the start form. -6. Open the completed run and inspect **Activities**, **Timeline**, **Data**, and **Plan vs execution**. +1. Under **Infrastructure → Environments**, open `simulation-example` and confirm two resources plus the SimGrid runtime. +2. Under **Infrastructure → Execution scopes**, find the scope and its network topology. +3. Under **Workflows → Definitions**, open `simulation-example-workflow` and confirm the three-node DAG. +4. Open its plan and the completed run. Inspect **Activities**, **Timeline**, **Data**, and **Plan vs execution**. The run is complete only when the header says `completed` and the activity summary says `3/3 settled`. In **Data**, confirm the 100 MB edge-to-cloud dependency and the 20 MB return dependency. @@ -235,11 +233,11 @@ The run is complete only when the header says `completed` and the activity summa | Failure | Cause and recovery | | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `401 Unauthorized` | The daemon requires a token. Set `AKOFLOW_API_TOKEN` and keep the `Authorization` header. | +| `401 Unauthorized` | The server requires a token. Set `AKOFLOW_API_TOKEN` and keep the `Authorization` header. | | `422` while creating an object | The stable ID probably already exists, or an earlier dependency was not created. Use a fresh instance or update every related ID consistently. | | `FOREIGN KEY constraint failed` while creating the plan | An assignment activity ID does not match the registered workflow version. Use the complete files from the same repository revision. | | `akoflow-simgrid-runner: executable file not found` | Install/build the runner and set `AKOFLOW_SIMGRID_BINARY`, or use the server image that includes it. | | Completed run has zero transferred bytes | The workflow lacks data dependencies or producer and consumer were placed on the same resource. Recheck `workflow.yaml`, the plan assignments, and topology IDs. | -| Run remains `pending` | Inspect the run events and daemon log; the asynchronous command may have failed before the simulation process started. | +| Run remains `pending` | Inspect the run events and server log; the asynchronous command may have failed before the simulation process started. | -Next, use [the edge-to-cloud Showcase](../../showcase/edge-cloud-simulation) to inspect the same model visually, or [Plan a workflow](./planning.md) to compare PRISM Cost, PRISM Time, and HEFT. +Next, use [the edge-to-cloud Showcase](/docs/showcase/edge-cloud-simulation) to inspect the same model visually, or [Plan a workflow](/docs/guides/workflows/planning) to compare PRISM Cost, PRISM Time, and HEFT. diff --git a/docs/docs/guides/workflows/planning.md b/docs/docs/guides/workflows/planning.md index b1e14336..a4c5c8b4 100644 --- a/docs/docs/guides/workflows/planning.md +++ b/docs/docs/guides/workflows/planning.md @@ -1,61 +1,49 @@ --- title: Plan a workflow +description: Make a manual plan or compare scheduler candidates before execution. --- # Plan a workflow -Planning is separate from execution. A planning session freezes a workflow version and an infrastructure/network scope, runs one or more scheduling algorithms against the same inputs, and preserves their candidate plans for comparison. - -Only a selected candidate becomes a canonical schedule plan that can be executed. - -## Sessions, algorithms, and candidates - -A session records its workflow version, execution scope, network topology, selected algorithms, optional deadline and budget, progress, and final selection. Its status is `queued`, `running`, `completed`, `failed`, or `cancelled`. - -The Desktop currently offers PRISM time and cost objectives plus HEFT when those algorithms are returned by the server. Always use `GET /planning-algorithms/` as the authoritative list for an installed instance. PRISM accepts an option count and beam width; an optional directed interference matrix can also be attached to the session. HEFT does not use that matrix while planning. - -Each candidate reports: - -- algorithm, objective, and rank; -- Pareto-optimal/dominated and feasible flags; -- predicted makespan and cost; -- a complete schedule with activity-to-resource assignments. - -Assignments include predicted ready, start, finish, runtime, transfer time, cost, core/slot placement, and order on the resource. Plans can also contain infrastructure lifecycle actions when cloud capacity is involved. +Plan a workflow before starting execution. For a known placement, make a manual plan. To compare placements, choose a workflow version and execution scope, generate candidates, then select one as the schedule plan. ## Using AkôFlow Desktop 1. Open a workflow definition and choose **Generate plan**. Planning sessions are created from that workflow so the session stays bound to its immutable version. 2. Choose **Automatic planning**. 3. Select an execution or simulation scope and its network topology. -4. Select one or more algorithms. Configure PRISM search options if applicable. +4. Select the available algorithms you want to compare. Desktop offers PRISM Time, PRISM Cost, and HEFT when the server reports them. Set PRISM's option count or beam width if you want to change the search. 5. Optionally set a deadline, budget, or import an interference matrix. 6. Choose **Generate candidate plans**. 7. Follow each algorithm run's progress. Expand candidates to inspect their Gantt timelines and assignments. -8. Compare predicted time, cost, feasibility, and Pareto status, then select a candidate. AkôFlow creates the executable schedule plan from that candidate. +8. Inspect predicted time, cost, feasibility, and assignments, then select a candidate. HEFT and PRISM use different prediction models, so compare observed runs when you need evidence of which plan performs better. AkôFlow saves the selected schedule plan for execution. AkôFlow Desktop Create an execution plan screen in light mode, with generated and manual planning choices, a planning target selector, an execution scope, and PRISM Cost, PRISM Time, and HEFT controls. *Choose **Generate plans** to compare candidate schedules. The target selector keeps real execution scopes separate from simulation-only scopes; PRISM Cost and PRISM Time are exclusive objectives, while HEFT is a comparison baseline.* +The server's available algorithms are listed by `GET /planning-algorithms/`. A session may also include a deadline, budget, or directed interference matrix; HEFT does not use that matrix for its placement. See [PRISM and HEFT](/docs/explanations/prism-and-heft) for the prediction models and [planning states](/docs/reference/planning-and-execution-states) for candidate and session fields. + ### Manual plans Choose the manual planning mode when placement is known in advance. Select a scope and topology, then assign every activity to a compatible runtime and resource and provide its expected duration. The Desktop computes a dependency-aware schedule and submits the complete plan for validation. ### Imported plans -The plans API also accepts a complete plan as imported data. Imported IDs must refer to an existing workflow version, execution scope, topology, and resources; the server validates the plan before saving it. +The plans API also accepts a complete plan as imported data. Imported IDs must refer to an existing workflow version, execution scope, topology, and resources; the server validates the plan before saving it. That validation does not check runtime bindings. Confirm an enabled, mode-compatible binding for every assigned resource before starting execution. ## Using the API +Complete [API connection setup](/docs/tutorials/api-access) before running the commands below. + First discover the algorithms available in the running instance: ```bash -curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ "$AKOFLOW_API_URL/planning-algorithms/" ``` -Create an automatic planning session. The IDs below match the repository's simulation example: +Create an automatic planning session. The IDs below refer to the environment, scope, topology, and workflow registered in the [SimGrid first-run sequence](/docs/guides/workflows/first-run). Complete those registration steps first, or replace all four IDs with records from your own instance: ```bash curl --fail-with-body \ @@ -77,31 +65,69 @@ curl --fail-with-body \ "$AKOFLOW_API_URL/planning-sessions/" ``` -Creation returns `202 Accepted`. Poll the session and list its candidates: +Creation returns `202 Accepted`. Poll the session until its status is `completed`, then list its candidates. This lets you compare the final ranks: ```bash -curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ "$AKOFLOW_API_URL/planning-sessions/planning-simulation-example/" -curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ "$AKOFLOW_API_URL/planning-sessions/planning-simulation-example/candidates/" ``` -Read a candidate before selecting it, then promote it to a plan: +List the candidate IDs, choose one after comparing the candidates, and inspect it before selection: ```bash -curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ - "$AKOFLOW_API_URL/planning-sessions/planning-simulation-example/candidates//" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/planning-sessions/planning-simulation-example/candidates/" | jq -r '.[].id' + +read -r -p 'Candidate ID to select: ' AKOFLOW_CANDIDATE_ID || exit 1 +[ -n "$AKOFLOW_CANDIDATE_ID" ] || exit 1 + +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/planning-sessions/planning-simulation-example/candidates/$AKOFLOW_CANDIDATE_ID/" curl --fail-with-body -X POST \ -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ - "$AKOFLOW_API_URL/planning-sessions/planning-simulation-example/candidates//select/" + "$AKOFLOW_API_URL/planning-sessions/planning-simulation-example/candidates/$AKOFLOW_CANDIDATE_ID/select/" ``` -Selection returns `201 Created` with the canonical schedule plan. +Check the candidate's `feasible` field before selecting it. It indicates that the candidate passed plan validation, not that its runtime bindings are ready. Selection returns `201 Created` with the saved schedule plan. + +For a manual plan, send the complete validation envelope used by `examples/simulation/plan-request.yaml` to `POST /schedule-plans/`. To import an already assembled plan whose referenced objects are registered, send `{ "plan": ... }` to `POST /schedule-plans/import/`; the server sets its source to `imported` and validates it. These routes save the predicted metrics you supply rather than recalculating them. + +### Import a saved plan + +To try the import route, complete the [SimGrid first-run tutorial](/docs/guides/workflows/first-run) through **Register the fixed plan**. This reads that saved plan, gives the copy, its assignments, and its cloud lifecycle actions new IDs, and submits only the import envelope. Run it once per imported ID; use another ID if the copy already exists. + +```bash +set -o pipefail +AKOFLOW_IMPORTED_PLAN_ID='simulation-example-import-v1' + +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/schedule-plans/simulation-example-plan-v1/" | + jq --arg id "$AKOFLOW_IMPORTED_PLAN_ID" '{plan:( + .id = $id | + .assignments |= map(.id = ($id + "-" + .id) | .planId = $id) | + (.lifecycleActions //= []) | + .lifecycleActions |= map( + .id = ($id + "-" + .id) | + .schedulePlanId = $id | + (.dependsOn //= []) | + .dependsOn |= map($id + "-" + .) + ) + )}' | + curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + -H 'Content-Type: application/json' --data-binary @- \ + "$AKOFLOW_API_URL/schedule-plans/import/" \ + -o imported-plan.json || exit 1 + +jq '{id,source,predicted}' imported-plan.json +``` -For a manual plan, send the complete validation envelope used by `examples/simulation/plan-request.yaml` to `POST /schedule-plans/`. To import an already assembled plan whose referenced objects are registered, send `{ "plan": ... }` to `POST /schedule-plans/import/`; the server sets its source to `imported` and validates it. +Expect `source: "imported"` and the new ID. The copied lifecycle dependencies must point to the new action or assignment IDs; the command above updates those references too. ## Next step -Review the selected plan and [start and monitor an execution](./executions.md). +Review the selected plan and [start and monitor an execution](/docs/guides/workflows/executions). diff --git a/docs/docs/installation.md b/docs/docs/installation.md index d689e3a7..61610882 100644 --- a/docs/docs/installation.md +++ b/docs/docs/installation.md @@ -8,9 +8,8 @@ description: Download the correct Desktop package, open AkôFlow, and verify the import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -Install **AkôFlow Desktop** on your workstation. It starts a local daemon and -BuildKit using Docker and downloads matching runtime archives automatically. -You do not need a source checkout to install the application. +Install **AkôFlow Desktop** on your workstation. It uses Docker for its local +services and downloads the files it needs. You do not need a source checkout. ## Before you begin: prepare Docker @@ -30,21 +29,19 @@ docker info docker compose version ``` -Both commands must succeed **as the user who opens AkôFlow**. The first shows -Docker's server information; the second prints the Compose plugin version. +Both commands must succeed **as the user who opens AkôFlow**. On Linux, if access works only with `sudo`, follow Docker's [non-root access instructions](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user), then sign out of the desktop session and sign back in before checking again. Membership in the Docker group grants root-level privileges; use your site's approved setup. A new terminal alone does not refresh the launcher session. -Keep internet access available for the application and its runtime downloads. -You do not need Git, Go, Node.js, a cloud account, or an HPC account for this -installation. The command-line tutorials introduce their own prerequisites. +Keep internet access available for the first launch. Git, Go, Node.js, and +remote infrastructure accounts are not needed for local installation. ## 1. Download the correct file -Open [Downloads and releases](./downloads), choose your operating system, and +Open [Downloads and releases](/docs/downloads), choose your operating system, and save the linked file. Wait until the browser finishes downloading before opening it. The version in the filename must match the release tag. @@ -56,12 +53,15 @@ it. The version in the filename must match the release tag. | Other Linux x64 desktops | `.AppImage` | Same Docker prerequisites; allow the file to execute | The runtime has Linux ARM64 archives, but v1.0.8 does not include a Linux ARM64 -Desktop package. Use the [server installation](./guides/operations/server-instance) +Desktop package. Use the [server installation](/docs/guides/operations/server-instance) for a supported ARM64 server deployment. -**Expected result:** one completed Desktop package for your operating system. -If the browser reports an interrupted download, retry before opening the file. -For checksum verification, use the [download verification procedure](./downloads#download-through-the-github-api). +The Linux v1.0.8 package was opened from an extracted copy and completed a local +workflow. A clean `apt` install and first launch on macOS, Windows, or AppImage +remain unverified. + +If the download is interrupted, retry before opening the file. For a checksum, +use the [download verification procedure](/docs/downloads#download-through-the-github-api). ## 2. Install and open @@ -82,13 +82,9 @@ before allowing it to run. 1. Open `Akoflow-Desktop-1.0.8-win-x64.exe` from the browser's download list. -2. Follow the package's installation prompts, if shown, then open AkôFlow Desktop. +2. Run the portable executable directly. v1.0.8 does not provide a separate Windows installer asset. 3. Keep Docker Desktop running with Linux containers enabled. -The v1.0.8 release lists one Windows executable; it does not offer separately -named installer and portable downloads. Do not look for an additional -`portable.exe` asset in that release. - @@ -115,19 +111,14 @@ If **AkôFlow could not start** appears, read the error and use ## 3. First launch: what happens -Desktop checks Docker and Compose, downloads the daemon and BuildKit archives -for its own version and architecture, verifies their SHA-256 checksums, loads -them into Docker, and starts the local services. Keep internet access available -for this first launch. You do not need to download the `.tar` files yourself. - -The application's proxy supplies the local API credential. Do not paste a token -into a form just to complete packaged Desktop installation. +Desktop checks Docker and Compose, downloads and verifies its matching service +files, then starts them locally. It handles its own API credential; you do not +need to download `.tar` files or enter a token. ### Welcome -Choose **Configure environment** to follow the complete local setup below. -The assistant proceeds through **Welcome → Engine checkup → Environment → -Connection → Ready**. +Choose **Configure environment** for the local setup below. The assistant moves +through **Welcome → Engine checkup → Environment → Connection → Ready**. If you only want to connect HPC or Google Cloud later, **Set up later** opens the main interface immediately. Continue at [Installation result](#4-installation-result), @@ -146,8 +137,8 @@ checks pass. ![Successful first-launch checkup: daemon, Docker and BuildKit are available](../static/img/interface/onboarding/engine-checkup.png) -_Observed result from the downloaded Linux package: all three services were -available. This check does not test an HPC cluster or a cloud credential._ +_The downloaded Linux package passed all three checks. Remote targets need +their own connection checks._ ### Environment: configure the local execution target @@ -157,14 +148,13 @@ or use a unique name, and optionally edit **Description**. Choose ![Environment step with Local machine selected and Configure and check visible](../static/img/interface/onboarding/environment-selection.png) -_Local machine configures execution through the daemon. With packaged Desktop, -that daemon runs in Docker; this is not a measurement of your laptop's full -compute capacity. Review discovered resources before planning real work._ +_Local machine uses the service running in Docker. Review discovered resources +before planning work that needs your workstation's full compute capacity._ The initial assistant also offers **Supercomputer / HPC** and **Kubernetes cluster**. -For HPC, use the [guided registration tutorial](./tutorials/register-hpc) to +For HPC, use the [guided registration tutorial](/docs/tutorials/register-hpc) to prepare and authorize an SSH key before connecting. For Kubernetes, use the -[cluster guide](./guides/infrastructure/kubernetes). Google Cloud is connected +[cluster guide](/docs/guides/infrastructure/kubernetes). Google Cloud is connected from the main **Environments** catalog after leaving this assistant. ### Connection: wait for registration, health and discovery @@ -174,8 +164,6 @@ resources. Let these operations finish; success advances to **Ready** automatica ![Connection step while the application checks the local environment](../static/img/interface/onboarding/connection-checkup.png) -_This step can be brief. The next screen is the completion checkpoint._ - If **Checkup needs attention** appears, read the failing operation. Use **Edit connection** to correct the settings or **Run checkup again** to retry. Registration can finish before a later check fails, so inspect the existing @@ -195,53 +183,33 @@ appears. Open it to inspect its connection and inventory. ![Environment catalog after completing local setup](../static/img/interface/onboarding/environment-catalog.png) **Expected result:** the local environment is saved, its connection check has -passed, and discovery has completed. No workflow has run yet. The full local -assistant was exercised with the official Linux package; remote success requires -the checks in the relevant infrastructure tutorial. +passed, and discovery has completed. No workflow has run yet. ## 4. Installation result -### Check through the interface - -| Checkpoint | Expected result | If it fails | -| -------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------- | -| Application opens | Welcome screen or Overview appears | Read startup error details and confirm Docker/Compose access | -| Local control plane | Sidebar connection indicator says **Connected** | Wait for startup; inspect the daemon failure rather than creating a new identity | -| Catalog navigation | **Infrastructure → Environments** opens | Use [Troubleshooting](./guides/operations/troubleshooting) for API/instance errors | -| Infrastructure setup | **Connect environment** opens the connection choices | Continue with the HPC or cloud tutorial below | - -![Overview after first launch with the local control-plane connection established](../static/img/interface/onboarding/installation-result.png) +If you chose **Set up later**, open **Overview** and check that the sidebar +shows **Connected**. Then open **Infrastructure → Environments**. An empty catalog +is expected until you register an environment; the connection indicator confirms +only that Desktop reached its local AkôFlow server. -_Overview after choosing Set up later on a fresh installation. If you completed -the local assistant, your environment is already present; empty execution charts -are still expected before running workflows._ +![Overview after first launch with the local AkôFlow service connected](../static/img/interface/onboarding/installation-result.png) -An empty catalog is normal on a new installation. A connected daemon confirms -that the application can reach its control plane; it does not prove that a -remote cluster, a cloud credential, or a workflow is ready. +_Overview after choosing Set up later. The execution charts stay empty until a +workflow runs._ -### Check through the API - -For a daemon you manage directly, first follow [API connection setup](./tutorials/api-access). -Run these public bootstrap checks against **that daemon**, using its actual port: - -```bash -curl --fail-with-body "$AKOFLOW_API_URL/preflight/" | jq -curl --fail-with-body "$AKOFLOW_API_URL/instance/" | jq '{id, name}' -``` - -Expect `server.available: true` and a non-empty instance ID. Review `docker` and -`buildkit` separately: server availability alone does not confirm either build -prerequisite. These checks diagnose an existing installation; HTTP requests do -not install the Desktop package. The packaged application's internal port and -credential are managed by Desktop; do not assume they are `8080` and a token -from a development checkout. +If you completed the local assistant, confirm the saved environment as described +in **Ready** above. If Desktop is not connected, use +[Troubleshooting](/docs/guides/operations/troubleshooting) before registering a +remote target. ## 5. Continue with your execution target -- [Register an HPC / SLURM environment](./tutorials/register-hpc): authorize an SSH key, test the login connection, and discover partitions. -- [Connect Google Cloud](./tutorials/connect-cloud): validate a service account, register the environment, and synchronize the compute catalog. -- [Run the first simulated workflow](./guides/workflows/first-run): verify workflow execution through the documented API setup without a remote account. +- [Run your first local workflow in Desktop](/docs/guides/workflows/first-local-run): create one activity, run it, and inspect its generated file. +- [Register an HPC / SLURM environment](/docs/tutorials/register-hpc): authorize an SSH key, test the login connection, and discover partitions. +- [Connect Google Cloud](/docs/tutorials/connect-cloud): validate a service account, register the environment, and synchronize the compute catalog. +- [Run the first simulated workflow](/docs/guides/workflows/first-run): verify workflow execution through the documented API setup without a remote account. + +For a server you manage separately, use the [server installation](/docs/guides/operations/server-instance) and [API connection setup](/docs/tutorials/api-access) guides. ## Recover at the step that failed @@ -257,18 +225,13 @@ from a development checkout. | Welcome no longer appears | This is expected after completing or skipping setup. Continue from Infrastructure → Environments. | | The app is connected but there are no runs | Continue with a workflow tutorial; installation does not submit a workflow. | -For further diagnosis, use [Troubleshooting](./guides/operations/troubleshooting). +For further diagnosis, use [Troubleshooting](/docs/guides/operations/troubleshooting). Keep the failed step, exact error, operating system and Desktop version when requesting help. -## Updates and verification scope +## Update AkôFlow -Export your instance before changing versions; see [Instance management](./guides/operations/instance-management). +Export your instance before changing versions; see [Instance management](/docs/guides/operations/instance-management). Keep Desktop and its runtime on matching versions. -The v1.0.8 Linux `.deb` was fully downloaded on 2026-09-12. Its SHA-256 matches -the GitHub asset digest, and its package metadata reports version `1.0.8`, -architecture `amd64`. The application extracted from that package also started its release-matched -daemon and BuildKit in Docker and reached the successful checkup shown above. -This was an extracted-package smoke test on Linux with a fresh application -profile, not a test of the `apt` installation procedure or of macOS/Windows. +For the v1.0.8 download digest and verification record, see [Downloads](/docs/downloads#download-verification-result). diff --git a/docs/docs/internal/workflow-spec.md b/docs/docs/internal/workflow-spec.md index 6843b6da..4cc00450 100644 --- a/docs/docs/internal/workflow-spec.md +++ b/docs/docs/internal/workflow-spec.md @@ -5,11 +5,13 @@ sidebar_label: Workflow specification description: Current YAML and JSON authoring contract accepted by the AkôFlow workflow API. --- -AkôFlow accepts a compact, portable workflow document and normalizes it into the versioned domain model used by planning and execution. This page documents the **authoring contract**, not the larger persisted API response. It is a reference: use [Workflow definitions](../guides/workflows/definitions) for the Desktop/API procedure and the SimGrid guide when modeling a simulation experiment. +AkôFlow accepts a compact, portable workflow document and normalizes it into the versioned domain model used by planning and execution. This page documents the **authoring contract**, not the larger persisted API response. It is a reference: use [Workflow definitions](/docs/guides/workflows/definitions) for the Desktop/API procedure and the SimGrid guide when modeling a simulation experiment. Submit YAML or JSON to `POST /akoflow-api/workflow-definitions/` or `/workflow-definitions/import/`. Exporting a workflow produces this portable format without generated IDs or resolved runtime state. -## Complete example +## Example document + +This example shows real-execution fields. Supply an image that contains the referenced `/app` scripts before running it. For a complete, tested submission sequence, use the [SimGrid first-run tutorial](/docs/guides/workflows/first-run). ```yaml name: astronomy-fanout @@ -21,9 +23,6 @@ spec: cpuLimit: "0.5" memoryLimit: 256Mi run: python /app/prepare.py - simulation: - model: fixed-duration - durationSeconds: 4 - name: analyze-a cpuLimit: "1" @@ -53,7 +52,7 @@ spec: ``` :::important Real and simulated capabilities -In the current portable importer, an activity with `simulation` is normalized as simulation-capable; an activity without it is normalized as real-capable. Do not assume that adding simulation fields creates one activity that runs in both modes. +In the current portable importer, an activity with `simulation` is simulation-capable; an activity without it is real-capable. Adding simulation fields does not make one activity runnable in both modes. ::: ## Top-level fields @@ -197,4 +196,4 @@ If the two activities are placed on different resources, this edge can become a The API response is richer than the submitted document. It contains the workflow and version IDs, normalized activities, capabilities, resources in bytes/cores, structured dependencies, policies, priorities, and runtime resolution state. Plans refer to `version.id`, not to the mutable authoring file. -See [Workflow definitions](../guides/workflows/definitions) for Desktop and API procedures, [SimGrid modeling](../guides/infrastructure/simgrid) for a calibrated simulated workflow, and [execution scopes and topologies](../reference/execution-scopes-and-topologies) for the network model used by a plan. +See [Workflow definitions](/docs/guides/workflows/definitions) for Desktop and API procedures, [SimGrid modeling](/docs/guides/infrastructure/simgrid) for a calibrated simulated workflow, and [execution scopes and topologies](/docs/reference/execution-scopes-and-topologies) for the network model used by a plan. diff --git a/docs/docs/modules.md b/docs/docs/modules.md index d988a66b..45350e47 100644 --- a/docs/docs/modules.md +++ b/docs/docs/modules.md @@ -1,13 +1,14 @@ --- id: modules -title: AkôFlow components and boundaries -sidebar_label: Components and boundaries +title: Architecture internals +sidebar_label: Architecture internals +description: How the AkôFlow server coordinates planning, execution, persistence, and adapters. --- import useBaseUrl from '@docusaurus/useBaseUrl'; -AkôFlow is a single control-plane daemon with a REST API, a persistent event queue, planning and execution services, and pluggable infrastructure adapters. The Desktop application is the primary client of that API. AkôFlow does **not** deploy a separate Workflow Engine into every environment. +The AkôFlow server exposes one REST API and coordinates planning, execution, and saved state. Desktop uses that API. Runtime adapters connect the server to local, cluster, and cloud execution technologies. ## At a glance @@ -23,34 +24,34 @@ The Desktop application and development web UI use the same React interface and - **Infrastructure** — environments, connections, discovered inventory, machine configurations, execution scopes, network topology, storage, and cloud capacity. - **Runs** — real, simulated, and interactive executions, activity status, logs, transfers, and planned-versus-observed timing. - **Artifacts** — executable artifacts, immutable variants, locations, builds, and materializations. -- **Provenance** and **Audit** — scientific lineage and operational actions respectively. +- **Provenance** — scientific lineage; **Audit** — recorded connection, discovery, and console actions. - **Settings** and **Console** — instance configuration, credential references, and supported interactive access. The UI is a client, not a second implementation of the control plane. Desktop actions call the same API available to automation clients. ## API and services -The HTTP server handles authentication, request validation, and representation. Handlers delegate to services for connection checks, discovery, workflows, planning, execution, storage, transfers, artifact builds, cloud provisioning, console commands, and terminal sessions. Operational and analytics/provenance persistence have distinct responsibilities. +The HTTP server authenticates and validates requests, then calls the service responsible for the task. Planning, execution, infrastructure checks, and data preparation have separate services. Operational state and provenance data also have separate persistence paths; the [source map](#source-map) points to their entry points. ## Persistent event loop -Long-running commands are queued rather than completed inside the initiating HTTP request. The daemon dispatches persistent typed jobs for planning sessions, execution runs, activities, cloud operations, and execution/activity domain events. Queue ownership and retries make work recoverable across interruptions. Clients should observe resource status instead of depending on the current 500 ms polling default. +Long-running commands are queued rather than completed inside the initiating HTTP request. The daemon dispatches persistent typed jobs for planning sessions, execution runs, activities, cloud operations, and execution/activity domain events. An expired queue lease can return a job to the pending state; this does not resume a workflow run already started by the supervisor. Clients observe the status of the requested operation. ## Planning -A planning session freezes the workflow version, execution scope, environment versions, resources, topology, activity profiles, deadline, budget, and optional interference model. Registered algorithms generate comparable candidates; built-ins currently include HEFT, PRISM Time, and PRISM Cost. +A planning session freezes the selected workflow, execution scope, topology, resources, and planning constraints. Built-in algorithms include HEFT, PRISM Time, and PRISM Cost. They use the same session inputs, but their predictions come from different evaluation models; see [PRISM and HEFT](/docs/explanations/prism-and-heft) before comparing them. Selecting a candidate creates or selects a schedule plan; it does not execute the workflow. A plan contains assignments, predicted timing and cost, transfer estimates, and optional cloud lifecycle actions. ## Execution -The execution supervisor consumes a selected plan. It validates the DAG and assignments, prewarms planned cloud capacity, finds dependency-ready activities, prepares executable/workspace data, resolves runtime adapters, starts and inspects handles, records observations, and releases ephemeral capacity. Simulation uses a simulator rather than real adapters. Interactive execution returns while its activity/session remains active. +The execution supervisor checks the selected plan and starts activities when their dependencies are ready. It prepares their executable and workspace data, selects a runtime adapter, then follows each activity through completion. When a real plan needs cloud capacity, it can prepare that capacity before dispatch and release it afterward. Simulation uses a simulator instead of real adapters. An interactive request returns while its session remains active. ## Infrastructure and data plane -An **environment** is a managed infrastructure boundary. Published versions contain runtimes, resources, bindings, storage, relations, connections, and capability observations. An **execution scope** combines environment versions with a network topology. +An **environment** is a managed infrastructure boundary. Published versions contain runtimes, resources, bindings, storage, relations, connections, and capability observations. An **execution scope** selects environment versions; a planning session also chooses a network topology. -Before start, the data plane can materialize executable artifacts and workspaces. Routes may use an existing location, shared storage, destination pull, source push, a gateway, runtime-local, or direct-runtime transfer. Implemented connectors include the artifact store, local filesystem, rsync/SSH, Kubernetes exec, HTTP, S3-compatible storage, and GCS. A materialization is usable only after digest verification commits it. +Before start, the data plane can prepare executable artifacts and workspaces. Implemented transfer paths include the artifact store, local filesystem, rsync/SSH, Kubernetes exec, HTTP download, and an S3-compatible connector. The current GCS connector rejects direct `gs://` transfers; a deployment needs another supported route or its own transfer agent. A prepared artifact is usable only after digest verification. ## Cloud lifecycle @@ -58,7 +59,7 @@ Cloud support separates catalog/configuration, capacity targets, provisioned ins ## Provenance and audit -Provenance links workflow versions, plans, runs, activities, data, artifacts, locations, materializations, and transfers. Audit records control-plane actions and their results. They are related but intentionally separate histories. +Provenance links workflow versions, plans, runs, activities, data, artifacts, locations, materializations, and transfers. Audit currently records connection health, resource discovery, and console actions and their outcomes. It does not record every control-plane change. These are separate histories. ## Source map diff --git a/docs/docs/reference/api-overview.md b/docs/docs/reference/api-overview.md index 4b2e021c..fb1bd3ed 100644 --- a/docs/docs/reference/api-overview.md +++ b/docs/docs/reference/api-overview.md @@ -5,18 +5,15 @@ description: Authentication, conventions, and current AkôFlow HTTP endpoint gro # API overview -The AkôFlow Desktop is an HTTP client of the same API available to automation. API paths below are relative to the daemon origin and begin with `/akoflow-api/`. +The AkôFlow Desktop uses the same API available to automation. Paths in the tables below are relative to `AKOFLOW_API_URL`, which includes `/akoflow-api`. ## Connect and authenticate -Set the daemon URL and token in your shell: +Follow [API connection setup](/docs/tutorials/api-access) to set the base URL and enter the token without putting it in shell history. The base URL includes `/akoflow-api`. Then check a protected catalog: ```bash -export AKOFLOW_URL="http://127.0.0.1:8080" -export AKOFLOW_TOKEN="replace-with-the-configured-token" - -curl -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - "$AKOFLOW_URL/akoflow-api/environments/" +curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "$AKOFLOW_API_URL/environments/" ``` The listen address is configuration-dependent; do not assume the example port in production. When an API token is configured, send `Authorization: Bearer `. `GET` or `HEAD` requests for `/akoflow-api/instance/` and `GET /akoflow-api/preflight/` are public bootstrap operations. All other operations require the token. A daemon without a token is restricted to loopback access. @@ -31,17 +28,19 @@ Browser origins are controlled by the daemon's allowed-origin configuration. Aut - Many collection paths retain a trailing slash; use the route exactly as shown. - Successful creates generally return `201 Created`; queued work commonly returns `202 Accepted`; deletes commonly return `204 No Content`. - Errors from kernel-wrapped routes use a JSON `error` message. Validation failures commonly return `400` or `422`; missing records return `404`; unavailable capabilities return `503`. -- An activated archive snapshot is read-only. Mutating requests return `423 Locked`, except instance activation itself. +- An activated archive snapshot is read-only. Requests other than `GET` return `423 Locked`, except instance activation itself. - Export, download, build output, and console stream routes return non-JSON content. Check daemon and local build capabilities: ```bash -curl "$AKOFLOW_URL/" -curl "$AKOFLOW_URL/akoflow-api/preflight/" +curl --fail-with-body \ + -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ + "${AKOFLOW_API_URL%/akoflow-api}/" +curl --fail-with-body "$AKOFLOW_API_URL/preflight/" ``` -The root health check returns `ok`. Preflight reports server, Docker, and BuildKit availability. +The authenticated root health check returns `ok`. Public preflight reports server, Docker, and BuildKit availability. ## Instance, search, and operations @@ -50,12 +49,12 @@ The root health check returns `ok`. Preflight reports server, Docker, and BuildK | `GET`, `PUT` | `/instance/` | Read or save installation identity/configuration | | `GET` | `/preflight/` | Report daemon, Docker, and BuildKit readiness | | `GET` | `/search/` | Global search | -| `GET` | `/audit-events/` | Filter operational audit events | +| `GET` | `/audit-events/` | Filter recorded connection, discovery, and console events | | `GET` | `/instances/` | List archived instances | | `GET` | `/instances/default/export/` | Export the default instance | | `POST` | `/instances/import/` | Import an instance archive | | `POST` | `/instance-activations/{instanceId}/` | Activate an archived instance | -| `POST` | `/factory-reset/` | Reset the active instance | +| `POST` | `/factory-reset/` | Clear the active catalog and managed Kubernetes tokens; [retained files need separate cleanup](/docs/guides/operations/instance-management#factory-reset) | | `GET`, `PUT` | `/user-preferences/{clientId}/` | Read or save client preferences | ## Environments, connections, and credentials @@ -95,6 +94,8 @@ The root health check returns `ok`. Preflight reports server, Docker, and BuildK | `GET` | `/environments/{environmentId}/cloud-catalog/` | Read cached provider catalog | | `POST` | `/environments/{environmentId}/cloud-catalog/refresh/` | Refresh provider catalog | +See [Configure cloud capacity](/docs/guides/infrastructure/cloud-capacity) for target and provisioning steps, and [Machine configurations](/docs/guides/infrastructure/machine-configurations) for the optional Ansible setup. + ## Resources, topology, and execution scopes | Method | Path | Purpose | @@ -146,14 +147,7 @@ The root health check returns `ok`. Preflight reports server, Docker, and BuildK | `GET` | `/planning-sessions/{sessionId}/candidates/{candidateId}/` | Read a candidate | | `POST` | `/planning-sessions/{sessionId}/candidates/{candidateId}/select/` | Select a candidate and produce a plan | -Create a workflow by posting the current workflow definition document: - -```bash -curl -X POST -H "Authorization: Bearer $AKOFLOW_TOKEN" \ - -H "Content-Type: application/json" \ - --data-binary @workflow.json \ - "$AKOFLOW_URL/akoflow-api/workflow-definitions/" -``` +For a complete workflow request and the required registration order, use [Workflow definitions](/docs/guides/workflows/definitions) or the [SimGrid first-run tutorial](/docs/guides/workflows/first-run). ## Executions @@ -170,7 +164,7 @@ List queries accept endpoint-specific pagination and filters. For execution runs |---|---|---| | `GET` | `/artifacts/` | List executable artifact versions | | `POST` | `/artifacts/docker/` | Register a Docker source and SIF build specification | -| `GET` | `/artifact-locations/` | List verified artifact locations | +| `GET` | `/artifact-locations/` | List recorded artifact locations and their availability flags | | `GET`, `POST` | `/artifact-materializations/` | List or record materializations (`runId` filters list) | | `POST` | `/build-contexts/` | Upload multipart `context`, or register stored metadata | | `POST` | `/artifact-builds/` | Create an immutable build specification | @@ -180,7 +174,7 @@ List queries accept endpoint-specific pagination and filters. For execution runs | `GET` | `/build-runs/{runId}/` | Read build-run status and logs | | `GET` | `/build-runs/{runId}/output/` | Stream SIF output | -See [Artifacts, storage, and builds](../guides/data/artifacts.md) for payload examples and lifecycle semantics. +For a build request, see [Build an executable](/docs/guides/data/build-executable). To inspect recorded locations and preparation status, see [Artifact locations](/docs/guides/data/artifact-locations). Storage browsing and file registration are covered in [Browse and manage storage](/docs/guides/infrastructure/storage). ## Provenance @@ -193,7 +187,7 @@ See [Artifacts, storage, and builds](../guides/data/artifacts.md) for payload ex | `POST` | `/provenance/sql/explain/` | Explain read-only SQL | | `GET` | `/provenance/lineage/{entity}/{id}/` | Traverse lineage | -See [Provenance and audit](../guides/data/provenance-and-audit.md) for query parameters and examples. +See [Trace a result with provenance](/docs/guides/data/provenance) for query examples. ## Console diff --git a/docs/docs/reference/environment-yaml.md b/docs/docs/reference/environment-yaml.md index 00d75a08..8528c808 100644 --- a/docs/docs/reference/environment-yaml.md +++ b/docs/docs/reference/environment-yaml.md @@ -5,16 +5,16 @@ description: Field-level reference for the environment definition accepted by th # Environment YAML reference -This reference describes the `EnvironmentDefinition` document accepted by `POST /environments/` and `PUT /environments/{environmentId}/`. JSON and YAML carry the same structure. It is for authors who need a reproducible infrastructure inventory; use the [environment guide](../guides/infrastructure/environments) for the Desktop workflow and the runtime guides for provider-specific setup. +This reference describes the `EnvironmentDefinition` document accepted by `POST /environments/` and `PUT /environments/{environmentId}/`. JSON and YAML carry the same structure. It is for authors who need a reproducible infrastructure inventory; use the [environment guide](/docs/guides/infrastructure/environments) for the Desktop workflow and the runtime guides for provider-specific setup. “Recommended” fields improve the inventory but are not required by the create handler. ## Before you write a definition -- Use stable, unique IDs. The environment ID is the identity used by `PUT`; send a complete definition when replacing an existing environment. The version ID is the identity referenced by scopes. +- Use stable, unique IDs. The environment ID is the identity used by `PUT`; send a complete definition when replacing an unused environment. Replacement can fail once a scope, plan, or other record references its inventory. The version ID is the identity referenced by scopes. - Create the environment before an execution scope. A scope refers to the version ID, and its network topology is a separate document. -- Declare performance values deliberately. Omitting a numeric value decodes it as `0` (except `computeSpeedup`, which the database defaults to `1`); that is rarely a useful planning model. -- Keep credentials out of the file. `credentialRef` and `credentialReference` name a credential already stored in AkôFlow; they are not the secret itself. +- Declare performance values deliberately. The API decodes omitted numeric values as `0`, including `computeSpeedup`, and saves them explicitly. Set a positive speedup and realistic capacity for schedulable resources. +- Keep secrets out of the file. Connection credential references identify saved credentials. Transfer and storage references have provider-specific behavior; see the [AWS/S3 limits](/docs/guides/infrastructure/aws) before using them. -The smallest useful simulation definition is versioned in [`examples/simulation/environment.yaml`](https://github.com/UFFeScience/akoflow/blob/main/examples/simulation/environment.yaml). It is a better starting point than an empty document because it includes a runtime, schedulable resources, and their bindings. +The smallest useful simulation definition is versioned in [`examples/simulation/environment.yaml`](https://github.com/UFFeScience/akoflow/blob/v1.0.8/examples/simulation/environment.yaml). It is a better starting point than an empty document because it includes a runtime, schedulable resources, and their bindings. ## Document shape @@ -28,11 +28,11 @@ resourceRelations: [] storages: [] activityResourceProfiles: [] connections: [] -connectionChecks: [] -connectorBindings: [] ``` -`environment` and `version` are required for a persisted definition. The remaining collections may be empty at creation time, but a plan needs at least one schedulable resource, an enabled binding, and a runtime compatible with the selected execution mode. +`environment` and `version` are required for a persisted definition. The remaining collections may be empty at creation time. Planning needs a schedulable resource in the selected scope; executing the plan also needs an enabled binding to a runtime compatible with the run mode. + +The create handler returns the submitted document. It may still show omitted nested parent IDs as empty strings. Read `GET /environments/{environmentId}/` to see the IDs actually saved with the environment and version. ## Identity and version fields @@ -41,44 +41,44 @@ connectorBindings: [] | `environment.id` | Yes | string | unique ID | Primary environment ID. | | `environment.name` | Yes | string | non-empty in a useful definition | Display name; unique names are not required. | | `environment.description` | No | string | `""` | Free text. | -| `environment.status` | No | string | `defined` | `defined`, `connecting`, `connected`, `discovering`, `ready`, `degraded`, or `unreachable`. Set it from observed connection state rather than treating it as a runtime selector. | +| `environment.status` | No | string | `defined` | Documented states are `defined`, `connecting`, `connected`, `discovering`, `ready`, `degraded`, and `unreachable`. The create path does not validate this string; use an observed state rather than treating it as a runtime selector. | | `environment.createdAt` | No | timestamp | database creation time | Returned by reads; do not author it. | | `version.id` | Yes | string | unique ID | The immutable ID referenced by scopes. | -| `version.environmentId` | Yes | string | `environment.id` | Keep it equal to the enclosing environment ID. The create path persists the enclosing ID. | +| `version.environmentId` | No | string | saved as `environment.id` | The repository uses the enclosing environment ID when it saves the version. | | `version.version` | Yes | integer | sequence chosen by author | Must be unique for an environment. | -| `version.status` | Yes | string | `draft`, `published`, `retired` | Use `published` for an inventory intended for a scope. | -| `version.networkModel` | Yes | string | author-defined label | A descriptive model label such as `static-links`; topology links themselves live in the execution-scope document. | -| `version.interferenceModel` | Yes | string | author-defined label | Record the model assumption, for example `none`. | -| `version.costModel` | Yes | string | author-defined label | Record the cost interpretation, for example `per-second`. | -| `version.configurationHash` | Yes | string | author-provided stable hash/label | Used to identify the inventory configuration. | +| `version.status` | Recommended | string | `""` if omitted | Documented states are `draft`, `published`, and `retired`; the create path does not validate this string. Use `published` for inventory intended for planning. | +| `version.networkModel` | No | string | `""` if omitted | Optional model label such as `static-links`. Topology links live in a separate network-topology document. | +| `version.interferenceModel` | No | string | `""` if omitted | Record the model assumption when one is known, for example `none`. | +| `version.costModel` | No | string | `""` if omitted | Record the cost interpretation when one is known, for example `per-second`. | +| `version.configurationHash` | Recommended | string | `""` if omitted | Supply a stable label or hash to identify the inventory configuration; the create path does not compute it. | | `version.createdAt`, `version.publishedAt` | No | timestamp | server-managed / optional | Read-only evidence fields. | ## Runtimes -Each entry in `runtimes` defines how a version can execute or simulate work. `configuration` is a runtime-specific object; see the relevant [SimGrid](../guides/infrastructure/simgrid), [Kubernetes](../guides/infrastructure/kubernetes), or [SLURM/HPC](../guides/infrastructure/hpc-slurm) guide before adding its keys. +Each entry in `runtimes` defines how a version can execute or simulate work. `configuration` is a runtime-specific object; see the relevant [SimGrid](/docs/guides/infrastructure/simgrid), [Kubernetes](/docs/guides/infrastructure/kubernetes), or [SLURM/HPC](/docs/guides/infrastructure/hpc-slurm) guide before adding its keys. | Path | Required | Type | Values / default | Notes | | --- | --- | --- | --- | --- | | `runtimes[].id` | Yes | string | unique ID | Referenced by resource and storage bindings. | -| `runtimes[].environmentVersionId` | Yes | string | `version.id` | Keep equal to the enclosing version ID; create persists the enclosing version. | +| `runtimes[].environmentVersionId` | No | string | saved as `version.id` | The repository uses the enclosing version ID when it saves each runtime. | | `runtimes[].name` | Yes | string | unique per version | User-facing runtime name. | | `runtimes[].driver` | Yes | enum | `slurm`, `kubernetes`, `ssh`, `local`, `serverless`, `simgrid`, `cloud` | The database validates this list. | | `runtimes[].mode` | Yes | enum | `execution`, `simulation` | The database validates this list. A SimGrid runtime uses `simulation`; a remote runtime normally uses `execution`. | | `runtimes[].role` | No | string | `""` | Informational role, such as `simulation`. | -| `runtimes[].configuration` | No | object | `{}` | Driver-specific settings. | +| `runtimes[].configuration` | No | object | omitted | Driver-specific settings; supply an object when the driver needs one. | | `runtimes[].capabilities` | Recommended | object | all booleans default to `false` when omitted | Declare only capabilities the runtime actually provides. | `capabilities` accepts these boolean keys: `batch`, `interactive`, `container`, `serverless`, `gpu`, `mpi`, `sharedStorage`, `dataStaging`, `cancellation`, `logStreaming`, and `simulation`. ## Resources and resource bindings -Resources are the candidates a plan can place activities on. A resource is usable only when it belongs to the selected version, is `schedulable: true`, and has an enabled binding to a compatible runtime. +Planning considers resources in the selected scope marked `schedulable: true`; for non-batch targets it also checks the workflow's CPU and memory requirements. It does not filter them by runtime binding. Before execution, ensure each assigned resource has an enabled binding to a runtime compatible with the run mode; the supervisor rejects the request otherwise. | Path | Required | Type | Values / default | Notes | | --- | --- | --- | --- | --- | | `resources[].id` | Yes | string | unique ID | Referenced by bindings, relations, profiles, assignments, and topology links. | -| `resources[].environmentVersionId` | Yes | string | `version.id` | Keep equal to the enclosing version ID; create persists the enclosing version. | -| `resources[].type` | Yes | enum | See resource types below | Classifies the resource. | +| `resources[].environmentVersionId` | No | string | saved as `version.id` | The repository uses the enclosing version ID when it saves each resource. | +| `resources[].type` | Recommended | string | `""` if omitted | Use a known resource type below to classify the resource. The create path does not validate this field against that list. | | `resources[].name` | Yes | string | — | Display name. | | `resources[].providerId` | Yes | string | unique per version | Provider-facing or modeled identifier. | | `resources[].executionTarget` | No | enum | `batch` | `batch`, `direct`, or `provisioned`. The create path normalizes an omitted value to `batch`. | @@ -87,13 +87,13 @@ Resources are the candidates a plan can place activities on. A resource is usabl | `resources[].cpuCores` | Recommended | integer | `0` | Number of modeled cores. Set the actual parallel capacity. | | `resources[].cpuCapacity` | Recommended | number | `0` | Schedulable CPU capacity. Keep it coherent with `cpuCores` for a one-unit-per-core model. | | `resources[].memoryBytes`, `storageBytes` | Recommended | integer | `0` | Capacity in bytes. | -| `resources[].computeSpeedup` | Recommended | number | `1` | Relative compute multiplier. The database defaults an omitted value to `1`; set it explicitly in portable YAML. | +| `resources[].computeSpeedup` | Recommended | number | `0` when omitted from API input | Relative compute multiplier. Set a positive value, commonly `1` for the baseline resource. | | `resources[].pricePerSecond` | Recommended | number | `0` | Cost rate used by planning/simulation. | | `resources[].bootOverheadSeconds`, `containerOverheadSeconds` | No | number | `0` | Modeled setup delays in seconds. | -| `resources[].schedulable` | Recommended | boolean | database default `true` | Set explicitly. `false` retains inventory visibility without making a placement target. | -| `resources[].metadata` | No | object | `{}` | Provider- or experiment-specific metadata. | +| `resources[].schedulable` | Recommended | boolean | `false` when omitted from API input | Set `true` for a placement target. `false` retains inventory visibility without making a placement target. | +| `resources[].metadata` | No | object | omitted | Provider- or experiment-specific metadata. | -Accepted resource types are: `cluster`, `node_pool`, `kubernetes_machine`, `hpc_partition`, `hpc_machine`, `cloud_vm`, `fog_device`, `local_machine`, `serverless_platform`, `serverless_function`, `batch_queue`, `kubernetes_namespace`, and `slurm_reservation`. +Known resource types are: `cluster`, `node_pool`, `kubernetes_machine`, `hpc_partition`, `hpc_machine`, `cloud_vm`, `fog_device`, `local_machine`, `serverless_platform`, `serverless_function`, `batch_queue`, `kubernetes_namespace`, and `slurm_reservation`. A stored type does not by itself make the resource runnable. ```yaml resourceRuntimeBindings: @@ -103,9 +103,9 @@ resourceRuntimeBindings: configuration: {} ``` -`resourceRuntimeBindings[].resourceId` and `runtimeId` are required and must reference entries in the same definition. `enabled` defaults to `true` in the database, but set it explicitly. `configuration` is optional and defaults to `{}`. +`resourceRuntimeBindings[].resourceId` and `runtimeId` must identify saved entries. Use entries from the same environment version: the database checks that both IDs exist, but does not check that their versions match. Set `enabled: true` for a usable binding; an omitted value decodes as `false` through the API. Omit `configuration` when the binding needs no settings. -`resourceRelations` is optional. When used, each relation needs `sourceResourceId`, `targetResourceId`, and `type`; `environmentVersionId` should equal `version.id`. The allowed relation types are `contains`, `member_of`, and `accessible_via`. A relation cannot point from a resource to itself. +`resourceRelations` is optional. When used, each relation needs `sourceResourceId`, `targetResourceId`, and `type`; the repository saves the enclosing `version.id` as its `environmentVersionId`. The allowed relation types are `contains`, `member_of`, and `accessible_via`. A relation cannot point from a resource to itself. ## Connections and transfer connectors @@ -113,32 +113,45 @@ resourceRuntimeBindings: | Path | Required | Type | Values / default | Notes | | --- | --- | --- | --- | --- | -| `connections[].id`, `name`, `type` | Yes | string / enum | `ssh`, `kubernetes`, `cloud`, `local`, `agent` | `name` is unique within the environment. | -| `connections[].environmentId` | Yes | string | `environment.id` | Keep it equal to the enclosing environment; create persists the enclosing ID. | +| `connections[].id`, `name`, `type` | Yes for a usable connection | string | Known types: `ssh`, `kubernetes`, `cloud`, `local`, `agent` | `name` is unique within the environment. The create path does not validate `type` against this list. | +| `connections[].environmentId` | No | string | saved as `environment.id` | The repository uses the enclosing environment ID when it saves each connection. | | `connections[].endpoint`, `username`, `credentialRef` | No | string | `""` | Reference stored credentials; never put tokens or private keys here. | -| `connections[].configuration` | No | object | `{}` | Connection-type-specific settings. | +| `connections[].configuration` | No | object | omitted | Connection-type-specific settings. | | `connections[].createdAt` | No | timestamp | server-managed | Read-only evidence field. | -`connectorBindings` declares artifact-transfer capabilities. Its `connector` enum is `rsync`, `scp`, `sftp`, `http`, `s3-compatible`, or `gcs`. The fields `id`, `environmentId`, and `connector` identify the binding; `endpoint`, `credentialRef`, and `configuration` are optional. `health` is observation data and should be written by a check rather than authored as an assumption. - -`connectionChecks` is also observed data. Do not copy a historical `online` result into a new environment file: validate the connection again after import. +Do not author `connectorBindings` or `connectionChecks` in this definition. The Go type includes both fields, but POST and PUT do not save them. GET includes recent connection checks recorded by separate health operations; it does not return a saved connector-binding list from this file. Configure storage or transfer use through the supported runtime and storage paths; see the [AWS/S3 guide](/docs/guides/infrastructure/aws) for the current S3 credential limits. Validate a connection again after import instead of copying a historical check. ## Storage -`storages` records accessible storage; it does not create a bucket, NFS export, PVC, or filesystem. Each storage entry requires `id`, `environmentVersionId`, `name`, and `type`. Supported types are `local`, `pvc`, `nfs`, `s3`, `lustre`, `gcs`, `s3-compatible`, and `ssh-filesystem`. +`storages` records storage that an environment may use; it does not create a bucket, NFS export, PVC, or filesystem. Each storage entry needs an `id`, `name`, and `type`; the repository saves the enclosing `version.id` as its `environmentVersionId`. Database-accepted type values are `local`, `pvc`, `nfs`, `s3`, `lustre`, `gcs`, `s3-compatible`, and `ssh-filesystem`. An accepted type does not prove that the running server can read its bytes; try the intended browse or transfer operation. | Path | Required | Type | Default | Notes | | --- | --- | --- | --- | --- | | `storages[].endpoint` | No | string | `""` | Mount, URL, bucket, or filesystem endpoint. | | `storages[].capacityBytes` | No | integer | `0` | Capacity in bytes; must not be negative. | | `storages[].shared`, `readOnly` | No | boolean | `false` | Access semantics. | -| `storages[].credentialReference` | No | string | `""` | Stored credential reference. | -| `storages[].configuration`, `metadata` | No | object | `{}` | Storage-provider details. | +| `storages[].credentialReference` | No | string | `""` | Recorded reference. The default S3 browser does not resolve it and sends unsigned requests. | +| `storages[].configuration`, `metadata` | No | object | omitted | Storage-provider details. | +| `storages[].configuration.browseRoots[]` | For browsing | array of objects | none | Approved roots, each with a `path`. For local filesystem browsing, include the exact `endpoint` path. | | `storages[].runtimeBindings[]` | No | array | none | Makes storage available to a runtime. | A storage runtime binding requires `runtimeId`. Its `containerPath` defaults to `/akoflow/data` when omitted, and `default`, `readOnly`, `hostPath`, and `configuration` are optional. At most one storage can be `default: true` for a given environment version and runtime. -`browseRoots`, `capabilities`, `health`, `indexPolicy`, and `indexStatus` are inventory/evidence fields returned by the API. Let discovery and indexing populate them; do not rely on an authored health status as proof that storage is reachable. +For a self-managed daemon browsing its own filesystem, set `AKOFLOW_LOCAL_STORAGE_ROOT` to an approved directory before starting it. Then register a `local` storage with the same absolute path as `endpoint` and in `configuration.browseRoots`: + +```yaml +storages: + - id: lab-files + environmentVersionId: lab-v1 + name: Lab files + type: local + endpoint: /srv/akoflow-lab + configuration: + browseRoots: + - path: /srv/akoflow-lab +``` + +Use this excerpt inside a complete environment definition; the directory must exist and be accessible to the daemon. The environment repository persists `configuration`, so a top-level `browseRoots` field alone will not enable browsing. `browseRoots`, `capabilities`, `health`, `indexPolicy`, and `indexStatus` also appear as fields in API responses. A catalog's `healthy` flag means the driver is available; it is not a fresh probe of the storage path or a compute node. ## Activity resource profiles @@ -190,7 +203,7 @@ resourceRuntimeBindings: enabled: true ``` -After creating it, retrieve `GET /environments/lab-sim/` and confirm that the runtime, resource, and binding are present. Then create an [execution scope](../guides/infrastructure/execution-scopes) and its network topology before generating a plan. +After creating it, retrieve `GET /environments/lab-sim/` and confirm that the runtime, resource, and binding are present. Then create an [execution scope](/docs/guides/infrastructure/execution-scopes) and its network topology before generating a plan. ## Compatibility and common failures @@ -198,9 +211,9 @@ After creating it, retrieve `GET /environments/lab-sim/` and confirm that the ru | --- | --- | | A runtime driver or mode is not in the documented enum | SQLite rejects the definition. Use a supported driver/mode pair. | | A duplicate `environment.id`, version number, provider ID, runtime name, connection name, or binding pair is supplied | The create transaction fails. Choose a new identity or update the existing definition through `PUT`. | -| A resource is not bound to the selected runtime | It is absent from compatible planning resources. Add an enabled resource-runtime binding. | +| A resource is not bound to a runtime compatible with the run mode | Planning can still assign it, but execution rejects the request. Add an enabled resource-runtime binding before starting the run. | | A resource has zero capacity or an omitted compute model | Planning may have no feasible placement or a meaningless estimate. Set resource capacities and workflow activity profiles explicitly. | | Two default storages bind to one runtime | The definition is rejected. Keep one default storage for each runtime/version pair. | -| A scope or plan already uses the environment | Deletion is blocked to preserve reproducibility. Create a new version instead of mutating historical infrastructure. | +| A scope or plan already uses the environment | Deletion or replacement can fail to preserve existing references. Register the revised inventory as a new environment with new environment and version IDs; the current API has no endpoint to append a version to an existing environment. | -Related reference: [workflow YAML](../internal/workflow-spec), [SimGrid modeling](../guides/infrastructure/simgrid), [storage](../guides/infrastructure/storage), and [execution scopes](../guides/infrastructure/execution-scopes). +Related reference: [workflow YAML](/docs/internal/workflow-spec), [SimGrid modeling](/docs/guides/infrastructure/simgrid), [storage](/docs/guides/infrastructure/storage), and [execution scopes](/docs/guides/infrastructure/execution-scopes). diff --git a/docs/docs/reference/execution-scopes-and-topologies.md b/docs/docs/reference/execution-scopes-and-topologies.md index 3800c348..8763d4ed 100644 --- a/docs/docs/reference/execution-scopes-and-topologies.md +++ b/docs/docs/reference/execution-scopes-and-topologies.md @@ -8,7 +8,7 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; # Execution scopes and network topology reference -This reference defines the two documents that freeze the infrastructure universe used in planning: an `ExecutionScope` selects environment versions and a `NetworkTopology` describes data-transfer links between their resources. It is intended for API and YAML authors. For the Desktop sequence and a worked setup, use [Execution scopes and network topologies](../guides/infrastructure/execution-scopes). +This reference defines the two API documents used to choose environment versions and describe data-transfer links for planning. An `ExecutionScope` selects the versions; a `NetworkTopology` defines links between their resources. For the Desktop sequence and a worked setup, use [Execution scopes and network topologies](/docs/guides/infrastructure/execution-scopes). The API accepts JSON, `application/yaml`, `application/x-yaml`, and `text/yaml` for both documents. @@ -43,7 +43,7 @@ metadata: | `name` | Yes | string | — | Display name. | | `networkTopologyId` | No | string | `""` | Optional topology ID recorded with the scope. No database foreign key validates it at scope creation. | | `environmentVersionIds` | Yes | array of strings | — | One or more environment-version IDs. Duplicate IDs cause the insert transaction to fail. Each ID must already exist. | -| `metadata` | No | object | `{}` | Additional descriptive data. | +| `metadata` | No | object | omitted | Additional descriptive data. | The repository rejects a scope with an empty `id`, empty `name`, or no environment versions. A scope cannot be deleted after a schedule plan references it; this preserves the infrastructure context of existing plans. @@ -77,7 +77,7 @@ metadata: | `version` | Yes | integer | — | Must be greater than zero. | | `executionScopeId` | Yes | string | — | Existing scope that owns this topology. | | `links` | No | array | `[]` | Directed link declarations. An empty topology is accepted, but it cannot model cross-resource transfer. | -| `metadata` | No | object | `{}` | Additional model or provenance data. | +| `metadata` | No | object | omitted | Additional model or provenance data. | ### Link fields @@ -90,10 +90,10 @@ metadata: | `bandwidthBitsPerSecond` | Yes | number | — | Strictly positive bandwidth in **bits per second**. | | `latencySeconds` | No | number | `0` | One-link latency in seconds; cannot be negative. | | `pricePerByte` | No | number | `0` | Transfer cost per byte; cannot be negative. | -| `bidirectional` | No | boolean | `true` in the database | Makes the declared link usable in both directions. Set it explicitly in portable YAML. | -| `sharingPolicy` | No | string | database schema default `independent` | Policy passed to the SimGrid platform: `independent` and `fatpipe` become `FATPIPE`; every other value, including `shared` and an omitted API value, becomes `SHARED`. Use `shared` or `independent` explicitly. | +| `bidirectional` | No | boolean | `false` when omitted from API input | Makes the declared link usable in both directions. Set it explicitly when reverse transfers are needed. | +| `sharingPolicy` | No | string | `""` when omitted from API input | Policy passed to the SimGrid platform: `independent` and `fatpipe` become `FATPIPE`; every other value, including `shared` and an omitted API value, becomes `SHARED`. Use `shared` or `independent` explicitly. | | `maxConcurrentTransfers` | No | integer | `0` | Cannot be negative. It is stored with the topology; treat it as an explicit model limit when your runtime/planner supports it. | -| `metadata` | No | object | `{}` | Link provenance or provider-specific context. | +| `metadata` | No | object | omitted | Link provenance or provider-specific context. | The API validates topology identity, positive version, scope ID, link identity, different endpoints, positive bandwidth, and non-negative latency, price, and concurrency. SQLite also rejects duplicate source/target pairs in one topology. @@ -115,7 +115,7 @@ The HEFT baseline finds a matching direct link for its transfer estimate. PRISM ## API sequence -The checked-in [SimGrid bundle](https://github.com/UFFeScience/akoflow/tree/main/examples/simulation) supplies a compatible `scope.yaml` and `topology.yaml`. Submit them in this order after creating the environment: +The checked-in [SimGrid bundle](https://github.com/UFFeScience/akoflow/tree/v1.0.8/examples/simulation) supplies compatible `scope.yaml` and `topology.yaml` files. Complete [API connection setup](/docs/tutorials/api-access), enter a v1.0.8 repository checkout, and create the bundle's environment first. The [SimGrid first-run tutorial](/docs/guides/workflows/first-run) gives the full setup. Then submit these two files in order: ```bash curl --fail-with-body \ @@ -149,7 +149,7 @@ curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ | Topology creation returns 422 | Check that `version >= 1`, `executionScopeId` is present, every link has distinct endpoints and positive bit/s bandwidth, and no value is negative. | | A reverse transfer has no modeled route | Set `bidirectional: true` or declare the reverse link explicitly. | | Transfer time is eight times too small or large | Verify units: links use bits/s; workflow data uses bytes. | -| A resource never appears in a candidate plan | Check its environment version is in the scope, it is schedulable, and it has an enabled binding to the selected runtime. | +| A resource never appears in a candidate plan | Check that its environment version is in the scope and it is schedulable; then inspect workflow constraints and the algorithm's placement. Runtime bindings are checked when execution starts, not by this planning filter. | | The scope cannot be deleted | Existing schedule plans reference it. Preserve it for evidence and create a new scope/version for a new experiment. | -Related reference: [Environment YAML](./environment-yaml), [workflow YAML](../internal/workflow-spec), [SimGrid modeling](../guides/infrastructure/simgrid), and [planning](../guides/workflows/planning). +Related reference: [Environment YAML](/docs/reference/environment-yaml), [workflow YAML](/docs/internal/workflow-spec), [SimGrid modeling](/docs/guides/infrastructure/simgrid), and [planning](/docs/guides/workflows/planning). diff --git a/docs/docs/reference/feature-coverage.md b/docs/docs/reference/feature-coverage.md index 0e43c68a..9a5cd891 100644 --- a/docs/docs/reference/feature-coverage.md +++ b/docs/docs/reference/feature-coverage.md @@ -5,61 +5,69 @@ sidebar_label: Desktop/API coverage description: Map every AkôFlow Desktop area to its API family and task documentation. --- -This matrix is maintained as the coverage checklist for the public documentation. A route may be hidden from the primary sidebar when it is a child page, compatibility redirect, or contextual action. +Use this map to find the guide and API family for a Desktop task. Some routes appear only after opening a record or starting an action. + +The `/network` and `/network/new` routes exist in Desktop, but the current sidebar and scope detail do not link to them. To register network links through a documented path, use the [execution-scope API procedure](/docs/guides/infrastructure/execution-scopes#using-the-api-1). ## Workflows and execution | Desktop route | Purpose | API family | Guide | |---|---|---|---| -| `/workflows` | List versioned workflow definitions | `/workflow-definitions/` | [Workflow definitions](../guides/workflows/definitions) | -| `/workflows/new` | Create or import a workflow | `/workflow-definitions/`, `/workflow-definitions/import/` | [Workflow definitions](../guides/workflows/definitions) | -| `/workflows/:id` | Inspect activities, dependencies, plans, and runs | Workflow, plan, and execution reads | [Workflow definitions](../guides/workflows/definitions) | -| `/workflows/:id/plans/new` | Generate candidates or define a manual plan | `/planning-sessions/`, `/schedule-plans/` | [Plan a workflow](../guides/workflows/planning) | -| `/planning-sessions` | List algorithm comparison sessions | `/planning-sessions/` | [Plan a workflow](../guides/workflows/planning) | -| `/planning-sessions/:id` | Follow algorithms and compare candidates | Planning session and candidate endpoints | [Plan a workflow](../guides/workflows/planning) | -| `/plans` | Aggregate plan index | `/schedule-plans/` | [Plan a workflow](../guides/workflows/planning) | -| `/workflows/:workflowId/plans/:id` | Inspect one plan and its predicted Gantt | `/schedule-plans/:planId/` | [Plan a workflow](../guides/workflows/planning) | -| `/executions` | Filter workflow, standalone, and interactive runs | `/execution-runs/` | [Execute and monitor](../guides/workflows/executions) | -| `/workflows/:workflowId/plans/:planId/executions/:id` | Compare the selected plan with observed execution | `/execution-runs/:runId/` | [Execute and monitor](../guides/workflows/executions) | -| `/workflows/:workflowId/plans/:planId/executions/:id/activities/:activityId` | Inspect one activity attempt | Execution context returned with the run detail | [Execute and monitor](../guides/workflows/executions) | -| `/executions/new` | Start a run from a plan | `POST /execution-runs/` | [Execute and monitor](../guides/workflows/executions) | +| `/workflows` | List versioned workflow definitions | `/workflow-definitions/` | [Workflow definitions](/docs/guides/workflows/definitions) | +| `/workflows/new` | Create or import a workflow | `/workflow-definitions/`, `/workflow-definitions/import/` | [Workflow definitions](/docs/guides/workflows/definitions) | +| `/workflows/:id` | Inspect activities, dependencies, plans, and runs | Workflow, plan, and execution reads | [Workflow definitions](/docs/guides/workflows/definitions) | +| `/workflows/:id/plans/new` | Generate candidates or define a manual plan | `/planning-sessions/`, `/schedule-plans/` | [Plan a workflow](/docs/guides/workflows/planning) | +| `/planning-sessions` | List algorithm comparison sessions | `/planning-sessions/` | [Plan a workflow](/docs/guides/workflows/planning) | +| `/planning-sessions/:id` | Follow algorithms and compare candidates | Planning session and candidate endpoints | [Plan a workflow](/docs/guides/workflows/planning) | +| `/plans` | Aggregate plan index | `/schedule-plans/` | [Plan a workflow](/docs/guides/workflows/planning) | +| `/plans/:id` | Inspect a saved plan | `/schedule-plans/:planId/` | [Plan a workflow](/docs/guides/workflows/planning) | +| `/workflows/:workflowId/plans/:id` | Inspect one plan and its predicted Gantt | `/schedule-plans/:planId/` | [Plan a workflow](/docs/guides/workflows/planning) | +| `/executions` | Filter workflow, standalone, and interactive runs | `/execution-runs/` | [Execute and monitor](/docs/guides/workflows/executions) | +| `/executions/:id` | Inspect a run outside the workflow-specific path | `/execution-runs/:runId/` | [Execute and monitor](/docs/guides/workflows/executions) | +| `/executions/:id/activities/:activityId` | Inspect an activity from that run | Execution context returned with the run detail | [Execute and monitor](/docs/guides/workflows/executions) | +| `/workflows/:workflowId/plans/:planId/executions/:id` | Compare the selected plan with observed execution | `/execution-runs/:runId/` | [Execute and monitor](/docs/guides/workflows/executions) | +| `/workflows/:workflowId/plans/:planId/executions/:id/activities/:activityId` | Inspect one activity attempt | Execution context returned with the run detail | [Execute and monitor](/docs/guides/workflows/executions) | +| `/executions/new` | Start a run from a plan | `POST /execution-runs/` | [Execute and monitor](/docs/guides/workflows/executions) | ## Infrastructure | Desktop route | Purpose | API family | Guide | |---|---|---|---| -| `/environments` | List connected and simulated environments | `/environments/` | [Environments](../guides/infrastructure/environments) | -| `/environments/new` | Connect real infrastructure or define simulation infrastructure | Environments, connection tests, SSH keys, Kubernetes tokens | [Environments](../guides/infrastructure/environments) | -| `/environments/:id` | Inspect one environment and its ownership hierarchy | `/environments/:environmentId/` | [Environments](../guides/infrastructure/environments) | -| `/environments/:id/edit` | Replace an environment definition or connection | Environment and connection updates | [Environments](../guides/infrastructure/environments) | -| `/environments/:id/inventory` | Inspect discovered compute, partitions, nodes, and filesystems | Environment discovery and `/resources/` | [Environments](../guides/infrastructure/environments) | -| `/environments/:id/storages` | Browse approved storage roots | `/storages/` | [Storage](../guides/infrastructure/storage) | -| `/resources` | Aggregate compute inventory | `/resources/` | [Execution scopes](../guides/infrastructure/execution-scopes) | -| `/resources/:id` | Inspect capacity, bindings, snapshots, and provisioning | `/resources/:resourceId/` | [Execution scopes](../guides/infrastructure/execution-scopes) | -| `/execution-scopes` | List planning boundaries | `/execution-scopes/` | [Execution scopes](../guides/infrastructure/execution-scopes) | -| `/execution-scopes/new` | Combine environment versions | `POST /execution-scopes/` | [Execution scopes](../guides/infrastructure/execution-scopes) | -| `/network` | List network topologies | `/network-topologies/` | [Execution scopes](../guides/infrastructure/execution-scopes) | -| `/network/new` | Create topology metadata and links | `POST /network-topologies/` | [Execution scopes](../guides/infrastructure/execution-scopes) | -| `/machine-configurations` | Validate and version configuration playbooks | `/machine-configurations/` | [Cloud capacity](../guides/infrastructure/cloud-capacity) | -| `/environments/:id/cloud-capacity` | Refresh provider catalog and configure capacity targets | Cloud catalog and capacity-target endpoints | [Cloud capacity](../guides/infrastructure/cloud-capacity) | -| `/environments/:id/provisioning` | List environment provisioning operations | `/cloud-operations/` | [Cloud capacity](../guides/infrastructure/cloud-capacity) | -| `/resources/:resourceId/provisioning/:instanceId` | Follow a resource-owned operation and logs | Cloud instance and operation endpoints | [Cloud capacity](../guides/infrastructure/cloud-capacity) | +| `/environments` | List connected and simulated environments | `/environments/` | [Environments](/docs/guides/infrastructure/environments) | +| `/environments/new` | Connect real infrastructure or define simulation infrastructure | Environments, connection tests, SSH keys, Kubernetes tokens | [Environments](/docs/guides/infrastructure/environments) | +| `/environments/:id` | Inspect one environment and its ownership hierarchy | `/environments/:environmentId/` | [Environments](/docs/guides/infrastructure/environments) | +| `/environments/:id/edit` | Replace an environment definition or connection | Environment and connection updates | [Environments](/docs/guides/infrastructure/environments) | +| `/environments/:id/inventory` | Inspect discovered compute, partitions, nodes, and filesystems | Environment discovery and `/resources/` | [Environments](/docs/guides/infrastructure/environments) | +| `/environments/:id/storages` | Browse approved storage roots | `/storages/` | [Storage](/docs/guides/infrastructure/storage) | +| `/resources` | Aggregate compute inventory | `/resources/` | [Execution scopes](/docs/guides/infrastructure/execution-scopes) | +| `/resources/:id` | Inspect capacity, bindings, snapshots, and provisioning | `/resources/:resourceId/` | [Execution scopes](/docs/guides/infrastructure/execution-scopes) | +| `/execution-scopes` | List planning boundaries | `/execution-scopes/` | [Execution scopes](/docs/guides/infrastructure/execution-scopes) | +| `/execution-scopes/new` | Combine environment versions | `POST /execution-scopes/` | [Execution scopes](/docs/guides/infrastructure/execution-scopes) | +| `/execution-scopes/:id` | Inspect a saved scope | `/execution-scopes/:scopeId/` | [Execution scopes](/docs/guides/infrastructure/execution-scopes) | +| `/network` | List network topologies | `/network-topologies/` | [Execution scopes](/docs/guides/infrastructure/execution-scopes) | +| `/network/new` | Create topology metadata and links | `POST /network-topologies/` | [Execution scopes](/docs/guides/infrastructure/execution-scopes) | +| `/network/:id` | Inspect a saved topology | `/network-topologies/:topologyId/` | [Execution scopes](/docs/guides/infrastructure/execution-scopes) | +| `/machine-configurations` | Validate and version configuration playbooks | `/machine-configurations/` | [Machine configurations](/docs/guides/infrastructure/machine-configurations) | +| `/environments/:id/cloud-capacity` | Refresh provider catalog and configure capacity targets | Cloud catalog and capacity-target endpoints | [Cloud capacity](/docs/guides/infrastructure/cloud-capacity) | +| `/environments/:id/provisioning` | List environment provisioning operations | `/cloud-operations/` | [Cloud capacity](/docs/guides/infrastructure/cloud-capacity) | +| `/environments/:id/provisioning/:instanceId` | Follow an instance from its environment | Cloud instance and operation endpoints | [Cloud capacity](/docs/guides/infrastructure/cloud-capacity) | +| `/resources/:resourceId/provisioning/:instanceId` | Follow a resource-owned operation and logs | Cloud instance and operation endpoints | [Cloud capacity](/docs/guides/infrastructure/cloud-capacity) | ## Artifacts, evidence, and operations | Desktop route | Purpose | API family | Guide | |---|---|---|---| -| `/artifacts` | List executable artifact definitions | `/artifacts/` | [Artifacts and builds](../guides/data/artifacts) | -| `/artifacts/new` | Register an OCI artifact or start a build | Artifact and build endpoints | [Artifacts and builds](../guides/data/artifacts) | -| `/artifacts/:id` | Inspect versions, locations, builds, and materializations | Artifact detail families | [Artifacts and builds](../guides/data/artifacts) | -| `/artifact-locations` | Compatibility/aggregate location catalog | `/artifact-locations/` | [Artifacts and builds](../guides/data/artifacts) | -| `/materializations` | Compatibility/aggregate materialization catalog | `/artifact-materializations/` | [Artifacts and builds](../guides/data/artifacts) | -| `/data` | Generated scientific data grouped by workflow | Provenance data projections | [Provenance and audit](../guides/data/provenance-and-audit) | -| `/provenance` | Explore entities, SQL, and lineage | `/provenance/` | [Provenance and audit](../guides/data/provenance-and-audit) | -| `/audit` | Search operational history | `/audit-events/` | [Provenance and audit](../guides/data/provenance-and-audit) | -| `/console` | Open interactive terminal sessions | `/console-commands/`, `/console-sessions/` | [Interactive console](../guides/operations/interactive-console) | -| `/settings` | Manage identity, appearance, instance archives, and reset | Instance and preference endpoints | [Instance management](../guides/operations/instance-management) | -| `/settings/ssh-keys` | Generate or import daemon-owned SSH keys | `/ssh-keys/` | [Credentials and SSH](../guides/operations/credentials-and-ssh) | +| `/artifacts` | List executable artifact definitions | `/artifacts/` | [Build an executable](/docs/guides/data/build-executable) | +| `/artifacts/new` | Register an OCI artifact or start a build | Artifact and build endpoints | [Build an executable](/docs/guides/data/build-executable) | +| `/artifacts/:id` | Inspect versions, locations, builds, and materializations | Artifact detail families | [Artifact locations](/docs/guides/data/artifact-locations) | +| `/artifact-locations` | Compatibility/aggregate location catalog | `/artifact-locations/` | [Artifact locations](/docs/guides/data/artifact-locations) | +| `/materializations` | Compatibility/aggregate materialization catalog | `/artifact-materializations/` | [Artifact locations](/docs/guides/data/artifact-locations) | +| `/data` | Generated scientific data grouped by workflow | Provenance data projections | [Trace a result](/docs/guides/data/provenance) | +| `/provenance` | Explore entities, SQL, and lineage | `/provenance/` | [Trace a result](/docs/guides/data/provenance) | +| `/audit` | Inspect recorded connection, discovery, and console events | `/audit-events/` | [Inspect audit events](/docs/guides/data/audit-events) | +| `/console` | Open interactive terminal sessions | `/console-commands/`, `/console-sessions/` | [Interactive console](/docs/guides/operations/interactive-console) | +| `/settings` | Manage identity, appearance, instance archives, and reset | Instance and preference endpoints | [Instance management](/docs/guides/operations/instance-management), [Personal preferences](/docs/guides/operations/personal-preferences) | +| `/settings/ssh-keys` | Generate or import daemon-owned SSH keys | `/ssh-keys/` | [SSH service keys](/docs/guides/operations/credentials-and-ssh) | ## Redirects and compatibility routes @@ -67,12 +75,3 @@ This matrix is maintained as the coverage checklist for the public documentation - `/builds` redirects to the artifact catalog because builds belong to artifacts. - `/ssh-keys` redirects to `/settings/ssh-keys`. - Environment-level provisioning is an aggregate index; an individual provisioning operation belongs to its resource. - -## Verification rule - -When a Desktop route or daemon endpoint is added, the same change must update or regenerate this documentation: - -1. Endpoint pages regenerate automatically from the Go router. -2. The relevant domain guide explains the user task and payload semantics. -3. This matrix records where the operation appears in Desktop. -4. A screenshot is added only when the spatial interface conveys information that text does not. diff --git a/docs/docs/reference/planning-and-execution-states.md b/docs/docs/reference/planning-and-execution-states.md index 94092ffe..2472cc5a 100644 --- a/docs/docs/reference/planning-and-execution-states.md +++ b/docs/docs/reference/planning-and-execution-states.md @@ -14,7 +14,7 @@ This reference distinguishes the state-bearing records used by AkôFlow planning Planning flow from request to selected plan and separate execution flow from request through durable queue job to terminal evidence. -A planning request is persisted as a session and publishes a queue job. An execution request first publishes a queue job; a workflow `ExecutionRun` is created only when the daemon starts processing that job. Consequently, an accepted execution request may not yet appear in `GET /execution-runs/`. +A planning request is persisted as a session and publishes a queue job. An execution request first publishes a queue job; the worker validates it before creating an `ExecutionRun`. An accepted request may not yet appear in `GET /execution-runs/`, and an invalid queued request may never produce a run. ## Planning session @@ -34,7 +34,9 @@ The cancellation endpoint returns a conflict for a completed or failed session, Each selected algorithm creates an `AlgorithmRun` within the session. It uses the same status values: `queued`, `running`, `completed`, `failed`, and `cancelled`. -Algorithm runs execute sequentially under the session's coordinator. A session can therefore be `running` while one algorithm run is `running` and later runs remain `queued`. A failed algorithm run does not automatically fail the session: other selected algorithms continue. The session fails only if there are no valid candidates after all work has finished. `progress` is a fraction between the completed algorithm runs; it is not a count of evaluated schedule states. `estimate` carries a predicted planning duration, search-space metadata, and confidence for that one algorithm run. +Algorithm runs execute sequentially. A session can be `running` while one algorithm run is `running` and later runs remain `queued`. If one algorithm fails, the others continue. The session fails only when none produces a valid candidate. + +`progress` is a fraction based on completed algorithm runs, not a count of evaluated schedules. `estimate` carries a predicted planning duration, search-space metadata, and confidence for one algorithm run. ## Candidates are not state machines @@ -42,7 +44,7 @@ A `PlanCandidate` has no `status` field. It is an immutable generated option ass | Field | Meaning | | --- | --- | -| `feasible` | The candidate passed plan validation and may be selected. Infeasible candidates cannot be promoted. | +| `feasible` | The candidate passed plan validation and may be selected. It does not confirm a runtime binding for execution. Infeasible candidates cannot be promoted. | | `rank` | Comparison order after session completion. Lower rank is preferred by the common ranking step. | | `paretoOptimal` | The candidate is on the non-dominated time/cost frontier. | | `dominated` | Another feasible candidate is no worse in both predicted metrics and better in at least one. | @@ -52,7 +54,7 @@ Candidates may appear while an algorithm run and its parent session are still `r ## Selecting a candidate and schedule plans -A `SchedulePlan` does **not** have a lifecycle status. It is the canonical persisted plan containing assignments, predicted metrics, algorithm/source information, and lifecycle actions. It can originate from a manual plan, an import, or a selected candidate. +A `SchedulePlan` does **not** have a lifecycle status. It is the saved plan containing assignments, predicted metrics, algorithm/source information, and lifecycle actions. It can originate from a manual plan, an import, or a selected candidate. `POST /planning-sessions/{sessionId}/candidates/{candidateId}/select/` promotes a feasible candidate. The API verifies that the candidate belongs to the session and is feasible, stores its embedded plan if it is new, and records `selectedCandidateId` and `selectedPlanId` on the session. It currently does not require the session to be `completed`, so clients should normally wait for completed ranking before selecting unless they deliberately choose an early candidate. @@ -60,7 +62,7 @@ Selecting another feasible candidate updates the session's selected IDs; it does ## Workflow execution runs -Workflow execution uses a distinct `ExecutionRun` lifecycle. Submit `POST /execution-runs/`; it returns an accepted queue job. Once the daemon consumes that job, the supervisor creates the run and begins execution. +Workflow execution uses a distinct `ExecutionRun` lifecycle. `POST /execution-runs/` returns an accepted queue job. Once the worker validates that job, the supervisor creates the run and begins execution. If worker validation fails, no run record is created. | State | How it is reached | Meaning | Terminal? | | --- | --- | --- | --- | @@ -77,7 +79,7 @@ Task records offer finer-grained evidence than the workflow-run badge: | Record | States | Notes | | --- | --- | --- | -| `TaskExecution` | `blocked`, `ready`, `preparing`, `running`, `completed`, `failed`, `cancelled` | The domain supports all values. The current supervisor persists running and completed task records for normal execution; failure/cancellation can be recorded from runtime outcomes. | +| `TaskExecution` | `blocked`, `ready`, `preparing`, `running`, `completed`, `failed`, `cancelled` | The domain supports all values. The current workflow supervisor persists `running`, `completed`, and `failed`; a stopped or failed runtime handle produces a failed task. The other values are not a normal workflow-run progression today. | | `ActivityHandle` | `starting`, `running`, `completed`, `failed`, `stopped` | Runtime adapter identity, such as a Kubernetes Job, Slurm Job, PID, or simulation event. `stopped` is surfaced as a failed task with the handle failure reason in task reads. | Task-stage totals such as `queueSeconds`, `transferSeconds`, and `runtimeSeconds` are accumulated over all tasks. They are diagnostic totals, not wall-clock makespan. Use the run's `makespanSeconds` and task timestamps to understand elapsed time. @@ -92,4 +94,4 @@ Task-stage totals such as `queueSeconds`, `transferSeconds`, and `runtimeSeconds | Wait for execution | `GET /execution-runs/{runId}/` after the daemon creates the run | Run is `completed` or `failed`. | | Explain an observed result | Run projection tasks, transfers, events, and Plan vs execution view | Task/transfer records account for the observed critical path. | -Related material: [planning a workflow](../guides/workflows/planning), [execution evidence](../guides/workflows/executions), [execution scopes and topologies](./execution-scopes-and-topologies), and [provenance and audit](../guides/data/provenance-and-audit). +Related material: [planning a workflow](/docs/guides/workflows/planning), [execution evidence](/docs/guides/workflows/executions), [execution scopes and topologies](/docs/reference/execution-scopes-and-topologies), and [provenance and audit](/docs/guides/data/provenance-and-audit). diff --git a/docs/docs/runtimes.md b/docs/docs/runtimes.md index 06d1432f..e3559aea 100644 --- a/docs/docs/runtimes.md +++ b/docs/docs/runtimes.md @@ -2,15 +2,18 @@ id: runtimes title: Runtime adapters sidebar_label: Runtime adapters +description: How AkôFlow maps planned activities to local, HPC, Kubernetes, cloud, and simulated runtimes. --- -A runtime adapter translates an assigned activity into operations on an execution technology. Runtimes belong to an environment version and connect to resources through bindings. Workflows do not select a runtime through a legacy top-level YAML `runtime` field; a selected plan assigns resources and execution resolves their bindings. +A runtime adapter translates an assigned activity into operations on an execution technology. Runtimes belong to an environment version and connect to resources through bindings. Execution resolves the binding for each planned assignment. -This explanation focuses on the adapter boundary. Read [system architecture](./concepts) for the surrounding records and [execution control plane](./engine) for how the supervisor uses adapters. +This explanation focuses on runtime adapters. Read [Architecture internals](/docs/modules) for the surrounding services and [Execution control plane](/docs/engine) for how the server uses adapters. ## Runtime model -Each runtime declares `id`, name, driver, `execution` or `simulation` mode, optional role/configuration, and capabilities such as batch, interactive, container, GPU, MPI, shared storage, staging, cancellation, log streaming, and simulation. +Each runtime has an ID, driver, and `execution` or `simulation` mode. Its configuration and declared capabilities describe what the driver can do. For example, a batch runtime may declare container and shared-storage support; these declarations do not verify a particular cluster or account. The [environment reference](/docs/reference/environment-yaml) lists the fields. + +The portable workflow document does not select a runtime through a top-level YAML `runtime` field. A plan assigns resources; execution resolves their runtime bindings. Adapters implement `Modes`, `Start`, `Inspect`, and `Stop`. A common handle keeps provider identifiers out of orchestration code. @@ -24,9 +27,9 @@ Adapters implement `Modes`, `Start`, `Inspect`, and `Stop`. A common handle keep | `slurm` | Batch submission or explicit direct target | real | | `simgrid` | Plan/activity simulation | simulation | | `cloud` | Capacity resolved to a concrete runtime allocation | real via lifecycle binding | -| `serverless` | Reserved domain capability | depends on registered provider | +| `serverless` | Schema value only; no built-in adapter | unavailable | -A driver value in the domain model does not prove that its provider is configured in a particular instance. +A driver value in the domain model does not prove that its provider is implemented or configured in a particular instance. The current server has no serverless runtime adapter. ## Local @@ -46,7 +49,7 @@ Slurm renders an `sbatch` script from activity, resource, and preparation contex ## SimGrid -Simulation is a mode, not a fake infrastructure connection. It uses frozen inventory, profiles, topology, transfer costs, and optional interference data to produce a trace without starting jobs. Participating activities declare the `simulation` capability and simulation definition. +Simulation uses frozen inventory, profiles, topology, transfer costs, and optional interference data to produce a trace without starting jobs. Participating activities declare the `simulation` capability and simulation definition. ## Cloud @@ -63,21 +66,12 @@ Inventory refresh must not mutate the frozen inputs of an existing planning sess ## Data access -Execution is preceded by preparation. Routes may use an existing verified location, shared storage, destination pull, source push, gateway, runtime-local, or direct-runtime transfer. Implementations include artifact store, filesystem, rsync/SSH, Kubernetes exec, HTTP, S3-compatible storage, and GCS. An adapter must reject an uncommitted preparation gate. - -## Choose a target - -In Desktop: +Execution is preceded by preparation. Routes may use an existing verified location, shared storage, destination pull, source push, gateway, runtime-local, or direct-runtime transfer. Implemented connectors include artifact store, filesystem, rsync/SSH, Kubernetes exec, HTTP download, and S3-compatible transfer. Direct `gs://` transfer is unavailable in the current server; the GCS connector returns an error until a deployment supplies a working transfer agent. -1. create an environment and connection; -2. validate it and run discovery; -3. review resources, bindings, storage, and capabilities in the inventory; -4. include the published version in an execution scope; -5. plan the workflow and inspect candidate assignments; -6. select a plan and start the required execution mode. +## User procedures -API clients perform the equivalent environment, check, discovery, scope, planning, selection, and execution operations. Use the generated API Reference for exact current routes. +To connect infrastructure, use [Create and inspect environments](/docs/guides/infrastructure/environments). For the task flow after registration, follow [Define execution scopes](/docs/guides/infrastructure/execution-scopes), [Plan a workflow](/docs/guides/workflows/planning), and [Execute and monitor a workflow](/docs/guides/workflows/executions). Those guides keep the user steps separate from adapter details here. ## Provider extension boundary -A complete provider generally needs an adapter, resolver/factory registration, probing and discovery for external infrastructure, endpoint/transfer integration, capability declarations, and tests for start, inspect, stop, failures, and artifact observation. Provider behavior stays behind ports; workflow, planning, and execution domain objects remain provider-neutral. +Adding a provider starts with an adapter registered for its driver and mode. External infrastructure also needs a connection check and discovery. Data access may need a transfer route. Test activity start, inspection, stop, failures, and output observation before documenting the provider as supported. Keep these provider details behind the runtime interface so workflow and plan records remain provider-neutral. diff --git a/docs/docs/showcase/edge-cloud-simulation.mdx b/docs/docs/showcase/edge-cloud-simulation.mdx index 4e885bf3..892c9a47 100644 --- a/docs/docs/showcase/edge-cloud-simulation.mdx +++ b/docs/docs/showcase/edge-cloud-simulation.mdx @@ -10,9 +10,9 @@ import {FileList, WorkflowDiagram} from '@site/src/components/WorkflowShowcase'; -This is a complete, deterministic SimGrid tutorial. It runs `prepare → analyze → summarize`: the 12-second analysis runs on a cloud VM that is four times faster than the edge device, then its result returns to the edge. The placement gains compute time and pays for two network flows and cloud use. +This is a complete, deterministic SimGrid tutorial. It runs `prepare → analyze → summarize`: the 12-second analysis runs on a modeled cloud resource four times faster than the edge resource, then its result returns to the edge. Faster compute trades against two modeled transfers and resource cost. -Use it when you want a small workflow whose planned and observed values can be inspected end to end. Do not use the checked-in manual plan to compare schedulers: generate a planning session instead when the goal is to compare PRISM and HEFT candidates. +Use it to inspect planned and observed values for a small workflow. The checked-in manual plan fixes placement; to compare PRISM and HEFT, generate a planning session. ## What the simulation models @@ -28,47 +28,34 @@ The diagram and the workflow YAML show the same topology: `prepare` produces `da ## Download the inputs - Environment YAML ↓ - Execution scope YAML ↓ - Network topology YAML ↓ - Workflow YAML ↓ - Manual plan envelope ↓ - Execution envelope ↓ + Environment YAML ↓ + Execution scope YAML ↓ + Network topology YAML ↓ + Workflow YAML ↓ + Manual plan envelope ↓ + Execution envelope ↓ + Submission script ↓ -

Run with AkôFlow Desktop

+

Inspect the API run in Desktop

+

Submit the versioned bundle through the API path below. Desktop can inspect its records only when connected to that same server. The packaged Desktop manages a separate local server by default.

    -
  1. Open Infrastructure → Environments and create a simulation environment matching environment.yaml. Add the SimGrid runtime, then bind it to the edge and cloud resources. Set cores, speedup, price, boot, and container values before planning.
  2. -
  3. Open Infrastructure → Execution scopes and create the scope from scope.yaml. Attach a topology matching topology.yaml: it must include both directions of the 100 Mbit/s link. A scope without this link cannot predict the cross-resource transfers in this example.
  4. -
  5. Open Workflows → Definitions and import workflow.yaml. Open the imported workflow and check the Definition graph: it must contain three activities and the two arrows prepare → analyze → summarize. Select an activity to confirm that it is simulatable and has its own duration profile.
  6. -
  7. To reproduce the documented placement, choose Generate plan, select Create manually, choose the simulation scope, then place prepare and summarize on the edge and analyze on cloud. The portable plan-request.yaml is the API equivalent of this choice.
  8. -
  9. To compare algorithms instead, choose Generate plans, select the same scope, and run the desired candidates. Expand a candidate to inspect its Gantt chart before selecting it.
  10. -
  11. Start the selected simulation. On the completed run, use Data for the two data flows and Plan vs execution for predicted versus observed makespan and cost.
  12. +
  13. Open Infrastructure → Environments and inspect the saved edge and cloud resources.
  14. +
  15. Open Workflows → Definitions and confirm the three-activity graph.
  16. +
  17. Open the completed run. Use Data to inspect two transfers and Plan vs execution to compare prediction with observation.
+

A Desktop-only submission of this complete bundle has not been verified. The current Desktop navigation does not expose link creation; the verified API path registers the network model supplied here.

} api={

Run through the API

-

Run this in a fresh AkôFlow instance, or change every ID in the six YAML files first. The API treats these identifiers as persistent objects and rejects duplicate IDs. From the repository root, set the daemon address and token, then submit the complete bundle:

-
{`export AKOFLOW_API_URL="http://127.0.0.1:8080/akoflow-api"
-export AKOFLOW_API_TOKEN=""
-
-post_yaml() {
-  curl --fail-with-body \\
-    -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \\
-    -H 'Content-Type: application/yaml' \\
-    --data-binary "@$2" "$AKOFLOW_API_URL/$1/"
-}
-
-post_yaml environments examples/simulation/environment.yaml
-post_yaml execution-scopes examples/simulation/scope.yaml
-post_yaml network-topologies examples/simulation/topology.yaml
-post_yaml workflow-definitions examples/simulation/workflow.yaml
-post_yaml schedule-plans examples/simulation/plan-request.yaml
-post_yaml execution-runs examples/simulation/execution-request.yaml`}
+

Complete API connection setup. Run this in a fresh AkôFlow instance, or change every ID in the six YAML files first. Clone the v1.0.8 files, or use an existing matching checkout, then submit the bundle:

+
{`git clone --branch v1.0.8 --depth 1 https://github.com/UFFeScience/akoflow.git akoflow-showcase
+cd akoflow-showcase
+sh examples/simulation/run.sh`}

Submitting execution-runs acknowledges the request; it does not mean the execution has completed. Poll the immutable run projection until status is completed:

-
{`curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \\
+    
{`curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \\
   "$AKOFLOW_API_URL/execution-runs/simulation-example-run-v1/"`}
} /> @@ -87,7 +74,7 @@ post_yaml execution-runs examples/simulation/execution-request.yaml`} -This example executes two real container activities on a local Kind cluster. Use it after the simulation walkthrough to validate runtime credentials, persistent storage, Kubernetes Jobs, logs, artifacts, and provenance. +This example executes two real container activities on a local Kind cluster. Use it after the simulation walkthrough to check runtime access, persistent storage, Kubernetes Jobs, logs, and output files. :::warning Development environment The checked-in access manifest intentionally grants broad permissions for a disposable local cluster. Do not reuse it in production. @@ -19,36 +19,35 @@ The checked-in access manifest intentionally grants broad permissions for a disp ## Download the inputs - Kind cluster ↓ - AkôFlow access ↓ - Persistent storage YAML ↓ - Environment YAML ↓ - Execution scope YAML ↓ - Network topology YAML ↓ - Workflow YAML ↓ - Plan envelope ↓ - Execution envelope ↓ + Kind cluster ↓ + AkôFlow access ↓ + Persistent storage YAML ↓ + Environment YAML ↓ + Execution scope YAML ↓ + Network topology YAML ↓ + Workflow YAML ↓ + Plan envelope ↓ + Execution envelope ↓ -

Run with AkôFlow Desktop

+

Inspect the API run in Desktop

+

Use the verified Kind and API procedure below. Desktop can inspect the run when it connects to that same server; the packaged Desktop uses a separate local server by default.

    -
  1. Create the Kind cluster and apply akoflow-access.yaml and storage.yaml.
  2. -
  3. Generate a short-lived ServiceAccount token. In Infrastructure → Environments, create the Kubernetes connection and store the token through the credential flow; do not paste it into the workflow.
  4. -
  5. Test the connection and run discovery. Confirm that the Kind worker appears as a schedulable resource.
  6. -
  7. Create a scope and topology matching the supplied YAML, then import dag.yaml under Workflows → Definitions.
  8. -
  9. Create a manual plan or generate candidates, select the Kind resource, and start a Real execution.
  10. -
  11. Inspect activity logs, generated files, artifacts, timeline, events, and provenance after completion.
  12. +
  13. Open the Kubernetes environment and confirm the discovered Kind worker.
  14. +
  15. Open the imported two-activity workflow and its saved plan.
  16. +
  17. Open the completed run to inspect Job logs, transferred data, output files, and events. Follow provenance when its explorer is configured.
+

A complete Desktop-only Kind submission has not been verified.

} api={

Run through the API

-

After creating the cluster and token as described in the complete Kind README, submit the same objects:

-
{`export AKOFLOW_API_URL="http://127.0.0.1:8080/akoflow-api"
-export AKOFLOW_API_TOKEN=""
-
-for pair in \\
+    

Complete API connection setup and clone v1.0.8, or use an existing matching checkout:

+
{`git clone --branch v1.0.8 --depth 1 https://github.com/UFFeScience/akoflow.git akoflow-showcase
+cd akoflow-showcase`}
+

From that checkout, follow the Kind README to create the cluster and token. Then use a fresh instance and submit:

+
{`for pair in \\
   "environments examples/kind/environment.yaml" \\
   "execution-scopes examples/kind/scope.yaml" \\
   "network-topologies examples/kind/topology.yaml" \\
@@ -71,4 +70,4 @@ A successful run produces two Kubernetes Jobs, a workspace PVC for each activity
 
 The checked-in bundle was executed from a clean Kind cluster on 2026-09-11 as `kind-dag-run-v8`: both activities completed, 9 bytes were transferred, and both files had checksum `sha256:cb064c1339ffa3d7777bcb0459de3dceddb9146156dde58065a4ac826b029aa7`. Its observed makespan was 17.776 s. Kubernetes scheduling and Pod startup are included in that wall-clock result.
 
-If the consumer Job remains `Pending`, use `kubectl describe pod ` to inspect PVC/node affinity. The full setup, verification, and cleanup procedure is in the [Kind README](https://github.com/UFFeScience/akoflow/tree/main/examples/kind).
+If the consumer Job remains `Pending`, use `kubectl describe pod ` to inspect PVC/node affinity. The full setup, verification, and cleanup procedure is in the [Kind README](https://github.com/UFFeScience/akoflow/tree/v1.0.8/examples/kind).
diff --git a/docs/docs/showcase/local-direct-execution.mdx b/docs/docs/showcase/local-direct-execution.mdx
index 76bae307..607c49d8 100644
--- a/docs/docs/showcase/local-direct-execution.mdx
+++ b/docs/docs/showcase/local-direct-execution.mdx
@@ -1,6 +1,6 @@
 ---
 title: Local direct execution
-description: Run a verified host-local workflow and inspect its output artifact through AkôFlow Desktop or the API.
+description: Run a verified host-local workflow through the API and inspect its output artifact.
 ---
 
 import InterfaceApiTabs from '@site/src/components/InterfaceApiTabs';
@@ -10,58 +10,59 @@ import {FileList, WorkflowDiagram} from '@site/src/components/WorkflowShowcase';
 
 
 
-This Showcase executes one real activity through the `local` runtime. The daemon starts the activity command on the **same host as the daemon**, then observes its workspace for created or changed files. It is useful for a controlled first real execution or a small trusted host-local tool.
+This Showcase executes one real activity through the `local` runtime. The AkôFlow server starts the command on its own host, then records files created or changed in the activity workspace. Use it for a controlled first real execution or a small trusted tool on the server host.
+
+For a first run entirely in Desktop, follow [Run your first workflow](/docs/guides/workflows/first-local-run). This Showcase reproduces a versioned API bundle.
 
 Do not use this runtime to isolate untrusted workloads. It is not a container sandbox, and it does not submit work to a Kubernetes cluster or a SLURM allocation.
 
 ## Prerequisites
 
-- An AkôFlow daemon running on the host that is allowed to execute the command.
-- A POSIX `sh` and `printf` available to that daemon process.
+- An AkôFlow server running on a host that is allowed to execute the command.
+- A POSIX `sh` and `printf` available to the server process.
 - Permission to run a trusted command and to create its temporary activity workspace.
 
-The bundle declares `busybox:1.36` as an executable reference because portable real-workflow imports require one. The local adapter does **not** pull or run that image: it invokes `command.entrypoint` and `command.arguments` on the daemon host.
+The bundle declares `busybox:1.36` as an executable reference because portable real-workflow imports require one. The local adapter does **not** pull or run that image: it invokes `command.entrypoint` and `command.arguments` on the server host.
 
 ## Download the inputs
 
 
-  Environment YAML ↓
-  Execution scope YAML ↓
-  Network topology YAML ↓
-  Workflow YAML ↓
-  Manual plan envelope ↓
-  Execution envelope ↓
-  Submission script ↓
+  Environment YAML ↓
+  Execution scope YAML ↓
+  Network topology YAML ↓
+  Workflow YAML ↓
+  Manual plan envelope ↓
+  Execution envelope ↓
+  Submission script ↓
 
 
 
-    

Run with AkôFlow Desktop

+

Inspect the API run in Desktop

+

Submit the versioned bundle through the API path below, then open Desktop connected to the same server.

    -
  1. In Infrastructure → Environments, create the local environment and its local-host resource from environment.yaml. Keep its execution target as Direct.
  2. -
  3. Create the scope and topology from the supplied YAML. This one-host Showcase deliberately has no network links.
  4. -
  5. In Workflows → Definitions, import workflow.yaml. Open its definition and confirm that write-report is a real activity assigned to the local runtime.
  6. -
  7. Create a manual plan with write-report on local-host, or import plan.yaml through the plan API. Start a Real execution.
  8. -
  9. When the run is complete, open its activity details and artifacts. Verify that result.txt is listed as a created file.
  10. +
  11. Open the local environment and confirm that local-host is the assigned resource.
  12. +
  13. Open the completed run and inspect the activity's artifacts. Confirm that result.txt is listed as a created file.
-

The host that runs Desktop is not necessarily the execution host; the daemon's host is. Check that distinction before starting a direct run.

+

The command runs on the server host, which may differ from the Desktop host. Desktop-only submission of this bundle has not been verified.

} api={

Run through the API

-

From the repository root, submit the versioned files in their required order:

-
{`export AKOFLOW_API_URL="http://127.0.0.1:8080/akoflow-api"
-# Set AKOFLOW_API_TOKEN too when this daemon requires authentication.
+    

Complete API connection setup. Clone v1.0.8, or use an existing matching checkout, then run the script from its root:

+
{`git clone --branch v1.0.8 --depth 1 https://github.com/UFFeScience/akoflow.git akoflow-showcase
+cd akoflow-showcase
 sh examples/local/direct-hello/run.sh
 
 curl --fail-with-body \
+  -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \
   "$AKOFLOW_API_URL/execution-runs/local-direct-hello-run-v1/"`}
-

When the daemon requires a token, set AKOFLOW_API_TOKEN; the supplied script adds the matching bearer header to each request.

+

The supplied script adds a bearer header when AKOFLOW_API_TOKEN is set.

} /> ## Verify the result -The checked-in files were run against an isolated local daemon on 2026-09-12. `local-direct-hello-run-v1` completed its one activity; the recorded artifact manifest contained one created file, `result.txt`, at 24 bytes with checksum: +The checked-in files were run against an isolated local AkôFlow server on 2026-09-12. `local-direct-hello-run-v1` completed its one activity; the recorded artifact manifest contained one created file, `result.txt`, at 24 bytes with checksum: ```text sha256:602b3cbda35539a2cd4c0504fe198cb423493832d93cf78147a470b2d82329db @@ -73,15 +74,15 @@ The observed runtime was approximately 0.006 seconds on that host. Treat that du Akoflow local execution ``` -The run has no data dependency and therefore reports zero transferred bytes. Use the [Kind real-execution Showcase](./kubernetes-real-execution) when you need a workflow that transfers output between activities. +The run has no data dependency and therefore reports zero transferred bytes. Use the [Kind real-execution Showcase](/docs/showcase/kubernetes-real-execution) when you need a workflow that transfers output between activities. ## Troubleshooting | Symptom | Cause and recovery | | --- | --- | | `activity entrypoint is required` | Use the supplied workflow or set `command.entrypoint`; `run` is converted to `sh -c` by the portable workflow importer. | -| `start local activity` fails | The daemon host cannot find or execute the command. Verify `sh` is on its `PATH`, then use an absolute entrypoint if needed. | +| `start local activity` fails | The server host cannot find or execute the command. Verify `sh` is on its `PATH`, then use an absolute entrypoint if needed. | | The activity writes no artifact | The run only records changes made below its activity workspace. Make the command write relative to its working directory, as this example does. | -| The wrong machine executes the command | Direct execution always occurs on the daemon host. Run a daemon in the target environment, or use a remote runtime such as Kubernetes or SLURM instead. | +| The wrong machine executes the command | Direct execution always occurs on the AkôFlow server host. Run the server in the target environment, or use a remote runtime such as Kubernetes or SLURM instead. | -Read [Execution modes and runtimes](../runtimes) for the execution boundary and [Workflow runs](../guides/workflows/executions) for monitoring and cancellation. +Read [Runtime adapters](/docs/runtimes) for where the command runs and [Execute and monitor a workflow](/docs/guides/workflows/executions) for run status and results. diff --git a/docs/docs/showcase/network-fanout.mdx b/docs/docs/showcase/network-fanout.mdx index b9127c21..0700482f 100644 --- a/docs/docs/showcase/network-fanout.mdx +++ b/docs/docs/showcase/network-fanout.mdx @@ -12,7 +12,7 @@ import {FileList, WorkflowDiagram} from '@site/src/components/WorkflowShowcase'; This complete SimGrid experiment makes network sharing visible. `t1` produces three 10 GB dependencies. `t2`, `t3`, and `t4` run concurrently on the three cores of M2, then each sends 10 GB to `t5` on M3. The links are shared: a concurrent flow does not receive the full nominal bandwidth on its own. -Use it to inspect how a placement with parallel tasks can still be limited by its network endpoints. Do not treat the 36-second manual-plan estimate as a universal formula for 10 GB/s networks; the observed trace is the authoritative evidence for the configured sharing model. +Use it to inspect how network endpoints limit parallel tasks. The manual plan's 36-second estimate applies to this model; compare it with the observed trace. ## Model at a glance @@ -27,35 +27,34 @@ Every dependency is 10,000,000,000 bytes. There are six dependencies, so a compl ## Download the model - Environment YAML ↓ - Execution scope YAML ↓ - Network topology YAML ↓ - Workflow YAML ↓ - Plan envelope ↓ - Execution envelope ↓ - Submission script ↓ + Environment YAML ↓ + Execution scope YAML ↓ + Network topology YAML ↓ + Workflow YAML ↓ + Plan envelope ↓ + Execution envelope ↓ + Submission script ↓ -

Explore with AkôFlow Desktop

+

Inspect the API run in Desktop

+

Run the versioned API script below, then open Desktop connected to that same server. The packaged Desktop uses its own local server by default.

    -
  1. Create a simulation environment with M1 (one core), M2 (three cores), and M3 (one core), and bind SimGrid to each resource.
  2. -
  3. Create the scope and attach the two shared, bidirectional 80 Gbit/s links from topology.yaml.
  4. -
  5. Import workflow.yaml. In its Definition graph, confirm that t1 fans out to three activities and that all three converge on t5.
  6. -
  7. Choose Generate plan. Use Create manually to reproduce the checked-in M1 → M2 → M3 assignment, or use Generate plans to compare PRISM Cost, PRISM Time, and HEFT on the same scope.
  8. -
  9. Expand a candidate Gantt. Verify that `t2`, `t3`, and `t4` occupy different M2 cores; then select the plan and start the simulation.
  10. -
  11. On the completed run, open Data to inspect six transfers and Plan vs execution to compare the 36-second estimate with the observed trace.
  12. +
  13. Open the workflow definition and confirm that t1 fans out to t2, t3, and t4, which converge on t5.
  14. +
  15. Open the saved plan and check that the three middle activities use different M2 cores.
  16. +
  17. Open the completed run. Use Data for the six transfers and Plan vs execution for timing.
+

The API script registers the two network links used by this result. The current Desktop navigation does not expose link creation, and a full Desktop-only submission has not been verified.

} api={

Register, plan, and execute through the API

-

From a fresh instance, run the versioned script. It submits the environment, scope, topology, workflow, manual plan, and execution envelope in dependency order:

-
{`export AKOFLOW_API_URL="http://127.0.0.1:8080/akoflow-api"
-export AKOFLOW_API_TOKEN=""
+    

Complete API connection setup and use a fresh AkôFlow instance. Clone v1.0.8, then run the script from that checkout. It submits the environment, scope, topology, workflow, manual plan, and execution envelope in order:

+
{`git clone --branch v1.0.8 --depth 1 https://github.com/UFFeScience/akoflow.git akoflow-showcase
+cd akoflow-showcase
 bash examples/simulation/30gb-fanout/run.sh`}

Poll the run until it reports completed:

-
{`curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \\
+    
{`curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \\
   "$AKOFLOW_API_URL/execution-runs/simgrid-30gb-fanout-run-v1/"`}
} /> diff --git a/docs/docs/showcase/parallel-50-core.mdx b/docs/docs/showcase/parallel-50-core.mdx index 0eda67df..77b0a5f2 100644 --- a/docs/docs/showcase/parallel-50-core.mdx +++ b/docs/docs/showcase/parallel-50-core.mdx @@ -12,7 +12,7 @@ import {FileList, WorkflowDiagram} from '@site/src/components/WorkflowShowcase'; This workload separates *machine capacity* from *activity count*. One hundred independent activities are assigned to M2, a simulated machine with 50 cores. Each activity requests one core and lasts 10 seconds, so the manual plan has two 50-activity waves. The example is useful for checking that a plan uses cores rather than treating a machine as one execution slot. -M1 and M3 are retained only to keep the three-machine SimGrid scope used by the related examples. No activity is assigned to them, and this workflow has no data dependencies. It is deliberately a compute-capacity exercise, not a network experiment. +M1 and M3 remain in the shared three-machine SimGrid scope, but no activity uses them. The workflow has no data dependencies, so its result shows compute capacity and queueing across cores. ## Model at a glance @@ -28,34 +28,34 @@ M1 and M3 are retained only to keep the three-machine SimGrid scope used by the ## Download the complete bundle - Environment YAML ↓ - Execution scope YAML ↓ - Network topology YAML ↓ - Workflow YAML ↓ - Plan envelope ↓ - Execution envelope ↓ - Runnable shell script ↓ + Environment YAML ↓ + Execution scope YAML ↓ + Network topology YAML ↓ + Workflow YAML ↓ + Plan envelope ↓ + Execution envelope ↓ + Runnable shell script ↓ -

Run with AkôFlow Desktop

+

Inspect the API run in Desktop

+

Submit the bundle with the versioned API script below, then use Desktop connected to that server to inspect it.

    -
  1. Open Infrastructure → Environments and create a simulation environment that matches environment.yaml. Add the SimGrid runtime and bind it to M1, M2, and M3. M2 must have 50 schedulable cores.
  2. -
  3. Open Infrastructure → Execution scopes, create the scope and topology from the supplied YAML, then attach the environment version. The links are present for consistency with the other examples but carry no data in this workflow.
  4. -
  5. Open Workflows → Definitions and import workflow.yaml. Its Definition view must contain 100 unconnected worker nodes, each with a 10-second simulation duration.
  6. -
  7. Choose Generate plan, then Create manually. Select the simulation scope and assign workers 001–050 to M2 cores 0–49. Assign workers 051–100 to the same cores after the first wave. The checked-in plan is the API representation of that placement.
  8. -
  9. Expand the plan Gantt chart before starting it. It should show 50 used M2 core lanes, with two adjacent 10-second bars per lane. Start the simulation and compare its plan with the completed run.
  10. +
  11. Open the workflow definition and confirm that it has 100 independent workers with 10-second simulation profiles.
  12. +
  13. Open the saved plan and check for 50 M2 core lanes with two waves of activities.
  14. +
  15. Open the completed run and compare its 20-second makespan with the accumulated activity time.
+

Desktop-only creation and submission of this 100-activity bundle have not been verified.

} api={

Run through the API

-

The checked-in script submits the objects in dependency order and stops on the first HTTP error. Run it against a fresh instance, or change every persistent ID in the bundle:

-
{`export AKOFLOW_API_URL="http://127.0.0.1:8080/akoflow-api"
-export AKOFLOW_API_TOKEN=""
+    

Complete API connection setup. The script submits objects in dependency order and stops on the first HTTP error. Use a fresh instance or change every persistent ID in the bundle, then run it from a v1.0.8 checkout:

+
{`git clone --branch v1.0.8 --depth 1 https://github.com/UFFeScience/akoflow.git akoflow-showcase
+cd akoflow-showcase
 bash examples/simulation/50core-fanout/run.sh`}

Poll the run projection until its status is completed:

-
{`curl -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \\
+    
{`curl --fail-with-body -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \\
   "$AKOFLOW_API_URL/execution-runs/simgrid-50core-workers-run-v2/"`}
} /> @@ -73,4 +73,4 @@ If the makespan is not 20 seconds, check these invariants in order: 3. Each assignment requests one core and uses a distinct `coreId` in its wave. 4. The second wave starts at 10 seconds rather than at 0 seconds on an already occupied core. -For a data-transfer counterpart, see [30 GB network fan-out](./network-fanout). For the distinction between accumulated stage time and makespan, see [Core concepts](../concepts). +For a data-transfer counterpart, see [30 GB network fan-out](/docs/showcase/network-fanout). For the distinction between accumulated stage time and makespan, see [Interpreting observed timing](/docs/explanations/observed-timing). diff --git a/docs/docs/showcase/slurm-local-fixture.mdx b/docs/docs/showcase/slurm-local-fixture.mdx index b1d2419b..7949a31a 100644 --- a/docs/docs/showcase/slurm-local-fixture.mdx +++ b/docs/docs/showcase/slurm-local-fixture.mdx @@ -10,9 +10,9 @@ import {FileList, WorkflowDiagram} from '@site/src/components/WorkflowShowcase'; -This Showcase is a reproducible **adapter fixture**, not a replacement for an HPC cluster. It starts an isolated AkôFlow daemon, puts small `sbatch` and `singularity` fixture commands ahead of the daemon's `PATH`, and runs the generated batch script inside a disposable Alpine container. The activity writes `result.txt`; the normal SLURM adapter observes its completion sentinel and persists the artifact manifest. +This local fixture checks AkôFlow's SLURM batch adapter. It starts an isolated daemon, supplies test `sbatch` and `singularity` commands, and runs the generated batch script in a disposable Alpine container. The activity writes `result.txt`; the adapter observes its completion sentinel and saves the artifact manifest. -Use it to verify a local checkout after changing the SLURM adapter, batch-script generation, or artifact observation. Do **not** use it as evidence that a real cluster's login node, SSH proxy, allocation, `sacct` accounting, `squeue`, `scancel`, shared filesystem, account, QoS, or partition policy is configured correctly. Use [Connect an HPC and SLURM cluster](../guides/infrastructure/hpc-slurm) for that site-approved procedure. +Use it after changing batch-script generation or artifact observation. It does not validate SSH access, scheduler accounting, shared storage, or site policies on a real cluster. For those checks, follow [Connect an HPC and SLURM cluster](/docs/guides/infrastructure/hpc-slurm). ## Prerequisites @@ -20,42 +20,39 @@ Use it to verify a local checkout after changing the SLURM adapter, batch-script - Port `18082` unused for the isolated daemon. - Permission for Docker to pull and run `alpine:3.20`. -The fixture is intentionally local and disposable. It writes all database and generated state under `examples/slurm/local-fixture/.runtime`, `scripts`, `akoflow-*.status`, `akoflow-*.log`, and `akoflow-workspaces`; those paths are ignored by Git. +Generated database and run files stay under `examples/slurm/local-fixture/.runtime`, `scripts`, `akoflow-*.status`, `akoflow-*.log`, and `akoflow-workspaces`; Git ignores those paths. ## Download the inputs - Environment YAML ↓ - Execution scope YAML ↓ - Network topology YAML ↓ - Workflow YAML ↓ - Manual plan YAML ↓ - Execution envelope ↓ - Fixture daemon script ↓ - Submission script ↓ + Environment YAML ↓ + Execution scope YAML ↓ + Network topology YAML ↓ + Workflow YAML ↓ + Manual plan YAML ↓ + Execution envelope ↓ + Fixture daemon script ↓ + Submission script ↓ -

Inspect it with AkôFlow Desktop

-
    -
  1. Start the fixture daemon as described below, then configure Desktop to use http://127.0.0.1:18082/akoflow-api.
  2. -
  3. Under Infrastructure → Environments, import or recreate environment.yaml. Confirm the slurm runtime is bound to the batch partition.
  4. -
  5. Create the scope and empty topology, then import workflow.yaml under Workflows → Definitions.
  6. -
  7. Import the manual plan or create the same one-activity assignment to slurm-fixture-partition. Start a Real execution.
  8. -
  9. Open the completed run. The activity's artifacts must list the created result.txt file.
  10. -
-

Desktop is optional for this fixture. The API path below submits the same versioned files and is the reproducible verification route.

+

Inspect the API run in a connected client

+

Run the fixture through the API path below. If a development Desktop client is configured for that same fixture server, open the completed run and verify that its activity artifacts include result.txt.

+

The packaged Desktop does not automatically connect to the fixture server on port 18082. A Desktop-only fixture submission has not been verified.

} api={

Run the fixture through the API

-

In one terminal, start the isolated daemon from the repository root:

-
{`sh examples/slurm/local-fixture/start-fixture.sh`}
-

Wait until it is listening, then use a second terminal:

+

Clone v1.0.8, or use an existing matching checkout. In one terminal, start the isolated daemon from its root:

+
{`git clone --branch v1.0.8 --depth 1 https://github.com/UFFeScience/akoflow.git akoflow-showcase
+cd akoflow-showcase
+sh examples/slurm/local-fixture/start-fixture.sh`}
+

Wait until it is listening, then open a second terminal at the root of the same checkout:

{`export AKOFLOW_API_URL="http://127.0.0.1:18082/akoflow-api"
 sh examples/slurm/local-fixture/run.sh
 
 curl --fail-with-body \\
+  -H "Authorization: Bearer \${AKOFLOW_API_TOKEN}" \\
   "$AKOFLOW_API_URL/execution-runs/slurm-fixture-run-v1/" \\
   | jq -r '.run.status'`}

The daemon uses no token by default. If your local configuration requires one, set AKOFLOW_API_TOKEN before running the supplied script.

@@ -92,8 +89,6 @@ rm -f examples/slurm/local-fixture/akoflow-*.status \\ examples/slurm/local-fixture/akoflow-*.log ``` -Never apply this cleanup pattern to an actual cluster workspace: those paths are owned by this fixture only. - ## Troubleshooting | Symptom | Cause and recovery | @@ -103,4 +98,4 @@ Never apply this cleanup pattern to an actual cluster workspace: those paths are | The run remains queued | Check that the first terminal is still running and that `sbatch` was invoked from the fixture's `bin` directory. Do not start a second fixture daemon against the same `.runtime` directory. | | The artifact is absent | Inspect `examples/slurm/local-fixture/akoflow-*.log` and `.status`; then confirm Docker can pull `alpine:3.20`. | -Related material: [SLURM/HPC connection guide](../guides/infrastructure/hpc-slurm), [local direct execution](./local-direct-execution), and [workflow runs](../guides/workflows/executions). +Related material: [SLURM/HPC connection guide](/docs/guides/infrastructure/hpc-slurm), [local direct execution](/docs/showcase/local-direct-execution), and [workflow runs](/docs/guides/workflows/executions). diff --git a/docs/docs/tutorials/api-access.md b/docs/docs/tutorials/api-access.md index ca5e663f..f357c3dc 100644 --- a/docs/docs/tutorials/api-access.md +++ b/docs/docs/tutorials/api-access.md @@ -4,10 +4,10 @@ sidebar_label: API connection setup description: Configure one API base URL and token convention for infrastructure tutorials. --- -The infrastructure tutorials offer Desktop and API paths. For the API path, -use Bash, `curl`, `jq`, and a daemon whose address and credential you manage. -The [server installation guide](../guides/operations/server-instance) explains -how to deploy one and choose its token. A development daemon is also suitable +Use this setup for the API path in the HPC and Google Cloud tutorials. You need +Bash, `curl`, `jq`, and an AkôFlow server whose address and credential you manage. +The [server installation guide](/docs/guides/operations/server-instance) explains +how to deploy one and choose its token. A development server is also suitable when its connection settings are known. Set the base URL **including** `/akoflow-api`, without a trailing slash: @@ -19,11 +19,11 @@ read -rsp 'Akoflow API token: ' AKOFLOW_API_TOKEN; printf '\n' export AKOFLOW_API_TOKEN ``` -`pipefail` keeps a failed HTTP request visible even when its output is piped -to `jq`. Stop at any failed command before creating dependent records. +`pipefail` keeps a failed HTTP request visible when its output is piped to +`jq`. Stop if a command fails before creating dependent records. -Replace the origin and port with your daemon's settings. Press Enter without a -token only for an explicitly tokenless local daemon. For packaged Desktop, +Replace the origin and port with your server's settings. Press Enter without a +token only for a local server configured without one. For packaged Desktop, connection details are managed by its proxy; completing the graphical tutorials does not require extracting its internal credential. @@ -38,10 +38,10 @@ curl --fail-with-body \ The first response must report `server.available: true`; the second must return a catalog, which may be empty. A `401` means the supplied credential was rejected. -A `403` may indicate that a tokenless daemon rejects non-loopback access. +A `403` may indicate that a server without a token rejects non-loopback access. Use a fresh tutorial identity. The examples use `research-hpc` and `research-gcp`; if those already exist, inspect them before continuing instead of resubmitting a create request. Store only returned credential references in environment JSON. -Continue with [HPC registration](./register-hpc) or [Google Cloud connection](./connect-cloud). +Continue with [HPC registration](/docs/tutorials/register-hpc) or [Google Cloud connection](/docs/tutorials/connect-cloud). diff --git a/docs/docs/tutorials/connect-cloud.md b/docs/docs/tutorials/connect-cloud.md index 6c212ad7..7fe83bbc 100644 --- a/docs/docs/tutorials/connect-cloud.md +++ b/docs/docs/tutorials/connect-cloud.md @@ -4,25 +4,22 @@ sidebar_label: Connect cloud / GCP description: Validate a GCP credential, register a cloud environment and inspect the compute catalog using Desktop or the API. --- -This tutorial connects **Google Cloud**, the compute provider available in the -current **Cloud on demand** form. Its result is a registered environment and a -synchronized catalog. It does not provision a VM. - -AWS support is currently for S3 data movement, not EC2 discovery/provisioning. -For that separate task use [Configure AWS](../guides/infrastructure/aws). +Connect Google Cloud through **Cloud on demand** and inspect its compute +catalog. You will finish with a registered environment and reviewed machine, +image, and disk choices. Connecting the account does not provision a VM. ## Before you begin -Complete [installation checks](../installation). Obtain a GCP project and an +Complete [installation checks](/docs/installation). Obtain a GCP project and an approved service-account JSON credential from your cloud administrator. The -project needs the APIs and access described in [Configure Google Cloud](../guides/infrastructure/gcp). +project needs the APIs and access described in [Configure Google Cloud](/docs/guides/infrastructure/gcp). Read that guide's access inventory; it distinguishes source-audited calls from minimum IAM permissions that still require validation in a disposable project. The service account belongs to Google Cloud. Creating an AkôFlow environment does not create the project, service account, billing configuration or IAM grants. -## Through the interface +## Using AkôFlow Desktop ### 1. Open the cloud form @@ -65,36 +62,41 @@ Open the saved environment and inspect **Cloud capacity**. If saving succeeded but refresh failed, reopen the existing environment and refresh there; do not create a duplicate just to retry synchronization. -## Through the API +## Using the API -Complete [API connection setup](./api-access). Keep the service-account file +Complete [API connection setup](/docs/tutorials/api-access). Keep the service-account file outside your repository, with access restricted to your account. ### 1. Validate the service account -The commands read the credential file directly; replace its path and the region. +The commands read the credential file directly. Set the path, target project ID, +and region to the values approved for this connection. The target project may +differ from the project that owns the service account if it has the required +access. Run the following in Bash so `pipefail` also catches a failed JSON preparation: ```bash set -o pipefail AKOFLOW_GCP_KEY_FILE='/secure/path/service-account.json' +AKOFLOW_GCP_PROJECT='your-project-id' AKOFLOW_GCP_REGION='us-central1' -AKOFLOW_GCP_PROJECT=$(jq -er '.project_id' "$AKOFLOW_GCP_KEY_FILE") || exit 1 -jq --arg region "$AKOFLOW_GCP_REGION" \ - '{provider:"gcp", credential:., projectId:.project_id, region:$region}' \ +jq --arg project "$AKOFLOW_GCP_PROJECT" --arg region "$AKOFLOW_GCP_REGION" \ + '{provider:"gcp", credential:., projectId:$project, region:$region}' \ "$AKOFLOW_GCP_KEY_FILE" \ | curl --fail-with-body \ -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' --data-binary @- \ - "$AKOFLOW_API_URL/cloud-credentials/validate/" -o gcp-validation.json + "$AKOFLOW_API_URL/cloud-credentials/validate/" -o gcp-validation.json || exit 1 jq . gcp-validation.json -jq -e '.valid == true' gcp-validation.json +jq -e '.valid == true' gcp-validation.json || exit 1 ``` Continue only when validation succeeds. Inspect `project`, `region`, -`machineCount`, `imageCount` and `diskCount` before saving. +`machineCount`, `imageCount` and `diskCount` before saving. A `valid: true` +response can still have an empty category; resolve that before choosing cloud +capacity. ### 2. Store the credential and prepare the environment @@ -104,7 +106,7 @@ jq '{id:"research-gcp-credential", provider:"gcp", credential:.}' \ | curl --fail-with-body \ -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' --data-binary @- \ - "$AKOFLOW_API_URL/cloud-credentials/" -o gcp-reference.json + "$AKOFLOW_API_URL/cloud-credentials/" -o gcp-reference.json || exit 1 ``` The response contains `credentialRef`, not the original secret. Download @@ -119,12 +121,12 @@ jq --arg ref "$AKOFLOW_GCP_REF" \ '.connections[0].credentialRef=$ref | .connections[0].configuration.projectId=$project | .connections[0].configuration.region=$region' \ - gcp-environment.template.json > gcp-environment.json + gcp-environment.template.json > gcp-environment.json || exit 1 curl --fail-with-body \ -H "Authorization: Bearer $AKOFLOW_API_TOKEN" \ -H 'Content-Type: application/json' --data-binary @gcp-environment.json \ - "$AKOFLOW_API_URL/environments/" | jq + "$AKOFLOW_API_URL/environments/" | jq || exit 1 ``` ### 3. Refresh and inspect the catalog @@ -149,16 +151,16 @@ A catalog GET may return `404` before the first successful refresh. Inspect warnings as well as machines, images and disks: unavailable pricing must not be interpreted as free compute. -## Verify the connection result +## Check the result | Evidence | Expected result | | --------------------- | ---------------------------------------------------------- | | Credential validation | Correct project/region and `valid: true` | | Environment | `research-gcp` exists with a cloud connection | -| Catalog | Machines, compatible images and disk choices are available | +| Catalog | Machine, image and disk counts are reviewed; any empty category is investigated before provisioning | | Capacity | No VM is expected merely from connecting the account | -Next, follow [Cloud capacity and machine configuration](../guides/infrastructure/cloud-capacity) +Next, follow [Configure cloud capacity](/docs/guides/infrastructure/cloud-capacity) to choose a target and deliberately provision a worker. That operation can create billable resources; its guide covers lifecycle and cleanup. Do not treat catalog access as proof that provisioning permissions are complete. diff --git a/docs/docs/tutorials/register-hpc.md b/docs/docs/tutorials/register-hpc.md index 4f3f47a7..d41960ab 100644 --- a/docs/docs/tutorials/register-hpc.md +++ b/docs/docs/tutorials/register-hpc.md @@ -4,29 +4,28 @@ sidebar_label: Register HPC / SLURM description: Register a cluster through Desktop or the API, test its SSH connection, and verify discovered inventory. --- -This tutorial registers an existing institutional HPC account in AkôFlow. It -does **not** create an account at the institution or allocate compute time. -Ask the cluster administrator for your login, permitted partition, SSH access -policy, gateway requirements, and a shared workspace before starting. - -The result is a saved environment with a healthy connection and reviewed -inventory. Running the first batch job is a separate step after registration. +Register an existing HPC account and check that AkôFlow can reach the cluster +and discover its resources. You will finish with a saved environment, a healthy +connection, and reviewed inventory. A batch job comes after registration. ## Before you begin -- Complete [installation and its result checks](../installation). +- Complete [installation and its result checks](/docs/installation). +- Ask the cluster administrator for your login, permitted partition, SSH access + policy, gateway requirements, and a shared workspace. Registration does not + create an institutional account or allocate compute time. - Obtain the login hostname, SSH user and port, SLURM partition, and gateway command when required. The AkôFlow daemon must be able to reach that route. - Obtain authorization to use a managed SSH key and verify the site's host-key trust requirements with your administrator. - Confirm `sinfo`, `sbatch`, `squeue`, `sacct`, and `scancel` are available to your - account. Review the [HPC operator guide](../guides/infrastructure/hpc-slurm) + account. Review the [HPC operator guide](/docs/guides/infrastructure/hpc-slurm) for account/QoS, storage and container-runtime requirements. `login.example.org`, `researcher`, and `cpu` below are placeholders. Replace them with the values provided by your institution. -## Through the interface +## Using AkôFlow Desktop ### 1. Register an SSH service key @@ -34,7 +33,7 @@ Open **Settings → SSH service keys**. Under **Register a service key**, enter `research-hpc` and choose **Generate key**. Copy the public key and have it authorized for your account on the login host and required gateways. If the institution requires an existing key, use the separate import action described -in [Credentials and SSH](../guides/operations/credentials-and-ssh). +in [Manage SSH service keys](/docs/guides/operations/credentials-and-ssh). ![SSH service keys settings with import and generation actions](../../static/img/interface/onboarding/ssh-service-keys.png) @@ -74,11 +73,11 @@ runs from the daemon's host. Choose **Save environment**, then open the saved environment. In its connection section, run **Check now** and **Discover**. Review **Inventory** for the expected cluster partitions and compute nodes; see the detailed -[discovery checks](../guides/infrastructure/hpc-slurm#3-discover-the-actual-cluster-before-trusting-the-catalog). +[discovery checks](/docs/guides/infrastructure/hpc-slurm#3-discover-the-actual-cluster-before-trusting-the-catalog). -## Through the API +## Using the API -Complete [API connection setup](./api-access). Use the same approved host, +Complete [API connection setup](/docs/tutorials/api-access). Use the same approved host, account and partition as in the graphical path. ### 1. Generate and authorize the key @@ -95,6 +94,9 @@ jq '{id, publicKey, fingerprint}' hpc-key.json Authorize the returned `publicKey` through your institution's procedure before continuing. Keep the returned `credentialRef`; do not invent a private-key path. +The returned `fingerprint` identifies your service key, not the cluster's host +key. Compare the host key separately as described in the +[HPC operator guide](/docs/guides/infrastructure/hpc-slurm#1-create-the-ssh-credential-and-proxy-aware-connection). ### 2. Prepare the environment and test its connection @@ -161,7 +163,7 @@ curl --fail-with-body \ Inspect the health result before running discovery. Keep the environment version returned by the server when creating an execution scope. -## Verify the registration result +## Check the result | Evidence | Expected result | | ----------------- | -------------------------------------------------------------------- | @@ -169,11 +171,11 @@ returned by the server when creating an execution scope. | SSH health | Healthy from the daemon using the selected credential and route | | Discovery | Expected partitions/nodes appear with plausible capacity | | Compute boundary | The login host is not treated as a batch compute allocation | -| Shared workspace | Site-provided path is accessible from an approved compute allocation | +| Shared workspace | Site-provided path is recorded; access from a compute allocation still needs a batch probe | A discovered partition is not a reservation. Registration does not prove that an account, QoS, container image or shared filesystem will work in a batch job. -Continue with [scope setup and a small real execution](../guides/infrastructure/hpc-slurm#5-scope-validate-and-submit-a-small-real-execution). +Continue with [scope setup and a small real execution](/docs/guides/infrastructure/hpc-slurm#5-scope-validate-and-submit-a-small-real-execution). ## If registration fails @@ -187,5 +189,3 @@ Continue with [scope setup and a small real execution](../guides/infrastructure/ The screenshots and payload structure were checked against the local interface and handlers. Remote SSH, discovery and a real batch submission require your institution's access and were not performed for this tutorial's capture. - -Next: [connect Google Cloud](./connect-cloud) when you also need cloud capacity. diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index a0c894cd..1f6a6984 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -68,6 +68,18 @@ const config: Config = { to: "/docs/reference/api-overview/", }, { from: "/docs/cli", to: "/docs/reference/api-overview/" }, + ...[ + "get-environments-environmentid-cloud-capacity-targets", + "post-environments-environmentid-cloud-capacity-targets", + "get-environments-environmentid-cloud-instances", + "post-environments-environmentid-cloud-instances", + "get-environments-environmentid-cloud-catalog", + "post-environments-environmentid-cloud-catalog-refresh", + "post-environments-environmentid-cloud-provisioning", + ].map((slug) => ({ + from: `/docs/api/endpoints/environments/${slug}`, + to: `/docs/api/endpoints/cloud/${slug}`, + })), ], }, ], @@ -118,7 +130,7 @@ const config: Config = { title: "Docs", items: [ { label: "Getting Started", to: "/docs/getting-started" }, - { label: "Modules", to: "/docs/modules" }, + { label: "Architecture internals", to: "/docs/modules" }, { label: "Installation", to: "/docs/installation" }, { label: "Downloads", to: "/docs/downloads" }, { label: "Interface Tour", to: "/docs/guides/interface-tour" }, diff --git a/docs/editorial-audit-2026-09-12.md b/docs/editorial-audit-2026-09-12.md new file mode 100644 index 00000000..7ec46350 --- /dev/null +++ b/docs/editorial-audit-2026-09-12.md @@ -0,0 +1,317 @@ +# Editorial audit ledger + +Date: 2026-09-12. Scope: authored documentation pages in the current branch; generated API endpoint pages are reviewed through their generator and component. + +This is an iteration ledger, not a completion certificate. The first pass read all 51 authored pages and corrected confirmed narrative, terminology, API convention, example, and support-claim findings. A Desktop first-workflow path was added as page 52; splitting the evidence, operations, artifact, and cloud-setup procedures and adding a Cloud support page now brings the authored tree to 61 pages. A final full audit, priority endpoint contracts, and external-provider validation remain open. + +## Open P0/P1 findings + +1. **P0 resolved — Desktop first workflow:** the v1.0.8 Linux package created a local environment, workflow, scope, and manual plan through Desktop. Run `run-1789254029488` completed with 1/1 activities, exit code 0, and generated `result.txt` (20 B, SHA-256 `8dcc517ee6ace065324746726b7f6b5cd67b8c22956ec75bd8b713a0aeaca070`). The new `guides/workflows/first-local-run.md` documents that UI path. The package was extracted and launched under Xvfb with Docker access; this run does not validate a clean package-manager install or other platforms. +2. **P0 — Generated request contracts:** ZIP instance import is corrected and inferred JSON is labeled. Six first-run POST pages link the verified, versioned SimGrid payloads and their submission order. All 55 other mutating routes now carry handler/service-checked notes, and the generator fails if a future mutating route lacks a note or runnable request. The planning-session page has a concise example with its actual required fields. A field-level validation pass is still needed for inferred JSON examples; notes and build success do not prove every copied payload works. +3. **P1 — Provider evidence:** GCP and S3 procedures still need disposable-account validation. The SLURM fixture is local adapter evidence, not an institutional batch run. +4. **P1 — Full plain-language review:** after those corrections, re-read every authored page and the generated template as a new user, then repeat the audit until no new P0/P1 issue appears. +5. **P0 resolved in this pass — AWS/S3 narrative:** the former guide described a Desktop storage-creation flow and implied saved AWS credentials enabled S3 operations. Current code exposes a browsing screen without creation and wires the transfer connector to server environment credentials. The guide and support matrix now state that limit; a live S3 procedure still needs validation. +6. **P0 resolved in this pass — GCS claim:** the former support matrix and runtime explanations listed GCS as implemented transfer. The current `gs://` connector returns an unavailable error. The matrix, runtime pages, and schema reference now distinguish accepted `gcs` values from a working transfer path. +7. **P1 resolved in this pass — scope/topology UI:** the scope form creates an empty topology. A separate link-creation form exists at `/network/new` in Desktop source, but current sidebar and scope detail do not link to it. The documented, navigable path for registering links is the API; the SimGrid and scope guides now say so. +8. **P1 resolved in this pass — cloud target language:** saving a capacity target was described as making a provisioned resource. The guide now states that no VM is created at that step. +9. **P1 resolved in this pass — execution state language:** the workflow guide said normal runs move through `created`, though the supervisor creates them as `running` after queue acceptance. The guide now matches the state reference. +10. **P1 resolved in this pass — core concepts:** the concept page conflated executable artifacts with observed scientific files. It now distinguishes executable artifacts from scientific data, matching the data guide. +11. **P1 resolved in this pass — Showcase Desktop claims:** six Showcase tabs described unverified Desktop-only submissions; some asked users to add network links through a Desktop path not exposed in current navigation. The tabs now identify API submission as the verified path and limit Desktop steps to inspection on the same server. +12. **P0 resolved in this pass — GCP Desktop route:** the detailed guide directed readers to a separate Settings credential form and a “New environment” action that do not match the current cloud onboarding. It now follows the tested form path in the connection tutorial. +13. **P0 resolved in the second pass — credential examples:** the SSH import example wrote a private key into a predictable `/tmp` JSON file without restrictive creation permissions. It now streams JSON directly from the existing protected key file to the API, without a temporary payload. The Kubernetes token example likewise reads a protected file into a streamed request instead of asking readers to put a token in a shell command. Both Bash blocks passed syntax checking. +14. **P0 resolved in the second pass — cloud target/API examples:** the API overview put a literal token in a shell `export`; it now uses the shared secret prompt. The capacity-target example omitted `sshSourceRanges`, which lets the current Terraform target default SSH ingress to `0.0.0.0/0`, and attached a configuration-version ID before the guide created it. The example now requires an approved CIDR and leaves optional machine configuration out of the base request. +15. **P0/P1 resolved in the second pass — Showcase setup:** four Showcase API blocks and the SimGrid guide put a token placeholder in a shell `export`; they now use the shared API setup. Six Showcase procedures assumed an unprovided repository checkout; each now shows how to enter the v1.0.8 files before running its script or inline requests. The edge–cloud page uses the checked-in submission script instead of repeating six HTTP calls. The Showcase index no longer calls a single 50-core run a scheduler scalability test. +16. **P0/P1 resolved in the second pass — core narrative and runtime support:** Core concepts now leads to the verified local Desktop run. `serverless` was listed alongside runtime drivers with an ambiguous mode; current source has a domain enum but no built-in adapter, so the runtime table now marks it unavailable. The planning and timing explanations removed repeated implementation detail while preserving prediction-versus-observation limits. +17. **P0/P1 resolved in the second pass — storage operation contracts:** five generated endpoint pages now state the storage and path preconditions plus the observed completion semantics for download, checksum, copy, archive, and index. The storage guide no longer groups immediate file downloads with queued archives. The `202` index route currently completes its scan before responding; the note makes that behavior explicit. +18. **P0/P1 resolved in the second pass — artifact examples and contracts:** the artifact guide no longer supplies nonexistent lineage/project IDs or leaves `BUILD_ID` undefined. Five generated endpoint pages now distinguish upload from metadata registration, build specification from started run, and stored materialization records from verified byte transfers. +19. **P0 resolved in the second pass — console outcome:** the one-shot console guide wrongly treated runner failure as HTTP `422`. The service waits for the runner and returns a `201` command record with `status: failed`; the guide and generated endpoint now tell readers to inspect status and failure. A successful session creation returns `connected`, not a `starting` session. Seven more generated endpoint pages now state checked console, connection-test, machine-configuration, and GCP-only catalog-validation limits. +20. **P0/P1 resolved in the generated API template:** the short-name struct index let a SimGrid `Request` alias overwrite the real console `Request`, so the console-command page displayed an unrelated workflow execution body. Concrete structs now win over aliases; conflicting short names produce no inferred sample. All 125 generated pages now show each JSON shape once, omit Go type names from the reader-facing component, use a short sample caveat, and link Console to its actual task guide. The six verified SimGrid routes use their versioned files instead of large inferred request bodies. +21. **P1 resolved in the generated API template — qualified responses:** `environment.Definition` and `workflow.Definition` shared a short name, which suppressed response examples after the conservative collision fix. The generator now resolves qualified aliases for both types; environment and workflow responses have their correct shapes again. Long response examples scroll within a bounded block instead of stretching the whole page. +22. **P1 resolved in the entry path — first action and download:** Home said to start with a local simulation even though the recommended first Desktop workflow is a real local run. It now names that workflow and sends the download action to the versioned platform-selection page. Installation and Interface tour replace avoidable daemon/control-plane language with the service or instance the reader sees. The current GitHub latest release was checked as `v1.0.8` before this second read. +23. **P1 resolved in the GCP connection tutorial — target project:** the API example derived its target project from the service-account key's `project_id`, while the provider accepts an explicit connection `projectId`. It now asks for the approved target project separately, matching Desktop and supporting a key authorized across projects. Critical credential/registration pipelines stop on failure rather than reading an older result file. All Bash blocks in the three connection tutorials parsed; a fake-key `jq` check confirmed separate credential-owner and target-project values. This is local contract evidence, not live GCP validation. +24. **P0 resolved in the Kubernetes how-to — token exposure:** its API example interpolated a short-lived bearer token into `curl --data`, exposing the token in process arguments. It now streams the token from `kubectl` through `jq` to `curl --data-binary @-`, stops on any pipeline failure, and uses the server-returned `credentialRef`. Handler and token-manager source confirm the response contains only that reference. Bash parsing and a fake-token JSON check passed; no shared cluster was contacted. +25. **P1 resolved in the environment how-to — incomplete remote path:** the page tested an SSH connection using `host:port` in `endpoint` and then queried a different connection ID that it never saved. Remote registration now links to complete HPC/GCP tutorials; the health/discovery commands use the actual ID from the HPC template as an explicit precondition. The page also replaces an internal Go type name with the fields readers need. +26. **P0/P1 resolved in the workflow guides — misleading examples:** the portable YAML guide reused the checked-in first-run workflow name, so following both guides could collide. It now uses its own name and matching read/export paths, says to save the file before the `curl` command, and identifies the empty commands as simulation-only. The execution guide no longer describes command history as a catalog of available console commands, and states the SimGrid setup required by its request example. The first-run guide trims repeated caveats while retaining its verification limit. +27. **P0 resolved in instance settings — sample overwrote identity:** the `PUT /instance/` example told readers to preserve the current identity but sent hard-coded `id`, `name`, and other metadata instead. It now reads the current object, changes only `transferBufferBytes` with `jq`, and sends the complete result. Handler code confirms the endpoint replaces the saved instance object and requires `id` and `name`. +28. **P1 resolved in scope/topology guidance — example prerequisites:** the reference submitted checked-in SimGrid files without saying how to get them or register their environment. It now links the versioned first-run setup and states the required checkout and order. The scope guide now identifies its HPC/cloud IDs as illustrative, links the runnable bundle, and states that topology creation does not enforce scope membership for link endpoints. +29. **P1 resolved in workflow specification — mixed-mode example:** the lead “complete” document combined one simulation-only activity with two real-only activities and named image paths without supplying scripts. It now presents a consistent real-execution field example, states the script prerequisite, and links the tested SimGrid sequence for a runnable tutorial. +30. **P0 resolved in environment reference — unavailable version action:** the common-failure row advised creating a new version within an in-use environment, but no API route appends a version and repository replacement deletes/reinserts the inventory transactionally, failing when references prevent it. The reference now tells readers to register revised inventory under new environment and version IDs and qualifies `PUT` replacement. +31. **P0/P1 resolved in server and troubleshooting guides — broken tunnel command and basic-path language:** the Linux server guide's `ssh ... @` line was invalid Bash because `<` starts redirection. It now prompts for SSH user and hostname and quotes the destination. The guide also replaces repeated control-plane language, corrects token creation instructions, and enables `pipefail` for both `curl | jq` checks. Troubleshooting calls reset deletion of local AkôFlow data. The planning/execution state reference was source-checked without a change. +32. **P0/P1 resolved in HPC guide — incomplete API update and proxy command:** the page submitted `research-hpc-connection.json` without creating it, used an ID different from the registration tutorial, and showed a `ProxyJump` command missing its SSH destination. It now reuses the tutorial ID, marks the credential reference as a replacement value, directs API registration to the complete template/test/save sequence, and asks readers to validate a complete proxy route from the server host. Institutional SLURM execution remains unverified. +33. **P1 resolved in instance import — manual response placeholder:** the import sequence asked readers to replace a quoted `SNAPSHOT_ID` placeholder by hand before activation. It now saves the import response, extracts the returned `id` with `jq`, and stops if import or extraction fails. A new repository check parses all 108 fenced Bash/sh blocks and runs in documentation CI; syntax coverage does not prove endpoint behavior or that named files exist. +34. **P0/P1 resolved in generated instance/environment reference — replacement contracts:** three more endpoint pages now state source-checked `PUT /instance/` identity and buffer limits, `PUT /environments/{environmentId}/` complete-definition/path-ID and in-use constraints, and archive activation response/restart behavior. The inferred JSON remains explicitly illustrative; the new notes link to task and field references. +35. **P0/P1 resolved in environment guide — incomplete local definition:** the API example omitted version-model fields, the resource provider ID and schedulable capacity, and an explicit enabled runtime binding, while the guide described versioning more broadly than the current single-version creation route. The example now supplies those fields; the intro tells readers to use new environment and version IDs for revised inventory already in use. +36. **P0 resolved in environment/topology references — misleading database defaults:** the create repositories explicitly insert decoded Go fields, so omitting `computeSpeedup`, `schedulable`, or resource-binding `enabled` from API input saves `0` or `false`, despite database schema defaults of `1` or `true`. Likewise, an omitted topology-link `bidirectional` saves `false`, and omitted `sharingPolicy` saves an empty string that SimGrid maps to shared. Both field references now state API behavior. The updated local environment JSON parsed and persisted through a one-off repository test, which confirmed its schedulable resource and enabled binding. +37. **P0/P1 resolved in generated connection/workflow/planning routes — task preconditions:** six more endpoint pages now state checked `PUT` connection identity and replacement behavior, health-probe `200` versus `offline`, discovery's saved-connection/bound-resource needs, portable workflow-import rules, duplicate-name requirements, and feasible-candidate selection semantics. The notes distinguish returned status from successful underlying work and link the workflow format where appropriate. +38. **P0/P1 resolved in cloud-capacity path — mismatched environment and missing response IDs:** the guide told readers to continue from the GCP tutorial but called `gcp-lab` instead of the tutorial's `research-gcp`, then left target and operation IDs as manual placeholders. It now captures both returned IDs and uses them for provisioning and inspection. Two generated endpoint notes state catalog-refresh behavior and capacity-target preconditions, including the current non-atomic target/resource registration sequence. Live GCP validation remains open. +39. **P0 resolved in planning cancellation contract — misleading missing-session status:** the handler maps cancellation failures to `409`, including a missing session, while the service accepts repeated cancellation but rejects completed and failed sessions. The generated endpoint now states those outcomes and that cancellation requests active work to stop. +40. **P1 resolved in planning how-to — candidate selection broke the API path:** after listing candidates, the guide reverted to an unfilled `` in its detail and selection requests. It now waits for final ranking, lists returned IDs, asks the reader to choose one, and reuses that value to inspect and select a feasible candidate. +41. **P0/P1 resolved in provenance/audit API examples — undefined filter IDs:** lineage used `$RUN_ID` without obtaining it, and the audit failure example required an undefined `$ENVIRONMENT_ID`. The page now asks for a run ID from Explore, rejects an empty value, and demonstrates a runnable failure query before showing an optional environment filter. The nearby panel and depth language was shortened. +42. **P0/P1 resolved in artifact browsing examples — undefined inventory IDs:** the guide used `$ENVIRONMENT_ID`, `$STORAGE_ID`, and `$RUN_ID` without obtaining them. It now takes an existing environment ID, lists its storages, asks for one returned storage ID, and lists materializations without requiring a run filter. Sample file and destination paths are explicitly identified as values to replace. +43. **P0/P1 resolved in interactive-console API flow — missing session ID and premature close:** the guide opened a session on a fictitious `hpc-login` ID, then used `$SESSION_ID` without setting it and placed session closure before streaming and log export. It now takes a saved interactive-capable resource ID, captures the returned session ID, reuses the resource for one-shot commands, and closes the session after use. The command JSON was checked with `jq`. +44. **P1 resolved in notification API equivalents — undefined operation IDs:** the page listed detail URLs with `$PLANNING_SESSION_ID`, `$RUN_ID`, and `$ENVIRONMENT_ID` without obtaining them. It now begins with the planning-session and run collections, then asks for a saved cloud environment ID only for the cloud-instance list. +45. **P1 resolved in troubleshooting connection history — undefined ID:** the history command used `$CONNECTION_ID` without a source. It now asks for the saved connection ID shown by the environment detail or registration response and rejects an empty value. +46. **P0 resolved in destructive and resource API contracts — outcome and dependency gaps:** seven more generated routes now state handler-checked reset, capacity-target, environment, storage-entry, scope, console-session, and resource-upsert behavior. The factory-reset guide also states that token-file cleanup can return `422` after the database has already been cleared. Resource creation is identified as an upsert that does not create a runtime binding; target deletion is identified as a soft disable that leaves its capacity resource unschedulable. +47. **P0 resolved in mutation-route coverage — nine remaining contracts:** the two read-only SQL POST routes, ZIP import, preference replacement, and five cloud lifecycle actions now have handler/service-checked notes. The instance-import limit was corrected from 10,000 to 100,000 archive entries to match `maxArchiveFiles`. All 61 mutating routes are now covered by 55 notes or six versioned runnable requests. The generator enforces that coverage for new routes; live cloud/provider validation and field-level payload checks remain open. +48. **P1 resolved in generated example presentation — inferred bodies looked runnable:** the shared endpoint component labeled inferred values simply “Body” and offered “Copy” for commands that still require a request file or path ID. It now labels these as request field shapes and cURL templates at the point of use, marks the one checked planning payload as an example request, and states what must be supplied before running a template. The repeated page-end caveat was removed. Rendered pages for inferred SQL, checked planning, and ZIP import showed the intended labels; field-level payload validation remains open. +49. **P2 resolved in scheduler explanation — repeated prediction caveats and dense prose:** the PRISM/HEFT page now keeps one concise account of shared inputs, search differences, detailed evaluation, cost, and evidence-based comparison. Its authored text fell from 1,021 to 745 words (27%) without removing the algorithm-specific evaluator limit. The two network examples now use the correct 8.6-second serialization estimate for 10 GiB at 10 Gbit/s, and the observed-timing page uses reader-facing language for run metrics. +50. **P2 resolved in installation narrative — repeated setup and verification prose:** the entry path keeps Docker checks, platform commands, and local onboarding steps, while shortening repeated first-launch and package-evidence explanations. The page fell from 1,818 to 1,667 words. It now states the tested Linux extracted-package scope and unverified clean `apt`/macOS/Windows paths in one place, linking to the recorded digest. +51. **P1/P2 resolved in entry navigation — inconsistent menu paths and tour scope:** the Desktop first-run page now names **Infrastructure → Environments** and **Infrastructure → Execution scopes** consistently with other guides. The Interface tour stays on Desktop navigation instead of repeating the general Desktop/API split; its text fell from 698 to 569 words while keeping search, breadcrumbs, terminal, and read-only guidance. +52. **P1 resolved in AWS/S3 guidance — implementation language obscured the usable path:** the guide now tells readers directly that S3 transfers need server environment credentials, saved AWS credentials do not enable those transfers, and the Storage screen cannot validate private-bucket access. It keeps the unverified live-AWS status and EC2 limit without explaining internal resolver or driver wiring in the user path. +53. **P2 resolved in HPC setup — repeated scope and implementation terms:** the opening now states who needs the guide and where to start, while the resource step describes the partition and node behavior in user terms. It keeps the local fixture's validation limit and site-specific SLURM requirements; the page fell from 1,532 to 1,451 words. +54. **P0 partially resolved in generated request contracts — SQL examples were placeholder shapes:** both provenance SQL POST pages now show a concrete `execution_runs` query with a named `status` parameter, and the query page includes pagination. Handler tests decode the exact JSON and confirm the forwarded fields; repository tests execute the query and explain it against SQLite. Both generated pages mark these requests as verified examples. Other inferred request shapes still need field-level validation. +55. **P0 partially resolved in generated request contracts — machine playbook validation was a placeholder shape:** `POST /machine-configuration-validations/` now shows a complete minimal Ansible playbook in `playbookYaml`. A handler test submits the exact JSON and checks HTTP `200`, `valid: true`, and a content digest; the existing validator test covers the same playbook. The endpoint checks structure only, as its note states; other inferred bodies remain open. +56. **P0 partially resolved in generated request contracts — machine configuration creation/versioning were placeholder shapes:** the two POST pages now use minimal requests in sequence, with one explicit configuration ID and a version-1 playbook. A handler test submits both exact JSON bodies against a bootstrapped SQLite repository and verifies the saved configuration, version, and digest. The version page tells readers to use the created ID in its path. Other inferred bodies remain open. +57. **P0 resolved in generated build-context submission — wrong primary cURL body:** `POST /build-contexts/` previously showed an inferred JSON shape and a JSON file template even though the documented, byte-uploading path is multipart field `context`. The generated page now shows a multipart cURL template for `context.tar.gz`; JSON is described only as metadata registration for bytes already in the artifact store. The built HTML contains the multipart command and no JSON content-type command. Existing handler tests submit multipart and JSON forms separately; both targeted tests passed. +58. **P0 partially resolved in generated artifact registration — Docker image body was a placeholder shape:** `POST /artifacts/docker/` now uses the same concrete BusyBox request as the user guide. A handler test submitted that exact JSON to a bootstrapped SQLite repository and verified the saved artifact version and build specification. The request does not start the registry pull or SIF conversion; those remain separate build-run work. Other inferred bodies remain open. +59. **P0 resolved in storage-promotion field names — generated PascalCase conflicted with the guides:** both promotion handlers now declare lower-camel JSON names explicitly. The generated field shapes and verified examples use `path`, `workflowVersionId`, `runId`, `activityId`, `name`, and `version` consistently. A handler test submits the exact two guide bodies and verifies forwarded fields; storage-service tests cover file checks and promotion. The example paths must be replaced with files in a registered storage, as the endpoint notes state. +60. **P0 partially resolved in storage operation requests — five placeholder shapes:** download, checksum, copy, archive, and index pages now show concrete request bodies, with explicit instructions to replace example paths, destination storage, or index ID. Handler tests submit the exact JSON and check route status, forwarded path/destination, and returned ID or digest; storage-service tests remain the evidence for file handling. These tests do not prove that the example files exist in a user's storage. +61. **P0 partially resolved in console request bodies — inferred shapes hid the minimal action:** the session and one-shot command pages now show only `resourceId` and, for a command, `command`. A handler test submits both exact JSON bodies and checks the forwarded fields and HTTP status. The route notes require a saved compatible resource and distinguish `201` from successful command execution; the test does not open a real terminal. +62. **P0 partially resolved in connection-test reference — generic body obscured a runnable local probe:** `POST /connection-tests/` now shows `{ "type": "local" }` and separates SSH, agent, and Kubernetes prerequisites from the local example. A handler test submits the exact JSON to the real local prober and checks `200`, `healthy: true`, and the decoded connection type. The route does not save a connection; remote/provider validation remains separate. +63. **P0 partially resolved in instance request examples — a generic replacement body risked lost fields:** `PUT /instance/` no longer displays an inferred full object as if it were safe to submit; its guide reads the current record, changes only `transferBufferBytes`, and sends the whole object back. A handler/SQLite test confirms that identity and metadata survive. `PUT /user-preferences/{clientId}/` now shows the guide's small verified body; the same test confirms its saved theme and animation setting. Sixteen inferred request bodies remain displayed across the generated reference. +64. **P0 partially resolved in workflow route variants — import and duplicate used inferred shapes:** the compatibility import page now links the versioned SimGrid workflow YAML as an alternative to the create route in the six-step tutorial. A handler test imports that exact file. The duplicate page now shows a short `name`/`namespace` JSON request, tested against a source workflow fixture. The reference warns against sending the same workflow through both creation routes. Fourteen inferred request bodies remain displayed. +65. **P0 partially resolved in resource upsert — inferred body implied a runnable resource:** `POST /resources/` now shows a concrete inventory-only resource in the first-run SimGrid environment, explicitly `schedulable: false`. A handler/SQLite test saves the exact JSON and checks its capacity, speedup, and lack of runtime binding. The page explains that upsert can overwrite an existing ID and that planning needs a complete environment definition with a binding. Thirteen inferred bodies remain displayed. +66. **P0 partially resolved in replacement references — inferred bodies could overwrite saved fields:** `PUT /environments/{environmentId}/` and `PUT /environment-connections/{connectionId}/` no longer display generated full-object shapes with fictitious values. Their handler-checked notes direct readers to read the current environment/connection, preserve the full definition, match path IDs, and account for in-use replacement limits. Source and existing handler tests support those constraints; a complete replacement procedure remains user-specific. Eleven inferred bodies remain displayed. +67. **P0 partially resolved in artifact operation references — inferred bodies hid required records:** `POST /artifact-builds/` and `POST /artifact-materializations/` now describe prerequisites without displaying speculative JSON. The build route records a specification after an uploaded context; it does not run the build. The materialization route records caller-provided state without copying or verifying bytes. Its public `environmentId` field must contain an environment version ID, as the repository foreign key and a regression test confirm. Nine inferred bodies remain displayed. +68. **P0 partially resolved in credential references — fake secrets looked usable:** SSH key generation now displays the exact JSON used by an existing handler test. SSH key import, Kubernetes token storage, cloud credential storage, and live cloud validation no longer display placeholder secret bodies; their notes specify the required fields and actual provider limits. Four inferred bodies remain displayed. +69. **P0 resolved in generated cloud-operation status labels:** seven cloud action handlers delegate to `enqueueCloudOperation`, which returns `202 Accepted`; shallow status extraction had shown `200 OK` on their pages. The generator now sets their delegated status explicitly. `202` means an operation was queued or an existing active operation returned, not that a VM is ready. +70. **P0 partially resolved in remaining request shapes — fabricated plan and provider objects:** schedule-plan import and three cloud target/provisioning routes no longer show generic JSON with `"string"` IDs, zero capacities, and placeholder image names. Their notes state the saved-record and account-specific prerequisites; the plan response shape remains available as a field reference. No inferred request bodies remain displayed, but full field-level validation of these routes and their responses is still open. +71. **P0 resolved in WebSocket success status:** the console stream page had inherited a default `200 OK` even though `StreamSession` upgrades a valid connection to `101 Switching Protocols`. The generated reference now states the WebSocket contract and links to the console guide. The generator rejects success statuses it cannot infer, with explicit exceptions only for the WebSocket delegate, seven queued cloud delegates, and five handlers that successfully write bytes with Go's implicit `200`. +72. **P0 resolved in WebSocket request presentation:** the shared endpoint component offered an ordinary cURL GET template for the terminal stream even though it requires a WebSocket upgrade. That page now shows the `ws://` route, `wss` guidance, and a link to the stream protocol; the built HTML has no cURL template on that page. Across generated JSON response pages, the illustrative-shape label now appears before the object so placeholder values are identified before readers see them. +73. **P0 resolved in daemon health command:** `GET /` was shown with the API base URL plus `/`, which targets `/akoflow-api/` instead of the registered root route. The cURL command now removes `/akoflow-api` from the configured base URL for this one endpoint. The page distinguishes its plain `ok` response from preflight capability checks; the built HTML contains the corrected shell expansion and not the old path. +74. **P0 resolved in WebSocket response label:** the console stream reference identified its response media type as `application/websocket`, but a successful handshake uses HTTP `101 Switching Protocols` and an Upgrade header rather than that `Content-Type`. The page now labels the result “WebSocket upgrade” while leaving message framing to the stream protocol guide. +75. **P0 resolved in preflight response presentation:** the generated preflight page showed `server`, `docker`, and `buildkit` as simultaneously available, although the handler returns `200 OK` even when the Docker socket or BuildKit command fails. The fabricated all-green response is gone; the page now names the three checks and tells readers to inspect each `available` value in the daemon's response before a local run. +76. **P1 resolved in infrastructure YAML presentation:** SimGrid, SLURM, and Kubernetes guides labeled partial YAML blocks with complete versioned filenames. The code titles now say which part of the file is excerpted, and SimGrid/SLURM explicitly direct readers to the full bundle before submission. The GCP guide now discloses at the start that its provider calls are source-audited but a disposable-project provision-and-destroy cycle is unverified; the SLURM guide likewise distinguishes its local fixture from an institutional cluster run. +77. **P1 resolved in installation narrative:** the installation page now states near platform selection that an extracted Linux v1.0.8 package completed a local workflow while clean `apt`, macOS, Windows, and AppImage first launches remain unverified. Its duplicate post-setup checkpoint table was replaced with a short `Set up later` confirmation: **Connected** proves local daemon reachability, while the catalog stays empty until an environment is registered. The existing **Ready** step remains the confirmation for the full local assistant path. +78. **P1 resolved in the basic reading path:** Home, Downloads, Getting Started, Installation, the Desktop first-workflow tutorial, and Interface Tour were read together as one new-user sequence. Downloads now calls daemon/BuildKit archives service assets without claiming automatic retrieval on every platform. The first-workflow tutorial identifies the verified Linux package as extracted and removes an irrelevant BusyBox implementation detail. The tour no longer introduces read-only instance modes before the user needs them. The sequence still requires clean-host and other-platform execution checks before its completion gate can be claimed. +79. **P1 resolved in the scheduling path:** the planning how-to led with session states, candidate field inventories, and assignment internals before the user procedure. It now starts with the workflow/scope/candidate action, keeps the Desktop and API steps together, and links to the PRISM/HEFT explanation and state reference when those details become useful. The PRISM/HEFT, planning-model, and observed-timing explanations were read alongside it; their predicted-versus-observed distinctions remain intact. Provider-dependent timing and full request validation are still open. +80. **P1 resolved in evidence guide scope:** one long guide mixed tracing a scientific result with investigating operational events. The old URL is now a short choice page; separate provenance and audit guides hold their own Desktop/API procedures, screenshots, limits, and investigation steps. Sidebar, Getting Started, Interface Tour, feature coverage, and API-reference links now lead to the relevant task. This preserves the old URL for inbound links while giving each procedure one objective. +81. **P0 partially resolved in SSH credential assignment example:** the credentials guide said to preserve the saved connection but showed a partial `PUT` body that could drop proxy and port settings. It now reads `GET /environments/{id}/`, selects the existing connection, changes only `credentialRef` with `jq`, sends the full object, and runs a separate health check. A local `jq` check preserved a sample port and proxy command; the repository `UpsertConnection` updates all supplied fields. The exact HTTP sequence still needs a controlled end-to-end submission. The cloud-credential section now links to the complete Google Cloud connection tutorial. +82. **P1 resolved in search and notification scope:** one operations page mixed record lookup with profile-local operation alerts. Its existing URL is now a short choice page; separate guides hold Desktop/API search, result limits, notification behavior, collection queries, and recovery. The Interface Tour links directly to record search. This keeps the two objectives distinct without losing the old address. +83. **P0 resolved in the GCP guide API checkpoint:** the cloud tutorial and its environment template create `research-gcp`, but the detailed GCP guide refreshed and read the catalog of `gcp-lab`, which would return 404 on the documented path. Both checkpoint commands now use `research-gcp`. The cloud support matrix and AWS/S3 guide were reread together; their partial-support limits remain explicit. Live provider provisioning and transfer validation remain open. +84. **P1 resolved in the console's basic path:** the console guide, troubleshooting step, and embedded connection diagram introduced control-plane and runtime-binding terms before the reader could open a terminal. They now describe the selected resource, interactive access, and its saved connection. The API section retains the runtime and connection IDs returned by session creation, where those fields matter. +85. **P1 resolved in workflow execution scope:** the execution how-to mixed starting a planned workflow with terminal-session API details and used adapter language in its first explanation. It now explains real versus simulated workflow runs in user terms and links once to the separate console task. The result list is qualified because transfer, cost, and startup observations depend on the runtime and available evidence. +86. **P1 resolved in artifact guide scope:** the former artifact guide combined storage browsing and file promotion, Docker/SIF builds, and artifact-location inspection. Storage already had a focused guide with the same browse and promotion procedures. The old URL is now a short choice page; a build guide and a location guide hold the remaining tasks, and sidebar, API overview, feature-coverage, and generated endpoint links point to the appropriate destination. The build no longer reports the two anchors removed from the former page. +87. **P1 resolved in credential guide scope:** the SSH key guide repeated a Kubernetes token procedure and included a cloud-credential section, despite separate provider tutorials. The page now handles generating/importing and assigning SSH keys only, with early links to Kubernetes and Google Cloud. The Kubernetes guide retains its own streamed token request, and referring labels now match the SSH page title. +88. **P1 resolved in instance guide scope:** appearance and graph-animation preferences were embedded between instance identity and archive export even though they are browser-profile settings. A short Personal preferences guide now owns the Desktop/API instructions; instance management, sidebar, feature coverage, and the generated preference endpoint link to it. +89. **P0/P1 resolved in cloud configuration path:** the capacity how-to mixed optional Ansible playbook creation with catalog/target/provisioning steps; the playbook it validated installed `curl`, but its saved version had no tasks. Machine configuration now has its own guide and uses the same playbook for validation and version creation. The response-derived version ID and optional target field are shown. The support matrix also distinguishes catalog discovery from zone lookup at provisioning and Billing-dependent price estimates. Live GCP provisioning remains unverified. +90. **P1/P2 resolved in installation scope:** the Desktop installation guide repeated two self-managed-server API checks already covered by the server and API setup guides, then repeated the package validation caveat at the end. It now keeps installation/checkup as its task, points separate-server users to their path, and leaves one early platform-verification limit plus the linked download digest. +91. **P1 resolved in Getting Started support choice:** the entry page gave provider links but required a reader to visit separate guides to learn which paths have end-to-end evidence. A short support section now distinguishes the verified local Desktop, SimGrid, and Kind paths, the SLURM fixture limit, GCP's unverified live lifecycle, and partial AWS/S3 support. It links the detailed cloud matrix without duplicating the AWS caveat in the provider list. +92. **P1 resolved in workflow-definition order:** the how-to opened with an eight-field table of persisted activity fields before showing the Desktop creation task, including fields absent from the portable YAML example. It now starts with creation steps, gives a short portable-input explanation beside the API example, and sends exact fields and compatibility rules to the Workflow specification reference. +93. **P1 resolved in core-concepts claim:** the run definition presented timing, transfers, and output evidence as universal fields. It now states that activity status is tracked and the other observations are stored when available, matching the runtime-dependent limits stated in the execution guide. +94. **P1/P2 resolved in provenance reading order:** the four-step result investigation was buried after Explore, lineage, and SQL controls. It now appears immediately after the page purpose, with SQL presented as optional when lineage is insufficient. A repeated browser-local favorites note was removed; the SQL control table already states that limit. +95. **P1/P2 resolved in audit reading order:** the event-investigation sequence was below the full control table and API filters. It now appears immediately after the page purpose, matching the provenance guide's task-first pattern. The second inventory of event types was shortened to avoid repeating the opening. +96. **P0 resolved in cloud target request example:** the target payload omitted `configuration.projectId`, although Terraform reads that field from the target rather than from the environment connection. It also used `x86_64`, which fails compatibility with the required built-in worker configuration's `amd64` architecture. The example now reads the validated project ID from the tutorial session, uses `amd64`, prompts for an actual Ubuntu `providerImageId` and approved CIDR, and builds the JSON with `jq` so literal placeholders cannot be sent. An optional saved machine-configuration version is attached when its returned ID is set. The generated target endpoint note states the prerequisites. Local `jq` checks produced valid targets both with and without the optional configuration and preserved sample project, image, architecture, and CIDR values; fields were checked against the handler, domain, repository, provisioner, and Terraform runner. Live provider execution remains unverified. +97. **P0 resolved in fixed-plan prediction claim:** the SimGrid first-run tutorial said the API reevaluates imported predicted cost and feasibility when submitting its fixed plan. The `POST /schedule-plans/` and `/import/` handlers validate the supplied schedule but save its predicted metrics without recalculating them. The first-run and planning guides, plus the generated import endpoint note, now state this distinction and direct readers to compare predictions with run observations. +98. **P0 partially resolved in schedule-plan import:** the guide previously offered only `{ "plan": ... }`; the SimGrid validation envelope cannot be sent directly to import because the decoder rejects unknown top-level fields. A new example fetches the plan already saved by the versioned tutorial, assigns a new plan ID and unique assignment IDs with matching `planId`, and sends only the import envelope. Local `jq` validation against the checked-in three-assignment plan preserved its predictions and IDs; the handler and repository source were checked. A controlled HTTP run on 2026-09-13 exposed a `422` unique-key collision on four cloud lifecycle action IDs. The example now also assigns new lifecycle IDs, `schedulePlanId`, and `dependsOn` references. Re-running against a fresh isolated server returned `201` on import and `200` on the copied-plan GET; all three assignments, four lifecycle actions, their dependencies, and predicted metrics were checked. + +99. **P1 resolved in Docker-to-SIF guide:** the API path stopped after starting the build and left the reader to infer both `build.id` and the asynchronous run ID. It now captures the two response IDs, reads the run status with failure details, and downloads output only after completion. The server-side Apptainer and artifact-store prerequisites are explicit. The response fields and `queued`/`running`/`publishing`/`completed`/`failed` states were checked against the handler, build manager, executor, and domain type; a live registry pull and SIF build remain unverified. + +100. **P1 resolved across architecture and planning:** the architecture page called HEFT and PRISM candidates “comparable” although their predictions use different evaluators. The architecture now states that candidates share session inputs but use different prediction models. The planning guide tells readers to inspect estimates for selection and compare observed runs when judging performance. Both now align with the source-audited PRISM/HEFT explanation. + +101. **P0 resolved in SimGrid route description:** the guide called the chosen path the “lowest-latency” route, implying payload-aware or latency-only choice. The SimGrid platform builder and PRISM compact router both sum link latency plus one-byte transmission time before applying the actual transfer volume. The guide now says route choice uses latency and bandwidth; the network explanation gives the one-byte rule and warns that a large payload could favor another path. + +102. **P0 resolved in artifact location claims:** the task guide and API overview called location records “verified bytes,” although `GET /artifact-locations/` only reads saved rows and does not probe the URI. The guide now distinguishes recorded URI/digest/`available` from a fresh storage check. It also states that a committed materialization requires both status and a matching verified digest, and that listing saved observations does not recheck destination bytes. The artifact task landing was aligned. The claims were checked against the domain `Committed()` predicate, list handlers, and repositories. + +103. **P1 resolved in documentation production contract:** the contributor page said every generated endpoint had a cURL command and discussed inferred request JSON as if it were displayed. The current component shows a WebSocket connection for the console stream, only checked request examples, templates where IDs/files are still needed, and illustrative response shapes. The contract now describes that behavior and requires handler plus real-response checks before field-level claims are verified. + +104. **P0 resolved across scope, SimGrid, and network explanations:** the scope guide treated links as optional only when time or cost mattered, and the SimGrid guide said a missing route was not a zero-cost transfer. Source review found that PRISM rejects a cross-resource data dependency without a route, while HEFT `transferSeconds` returns zero when no direct matching link exists. The guides now tell readers to model links for cross-resource dependencies, and the network explanation identifies that HEFT limitation rather than implying a safe free transfer. The scope link example also omits redundant `topologyId`, matching the field reference. + +105. **P2 resolved in four Showcase narratives:** the SLURM fixture page repeated its local-only warning with a long inventory of untested cluster commands and policies; it now states the tested adapter path and groups the real-cluster limits in one short sentence. The edge-cloud, network fan-out, and 50-core pages now state what their fixed examples demonstrate without defensive “do not” framing. Checked-in evidence, result numbers, prerequisites, and recovery steps remain. Authored text across these files was reduced without removing support limits; the full 60-page final plain-language pass remains open. + +106. **P0/P1 resolved in Showcase command coverage:** the local direct API page submitted its bundle with a bearer token but omitted that token on the final run GET, causing `401` on a protected daemon. The GET now uses the shared API credential. The edge-cloud, network fan-out, and 50-core polling commands now fail on HTTP errors; the Showcase index distinguishes existing-daemon API setup from the self-started SLURM fixture. The shell syntax checker now covers the 11 JSX template-literal command blocks as well as 108 fenced blocks (119 total), closing a verifier blind spot; the contributor contract records its exact scope. These checks do not replace HTTP execution or final visual review. + +107. **P0/P1 resolved in storage download flow:** the guide created a ready file-download record but did not show how to fetch its bytes, poll copy/archive records, or retrieve the archive. It now follows the example IDs through those steps and gives platform-specific SHA-256 comparison commands. Source review found that `StartDownload` only stats the path, while `OpenDownload` opens it later, so a ready record is not an immutable snapshot; the guide and generated endpoint note now say so. Archive output and status were initially checked against the coordinator, handler routes, and storage tests; the subsequent isolated HTTP test and its defect are recorded in finding 108. + +108. **P0 resolved in archive download and local-storage configuration:** an isolated daemon with two registered local storages completed browse (`200`), file download (`201`/content `200`), checksum (`200`), and copy (`202` to `completed`) with matching bytes. It also proved a ready download record is not a snapshot by changing the source and reading different bytes under the same ID. Archive creation reached `ready` but content returned `404`: the repository UPSERT saved status but not the archive's new `.tar.gz` path. Updating `path` and adding a repository regression assertion made a fresh isolated HTTP run pass archive `202` → `ready`, stored `.tar.gz` path, and content `200` with the expected tar member. The environment reference now shows `AKOFLOW_LOCAL_STORAGE_ROOT` and `configuration.browseRoots`; top-level `browseRoots` alone is not persisted. Storage health and compute-node visibility are labeled as catalog/configuration signals, not live path or node probes. External storage providers remain unverified. + +109. **P1 resolved in HPC registration and storage narrative:** the tutorial listed compute-allocation workspace access as an expected result of registration, although its steps stop after SSH health and discovery from the daemon/login path. The result table now records the site path and defers compute-node access to the batch probe in the operator guide. The Lustre/NFS catalog excerpt now says Desktop browsing also needs a configured browser and approved roots. Institutional SSH, scheduler, and allocation validation remain open. + +110. **P1 resolved in cloud catalog result:** the GCP tutorial treated available machine, image and disk choices as the expected result of `valid: true`. The validation handler returns counts from discovery without requiring any count to be positive; public-image lookup errors can also be warnings. The tutorial now asks readers to inspect the counts and investigate an empty category before provisioning. Live credential and provider checks remain open. + +111. **P1/P2 resolved in the public reference overview:** the Desktop/API coverage page mixed a user route map with maintainer instructions. The update rule now lives in the editorial contract, leaving the public page focused on finding a task, guide, and API family. The API overview's archive rule said only mutating requests return `423`, but `readOnlyAPI` blocks every non-`GET` method except instance activation; the wording now matches the middleware, including `HEAD`. Full endpoint-contract and final plain-language audits remain open. + +112. **P0 resolved in health diagnostics:** the API overview and troubleshooting guide called the root health route without a bearer token, which returns `401` on a protected daemon because only instance identity and preflight are public bootstrap routes. Both root commands now send the configured token; troubleshooting labels preflight correctly as public. A security regression assertion covers the root route. The generated root endpoint template already supplied the token. + +113. **P1/P2 resolved across six task guides:** the provenance page repeated its screen tables in three long screenshot captions, which now identify the relevant result without re-explaining controls. A cross-page scan found 16 authored API `curl` examples without HTTP-error failure behavior across provenance, workflow definitions, planning, executions, build context, and troubleshooting. All now use `--fail-with-body`, so failed lookups and uploads produce failing exit statuses; download examples already used `--fail`. The shell checker now rejects future `curl` lines without either fail option. Syntax, links, and HTTP behavior have separate verification scopes. + +114. **P1 resolved in generated cloud navigation:** seven environment-scoped cloud catalog, target, instance, and provisioning routes appeared under the generic Environments endpoint category because their URL starts with `/environments/`. The generator now groups them by their cloud operation, gives them the cloud-capacity guide, and points the compatibility provisioning route to the moved instance endpoint. The generated route count remains 125. Redirects preserve the seven former documentation URLs; HTTP routes are unchanged. Link/build checks cover the new navigation, while cloud account behavior remains unverified. + +115. **Entry/reference consistency check:** all 97 route rows in the API overview expanded to 124 method/path pairs, and every pair matched `internal/api/httpserver/httpserver.go`; the overview is intentionally a summary rather than a list of all 125 endpoint pages. In the new-user layer, Getting Started now names the verified Kubernetes example as Kind, and Installation no longer repeats the Windows asset distinction already stated in Downloads. This check covers route registration and wording, not field or response contracts. + +116. **P0 resolved in cloud zone selection claim:** the capacity guide asked readers to choose a zone policy and sent `zonePolicy: "any"`, implying that policy controls provisioning. The target repository stores the field, but the Terraform runner passes only `fixedZone` to its module; without it, the module takes the first active zone returned for the region. The capacity guide, GCP guide, and generated target endpoint note now say this directly, and the example omits the ineffective policy value. This is source-audited behavior; a live project run remains open. + +117. **P0/P1 resolved in S3 credential narrative:** the AWS guide claimed every nonempty transfer credential reference fails, but `EnvironmentS3Credentials` accepts the literal `env` as well as an omitted reference; only other values fail with the default resolver. The guide and environment reference now state that rule. The default S3 storage browser is constructed without a credential resolver, so its saved `credentialReference` and server AWS environment variables do not sign browse requests; the docs distinguish that from the separate transfer connector. A regression assertion covers the accepted `env` reference. Live AWS and S3-compatible bucket access remain unverified. + +118. **P1 resolved in storage entry narrative:** the storage guide formerly sent object-storage readers to two support pages before they could learn whether browsing a private S3 bucket would work. Its opening now states the current unsigned-browser limit directly and distinguishes browsing from credentialed transfers, while retaining the AWS guide for details. The generic catalog caveat was shortened. Remote and provider storage operations remain unverified. + +119. **P1 resolved in editorial governance:** the public Documentation production plan already held the page-level writing contract, KEEP/SIMPLIFY/MOVE/DELETE/VERIFY labels, priority order, iterative loop, and completion gate. The repository quality plan now links to that contract instead of duplicating its rules. The contract makes progressive disclosure explicit and describes the current shell check's HTTP-error requirement. The quality-plan link-check evidence was refreshed to 456 local links and 54 Showcase downloads. + +120. **P1/P2 resolved across the five explanation pages:** the planning explanation treated candidate rank as immediate, although ranking and Pareto fields are finalized when a session completes, and its selection sentence could imply that selecting a candidate starts a run. The page now states the lifecycle in order. Evidence/provenance now distinguishes real runtime handles from simulated task timing, which has no provider job to inspect. Network route wording and observed-timing introduction were shortened, and the PRISM/HEFT comparison headings now name the reader's task. The final all-page audit remains open. + +121. **P0 resolved in generated map response shapes:** shallow key extraction rendered every value of several `map[string]any` responses as `"string"`, including cloud validation's boolean `valid` and integer counts, connection health's boolean, search totals and result arrays, provenance arrays, archive activation's boolean, and planning-session runs. Checked shapes now cover nine handlers. The connection test note says `200 OK` can still have `healthy: false`; cloud validation counts can be zero. `GET /execution-runs/` has two actual response forms: an array without pagination parameters and an envelope when `page` or `pageSize` is supplied; its misleading single example was replaced with that rule. The generator rejects checked-shape entries whose handler disappears from the router. This closes this map-shape class, not full field/response validation of all 125 endpoints. + +122. **P1/P2 resolved in the three infrastructure tutorial openings:** API setup now names its specific reader and tools; HPC registration begins with the result the steps can prove; and the GCP connection tutorial starts with its own task instead of an unrelated AWS/S3 support paragraph. HPC and GCP use the same “Check the result” heading. Their external-account, batch-job, and live-provider limits remain at the step or result where the reader needs them. Remote HPC and GCP validation remain open. + +123. **P1 resolved in Cloud navigation and page purpose:** a provider matrix interrupted the cloud-capacity procedure before its first catalog action. It now has a dedicated Cloud provider support page immediately before the capacity guide in the sidebar. Getting Started links directly to that page, and the stale section anchor was removed. The capacity guide begins with its task and links to the support decision; the matrix keeps GCP compute, incomplete GCS transfer, partial AWS S3 transfer, and unverified live-provider limits together. The Cloud path is now support → connect GCP or review AWS → configure capacity, without hiding the status behind a long how-to opening. + +124. **P1 resolved in notification recovery:** the API section for a cloud-provisioning notification formerly listed cloud instances, which show resource state rather than the tracked operation. It now lists cloud operations, adds artifact-build runs for another notification type named on the page, and identifies Desktop update notices as app-local. The Desktop section heading and terminal-state description were shortened. Router paths were checked against the current Go server; live Desktop notification behavior remains a separate UI validation. + +125. **P0/P1 resolved in Cloud provisioning acceptance wording:** both provision endpoints return `202 Accepted` after persisting and enqueueing an operation. Target existence, environment ownership, connection, credential, and provider checks happen later in the provisioner. The generated notes for both routes and the capacity guide now direct readers to status, failure reason, and events before treating a VM as ready. This is source-checked asynchronous behavior; a live provider run remains unverified. + +126. **P1 resolved in Cloud operation follow-up reference:** list, detail, and event endpoints now explain global newest-first listing, terminal versus retrying status, and sequence-ordered events. A provider-log error event may belong to a retried attempt, so readers check the operation status before treating it as final. The shared generated endpoint component now says optional JSON fields may be absent, and all handler-checked notes use a behavior heading that fits both GET and mutation routes. The generator rejects notes for routes missing from the Go router. This checks the Cloud operation response narrative, not all 125 endpoint field contracts. + +127. **P0/P1 resolved in cross-runtime setup reading:** the pinned v1.0.8 SLURM catalog opts its login node into direct workflow scheduling, while current discovery marks a login gateway unschedulable. The current repository example now defaults that login node to unschedulable, and the HPC guide tells readers how to correct the pinned file before institutional registration. It distinguishes a batch compute node from an approved direct target. Its discovery checklist no longer presents compute-allocation workspace access as something a login-host probe can prove; that check belongs to the later batch probe. Kubernetes and SimGrid opening prose was shortened while keeping their real-versus-modeled boundary. A real cluster run remains unverified. + +128. **P1/P3 resolved in entry-layer plan/run narrative and diagram:** the authored-page inventory still matches all 61 current source pages. Home, Getting Started, and Core concepts now state the explicit execution action between selecting a plan and recording a run; the record-chain SVG labels that arrow and its accessible description follows the same sequence. Its unclosed arrow paths previously rendered as large filled triangles; the SVG now keeps paths unfilled, verified in a Chromium screenshot. At 390 × 844, the built Home → Getting Started → Installation → first local workflow links opened without page errors or horizontal overflow. The first-workflow tutorial names the separate **Execute plan** and **Start execution** controls. The final all-page new-reader pass remains open. + +129. **P3 resolved across architecture diagrams:** the record-chain inspection exposed the same inherited SVG fill behavior in nine other arrow groups. In particular, the request-dispatch branching paths rendered as large black triangles that obscured the branches. Arrow groups now set `fill="none"`, and the two standalone network arrows do the same. All 13 architecture SVGs parse with a title and description; Chromium previews of request dispatch, planning lifecycle, control-plane components, and network flow were inspected after the fix. The diagrams' wording and topology were not changed in this pass. + +130. **P1 resolved in Cloud read-reference behavior:** all 21 generated body examples are marked verified and no inferred body example is displayed, but three Cloud GET pages lacked the distinctions needed to interpret their results. The catalog GET reads synchronized cache and can return `404` before refresh; the target list returns only enabled records; the instance list includes destroyed records. Handler and repository source were checked for all three, and the generator's route guard covers their new notes. This narrows a reference gap without claiming full field-level validation of the 125 endpoints. + +131. **P1 resolved in artifact evidence wording:** a cross-page read of all six Data and evidence guides found one contradiction: the artifact-location guide said the API lists saved observations, while the API overview promised to "inspect prepared bytes" and the guide's closing sentence implied a fresh byte check. Both now describe recorded locations, preparation status, and run observations. The list handlers read catalog records; they do not recheck destination bytes. The other Data and evidence pages kept their distinct build, provenance, and audit tasks. The final all-page pass remains open. + +132. **P0 resolved in Audit coverage claims:** the guide, chooser, notifications, entry pages, explanation, and route map previously implied that Audit records workflow, credential, planning, build, and cloud operations, or answers who changed any state. A repository-wide search of `RecordAuditEvent` call sites found producers only for connection health, resource discovery, and console commands/sessions. Twelve authored pages now route readers to the owning operation or provenance record and state the actual Audit scope. The Desktop still shows workflow and credential category tabs, but the current daemon does not emit events into them. The final all-page pass and live Desktop verification remain open. + +133. **P2 resolved in four long prose blocks:** a length scan across the Markdown/MDX documentation found five non-code paragraphs over 85 words. Four were split or shortened after review. The Cloud target note now separates required input, provider choices, and saved outcome/failure recovery without removing its checked prerequisites; the generator remains the source of truth. The documentation production plan states what local checks cover in shorter prose. The environment YAML reference separates binding fields from S3/GCS limitations, and the planning-state reference separates algorithm lifecycle from progress fields. The fifth is a dense schedule-import request contract left intact for field-level verification. The final all-page plain-language pass remains open. + +134. **P1 resolved in the network explanation:** a cross-read of the five explanation pages and the scope/topology reference found one incorrect opening premise: the network page said the directed topology is included in the execution scope. The scope may omit `networkTopologyId`; a planning session supplies its own topology ID, while a topology records its scope ID. The opening now says the topology is chosen for the planning session, without introducing the optional-field detail before the reader needs it. Source checks covered the planning-session validator and topology repository. The final all-page pass remains open. + +135. **P1 resolved in the Docker artifact response example:** a scan of map-shaped API responses found that `POST /artifacts/docker/` showed empty `artifact` and `build` objects, although the next documented step requires `build.id`. The generated example now shows the `ArtifactVersion` and `ArtifactBuild` JSON fields, including both IDs, and the route note distinguishes registration from the later build run. Handler, domain structs, and the existing HTTP repository test confirm the response keys and stored build specification. This verifies one response family; the 125-endpoint field-level audit remains open. + +136. **P1 resolved in execution detail response coverage:** `GET /execution-runs/{runId}/` previously displayed `run: {}` and five arrays, hiding the run's key status/plan/timing fields and the conditional cloud/data families. The generated example now shows the core `ExecutionRun` fields and the response note names `infrastructureRuns`, `dataObjects`, `dataLocations`, `artifactMaterializations`, and `artifactTransferRuns` with their configuration conditions. The execution guide uses the same language. Handler map assembly, domain JSON fields, and the existing execution-detail HTTP test were checked. This narrows the response audit; it does not validate every nested array contract. + +137. **P1 resolved across four map response examples:** the planning-session detail, instance activation, provenance entity catalog, and provenance SQL schema pages showed empty nested objects or lists that hid the response fields readers need next. Their generated examples now show source-checked session/algorithm-run fields, active-instance identity and restart flag, one catalog entity with a field and link, and one safe SQL table with columns. Notes identify selected-plan fields as conditional, imported snapshots as read-only, and both provenance examples as partial catalogs. Handler, domain, catalog, schema, and instance-archive source were checked; the remaining 125-endpoint field audit is still open. + +138. **P1 resolved in the Cloud provisioning-log read path:** the remaining seven JSON-object response pages were checked against their handler map literals: cloud log, cloud/Kubernetes credential references, discovery snapshots, storage checksum, and the two promotion IDs. Their outer keys match current handlers. The Cloud log page now says to use an instance ID rather than an operation ID, and explains the `200 OK` waiting message before Terraform writes a log. The service and Terraform runner were checked. This completes the outer-key review of all 16 map-shaped response pages; nested fields, error variants, and the rest of the 125 endpoints remain open. + +139. **P0 resolved in generated list and nested response types:** a scan of all 125 generated response examples found `GET /audit-events/` rendered as `[null]` and four environment create/read/replace/list pages rendered `connectorBindings: [null]`. The generator had treated same-named Go structs from different packages as ambiguous. Audit now has a source-checked connection-event example; environment responses use the `environment.ConnectorBinding` fields. Beyond the sample depth, known struct values now render as `{}` instead of the false primitive `"string"` (for example runtime `capabilities`). Generation now fails if any displayed response example contains a synthetic null. The zero-null scan passed. This fixes the misleading-shape class while full field-level validation remains open. + +140. **P0 resolved in plan-creation response:** `POST /schedule-plans/` displayed `CreatePlanRequest` as its response, including the submitted workflow, resources, scope, and topology. The handler actually saves and returns only `request.Plan`, after filling its topology ID when needed. The generated page now shows `domain.SchedulePlan` and says that prediction values are saved without recalculation. Generation rejects future success-response types ending in `Request`. This fixes one endpoint contract; the field-level review of all 125 pages remains open. + +141. **P1 resolved in troubleshooting evidence:** the final checklist asked for Audit events as general operational evidence and labeled `/audit-events/` as durable operational events. Current emitters cover only connection health, resource discovery, and console actions, so the page now sends readers to the run or operation record for the failed step, Provenance for scientific evidence, and Audit only for its actual emitters. The API overview route label uses that same scope. Handler and emitter call sites were checked; the final all-page audit remains open. + +142. **P1 resolved in the entry narrative:** Home and Getting Started offered plan comparison before the first Desktop path, which makes a manual plan. They now lead with making and executing a plan, leaving comparison as a later choice. The first local-run introduction now promises the output-file record and checksum actually visible in Desktop, rather than suggesting the file bytes appear in the UI. The Home metadata describes the scientific-workflow task. Installation and Interface Tour were reread as part of the same path; no additional P0/P1 prose issue was found in this pass. Clean-host and cross-platform runs remain unverified. + +143. **P2 resolved in basic-path terminology:** Getting Started, Installation, API connection setup, and the first SimGrid tutorial called the AkôFlow server a `daemon` in prose where the reader only needs its address, readiness, or log. Those passages now use `server`; exact checkup labels such as **AkôFlow daemon** remain unchanged. This keeps implementation vocabulary out of the entry path without hiding operational prerequisites. The larger user-guide terminology pass remains open. + +144. **P1 resolved across data and evidence tasks:** the Audit guide's procedure still said to find any "operation" in Audit and to compare a workflow run ID directly with an Audit event, despite the limited emitters. It now names connection checks, discovery, and console actions and sends workflow-result tracing to Provenance. The chooser includes discovery in the same scope. The Docker-to-SIF guide now states that a live registry pull and conversion remain unverified, matching the audit evidence rather than implying a completed build is already demonstrated. The artifact-location and Provenance guides were reread without another P0/P1 wording change; runtime/provider validation remains open. + +145. **P1 resolved in operations page ownership:** the earlier preferences split left a full duplicate Desktop/API procedure in Instance management, despite its link to the dedicated Personal preferences page and an inventory note claiming it had moved. The duplicate is removed; the link, dedicated guide, sidebar entry, and API overview remain. A repository search found no links to the removed heading. The notifications guide now calls its absent server record "server-side" rather than introducing daemon terminology. Search, console, and the remaining instance lifecycle were reread; snapshot/runtime behavior still needs its own validation. + +146. **P1 resolved in environment-to-execution progression:** Planning now introduces the manual path used by the first Desktop workflow before explaining automatic candidate comparison. Execution includes the verified local runtime among real-run examples. The execution-scope API explanation marks `networkTopologyId` optional and says a planning session selects its topology; the scope repository and planning service were checked. The SimGrid prerequisite uses user-facing server terminology. Environments, Kubernetes, and HPC/SLURM were reread in the same sequence; live remote-target validation remains open. + +147. **P1/P2 resolved across explanations:** the Planning explanation now introduces manual placement as well as automatic session comparison, matching the first Desktop path and the planning guide. The Evidence/Provenance opening sends scientific-result questions to Provenance and limits Audit to its actual emitters. Observed timing no longer repeats the same 10 GiB/10 Gbit/s calculation already worked through in Network modeling; it links to that example. PRISM/HEFT and Network modeling were reread without another P0/P1 prose change. Field-level trace aggregation and full scientific-result validation remain open. + +148. **P2 resolved in page descriptions:** a scan of all 61 authored documentation pages found nine without frontmatter descriptions: four infrastructure guides, three workflow guides, Architecture internals, and Runtime adapters. Each now has a one-sentence description naming its task or subject without adding a support claim. A second scan found zero missing descriptions across the 61 pages. This standardizes metadata and previews; it does not prove the body of every page has passed the final editorial gate. + +149. **P2 resolved in first-paragraph language:** all 61 authored-page openings were scanned for whether they state a task or subject early. The scope/topology reference replaced "freeze the infrastructure universe" with the concrete version-and-link relationship. The local direct Showcase now says the server runs the command on its own host and records workspace file changes; prerequisites use the same term. Other openings were left intact because their first paragraph already states a use or audience, or the page is a short choice table. This is an opening scan, not a full-body editorial pass. + +150. **P2 resolved in Showcase and operator wording:** a sentence-length scan of authored prose found few long sentences, but the local Showcase still alternated `daemon host` with `server host` after its opening had been simplified. Its evidence and recovery text, the Showcase index card/setup, and the edge-cloud trace location now use server language. The SLURM fixture keeps daemon terminology where it names the isolated process and script. The Linux server-update sequence is split into two shorter steps without changing the versioned-image order. Full-body and runtime-claim review remains open. + +151. **P1 resolved in three navigation continuations:** the first local workflow now links its recorded result to the plan-versus-run explanation, completing the new-user path from install through result interpretation. The HPC/SLURM guide links a site-approved run to execution monitoring. The cloud-capacity guide links a ready worker to scope membership and the Google Cloud validation/cleanup section, while still marking the live cycle unverified. These links address reading continuity; clean-host, institutional-cluster, and disposable-cloud execution still need their own evidence. + +152. **P0/P1 resolved in Showcase support language:** across all seven Showcase pages, the edge–cloud simulation still called its modeled target a "cloud VM" and said it "pays" for cloud use. It now names modeled resources, transfers, and cost. The network and 50-core index cards explicitly say their machines and cores are simulated. The Kind page no longer lists provenance among the verified outputs of its recorded run; Desktop inspection mentions lineage only when the explorer is configured. The real Kind run, local direct run, and local SLURM fixture remain distinct from the SimGrid scenarios. This wording does not substitute for provider or lineage verification. +153. **P1 resolved in developer architecture narrative:** the architecture page described an execution scope as combining environment versions with a topology, although planning sessions select the topology separately. It now gives each concept its actual role. The architecture and runtime adapter openings now state what the server and adapters do before introducing internal or legacy YAML detail; the SimGrid paragraph describes its behavior directly. +154. **P0 resolved in execution internals:** the page implied the workflow supervisor resumes an interrupted run from persisted handles and retries a failed activity. Current code creates a new run and tracks running handles in memory; a failed activity ends that run. The page now states those limits and distinguishes the activity controller's internal `Stop` method from an unavailable workflow-run cancellation API. The opening also explains the queue without a defensive control-plane label. +155. **P0 propagation pass on recovery and cancellation:** the architecture page still said queue retries made work recoverable across interruptions. The event loop can return an expired leased job to pending, but the supervisor does not resume an already-started workflow; the page now states that distinction. The execution page description no longer promises runtime recovery. The SLURM guide now distinguishes the adapter's internal `scancel` call from an unavailable workflow-run cancellation API and directs users to site-approved procedures. +156. **P1 resolved in task-state presentation:** the execution guide listed every domain `TaskExecution` state as if users should observe that progression, including `preparing` and `cancelled`. The current supervisor persists running/completed/failed task states. The guide and state reference now distinguish implemented observations from model values, and the preparation troubleshooting step no longer assumes a persisted `preparing` task or runtime log. +157. **P1 resolved across generated endpoint presentation:** all 125 generated pages inherited a formulaic description and displayed the same placeholder sentence for query parameters, even though the generator already defined descriptions for all 26 query names it found. Pages now use their route-specific title and method/path in metadata, show the route title as the heading, and display the mapped query explanation. Generation fails if a future query parameter lacks a description. Handler and response-shape claims still need their own evidence pass. +158. **P1 resolved in generated response evidence language:** the endpoint component labeled manually handler-checked JSON examples and Go-type-inferred JSON examples with the same generic sentence. It now identifies which examples were checked against handlers and which only show fields inferred from Go types, so an inferred shape is not presented with the same confidence as a checked contract. The remaining inferred response shapes still require route-by-route verification. +159. **P1 resolved in Provenance response examples:** entity query and read-only SQL pages showed synthetic `[{}]` rows because their row keys depend on the selected entity or query. Handler and service checks now support empty-result examples with the real response envelope and a note about variable columns. The SQL explain page omits a fixed plan example because SQLite plan rows depend on the statement and database; it names the response fields instead. Other inferred shapes remain to be checked. +160. **P1 resolved across inferred list fields:** generated request and response shapes still included `[{}]` and `[null]` for list items whose Go type was ambiguous or truncated by the sampler's depth limit. Those placeholders looked like real rows. The sampler now emits an empty list for such fields, including optional connector bindings, and generation rejects ambiguous null/empty-object list items in future examples. A full manifest scan found none across the 125 pages; known item fields still appear where inference succeeds. +161. **P0 resolved in environment field contract:** the YAML reference marked version model labels and configuration hash as API-required and treated environment/version status, resource type, and connection type as validated enums. The create handler sends the decoded definition directly to the database repository; its schema permits empty strings in those fields and does not constrain those status/type lists. The reference now separates recommended values from enforced constraints and points topology links to their own document, not the scope document. Runtime driver/mode and storage type retain their database-validated wording. +162. **P0 resolved in environment parent IDs:** the YAML reference marked nested `environmentId`/`environmentVersionId` fields as required in the request for versions, runtimes, resources, connections, and storage. Repository insertions use the enclosing environment/version IDs instead, including for relations. The reference now marks the nested IDs optional, explains their saved values, and distinguishes the create response (submitted document) from a later GET (persisted IDs). Remaining field-level claims still need review. +163. **P0 resolved in environment binding authoring:** the reference presented `connectorBindings` and `connectionChecks` as part of a persisted EnvironmentDefinition, but the create/replace repository ignores those slices. GET assembles recent connection checks from separate health records and does not return connector bindings from this document. The reference removes both from the authoring shape; generated POST/PUT request shapes and handler notes now explain the limitation. Resource-runtime bindings are recommended within the same version, while the current database only checks the two IDs individually; storage-runtime bindings have the stronger same-version foreign keys. +164. **P0 propagation pass on Environment API responses:** generated response examples for list/create/get/replace still showed `connectorBindings` even though the repository never populates them from EnvironmentDefinition; some also showed a synthetic connection check. The four examples now omit connector bindings, POST/PUT examples omit checks, and GET examples start with an empty check list. GET endpoint notes explain that any observed checks come from separate health history. The authored-doc search found no other promise that these slices persist through Environment POST/PUT. +165. **P0 resolved in planning versus execution binding narrative:** Environment YAML, scope/topology troubleshooting, and SimGrid troubleshooting claimed an unbound resource is absent from planning candidates. The current planning filter uses scope membership, `schedulable`, and non-batch capacity checks, but does not read runtime bindings; the execution supervisor requires an enabled binding for each assignment. All three pages now locate that check at execution and give separate diagnostics for candidate placement and run rejection. +166. **P1 resolved in plan readiness language:** the planning explanation's metadata said a selected placement becomes executable, and the guide/reference could let readers treat `feasible` or a validated imported plan as a runtime readiness check. The plan validator checks workflow/placement constraints but not runtime bindings; the execution supervisor checks those before a run starts. The explanation, planning guide, and state reference now make that distinction at selection and import. +167. **P2 resolved in first-user narrative:** the Home subheadline introduced provenance before the first workflow, while the verified local tutorial ends with an observed output-file record and checksum. Home now promises only the result inspection used on that path; Provenance remains a follow-on guide. At 390 px, browser clicks reached Home → Getting Started → Installation → First local workflow with no JavaScript errors or horizontal overflow. +168. **P0 resolved in the HPC path:** the SLURM guide warned readers to keep the login node unschedulable, but its own YAML excerpt set `slurm-login-node` to `schedulable: true`. The excerpt now uses `false`, matching the current repository example and the guide's batch-allocation instructions. A real institutional run still requires site access and approval. +169. **P0 resolved in SSH trust language:** the HPC guide called host keys recorded by the first connection test trusted, while the SSH executor uses `StrictHostKeyChecking=accept-new`, which saves an unknown key without checking it against an administrator's fingerprint. The guide now requires that comparison for the login host and gateways, and the registration tutorial distinguishes the service-key fingerprint returned by the API from the remote host-key fingerprint. +170. **P2 resolved in the workflow run guide:** the API path interrupted the submit-and-inspect task with a nine-field execution envelope list. It now explains the example's purpose in user terms, keeps the `202 Accepted` and run-ID instructions, and sends field-level readers to the generated request reference. +171. **P2 resolved in the developer architecture page:** the API, planning, and execution sections each compressed many services, frozen inputs, or supervisor steps into one long enumeration. They now explain the responsibility and sequence in shorter sentences, preserving the algorithm/model distinction and real-versus-simulated execution boundary. +172. **P0 resolved across documentation navigation:** source-relative Markdown page links compiled to plausible absolute `href` values but client-side clicks resolved their original relative paths against the current URL; the execution guide's request link landed on `/docs/guides/api/...` and the Kind example on `/docs/guides/showcase/...`, both 404s. All 334 remaining relative links to documentation pages were converted to `/docs/...` routes across 58 pages. The repository link check now rejects newly introduced route-relative links. A 390 px browser pass clicked a visible internal link from each of the 61 authored pages: all 61 reached their compiled targets after accounting for hidden Showcase tabs. +173. **P2 resolved in developer explanations:** the execution page's handle and recovery paragraphs now separate saved evidence, failure behavior, and cancellation limits. The runtime page replaces long capability and extension inventories with the driver/mode model, a field-reference link, and the steps needed to validate a new provider. No user path gained internal terminology. +174. **P0 resolved in factory-reset claims:** the instance guide promised removal of all managed credentials and implied a server reset cleared personal preferences everywhere. `cmd/server/api.go` resets the database and removes only the managed Kubernetes token directory; SSH/cloud credential files and artifact bytes remain. Desktop additionally clears its current browser profile's local storage, while direct API calls do not. The guide and API overview now state these boundaries, including the Desktop confirmation's broader wording. The generated endpoint already had the narrower server-side contract. +175. **P1 resolved in Desktop notifications:** the guide described application-update notices as terminal tracked-operation states. `NotificationCenter.jsx` instead shows `available`, `downloading`, and `downloaded` update phases in a separate card; tracked planning, execution, build, terminal, and provisioning results become saved notification entries. The page now separates these cases and keeps the profile-local persistence limit. +176. **P2 resolved in task-path headings:** the HPC and Google Cloud tutorials used “Through the interface/API” while the other task guides used “Using AkôFlow Desktop/the API”; the notification guide used a third “In Desktop” form. These headings now follow the same two-path vocabulary. The HPC operator guide's direct link to the registration API section was updated to the new anchor. +177. **P1 resolved in Desktop/API route coverage:** comparison with the current Desktop `src/App.jsx` found six real detail routes absent from the reference map: generic plan/run/activity details, scope and topology details, and environment-owned provisioning detail. The map now includes them with their owning API family and task guide. A route extraction found 45 functional mapped routes plus three redirect routes documented separately; `/` and the catch-all are outside this task map. A full built-HTML scan found 25 internal anchor links and no missing destination IDs. +178. **P2 resolved in the result-evidence path:** the choice page now tells a reader with a run ID where to start without repeating the scientific-versus-operational explanation. The Provenance guide describes exports as saved records or query pages rather than an ambiguous scientific “result,” and Audit states its supported event scope in two short paragraphs. The links still lead to the same task guides. +179. **P0 resolved in Windows download instructions:** the v1.0.8 release has one `Akoflow-Desktop-1.0.8-win-x64.exe` asset. The successful Windows packaging job built `nsis` and then `portable` to that same filename, signing the latter afterward; the published asset is therefore the portable target, not a separate installer. Downloads and Installation now say to run it directly. The future release-note template no longer promises both installer and portable assets. This conclusion comes from the release asset list and build order; a Windows host launch remains unverified. +180. **P0 resolved in execution submission contracts:** `POST /execution-runs/` returns a queue job, not a run, and the supervisor validates the queued request before `CreateRun`. The generated endpoint now says “Queue workflow execution,” shows a handler-checked new-job response, distinguishes job ID from `run.id`, and notes that a request rejected by worker validation can leave `GET /execution-runs/{runId}/` at `404`. The execution guide and state reference now give the same interpretation and a recovery direction. There is no public queue-job read endpoint to substitute for a missing run. + +## Page inventory + +| Page | Current pass | Next review | +| --- | --- | --- | +| `guides/workflows/first-local-run.md` | Navigation reread; result evidence now leads to the plan-versus-run explanation; Linux package UI run remains verified | Repeat on a clean supported host and other platforms | +| `src/pages/index.tsx` | Fifth read; first-user promise now ends at result inspection before introducing Provenance later | Recheck rendered entry path on mobile | +| `concepts.md` | Second claim reread; plan selection is separate from execution, including diagram alt text; runtime-dependent observations stay qualified | Recheck complete new-user path | +| `contributing/documentation-plan.md` | Fourth read; link and shell check scope now fits short paragraphs; progressive disclosure and HTTP-failing cURL checks remain explicit | Recheck contract at final audit | +| `downloads.md` | Third read; v1.0.8 Windows asset identified as portable from release job/build order; platform limits remain explicit | Recheck release links when version changes | +| `engine.md` | Fourth read; handle observations and recovery limits now read as separate responsibilities; cancellation remains explicitly unavailable via API | Recheck remaining queue claims against event-loop code | +| `explanations/evidence-and-provenance.md` | Fourth read; opening routes result records to Provenance and actual Audit emitters to Audit | Recheck against execution evidence after P0 fixes | +| `explanations/network-modeling.md` | Fourth read; opening now names the topology chosen for the planning session; one-byte route choice remains qualified | Recheck transfer claims against execution paths | +| `explanations/observed-timing.md` | Fourth read; makespan versus accumulated time leads, and network example is linked rather than repeated | Recheck metrics against trace aggregation | +| `explanations/planning.md` | Fifth read; saved-plan wording and execution-time binding check now match validator/supervisor | Recheck remaining planning claims against coordinator | +| `explanations/prism-and-heft.md` | Third read; comparison headings now describe observed-run and experiment tasks | Recheck algorithm claims against source | +| `getting-started.md` | Sixth read; a manual first plan precedes comparison and server terminology stays user-facing | Recheck the entry flow on a clean supported host | +| `guides/data/artifacts.md` | Short choice page preserving the old URL and routing storage, build, and recorded-location tasks | Check destinations in navigation | +| `guides/data/build-executable.md` | Fourth read; source-checked Docker/SIF build flow now identifies missing live conversion evidence | Verify a live registry pull and SIF conversion | +| `guides/data/artifact-locations.md` | Cross-page read; catalog and run observations are explicitly saved records, not live byte checks | Recheck materialization payloads after P0 contracts fix | +| `guides/data/provenance-and-audit.md` | Third read; run-ID choice is direct and the explanation link follows the task choice | Check both destinations in navigation | +| `guides/data/provenance.md` | Plain-language reread; export wording names record/query pages and run-first entry; API examples fail on HTTP errors | Recheck Desktop interactions against packaged app | +| `guides/data/audit-events.md` | Third read; opening separates recorded event types from absent workflow/credential history | Recheck Desktop interactions against packaged app | +| `guides/infrastructure/aws.md` | Third read; omitted/`env` transfer credential selection and unsigned S3 browsing are explicit | Check provider claims against disposable-bucket evidence | +| `guides/infrastructure/cloud-capacity.md` | Fifth read; ready-worker next step points to scope membership and GCP validation/cleanup | Validate with disposable GCP account | +| `guides/infrastructure/cloud-support.md` | First read; GCP/AWS support matrix separated from capacity procedure and linked to provider tasks | Recheck against live GCP/S3 evidence | +| `guides/infrastructure/machine-configurations.md` | Focused optional Ansible setup; validation and saved version use one playbook, and the returned version ID is consumed by the capacity example in the same Bash session | Validate against disposable GCP worker | +| `guides/infrastructure/environments.md` | Plain-language/claim pass; local API definition persisted in a one-off repository test, and in-use revision language matches the API | Recheck remote flows with provider evidence | +| `guides/infrastructure/execution-scopes.md` | Third read; API explanation marks scope topology ID optional and session topology selection explicit | Recheck API payloads after P0 contracts fix | +| `guides/infrastructure/gcp.md` | Third read; target zone choice now matches Terraform's fixed-or-first-active behavior | Check provider claims against disposable-project evidence | +| `guides/infrastructure/hpc-slurm.md` | Sixth read; registration API link follows the standardized heading; login-node and first-contact SSH limits remain explicit | Check provider claims against real cluster evidence | +| `guides/infrastructure/kubernetes.md` | Second cross-runtime read; real Job versus modeled-cluster choice is direct, and the token stream stays out of shell variables and files | Recheck procedure against Kind bundle and shared-cluster RBAC | +| `guides/infrastructure/simgrid.md` | Fifth read; missing-candidate troubleshooting no longer attributes planning exclusion to runtime binding | Recheck procedure against pinned bundle | +| `guides/infrastructure/storage.md` | Third read; opening now states unsigned S3 browsing directly; local API path remains verified | Verify remote/provider storage independently | +| `guides/interface-tour.mdx` | Plain-language pass; removed repeated Desktop/API framing and shortened search/breadcrumb guidance; rendered page inspected at 390 × 844 | Recheck screenshots and controls during final visual audit | +| `guides/operations/credentials-and-ssh.md` | Task-scope reread; now covers SSH keys and assignment only, with provider credentials routed to their own tutorials | Recheck current Desktop form and key lifecycle claims | +| `guides/operations/instance-management.md` | Third read; reset now distinguishes database records, Kubernetes tokens, retained SSH/cloud/artifact files, and Desktop browser storage | Recheck complete snapshot behavior against a local archive | +| `guides/operations/personal-preferences.md` | Focused Desktop/API instructions for theme and graph animation, moved from instance management | Recheck current Desktop controls | +| `guides/operations/interactive-console.md` | Plain-language reread; basic path and diagram now use resource/connection terms, while API retains returned IDs; closure follows streaming/log use | Recheck session behavior against Desktop | +| `guides/operations/search-and-notifications.md` | Short choice page preserving the old URL and distinguishing lookup from profile-local alerts | Check both destinations in navigation | +| `guides/operations/find-records.md` | Desktop/API search procedure, result fields, limits, and empty-result recovery | Recheck UI behavior against Desktop | +| `guides/operations/follow-notifications.md` | Fourth read; Desktop heading matches task guides and update card is separate from saved terminal-operation notifications | Recheck UI behavior against packaged Desktop | +| `guides/operations/server-instance.md` | Third read; update sequence split into short steps; tunnel command and HTTP failure checks remain | Recheck release assets when version changes | +| `guides/operations/troubleshooting.md` | Fifth read; evidence collection now separates run/operation records, Provenance, and actual Audit emitters | Recheck other diagnostic claims after P0 fixes | +| `guides/workflows/definitions.md` | Third read; API list, detail, and export now fail on HTTP errors | Recheck payload against importer after P0 contracts fix | +| `guides/workflows/executions.md` | Eighth read; API path now handles temporary or persistent missing run after `202` due to pre-run worker validation | Recheck other runtimes against their own guides | +| `guides/workflows/first-run.md` | Terminology reread; server address/readiness/log language is consistent; fixed-plan submission remains validation and save | Keep the SimGrid API example aligned with its versioned bundle | +| `guides/workflows/planning.md` | Fifth read; `feasible` and imported-plan validation no longer imply runtime readiness | Verify automatic Desktop planning flow | +| `installation.md` | Fifth entry-path read; Windows step now matches the single published portable EXE; Desktop checkup stays central | Verify clean-host and cross-platform installation | +| `internal/workflow-spec.md` | Second read; lead example now uses one execution mode and marks script paths as prerequisites | Check every field contract against current importer | +| `modules.md` | Developer detail remains in the architecture section; API, planning, and execution passages now use short responsibility/sequence explanations | Recheck remaining claims against daemon composition | +| `reference/api-overview.md` | Eighth read; factory-reset route label now points to retained-file cleanup; 124 listed method/path pairs match the current Go router | Check field and response contracts against current handlers and schemas | +| `reference/environment-yaml.md` | Eighth read; binding is now required at execution, not a planning candidate filter | Continue remaining field-level schema contract audit | +| `reference/execution-scopes-and-topologies.md` | Second pass; candidate diagnostics now separate planning filters from runtime binding validation | Check remaining contracts against current handlers and schemas | +| `reference/feature-coverage.md` | Fourth read; all 45 functional Desktop paths map to an API family and guide, with three redirects described separately | Check contracts against current handlers and schemas | +| `reference/planning-and-execution-states.md` | Sixth read; queue acceptance and pre-run validation failure now distinguished from a persisted run | Recheck generated endpoint contracts after P0 fixes | +| `runtimes.md` | Third read; capability and provider-extension inventories shortened, with field details linked to Environment YAML | Recheck other provider claims against adapters | +| `showcase/edge-cloud-simulation.mdx` | Fourth read; modeled resources, transfers, and cost replace real-VM phrasing | Check result against pinned bundle | +| `showcase/index.mdx` | Fourth read; simulation cards label modeled machines/cores and fixture remains distinct | Recheck cards after Showcase audit | +| `showcase/kubernetes-real-execution.mdx` | Third read; intro names observed Kind outputs, with lineage conditional on explorer configuration | Check result against pinned bundle | +| `showcase/local-direct-execution.mdx` | Fourth read; server-host wording is consistent across purpose, evidence, and recovery | Check result against pinned bundle | +| `showcase/network-fanout.mdx` | Second read; model-specific estimate phrased directly; authenticated polling now fails on HTTP errors | Check result against pinned bundle | +| `showcase/parallel-50-core.mdx` | Second read; compute-capacity purpose stated directly; authenticated polling now fails on HTTP errors | Check result against pinned bundle | +| `showcase/slurm-local-fixture.mdx` | Second read; local adapter evidence and real-cluster limits stated once; versioned checkout and optional Desktop inspection retained | Check result against pinned bundle | +| `tutorials/api-access.md` | Fourth read; API-only prerequisites and token limits use server language; Bash blocks parsed | Recheck commands after P0 contracts fix | +| `tutorials/connect-cloud.md` | Third read; Desktop/API path headings now match the other task guides; valid access remains separate from nonempty catalog choices | Validate with disposable GCP account | +| `tutorials/register-hpc.md` | Fourth read; Desktop/API headings match the other guides, and service-key and host-key fingerprints remain distinct | Validate on an approved institutional cluster | + +## Verification in this pass + +- `npm run typecheck`, `npm run build`, `npm run check:links`, and `git diff --check` passed on the editorial branch. All 125 endpoint pages generated; targeted checks confirmed the console-command request, qualified environment and workflow responses, and all six versioned first-run links. +- All 107 fenced Bash/sh blocks in authored documentation parsed with `bash -n` on 2026-09-13. Duplicated blocks were removed as artifact, SSH, and installation guides were focused; the preferences block moved and a saved-plan import example was added. This is a syntax check, not an execution test; snippets embedded in JSX and commands outside fences need separate review. +- The latest link check covered 466 local links/assets and 54 showcase downloads from the `v1.0.8` Git tag on 2026-09-13. It now rejects route-relative Markdown links whose source target is another documentation page. +- Headless Chromium at 390 × 844 loaded Getting Started, Core concepts, the console guide, the new Desktop first-run page, and all seven Showcase pages without page errors or horizontal overflow. Every Showcase API tab displayed its v1.0.8 checkout command; the first-run page's mobile menu opened and showed its tutorial link. +- These checks establish site integrity for this pass. They do not prove tutorial execution, provider support, or completion of the editorial gate. diff --git a/docs/editorial-closeout-2026-09-13.md b/docs/editorial-closeout-2026-09-13.md new file mode 100644 index 00000000..c8b78ac8 --- /dev/null +++ b/docs/editorial-closeout-2026-09-13.md @@ -0,0 +1,22 @@ +# Editorial version closeout + +Date: 2026-09-13. Branch: `docs/editorial-consistency`. This closes the current editorial iteration, not the external-user completion gate in `quality-plan.md`. + +## What changed + +- All 61 authored pages received an editorial inventory and at least one pass. The entry path now leads from workflow and environment to plan, run, and result. Task guides put Desktop or API steps before internal architecture; the developer pages retain implementation details. +- Support language distinguishes verified local, SimGrid, and Kind runs from a local SLURM adapter fixture and unverified institutional HPC and live cloud paths. The Cloud support matrix states the current GCP, AWS EC2, S3, and `gs://` limits. +- A Linux v1.0.8 Desktop package completed the documented first local workflow and produced a recorded output file and checksum. The package was extracted and launched under Xvfb with Docker; this does not establish clean-host package-manager installation or other-platform launch. +- The generator builds 125 endpoint pages. All 61 mutating routes have handler-checked notes or versioned runnable SimGrid requests. It no longer presents inferred request bodies as runnable examples, labels illustrative response shapes, and fails on unknown success statuses. +- Documentation navigation uses stable `/docs/...` routes. The checker rejects route-relative documentation links. The mobile menu fix and a 390 px browser pass are recorded in the audit ledger; one internal link from each authored page reached its compiled destination. +- `documentation-plan.md` now holds the ongoing editorial contract. `editorial-audit-2026-09-12.md` records individual corrections and evidence. + +## Final assessment of this iteration + +The basic narrative, verified Linux first-run path, site navigation, and documented support boundaries are substantially improved. Current build and link checks establish that the site compiles and its checked routes resolve. They do not establish that every API field example is correct or that every procedure works on every claimed host and provider. + +The full completion gate remains **open**. `quality-plan.md` retains the specific work: clean-host and other-platform installation, real GCP and S3 account validation, institutional SLURM validation, field-level verification across all 125 endpoint contracts, and a final plain-language and claim pass after those corrections. The audit ledger explicitly records these as unresolved. No claim of zero P0/P1 findings is made for this version. + +## Handoff + +Keep the pull request in draft until the completion gate is evidenced. Resume with the open items in `quality-plan.md`, prioritize false or unusable instructions, and update the support matrix and page inventory as each external validation is completed. Re-run typecheck, production build, link and shell checks, then inspect the rendered first-user paths at mobile and desktop widths before marking the documentation ready. diff --git a/docs/package.json b/docs/package.json index 32387a9b..d11c1759 100644 --- a/docs/package.json +++ b/docs/package.json @@ -17,7 +17,8 @@ "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", "typecheck": "tsc", - "check:links": "node scripts/check-links.mjs" + "check:links": "node scripts/check-links.mjs", + "check:shell": "node scripts/check-shell-examples.mjs" }, "dependencies": { "@docusaurus/core": "3.8.1", diff --git a/docs/quality-plan.md b/docs/quality-plan.md index 981766be..b48f8d66 100644 --- a/docs/quality-plan.md +++ b/docs/quality-plan.md @@ -2,10 +2,12 @@ This file is the editorial backlog for preparing the AkôFlow documentation for external open-source users. Update it after each documentation unit. A checked item must point to evidence in the repository or to a recorded verification command; absence of a known defect is not sufficient evidence. -Last audited: 2026-09-11 after the verified SimGrid first-run exercise. +Last audited: 2026-09-13. The current iteration is assessed in [editorial-closeout-2026-09-13.md](./editorial-closeout-2026-09-13.md). The Desktop first-workflow gap and several generated-reference defects have been corrected. Clean-host installation, provider validation, remaining API contracts, and the final full-page audit still keep the completion gate open. ## Editorial contract +The [documentation production plan](./docs/contributing/documentation-plan.md) is the writing and review contract for every authored page. This file tracks evidence and unresolved work against that contract. + Every user-facing page has one primary Diátaxis purpose: - **Tutorial:** a learning path that starts from stated prerequisites and ends in a result the reader can verify. @@ -15,17 +17,26 @@ Every user-facing page has one primary Diátaxis purpose: Showcases are extended tutorials. They may link to how-to and reference pages, but must not duplicate those pages. Generated endpoint pages are reference material. Provider setup pages are how-to guides. Architecture and scheduling-model pages are explanations. +When a Desktop route or daemon endpoint changes, regenerate the endpoint reference, update the task guide and the Desktop/API coverage map, and add a screenshot only when it clarifies the interface. + ## Current evidence - [x] The documentation builds from a clean generated state. Evidence: `cd docs && npm run clear && npm run typecheck && npm run build`, passed on 2026-09-11. - [x] API endpoint reference is generated from `internal/api/httpserver/httpserver.go`. Evidence: `docs/scripts/generate-api-reference.mjs`; 125 generated endpoint pages in the current tree. -- [x] Provider limitations are stated explicitly. Evidence: `guides/infrastructure/cloud-capacity.md`, `gcp.md`, and `aws.md` distinguish GCP compute provisioning from AWS S3 support. +- [x] Generated map responses preserve checked JSON value types for nine handler responses; the execution-list endpoint documents its array and paginated-envelope variants. Evidence: `checkedMapResponses` in the generator, handler source, and generated cloud, search, provenance, planning, instance, connection, artifact, and execution pages. This is a shape check, not complete field-level validation. +- [x] Cloud operation list, detail, and events pages distinguish retry events from final status; generated JSON examples state that optional fields may be absent. Evidence: route-checked behavior notes in `docs/scripts/generate-api-reference.mjs` and the shared `ApiEndpoint.tsx` response label. Other endpoint field contracts remain open. +- [x] Cloud catalog, capacity-target, and instance list pages distinguish cached catalog reads, enabled-only target listing, and destroyed instance records. Evidence: route-checked notes in the generator plus handler and database queries; this is scoped read-behavior validation. +- [x] Environment-scoped cloud API routes appear with cloud operations and point to the cloud-capacity task guide. Evidence: the generator classifies `/environments/{environmentId}/cloud-*` before generic environment routes; seven pages moved to the Cloud category without changing the 125-route total. +- [x] Provider limitations are stated explicitly. Evidence: `guides/infrastructure/cloud-support.md`, `cloud-capacity.md`, `gcp.md`, and `aws.md` distinguish GCP compute provisioning from partial object-storage support. The current GCS connector rejects direct `gs://` transfer, and saved AWS credentials are not wired to the S3 transfer connector. - [x] GCP catalog and provisioning access are documented as source-audited behavior rather than an unverified IAM recipe. Evidence: `guides/infrastructure/gcp.md`, `internal/provider/cloud/gcp/catalog.go`, and `internal/provider/cloud/terraform/runner.go`; a disposable-project validation remains required. -- [x] HPC concepts and the proxy-aware connection path are documented. Evidence: `guides/infrastructure/hpc-slurm.md` and `guides/operations/interactive-console.md`. +- [x] HPC concepts and the proxy-aware connection path are documented. Evidence: `guides/infrastructure/hpc-slurm.md` and `guides/operations/interactive-console.md`. The guide also flags the pinned example's opt-in login-node scheduling and defers compute-workspace proof to a batch allocation. +- [x] The general environment guide does not imply a remote connection was saved after a standalone health test. It links to the complete HPC/GCP registration tutorials and uses the saved HPC template's connection ID for follow-up checks, verified on 2026-09-13. - [x] Existing Showcase download URLs use `raw.githubusercontent.com` and the 50-core bundle was checked against repository files on 2026-09-11. - [x] No screenshot markers remain. `rg '