The Scaffold Pipeline

The mental model

Scaffold is a prompt pipeline: a curated, ordered sequence of structured meta-prompts that turn an idea into a fully-specified, build-ready project. Each meta-prompt is a markdown file under content/pipeline/; the CLI assembles one into a full prompt at runtime (injecting upstream artifacts, knowledge entries, and depth instructions) and hands it to Claude Code or another AI tool.

The pipeline divides cleanly into two regimes:

The 16 phases are the single source of truth in code: the PHASES constant (src/types/frontmatter.ts:6) defines every slug, number, and display name. Everything in this guide is anchored to it.

90 meta-prompts, not 90 steps you run. The pipeline directory holds 90 files across 16 phase directories, but most projects run only a fraction. Game, multi-service, and platform-specific steps are disabled unless an overlay turns them on, and many steps are conditional (see Methodology & depth).

The 16 phases at a glance

Phase numbers and display names below are quoted verbatim from the PHASES constant (src/types/frontmatter.ts:6). Phases 0–14 are planning; phase 15 is the stateless build phase.

#slugnamewhat it produces
0visionProduct VisionA strategic vision document — who it's for, what's different, what success looks like
1preProduct DefinitionThe PRD, then user stories with testable acceptance criteria
2foundationProject FoundationTech-stack decisions, coding standards (+ linter configs), TDD strategy, project structure
3environmentDevelopment EnvironmentOne-command dev env, design system (web), git workflow + CI, optional PR review, AI memory
4integrationTesting IntegrationE2E setup — Playwright (web) or Maestro (mobile); auto-skips for backend-only
5modelingDomain ModelingCore entities, relationships, invariants, domain events — a shared vocabulary
6decisionsArchitecture DecisionsAn ADR per significant technology/design decision, with alternatives + rationale
7architectureSystem ArchitectureThe system blueprint — components, data flow, where code lives, extension points
8specificationSpecificationsPer-layer interface specs — DB schema, API contracts, UX spec (each conditional)
9qualityQuality GatesTesting review, test skeletons, evals, operations/deploy plan, security review
10parityPlatform ParityCross-platform gap audit (multi-platform only; auto-skips otherwise)
11consolidationConsolidationCLAUDE.md optimization + workflow-doc consistency audit
12planningPlanningThe implementation plan — stories decomposed into small, dependency-ordered tasks
13validationValidationSeven cross-cutting pre-implementation audits (scope, cycles, traceability, …)
14finalizationFinalizationApply validation fixes, freeze docs, onboarding guide, implementation playbook
15buildBuildStateless execution loops — single/multi-agent, resume, quick-task, new-enhancement

Each step's order is phase-aligned: phase N occupies the N00–N99 band (tech-stack is 220, coding-standards is 230, single-agent-start is 1510). The order field is the primary tiebreaker in the topological sort, so within a phase steps run in order sequence.

#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#000000;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#my-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#my-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:1px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#666;stroke:#666;}#my-svg .marker.cross{stroke:#666;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg p{margin:0;}#my-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#000000;}#my-svg .cluster-label text{fill:#333;}#my-svg .cluster-label span{color:#333;}#my-svg .cluster-label span p{background-color:transparent;}#my-svg .label text,#my-svg span{fill:#000000;color:#000000;}#my-svg .node rect,#my-svg .node circle,#my-svg .node ellipse,#my-svg .node polygon,#my-svg .node path{fill:#eee;stroke:#999;stroke-width:1px;}#my-svg .rough-node .label text,#my-svg .node .label text,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-anchor:middle;}#my-svg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#my-svg .rough-node .label,#my-svg .node .label,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-align:center;}#my-svg .node.clickable{cursor:pointer;}#my-svg .root .anchor path{fill:#666!important;stroke-width:0;stroke:#666;}#my-svg .arrowheadPath{fill:#333333;}#my-svg .edgePath .path{stroke:#666;stroke-width:1px;}#my-svg .flowchart-link{stroke:#666;fill:none;}#my-svg .edgeLabel{background-color:white;text-align:center;}#my-svg .edgeLabel p{background-color:white;}#my-svg .edgeLabel rect{opacity:0.5;background-color:white;fill:white;}#my-svg .labelBkg{background-color:rgba(255, 255, 255, 0.5);}#my-svg .cluster rect{fill:hsl(0, 0%, 98.9215686275%);stroke:#707070;stroke-width:1px;}#my-svg .cluster text{fill:#333;}#my-svg .cluster span{color:#333;}#my-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(-160, 0%, 93.3333333333%);border:1px solid #707070;border-radius:2px;pointer-events:none;z-index:100;}#my-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#000000;}#my-svg rect.text{fill:none;stroke-width:0;}#my-svg .icon-shape,#my-svg .image-shape{background-color:white;text-align:center;}#my-svg .icon-shape p,#my-svg .image-shape p{background-color:white;padding:2px;}#my-svg .icon-shape .label rect,#my-svg .image-shape .label rect{opacity:0.5;background-color:white;fill:white;}#my-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#my-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#my-svg .node .neo-node{stroke:#999;}#my-svg [data-look="neo"].node rect,#my-svg [data-look="neo"].cluster rect,#my-svg [data-look="neo"].node polygon{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node path{stroke:url(#my-svg-gradient);stroke-width:1px;}#my-svg [data-look="neo"].node .outer-path{filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node .neo-line path{stroke:#999;filter:none;}#my-svg [data-look="neo"].node circle{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node circle .state-start{fill:#000000;}#my-svg [data-look="neo"].icon-shape .icon{fill:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].icon-shape .icon-neo path{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}frozen specrun repeatedly0 · vision1 · prePRD + stories2 · foundationtech-stack, standards, tdd,structure3 · environment4 · integratione2e (conditional)5 · modeling6 · decisionsADRs7 · architecture8 · specificationdb / api / ux (conditional)9 · quality10 · parity (conditional)11 · consolidation12 · planningimplementation-plan13 · validation7 audits14 · finalizationplaybook15 · buildstateless loops

The arrows show the phase progression, not the exact step-level dependency graph — a single step usually depends on one upstream step, not its whole phase. See Why a step is blocked for how dependencies actually gate execution.

Methodology & depth

Two orthogonal knobs control how much of the pipeline runs and how thoroughly:

  1. Presetwhich steps are enabled. Three presets ship (content/methodology/): mvp, custom (balanced, depth 3), and deep (the schema default).
  2. Depthhow thorough each enabled step's output is, on a 1–5 scale.

Depth (1–5)

Every depth level dials the same step from a sketch to an exhaustive document. Each step's ## Methodology Scaling section spells out its behavior per level — coding-standards at depth 1 is "core naming conventions, commit format, import ordering, 1–2 pages"; at depth 5 it's "full suite with all sections, custom linter rules, and code review checklist, 15–20 pages."

depthnamewhat you get
1MinimalBare minimum to start building
2LightSlightly more detail; still speed-first
3BalancedRecommended default — good coverage, no excess
4ThoroughComprehensive; review/validation steps add external-model validation (Codex/Gemini) where their Methodology Scaling declares it
5ExhaustiveMaximum detail; multi-model reconciliation on the steps that opt into it; for critical/regulated work

External-model / multi-model dispatch at depth 4–5 is step-specific — it applies to the prompts whose ## Methodology Scaling section declares it (chiefly the review-* / innovate-* / validation steps). For most authoring steps, higher depth just means a more thorough single-model output.

Depth 3 is the inflection point where steps start adding structure, cross-references, and validation beyond the basics. Override depth per run with scaffold run <step> --depth N.

The three presets

Ship fast with minimal ceremony. Only the essential planning steps are enabled: vision, PRD + stories (with reviews), tech-stack, coding-standards, tdd, project-structure, dev-env-setup, implementation-plan, and implementation-playbook — then the build loops. Everything else (domain modeling, ADRs, architecture, specs, quality gates, validation) is disabled. This is the minimum safe depth: still enough spec to TDD against, but no ceremony you'd skip on a weekend project.

Balanced. Most steps are enabled at depth 3. The exceptions: the three innovate-* steps and automated-pr-review are off by default, and the conditional steps (beads, design-system, add-e2e-testing, the spec steps, platform-parity-review) are enabled-but-if-needed. You override individual steps to taste.

Maximum quality — and the schema default (methodology defaults to deep src/config/schema.ts:272; the resolver also falls back to deep). Every planning step is enabled, including the innovate-* steps (as if-needed), domain modeling, ADRs, full architecture, all specs, every quality gate, all seven validation audits, and the full finalization phase. External-model dispatch kicks in at depth 4+. Best for complex or regulated systems.

Game / multi-service / platform steps are off in all three presets. The 24 game steps and 5 cross-service steps are enabled: false in mvp, custom, and deep. They only switch on via a project-type overlay — see the playbooks below.

Project-type playbooks

Overlays (content/methodology/*-overlay.yml) layer onto a preset. Most overlays only inject domain knowledge into existing steps (so a web-app build pulls in web-app-auth-patterns during tech-stack, security, etc.); a few also enable whole step families.

web-app-overlay.yml is knowledge-only — it appends web-app expertise to ~25 steps (rendering strategies + deployment + auth into tech-stack, UX patterns into ux-spec, the design system into design-system, and so on). The spec steps you'll actually use: database-schema, api-contracts, ux-spec (all conditional). add-e2e-testing configures Playwright.

mobile-app-overlay.yml injects mobile knowledge the same way. The distinctive piece is add-e2e-testing, which auto-detects the platform and wires up Maestro for mobile/Expo instead of Playwright (phase 4 — integration).

game-overlay.yml is the heavyweight: it enables a whole phase family via step-overrides. On come game-design-document, review-gdd, performance-budgets, narrative-bible, netcode-spec, ai-behavior-design, art-bible, audio-design, economy-design, save-system-spec, game-ui-spec, playtest-plan, platform-cert-prep, and more — many as if-needed. These live across the pre, architecture, specification, and quality phases.

multi-service-overlay.yml activates when services[] is present in config. It enables five cross-service steps (service-ownership-map, inter-service-contracts, cross-service-auth, cross-service-observability, integration-test-plan) and — crucially — adds dependency-overrides and reads-overrides so downstream steps wait for and consume those cross-service artifacts. Use scaffold next --service <name> to drive a single service.

cli-overlay.yml (and library-overlay.yml) are knowledge-only. They append CLI expertise — command parsing, distribution, shell integration, output formatting — into tech-stack, system-architecture, api-contracts, operations, etc. No extra steps are enabled; you mostly skip the UX/design and (often) the database spec steps.

Other shipped overlays include backend, data-pipeline, data-science, ML, web3, browser-extension, and several research presets — all under content/methodology/.

The CLI is your driver. Every command lives in src/cli/commands/.

commandwhat it doessource
scaffold nextShow the next eligible step(s) — what's unblocked right nowsrc/cli/commands/next.ts:28-29
scaffold run <step>Assemble + run a step; on completion, advances statesrc/cli/commands/run.ts:45
scaffold complete <step>Mark a step done that you ran outside scaffold runsrc/cli/commands/complete.ts:28
scaffold skip <step..>Skip one or more steps (treated as satisfied for deps)src/cli/commands/skip.ts:35
scaffold reworkRe-run steps by phase for depth improvement or cleanupsrc/cli/commands/rework.ts:39-40
scaffold reset [step]Reset one step to pending, or wipe all pipeline statesrc/cli/commands/reset.ts:32
scaffold statusShow overall progress and per-step statusessrc/cli/commands/status.ts:80-81

A typical loop: scaffold next to see what's unblocked → scaffold run <step> → repeat. next is a pure read — it derives eligibility live from the graph + state and deliberately does not mutate state.json, so running it after an upgrade won't churn committed state.

rework is phase-scoped: scaffold rework --through 5 re-runs phases 1–5, --phases 2,7 re-runs just those, --exclude 3 drops a phase, --depth 5 bumps depth for the batch. It batch-resets the selected steps to pending and creates a rework session the runner skill walks through.

For build-phase work you don't touch next/complete — the stateless steps (single-agent-start, multi-agent-start, the resume commands, quick-task, new-enhancement) are run on demand and never tracked. See the concepts guide{mode=advisory} and the CLI reference{mode=advisory} for the full command surface.

Why a step is blocked

A step becomes eligible only when its dependencies are satisfied. The frontmatter distinguishes two relationships, and they behave very differently:

readsdependencies — and that trips people up. Because reads don't gate execution, a step can run "successfully" while silently missing context it would have benefited from. If you skip an upstream step, downstream steps that only read it proceed without warning. When ordering matters, an overlay can promote a read into a dependency (the multi-service overlay does exactly this with its dependency-overrides).

Conditional ("if-needed") steps

A step with conditional: 'if-needed' (src/types/frontmatter.ts:118) is enabled but only applies to certain project shapes. database-schema is conditional: "if-needed" (content/pipeline/specification/database-schema.md:10) — it runs only if your project has a database layer. The spec steps (database-schema, api-contracts, ux-spec), add-e2e-testing, design-system, beads, and platform-parity-review are all conditional in the default presets.

The silent-skip trap. Conditional steps that don't apply, and steps you skip manually, both count as "satisfied" for dependency purposes — so the pipeline keeps flowing and scaffold next shows green. That's by design, but it means the pipeline won't warn you that you skipped something important. If ux-spec is skipped on a project that genuinely has a UI, nothing downstream will block; the gap only surfaces in phase 13 validation (or the build observability audit). Run scaffold status to see what was actually skipped vs completed.

A representative dependency slice

The phase-2 foundation steps show the gating in miniature: tech-stack has no dependencies (it kicks off the foundation), and coding-standards depends on it.

#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#000000;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#my-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#my-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:1px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#666;stroke:#666;}#my-svg .marker.cross{stroke:#666;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg p{margin:0;}#my-svg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#000000;}#my-svg .cluster-label text{fill:#333;}#my-svg .cluster-label span{color:#333;}#my-svg .cluster-label span p{background-color:transparent;}#my-svg .label text,#my-svg span{fill:#000000;color:#000000;}#my-svg .node rect,#my-svg .node circle,#my-svg .node ellipse,#my-svg .node polygon,#my-svg .node path{fill:#eee;stroke:#999;stroke-width:1px;}#my-svg .rough-node .label text,#my-svg .node .label text,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-anchor:middle;}#my-svg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#my-svg .rough-node .label,#my-svg .node .label,#my-svg .image-shape .label,#my-svg .icon-shape .label{text-align:center;}#my-svg .node.clickable{cursor:pointer;}#my-svg .root .anchor path{fill:#666!important;stroke-width:0;stroke:#666;}#my-svg .arrowheadPath{fill:#333333;}#my-svg .edgePath .path{stroke:#666;stroke-width:1px;}#my-svg .flowchart-link{stroke:#666;fill:none;}#my-svg .edgeLabel{background-color:white;text-align:center;}#my-svg .edgeLabel p{background-color:white;}#my-svg .edgeLabel rect{opacity:0.5;background-color:white;fill:white;}#my-svg .labelBkg{background-color:rgba(255, 255, 255, 0.5);}#my-svg .cluster rect{fill:hsl(0, 0%, 98.9215686275%);stroke:#707070;stroke-width:1px;}#my-svg .cluster text{fill:#333;}#my-svg .cluster span{color:#333;}#my-svg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(-160, 0%, 93.3333333333%);border:1px solid #707070;border-radius:2px;pointer-events:none;z-index:100;}#my-svg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#000000;}#my-svg rect.text{fill:none;stroke-width:0;}#my-svg .icon-shape,#my-svg .image-shape{background-color:white;text-align:center;}#my-svg .icon-shape p,#my-svg .image-shape p{background-color:white;padding:2px;}#my-svg .icon-shape .label rect,#my-svg .image-shape .label rect{opacity:0.5;background-color:white;fill:white;}#my-svg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#my-svg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#my-svg .node .neo-node{stroke:#999;}#my-svg [data-look="neo"].node rect,#my-svg [data-look="neo"].cluster rect,#my-svg [data-look="neo"].node polygon{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node path{stroke:url(#my-svg-gradient);stroke-width:1px;}#my-svg [data-look="neo"].node .outer-path{filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node .neo-line path{stroke:#999;filter:none;}#my-svg [data-look="neo"].node circle{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].node circle .state-start{fill:#000000;}#my-svg [data-look="neo"].icon-shape .icon{fill:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg [data-look="neo"].icon-shape .icon-neo path{stroke:url(#my-svg-gradient);filter:drop-shadow( 1px 2px 2px rgba(185,185,185,1));}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}readsreadsdependencydependencycreate-prd(phase 1)tech-stackdeps: []coding-standardsdeps: [tech-stack]tdddeps: [coding-standards]project-structuredeps: [tech-stack,coding-standards]

Solid arrows are hard dependencies (block until done); dashed arrows are soft reads (used if present, never block).

CREATE vs UPDATE mode

Running a planning step a second time doesn't blindly overwrite its artifact. Every document-creating prompt carries a Mode Detection block: if the output file already exists, the step runs in UPDATE mode instead of CREATE mode.

scaffold run detects this and (unless --force) confirms before re-running a completed step, and warns on a depth downgrade (re-running at a lower depth than last time). In UPDATE mode the prompt is instructed to preserve human/team customizations and only change what genuinely needs to change. From coding-standards's Mode Detection block (content/pipeline/foundation/coding-standards.md:57):

Update mode if docs/coding-standards.md exists. In update mode: preserve naming conventions, lint rule customizations, commit message format, and project-specific patterns.

So re-running coding-standards after you've hand-tuned its linter config keeps your overrides; it doesn't reset them. This is what makes the planning phases safe to iterate — you can rework a phase at higher depth and get richer output without losing the decisions you've already made.

Phase-15 steps don't use the planning CREATE-vs-UPDATE semantics. They produce no persistent planning doc, so the document Mode Detection block doesn't apply. Each build prompt instead declares its own execution mode: the agent loops just execute, single-agent-resume/multi-agent-resume run in RESUME mode, quick-task in CREATE mode, and new-enhancement in ENHANCEMENT mode.

Phase-boundary audits

Completing certain planning docs automatically triggers a non-gating cross-document audit. Six steps are phase boundaries (src/observability/engine/phase-subsets.ts:1-8): user-stories, tech-stack, coding-standards, design-system, implementation-plan, and implementation-playbook. When you complete one of these, the state manager fires an H-cross-doc audit and prints a one-line summary — catching doc drift the moment a planning phase closes, without ever blocking the transition. See the build observability guide{mode=advisory} for how that audit works and what the nine lenses check.

Where it all lives

pathwhat it holds
content/pipeline/<phase>/*.mdThe 90 meta-prompt files, one directory per phase
content/methodology/*.ymlPresets (mvp, custom-defaults, deep) + project-type overlays
content/knowledge/Domain entries injected into prompts during assembly
src/types/frontmatter.tsThe canonical PHASES constant + frontmatter schema
src/cli/commands/next, run, complete, skip, rework, reset, status
.scaffold/state.jsonPer-step completion state (planning phases only)

The phase list, ordering, and slugs are defined exactly once, in PHASES (src/types/frontmatter.ts:6); every doc, skill, and command resolves against it.