| 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) |
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. A node is <capability>/<unit> 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 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.
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)
- Three kinds, declared — descriptive / reference (
## Subject, no suite) / behavioral (owns a
suite); never inferred from files or location.
- Placement is the taxonomy applied to folders — rules to
design/, behavior to the capability
folder, reference artifacts to the capability that owns them.
- Screaming architecture with three non-capability folders (
design/, workflows/, ledger/)
and root files, not folders, for single documents (glossary.md required).
- Two levels, never three — deeper sub-grouping is a
concept: tag, not a folder.
- 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.
- 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.