ποΈ Architecture β the full spec-driven delivery flow#
This page is the single source of truth for how the tool, the domain pack and an implementation project fit together, and where in that picture the harness, opencode/Claude, and the human reviewer live.
Companion docs:
tutorial.mdis the step-by-step walkthrough;bootstrap-prompt.mdis the hand-off prompt for Phase 1;harness.md,specops.mdanddomain-pack-format.mddrill into individual subsystems.
1. The three repos#
ββββββββββββββββββββββββββββββββββββ
β create-spec-driven-app (TOOL) β
β npm package Β· CLI binary β
β commands: init, specops, β
β pack, plan, done, validate, β
β harness β
βββββββββββββββ¬βββββββββββββββββββββ
β uses
βββββββββββββββββββββββββββββββββββ β ββββββββββββββββββββββββββββββββββββββ
β DOMAIN PACK REPO β β β IMPLEMENTATION PROJECT REPO β
β parking-management-specops/ β β β smart-parking-spring/ β
β β β β β
β pack.yaml β β β spec.md ββ rendered β
β templates/ β β β AI_RULES.md ββ rendered β
β AI_RULES.md.tpl β β β features/**/*.feature ββ rendered β
β spec.md.tpl β csda β csda β docs/specs/ β
β features/**/*.feature.tpl βββpack lintβββΊβββspecops add β pom.xml | build.gradle | β¦ β
β β --graph β --pack-repoβ src/main, src/test β
β git tags: v0.1.0, v0.2.0 β¦ β --strict β --version β .specops.lock ββ points back β
β β pack infer β --var β¦ β .specops/baseline/ (merge base) β
β AUTHORED by domain experts β β β .specops/harness-prompts/ (audit) β
β Stack-agnostic β β csda β harness.config.yaml β
β β β specops syncβ β
β β β --pack-vers β IMPLEMENTED by humans + agents β
β β β β ONE per stack (Spring / Quarkus / β
βββββββββββββββββββββββββββββββββββ β β Micronaut / Node / Quarkus / β¦) β
β β β
β β Iteration loop: β
β β ββββββββββββββββββββββββββββββββ β
β β β csda harness run --req REQ β β
β β β β β
β β β ββββββββββββββββββββββββββ β β
β β β β git worktree β β β
β β β β harness/REQ-NNN β β β
β β β β β β β
β β β β prompt = prefix + β β β
β β β β facts + Gherkin + β β β
β β β β AI_RULES + DoD β β β
β β β β β β β
β β β β βΌ β β β
β β β β opencode / claude / β β β
β β β β aider / stub agent β β β
β β β β β writes code β β β
β β β β βΌ β β β
β β β β src/, test/ β β β
β β β β β β β β
β β β β βΌ GATE β β β
β β β β validate --strict-tdd β β β
β β β β + test_cmd β β β
β β β β β β β β
β β β β green: done + commit β β β
β β β β red: retry w/ fail β β β
β β β ββββββββββββββββββββββββββ β β
β β ββββββββββββββββββββββββββββββββ β
β β β
β β Human reviews harness/REQ-* β
β β branches and merges to main. β
β ββββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββ
β Companion tools β
β - vscode-spec-driven extension β
β Β· pack.yaml schema squiggliesβ
β Β· dangling-ref autocomplete β
β Β· "Show Pack Graph" webview β
β - mcp-spec-driven server β
β Β· plan / done / lint_pack β
β as MCP tools for Claude β
β Desktop, Cursor, opencode β
ββββββββββββββββββββββββββββββββββββThree lifecycles, three responsibilities.
| Piece | Changes when⦠| Owner |
|---|---|---|
| Tool | the CLI gains features / fixes | tool maintainers |
| Pack | the domain evolves (new requirements, scenarios, events) | domain experts |
| Implementation | features are built / bugs are fixed | the product team |
2. Per-project chronology#
Read top-to-bottom β every step is a real command somebody runs.
Day 1 (human) ββββΊ csda init (scaffold from project.yaml)
β
Day 1 (human) ββββΊ csda specops add (pulls pack, renders specs)
β
Day 1 (human + AI) ββββΊ Bootstrap prompt β opencode / Claude
β PHASE 1: build files, BDD wired, hex skeleton,
β first bounded context green
β
ββββΊ git commit "phase 1 complete"
β
Day N (AI via harness) ββββΊ csda harness prompt REQ-001 (preview)
ββββΊ csda harness run --req REQ-001
β ββ worktree, prompt(prefix+facts+Gherkin+AI_RULES),
β agent writes code, gate, done, commit on
β harness/REQ-001
β
ββββΊ human reviews + merges harness/REQ-001
β
ββββΊ csda harness run --req REQ-002
β β¦
β
Pack v0.2.0 ships ββββΊ csda specops diff --pack-version v0.2.0
ββββΊ csda specops sync --pack-version v0.2.0
β β¦
ββββΊ continuesThe line Bootstrap prompt β opencode / Claude is the only
freeform-AI step. Everything that follows is the harness driving the same
loop, deterministically, one requirement at a time.
3. Responsibility layers#
| Layer | Who | Cadence | Output |
|---|---|---|---|
| Pack authoring | domain expert + tech lead | once, then per new business feature | pack.yaml versioned, git-tagged |
| Project bootstrap (Phase 1) | human + AI via the bootstrap prompt | once per (project, stack) | build manifest + hex skeleton + first context green |
| Per-REQ implementation (Phase 2..N) | AI agent via the harness | iterative, one REQ per worktree | branch harness/REQ-NNN with code + test |
| Review & merge | human | iterative | main advances with verified code |
| Pack version bumps | pack maintainer publishes; each project syncs | when a new tag ships | specops sync three-way-merges the delta |
The harness never operates on a pack repo, only on implementation projects. Pack authoring is a separate flow (
pack init/pack lint/pack lint --graph/pack infer) run inside the pack repo.
4. What the harness prompt actually contains#
Every per-REQ prompt the harness hands the agent is assembled in this
order β top to bottom β by scripts/harness/prompt.ts:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β promptPrefix (from harness.config.yaml: prompt_prefix or β
β prompt_prefix_file β your universal Role / β
β Active Project Boundary / Execution Policy)β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β --- β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β # Implement REQ-NNN β
β ## Requirement facts β
β feature_file Β· test_artifact Β· technical_artifact Β· status β¦ β
β ## Suggested approach (hint from `csda plan`) β
β ## Gherkin scenario (inlined from features/β¦feature) β
β ## Project rules (AI_RULES.md inlined verbatim) β
β ## Definition of done β
β - write the test first β
β - then the production code β
β - DO NOT modify spec.md / AI_RULES.md / features/**.feature β
β - DO NOT edit docs/specs/traceability.md (harness handles it) β
β - validate --strict-tdd + the project test command must pass β
β ## Previous attempt failed (only on retries, with the gate log) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββcsda harness prompt REQ-NNN prints exactly that text to stdout β no git,
no agent invocation, no gate. Use it to inspect what an agent receives.
Every prompt the harness actually sends during harness run is also
mirrored to .specops/harness-prompts/REQ-NNN-<timestamp>-attempt-N.md
for audit.
5. Multi-stack: one pack, many implementations#
The pack/implementation split lets you ship the same domain spec in multiple stacks without duplicating requirements or scenarios:
parking-management-specops@v0.1.0 βββ one spec, stack-agnostic
ββββΊ smart-parking-spring/ (STACK=Spring Boot, JUnit+Cucumber)
ββββΊ smart-parking-quarkus/ (STACK=Quarkus, JUnit+Cucumber)
ββββΊ smart-parking-micronaut/ (STACK=Micronaut, JUnit+Cucumber)Each implementation is its own repo, with its own csda init (different
STACK), its own csda specops add (same pack + version + domain vars),
its own bootstrap prompt run, and its own harness loop. The pack's
spec.md, features/** and traceability matrix are identical across
all three; AI_RULES.md differs because its {{STACK}} substitution does.
For this to work cleanly, packs must be stack-neutral. No Java/Spring
code in spec.md.tpl or features/**.feature.tpl. Only the
AI_RULES.md.tpl is allowed to reference {{STACK}} / {{TESTING}}.
pack lint --strict catches scenario-quality issues that would otherwise
manifest as stack-specific debt later.
Useful patterns:
- Reference implementations across frameworks for tech-lead comparisons.
- Migration POCs (run two stacks side by side, retire one).
- Educational material ("same problem, three stacks").
6. Boundaries the architecture enforces#
- The pack is read-only from the project's perspective.
specops add/synconly ever read the pack. The pack's git history is the audit trail for domain decisions. - The implementation project is the only thing the harness writes to.
Worktrees live under
$TMPDIR, but branches and commits land in the project's own git repo. spec.md,AI_RULES.md,features/**are the agent's source of truth β explicitly immutable for the agent. The harness prompt says so;specops syncis the only legitimate path to change them (and even then, three-way merges preserve local edits).docs/specs/traceability.mdis the matrix;csda doneowns it. Agents must not hand-edit it..specops.lockrecords which pack and version the project consumes and the--varvalues used. Commit it..specops/baseline/is the merge base forspecops sync. Commit it..specops/harness-prompts/is the audit log for what was sent to the agent on each attempt. Commit or gitignore β your call.