--- name: spec-structure-governance description: "Partial Skill: invoke by name only — the SDD project-spec organization contract: what kind of node a spec is and where that kind lives. Loaded by scaffold-project-spec, place-node, the formation Warden, and the architect bars, not user-triggered." user-invocable: false --- # SDD Spec-Structure Governance What kind of node a spec is, and **where that kind lives** in the project spec. This skill is the canonical home consumers load instead of restating it — `scaffold-project-spec` when it lays a tree out, `place-node` when it suggests a home, the formation **Warden** when it audits structure, and the **architect** bars when they judge placement. Taxonomy and placement are **one rule, not two**: the placement law is the taxonomy applied to folders, and cannot be stated without it. A descriptive doc in `design/` is correct where a behavioral node in the same folder is a defect — the folder alone does not say which. The lifecycle a spec moves through is `sdd:lifecycle-governance`; a node's internal section shape is `sdd:spec-format-governance`; how the suite is written is `sdd:suite-format-governance`. ## The node taxonomy — three kinds, declared | Kind | Subject | Owns a suite | Carries | Marker | |---|---|---|---|---| | **descriptive** | none | no | ordinary prose | *(none — the default)* | | **reference artifact** | a real thing with no testable surface of its own | no, by design | `## Subject` in place of `## Use Cases` | `spec-type: reference` | | **behavioral artifact** | a testable subject | **yes** | the node sections | `spec-type: behavioral` | **Declared, never inferred.** The kind lives in frontmatter. Inference breaks both ways: a behavioral node has no suite *yet* while it is being authored, and descriptive indexes live outside the rules folder — so neither file-presence nor location classifies reliably. Declaring it up front makes an unfinished behavioral node read as **incomplete** rather than as an index. A **capability** is what the project *does*. The everyday word for one behavioral node is a **unit spec**. ## Placement — the taxonomy applied to folders **Screaming architecture** is the default: top-level folders are named for **capabilities**, so the folder names say what the project does. Three folders are deliberately *not* capabilities: | Folder | Holds | |---|---| | `design/` | the **rules** — the model and the *why* (descriptive docs), in its own shape (below) | | `workflows/` | the **usage** — how capabilities compose into whole flows (the project-level suite) | | `ledger/` | the **provenance** — durable audit records; data, outside the node taxonomy | **Rule-in-design, behavior-in-capability.** A rule and the behavior enacting it live apart: rules go to `design/` as descriptive docs, the scenarios that enact them go to the capability folders as behavioral specs, and a reference artifact is homed in the capability that owns it. This keeps `design/` readable as a model while the capabilities stay testable as behavior. **Root files, not folders.** Every mandated folder is an exception to screaming architecture, so the mandated set stays minimal: anything that is one document lives as a **root file beside `spec.md`**. `glossary.md` — the project's ubiquitous language, every load-bearing term defined once — is required of every project spec. **Two levels, never three — for capability nodes.** A capability node is `/` and never sits three deep. A sub-grouping inside a capability is a **cross-cutting concern**, so it is expressed as a `concept:` tag and recovered through the generated by-concept index — never as a third folder level. The rule covers capability nodes only: its reason does not reach a design version, which is a whole alternate snapshot of the model that no `concept:` tag can express. **The `design/` shape — current at the top, the next design beside it.** `design/` is the single description of the system; ADRs are the frozen record of why it changed. A design stays trustworthy only if it is updated as a whole, so: - **Current at the top level, one file per perspective** — the angles a reader takes on the whole system, one file each, **never a perspective folder**. The ADR log `design/decisions/` is the one standing sub-folder. - **A version folder holds the next design while one exists.** The project names it (`design/next/` is a suggestion; `design/v2/` works as well). It holds a **full copy** of the perspective files, never a diff, so each version reads on its own and `diff -r` shows the whole change. It holds no `decisions/`. At most one exists at a time. - **The cut is one commit**: the version folder's contents replace the top-level perspective files, and the folder and its placement-map record go. Git keeps the previous version; `design/` never carries a `previous/`. - **The cut trigger is recorded and checkable.** While a version folder exists, the root `spec.md` placement map names it and what cuts it over — a capability set reaching `implemented`, or a named release. Without a checkable trigger the next design drifts into an unofficial current. Making it checkable is the author's duty; the formation Warden checks that one is recorded. A sub-folder of `design/` the map does not name, other than `decisions/`, is a perspective folder. Current stays at the top rather than in `design/current/` so that links to a design doc survive every cut: most of a project's life has no next design, and links accumulate from ADRs, capability specs, and the docs site. **Rejected — a fourth exempt top-level folder** (`design-next/`). It grows the mandated set this governance keeps minimal, and it would sit among the capability folders as if it were one. **The concept axis.** The tree can privilege only one axis, and it privileges capability; a concern enacted across several capabilities is declared in `concept:` frontmatter and navigated through the index instead. **Suite organization.** Unit suites **colocate** with their capability node, one per unit. The project-level suite lives in `workflows/`, where a **workflow** is the project-level analogue of a use case — a path through the composed capabilities. ## One spec per project A **project** is the unit a spec maps to — a repo harness, an agent plugin, an npm package, a website, or one package inside a monorepo. Each has exactly **one** spec: one `spec.md`, one suite, one gate/freeze baseline. Growth is absorbed by **adding folders**, never by splitting into sibling specs — splitting fragments the lifecycle, so one change touching three areas would re-open three frozen specs and pay three approvals. **Colocate by default**, nested projects included. **Hoist only when the spec cannot be kept out of what ships** — the project dir is copied **wholesale**, with no include/exclude mechanism to leave the spec behind. The one identified case is an **agentic plugin**: plugin install copies the whole directory, so a colocated spec would reach every consumer. An npm package colocates — its `files` / ignore list excludes the spec from the tarball. **Nesting is never the reason**; if a new packaging format has the same all-or-nothing copy, it joins the hoisting case. ## Strategy is policy; homes are data Screaming architecture is the **default**, not the only layout. Whichever layout a project uses is a **choice**, and choices are declared. But the choices are **not equals** — see the partition stake below; declaring a layout does not license breaking node<->capability alignment. - **The strategy** (`capability-first`, `mirror-source`, …) is **declared** in the root `spec.md` **placement map** and **read**. Never derive it from the tree: a greenfield project has no tree yet and still has a strategy; deriving it from a healthy tree is circular (it launders a past decision as an observation); and on a half-migrated tree it perpetuates the layout being migrated *away* from. - **The homes** — which folder a given concept's node sits in — are **facts** about the current tree, derived from `concept:` tags. A stored home list is a second source that rots, so homes are never stored. - **They compose:** the declared strategy **parameterizes the derivation**. Keep deriving homes, but ask the placement map *which* derivation to run. **The placement map has two parts, and a placement judgment must consult both.** Beside the declared strategy it carries a **routing table** — the maintained "a concept of kind K lives in home H" taxonomy plus the human **tie-break** rows for genuinely contested overlaps. The table records decisions the strategy alone does not settle, so a node placed by an explicit routing-table row is **correctly placed even when it does not match the strategy's derivation**. Judging misplacement on the strategy alone therefore reports false findings against exactly the placements a human already adjudicated. The test is a disjunction: a node is misplaced only when it **neither** follows the declared strategy **nor** matches a routing-table row. While a next design exists, the map also names the **design version** folder and its cut trigger (the `design/` shape above); a judgment of `design/` reads that entry. This is the same split the corpus-discovery rule already makes — fixed conventions are scanned, while an off-convention anchor list is declared and curated. "No drift" means *do not store what you can observe*, never *do not declare a choice*. ### The partition stake — why capability-first is more than a preference Capability-first is the partition the **mission scheduler** depends on. One mission owns one spec-node, so when **node <-> capability is 1:1** a change touches one node and its collisions are legible; missions run in parallel. A **layered / framework-first top level scatters one capability across many folders** — the mapping breaks, a single behavior smears across nodes, collisions explode, and the schedule degrades toward **serial** (ADR-0025). So layouts are ranked by whether they preserve that alignment, not by taste: - **capability-first** — aligned by construction; the recommendation. - **mirror-source** — inherits whatever alignment the source has. Best case is a feature-first source, which is already capability-aligned; over a layered source it is **still offered**, with the cost named (below). - **layered / framework-first as the *top* level** — **discouraged** as a *chosen* layout for a project free to choose, and a declaration does not rescue it. Layering survives *nested inside* a capability. The invariant that holds under **every** strategy: **one capability per node, never smeared across nodes**. A declared layout says where a node goes; it never licenses a capability to scatter. The scheduler's **false-conflict rate** is the standing metric of the partition's quality. ### A coarse partition costs precision, not correctness This is why an imperfect layout is workable rather than disqualifying. The scheduler is **conservative** — a collision it cannot resolve **serializes** — so the worst case of a poor partition is a **slower schedule, never a corrupted one**. Three mechanisms recover most of the loss: - **The collision ladder descends below the node** — file, region, semantic, symbol — so two missions sharing a node but touching different symbols classify **soft** and still co-wave. The residue is `symbol-rung-deferred`: symbols that cannot be inferred stay hard. - **Worktrees** dissolve file-level false dependencies until write-back. - **The concept axis** carries the capability view the folders do not: in a mirrored tree the folders name source areas while `concept:` tags still name capabilities. **Adoption over purity.** Demanding a restructuring before a project may hold its first spec is an entry toll, and an unadopted tool partitions nothing. A project adopts on the shape it has, accumulates `concept:` tags as it writes nodes, and **hoists one capability at a time when the false-conflict rate earns the move** — a concept spanning many nodes being the measured signal that a capability wants its own home. Capability-first is the **destination**, reached on evidence, not the entry condition. ## Key points (read-check) 1. **Three kinds, declared** — descriptive / reference (`## Subject`, no suite) / behavioral (owns a suite); never inferred from files or location. 2. **Placement is the taxonomy applied to folders** — rules to `design/`, behavior to the capability folder, reference artifacts to the capability that owns them. 3. **Screaming architecture** with three non-capability folders (`design/`, `workflows/`, `ledger/`) and **root files, not folders**, for single documents (`glossary.md` required). 4. **Two levels, never three, for capability nodes** — deeper sub-grouping is a `concept:` tag, not a folder. 5. **`design/` has its own shape** — current at the top, one file per perspective (never a perspective folder), at most one project-named version folder holding a full copy of the next design, a one-commit cut, and the cut trigger recorded in the placement map. 6. **One spec per project**; colocate by default and **hoist only when the spec cannot be kept out of what ships** (the agentic plugin) — nesting is never the reason. 7. **Strategy is policy, homes are data** — read the declared strategy from the placement map, derive homes from `concept:` tags, and let the strategy pick the derivation.