ADR-024: Spec-driven bootstrap
Status: Accepted; the --plan flag, STORY-NNN stories and docs/plan/ for single-repo plans are superseded by ADR-026: Feature specs drive the build (svc 3.0)
Date: 2026-10-07
Builds on: ADR-008: Shape detection — .copier-answers.yml with sniffing fallback, ADR-011: Multi-repo plan format for /app:build-feature, ADR-015: Shape registry as code (shapes.yml)
Context
Section titled “Context”The platform has the pieces of spec-driven development: the product-manager writes stories into docs/backlog.md, the architect writes a plan into docs/plan/<slug>.md, /svc:plan-feature produces both without code. The path between them was missing:
/shared:new-serviceand/shared:new-appprinted/svc:build-featureas the first step, soplan-featurewas never suggested./svc:build-featurealways re-ran the product-manager and architect phases. Runningplan-featurefirst meant planning twice and overwriting the reviewed plan; only the multi-repo--from-plan(ADR-011) consumed a finished plan.- No template shipped
docs/backlog.md, and only gitops-app shippeddocs/plan/. Stories had no ids a plan or a PR could cite. - The
CLAUDE.mdof the templates listed the workflows but did not say a feature starts with a plan.
Decision
Section titled “Decision”- Plan first in every bootstrap output. For service, library and web shapes the Next steps start with
/svc:plan-feature "<description>"followed by/svc:build-feature --plan docs/plan/<slug>.md; for gitops-app andnew-appthey start with/app:build-featurefollowed by/app:run-plan. Bootstrap stays a deterministic script: it prints the command with the description filled in and does not start an agent (planning needs the new repo as working directory). /svc:build-feature --plan <path>builds a plan that was already produced and reviewed. Phases 1 and 2 are skipped. The plan must start with the YAML metadata block, itsshapemust equal the repo’s shape and every id instories:must exist indocs/backlog.md. The acceptance criteria of those stories drive testing and the PR; Phase 6 marks exactly those stories done. It excludes--from-plan. Without--planthe command is unchanged and writes the same artifacts.- Stories and plans reference each other. Stories are
#### STORY-NNN — <title>(ids continue the highest in the file); plan metadata listsstories: [STORY-NNN, …]; the PR description names the story ids. - Every template seeds the spec directories.
docs/backlog.md(format header, no stories) anddocs/plan/are project-owned (_skip_if_exists). Existing repos do not get the files; they get theCLAUDE.mdrule on their next/shared:update-service. - Every template’s
CLAUDE.mdhas a “Spec first” section with the rule. Quick tasks and bug fixes are exempt. - The contract is enforced.
shapes.py checkfails when a template lacksdocs/plan/, the seededdocs/backlog.md(gitops-app needs onlydocs/plan/) or the “Spec first” section, so a future shape cannot skip them.
Consequences
Section titled “Consequences”- The first feature of any new repo goes through a reviewable spec. The cost is one extra command before building;
/svc:build-featurewithout--planstill works for people who want one step. - Enforcement is by convention and contract, not by a gate. A hard CI check that PRs cite a story is deferred until this version has been used; a plan approval step (
status: approved, refused whendraft) follows as STORY-036. - Plans edited after review can drift from their stories: validation checks that the stories exist, not that their criteria are unchanged.
svc2.2.0 (new flag,stories:metadata),shared0.8.1 (next steps).
Not included
Section titled “Not included”A CI story check, the approval status, retrofitting stories into existing repos, and running plan-feature automatically from the bootstrap command.