SDD — Spec-Driven Development with Speckit
Coffer uses Speckit for spec-driven development. Every PR that changes externally visible behavior updates the relevant spec.md first, then the code.
Folder Layout
All specs live flat under specs/<NNN>-<short-name>/, where NNN is a zero-padded three-digit ordinal (001, 002, …). There is one kind of spec — no foundation / capability / quality split.
Cross-cutting mechanisms (audit, credentials, events, jobs, storage, session) get shared modules rather than their own specs; the "extract only after the second feature needs them" rule is the invariant in .specify/memory/constitution.md.
specs/<NNN>-<short-name>/
spec.md # User-visible contract. Generated by /speckit-specify.
# Includes "## Acceptance Scenarios" section
# (Spec Kit convention — scenarios live in spec.md,
# NOT in a separate .feature file).
plan.md # Implementation plan. Generated by /speckit-plan.
tasks.md # Work breakdown. Generated by /speckit-tasks.
research.md # Background, alternatives. /speckit-plan Phase 0.
data-model.md # Entities, fields, relationships. /speckit-plan Phase 1.
contracts/
api.openapi.yaml # Wire contract (hand-authored, PR-reviewed).
events.json # Event schemas (when applicable).
tools.json # MCP tool schemas (when applicable).
quickstart.md # How to use this feature. /speckit-plan Phase 1.
checklists/
review.md # Generated by /speckit-checklist.
release.mdOne spec per behavior, not per layer. A spec covers the entire vertical slice — backend services plus whatever surfaces are needed to deliver that user-visible behavior (CLI, MCP / shim, REST). Do not split a single behavior into separate per-surface specs; that creates drift between two halves of the same contract.
Skeleton-first phase: When seeding a new spec, write spec.md first. Other files (plan.md, tasks.md, contracts/, etc.) are added when the spec moves toward implementation, via /speckit-plan and /speckit-tasks.
Keep the Docs in Sync With the Code
When a change alters behavior, update the spec and every related doc in the same PR — before or alongside the code, never as a follow-up. Spec-first: the spec is the source of truth and the code conforms to it. "Related docs" is the whole set, not just spec.md:
specs/<NNN>/spec.md(+ itsspec.zh.mdcompanion) — the user-visible contract and its acceptance scenarios.specs/<NNN>/contracts/api.openapi.yaml— the wire contract; add/rename/remove endpoints and schemas to match the code.specs/<NNN>/data-model.md,plan.md,quickstart.md(+ each.zh.mdcompanion) — entities, plan, and usage prose.- Cross-cutting docs the change touches: the relevant
docs/decisions/ADR,.specify/memory/architecture.md, and any affectedagents/*convention such asagents/visual-language.md.
Every prose .md has a .zh.md companion that must be updated in the same commit (the only exemptions are tasks.md and the OpenAPI YAML). The acceptance audit (scripts/audit_acceptance.py, run by make verify) ties each spec.md scenario name to a test marker, so renaming/adding/removing a scenario means updating its @pytest.mark.acceptance(... scenario=...) / acceptance(...) marker too. A pure refactor or a frontend-only change with no contract impact needs no spec edit — but if behavior, an endpoint, a schema, or the IA changes, the docs change with it.
Acceptance Scenarios — In spec.md, Gherkin-Style
Use Gherkin-style language inside the ## Acceptance Scenarios section of spec.md. Each scenario maps to one or more tests (see testing.md).
## Acceptance Scenarios
### Scenario: <verb-led short name>
- **Given** <precondition>
- **When** <action>
- **Then** <observable outcome>
- **And** <additional assertion>Tests cover each scenario via the acceptance(spec, scenario) marker — see testing.md "Acceptance Scenarios — Cross-Tier Markers".
End-to-End Deliverable Rule
Every feature, on completion, must deliver a usable end-to-end product: backend persistence + the surfaces that expose it (CLI, MCP / coffer-mcp-shim, REST) — all wired so the user can really operate the feature.
A spec is "shipped" only when the end-to-end deliverable works AND every acceptance scenario has at least one covering test.
Markdown Style for spec.md
spec.mdis for the user-visible contract; ≤ 300 lines preferred.- Don't restate architecture in
spec.md; reference.specify/memory/constitution.md. - Use plain English. Avoid jargon.
- No time annotations (
Day N,Last updated, etc.) in spec / plan / research / data-model / quickstart.