A spec stays the contract — objective, durable outputs, boundaries, testing
strategy, acceptance criteria. The low-level design (the how: data model,
component decomposition, screen states, resilience, deployment sequencing) lives
in the plan. Three additive pieces connect them: the spec’s Shape:
selector, the spec’s ## Durable Outputs table, and the plan’s
## Design (LLD) section.
Durable outputs
Section titled “Durable outputs”## Durable Outputs names the lasting records that must exist outside the
delivery container before closeout can dispose of it. It is repository-specific.
Authors assess the actual application and repository for user promises, current
product truth, architecture, decision rationale, interface compatibility,
operations, maintainer procedure, release history, and reusable learning.
Each applicable output names its semantic role, destination, owner, expected
evidence, and closeout condition. none needs an explicit rationale. Ambiguous
or absent destinations remain named blockers until a person selects or creates
the owner; the workflow does not assume this catalogue’s paths in another repo.
Shaping reads each applicable existing surface as a whole. A touched page, link, or passing test is evidence for freshness, not proof. User-facing behavior gets an established user-documentation draft before implementation approval when that surface exists. Architecture and maintainer pages stay terse: ownership, boundaries, invariants, navigation, and links to implementation, contracts, tests, and verified commands.
The Shape: field
Section titled “The Shape: field”An optional spec header that names the kind of work, so the plan scaffolds the right design sub-sections and no more. It is stack-neutral — it never names a framework.
| Value | The feature is… |
|---|---|
ui | a screen, view, or interaction flow |
service | a backend endpoint, worker, or job |
data | a schema, model, or migration change |
integration | a wiring-together of external systems |
mixed | spanning several of the above, or unsure |
- **Shape:** ui- Optional and additive. A spec omits it (or sets
mixed) and stays valid. - It selects, it doesn’t constrain. A narrower shape scaffolds fewer
## Design (LLD)sub-sections;mixed/unsure scaffolds the full set, then you prune. author-delivery-brief continuesets it per slice from the brief’s framing;new-specasks when it isn’t obvious.
The ## Design (LLD) section
Section titled “The ## Design (LLD) section”An optional, shape-pruned section in plan.md, placed before ## Tasks. It holds nine stack-neutral design categories as ### sub-headings; you keep only the ones the Shape: selects and delete the rest. A one-file change keeps the section thin or empty.
| # | Sub-heading | What it captures |
|---|---|---|
| 1 | Design decisions | Load-bearing choices and the alternatives rejected |
| 2 | Data & schema | Entities, fields, types, ownership, migrations, retention. When the feature migrates existing data: backfill checkpointing, restartability, cutover validation |
| 3 | Interfaces & contracts | Surfaces exposed/consumed (REST, events, BFF, RPC). When the feature crosses a boundary: a named test seam per crossed boundary |
| 4 | Component / module decomposition | The parts, their responsibilities, new vs. reused |
| 5 | State & control flow | State model, transitions, sequencing; UI navigation. When state changes concurrently: concurrency, consistency, locking, atomicity, transaction boundaries |
| 6 | Behavior & rules | Business and validation rules |
| 7 | Failure, edge cases & resilience | Retries, fallbacks, timeouts, idempotency, degraded modes. When external failures are possible: stable error classes, retryability, external failure mapping |
| 8 | Quality attributes (NFRs) | How the design meets each NFR-with-a-bar. When the feature needs operational visibility: a concrete observability surface |
| 9 | Dependencies & integration | External systems/services/libraries and their coupling |
The tenth design category — rollout & deployment — is not a Design sub-heading. It is realized by the plan’s expanded ## Rollout section (infrastructure, external-system integration, deployment sequencing). Cross-link it from the Design sub-sections; never duplicate it.
Each sub-section traces to the acceptance criteria it satisfies and the contracts/ it implements — so the design is always anchored to something verifiable. No acceptance criterion lives in the design; the spec keeps the contract. (A user-visible UI state and an NFR with a pass/fail bar each rise to the spec as acceptance criteria; the per-screen and per-NFR design sits here.)
Each sub-section also carries Owned by: — the task IDs that implement its
decisions, comma-separated, each matching T<number> with an optional lettered
suffix. Traces to: points up at the contract; Owned by: points down at the
work, so a design decision that nothing builds is visible before execution
starts.
The edge runs one way only. A design decision names its tasks; a task never
has to cite a design decision. Over a third of tasks have no design origin —
release, gate, documentation, projection and test-only work answers to
## Durable Outputs and the acceptance criteria instead. Measured on this
catalogue’s own corpus: 921 of 2,511 tasks, 36.7%, sit in the 183 plans that
carry no design section at all, so a reverse rule would fire on every one of
them.
Once any ## Design (LLD) sub-section of a plan carries Owned by:,
lint-contract-item-alignment.py checks that plan: every sub-section with body content must name at least one task ID,
and every named ID must match a task heading in that plan. A plan that carries
the field nowhere is reported as predating it, never failed, so no existing
plan needs migrating. The lint checks the declared field; whether every
design decision genuinely has an owner is the pre-review walk’s question, not
the lint’s.
Before approval, the design is working material an implementer corrects in
place. After approval it is not: the approval digest hashes the whole plan, so
an in-place edit moves the hash and the transition guard refuses it. Two cases
then route differently — grounding that arrives for a seam the plan recorded as
no stub (implementation-discovered) goes to the verification ledger, because
the plan predicted that discovery; a design decision approval settled and
execution falsified is a plan error taking the controlled-amendment procedure.
The ledger is not a route for the second.
At closeout, the LLD is treated as mixed delivery material. Policy, trade-offs, rejected alternatives, current ownership, state/control flow, security invariants, interface promises, operations, and reusable learning move to their applicable durable owners when they cannot be reconstructed faithfully from code or tests. Mechanically evident internal shapes stay with code, types, docstrings, and tests. One-off construction order and review choreography can remain disposable residue. A non-inferable design fact that still lives only in the plan blocks disposition.
Which Shape: selects which sub-sections
Section titled “Which Shape: selects which sub-sections”A guide, not a gate — prune freely. The authoritative copy of this mapping is the shape-map comment in the plan.md template (new-spec’s assets/plan.md); the table below reproduces it for reading — if the two ever disagree, the template wins.
Shape: | Typical sub-sections |
|---|---|
ui | decomposition · state & control flow · behavior & rules · quality attributes |
service | interfaces & contracts · data & schema · failure & resilience · quality attributes |
data | data & schema · interfaces & contracts |
integration | dependencies & integration · interfaces & contracts · failure & resilience |
mixed / unsure | scaffold all, then prune |
Stack-derivation: how the design gets its stack
Section titled “Stack-derivation: how the design gets its stack”The Design headings are universal; the prose under them names a concrete stack. That stack is derived, never baked into the template:
- Reference architecture present — when
docs/architecture/reference.mdexists, the design conforms to it: it references that document’s named components, stereotypes, layers, and standards by name rather than inventing parallel ones. The reference architecture is the source of truth; the design is an instance of it. - Reference architecture absent — the step degrades to detecting the established stack from the repo: lockfiles (
package.json,pyproject.toml,go.mod,Cargo.toml, …), build/orchestration files, and the imports in the module the feature touches — plus any stack context a product brief carried. - Ambiguous or greenfield — the step asks. It never guesses a framework into the design: elicit, don’t invent.
See also
Section titled “See also”reference.mdsections and the stack-pack contract — the golden path this design conforms to when it’s present.- Why the plan owns the low-level design — the reasoning behind this split.
- Close work without losing lasting context — how closeout verifies durable owners before disposition.
- Product brief fields — the sibling spec fields a brief stamps (
Brief:,Satisfies:). - Why a brief layer — where briefs sit relative to specs and plans.