The SDD pipeline
This page is the team member's guide to the spectacles spec-driven development (SDD) pipeline: how a plain GitHub issue becomes a merged implementation, and what a human does at each step.
The pipeline runs as a set of agentic GitHub Actions workflows. You operate it entirely through GitHub primitives you already use: opening an issue, applying a label, writing a comment, and reviewing and merging a pull request. There is no new tool to install and no separate task board.
The six agents
| Agent | Turns | Into |
|---|---|---|
sdd-spec |
a tracking issue | full path: a structured spec, delivered as a PR. Fast path: a stub spec PR plus a single execution-plan comment on the tracking issue (ADR 0012) |
sdd-triage |
a merged spec | an architecture record, then a task graph of sub-issues |
sdd-dispatch |
/dispatch on a tracking issue, or a task sub-issue closing |
fan-out of ready tasks to sdd-execute variants, bounded by max-parallel (noop on fast-path issues) |
sdd-execute |
a ready task sub-issue, or a fast-path tracking issue on /approve |
an implementation PR with proof artifacts |
sdd-validate |
a phase-boundary artifact | advisory findings posted as a comment |
sdd-review |
an implementation PR | code-review comments on correctness, security, and spec compliance |
Lifecycle labels on the tracking issue: sdd:spec, sdd:fastpath,
sdd:fastpath-review, sdd:triage, sdd:ready, sdd:in-progress,
sdd:review, sdd:done. The sdd:fastpath and sdd:fastpath-review
labels mark the fast-path states (ADR 0012); a fast-path tracking issue
never carries sdd:triage, sdd:ready, or sdd:review.
sdd-triage runs three phases under one workflow: architecture design, a
plan-comment proposal on the tracking issue, and — on /approve — the
creation of the Unit and task sub-issue tree (ADR 0010). Structure is only
created after /approve: until then the plan is a proposal, not a tree.
sdd-dispatch is the cascade orchestrator. On /dispatch it computes the
ready set from the dependency graph and fans out to sdd-execute variants
in a bounded matrix; it then re-fires on every task close until the tree
is drained. Execution is fully event-driven (ADR 0011): there is no daily
cron.
sdd-spec has two modes: full-path (the default) and fast-path. On
intake it classifies the work against six heuristics and, when all pass,
posts a proposal asking the human to comment /fastpath to confirm or
/spec to keep the full flow (ADR 0012). On /fastpath it produces a
compressed stub spec PR plus a single execution-plan comment on the
tracking issue; the human merges the stub and comments /approve to
dispatch the implementation directly. Two extra lifecycle labels —
sdd:fastpath and sdd:fastpath-review — mark the fast-path states.
/dispatch is a noop on a fast-path tracking issue (the fan-out is
unused).
End-to-end flow
The steps below trace one feature from idea to close. The lifecycle label on the tracking issue, listed in the right-hand column, tells you where the feature is at any moment.
The diagram traces that path end to end. Amber-bordered nodes are the steps a
human takes; blue-bordered nodes are automated agent runs; the red-bordered
node is a needs-human hand-off, which any agent can raise and only a human
clears. Dotted edges run
backward: a /revise comment sends a pull request back to its agent for
changes, and clearing needs-human resumes a stalled hand-off.
flowchart TD
classDef human stroke:#e0a82e,stroke-width:4px;
classDef agent stroke:#4493f8,stroke-width:4px;
classDef handoff stroke:#f85149,stroke-width:4px;
open([Human: open a feature or bug issue<br/>the template applies sdd:spec]):::human
subgraph s_spec [Tracking issue state: sdd:spec]
a_classify[sdd-spec classifies the issue<br/>full path: draft a spec<br/>fast path: post a /fastpath proposal]:::agent
a_spec[sdd-spec drafts the spec<br/>opens a spec sub-issue and a spec PR]:::agent
h_spec([Human: review and merge the spec PR<br/>the spec sub-issue closes on merge]):::human
end
subgraph s_fast [Fast path: sdd:fastpath then sdd:fastpath-review]
h_fast([Human: comment /fastpath]):::human
a_fast[sdd-spec: stub spec PR + execution plan comment]:::agent
h_fast_merge([Human: review and merge the stub spec PR]):::human
h_approve_fast([Human: comment /approve]):::human
end
subgraph s_triage [Tracking issue state: sdd:triage]
h_triage([Human: comment /triage]):::human
a_arch[sdd-triage phase A: maps the code<br/>opens an architecture sub-issue and PR]:::agent
h_arch([Human: review and merge the architecture PR<br/>the architecture sub-issue closes on merge]):::human
a_units[sdd-triage phase B: posts the proposed plan<br/>as one comment on the tracking issue]:::agent
h_approve([Human: comment /approve]):::human
end
subgraph s_ready [Tracking issue state: sdd:ready]
a_tasks[sdd-triage phase C: creates Unit sub-issues and<br/>task sub-issues; labels unblocked tasks sdd:ready]:::agent
end
subgraph s_dispatch [Tracking issue state: sdd:ready, awaiting /dispatch]
h_dispatch([Human: comment /dispatch on the tracking issue]):::human
a_dispatch[sdd-dispatch computes the ready set and fans out to<br/>sdd-execute variants, bounded by max-parallel<br/>re-fires on every task close until the tree drains]:::agent
end
subgraph s_progress [Tracking issue state: sdd:in-progress, sdd:dispatched]
a_exec[sdd-execute implements a ready task, opens an<br/>implementation PR with proof artifacts<br/>runs on workflow_dispatch from sdd-dispatch, or on /execute]:::agent
end
subgraph s_review [Tracking issue state: sdd:review]
a_check[sdd-validate posts advisory findings<br/>sdd-review posts code-review comments]:::agent
h_merge([Human: review and merge the implementation PR<br/>the task sub-issue closes on merge]):::human
end
subgraph s_done [Tracking issue state: sdd:done]
a_done[Every task closes its Unit sub-issue; once all<br/>Units close, sdd-execute sets sdd:done + needs-human]:::agent
h_close([Human: final review, then close the tracking issue]):::human
end
open --> a_classify
a_classify -->|full path| a_spec --> h_spec --> h_triage --> a_arch --> h_arch
a_classify -->|fast-path proposal| h_fast
h_fast --> a_fast --> h_fast_merge --> h_approve_fast --> a_exec
h_arch --> a_units --> h_approve --> a_tasks --> h_dispatch
h_dispatch --> a_dispatch --> a_exec --> a_check --> h_merge
h_merge -->|tasks remain, full path| a_dispatch
h_merge -->|last task done, or fast path| a_done --> h_close
hand[/"Any agent, on low confidence or a blocker:<br/>posts questions, applies needs-human, stops"/]:::handoff
ans([Human: answer the questions, remove needs-human<br/>the agent re-runs and resumes]):::human
a_classify -.-> hand
a_spec -.-> hand
a_fast -.-> hand
a_arch -.-> hand
a_tasks -.-> hand
a_exec -.-> hand
hand --> ans
h_spec -.->|changes needed? comment /revise| a_spec
h_arch -.->|changes needed? comment /revise| a_arch
h_merge -.->|changes needed? /revise or a review comment| a_exec
| Step | Who acts | What happens | Lifecycle label |
|---|---|---|---|
| 1. Open the issue | you | Open an issue from the feature or bug template. The template applies sdd:spec, which triggers sdd-spec. |
sdd:spec |
| 2. Review the spec PR | you | sdd-spec drafts a spec and opens it as a PR. Read it, comment, and merge when it is right. Merging advances the pipeline. |
sdd:spec |
| 3. Start triage | you | Comment /triage on the tracking issue. sdd-triage phase A maps the code and opens an architecture PR. |
sdd:triage |
| 4. Review the architecture PR | you | Read the architecture record, comment, and merge it. Merging triggers phase B. | sdd:triage |
| 5. Approve the plan | you | sdd-triage posts the proposed plan as a comment on the tracking issue. Comment /approve to materialize it, or /revise <note> to amend. |
sdd:triage |
| 6. Tree is created | sdd-triage |
Phase C creates Unit sub-issues and sub-task issues together, each with its scope, proof artifacts, and a model:* tier label. |
sdd:ready |
| 6a. Dispatch the plan | you | Comment /dispatch on the tracking issue. sdd-dispatch arms the cascade: it computes the ready set from the dependency graph, fans out sdd-execute runs in a bounded matrix (SDD_DISPATCH_MAX_PARALLEL, default 5), and re-fires on every task close until the tree is drained. |
sdd:in-progress |
| 7. Tasks are implemented | sdd-execute |
Each dispatched task: sdd-execute picks it up via workflow_dispatch from the cascade and opens an implementation PR. A human may also comment /execute on a task to run it immediately, outside the cascade. |
sdd:in-progress |
| 8. Validation runs | sdd-validate |
At each phase boundary, sdd-validate posts advisory findings as a comment. A clean implementation pass moves the issue to sdd:review. |
sdd:review |
| 9. Code review runs | sdd-review |
sdd-review posts review comments on the implementation PR. You read them and decide. |
sdd:review |
| 10. Merge and close | you | Merge the implementation PRs. When every task sub-issue is closed, the issue moves to sdd:done and needs-human is applied for your final review and close. |
sdd:done |
Structure is only created after /approve. Until then the plan lives as a
single comment on the tracking issue, so a /revise <note> is cheap:
sdd-triage re-posts the plan with the note applied and there is no tree
to garbage-collect. ADR 0010 records the gate semantics.
Fast-path steps
The fast-path flow (ADR 0012) compresses spec, architecture, and plan
into one agent run for single-session work. The steps below run in
place of the full table above when the tracking issue's lifecycle
forks off to sdd:fastpath after /fastpath.
| Step | Who acts | What happens | Lifecycle label |
|---|---|---|---|
| 1. Open the issue | you | Open from the feature or bug template (same as the full path). |
sdd:spec |
| 2. Classify | sdd-spec |
The agent reads the issue, checks six fast-path heuristics, and posts one proposal comment asking for /fastpath (small change) or /spec (full flow). Silence means the full flow runs. |
sdd:spec |
| 3. Confirm fast-path | you | Comment /fastpath on the tracking issue. The wrapper moves the lifecycle to sdd:fastpath and re-invokes sdd-spec. |
sdd:fastpath |
| 4. Author the stub | sdd-spec |
One run produces a stub spec PR (problem statement, R-IDs, proof artifacts, one Unit) and an execution plan comment on the tracking issue. | sdd:fastpath-review |
| 5. Merge the stub spec PR | you | Review and merge. The spec sub-issue closes via the existing Closes keyword. |
sdd:fastpath |
| 6. Approve and dispatch | you | Comment /approve on the tracking issue. The sdd-spec wrapper finds the plan comment, parses the model:* tier, and dispatches one sdd-execute-{tier} against the plan. No Unit or task sub-issues are created. |
sdd:in-progress |
| 7. Implementation runs | sdd-execute |
The variant opens one implementation PR with proof artifacts. sdd-validate and sdd-review run as on the full path; the absence of an architecture record and a sub-task tree is not a finding. |
sdd:in-progress |
| 8. Merge and close | you | Merge the implementation PR. sdd-execute moves the tracking issue to sdd:done and applies needs-human for your final close. |
sdd:done |
/dispatch on a fast-path tracking issue is a noop with a one-comment
explanation pointing to /approve. A /revise <note> between the
execution plan comment and /approve edits the plan in place (a new
plan comment is posted; the prior one is hidden as OUTDATED).
If during execution sdd-execute finds the work is materially bigger
than fast-path assumed, it posts one comment naming the mismatch and
applies needs-human. Your recourse is the standard needs-human
flow: answer in a comment and either tighten the scope (the executor
resumes) or comment /spec to bounce the issue into the full
pipeline (sdd:fastpath becomes sdd:spec; the stub is the
starting point of a fuller spec).
What a human does
Across the whole pipeline a human takes only four kinds of action:
- Open an issue from the
featureorbugtemplate to start a feature. When you already have a Claude plan document, open from the Specification (from Claude plan) template (spec.md) and paste the plan into the body instead. That template applies aplan:providedmarker, which puts the pipeline into translation mode:sdd-spectranslates the plan into a structured spec rather than authoring one from a slim description, andsdd-triagetranslates the plan's architecture section into the architecture record. The marker clears once the architecture PR opens (or, on the fast path, the stub spec PR). - Comment a command to steer:
/spec,/fastpath,/triage,/approve,/dispatch,/revise, or/execute. See the command table inshared/sdd-interaction.md. - Review and merge PRs. Merging a PR is the approval signal that advances the pipeline. No agent merges a PR; merge authority stays with humans and consumer CI.
- Answer
needs-human. When an agent cannot safely proceed, it applies theneeds-humanlabel and posts one comment with the blocker. Answer in a comment and clear the label; the agent re-reads the thread and resumes. See ADR 0001 (decisions/0001-needs-human.mdin the repository root).
Giving feedback on a pull request
Every pull request the pipeline opens can be sent back for changes instead of merged. Feedback never opens a second pull request; the owning agent updates the existing one.
- A spec PR or an architecture PR. Comment
/revise <note>on the pull request. The owning agent —sdd-specorsdd-triage— re-runs with the note as an added instruction and updates the same pull request. Repeat until it is right, then merge. - An implementation PR. Leave an inline review comment on the diff, or
comment
/revise <note>on the pull request.sdd-executepushes follow-up commits to the same branch addressing it. A comment that needs a human decision is escalated throughneeds-humaninstead.
Where state lives
- The spec and the architecture record are committed files, reviewed and merged as PRs and rendered into this docs site.
- Tasks are GitHub sub-issues linked to the tracking issue.
- Lifecycle is a single
sdd:*label on the tracking issue. - Every human decision point is an issue or PR comment.
Validation is advisory by design. sdd-validate posts findings and escalates
blockers through needs-human, but it is never a required status check and
never blocks a merge. Human review plus consumer CI is the only merge gate.
Verification
- Open a test issue from the
featuretemplate and confirm it carries both thekind:featureandsdd:speclabels. - Confirm
templates/.github/labels.ymldefines all eightsdd:*lifecycle labels, thesdd:dispatchedandplan:providedmarkers, and all threemodel:*tier labels. - Confirm
shared/sdd-interaction.mdstates the lifecycle state machine, the command table, and theneeds-humancontract, and referencesdecisions/0001-needs-human.md.