---
title: Workflow guide
type: guide
status: active
updated: "2026-09-03T14:45:28Z"
description: "Explains the shared workflow folder, workspace links, and history lookup without migration."
owner: locus-pi maintainers
tags: [workflows, guide]
---

# Workflow guide

[Workflow documentation by topic](workflows/index.md) — open only the contract needed for the current task.

The `workflows` extension discovers trusted JavaScript workflow modules, runs them through Pi child sessions, and persists execution groups under `.locus-pi/runs/<storageRootRunId>/`.

To create or revise a workflow, start with [Locus Pi workflows: authoring and styles](locus-pi-workflows.md).

## Package catalog

`extensions/workflows/examples/` is the shipped registry.

<!-- locus:workflows:start -->
<!-- Generated by `npm run build:catalogs`. Edits between these markers are overwritten. -->

The registry ships four curated Package workflow namespaces with twelve runnable names.

| Workflow                      | Namespace          | Purpose                                                                                    |
| ----------------------------- | ------------------ | ------------------------------------------------------------------------------------------ |
| `live-smoke`                  | `live-smoke`       | Checks that the Pi host can spawn full-tool workflow agents and collect their reports.     |
| `post-code-review`            | `post-code-review` | Run modular code-shape review lanes and publish the code-shape decision.                   |
| `post-code-review/boundaries` | `post-code-review` | Audit ownership and architecture boundaries, then publish review-boundaries.md.            |
| `post-code-review/contracts`  | `post-code-review` | Audit API and internal contracts for one post-code review scope.                           |
| `post-code-review/necessity`  | `post-code-review` | Challenge behavioral and code-shape fixes for necessity, ownership, and complexity.        |
| `post-code-review/scope`      | `post-code-review` | Resolve a review target into an exact evidence boundary and write review-scope.md.         |
| `post-code-review/simplicity` | `post-code-review` | Audit a frozen review scope for delete-first contraction and publish simplicity findings.  |
| `post-code-review/style`      | `post-code-review` | Audit comments and project-specific code style for one post-code review scope.             |
| `post-code-review/synthesis`  | `post-code-review` | Verify review evidence and publish the final code-shape decision.                          |
| `stage-loop`                  | `stage-loop`       | Implements one task stage, gates it, fixes it up to three times, then commits.             |
| `task/draft`                  | `task`             | Turn a raw request into an editable workflow brief with explicit orchestration choices.    |
| `task/plan`                   | `task`             | Turn an accepted workflow brief into a checked workflow.mjs through bounded source slices. |

<!-- locus:workflows:end -->

`task` is a group-only namespace and is not runnable by itself.

## Operator commands

```text
/workflows
/workflows dashboard
/workflows list [query]
/workflows info [name]
/workflows status [runId]
/workflows result [runId|last]
/workflows run <name|path> [--run-name <name> | --output-dir <path>] [--resume <runId>] [--no-operator|--operator] [--] [input]
/workflows continue <runId>
/workflows stop [runId|last]
```

Bare `/workflows` opens the command menu when interactive UI is available and otherwise prints typed help.

Use `--` when semantic input begins with an option-looking token. Every fresh workflow run receives a unique `.locus-pi/workspaces/<generated-run-name>` workspace. Pass `--run-name <name>` with any workflow to select the stable `.locus-pi/workspaces/<name>` workspace. Existing named workspaces under `.locus-pi/plans/<name>` remain bound to that physical directory so their checkpoint identity cannot change; if both old and new directories exist, launch fails before child work. The `task/draft` completion card tells the operator to copy or edit the complete draft before passing it to `task/plan`; the `task/plan` card points to the generated `workflow.mjs`. `/workflows run <name|path> --output-dir <path>` selects another confined workspace. An absolute path must stay inside the project, `./path` resolves from the agent working directory, and other relative paths resolve from the project root. A legacy `.locus-pi/plans/<name>` explicit output directory is accepted only when it already exists; new legacy workspaces are never created.

The model-callable `workflow` tool accepts a package name or trusted script path and supports structured fields such as `items`, `outputDir`, `resumeFromRunId`, and an approved continuation. Fields that have no slash-command representation must fail closed rather than be silently dropped.

## Run evidence

Open the group README: it links the original launch, workspace, saved children, and resume attempts.

```text
.locus-pi/runs/<storageRootRunId>/
  README.md   links to the workspace and all execution types
  outputs/    human-readable host projection
  runtime/    machine evidence and continuation authority
    journal.ndjson         append-only lifecycle evidence
    result.json            terminal result, run metadata, and bounded finalization errors
    replay.ndjson          replay records when the source is eligible
    script-<sha256>.workflow.mjs
    artifacts/             answers, transcripts, result envelopes, inputs, and publications
  children/<runId>/         separate outputs/ and runtime/ for each saved child
  attempts/<runId>/         separate outputs/ and runtime/ for each resume attempt
```

Workflow-owned working files live separately under a unique `.locus-pi/workspaces/<generated-run-name>/` directory by default or in an explicit confined output directory. Independent root launches receive different groups even in one session; resume uses the original workspace but writes its own receipt. The workflow workspace and run-evidence directory must never resolve to the same directory. Loose `.locus-pi/plans/*.md` files are plan documents left by the removed `plan` extension: user data, not workflow workspaces.

The workflow workspace is the durable location for handoffs, final results,
review evidence, and explicit resume inputs. Keep disposable environments,
dependency caches, test basetemp, transient renderer output, and staging in
ordinary OS or tool temporary and cache locations. If renderer output is the
final deliverable, write or promote it into the workflow workspace. Promote any
scratch output needed for review or resume before its temporary or cache location
expires. This guidance reduces accidental mixing; an authored prompt that
explicitly requests another placement remains authoritative.

Workspace `.workflow-runs.md` contains backlinks. It is a reserved runtime file: a user file with this name is never overwritten, and the launch explicitly rejects. The group README and backlink are replaced with complete durable content through temp+rename and parent-directory sync. An incomplete runtime-owned README is restored from root metadata; an incomplete backlink returns an explicit recovery error so earlier links are not lost. The shared pages contain permanent links, not the “latest status”; see each execution's current state in its `runtime/result.json` and journal. They are written only by the root under the workspace lease, never after it is released.

Old flat runs remain readable and resumable in place. Each runId is resolved through the shared confined lookup; symlink paths and ambiguous IDs are never selected arbitrarily. A safely located resume adds `attempts/<newRunId>/`; an early unsafe or missing source stores a separate rejected receipt. Runs and workspaces are never migrated or deleted automatically.

`runtime/journal.ndjson` is the chronological event authority. New `runtime/result.json` envelopes do not repeat the full journal. They retain only typed bounded finalization errors that must survive an independent best-effort journal write failure. Older envelopes with an embedded journal remain readable.

`.locus-pi/workflow-state/v1/<hash>/` is active runtime state. It holds the workspace lease namespace and saved-child checkpoints. A workflow with no saved children can leave this directory empty after its temporary lock is released; that empty directory is not legacy run evidence.

Use `/workflows result` for complete prose output and `/workflows status` for stages, evidence, replay markers, and actionable handoffs.

Root results and direct `parallel()`/`pipeline()` returns share one terminal-outcome rule. A JSON object is semantic failure when `ok === false`, `partial === true`, or `status` is `"failed"`, `"blocked"`, or `"cancelled"`. The original result remains in evidence, but the durable workflow disposition is `failed`. Other JSON-safe shapes retain legacy success semantics.

## Resume and replay

`--resume <runId>` reuses eligible recorded agent answers. Editing the workflow source between the two runs no longer ends the resume: the recorded answers stay in play and each call is matched by its recorded node name and its exact request. Replayed answers are marked as recorded evidence, not fresh work. A replayed call returns the recorded answer text and nothing else: it does not repeat child side effects, re-create files, or re-read the project. Reuse is therefore correct only while the workspace and the project tree still contain what the replayed calls wrote; against a cleaned workspace a recorded "checks passed" answer is a false green. Repeat the same `--run-name <name>` when resuming a named non-task workflow. Supplying a different workspace fails closed.

A run awaiting operator input must be continued explicitly. Automation must not synthesize an operator answer.

## Recovery

A workflow that stopped at some node is repaired in the same file and continued from that node. Recovery starts from the run id and ends in a new terminal result or a named refusal. Read `/workflows status <runId>` for stages, replay markers, and the failure diagnostic, `/workflows result <runId>` for the exact prose, and the run's own `runtime/result.json`, `runtime/journal.ndjson`, and `runtime/replay.ndjson` for the same content as files. There are two outcomes: `continue` and `refuse`.

**Continue the stopped run.** Fix the wrong node in the same `.workflow.mjs`, then run `/workflows run <target> --resume <runId>`. The nodes that already completed return their recorded answers and do not execute again; the repaired node and the tail after it run fresh. Each recorded agent line carries a `node` name — `[phase, label, occurrence]` — so `runtime/replay.ndjson` answers "which nodes finished" on its own, and the `replay` envelope of the new run's `result.json` reports `divergedAtNode`, the node where continuation became fresh.

The precondition is binding: the workspace and project tree must still hold the files the replayed calls produced, because replay reuses answer text only. A resume runs in the source run's workspace. When that workspace was chosen explicitly, repeat it with `--run-name <name>` (or `outputDir` on the tool path); omitting it or passing another path fails closed rather than starting somewhere new.

Reuse ends at the first changed, failed, unnamed or otherwise ineligible recorded
call. That call and the suffix execute fresh; accepted answers before it remain
replayed. The [replay contract](workflows/replay.md#continuing-a-repaired-workflow) owns
the refusal reasons and their effects. See [recovery and continuation](workflows/recovery-and-continuation.md)
for a missing terminal result or an operator handoff.

**A run recorded before this release usually re-runs from its first agent call, whatever kind of call it is.** `timeoutMs`, `toolCalls` and `turns` belong to every call's canonical request, and the package defaults that used to fill them (`86400000` / `1000` / `1000`) are gone, so those axes now read `null` and the recorded key no longer matches. Plain text is affected exactly like a shaped call: the first call reports `key-mismatch` and the whole run is fresh. A run that declared each of those budgets explicitly inherited nothing, so its keys are unchanged and it replays as before. See [replay across this release boundary](workflows/recovery-and-continuation.md#replay-across-this-release-boundary).

A `fusion()` group standing after the point where continuation went fresh runs as an ordinary fresh panel — every leg fresh, with its model preflight. What is refused is a MIXED panel, some legs recorded and some fresh, which ends the run with `fusion resume cannot mix recorded and fresh agent calls`: the group's transactional rule is kept at the cost of a terminal error. A panel served entirely from the record costs nothing against `totalAgents`, because it starts no child.

Known limitations: a stopped run recorded before node names existed carries none, so a repair makes every call miss with `unnamed-node` and the continuation is a fresh run. Checkpoint identity covers entry and child script bytes, not a neighboring `.prompt.md`, and repairing a parent invalidates the checkpoints of even its untouched children, so hierarchical workflows do not continue in place.

`/workflows continue <runId>` is not part of recovery. It answers a handoff a run declared itself and stopped at, and it needs a real operator answer.

Named refusal is a valid outcome. Refuse when the run directory or `result.json` is unreadable, when the source journal says `replay: not recorded`, when the script lives outside the project, when the original input cannot be reproduced, when the run ended `awaiting_operator`, when the workspace or project tree changed under the recorded answers, or when a resume cannot use the source workspace.

Live `workflow_ask` answers are stored as indexed run artifacts with digest readback. If that evidence cannot be persisted, the child call fails with `ask-evidence-persistence`; the answer is not returned as a successful tool result and the same invocation does not show the question again.

Cleanup is explicit. Remove retained Git worktrees through Git before deleting a run. Remove a workspace checkpoint namespace only after the workspace is retired. Migration never deletes legacy workspaces or home plan files automatically.

## Fusion

Fusion is disabled by default. `/fusion configure` or `/fusion set` defines a project-local homogeneous roster and judge; `/fusion enable` exposes the model-callable tool, and `/fusion disable` removes it again. Fusion forwards only the explicit question/context supplied to the call, not ambient session history.

## Trust and approvals

Workflow modules are trusted JavaScript executed in the Pi Node.js host. They may read or write files, start subprocesses, use the network, call models, or import modules according to host capabilities. Review every project or user workflow before execution.

Pi approvals remain the enforcement owner. Source hashes, confined output paths, journals, and audit events improve evidence and consent but do not provide OS-level isolation.

## Authoring

- [Readable workflow authoring contract](locus-pi-workflows.md)
- [Advanced runtime and DSL reference](workflows/index.md)
- [Packaged examples](../extensions/workflows/examples/README.md)
- [Workflow-create skill](../skills/locus-pi-workflow-create/SKILL.md)
- [Workflow-run skill](../skills/locus-pi-workflow-run/SKILL.md)
- [External Locus Pi: interactive session from Codex or Claude Code](../skills/external-locus-pi/SKILL.md)
- [Skill host matrix and installation](../skills/README.md)

Read the [source boundary](../skills/locus-pi-workflow-create/references/source-boundary.md) before building source. The [authoring history](../skills/locus-pi-workflow-create/references/authoring-decisions.md) explains why repeated process instructions were removed.

Inside Pi, validate a standard-profile workflow source with the
`workflow_check_source` tool:

```json
{ "path": "path/to/example.workflow.mjs" }
```

Use `"mode": "orchestration-only"` for new source produced by
`locus-pi-workflow-create`. The default compatibility mode remains available
for existing reviewed workflows that use the broader standard DSL surface.

From a `locus-pi` source checkout, run the same strict validator without
starting a Pi child session:

```bash
npm run check:workflow-source -- --mode orchestration-only <workflow-path>
```

`<workflow-path>` may be relative to the command working directory or absolute.
The command reads source text and does not import or run the workflow.

The tool prints compiler-style diagnostics as
`path:line:column [CODE] message` and returns structured one-based spans in
`details.diagnostics`. Errors fail the check. Warning-only results remain
successful; current warnings identify unused or out-of-order non-empty
`meta.phases` declarations. A non-empty declaration must cover every unique
literal `phase("...")` call exactly once and in planned first-source order;
duplicate or case-equivalent declarations fail the check.
