Symphony's default workflow now has four active agent lanes:
Todo -> In Progress -> Verify -> Document -> Done
^ | |
| | +-> critical/manual intervention -> Human Review
+--------------+
Verify or Document findings rewind here
WORKFLOW.md remains the orchestration manifest. Worker instructions live in
docs/symphony-prompts/, and the orchestrator assembles the shared base prompt
plus the current state's stage prompt for each fresh turn.
| State | Owner of this turn | Required output |
|---|---|---|
| Todo | triage/router | ## Triage, then route actionable work to In Progress or explain Blocked |
| In Progress | implementer | ## Plan, ## Acceptance Tests, ## Done Signals, ## Implementation, ## Self-Critique, plus goal/before/after proof notes under docs/<ID>/work/ |
| Verify | reviewer + QA + merge preflight | ## Security Audit, clean ## Review or ## Review Findings, ## QA Evidence, ## AC Scorecard, ## Merge Status, plus not-covered and rerun guidance |
| Document | distiller | docs/llm-wiki/ updates, ## Wiki Updates, ## As-Is -> To-Be Report; may rewind real defects to In Progress |
| Human Review | operator | manual intervention or explicit review before Done |
| Done | reporter | ## As-Is -> To-Be Report with goal, evidence, residual risk, and how to re-run |
| Blocked | agent or operator | ## Blocker describing the missing input or failed gate |
A request may enter the board from the web chat. The chat agent never files
the request itself: it proposes an intent card (Problem, Evidence, Success
criteria, Out of scope, Constraints, Open questions, Track), the operator
approves it once, and the server files the request ticket and records
.sdlc/work/<slug>/intent.md. On this default board the ticket lands in
Todo; on the deep preset it lands in Intake, whose prompt consumes the
intent instead of re-asking (docs/symphony-prompts/file/deep/intake.md).
The ticket description carries the whole intent, so every lane treats it as
the scope of record and never reopens the ask with the operator; Human Review stays reserved for a real blocker.
The old eight-stage flow spread one delivery story across too many agent turns. The new shape keeps the important gates while reducing context loss:
- Todo only decides whether a ticket is actionable.
- In Progress owns planning and implementation together, so the worker does not hand its own plan to a different fresh context before writing code.
- Verify keeps review, execution, acceptance scorecard, and merge preflight in one compulsory lane; the merge itself happens once, at Done.
- Document remains a separate write-back lane because durable project knowledge is different from verification evidence.
In Progress must leave enough evidence for a fresh verifier to audit the work:
## Plan- user goal, before state, after target, rejected alternatives, and ordered implementation steps.## Acceptance Tests- one observable proof per acceptance criterion.## Done Signals- exact state the verifier should see, including anything stillNot proven.## Implementation- changed files, behavior, and why this approach was chosen.## Self-Critique- known limits, not-covered areas, and suspicious paths for Verify.docs/<ID>/work/- at least one durable work artefact when a docs root is available.
If Verify or Document rewinds a ticket to In Progress, the worker reads the most
recent ## Review Findings, ## QA Failure, or ## Document Defect first and
fixes that scope before opening new work.
Verify is never skipped. For trivial non-runtime changes the QA section may be short, but the lane still records what was checked and why runtime coverage was not needed.
Verify must produce:
## Security Audit- pass/fail rows for auth, input validation, data exposure, destructive actions, and secrets.## Reviewfor a clean diff, or## Review Findingswith severity and cited paths for blocking issues.## QA Evidence- commands, exit codes, and evidence paths.## QA Evidencealso names what worked, what failed, what is not covered, and how to re-run the proof.## AC Scorecard- acceptance criteria with signal, source, pass/fail status, and evidence path.## Merge Status- target branch, feature branch, and thegit merge-tree --write-treepreflight result.
There is exactly one merge, and the orchestrator makes it:
Verify proves, Document documents, the orchestrator merges. Verify runs a
git merge-tree --write-treepreflight and records the result; when the ticket reachesDone,agent.auto_merge_on_donecreates the single--no-ffmerge commit on the target branch. With the defaultagent.auto_merge_push_target: true, it then pushes and verifies the target's configured upstream. Set that option tofalsefor a local-only run: all local safety checks and the--no-ffmerge remain active, while neithergit pushnorgit ls-remoteis called (including no-op retries). Normal ticket final-history snapshotting follows the same setting, so a local-only ticket cannot publish its feature branch before the target merge; release-evidence snapshots remain local audit records.
This ordering is also the wiki write-back rule. The wiki is a host-repo,
tracked path (<workflow-dir>/docs/llm-wiki/, configurable via wiki.root).
Workers write it inside their worktree at the same relative path; the
per-turn wip commit carries it and the Done merge delivers it. The wiki is
never symlinked into the workspace and never written directly to the host
tree. If you do symlink it (to share it across tickets), add that path to
agent.auto_merge_capture_untracked so the merge commit still carries it.
A Verify lane that hand-merged produced two merge commits per ticket and landed code on the target branch before Document ran — which is why wiki write-back used to arrive inconsistently.
Any CRITICAL/HIGH/MEDIUM review issue, failed command, failed AC, or failed
security row rewinds to In Progress. Verify should not hide failures by
retrying until the output looks clean.
Document compares the ticket's plan, implementation, verification evidence, and
merge status against what future tickets need to know. It writes durable notes
to ${LLM_WIKI_PATH:-./docs/llm-wiki}/, appends ## Wiki Updates, appends
## As-Is -> To-Be Report, and moves normal successful work to Done.
The operator can skip an idle Document ticket through the TUI or web app. That
action appends ## Document Skipped and moves the card to Human Review without
spawning an agent. Agents must not simulate this skip themselves, and should
use Human Review only when a recorded critical/manual intervention remains.
The example workflows use a stage-specific prompt manifest:
prompts:
base: ./docs/symphony-prompts/file/base.md
stages:
Todo: ./docs/symphony-prompts/file/stages/todo.md
"In Progress": ./docs/symphony-prompts/file/stages/in-progress.md
Verify: ./docs/symphony-prompts/file/stages/verify.md
Document: ./docs/symphony-prompts/file/stages/document.md
Done: ./docs/symphony-prompts/file/stages/done.mdUse docs/symphony-prompts/file/ for the Markdown-file Kanban tracker and
docs/symphony-prompts/linear/ for Linear. Customize those files directly
when a board needs different agent behavior.
The supported production active states are:
tracker:
active_states: [Todo, "In Progress", Verify, Document]
terminal_states: ["Human Review", Done, Blocked, Archive]The orchestrator dispatches a worker for any ticket whose state is active.
Terminal states stop dispatch. Human Review is terminal because a human must
resolve or confirm an explicit intervention before Done.
The web board opens on active agent lanes. Human Review, Done, Blocked,
and Archive stay visible in the compact Review and parked group until
you switch to All.
max_concurrent_agents_by_state can throttle expensive lanes, for example one
Verify worker at a time when browser QA or integration tests contend for shared
ports.
- Copy
WORKFLOW.file.example.md(file tracker) orWORKFLOW.example.md(Linear) toWORKFLOW.mdand customize. - Confirm
tracker.active_statescontains exactly the active lanes you want. For the default production flow, keepTodo,In Progress,Verify, andDocument. - Confirm the
prompts:block points at the matching prompt flavor. - Confirm hooks land each agent in a workspace where tests, APIs, and browser checks can actually run.
- Decide whether
docs/llm-wiki/lives in this repo or a sibling docs repo. - Run
symphony doctor ./WORKFLOW.mdbefore launch.
Every durable artefact for a ticket should live under:
docs/<TICKET-ID>/
reproduce/ bug reproductions, when relevant
work/ implementation notes, generated docs, screenshots, fixtures
verify/ review notes, diff evidence, merge proof
qa/ command output, traces, HAR files, screenshots
Document is the only default lane that writes outside the ticket root; it updates
${LLM_WIKI_PATH:-./docs/llm-wiki}/.
A complete worked example lives at docs/PIPELINE-DEMO.md.
It includes every section a finished pipeline ticket should carry:
## Plan, ## Acceptance Tests, ## Done Signals, ## Implementation,
## Self-Critique, ## Security Audit, ## Review, ## QA Evidence,
## AC Scorecard, ## Merge Status, ## Wiki Updates, and
## As-Is -> To-Be Report.
Evidence-first stage rules adapt ideas from cskwork/backend-dev-skills (MIT).