--- name: formation-loop description: "Partial Skill: invoke by name only — the SDD formation loop, the Architect's outer loop run by the Warden — invoked by the formation-loop delegate, not triggered by users directly." user-invocable: false metadata: internal: true --- # SDD Formation Loop The **structure outer loop** of the SDD model. Owned by the **Architect** and run by its delegate, the **Warden** (`sdd-warden`), parallel to the conductor running the mission loop. It fires **post-mission**, **corpus-wide and continuous**, and asks one question and only one — **is what we have organized right?** Its standing subject is `corpus/` + `project-spec/` and the whole organization: it evolves how the corpus is **arranged**, never what it says. Load `sdd:combat-log-governance` for any provenance it touches; the floor + gradient the Warden renders its per-act verdict against are the conductor's autonomy bar (`start-mission`) — this skill defers both and never restates them. ## Corpus-wide, never the per-spec gate This is the load-bearing distinction. The Architect appears in **two** places that must never be conflated: | | **Formation loop** (this skill) | **The gate's Architect-backward face** | |---|---|---| | Scope | the **whole corpus** | **one spec** | | Cadence | **continuous**, across missions | **point-in-time**, at one spec's gate | | Question | is the corpus **organized** right? | does **this change** fit structurally? | | Acts | audit node-shape, split, reconcile | one approve/pause/reject structural verdict | Every run produces a **finding set covering every spec in the corpus**; a structural pass scoped to one spec is **not** a formation run. When asked to act as the per-spec gate structural check, the loop **declines** and renders no per-spec gate verdict. ## Input — corpus structure + discovery, never the combat log The Warden reads what the corpus **is**, never what a mission **did**. Its **primary** input is structural: the corpus **structure** and **discovery** (`corpus/` + `project-spec/`). To stay efficient rather than cold-scanning the whole corpus every run, it may consult the durable **public trail** (CR-source conclusions + changesets + git history) **forward** via a cursor to learn what shipped recently and prioritize the structural pass there first. It reads **never** the combat log (the doctrine loop's input, retired at retro) and **never** live subagent context — like the other outer loops it fires strictly post-mission. **Read the declared strategy before judging.** Each project spec's root `spec.md` carries a **placement map** naming the layout strategy it chose (`capability-first | mirror-source | …`). Read it and judge structural fit **against that**, never against a default: a project that declared `mirror-source` is not misplaced for mirroring its source tree. **Never infer the strategy from the tree** — that makes the audit circular (the shape the corpus has becomes the standard it is judged by) and, on a half-migrated corpus, judges it against the layout it is migrating away from. A map naming no strategy is judged against the **capability-first** default, and the missing declaration is itself a finding. **Read the map's routing table too, not only its strategy:** a node placed by an explicit routing-table row (the "concept of kind K lives in home H" taxonomy and its tie-breaks) is correctly placed even where the strategy's own derivation would put it elsewhere, so report a node misplaced only when it **neither** follows the declared strategy **nor** matches a routing-table row — judging on the strategy alone raises false findings against placements a human already adjudicated. A declared layout settles *where a node goes*; it never licenses a capability to scatter across nodes. (Strategy is policy — read it; homes are data — derive them.) **Depth on capability nodes; `design/` by its own shape** (`sdd:spec-structure-governance`). The two-level cap covers capability nodes: one three levels deep is a depth finding naming it, its sub-grouping owed to a `concept:` tag. `design/` is judged by its own shape instead — current design at the top, one file per perspective, the `decisions/` ADR log, and at most one version folder holding the next design. The placement map names that version folder and its cut trigger; the named folder and its files raise no finding, any other `design/` sub-folder besides `decisions/` is a perspective-folder finding, a named version with no cut trigger is a finding, and so is a named version whose folder does not exist (a stale record the cut left behind). Tell the two apart by the map, never by the folder's contents. ## The intra-spec structural acts It acts on each spec's **structure**, not its content — one project is **one spec**, so structural maintenance is **intra-spec**. A station is **not** a dependency — formation depends on the corpus structure and discovery (`corpus/` + `project-spec/`), not on any given station skill. | Act | Trigger | Station (`corpus/` + `project-spec/`) | Output | |---|---|---|---| | **Audit node-shape** | a formation pass fires post-mission | `check-spec-structure` | a finding set: untagged-node (blocking) + oversized-node (advisory), each naming the node | | **Split an oversized node** | the Warden's `@rubric` breadth-vs-depth judgment routes an oversized-node's shape profile to breadth-overflow | `check-spec-structure` | a sub-node split whose **organizing axis is first checked against a real capability/command boundary** (below); depth-overflow instead down-levels via the scenario→test bridge (`verify-scenarios`) or is redesigned — the engine emits only the profile, never the route | | **Reconcile drift / contradiction** | prose↔suite drift, or two nodes contradict | `align-spec` | a reconcile finding (drift fixed by direction; contradiction → align the losing side) | | **Dedupe cross-node scenario overlap** | the same behavior is specified in two nodes' suites — a hard collision the scenario rung cannot see (spec-level SSA) | `check-scenario-overlap` | a dedup finding naming both nodes; the Warden's `@rubric` arm confirms real overlap and **assigns a single owning node** (one behavior = one scenario in one node) | A node **within** the granularity heuristic raises **no** oversized finding; a concept-tagged node raises **no** untagged finding; nodes (or governances) that **agree** raise **no** reconcile finding; two nodes that specify **no** shared behavior raise **no** dedup finding. The acts are evidence-gated, not run unconditionally. **The split-axis check — validate the organizing axis, not just the granularity.** An oversized node is a **granularity** signal, but a split carves it along a proposed **organizing axis**, and the wrong axis produces a split CR that gets **superseded rather than landed** — a full formation cycle wasted. So before proposing a split (self-clearing it or escalating its CR), the Warden **checks the proposed axis against a real capability/command boundary**: each side must map to a **distinct capability, command, or lifecycle phase**, not merely to an **internal implementation grouping** that shares one boundary. - an axis where each side is a distinct capability/command boundary **passes** — the split is proposed on that axis; - an axis that only regroups internal implementation under one shared boundary **fails** — the Warden does **not** carve sub-nodes on it, and raises the oversize as a **wrong-axis reorganization** (the axis is wrong), not a granularity split to carve as-proposed. An oversize can be a symptom of the **wrong axis**, not just wrong granularity: turn "this node is too big" into "too big **along which axis** — and is that axis real?" Alongside its findings a pass surfaces an **advisory layout-quality signal** — the scheduler's **false-conflict rate** doubles as a **partition-quality metric**: a layout that keeps node↔folder clean holds the rate low, and one that scatters a single concern across folders drives it up. Read the signal **against the strategy the project declared** — a high rate under `mirror-source` means the source tree itself scatters the concern, which is a different finding from a capability-first spec drifting toward layers. But the rate measures the same thing either way: **node <-> capability alignment**, which the scheduler depends on and which no declaration suspends (ADR-0025). The signal is **advisory** — it **gates no mission**; it points the Warden and Council at a degrading partition so the **declared** layout can be re-asserted, or deliberately re-declared. **Measuring it, when a pass wants the number.** `sdd:check-partition-quality` computes this signal from the project's git history — the parallelizable share of change pairs under the declared layout, against a shuffled control, optionally compared with a candidate cut. **Opt-in**: it reads `git log`, so a pass runs it deliberately rather than every time, and its output is a measurement, never a verdict. Read its headline (the parallelizable share) and ignore its labelled diagnostics — both reward a coarser partition for being coarse. ## The Warden's self-clear-vs-escalate verdict The Warden is **rubric-subject**, exactly as the conductor is at a gate, and has **no direct user channel**. For **each structural act** it applies the full floor + gradient (the conductor's autonomy bar, `start-mission`) — the floor (**Clearance** for a narrowing act; **Compatibility** when the act's semver class exceeds the ceiling; **Conflict** for a contested reconciliation) plus the gradient (**blast** magnitude, **novelty**, **confidence**) — and renders its own verdict: - **Self-clear** the reversible, derivable, low-blast acts — a coverage-preserving split, a refactor or consistency fix. The Warden acts **in-session** and leaves a **provisional, agent-attributed marker** that is never final until the Council ratifies the trail; a Council reject unwinds it. - **Escalate** the narrowing, contested, or class-exceeding acts. The escalated finding re-enters as a **new CR** (`intake/`) naming the artifacts; it does not land until the Council ratifies. - **narrowing** — a reconcile or split that drops scenarios → **Clearance**; - **contested** — a reconciliation whose winning claim is contested → **Conflict**; - **class-exceeding** — a structural change whose semver class exceeds the ceiling → **Compatibility**; - a **destructive** act (it deprecates a node) → **escalates regardless** of contract-impact class. It is **not** true that every act is proposed-and-ratified: the reversible/derivable acts self-clear under the provisional marker; the narrowing/contested/class-exceeding ones emit a CR. ## Stations, not status — and the frozen-contract guard The Warden runs stations in-session and **never** writes a spec's `status`. The frozen-contract guard is keyed on **contract impact**, not the bare fact that a `.feature` is frozen: - a split that **preserves every scenario verbatim narrows nothing** — it self-clears **even on a frozen `.feature`**, leaving the provisional marker; no freeze re-open needed; - a split that **alters or drops scenario truth is a narrowing** — it shards a frozen contract only with a Council-ratified freeze re-open; - a **deprecating act is destructive** — it **escalates regardless** of contract-impact class. ## Altitude discipline — route, do not decide Formation owns corpus **structure** only and emits **no** out-of-loop decision: - a **build-or-deprecate** request → routed to `campaign/` (Product); it makes no build-or-deprecate decision itself; - a **process lesson** → routed to `doctrine/` (Process); it emits no process edit itself; - a **per-spec gate structural check** → **declined**; formation does not run as the gate check. Cross-capability outcome scenarios (a split or reconcile carried end-to-end) live in `../workflows/`; the loop and verdict behaviors are in `formation/formation.feature`.