cyber-sdd 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/.claude-plugin/plugin.json +17 -0
  2. package/.codex-plugin/plugin.json +17 -0
  3. package/.plugin/plugin.json +17 -0
  4. package/README.md +159 -0
  5. package/agents/sdd-automaton.md +97 -0
  6. package/agents/sdd-impl-judge.md +214 -0
  7. package/agents/sdd-scanner.md +120 -0
  8. package/agents/sdd-spec-judge.md +224 -0
  9. package/agents/sdd-warden.md +101 -0
  10. package/package.json +24 -0
  11. package/skills/align-spec/README.md +20 -0
  12. package/skills/align-spec/SKILL.md +111 -0
  13. package/skills/align-spec/scripts/align-spec.mts +187 -0
  14. package/skills/architect-impl-governance/README.md +46 -0
  15. package/skills/architect-impl-governance/SKILL.md +45 -0
  16. package/skills/architect-spec-governance/README.md +48 -0
  17. package/skills/architect-spec-governance/SKILL.md +59 -0
  18. package/skills/blast-estimate/README.md +47 -0
  19. package/skills/blast-estimate/SKILL.md +133 -0
  20. package/skills/blast-estimate/scripts/blast-estimate.mts +583 -0
  21. package/skills/builder-impl-governance/README.md +47 -0
  22. package/skills/builder-impl-governance/SKILL.md +47 -0
  23. package/skills/builder-spec-governance/README.md +49 -0
  24. package/skills/builder-spec-governance/SKILL.md +36 -0
  25. package/skills/check-partition-quality/README.md +22 -0
  26. package/skills/check-partition-quality/SKILL.md +51 -0
  27. package/skills/check-partition-quality/scripts/check-partition-quality.mts +336 -0
  28. package/skills/check-plan-safety/README.md +17 -0
  29. package/skills/check-plan-safety/SKILL.md +60 -0
  30. package/skills/check-plan-safety/scripts/check-plan-safety.mts +145 -0
  31. package/skills/check-project-specs/README.md +19 -0
  32. package/skills/check-project-specs/SKILL.md +69 -0
  33. package/skills/check-project-specs/scripts/check-project-specs.mts +217 -0
  34. package/skills/check-scenario-overlap/README.md +19 -0
  35. package/skills/check-scenario-overlap/SKILL.md +74 -0
  36. package/skills/check-scenario-overlap/scripts/check-scenario-overlap.mts +249 -0
  37. package/skills/check-spec-structure/README.md +17 -0
  38. package/skills/check-spec-structure/SKILL.md +66 -0
  39. package/skills/check-spec-structure/scripts/check-spec-structure.mts +346 -0
  40. package/skills/collision-ladder/README.md +18 -0
  41. package/skills/collision-ladder/SKILL.md +83 -0
  42. package/skills/collision-ladder/scripts/collision-ladder.mts +657 -0
  43. package/skills/combat-log-governance/README.md +13 -0
  44. package/skills/combat-log-governance/SKILL.md +257 -0
  45. package/skills/concept-index/README.md +13 -0
  46. package/skills/concept-index/SKILL.md +38 -0
  47. package/skills/concept-index/scripts/concept-index.mts +245 -0
  48. package/skills/discover-plans/README.md +16 -0
  49. package/skills/discover-plans/SKILL.md +74 -0
  50. package/skills/discover-plans/scripts/discover-plans.mts +212 -0
  51. package/skills/discover-specs/README.md +15 -0
  52. package/skills/discover-specs/SKILL.md +76 -0
  53. package/skills/discover-specs/scripts/discover-specs.mts +396 -0
  54. package/skills/doctrine-loop/README.md +15 -0
  55. package/skills/doctrine-loop/SKILL.md +97 -0
  56. package/skills/formation-loop/README.md +17 -0
  57. package/skills/formation-loop/SKILL.md +140 -0
  58. package/skills/gate-validation-governance/README.md +12 -0
  59. package/skills/gate-validation-governance/SKILL.md +87 -0
  60. package/skills/impl-producer-governance/README.md +48 -0
  61. package/skills/impl-producer-governance/SKILL.md +85 -0
  62. package/skills/init/README.md +27 -0
  63. package/skills/init/SKILL.md +68 -0
  64. package/skills/init/scripts/wire-statusline.mts +276 -0
  65. package/skills/lifecycle-governance/README.md +11 -0
  66. package/skills/lifecycle-governance/SKILL.md +168 -0
  67. package/skills/manage/README.md +9 -0
  68. package/skills/manage/SKILL.md +62 -0
  69. package/skills/manage-ignore/README.md +19 -0
  70. package/skills/manage-ignore/SKILL.md +52 -0
  71. package/skills/manage-ignore/scripts/manage-ignore.mts +294 -0
  72. package/skills/manage-scenario-bridge/README.md +20 -0
  73. package/skills/manage-scenario-bridge/SKILL.md +60 -0
  74. package/skills/manage-scenario-bridge/scripts/manage-scenario-bridge.mts +156 -0
  75. package/skills/manage-spec-anchors/README.md +18 -0
  76. package/skills/manage-spec-anchors/SKILL.md +56 -0
  77. package/skills/manage-spec-anchors/scripts/manage-spec-anchors.mts +328 -0
  78. package/skills/mission-graph/README.md +15 -0
  79. package/skills/mission-graph/SKILL.md +67 -0
  80. package/skills/mission-graph/scripts/mission-graph.mts +844 -0
  81. package/skills/oracle-spec-governance/README.md +45 -0
  82. package/skills/oracle-spec-governance/SKILL.md +45 -0
  83. package/skills/ownership-governance/README.md +65 -0
  84. package/skills/ownership-governance/SKILL.md +104 -0
  85. package/skills/pause-mission/README.md +18 -0
  86. package/skills/pause-mission/SKILL.md +112 -0
  87. package/skills/place-node/README.md +12 -0
  88. package/skills/place-node/SKILL.md +47 -0
  89. package/skills/place-node/scripts/place-node.mts +157 -0
  90. package/skills/plan-retirement/README.md +32 -0
  91. package/skills/plan-retirement/SKILL.md +90 -0
  92. package/skills/plan-retirement/scripts/retire-plans.mts +196 -0
  93. package/skills/plugin-contract-governance/README.md +12 -0
  94. package/skills/plugin-contract-governance/SKILL.md +112 -0
  95. package/skills/remediation-governance/README.md +46 -0
  96. package/skills/remediation-governance/SKILL.md +78 -0
  97. package/skills/resolve-governances/README.md +18 -0
  98. package/skills/resolve-governances/SKILL.md +50 -0
  99. package/skills/resolve-governances/scripts/resolve-governances.mts +515 -0
  100. package/skills/resolve-tracking/SKILL.md +64 -0
  101. package/skills/resolve-tracking/scripts/resolve-tracking.mts +213 -0
  102. package/skills/resume-mission/README.md +12 -0
  103. package/skills/resume-mission/SKILL.md +53 -0
  104. package/skills/scaffold-project-spec/README.md +7 -0
  105. package/skills/scaffold-project-spec/SKILL.md +192 -0
  106. package/skills/sdd/README.md +7 -0
  107. package/skills/sdd/SKILL.md +92 -0
  108. package/skills/solution-producer-governance/README.md +9 -0
  109. package/skills/solution-producer-governance/SKILL.md +44 -0
  110. package/skills/spec-format-governance/README.md +73 -0
  111. package/skills/spec-format-governance/SKILL.md +114 -0
  112. package/skills/spec-gate/README.md +26 -0
  113. package/skills/spec-gate/SKILL.md +201 -0
  114. package/skills/spec-gate/scripts/check-spec-state.mts +601 -0
  115. package/skills/spec-gate/scripts/check-suite.mts +501 -0
  116. package/skills/spec-gate/scripts/classify-edit-class.mts +411 -0
  117. package/skills/spec-producer-governance/README.md +7 -0
  118. package/skills/spec-producer-governance/SKILL.md +86 -0
  119. package/skills/spec-structure-governance/README.md +40 -0
  120. package/skills/spec-structure-governance/SKILL.md +169 -0
  121. package/skills/ssa-lowering/README.md +26 -0
  122. package/skills/ssa-lowering/SKILL.md +181 -0
  123. package/skills/start-mission/README.md +7 -0
  124. package/skills/start-mission/SKILL.md +115 -0
  125. package/skills/suite-format-governance/README.md +75 -0
  126. package/skills/suite-format-governance/SKILL.md +299 -0
  127. package/skills/suite-format-governance/references/rubric.md +313 -0
  128. package/skills/touch-set-correction/README.md +16 -0
  129. package/skills/touch-set-correction/SKILL.md +67 -0
  130. package/skills/touch-set-correction/scripts/touch-set-correction.mts +418 -0
  131. package/skills/verify-scenarios/README.md +17 -0
  132. package/skills/verify-scenarios/SKILL.md +109 -0
  133. package/skills/verify-scenarios/scripts/verify-scenarios.mts +386 -0
@@ -0,0 +1,169 @@
1
+ ---
2
+ name: spec-structure-governance
3
+ 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."
4
+ user-invocable: false
5
+ ---
6
+
7
+ # SDD Spec-Structure Governance
8
+
9
+ What kind of node a spec is, and **where that kind lives** in the project spec. This skill is the
10
+ canonical home consumers load instead of restating it — `scaffold-project-spec` when it lays a tree
11
+ out, `place-node` when it suggests a home, the formation **Warden** when it audits structure, and the
12
+ **architect** bars when they judge placement.
13
+
14
+ Taxonomy and placement are **one rule, not two**: the placement law is the taxonomy applied to
15
+ folders, and cannot be stated without it. A descriptive doc in `design/` is correct where a
16
+ behavioral node in the same folder is a defect — the folder alone does not say which.
17
+
18
+ The lifecycle a spec moves through is `sdd:lifecycle-governance`; a node's internal section shape is
19
+ `sdd:spec-format-governance`; how the suite is written is `sdd:suite-format-governance`.
20
+
21
+ ## The node taxonomy — three kinds, declared
22
+
23
+ | Kind | Subject | Owns a suite | Carries | Marker |
24
+ |---|---|---|---|---|
25
+ | **descriptive** | none | no | ordinary prose | *(none — the default)* |
26
+ | **reference artifact** | a real thing with no testable surface of its own | no, by design | `## Subject` in place of `## Use Cases` | `spec-type: reference` |
27
+ | **behavioral artifact** | a testable subject | **yes** | the node sections | `spec-type: behavioral` |
28
+
29
+ **Declared, never inferred.** The kind lives in frontmatter. Inference breaks both ways: a behavioral
30
+ node has no suite *yet* while it is being authored, and descriptive indexes live outside the rules
31
+ folder — so neither file-presence nor location classifies reliably. Declaring it up front makes an
32
+ unfinished behavioral node read as **incomplete** rather than as an index.
33
+
34
+ A **capability** is what the project *does*. The everyday word for one behavioral node is a **unit
35
+ spec**.
36
+
37
+ ## Placement — the taxonomy applied to folders
38
+
39
+ **Screaming architecture** is the default: top-level folders are named for **capabilities**, so the
40
+ folder names say what the project does. Three folders are deliberately *not* capabilities:
41
+
42
+ | Folder | Holds |
43
+ |---|---|
44
+ | `design/` | the **rules** — the model and the *why* (descriptive docs) |
45
+ | `workflows/` | the **usage** — how capabilities compose into whole flows (the project-level suite) |
46
+ | `ledger/` | the **provenance** — durable audit records; data, outside the node taxonomy |
47
+
48
+ **Rule-in-design, behavior-in-capability.** A rule and the behavior enacting it live apart: rules go
49
+ to `design/` as descriptive docs, the scenarios that enact them go to the capability folders as
50
+ behavioral specs, and a reference artifact is homed in the capability that owns it. This keeps
51
+ `design/` readable as a model while the capabilities stay testable as behavior.
52
+
53
+ **Root files, not folders.** Every mandated folder is an exception to screaming architecture, so the
54
+ mandated set stays minimal: anything that is one document lives as a **root file beside `spec.md`**.
55
+ `glossary.md` — the project's ubiquitous language, every load-bearing term defined once — is
56
+ required of every project spec.
57
+
58
+ **Two levels, never three.** A node is `<capability>/<unit>` and never sits three deep. A
59
+ sub-grouping inside a capability is a **cross-cutting concern**, so it is expressed as a `concept:`
60
+ tag and recovered through the generated by-concept index — never as a third folder level.
61
+
62
+ **The concept axis.** The tree can privilege only one axis, and it privileges capability; a concern
63
+ enacted across several capabilities is declared in `concept:` frontmatter and navigated through the
64
+ index instead.
65
+
66
+ **Suite organization.** Unit suites **colocate** with their capability node, one per unit. The
67
+ project-level suite lives in `workflows/`, where a **workflow** is the project-level analogue of a
68
+ use case — a path through the composed capabilities.
69
+
70
+ ## One spec per project
71
+
72
+ A **project** is the unit a spec maps to — a repo harness, an agent plugin, an npm package, a
73
+ website, or one package inside a monorepo. Each has exactly **one** spec: one `spec.md`, one suite,
74
+ one gate/freeze baseline. Growth is absorbed by **adding folders**, never by splitting into sibling
75
+ specs — splitting fragments the lifecycle, so one change touching three areas would re-open three
76
+ frozen specs and pay three approvals.
77
+
78
+ **Colocate by default**, nested projects included. **Hoist only when the spec cannot be kept out of
79
+ what ships** — the project dir is copied **wholesale**, with no include/exclude mechanism to leave
80
+ the spec behind. The one identified case is an **agentic plugin**: plugin install copies the whole
81
+ directory, so a colocated spec would reach every consumer. An npm package colocates — its `files` /
82
+ ignore list excludes the spec from the tarball. **Nesting is never the reason**; if a new packaging
83
+ format has the same all-or-nothing copy, it joins the hoisting case.
84
+
85
+ ## Strategy is policy; homes are data
86
+
87
+ Screaming architecture is the **default**, not the only layout. Whichever layout a project uses is a
88
+ **choice**, and choices are declared. But the choices are **not equals** — see the partition stake
89
+ below; declaring a layout does not license breaking node<->capability alignment.
90
+
91
+ - **The strategy** (`capability-first`, `mirror-source`, …) is **declared** in the root `spec.md`
92
+ **placement map** and **read**. Never derive it from the tree: a greenfield project has no tree yet
93
+ and still has a strategy; deriving it from a healthy tree is circular (it launders a past decision
94
+ as an observation); and on a half-migrated tree it perpetuates the layout being migrated *away*
95
+ from.
96
+ - **The homes** — which folder a given concept's node sits in — are **facts** about the current tree,
97
+ derived from `concept:` tags. A stored home list is a second source that rots, so homes are never
98
+ stored.
99
+ - **They compose:** the declared strategy **parameterizes the derivation**. Keep deriving homes, but
100
+ ask the placement map *which* derivation to run.
101
+
102
+ **The placement map has two parts, and a placement judgment must consult both.** Beside the declared
103
+ strategy it carries a **routing table** — the maintained "a concept of kind K lives in home H"
104
+ taxonomy plus the human **tie-break** rows for genuinely contested overlaps. The table records
105
+ decisions the strategy alone does not settle, so a node placed by an explicit routing-table row is
106
+ **correctly placed even when it does not match the strategy's derivation**. Judging misplacement on
107
+ the strategy alone therefore reports false findings against exactly the placements a human already
108
+ adjudicated. The test is a disjunction: a node is misplaced only when it **neither** follows the
109
+ declared strategy **nor** matches a routing-table row.
110
+
111
+ This is the same split the corpus-discovery rule already makes — fixed conventions are scanned,
112
+ while an off-convention anchor list is declared and curated. "No drift" means *do not store what you
113
+ can observe*, never *do not declare a choice*.
114
+
115
+ ### The partition stake — why capability-first is more than a preference
116
+
117
+ Capability-first is the partition the **mission scheduler** depends on. One mission owns one
118
+ spec-node, so when **node <-> capability is 1:1** a change touches one node and its collisions are
119
+ legible; missions run in parallel. A **layered / framework-first top level scatters one capability
120
+ across many folders** — the mapping breaks, a single behavior smears across nodes, collisions
121
+ explode, and the schedule degrades toward **serial** (ADR-0025).
122
+
123
+ So layouts are ranked by whether they preserve that alignment, not by taste:
124
+
125
+ - **capability-first** — aligned by construction; the recommendation.
126
+ - **mirror-source** — inherits whatever alignment the source has. Best case is a feature-first
127
+ source, which is already capability-aligned; over a layered source it is **still offered**, with
128
+ the cost named (below).
129
+ - **layered / framework-first as the *top* level** — **discouraged** as a *chosen* layout for a
130
+ project free to choose, and a declaration does not rescue it. Layering survives *nested inside* a
131
+ capability.
132
+
133
+ The invariant that holds under **every** strategy: **one capability per node, never smeared across
134
+ nodes**. A declared layout says where a node goes; it never licenses a capability to scatter. The
135
+ scheduler's **false-conflict rate** is the standing metric of the partition's quality.
136
+
137
+ ### A coarse partition costs precision, not correctness
138
+
139
+ This is why an imperfect layout is workable rather than disqualifying. The scheduler is
140
+ **conservative** — a collision it cannot resolve **serializes** — so the worst case of a poor
141
+ partition is a **slower schedule, never a corrupted one**. Three mechanisms recover most of the loss:
142
+
143
+ - **The collision ladder descends below the node** — file, region, semantic, symbol — so two missions
144
+ sharing a node but touching different symbols classify **soft** and still co-wave. The residue is
145
+ `symbol-rung-deferred`: symbols that cannot be inferred stay hard.
146
+ - **Worktrees** dissolve file-level false dependencies until write-back.
147
+ - **The concept axis** carries the capability view the folders do not: in a mirrored tree the folders
148
+ name source areas while `concept:` tags still name capabilities.
149
+
150
+ **Adoption over purity.** Demanding a restructuring before a project may hold its first spec is an
151
+ entry toll, and an unadopted tool partitions nothing. A project adopts on the shape it has,
152
+ accumulates `concept:` tags as it writes nodes, and **hoists one capability at a time when the
153
+ false-conflict rate earns the move** — a concept spanning many nodes being the measured signal that a
154
+ capability wants its own home. Capability-first is the **destination**, reached on evidence, not the
155
+ entry condition.
156
+
157
+ ## Key points (read-check)
158
+
159
+ 1. **Three kinds, declared** — descriptive / reference (`## Subject`, no suite) / behavioral (owns a
160
+ suite); never inferred from files or location.
161
+ 2. **Placement is the taxonomy applied to folders** — rules to `design/`, behavior to the capability
162
+ folder, reference artifacts to the capability that owns them.
163
+ 3. **Screaming architecture** with three non-capability folders (`design/`, `workflows/`, `ledger/`)
164
+ and **root files, not folders**, for single documents (`glossary.md` required).
165
+ 4. **Two levels, never three** — deeper sub-grouping is a `concept:` tag, not a folder.
166
+ 5. **One spec per project**; colocate by default and **hoist only when the spec cannot be kept out of
167
+ what ships** (the agentic plugin) — nesting is never the reason.
168
+ 6. **Strategy is policy, homes are data** — read the declared strategy from the placement map, derive
169
+ homes from `concept:` tags, and let the strategy pick the derivation.
@@ -0,0 +1,26 @@
1
+ # ssa-lowering
2
+
3
+ The reasoning **front-end** of the CR→mission compiler — the doctrine the conductor runs during
4
+ intake/Explore to lower one-or-more change requests into a partitioned set of Missions (SSA: **one
5
+ owning Mission per spec-node**). It applies the **Oracle** lens (should we do this at all?) and the
6
+ **Architect** lens (where does each piece belong, is it a barrier?), resolves same-node contention into
7
+ ordered **versioned-RAW** edges, and lowers only the **frontier** deeply.
8
+
9
+ It sits **above** the shipped deterministic back-end and cites it, never re-implements it: the
10
+ [`mission-graph`](../mission-graph/SKILL.md) store records the partition, the
11
+ [`collision-ladder`](../collision-ladder/SKILL.md) classifies node collisions, and
12
+ [`touch-set-correction`](../touch-set-correction/SKILL.md) reconciles declared touch-sets against real
13
+ diffs. It **decides** the cut; it does not build, store, classify, or automatically emit its
14
+ decision-evidence (SQ-F5 #194, deferred).
15
+
16
+ Built for the Op2 ★ capstone of the cyberfleet-batch change request (GitHub issue #189, the reasoning
17
+ front-end above the shipped deterministic back-end); see
18
+ [`.agents/specs/sdd/ssa-lowering/README.md`](../../../../.agents/specs/sdd/ssa-lowering/README.md) for
19
+ the authoritative behavior description and
20
+ [`ssa-lowering.feature`](../../../../.agents/specs/sdd/ssa-lowering/ssa-lowering.feature) for the frozen
21
+ behavior suite.
22
+
23
+ This is a **doctrine, not an engine** — it emits no `.mts`, computes nothing deterministically, and holds
24
+ no state. Working node name only (SQ-name #195).
25
+
26
+ - **Skill contract:** [`SKILL.md`](./SKILL.md)
@@ -0,0 +1,181 @@
1
+ ---
2
+ name: ssa-lowering
3
+ description: "Internal skill: the reasoning front-end that lowers one-or-more change requests into a partitioned set of Missions — one owning Mission per spec-node (SSA) — applying the Oracle (should we?) and Architect (where/barrier?) lenses, resolving same-node contention into ordered versioned-RAW edges, and lowering only the frontier deeply; run by the conductor during intake/Explore, not triggered by users directly."
4
+ user-invocable: false
5
+ metadata:
6
+ internal: true
7
+ ---
8
+
9
+ # SSA-Lowering Doctrine
10
+
11
+ The reasoning **front-end** of the CR→mission compiler. Given one-or-more change requests, it decides
12
+ **the cut**: how to partition their combined **write-set** into a set of **Missions** — targeting SSA,
13
+ **exactly one owning Mission per spec-node** — plus the RAW/parent-child edges, per-Mission touch-sets,
14
+ and provenance that the deterministic back-end then records and classifies.
15
+
16
+ It sits **above** the shipped deterministic machinery and cites it, never re-implements it:
17
+ - the [`mission-graph`](../mission-graph/SKILL.md) store **records** the partition (nodes, edges, status);
18
+ - the [`collision-ladder`](../collision-ladder/SKILL.md) **classifies** a known node collision hard/soft;
19
+ - [`touch-set-correction`](../touch-set-correction/SKILL.md) **reconciles** a declared touch-set against the real diff.
20
+
21
+ This doctrine **decides** what to record; it does not build the Missions (the mission loop does), store
22
+ them, classify collisions, or **automatically emit** its decision-evidence (SQ-F5 #194, deferred — in v1
23
+ you record the shown-work **by hand**). Working node name only (SQ-name #195).
24
+
25
+ Its output is a **judgment call**, not a pure function. Two SDD actor lenses are pulled forward into
26
+ planning and applied with **strong weight** — judgment first, mechanics second.
27
+
28
+ ## When to run
29
+
30
+ **Routing guidance for the caller** — the conductor deciding what to send here. It is **not a
31
+ self-refusal gate**. Once this doctrine is invoked it **always runs step 1 (the Oracle lens)** and
32
+ never exits without a verdict: step 1 judges legitimacy *before* partitioning, so "there is nothing
33
+ to partition" cannot gate it.
34
+
35
+ Route a change request here when it must be **cut into Missions** during intake/Explore:
36
+ - a CR spanning multiple capabilities must be decomposed into Missions;
37
+ - two-or-more open CRs overlap on a shared capability and must be **regrouped** into Missions;
38
+ - a **far-horizon** CR has reached the frontier and must be lowered (re-validate it — never trust the filing-time verdict);
39
+ - a CR describes a **project-wide** change (rename/refactor) that must be planned as fleet work (barrier).
40
+
41
+ These have nothing to partition, so routing them here buys nothing:
42
+ - a single-capability change to one artifact-type → straight to the mission loop;
43
+ - adding one scenario to an existing feature file within one node;
44
+ - running `ready`/`cycles` over the mission-graph store (that is a query);
45
+ - classifying an already-detected node collision (that is `collision-ladder`).
46
+
47
+ **Invoked anyway on one of those, do not refuse.** Run step 1, record the Oracle verdict, and emit
48
+ whatever the cut yields — for a single-capability CR that is one Mission, or **zero** if the Oracle
49
+ kills it. Refusing drops the legitimacy judgment, which is the cheapest judgment to make here and the
50
+ most expensive to skip. Note the standing gap this leaves: a CR routed straight to the mission loop is
51
+ Oracle-vetted by nothing until the intake-vet automation lands (#196).
52
+
53
+ ## Procedure
54
+
55
+ Work the steps in order. **Record the shown-work as you go** (see "Decision-evidence") — the produced
56
+ partition is not complete without it, and until SQ-F5 lands nothing emits it for you.
57
+
58
+ ### 1 — Oracle lens: judge legitimacy before lowering (kill-or-reshape up front)
59
+
60
+ Before partitioning anything, decide whether the CR should be done **at all**. Lowering dead work is the
61
+ most expensive mistake; killing it here is the cheapest flush (nothing is lowered).
62
+
63
+ - **Stale** — a better solution has **shipped since the CR was filed**, so its goal is already covered
64
+ (e.g. a CR to add mailer retry after the mailer was replaced by an auto-retrying queue). Recognize the
65
+ supersession; **kill or reshape** the CR to only what remains uncovered.
66
+ - **Misaligned** — nothing supersedes it and it is technically doable, but it fits the **product
67
+ direction** poorly (e.g. a per-user telemetry tracker against an explicitly zero-telemetry, local-only
68
+ product). Judge it on **direction-fit**, not on being superseded; **reshape toward the direction or
69
+ kill** it up front. Do not mistake misalignment for staleness — they are different verdicts.
70
+ - **A killed CR lowers to ZERO Missions.** The produced partition contains **no** Missions — in
71
+ particular no Mission that builds the superseded/off-direction work.
72
+ - **Re-check monadically.** A far-horizon CR judged legitimate at filing can go **stale** while parked.
73
+ When it reaches the frontier, **re-run the Oracle check** against the *current* ground; the re-confirm
74
+ or newly-kill verdict must reflect the shifted state, not the stale filing verdict.
75
+
76
+ Record the legitimacy verdict (ship / reshape / kill + why) as shown-work.
77
+
78
+ ### 2 — Architect lens: placement and barrier detection
79
+
80
+ For each surviving CR, decide **where each piece belongs** and whether it is a barrier.
81
+
82
+ - **Placement.** Each distinct capability lands in its **own spec-node**, placed under the layout the
83
+ project **declared** in its placement map (`sdd:spec-structure-governance` — the rule lives there;
84
+ this bar only requires one node per capability). Two unrelated new
85
+ capabilities in one CR (e.g. a rate-limiter and an audit-log) go to **separate** nodes; do not fuse
86
+ unrelated capabilities into one Mission.
87
+ - **Barrier detection.** A **project-wide** change — an architecture refactor, a rename of a core type
88
+ used across every capability — **owns no single node**; it cross-cuts most of the project and would
89
+ WAW-conflict with almost everything. Mark it a **barrier**:
90
+ - it is **not** modeled as one node-owning Mission among peers;
91
+ - **hoist it early** — schedule it before the feature Missions that would rebase onto it;
92
+ - **nothing else starts before the barrier retires**; the fleet **rebases onto the new world** after
93
+ the fence, then fans out.
94
+
95
+ Record the placement decisions and any barrier verdict (with its fence reasoning) as shown-work.
96
+
97
+ ### 3 — The SSA cut: one owning Mission per spec-node
98
+
99
+ Partition the combined write-set toward SSA.
100
+
101
+ - **Single-writer.** Every spec-node the write-set touches is assigned to **exactly one** owning Mission.
102
+ No spec-node is assigned to two Missions at once. A **new** node is single-writer by construction;
103
+ contention only arises on an **existing shared** node (step 4).
104
+ - **Cohesion — do not over-split.** Tightly-coupled work within one node that cannot be verified apart
105
+ stays in **one cohesive Mission**, verifiable as a unit. Do not scatter a node into thin fragments
106
+ across Missions. (The one node still has exactly one owning Mission.)
107
+ - **Regroup by ownership, across CR boundaries.** Cut Missions by **ownership of nodes, not by
108
+ originating CR** — so N CRs produce M Missions, not one-per-CR. When two CRs both touch a shared
109
+ node, **one** Mission owns that node drawing on **both** CRs (not one Mission per CR splitting the
110
+ node).
111
+ - **Provenance + local ref.** Each Mission **records its originating CR(s) as provenance**, and carries a
112
+ **locally-minted mission-ref** (the mission-graph node id) — **not** a tracker ticket ref. The tracker
113
+ speaks intent; a Mission is a local decomposition of it.
114
+
115
+ ### 4 — Resolve same-node contention by versioning it into an ordered dependency
116
+
117
+ When two concerns both need to write the **same** existing node, do not emit two concurrent writers.
118
+
119
+ - **Order can be imposed** (one concern can sensibly go first, the other rebases/reworks onto its
120
+ result): **version it** — do-first concern A, then rework-second concern B — and emit a **RAW edge**
121
+ A → B. The partition then contains **no two Missions writing that node concurrently**; it contains the
122
+ RAW edge ordering the second after the first. **Do not** call an order-imposable contention an
123
+ irreducible hard collision.
124
+ - **Order-less concurrent co-write** (both must write the node and no order avoids rework either way):
125
+ leave it an **irreducible hard** collision. Recognize that no clean order exists (a versioned-RAW would
126
+ not resolve it); **serialize** the two writes (do not start them concurrently); and **flag** that the
127
+ second write needs real **rework**, not a clean replay, because the first moved the ground.
128
+ - The coarser the atom, the more a same-node clash biases to serial. Emit the RAW / hard-collision
129
+ annotation for the back-end; the [`collision-ladder`](../collision-ladder/SKILL.md) — not this doctrine
130
+ — later descends the finer grains to justify any hard→soft downgrade.
131
+
132
+ ### 5 — Lower lazily (monadic) and default conservative-first
133
+
134
+ - **Deeply lower only the frontier.** Cut the near-term frontier into concrete, verifiable Missions.
135
+ Leave the fuzzy far horizon as **coarse Operations**, not prematurely partitioned Missions —
136
+ **commit near, speculate far**; commitment decays with distance. Do not schedule the far horizon.
137
+ - **Conservative-first on low confidence.** When two Missions' predicted touch-sets overlap on a node
138
+ and the overlap is only **partially known** with no finer evidence of disjointness, treat the unproven
139
+ overlap as a **hard** collision and **serialize**. Do not optimistically parallelize on a guess. Note
140
+ that it would **relax to parallel only** when finer evidence (via the collision-ladder) proves the
141
+ writes disjoint.
142
+ - **Never fabricate a dependency.** When the write-set is a set of genuinely **independent** spec-nodes
143
+ with no shared writes, emit **no RAW or collision edge** between those Missions — let them run in
144
+ **parallel**. Conservative-first applies to *unproven overlap*, not to proven independence.
145
+
146
+ ### 6 — Emit the partition (do not re-implement the back-end)
147
+
148
+ Emit, for the deterministic back-end to consume:
149
+ - the **Missions** (each owning its spec-node(s), with its per-Mission touch-set);
150
+ - the **RAW / parent-child edges** and any barrier fence;
151
+ - each Mission's **provenance** (originating CR(s)) and **locally-minted ref**;
152
+ - the hard-collision / order annotations.
153
+
154
+ The [`mission-graph`](../mission-graph/SKILL.md) store **records** it; the
155
+ [`collision-ladder`](../collision-ladder/SKILL.md) **classifies** node collisions; do **not** re-derive
156
+ `ready`/`cycles`, re-detect collisions, or re-classify grains here. Record the decision-evidence **by
157
+ hand** (SQ-F5 #194 automation is deferred).
158
+
159
+ ## Decision-evidence (record by hand — v1)
160
+
161
+ The record **accompanies the produced partition** — the partition is incomplete without it. Record:
162
+ - **Sources** — the CRs, specs, and shipped changes the cut drew on.
163
+ - **Oracle verdict** — per CR: ship / reshape / kill, and why (staleness vs misalignment vs
164
+ frontier re-validation).
165
+ - **Architect verdict** — node placements and any barrier: the fence/rebase reasoning, and the
166
+ sequencing it implies — that the fleet rebases onto the new world after the fence, then fans out.
167
+ - **Cut decisions** — why each Mission owns its node(s), each RAW/versioning choice (do-first vs
168
+ rework-second), each irreducible-hard call, and each conservative-vs-parallel default.
169
+
170
+ This record must be **in view alongside the partition** when the cut is reviewed or judged; nothing
171
+ emits it automatically until SQ-F5 lands.
172
+
173
+ ## Boundaries
174
+
175
+ - **Decides the cut only.** Does not build Missions (mission loop), record the plan
176
+ ([`mission-graph`](../mission-graph/SKILL.md)), classify a collision at a finer grain
177
+ ([`collision-ladder`](../collision-ladder/SKILL.md)), reconcile a touch-set against a diff
178
+ ([`touch-set-correction`](../touch-set-correction/SKILL.md)), spawn worktrees, or gate.
179
+ - **Out of scope (cite, never build here):** the SQ-F5 decision-evidence **emit** automation (#194); the
180
+ capability/engine **name** finalization (#195 — keep the working name `ssa-lowering`); the
181
+ Oracle/Architect **intake-vet** automation (#196). Do not rename or rebuild the shipped back-end.
@@ -0,0 +1,7 @@
1
+ # start-mission
2
+
3
+ The single user-facing entry for **changing an SDD project** — triggered by a general change request ("add a start-mission skill to sdd", "implement the auth capability", "work on `<github issue url>`"). User-invocable: opens a **change request** against the one durable project spec and runs the **mission loop** (intake → explore → deliver → handoff) over it.
4
+
5
+ The session that runs this skill **is the conductor** — the in-session realization of the conductor role; the headless realization is the `automaton` agent. A third realization is **in-session plan-mode preview**: when Claude Code plan mode is active, explore runs its reasoning (classify, seed-intent grill, draft the spec + scenario list, cold spec-judge) but writes no repo files — it renders the drafted spec + suite into the plan file and ends at **ExitPlanMode**, dropping the build-to-learn spikes. On approval the next real explore adopts the preview as the settled draft. Plan mode is detected **in-body**, never via the trigger `description`, so it never re-fires per turn. It supersedes the retired spec-as-mission entries (`create-spec` / `revise-spec`): adding, revising, or deduping part of the project spec is now an **explore-phase operation inside a CR**, not a top-level mission.
6
+
7
+ Bakes in: step-1 intake (recover the request or fetch an issue URL; scaffold the `.plan.md`); explore as the live grill (classify spec-type + artifact-types, scaffold the node, seed-intent Q&A, the inline spec-producer + cold spec-judge loop with build-to-learn spikes, the iteration cap, the **freeze re-open guard**, observation routing); the internal spec gate (freeze + per-CR gate line to the conductor's own `ledger/` shard + `status: approved`); deliver (spawned impl-producer builder + the internal impl gate); handoff; and the baked autonomy bar (initial strategy, per-gate verdicts, the three hard floors). Pairs with `pause-mission` / `resume-mission`.
@@ -0,0 +1,115 @@
1
+ ---
2
+ name: start-mission
3
+ description: Use this skill to make a change to an SDD project — triggered by a general change request like "add a start-mission skill to sdd", "implement the auth capability", "revise the gateway spec", or "work on <github issue url>". Opens a change request against the durable project spec and runs the mission loop (explore → deliver → handoff).
4
+ ---
5
+
6
+ # start-mission
7
+
8
+ The single user-facing entry for **changing an SDD project**. It opens a **change request (CR)** against the one durable project spec (`.agents/specs/<project>/`) and runs the **mission loop** over it. The session that runs this skill **is the conductor** — the user in the driver's seat, holding the user channel, grilling live, ratifying in-session. This skill is the **in-session realization of the conductor role** (the `automaton` agent is the headless realization for an unattended scheduler or a multi-CR fan-out).
9
+
10
+ **Three realizations of the conductor.** *In-session interactive* (default — the grill loop below); *in-session **plan-mode preview*** (Step 2 runs the preview branch — reasoning only, renders the drafted spec + suite into the plan file, ends at **ExitPlanMode**); *headless `automaton`* (unattended). The plan-mode branch is detected **in-body** from the harness plan-mode signal (only the plan file is writable) — **never** from the `description`, so a mission triggers on change-intent alone (plan mode or not) and never re-fires per turn: the branch is a fork inside an already-loaded explore phase, not a trigger.
11
+
12
+ A CR is the **unit of change-intent** (git-PR-shaped); the mission loop is the workflow that carries it. Whether the CR **adds** a capability, **revises** behavior, or **reconciles** overlap is decided during **explore** — not by a separate entry skill. A request with **no suite-relevant behavior** is **not a CR** and escapes the lifecycle (leave no SDD record).
13
+
14
+ > **Advise a capable model (e.g. Opus) on entry.** The explore grill runs in this session, so its quality tracks the session model. Surface this **before** the grill so the user can switch if needed. (The harness cannot switch the session model on your behalf.)
15
+
16
+ Load `sdd:lifecycle-governance` (status enum, the freeze re-open transition), `sdd:ownership-governance` (who writes each field), `sdd:spec-format-governance` + `sdd:suite-format-governance` (the node skeleton + suite bars), `sdd:spec-producer-governance` (the grilling procedure run inline), `sdd:impl-producer-governance` (what the spawned builder loads), `sdd:gate-validation-governance` (legal gate-state tuples), `sdd:remediation-governance` (how a producer answers a `change` verdict at either gate), and `sdd:combat-log-governance` (the provenance shapes). The autonomy bar is baked in (below).
17
+
18
+ ## Step 1 — intake: open the CR and scaffold the plan
19
+
20
+ Get the CR into the system and create its plan brief — the plan is a step-1 artifact, not something explore invents later.
21
+
22
+ - **Recover the request.** From a general change prompt, name the change and the target. From a **source URL** (`work on <github issue url>`), fetch the issue and read it as the CR body.
23
+ - **Locate the project spec** by running the **`discover-specs`** skill (the `corpus/discovery` engine) — it returns the TOON list of every project spec at the SDD spec locations (the three fixed conventions plus any declared extra anchors, ADR-0019) with its `status` and `project-path`. Resolve the CR's target to one spec by folder slug or `project-path`; an ambiguous match is disambiguated with the user, never guessed. One project is one spec — there is no spec fleet to pick from. If `discover-specs` finds **no** spec for the target project, that is the **backfill** path (load `scaffold-project-spec`).
24
+ - **Scaffold `.agents/plans/<cr-ref>-<what>.plan.md`** — name the brief with a short kebab `<what>` slug naming what the CR does, even when the ref comes from an external source (`github-34-rejudge-sweep.plan.md`, not `github-34.plan.md`). The source name (`github`) is **optional** — most projects draw from one external source, so a bare `34-rejudge-sweep.plan.md` is fine; keep the source prefix only when a project mixes sources. Fill from a basic template: frontmatter `todos` (ordered, `status: pending`, each `content` a **short summary < 120 chars**) + a `## NEXT` anchor + the CR link. Keep the plan body **concise** — it is read by the agent each resume, so phrase for an agent first while staying human-legible (terse lead, no prose padding). This is the portable handoff brief `pause-mission` / `resume-mission` operate on. **Safe-to-publish floor** (the same one the combat log carries in `combat-log-governance`): the brief is **tracked and committed**, so it references **only repo-relative paths** — never an absolute path, `$HOME`/`$USER`, an OS username, or any machine-local location outside the repo. When the CR's design came from a plan-mode doc under a machine-local path (e.g. `~/.claude/plans/…`), bring that content **into** the repo (a sibling `<cr-ref>.design.md` beside the brief) and reference it repo-relative — do not link the external absolute path. The `check-plan-safety` engine enforces this mechanically. **When that brought-in content is a plan-mode preview** (a drafted spec + scenario list from a prior `### Plan-mode preview` run), the explore phase **adopts it as the settled draft** (see Step 2) rather than re-grilling from scratch.
25
+ - **Escape a non-CR.** If the grill shows no suite-relevant behavior, escape: create no draft, invoke no gate, write no record. Independently, **escape by tracking**: for each artifact the request touches, run the **`resolve-tracking`** skill (`intake/resolve-tracking`'s concrete engine) — `node "<skill>/scripts/resolve-tracking.mts" --root . --path <path> [--artifact-type <type>] [--explicit tracked|ignored]`, passing `--explicit` when the requester stated tracking directly and `--artifact-type` when convention already makes it obvious. If **every** touched artifact resolves `ignored`, escape the whole request the same way. If the request is **mixed**, carve the tracked artifacts into the CR and escape the ignored ones (the same carve-and-escape shape already used for the no-behavior case). Escaping does not mean stopping: if the artifact-type has a producer with an escaped-request entry point (`define-skill` for `skill`), invoke it directly to do the work; only state "leaving the lifecycle" and stop when no such producer exists.
26
+
27
+ ## Step 2 — explore: grill the spec + suite, build to learn
28
+
29
+ Run authoring **in-session** as the conductor. Explore **builds the implementation to learn** (build-to-learn) — implementation is not deferred to deliver; the freeze is the boundary. The phase ends at the **spec gate**.
30
+
31
+ **Mission statusline (opt-in).** On entering explore, overwrite `.agents/sdd/statusline` with `explore` — a single-line, best-effort write; a missing file / no `init`-wired reader is not an error, just skip it. This is the runtime status **value**, distinct from the lifecycle `status` frontmatter field, and is written **only while a mission is in flight** (never at rest, no heartbeat). Skip this write during the **Plan-mode preview** branch below — it writes no repo files at all.
32
+
33
+ **If plan mode is active, run the `### Plan-mode preview` (end of this step) instead of the live grill loop** — same reasoning, no repo writes, no build-to-learn spikes; the phase ends at **ExitPlanMode**, not the spec gate.
34
+
35
+ **Resolution first.** Run `resolve-governances` over **only** the project registry `.agents/universal-plugin.json` (never scan plugin dirs), passing the current project's anchors (`--project`, plus `--project-root` in a monorepo — you know the project from `discover-specs` / context). For **each touched file's** `artifact-type` it names each production-chain role's agent (a plugin delegate or the SDD default) plus the resolved-actor bar **candidates bucketed by tier** (`project` / `project-root` / `plugin` / `sdd`). It does **not** compose — **load each candidate and compose them yourself** by precedence `sdd-default < plugin < project-root < project` (most-specific wins on conflict; a governance's own `compose: replace` supersedes its bar's lower-precedence candidates); the fixed-universal governances are loaded from the role/agent definition (the matcher does not emit them) — their **names** up front as a compact digest, each **body lazily** only at the gate/decision that invokes it (`gate-validation`/`lifecycle` at a gate, `suite-format` when authoring a `.feature`; `sdd` governance-resolution), so a one-line change never reads all six. A required role with no real delegate **fails closed**. A **resolved** delegate that **recuses** from a subject (produces nothing, declaring it outside its domain — e.g. a plugin bound by artifact-type meets a subject its lens does not fit) is **not** a fail-closed: **re-resolve that one unit's chain to the SDD defaults** (default producer + SDD-default bars + judge) and proceed, recording the recusal as a combat-log line (never a halt); other units keep their squad (`sdd:lifecycle-governance`). A domain claimed by two plugins → ask (answered live in-session).
36
+
37
+ For each unit the CR touches:
38
+
39
+ - **Locate or place the node — provisionally.** If a `spec.md` / `README.md` already exists at the target → this is a **revise** (no scaffolding). Otherwise **scaffold** a new node and drop it in a *plausible* home **under the layout the project declared** in its root `spec.md` placement map — `capability-first` groups by what the project *does*, `mirror-source` mirrors the source tree. Placement is judged *within* that declaration, never against a preferred one (`sdd:spec-structure-governance`, "strategy is policy, homes are data"); where no strategy is declared, the `capability-first` default applies. A layered / framework-first **top level** stays discouraged under every strategy (it scatters a capability across folders, breaking node↔folder and degrading scheduling). Consult `project-spec/place-node` (`--concept` → candidate homes; `--name` → "belongs near X" duplicate-catch) and the placement-map routing table (root `spec.md`) for contested overlaps, but **do not agonize**: placement is **provisional** and finalized cheaply at **handoff** (step 4), where a scoped Warden pass relocates it to its blessed home *in the same change* (a pure rename — freeze survives, `sdd:lifecycle-governance`). If the user named no capability, propose a capability folder from the CR and confirm.
40
+ - **Classify the node** (declared, never inferred): `spec-type: behavioral` (a testable unit → `## Use Cases` + a `<unit>.feature`), `reference` (a shipped non-testable artifact → `## Subject`, no `.feature`), or **descriptive** (an index → no marker). Tag the node's cross-cutting **`concept:`** (the concern it serves — e.g. `lifecycle` / `resolution`; a string or list, orthogonal to `spec-type`; it feeds `project-spec/concept-index`). Also classify each touched file's **artifact-type** (the squad key — resolved per file, **not stored**): **by convention first** (`skill` under `skills/`, `subagent` under `agents/`, …; the extension never decides). On a genuine **ambiguity or a user-flagged path**, consult and record the tiebreaker map `.agents/sdd/artifact-types.toml` and **confirm — never guess** (`sdd:artifact-type` model).
41
+ - **Scaffold the skeleton** per `sdd:spec-format-governance` (sections per type; `.feature` form per `sdd:suite-format-governance`). Write **no** control frontmatter (`status` / `project-path` / `approval` / `produced-by`) — those live on the root `spec.md` and belong to the conductor and the gate.
42
+ - **Collect seed intent.** For a **new** feature, ask 3–5 targeted questions (the core problem and who has it; observable behavior; the public interface; edge cases / non-goals; reviewers who must be heard). For **backfill** (behavior already in code), skip — the producer reads source, tests, history. For a **revise**, collect what changes and why and the parts it touches.
43
+
44
+ **The grill loop (the user loop).** You are the conductor. Run the spec-producer **inline** (load `sdd:spec-producer-governance`, or persona-load a plugin specialist for the `artifact-types`), **dispatch the cold spec-judge** each round — through the dispatch capability's intent seam when one is available (preferring its **warm** unit, context-cleared fresh via `npx cyberlegion@<version> unit clear <ref>` before each round's judgment), else a portable cold subagent — and for build-to-learn **dispatch the impl-producer builder** the same way (its warm unit **keeps** its context across spikes; no reset) in `explore` mode against the **non-frozen** suite — spikes are thrown away; their learnings feed the live grill to steer the spec + suite. Set an **iteration cap** (default **3**; honor a user-named cap), then loop:
45
+
46
+ **Governance provenance relay.** When you dispatch the cold spec-judge, forward the inline spec-producer's declared `governances_loaded` (`sdd:spec-producer-governance`) verbatim through the same dispatch channel, keyed **`producer_governances_declared`** — a brief field when the judge is a cold subagent, a mail envelope field when it runs through an agent pool. Forward it **as-is, including an empty set** — you render **no opinion** on which governances were actually required; that check is the spec-judge's own pre-flight (`sdd:sdd-spec-judge`).
47
+
48
+ 1. Grill the user **live** with the node path, `artifact-types`, and the seed intent (or `backfill` / `revise`); write the draft `spec.md` + `.feature`.
49
+ 2. Spawn the cold spec-judge; incorporate its verdict and any `<!-- open: -->` markers.
50
+ 3. On convergence → exit to the spec gate.
51
+ 4. On `blocked`, or the cap hit without converging → **do not auto-accept**. Present the failing scenarios and ask the user to **accept as-is**, **keep looping** (reset the count), or **change direction**.
52
+
53
+ **Freeze re-open guard.** A node at `status: approved` or `implemented` has a **frozen `.feature`**. The unfreeze trigger is **risk, not phase** (`sdd:lifecycle-governance`), so what you may do to that file depends on the *edit class*, not on it being frozen — read the edit class **structurally**, per named `Scenario`, **never from a raw line diff** (a step orphaned off a frozen scenario onto a new adjacent scenario shows no `-` line and would misread as additive): `npx gherkin-cli@0.0.2 diff --base <baseref> <file> --format json` (`addOnly` / only `added` ⇒ additive; any `modified`/`removed` ⇒ examine for narrowing), or the spec-gate's `plugins/sdd/skills/spec-gate/scripts/classify-edit-class.mts` which wraps this same structural diff plus git rename detection. An **additive** scenario (new behavior, nothing weakened) **self-clears — it stays `@frozen`, needs no re-open**; a **pure move/rename** (`git mv`, zero content delta) likewise **preserves freeze and is not a gate-able edit**. Only a **narrowing or rewriting** edit to an existing scenario is a re-open — a freeze transition and a `status` write you do not own, so confirm it was **ratified** (the lightweight async re-open flag) before touching that scenario's content. **Never narrow or rewrite a frozen scenario without the ratified re-open**; adding and relocating need none.
54
+
55
+ **Route observations.** Each production-chain producer (spec-, impl-, solution-producer) may surface typed `OBSERVATIONS` (`architect` | `strategist`); never act on them silently. When several producers surface observations in one segment, **forward every producer's observations to the plan — drop or filter none of them** — and **spawn no spec of your own** from them. A granularity / split observation becomes a **new node** or a **project-spec** operation (the plan's or the user's call) — never a marker grown into this node, and never a spawn you make here. An observation the plan or user then **declines** is dropped by that decision — an explicit call, not silent loss.
56
+
57
+ ### Plan-mode preview
58
+
59
+ Run **only** when plan mode is active (the harness blocks every write except the plan file). Run the **explore reasoning in full but write no repo files** — the plan file is the single output.
60
+
61
+ - **Reason as normal.** `resolve-governances`; locate/place the node **provisionally in-memory** (no scaffold write); **classify** it (`spec-type`, `concept:`, per-file `artifact-type`); **collect seed intent** with the same 3–5 targeted questions (backfill reads source instead).
62
+ - **Draft, don't write.** Compose the `spec.md` prose and the `<unit>.feature` **scenario list** per `sdd:spec-format-governance` / `sdd:suite-format-governance`, but render them into the **plan file** under `## Proposed Spec` and `## Proposed Scenarios` (scenario titles + `Given/When/Then`, grouped by `# ── <stage> ──`, `@rubric`/`@trigger` tags noted) — never to their repo paths.
63
+ - **Keep the cold spec-judge** (read-only): spawn it over the in-memory draft as embedded in the plan; fold its verdict and any `<!-- open: -->` markers into the preview so unresolved gaps are visible.
64
+ - **Drop the build-to-learn spikes.** Do **not** spawn the impl-producer — spikes mutate files / run builds (disallowed in plan mode) and are out of scope; note in the preview that the draft is un-spiked.
65
+ - **No gate, no writes.** No spec gate, no `@frozen`, no `status` / `approval` / ledger writes. End the turn with **ExitPlanMode** presenting the drafted spec + scenario list.
66
+ - **Adoption on approval.** On approve + exit plan mode, the next non-plan-mode explore run **adopts this preview as the settled draft** (via the intake `<cr-ref>.design.md` seam, Step 1): it writes `spec.md` + `<unit>.feature` from the preview, runs build-to-learn to validate, and proceeds to the spec gate **without re-grilling seed intent**. **Guard:** if the preview carried a failing spec-judge verdict or unresolved `open` markers, resolve those first — never blind-adopt a known-incomplete draft.
67
+
68
+ ## Step 2 gate — the spec gate (Draft → Approved, internal)
69
+
70
+ On entering the gate, overwrite the statusline file with `spec gate` (same opt-in, best-effort write as explore — skip when plan mode escaped this step via ExitPlanMode).
71
+
72
+ Run the spec gate as an **internal step** (not a user-invocable skill). Judge each touched unit suite against `sdd:suite-format-governance` (untagged scenarios boolean; `@rubric` well-formed) and the spec-format bars; load `sdd:lifecycle-governance` + `sdd:ownership-governance` + `sdd:gate-validation-governance` for the legal state tuple. **Never advance** with judge failures, open markers, or a suite that does not cover the spec. On a **change** verdict the findings are **evidence, not a work order**: substantiate each before acting, state the **rule** each instantiates and sweep for its other instances, re-derive every correction against the rule **governing the artifact** rather than against the finding alone, and account for each finding's **provenance** — a finding naming an artifact the previous round's commits changed is a **regression**, which stops the loop for a re-plan instead of another round (`sdd:remediation-governance`). ("Regression" here is finding provenance, distinct from the grill loop's convergence above.) On **approve**: **freeze** each touched `.feature` via its `@frozen` tag, record a per-CR `gate` line in **your own shard** in the `ledger/` directory sibling to `spec.md`, and set `status: approved`. `spec.md` stays in sync, never frozen.
73
+
74
+ ## Step 3 — deliver: build to keep
75
+
76
+ On entering deliver, overwrite the statusline file with `deliver`.
77
+
78
+ Build-to-keep against the **frozen** suite. The deliver **read-set is scoped** (`sdd` deliver spec): the frozen `<unit>.feature` (the contract), the optional `<unit>.solution.md`, and the implementation files for the touched artifact-type (via `produced-by` / `resolve-governances`) — **not** the prose unit spec, which was explore's input and adds no constraint the frozen suite doesn't already carry. **Dispatch** the impl-producer builder (it loads `sdd:impl-producer-governance`; a named plugin / model-tuned producer runs at its own model + effort) — through the dispatch capability's intent seam when available, preferring the **same warm builder unit reused from explore** (it keeps its context; no reset) over a cold one-shot, else a portable cold subagent — to build the artifact **and** one verification per frozen scenario.
79
+
80
+ **Rebase onto the target — the last deliver act, before the gate.** Before running the impl gate, **rebase the CR branch onto the current tip of the declared target** (for a commit-to-main project, the equivalent `pull --rebase` onto the latest `main`), so the impl gate judges the **merged tree that will actually land** — keeping history linear and leaving handoff a pure consumer that never re-verifies. A **textual conflict** is resolved as **deliver code work** against the frozen `.feature` (never a `.feature` edit); the gate then runs on the resolved tree. A conflict you **cannot resolve confidently is never guess-resolved** — the frozen suite covers *this CR's* behavior, not the incoming change's, so a wrong resolution could still pass the gate and land broken; **stop and escalate** (in-session ask the user; headless return `needs-input` up the relay) and record a `halt`, never land a low-confidence resolution. Rebasing an *unmerged* CR branch is git-reversible (reflog), so it raises **no new hard floor** — but a conflict resolution that would **narrow** a frozen scenario still fires the existing **Clearance** floor, a semver class over the ceiling **Compatibility**, and a genuine contradiction **Conflict** (autonomy bar, below). The rebase-then-gate is **optimistic**: if the target **advances again** between the passing gate and the push (another CR merged in the window), **re-rebase onto the new tip and re-run the impl gate — do not push until the gate passes on the re-rebased tree**, looping until the push wins, so what lands is always a tree the gate saw green. **The loop is bounded, not forced** — if the target keeps advancing past a small cap of attempts, **stop and escalate** (record a `halt`) rather than spinning forever (a liveness stop, same as the unconfident-conflict halt).
81
+
82
+ **The impl gate (Approved → Implemented, internal).** On entering the gate, overwrite the statusline file with `impl gate`. Dispatch the **cold impl-judge** (`sdd:sdd-impl-judge` or the covering plugin's judge) — same seam-when-available wiring, preferring its warm unit context-cleared fresh via `npx cyberlegion@<version> unit clear <ref>` for this judgment, else a portable cold subagent — to run the verification per frozen scenario plus an orthogonal structural/scope read. Advance to **`status: implemented`** **only when every impl-judge passes** (a frozen scenario with no verification blocks the advance — impl-sync is this suite run, not a stored flag). The three actions: **approve** → `implemented`; **change** → fix the **code** (never the frozen `.feature`), under the same evidence-not-a-work-order remediation the spec gate uses (`sdd:remediation-governance`) — including the **provenance** account that stops a regressing loop; **reject** → redo, or a **Oracle-lens revert** (a frozen scenario proved fatal → unfreeze the `.feature`, return to `draft` — the only place a frozen `.feature` reopens).
83
+
84
+ ## Step 4 — handoff
85
+
86
+ On entering handoff, overwrite the statusline file with `handoff`. **Clear the statusline file** (delete `.agents/sdd/statusline`, not just blank it) once the mission lands — a clean handoff is one of the loop's exit paths, and the file is written only while a mission is in flight.
87
+
88
+ Land per the handoff unit. First **finalize placement**: run a Warden placement pass **scoped to this mission's touched nodes**, and relocate any provisionally-placed node to its blessed home (placement-map routing table) via `git mv` — a pure rename that preserves freeze (`sdd:lifecycle-governance`), logged as a detail-adjustment, so the delivery shows every node already in the right place (no follow-up formation CR). Then land per the declared delivery shape (branch → PR where the repo is PR-flow), decomposed by **unit of work** (one co-committable change per commit), conditional `status` write-back — when the CR's source **closes by reference** (a same-forge issue, e.g. GitHub/GitLab), write the auto-close reference (`Closes #<n>`, naming the source) **into the PR body** so the source auto-closes on merge; a source that does not close by reference (a bare prompt, or a cross-system source like Asana/Jira) gets **no** closing reference (direct-to-`main` work transitions it to `done` on push; a cross-system source is moved natively) — and a distilled public summary. Introduce no new hard floor; keep the combat log in the PR; keep the plan until the CR is done/merged and doctrine-distilled.
89
+
90
+ **Follow-ups: record, classify, propose, drain — only the first always works.** A follow-up (work the mission noticed but held out of scope) is carried through four stages. **1. Record — unconditional, first.** Before anything else, and before any filing is attempted, append each identified follow-up as a `kind: followup` line to the CR's own **ledger shard** (`sdd:combat-log-governance`) — no permission, no forge, no human, so it cannot be denied; it goes to the **ledger**, never the combat log (the combat log is deleted from the tree at retro; the record must outlive the mission). **2. Classify — a proposal, not a verdict.** Mark it `blocking` (it **contradicts a completion claim the mission already made** — name that claim in the line) or `backlog` (genuinely new territory); a finding that the mission's own **frozen contract** was wrong is **not** a follow-up at all — route it as an Oracle-lens revert inside this mission instead. **3. Propose, never admit.** Emit the classified proposal plus its evidence; write **no** node or edge to the mission graph and spawn **no** mission for it — admission is the graph's single writer's act, out of scope here; filing an issue is not opening a CR, and a filed follow-up re-enters SDD only when a **later** mission is started from it. **4. Drain — permission-gated, class-agnostic.** File **one issue per outstanding follow-up**, `blocking` and `backlog` alike (the class decides graph admission, never filing) — **dedupe first** against the forge's existing issues, **open or closed** (at least two keyword combinations: the full title, then the core noun/verb) — and on a **mixed** set file only the unmatched, skipping the matched, never all-or-nothing. **Forge-conditional:** a source with no issue forge files none; the records still stand. The `followup` line carries **no filed-state** — never edit it to mark it filed — so a later drain **re-derives** what is outstanding by that same dedupe, which is what makes a retry both correct and idempotent (a follow-up whose filed issue was since closed is a **closed** match, so it is skipped, not re-filed).
91
+
92
+ **The denial path is first-class.** Filing can be **refused** (an unattended mission has no channel to grant it). When refused: the ledger records **stand**, you **report the refusal loudly**, and you **never** report the follow-ups as filed — a fallback indistinguishable from success is the exact failure this doctrine exists to avoid. The drain **retries later** from the durable record, filing the still-outstanding follow-ups once permission is granted.
93
+
94
+ **The issue body meets a stricter outward-publish floor than the committed record.** Compose it **self-contained** — a reader who cannot see the mission's internal artifacts can act on it, with no "see the ledger line" and no gate/judge/leash prose — carrying **no production-internal artifact reference**: no ledger shard filename (it embeds a per-session hash), no combat-log reference, no plan-brief path — even though a repo-relative ledger shard filename passes the committed-record floor cleanly; this bar is stricter and excludes it anyway. Plus everything the committed-record floor already bans (absolute paths, `$HOME`/`$USER`, usernames, hostnames, secrets, code, raw numbers). Every filed follow-up also carries a **marker identifying it as agent-filed** and **names the mission (`<cr-ref>`) it was discovered from**, so intake can tell agent- from human-filed follow-ups and the loop's branching factor is measurable.
95
+
96
+ Before you close out, run the **correction-line finalize backstop** (autonomy bar, below): flush any correction whose combat-log line was never written, creating the plan's `*.log.jsonl` if absent.
97
+
98
+ Before closing out, **reset the mission's warm units**: `npx cyberlegion@<version> unit clear <ref>` (context-clear, pane stays warm) or tear down every warm unit this mission dispatched — none carries this mission's context into the next.
99
+
100
+ Once landed, **do not spawn** the formation Warden. Surface a **one-line nudge** that a corpus-wide formation pass is due, pointing to `sdd:manage` ("audit the corpus structure" → `formation-loop`). The pass is **on-demand** — run deliberately, not auto-spawned on every landing; `sdd:manage` owns the trigger. Gate nothing on it.
101
+
102
+ ## Autonomy, provenance, and the hard floor (baked in)
103
+
104
+ - **Dispatch transport.** Every spawn beyond this session states a **dispatch intent** — role, brief, expected verdict schema — never a pinned command. When a harness-agnostic dispatch capability is available (detected at runtime; the concrete case is the Legate's `dispatch-governance` composing `cyberlegion` primitives — `agent resolve` + `unit spawn` + `mail await` — with **no** `dispatch` CLI verb, the seam named in `.agents/specs/sdd/design/harness-spawning.md`), route through its intent seam and let it pick `subagent | channel | run-inline`, **preferring a warm unit** over a cold one-shot spawn; with no capability present, fall back to the portable cold subagent (depth-1) default — grader independence intact either way. **Warmth is a property of the unit/process; coldness of the context**: a judge's fresh-context guarantee (ADR-0016) is transport-agnostic — satisfied by a newly spawned cold subagent **or** a warm unit **context-cleared** to a fresh context before **each** judgment (re-deriving its oracle, carrying none of a prior round's context). Clear a warm unit with **`npx cyberlegion@<version> unit clear <ref>`** (`<ref>` = unit id / handle / worktree branch or CR ref) — it injects the harness's own fresh-context command (`/clear` on Claude/Codex/Copilot, `/new-chat` on Cursor; fail-loud on a harness with no honest reset) so the **pane stays warm** while the **context goes cold**; it tears nothing down. The **impl-producer builder** instead stays warm and **keeps** its context across the explore spikes and the deliver build (never cleared between those uses). Warm units stay warm for **one mission** — reused within it, then **`unit clear`**'d or torn down at **handoff**, never carrying this mission's context into the next.
105
+ - **Initial strategy** (run start): assess blast radius + the other dimensions and emit a run-level `kind: leash` block to **your own ledger shard** (`ledger/<cr-ref>.<hash>.jsonl` — mint `<hash>` as 6 random hex **once per session** and reuse it for every line you append; `sdd:combat-log-governance`) — `leash` (`auto-none | auto-spec | auto-all`), `by: derived | user`, `approach[]`. It may be user-specified. This block is `kind: leash`, **not** `strategy` — `strategy` is the doctrine Scanner's alone. Ledger lines carry **no `ts`**.
106
+ - **Per-gate verdict.** At each gate, derive the leash against discovered state and either **self-assert within leash** (write `approval.<gate>: { verdict: approve, by: agent, why }`; the spec lands in the async review queue) or **stop** with a verdict packet for the human. **Never advance** when any judge fails, any open marker remains, or (at the impl gate) any frozen scenario's verification does not pass. Human ratification (`by: <name>`, advance `status`) is reserved to the in-session position holding the user channel — by default you, in-session; a headless `automaton` emits the verdict packet and stops, **even when a coordinator relays "the user approved."**
107
+ - **Combat log.** Append `report` / `correction` lines (and the halt that stopped you) to the plan's `*.log.jsonl` (these carry a UTC `ts`); your run-start `leash` block, self-asserted `gate` lines, and the handoff `followup` records go to **your own shard** in the durable `ledger/` directory sibling to `spec.md` — never another writer's shard, never a shared file (`strategy` there is the Scanner's alone). Free text is commit-message-grade — never code, prompts, secrets, or literal values.
108
+ - **Correction-line durability** (`combat-log-governance` write duty). When a gate you self-assert was reached via a **judge-reject→fix→pass**, append the discrete `correction` line (`correction-kind: judge-iteration`, a matchable `cause`) to the combat log **before** you write the gate `why` — never leave the iteration recorded only in the `why` prose; a gate that passed clean appends none. At **handoff/finalize**, if any correction occurred whose combat-log line was never flushed, write it now — **creating the plan's `*.log.jsonl` if it does not exist** — so no correction is lost to the no-log mission class (a mission with no correction forces nothing). The forced line stays a combat-log `correction`, never a ledger line.
109
+ - **Hard floors (mandatory stops):** **Clearance** of a narrowing (weakening/deleting an acceptance scenario; pre-authorizable in the CR), **Compatibility** when the semver class exceeds the change-class ceiling (pre-authorizable), and **Conflict** of a logical contradiction in the suite (not pre-authorizable). An obvious stale-mistake contradiction is a conductor-served minor fix; escalate only when both sides are plausibly intended. **Clear the statusline file** on any abort/halt that ends the mission (a hard floor stop, an unconfident-conflict escalation, or any other terminal halt) — the same exit-path clear as handoff and pause; a mid-mission escalation the user resolves in-session (not a halt) is not an exit and leaves the file as-is.
110
+
111
+ ## Suspend and resume
112
+
113
+ A mission runs as **segments** (one autonomous sitting each). Position is **derived from the artifacts** (`spec.md`, the `.feature`, frontmatter, the plan), never a stored cursor. To checkpoint a mission into its plan, use `pause-mission`; to pick one up, `resume-mission` reads the `.plan.md` and continues this loop where it left off.
114
+
115
+ **Clear the statusline file on pause too.** A pause is an exit path like handoff — before (or as part of) invoking `pause-mission`, delete `.agents/sdd/statusline`. This is **your** write (the conductor's), not `pause-mission`'s — its write scope stays boundaried to the plan brief (`todos`, `## NEXT`, and, with `--approve`, `status`); it never touches the statusline file.