wdi-method 0.6.18 → 0.6.24

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 (34) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/LICENSE +21 -21
  3. package/NOTICE +28 -0
  4. package/README.id.md +190 -0
  5. package/README.ja.md +188 -0
  6. package/README.md +190 -530
  7. package/README.zh.md +188 -0
  8. package/bin/wdi-method.js +2199 -2112
  9. package/kit/.constitution/method/README.md +1 -0
  10. package/kit/.constitution/method/branch-guide.md +87 -0
  11. package/kit/.constitution/method/ci-guide.md +169 -0
  12. package/kit/.constitution/method/constitution.md +1 -0
  13. package/kit/.constitution/method/scripts/lifecycle.py +416 -0
  14. package/kit/.constitution/method/scripts/validate.py +126 -9
  15. package/kit/skills/wdi-autopilot/SKILL.md +461 -384
  16. package/kit/skills/wdi-build/SKILL.md +404 -393
  17. package/kit/skills/wdi-daily-autopilot/SKILL.md +138 -0
  18. package/kit/skills/wdi-daily-what-to-build/SKILL.md +155 -0
  19. package/kit/skills/wdi-daily-what-to-test/SKILL.md +127 -0
  20. package/kit/skills/wdi-explain-to-me/SKILL.md +1 -1
  21. package/kit/skills/wdi-help/SKILL.md +21 -7
  22. package/kit/skills/wdi-init/SKILL.md +16 -0
  23. package/kit/skills/wdi-prune-or-archive/SKILL.md +76 -0
  24. package/kit/skills/wdi-review/SKILL.md +4 -1
  25. package/kit-overlay/AGENTS.md +37 -4
  26. package/kit-overlay/README.md +1 -0
  27. package/kit-overlay/constitution.md +1 -0
  28. package/lib/identity.mjs +246 -117
  29. package/package.json +8 -4
  30. package/scaffold/.control/custom-dispatch.yaml.example +65 -0
  31. package/scaffold/.control/registry/index.yaml +9 -0
  32. package/scaffold/.control/test-targets/desktop.md +15 -0
  33. package/scaffold/.control/test-targets/mobile.md +6 -0
  34. package/scaffold/.control/test-targets/web.md +6 -0
@@ -1,393 +1,404 @@
1
- ---
2
- name: wdi-build
3
- description: Use at G5 Release — one spec from open to closed in one supervised run. Opens the spec, hands the owner to-spec and to-tickets, ships every ticket to a green PR through a five-step pipeline, then closes the spec. One invocation, not four.
4
- ---
5
-
6
- # WDI Build
7
-
8
- One unit of work, one invocation. A spec used to need four calls — open it, produce the contract, ship each
9
- ticket, close it — and three of those were bookkeeping. They are all in here now, because a unit of work that
10
- needs four invocations gets three of them skipped.
11
-
12
- **The engine layer below this gate is not BMad's, and it MUST be this one.** `to-spec`, `to-tickets`,
13
- and `implement` produce the contract, the tickets, and the code; `tdd` and `code-review` do the work
14
- inside them. All five are `mattpocock/skills`, installed **in this repo** — the installer refuses
15
- without them. Thirteen BMad skills are **retired** at this gate and MUST NOT be used anywhere:
16
- `bmad-spec`, `bmad-build`, `bmad-build-auto`, `bmad-code-review`, `bmad-retrospective`,
17
- `bmad-agent-dev`, `bmad-create-epics-and-stories`, `bmad-create-story`, `bmad-dev-story`,
18
- `bmad-dev-auto`, `bmad-quick-dev`, `bmad-sprint-planning`, `bmad-sprint-status`. That is enforced, not
19
- requested: `install` and `update` lock each one out of model invocation and add a `Skill()` deny rule.
20
- `bmad-skill-register.md` carries the list and the criterion behind it.
21
-
22
- **All five engines are INVOKED, by this skill, through the Skill tool.** Upstream ships `to-spec`,
23
- `to-tickets` and `implement` with `disable-model-invocation: true`; `wdi-method` strips it from the
24
- copies this repo owns, so there is no command to hand to the owner and no reading-and-following to do.
25
- Where an engine needs a decision — the seams, the `to-tickets` quiz — that decision is made before the
26
- invocation and passed IN it, because an engine that stops to ask inside an unattended run is a run
27
- that stalls with nobody there to answer.
28
-
29
- **If an engine will not invoke, stop and say why.** `disable-model-invocation` back in its frontmatter
30
- is what `npx skills update` does, and the fix is one command: `npx wdi-method engines --fix`, or the
31
- `wdi-init` / `wdi-upgrade` skill. MUST NOT work around it by pasting the engine's process inline: the
32
- engine's rules are its own, and a paraphrase of them is not the engine.
33
-
34
- **Under an active mandate the owner's part is `wdi-autopilot`'s.** A `DEC-` of `type: mandate` at
35
- `status: accepted`, unexpired, moves **every** "the owner runs" and "the owner decides" in this skill to the
36
- coordinator — G5's checklist and Step 2's *stop and reach the owner* included, which reach the coordinator and
37
- not a person. Three of them change **shape** as well as owner: the engines run by **read-and-follow** — a builder brief
38
- that names the engine's `SKILL.md` path and carries out its process — or from a copy in the repo, and the ledger
39
- names which; the seams, the `to-tickets` quiz, and § When the code turns out to be right are decided by the
40
- coordinator and written to the ledger, one row each; and whatever the mandate lists as `parked` still stops,
41
- reported for the owner rather than decided. One thing changes **shape** rather than owner: a mandate is one
42
- unit of work and reaches `main` through **one PR**, so Step 4 commits the ticket to the run branch instead of
43
- opening a PR per ticket, and Step 5's push and CI watch happen at every spec close on that one PR — the
44
- checklist, the head-SHA rule, and the caps are unchanged. Nothing else in this skill relaxes. `wdi-autopilot` owns the
45
- mandate, the ledger, and the loop; this skill MUST NOT restate them.
46
-
47
- **No orchestration tool is required, and this skill MUST NOT name one.** How the work is carried out is the
48
- session's own arrangement: an orchestration skill, this CLI's native subagent tooling, or the coordinator doing
49
- a step itself. Which CLI, which model, and which effort staff a step come from the local Agent Rules, and MUST
50
- NOT be restated here. Every rule below holds whatever the mechanism — they are about the artifact and who
51
- judges it, not about how an agent is launched.
52
-
53
- Two roles exist regardless. The **coordinator** — this session — holds every judge call, the registries, and
54
- every remote git action. The **builder** of a step holds the spec and the code.
55
-
56
- When the coordinator is also the builder, the separation the pipeline rests on is absent. That MUST be reported
57
- as absent rather than worked around: a step judged by whoever wrote it is a self-report. One consequence is
58
- hard — see Step 3: at `risk_accepted: low` the panel requires reviewers who are not the builder, and a session
59
- that cannot provide them is **blocked**, not excused.
60
-
61
- ## Precondition, and the one that is easy to miss
62
-
63
- | Check | When it fails |
64
- |---|---|
65
- | Every component this spec touches has passed G4, **or** sits at `mode: catalog` | Route to `wdi-component`. `spec-after-g4` checks it, and `catalog` skipping G4 is by design, not an exception |
66
- | An isolated worktree | Isolate first. MUST NOT run in a shared checkout |
67
- | Every `prd` slug names a real `.what/_prd/<initiative>/` folder | A spec without a promise covering it is a spec nobody agreed to (`spec-names-release-prd`) |
68
-
69
- The repo commits straight to `main` and opens a PR only when asked. **Invoking this skill is that ask**, for
70
- this spec only; it MUST NOT be read as standing permission for the next change.
71
-
72
- ## Phase 1 — Open the spec
73
-
74
- Record it in `.control/registry/specs.yaml`. The frame opens here; the `tickets` rows land in Phase 2, because
75
- that is where they are born.
76
-
77
- | Field | Rule |
78
- |---|---|
79
- | `id` | `SPEC-<N>`, monotonic, never reused. A `W<N>` id in a frozen record is a **retired alias** and MUST NOT be rewritten |
80
- | `release` | MUST be stated. The release↔spec cadence is situational and MUST NOT be inferred from numbering (`spec-names-release-prd`) |
81
- | `prd` | MUST be stated: which initiative PRDs this spec delivers against. MUST NOT be derived from `release` |
82
- | `fr` | The `FR` this spec satisfies. Ideally one — an `FR` is human-testable from birth |
83
- | `size` | `S` · `M` · `L`. MAY be raised mid-flight; MUST NOT be lowered |
84
- | `depends_on` | At **spec** level. A spec declaring none runs in parallel with its neighbours |
85
- | `spec_folder` | One per spec, not one per spec × component |
86
- | `tickets` | Flat, one row per ticket: `id` · `component` · `satisfies: [UC]` · `blocked_by` · `touches` · test names |
87
- | a ticket `id` | `<spec-id>-<NN>` — `SPEC-3-01`. The engine numbers its files from `01` per feature, which is unique only inside one spec; the RTM needs a key that is unique across the corpus |
88
-
89
- **`tickets` is an index, not a store.** The ticket's prose lives where the tracker put it; the row carries only
90
- what RTM and the validators read. And ticket **status** MUST NOT be copied here — it is read from the ticket
91
- itself when `.control/generated/` regenerates (`ticket-status-one-home`). Two homes for one fact is how registries start lying.
92
-
93
- `ticket-status-one-home` finds the file at `{spec_folder}/issues/<NN>-*.md`, from the number at the tail of the id, and reads its
94
- status from either a `**Status:**` body line — what the engine writes, because a ticket file is a tracker
95
- payload and trackers do not read YAML — or `status:` in frontmatter.
96
-
97
- The `epics` nesting is **repealed**. A ticket names its `component` directly; an intermediate level that only
98
- grouped rows bought nothing and cost a lookup.
99
-
100
- Size does not choose which gates are active — that is `mode`'s job. It decides two things: session merging
101
- (`S` merges G4 and G5 into one 20-minute session) and whether `SPEC.md` is written at all.
102
-
103
- ## Phase 2 — The contract, and the tickets
104
-
105
- Two engines, and **this skill invokes both.** Invoke, then verify and land.
106
-
107
- | Size | What this skill invokes | What lands |
108
- |---|---|---|
109
- | `M` · `L` | `to-spec`, then `to-tickets` | `SPEC.md` in `spec_folder` · ticket files · the `tickets` index rows |
110
- | `S` | `to-tickets` only | ticket files · the `tickets` index rows. **No `SPEC.md`** |
111
-
112
- Each invocation carries what the engine would otherwise stop to ask: the tracker is already configured
113
- in `docs/agents/issue-tracker.md`, the seams and the testing decisions are settled above, and the
114
- `to-tickets` quiz — granularity and blocking edges — is answered from the size table in
115
- `delivery-flow-guide.md` plus `depends_on` and `touches`. Under a mandate every one of those answers is
116
- also a ledger row.
117
-
118
- At `S` the tickets **are** the contract. `to-tickets` accepts a conversation directly, so a middle document
119
- buys nothing there. From `M` up it is written first, because two things have to be settled **before** tickets
120
- are cut and neither survives being decided afterwards: the **seams** the feature will be tested at — fewest
121
- possible, highest possible, agreed with the owner — and the **testing decisions**, which say what a good test
122
- is here and name the prior art.
123
-
124
- ### What you verify before landing anything
125
-
126
- - **Nothing new.** `SPEC.md` is a **projection** of `.what/` + `.how/`. It MAY restate a promise in its own
127
- words — a machine contract is more useful self-contained — but **every restatement MUST refer to the live
128
- corpus document it came from.** A reference that does not resolve is not a wording problem: the gap is
129
- upstream. Route to `wdi-component` or `wdi-blueprint`, and do not let the contract invent it.
130
- - **Every user story resolves to an id.** A user story with no `FR` or `UC` behind it is a **new promise**,
131
- and a new promise is `wdi-product`'s, never a spec's.
132
- - **Every ticket names what it satisfies.** No `satisfies`, no landing: without it the chain
133
- `FR → UC → ticket → test` breaks and RTM cannot say which promise went green. This is the one field
134
- `to-tickets` does not ask for on its own, so it is the one most likely to be missing.
135
- - **Every ticket is vertical.** A slice of one layer is not a ticket. The exception is a wide refactor,
136
- sequenced expand → migrate in batches → contract; `delivery-flow-guide.md` owns that rule.
137
- - **Ticket files land under `spec_folder`, and `spec_folder` is `.scratch/<spec-id>-<slug>/`.** Their
138
- **shape** is the engine's — one file per ticket, numbered in dependency order, blocking edges declared
139
- — and the location is ours, written in `docs/agents/issue-tracker.md` where the engines read it. The
140
- id in front of the slug is not decoration: four live repos wrote that leaf four different ways, one of
141
- them all four inside a single repo, and a folder nothing can trace back to a row in `specs.yaml` is
142
- how a spec goes missing. A ticket at the repo root, or under `docs/`, or in a `.scratch/` directory
143
- with no row in `specs.yaml`, is drift.
144
-
145
- `SPEC.md` and ticket files **are not read by humans.** Both are machine contracts, and no review burden MAY be
146
- moved onto them. `wdi-review` MAY still be dispatched over the contract; its trace lands on the spec in
147
- `specs.yaml` — and where there is no `SPEC.md`, one trace covers the **ticket set as one artifact**, never one
148
- review per ticket.
149
-
150
- ## Phase 3 — Ship each ticket
151
-
152
- Work the **frontier**: the tickets whose blockers are all closed. A ticket whose `blocked_by` is not yet
153
- satisfied MUST NOT be started, however ready it looks.
154
-
155
- | # | Step | Engine | Exit condition |
156
- |---|---|---|---|
157
- | 1 | Encode | invoke `tdd` | **Failing tests exist that encode this ticket's acceptance criteria** |
158
- | 2 | Build | invoke `implement` — it uses `tdd` at the agreed seams and calls `code-review` itself | Those tests green, typecheck clean, full suite green once |
159
- | 3 | Panel | invoke `code-review`, as a **separate** dispatch by a **different** agent | Panel adjudicated, zero unresolved must-fix |
160
- | 4 | Publish | — | Branch pushed, PR open, ticket-closing checklist answered |
161
- | 5 | CI | — | All checks conclude green on the pushed head SHA |
162
-
163
- **Step 1 is the change that matters most.** It used to be a plan, judged from a frontmatter field a builder
164
- wrote about itself. Now it is a **failing test suite** — the acceptance criteria, encoded, and demonstrably
165
- red. That is evidence rather than a claim, and it is what `ticket-has-test` and G5's ★2 have always been asking for:
166
- *acceptance criteria proven by a test, not by an agent's statement.* Under TDD the test exists **before** the
167
- code, so the proof is not retrofitted.
168
-
169
- ### Engine rules
170
-
171
- - **MUST judge Steps 1 and 2 from the test suite**, not from a report and not from a status field. Red at the
172
- right assertions closes Step 1; green with a clean typecheck closes Step 2. A builder's chat report MUST NOT
173
- settle either.
174
- - Ticket **status** is read from the ticket itself. It MUST NOT be copied into `specs.yaml` (`ticket-status-one-home`).
175
- - Every step MUST start from a **fresh context**, and a fix round MUST NOT go back to whoever produced the
176
- code. The ticket carries everything the next builder needs, and inherited context is how a step stops judging
177
- the artifact on its own merits. Where one session runs consecutive steps itself, it MUST re-read the artifact
178
- rather than trust what it remembers writing.
179
- - A step handed to a separate agent MUST be launched so it cannot sit waiting for input nobody will give, and
180
- its start MUST be confirmed from observed activity — never from a readiness match alone.
181
- - A step that fails because the agent could not spawn what it needed is a **capability** failure, not a ticket
182
- failure. MUST retry it somewhere that can, and MUST NOT record it against the ticket.
183
- - MUST NOT reorder or drop a step. A step with nothing to do MUST be reported as such, not skipped silently.
184
- - A ticket returned by the panel MUST have its acceptance criteria amended and its status reset before it is
185
- picked up again — see Step 3.
186
-
187
- ### What every builder brief MUST carry
188
-
189
- Three rules this corpus adds, and `/implement` knows none of them. All three MUST reach whoever writes code in
190
- this spec — in the dispatch when a step is dispatched, and in the session's own working instructions when it
191
- is not.
192
-
193
- - **Debugging is conditional, never a phase.** When a test or build fails and the cause is not known, the
194
- builder MUST run `wdi-systematic-debugging` before proposing any fix. A third failed fix attempt is the signal
195
- to escalate, not to try a fourth.
196
- - **The corpus is not the builder's to change.** A builder MUST NOT edit `.what/`, `.how/`, or an `applied`
197
- `DEC-`. A deviation from the SDD or an `AD-N` is **reported**, and it becomes a `DEC-` through
198
- `wdi-decision` — never absorbed as a code patch.
199
- - **Verification is run, not assumed.** The commands are this product's, and they live in
200
- `.constitution/project/codebase-stack-guide.md` — build, test, and whatever the front end needs, each with
201
- the directory it runs from. A skill MUST NOT carry one product's build line. A green registry workflow
202
- MUST NOT be reported as proof the code compiles; they answer different questions.
203
-
204
- ### Step 1 — encode the acceptance criteria as failing tests
205
-
206
- - The tests MUST be written **at the seams the spec agreed** — existing seams preferred, highest possible,
207
- fewest possible. Inventing a new seam here, after the agreement, is a finding: it means Step 1 is redesigning
208
- what Phase 2 settled.
209
- - Every acceptance criterion MUST have at least one test. A criterion no test can express is not an acceptance
210
- criterion — it goes back to the ticket, or to the owner as an intent gap.
211
- - The tests MUST be **seen red, at the right assertions.** A test that passes before the code exists is testing
212
- nothing, and a suite that fails for the wrong reason — an import error, a missing fixture — has not encoded
213
- anything yet.
214
- - A test MUST NOT assert a literal where the behaviour is what matters. The panel treats that as a test that
215
- cannot fail, and returns it.
216
-
217
- ### Step 2 — build
218
-
219
- - The owner runs `/implement`, and it MUST be given the ticket and the three brief rules above.
220
- - It commits to the current branch and **never pushes**. That is its own behaviour and it is what we want; the
221
- coordinator is the hand that pushes.
222
- - **`/implement` calls `/code-review` itself, and that call does NOT satisfy Step 3.** It is the builder
223
- reviewing its own work — self-review by construction. Step 3 stands as a separate dispatch regardless of what
224
- ran inside Step 2.
225
- - The full suite MUST be run green once at the end, not only the tests this ticket touched. A ticket that
226
- passes its own tests and breaks a neighbour's has not finished.
227
- - Where the work turns out to need something the ticket does not authorise, it stops and reaches the owner with
228
- the question verbatim. The builder MUST NOT widen its own scope.
229
-
230
- ### Step 3 — panel, then judge
231
-
232
- Panel composition follows `risk_accepted`: at `low` a two-reviewer panel is **required** on the code; at
233
- `medium` and `high` it is available and SHOULD be used when the diff touches money, personal data, or a third
234
- party. The local Agent Rules govern which CLIs and models staff the panel. **A reviewer MUST be a different
235
- agent from the builder** — the builder's own review layers, `/implement`'s internal `/code-review` included,
236
- are self-review by construction and never satisfy the panel. This is the one separation in the pipeline that
237
- MUST NOT be collapsed: where the session cannot provide it and `risk_accepted` is `low`, the ticket is blocked
238
- and the owner MUST be told, because the field they set is what makes the panel required.
239
-
240
- `code-review` reviews along two axes — **Standards**, against this repo's documented conventions, and
241
- **Spec**, against what the ticket asked for. Both MUST run. Reporting one axis as the panel is reporting half
242
- a review.
243
-
244
- - MUST adjudicate every contested finding by reading the cited lines. Votes MUST NOT settle a finding. A finding
245
- neither reviewer can locate in the diff is dismissed with that reason stated.
246
-
247
- **MUST return to Step 2:**
248
-
249
- - Breaks a ticket's acceptance criterion, or contradicts the contract, the SDD, an `AD-N`, or an `applied` `DEC-`
250
- - Wrong behaviour, crash, or data loss reachable from the running app
251
- - Corpus drift: an `LC` touched but not registered, a contract changed in code but not in `02-contracts/`, a
252
- screen added without its `01-ux/` entry
253
- - An enum value rendered straight to the screen instead of read off its label map
254
- - Payment or private data reaching a tracked file
255
- - A weakened guard, or a test that cannot fail — including one asserting a literal instead of the behaviour it
256
- claims to cover
257
-
258
- **MUST record as follow-up and MUST NOT return to Step 2:** style or naming with no behaviour delta · a
259
- refactor outside this ticket's scope · a pre-existing defect this ticket did not touch · a speculative risk
260
- with no reachable path.
261
-
262
- A must-fix MUST return as a **ticket amendment**, never a chat instruction: amend what the ticket asks for,
263
- note the finding that caused it, reset the ticket's status to `ready-for-agent`, then pick it up again. **What
264
- a ticket `satisfies` is not amendable here** — that is the promise, and a must-fix rooted in the promise is an
265
- intent gap that goes to the owner through `wdi-product`. Changing the `FR` a ticket serves in order to make the
266
- code pass is how a corpus starts agreeing with whatever was built.
267
-
268
- Cap: **2 return trips.** MUST re-run the whole panel after each fix round — a fix introduces defects. On hitting
269
- the cap MUST escalate and MUST NOT open a PR carrying an unresolved must-fix.
270
-
271
- ### When the code turns out to be right and the document wrong
272
-
273
- This is normal during G5 and it is **not drift**. Building a thing is how you find out what the thing is.
274
-
275
- The builder still MUST NOT edit `.what/`, `.how/`, or an `applied` `DEC-` to make its own code fit — that is
276
- the corpus learning to agree with whatever was built, and it is a different failure. What happens instead:
277
-
278
- 1. **Say it once.** Name what the code does, which promise it contradicts, and what that costs. One place,
279
- one time. An `AD-N` is the one contradiction that **stops** — `decision-guide.md` owns it.
280
- 2. **The owner decides.** If they adopt the code, that survey is spent.
281
- 3. **The owning skill edits**, in the present tense, as if the design had always said this — `wdi-product`
282
- for an `FR`, `wdi-component` for behaviour or design, `wdi-blueprint` for a cross-component rule.
283
-
284
- What MUST NOT happen after step 2: raising the same conflict again in a later pass, opening an `OQ-` for it,
285
- dispatching a review over it, or writing anywhere in the corpus that the change arrived late. The commit is
286
- that record. `corpus-guide.md` § The corpus is written in the present tense is the binding rule.
287
-
288
- ### Step 4 — ticket-closing checklist, then push and PR
289
-
290
- The checklist is **three items**, and it MUST be answered before the PR opens:
291
-
292
- 1. Something the next person needs to know? → **into the document that carries it**, and that is almost
293
- always where it ends. It reaches `wdi-decision` only when no design document has a home for it —
294
- `decision-guide.md` § A decision's first home. A ticket contradicting an `AD-N` **stops** rather than
295
- closing; that is the one case where recording is mandatory.
296
- 2. A trap for the next agent? → recorded where the next agent will read it.
297
- 3. Test names matching what `specs.yaml` records?
298
-
299
- The five items that left this list moved to Phase 4, where the information actually exists.
300
-
301
- - MUST run the repository's commit/push audit before `git push`: refuse the forbidden paths, run the guard test,
302
- fix content on failure. A failing guard is a finding about the content — MUST NOT weaken the guard or the test.
303
- - MUST NOT push to `main`/`master`, MUST NOT force-push, MUST NOT merge.
304
- - The coordinator MUST be the hand that pushes and opens the PR.
305
-
306
- ### Step 5 — watch CI, then judge
307
-
308
- - MUST wait for every check to conclude, then confirm the checks belong to the **pushed head SHA**. A green
309
- report from a stale run is a false report.
310
- - `korpus.yml` validates the corpus, not the code. Build and test evidence comes from Step 2's own runs.
311
- - Classify each failure before acting: a defect from this change → Step 1 if the test was missing, Step 2 if
312
- the code was wrong, with `wdi-systematic-debugging` when
313
- the cause is unknown · infrastructure or flake → re-run **once**, and MUST NOT patch code to mask it; a second
314
- identical failure is a defect · a guard failure → fix the content.
315
- - Cap: 2 return trips. On hitting the cap MUST report red honestly rather than keep pushing.
316
-
317
- ### Parallel tickets
318
-
319
- Tickets with no blocking edge between them MAY run at once — that is what the frontier is — but four
320
- conditions MUST hold: each concurrent builder in its own worktree; `parallel-tickets-blocked` green for every pair released together;
321
- the first ticket that establishes a component's shape already closed, so later tickets inherit its code map;
322
- and no shared registry write in flight.
323
-
324
- **A wide refactor is the exception, and it inverts the rule.** Its batches MUST run in sequence, not in
325
- parallel, because each keeps CI green only while the expand still stands. Where even a batch cannot stay green
326
- alone, they share an integration branch and green is promised only at the final integrate-and-verify ticket.
327
-
328
- The pattern that MUST be preferred: run the biggest blocker alone first, let its shape decisions land, then fan
329
- out.
330
-
331
- ## Phase 4 — Close the spec
332
-
333
- **Six steps.** Run in this order and stop at the first failure.
334
-
335
- 1. **Registry catch-up.** Every `LC` the spec's design named is registered in `components.yaml`, and every
336
- `touches` value resolves — `lc-registered`. This is the moment those questions have answers.
337
- 2. **Inventories refreshed from code.** Run `.constitution/method/scripts/inventory.py`. The plan-versus-reality
338
- difference is reported as a finding; it MUST NOT be patched into agreement by hand.
339
- 3. **Structure maps refreshed** through `wdi-init` intent `structure`, if a base folder was born or removed or a
340
- key file moved.
341
- 4. **Distillation.** Every applicable row of the ownership table in `corpus-guide.md` has been landed by its
342
- owner. Anything durable in the spec folder leaves it now, or dies with it — **the ticket files included.**
343
- Their prose is working output; what survives is the index in `specs.yaml` and whatever the checklist routed.
344
- 5. **RTM green.** Every traceability row for this spec is closed. New risks are in the risk register with an
345
- owner.
346
- 6. Mark the spec `status: closed` in `specs.yaml`.
347
-
348
- The retrospective step is **repealed**, and `RTR-` with it. It was the only thing size `L` decided, and the
349
- only thing `V19` checked.
350
-
351
- - You MUST NOT close a spec with an open distillation row. The whole point of an ephemeral working layer is that
352
- durable truth leaves it first.
353
- - You MUST NOT reopen a closed spec to add scope. Scope arriving late opens a new spec, or goes through
354
- `wdi-decision` if it invalidates what is already planned.
355
- - A change invalidating more than 30% of a spec's tickets MUST go through `wdi-decision`, not a patch to
356
- `specs.yaml`.
357
- - Fast Path work is recorded as `fastpath` with no gates. If an `FR` turns out to be touched, the work MUST stop
358
- and be raised to a spec `S`.
359
-
360
- ## Red Flags — STOP
361
-
362
- - "One reviewer approved, good enough"
363
- - Judging Step 1 or Step 2 from a report instead of from the test suite
364
- - **Counting `/implement`'s own `/code-review` as the panel** — that is the builder reviewing itself
365
- - Writing `SPEC.md` at size `S`, or skipping it at `M` and up
366
- - Landing a ticket with no `satisfies` — the RTM chain breaks silently and nothing else notices
367
- - Amending what a ticket `satisfies` to make a must-fix go away
368
- - A ticket that slices one layer instead of cutting through all of them, outside a wide refactor
369
- - Running a wide refactor's batches in parallel
370
- - Claiming this skill invoked `to-spec`, `to-tickets`, or `implement` — it cannot; the owner runs them, or under
371
- a mandate a builder reads and follows them, and the ledger says so
372
- - A builder editing `.what/`, `.how/`, or an `applied` `DEC-` to make its code fit
373
- - Fixing a failing test without knowing why it failed
374
- - Opening a PR with an unresolved must-fix, or before the ticket-closing checklist is answered
375
- - Editing a guard, a test, or an assertion to turn something green
376
- - Reporting green without checking the head SHA, or reading green `korpus.yml` as a passing build
377
- - Leaving a dispatched step able to stall on a question nobody is there to answer
378
- - Naming an orchestration tool as this skill's requirement, or restating a CLI/model mapping the Agent Rules own
379
- - Closing the spec without the registry catch-up in Phase 4 — that is where five checklist items now live
380
- - Letting the contract state something `.what/` and `.how/` do not, or restate it without a reference
381
-
382
- **Each of these means: stop, return to the step or phase that owns it, or escalate to the owner.**
383
-
384
- ## Output
385
-
386
- MUST follow the Agent Rules `Answer Closing` block, carrying these additions:
387
-
388
- - **what was done** — spec, `FR` satisfied, every ticket with its branch and PR URL, what the code now does
389
- - **what blocked it** — every step that looped, every dismissed finding and why, anything left red, and every
390
- Phase 4 item that did not pass
391
- - **what comes next** — every finding recorded as follow-up, every entry in a contract's `deferred` list, every
392
- ticket-closing item routed to another skill, and the plan-versus-code inventory differences. A follow-up
393
- absent here is a lost finding.
1
+ ---
2
+ name: wdi-build
3
+ description: Use at G5 Release — one spec from open to closed in one supervised run. Opens the spec, hands the owner to-spec and to-tickets, ships every ticket to a green PR through a five-step pipeline, then closes the spec. One invocation, not four.
4
+ ---
5
+
6
+ # WDI Build
7
+
8
+ One unit of work, one invocation. A spec used to need four calls — open it, produce the contract, ship each
9
+ ticket, close it — and three of those were bookkeeping. They are all in here now, because a unit of work that
10
+ needs four invocations gets three of them skipped.
11
+
12
+ **The engine layer below this gate is not BMad's, and it MUST be this one.** `to-spec`, `to-tickets`,
13
+ and `implement` produce the contract, the tickets, and the code; `tdd` and `code-review` do the work
14
+ inside them. All five are `mattpocock/skills`, installed **in this repo** — the installer refuses
15
+ without them. Thirteen BMad skills are **retired** at this gate and MUST NOT be used anywhere:
16
+ `bmad-spec`, `bmad-build`, `bmad-build-auto`, `bmad-code-review`, `bmad-retrospective`,
17
+ `bmad-agent-dev`, `bmad-create-epics-and-stories`, `bmad-create-story`, `bmad-dev-story`,
18
+ `bmad-dev-auto`, `bmad-quick-dev`, `bmad-sprint-planning`, `bmad-sprint-status`. That is enforced, not
19
+ requested: `install` and `update` lock each one out of model invocation and add a `Skill()` deny rule.
20
+ `bmad-skill-register.md` carries the list and the criterion behind it.
21
+
22
+ **All five engines are INVOKED, by this skill, through the Skill tool.** Upstream ships `to-spec`,
23
+ `to-tickets` and `implement` with `disable-model-invocation: true`; `wdi-method` strips it from the
24
+ copies this repo owns, so there is no command to hand to the owner and no reading-and-following to do.
25
+ Where an engine needs a decision — the seams, the `to-tickets` quiz — that decision is made before the
26
+ invocation and passed IN it, because an engine that stops to ask inside an unattended run is a run
27
+ that stalls with nobody there to answer.
28
+
29
+ **If an engine will not invoke, stop and say why.** `disable-model-invocation` back in its frontmatter
30
+ is what `npx skills update` does, and the fix is one command: `npx wdi-method engines --fix`, or the
31
+ `wdi-init` / `wdi-upgrade` skill. MUST NOT work around it by pasting the engine's process inline: the
32
+ engine's rules are its own, and a paraphrase of them is not the engine.
33
+
34
+ **Under an active mandate the owner's part is `wdi-autopilot`'s.** A `DEC-` of `type: mandate` at
35
+ `status: accepted`, unexpired, moves **every** "the owner runs" and "the owner decides" in this skill to the
36
+ coordinator — G5's checklist and Step 2's *stop and reach the owner* included, which reach the coordinator and
37
+ not a person. Three of them change **shape** as well as owner: the engines run by **read-and-follow** — a builder brief
38
+ that names the engine's `SKILL.md` path and carries out its process — or from a copy in the repo, and the ledger
39
+ names which; the seams, the `to-tickets` quiz, and § When the code turns out to be right are decided by the
40
+ coordinator and written to the ledger, one row each; and whatever the mandate lists as `parked` still stops,
41
+ reported for the owner rather than decided. One thing changes **shape** rather than owner: a mandate is one
42
+ unit of work and reaches the active development branch (`policy.development_branch`, default `main`) through **one PR**, so Step 4 commits the ticket to the run branch instead of
43
+ opening a PR per ticket, and Step 5 splits: the coordinator pushes the run branch at every spec close, but
44
+ **the cloud run happens once, at `wdi-autopilot` § Finish** — every intermediate push starts nothing, and
45
+ what a spec close is judged on until then is the run branch's own full suite, run locally. The checklist,
46
+ the head-SHA rule, and the caps are unchanged. Nothing else in this skill relaxes. `wdi-autopilot` owns the
47
+ mandate, the ledger, and the loop; this skill MUST NOT restate them.
48
+
49
+ **No orchestration tool is required, and this skill MUST NOT name one.** How the work is carried out is the
50
+ session's own arrangement: an orchestration skill, this CLI's native subagent tooling, or the coordinator doing
51
+ a step itself. Which CLI, which model, and which effort staff a step come from the local Agent Rules, and MUST
52
+ NOT be restated here. Every rule below holds whatever the mechanism — they are about the artifact and who
53
+ judges it, not about how an agent is launched.
54
+
55
+ Two roles exist regardless. The **coordinator** — this session — holds every judge call, the registries, and
56
+ every remote git action. The **builder** of a step holds the spec and the code.
57
+
58
+ When the coordinator is also the builder, the separation the pipeline rests on is absent. That MUST be reported
59
+ as absent rather than worked around: a step judged by whoever wrote it is a self-report. One consequence is
60
+ hard — see Step 3: at `risk_accepted: low` the panel requires reviewers who are not the builder, and a session
61
+ that cannot provide them is **blocked**, not excused.
62
+
63
+ ## Precondition, and the one that is easy to miss
64
+
65
+ | Check | When it fails |
66
+ |---|---|
67
+ | Every component this spec touches has passed G4, **or** sits at `mode: catalog` | Route to `wdi-component`. `spec-after-g4` checks it, and `catalog` skipping G4 is by design, not an exception |
68
+ | An isolated working tree | Isolate first. MUST NOT run in a shared or dirty checkout. Permitted isolation models: an isolated linked worktree (`git worktree add`), or an exclusive primary working tree checked out to the task branch with a clean status dedicated to this task (`.constitution/method/branch-guide.md`). Standing exception: Phase 1 (Open the spec) and Phase 2 (The contract and the tickets) authoring runs directly on `development_branch` (`policy.development_branch`, default `main`) with no code changes; the isolated working tree requirement binds Phase 3 (Ship each ticket) onward |
69
+ | Every `prd` slug names a real `.what/_prd/<initiative>/` folder | A spec without a promise covering it is a spec nobody agreed to (`spec-names-release-prd`) |
70
+ | Development branch verified locally or on remote (`refs/heads/<branch>` or `refs/remotes/origin/<branch>`) | Branch missing. Stop immediately and report to maintainer; MUST NOT guess or silently fall back to `main` (`.constitution/method/branch-guide.md`) |
71
+
72
+ The repo commits straight to the active development branch (`policy.development_branch`, default `main`) during Phase 1 & 2 authoring and opens a PR only when asked. **Invoking this skill is that ask**, for
73
+ this spec only; it MUST NOT be read as standing permission for the next change.
74
+
75
+ ## Phase 1 — Open the spec
76
+
77
+ Record it in `.control/registry/specs.yaml`. The frame opens here; the `tickets` rows land in Phase 2, because
78
+ that is where they are born.
79
+
80
+ | Field | Rule |
81
+ |---|---|
82
+ | `id` | `SPEC-<N>`, monotonic, never reused. A `W<N>` id in a frozen record is a **retired alias** and MUST NOT be rewritten |
83
+ | `release` | MUST be stated. The release↔spec cadence is situational and MUST NOT be inferred from numbering (`spec-names-release-prd`) |
84
+ | `prd` | MUST be stated: which initiative PRDs this spec delivers against. MUST NOT be derived from `release` |
85
+ | `fr` | The `FR` this spec satisfies. Ideally one — an `FR` is human-testable from birth |
86
+ | `size` | `S` · `M` · `L`. MAY be raised mid-flight; MUST NOT be lowered |
87
+ | `depends_on` | At **spec** level. A spec declaring none runs in parallel with its neighbours |
88
+ | `spec_folder` | One per spec, not one per spec × component |
89
+ | `tickets` | Flat, one row per ticket: `id` · `component` · `satisfies: [UC]` · `blocked_by` · `touches` · test names |
90
+ | a ticket `id` | `<spec-id>-<NN>` — `SPEC-3-01`. The engine numbers its files from `01` per feature, which is unique only inside one spec; the RTM needs a key that is unique across the corpus |
91
+
92
+ **`tickets` is an index, not a store.** The ticket's prose lives where the tracker put it; the row carries only
93
+ what RTM and the validators read. And ticket **status** MUST NOT be copied here — it is read from the ticket
94
+ itself when `.control/generated/` regenerates (`ticket-status-one-home`). Two homes for one fact is how registries start lying.
95
+
96
+ `ticket-status-one-home` finds the file at `{spec_folder}/issues/<NN>-*.md`, from the number at the tail of the id, and reads its
97
+ status from either a `**Status:**` body line — what the engine writes, because a ticket file is a tracker
98
+ payload and trackers do not read YAML — or `status:` in frontmatter.
99
+
100
+ The `epics` nesting is **repealed**. A ticket names its `component` directly; an intermediate level that only
101
+ grouped rows bought nothing and cost a lookup.
102
+
103
+ Size does not choose which gates are active — that is `mode`'s job. It decides two things: session merging
104
+ (`S` merges G4 and G5 into one 20-minute session) and whether `SPEC.md` is written at all.
105
+
106
+ ## Phase 2 — The contract, and the tickets
107
+
108
+ Two engines, and **this skill invokes both.** Invoke, then verify and land.
109
+
110
+ | Size | What this skill invokes | What lands |
111
+ |---|---|---|
112
+ | `M` · `L` | `to-spec`, then `to-tickets` | `SPEC.md` in `spec_folder` · ticket files · the `tickets` index rows |
113
+ | `S` | `to-tickets` only | ticket files · the `tickets` index rows. **No `SPEC.md`** |
114
+
115
+ Each invocation carries what the engine would otherwise stop to ask: the tracker is already configured
116
+ in `docs/agents/issue-tracker.md`, the seams and the testing decisions are settled above, and the
117
+ `to-tickets` quiz — granularity and blocking edges — is answered from the size table in
118
+ `delivery-flow-guide.md` plus `depends_on` and `touches`. Under a mandate every one of those answers is
119
+ also a ledger row.
120
+
121
+ At `S` the tickets **are** the contract. `to-tickets` accepts a conversation directly, so a middle document
122
+ buys nothing there. From `M` up it is written first, because two things have to be settled **before** tickets
123
+ are cut and neither survives being decided afterwards: the **seams** the feature will be tested at — fewest
124
+ possible, highest possible, agreed with the owner — and the **testing decisions**, which say what a good test
125
+ is here and name the prior art.
126
+
127
+ ### What you verify before landing anything
128
+
129
+ - **Nothing new.** `SPEC.md` is a **projection** of `.what/` + `.how/`. It MAY restate a promise in its own
130
+ words — a machine contract is more useful self-contained — but **every restatement MUST refer to the live
131
+ corpus document it came from.** A reference that does not resolve is not a wording problem: the gap is
132
+ upstream. Route to `wdi-component` or `wdi-blueprint`, and do not let the contract invent it.
133
+ - **Every user story resolves to an id.** A user story with no `FR` or `UC` behind it is a **new promise**,
134
+ and a new promise is `wdi-product`'s, never a spec's.
135
+ - **Every ticket names what it satisfies.** No `satisfies`, no landing: without it the chain
136
+ `FR → UC → ticket → test` breaks and RTM cannot say which promise went green. This is the one field
137
+ `to-tickets` does not ask for on its own, so it is the one most likely to be missing.
138
+ - **Every ticket is vertical.** A slice of one layer is not a ticket. The exception is a wide refactor,
139
+ sequenced expand → migrate in batches → contract; `delivery-flow-guide.md` owns that rule.
140
+ - **Ticket files land under `spec_folder`, and `spec_folder` is `.scratch/<spec-id>-<slug>/`.** Their
141
+ **shape** is the engine's — one file per ticket, numbered in dependency order, blocking edges declared
142
+ — and the location is ours, written in `docs/agents/issue-tracker.md` where the engines read it. The
143
+ id in front of the slug is not decoration: four live repos wrote that leaf four different ways, one of
144
+ them all four inside a single repo, and a folder nothing can trace back to a row in `specs.yaml` is
145
+ how a spec goes missing. A ticket at the repo root, or under `docs/`, or in a `.scratch/` directory
146
+ with no row in `specs.yaml`, is drift.
147
+
148
+ `SPEC.md` and ticket files **are not read by humans.** Both are machine contracts, and no review burden MAY be
149
+ moved onto them. `wdi-review` MAY still be dispatched over the contract; its trace lands on the spec in
150
+ `specs.yaml` — and where there is no `SPEC.md`, one trace covers the **ticket set as one artifact**, never one
151
+ review per ticket.
152
+
153
+ ## Phase 3 — Ship each ticket
154
+
155
+ Work the **frontier**: the tickets whose blockers are all closed. A ticket whose `blocked_by` is not yet
156
+ satisfied MUST NOT be started, however ready it looks.
157
+
158
+ | # | Step | Engine | Exit condition |
159
+ |---|---|---|---|
160
+ | 1 | Encode | invoke `tdd` | **Failing tests exist that encode this ticket's acceptance criteria** |
161
+ | 2 | Build | invoke `implement` — it uses `tdd` at the agreed seams and calls `code-review` itself | Those tests green, typecheck clean, full suite green once |
162
+ | 3 | Panel | invoke `code-review`, as a **separate** dispatch by a **different** agent | Panel adjudicated, zero unresolved must-fix |
163
+ | 4 | Publish | — | Branch pushed, PR open, ticket-closing checklist answered |
164
+ | 5 | CI | — | All checks conclude green on the pushed head SHA |
165
+
166
+ **Step 1 is the change that matters most.** It used to be a plan, judged from a frontmatter field a builder
167
+ wrote about itself. Now it is a **failing test suite** — the acceptance criteria, encoded, and demonstrably
168
+ red. That is evidence rather than a claim, and it is what `ticket-has-test` and G5's ★2 have always been asking for:
169
+ *acceptance criteria proven by a test, not by an agent's statement.* Under TDD the test exists **before** the
170
+ code, so the proof is not retrofitted.
171
+
172
+ ### Engine rules
173
+
174
+ - **MUST judge Steps 1 and 2 from the test suite**, not from a report and not from a status field. Red at the
175
+ right assertions closes Step 1; green with a clean typecheck closes Step 2. A builder's chat report MUST NOT
176
+ settle either.
177
+ - Ticket **status** is read from the ticket itself. It MUST NOT be copied into `specs.yaml` (`ticket-status-one-home`).
178
+ - Every step MUST start from a **fresh context**, and a fix round MUST NOT go back to whoever produced the
179
+ code. The ticket carries everything the next builder needs, and inherited context is how a step stops judging
180
+ the artifact on its own merits. Where one session runs consecutive steps itself, it MUST re-read the artifact
181
+ rather than trust what it remembers writing.
182
+ - A step handed to a separate agent MUST be launched so it cannot sit waiting for input nobody will give, and
183
+ its start MUST be confirmed from observed activity — never from a readiness match alone.
184
+ - A step that fails because the agent could not spawn what it needed is a **capability** failure, not a ticket
185
+ failure. MUST retry it somewhere that can, and MUST NOT record it against the ticket.
186
+ - MUST NOT reorder or drop a step. A step with nothing to do MUST be reported as such, not skipped silently.
187
+ - A ticket returned by the panel MUST have its acceptance criteria amended and its status reset before it is
188
+ picked up again — see Step 3.
189
+
190
+ ### What every builder brief MUST carry
191
+
192
+ Three rules this corpus adds, and `/implement` knows none of them. All three MUST reach whoever writes code in
193
+ this spec — in the dispatch when a step is dispatched, and in the session's own working instructions when it
194
+ is not.
195
+
196
+ - **Debugging is conditional, never a phase.** When a test or build fails and the cause is not known, the
197
+ builder MUST run `wdi-systematic-debugging` before proposing any fix. A third failed fix attempt is the signal
198
+ to escalate, not to try a fourth.
199
+ - **The corpus is not the builder's to change.** A builder MUST NOT edit `.what/`, `.how/`, or an `applied`
200
+ `DEC-`. A deviation from the SDD or an `AD-N` is **reported**, and it becomes a `DEC-` through
201
+ `wdi-decision` — never absorbed as a code patch.
202
+ - **Verification is run, not assumed.** The commands are this product's, and they live in
203
+ `.constitution/project/codebase-stack-guide.md` — build, test, and whatever the front end needs, each with
204
+ the directory it runs from. A skill MUST NOT carry one product's build line. A green registry workflow
205
+ MUST NOT be reported as proof the code compiles; they answer different questions.
206
+
207
+ ### Step 1 — encode the acceptance criteria as failing tests
208
+
209
+ - The tests MUST be written **at the seams the spec agreed** — existing seams preferred, highest possible,
210
+ fewest possible. Inventing a new seam here, after the agreement, is a finding: it means Step 1 is redesigning
211
+ what Phase 2 settled.
212
+ - Every acceptance criterion MUST have at least one test. A criterion no test can express is not an acceptance
213
+ criterion — it goes back to the ticket, or to the owner as an intent gap.
214
+ - The tests MUST be **seen red, at the right assertions.** A test that passes before the code exists is testing
215
+ nothing, and a suite that fails for the wrong reason — an import error, a missing fixture — has not encoded
216
+ anything yet.
217
+ - A test MUST NOT assert a literal where the behaviour is what matters. The panel treats that as a test that
218
+ cannot fail, and returns it.
219
+
220
+ ### Step 2 — build
221
+
222
+ - The owner runs `/implement`, and it MUST be given the ticket and the three brief rules above.
223
+ - It commits to the current branch and **never pushes**. That is its own behaviour and it is what we want; the
224
+ coordinator is the hand that pushes.
225
+ - **`/implement` calls `/code-review` itself, and that call does NOT satisfy Step 3.** It is the builder
226
+ reviewing its own work — self-review by construction. Step 3 stands as a separate dispatch regardless of what
227
+ ran inside Step 2.
228
+ - The full suite MUST be run green once at the end, not only the tests this ticket touched. A ticket that
229
+ passes its own tests and breaks a neighbour's has not finished.
230
+ - Where the work turns out to need something the ticket does not authorise, it stops and reaches the owner with
231
+ the question verbatim. The builder MUST NOT widen its own scope.
232
+
233
+ ### Step 3 — panel, then judge
234
+
235
+ Panel composition follows `risk_accepted`: at `low` a two-reviewer panel is **required** on the code; at
236
+ `medium` and `high` it is available and SHOULD be used when the diff touches money, personal data, or a third
237
+ party. The local Agent Rules govern which CLIs and models staff the panel. **A reviewer MUST be a different
238
+ agent from the builder** — the builder's own review layers, `/implement`'s internal `/code-review` included,
239
+ are self-review by construction and never satisfy the panel. This is the one separation in the pipeline that
240
+ MUST NOT be collapsed: where the session cannot provide it and `risk_accepted` is `low`, the ticket is blocked
241
+ and the owner MUST be told, because the field they set is what makes the panel required.
242
+
243
+ `code-review` reviews along two axes — **Standards**, against this repo's documented conventions, and
244
+ **Spec**, against what the ticket asked for. Both MUST run. Reporting one axis as the panel is reporting half
245
+ a review.
246
+
247
+ - MUST adjudicate every contested finding by reading the cited lines. Votes MUST NOT settle a finding. A finding
248
+ neither reviewer can locate in the diff is dismissed with that reason stated.
249
+
250
+ **MUST return to Step 2:**
251
+
252
+ - Breaks a ticket's acceptance criterion, or contradicts the contract, the SDD, an `AD-N`, or an `applied` `DEC-`
253
+ - Wrong behaviour, crash, or data loss reachable from the running app
254
+ - Corpus drift: an `LC` touched but not registered, a contract changed in code but not in `02-contracts/`, a
255
+ screen added without its `01-ux/` entry
256
+ - An enum value rendered straight to the screen instead of read off its label map
257
+ - Payment or private data reaching a tracked file
258
+ - A weakened guard, or a test that cannot fail — including one asserting a literal instead of the behaviour it
259
+ claims to cover
260
+
261
+ **MUST record as follow-up and MUST NOT return to Step 2:** style or naming with no behaviour delta · a
262
+ refactor outside this ticket's scope · a pre-existing defect this ticket did not touch · a speculative risk
263
+ with no reachable path.
264
+
265
+ A must-fix MUST return as a **ticket amendment**, never a chat instruction: amend what the ticket asks for,
266
+ note the finding that caused it, reset the ticket's status to `ready-for-agent`, then pick it up again. **What
267
+ a ticket `satisfies` is not amendable here** — that is the promise, and a must-fix rooted in the promise is an
268
+ intent gap that goes to the owner through `wdi-product`. Changing the `FR` a ticket serves in order to make the
269
+ code pass is how a corpus starts agreeing with whatever was built.
270
+
271
+ Cap: **2 return trips.** MUST re-run the whole panel after each fix round — a fix introduces defects. On hitting
272
+ the cap MUST escalate and MUST NOT open a PR carrying an unresolved must-fix.
273
+
274
+ ### When the code turns out to be right and the document wrong
275
+
276
+ This is normal during G5 and it is **not drift**. Building a thing is how you find out what the thing is.
277
+
278
+ The builder still MUST NOT edit `.what/`, `.how/`, or an `applied` `DEC-` to make its own code fit — that is
279
+ the corpus learning to agree with whatever was built, and it is a different failure. What happens instead:
280
+
281
+ 1. **Say it once.** Name what the code does, which promise it contradicts, and what that costs. One place,
282
+ one time. An `AD-N` is the one contradiction that **stops** — `decision-guide.md` owns it.
283
+ 2. **The owner decides.** If they adopt the code, that survey is spent.
284
+ 3. **The owning skill edits**, in the present tense, as if the design had always said this — `wdi-product`
285
+ for an `FR`, `wdi-component` for behaviour or design, `wdi-blueprint` for a cross-component rule.
286
+
287
+ What MUST NOT happen after step 2: raising the same conflict again in a later pass, opening an `OQ-` for it,
288
+ dispatching a review over it, or writing anywhere in the corpus that the change arrived late. The commit is
289
+ that record. `corpus-guide.md` § The corpus is written in the present tense is the binding rule.
290
+
291
+ ### Step 4 — ticket-closing checklist, then push and PR
292
+
293
+ The checklist is **three items**, and it MUST be answered before the PR opens:
294
+
295
+ 1. Something the next person needs to know? → **into the document that carries it**, and that is almost
296
+ always where it ends. It reaches `wdi-decision` only when no design document has a home for it —
297
+ `decision-guide.md` § A decision's first home. A ticket contradicting an `AD-N` **stops** rather than
298
+ closing; that is the one case where recording is mandatory.
299
+ 2. A trap for the next agent? → recorded where the next agent will read it.
300
+ 3. Test names matching what `specs.yaml` records?
301
+
302
+ The five items that left this list moved to Phase 4, where the information actually exists.
303
+
304
+ - MUST run the repository's commit/push audit before `git push`: refuse the forbidden paths, run the guard test,
305
+ fix content on failure. A failing guard is a finding about the content — MUST NOT weaken the guard or the test.
306
+ - MUST NOT push directly to protected branches (`primary_branch` or `development_branch` from `policy:`, default `main`), MUST NOT force-push, MUST NOT merge.
307
+ - The coordinator MUST be the hand that pushes and opens the PR.
308
+
309
+ ### Step 5 — watch CI, then judge
310
+
311
+ - MUST wait for every check to conclude, then confirm the checks belong to the **pushed head SHA**. A green
312
+ report from a stale run is a false report.
313
+ - **A cloud runner is metered, and this step is where the meter runs.** One unit of work earns **one** cloud
314
+ run: the workflow MUST NOT be shaped so that every intermediate push starts one — `ci-guide.md` owns the
315
+ trigger shape, and under a mandate `wdi-autopilot` § Cycle-end CI moves this step's run to § Finish.
316
+ - `korpus.yml` validates the corpus, not the code. Build and test evidence comes from Step 2's own runs.
317
+ - Classify each failure before acting: a defect from this change → Step 1 if the test was missing, Step 2 if
318
+ the code was wrong, with `wdi-systematic-debugging` when
319
+ the cause is unknown · infrastructure or flake → re-run **once**, and MUST NOT patch code to mask it; a second
320
+ identical failure is a defect · a guard failure → fix the content.
321
+ - Cap: 2 return trips. On hitting the cap MUST report red honestly rather than keep pushing.
322
+
323
+ ### Parallel tickets
324
+
325
+ Tickets with no blocking edge between them MAY run at once — that is what the frontier is — but four
326
+ conditions MUST hold: each concurrent builder in its own worktree; `parallel-tickets-blocked` green for every pair released together;
327
+ the first ticket that establishes a component's shape already closed, so later tickets inherit its code map;
328
+ and no shared registry write in flight.
329
+
330
+ **A wide refactor is the exception, and it inverts the rule.** Its batches MUST run in sequence, not in
331
+ parallel, because each keeps CI green only while the expand still stands. Where even a batch cannot stay green
332
+ alone, they share an integration branch and green is promised only at the final integrate-and-verify ticket.
333
+
334
+ The pattern that MUST be preferred: run the biggest blocker alone first, let its shape decisions land, then fan
335
+ out.
336
+
337
+ ## Phase 4 — Close the spec
338
+
339
+ **Six steps.** Run in this order and stop at the first failure.
340
+
341
+ 1. **Registry catch-up.** Every `LC` the spec's design named is registered in `components.yaml`, and every
342
+ `touches` value resolves — `lc-registered`. This is the moment those questions have answers.
343
+ 2. **Inventories refreshed from code.** Run `.constitution/method/scripts/inventory.py`. The plan-versus-reality
344
+ difference is reported as a finding; it MUST NOT be patched into agreement by hand.
345
+ 3. **Structure maps refreshed** through `wdi-init` intent `structure`, if a base folder was born or removed or a
346
+ key file moved.
347
+ 4. **Distillation.** Every applicable row of the ownership table in `corpus-guide.md` has been landed by its
348
+ owner. Anything durable in the spec folder leaves it now, or dies with it — **the ticket files included.**
349
+ Their prose is working output; what survives is the index in `specs.yaml` and whatever the checklist routed.
350
+ 5. **RTM green.** Every traceability row for this spec is closed. New risks are in the risk register with an
351
+ owner.
352
+ 6. Mark the spec `status: closed` in `specs.yaml`.
353
+ 7. **Housekeeping (Archive or Prune).** Once marked closed, offer the maintainer the choice to clean up
354
+ the completed spec directory from `.scratch/<spec-id>-<slug>/` using `/wdi-prune-or-archive`:
355
+ - **Archive:** `/wdi-prune-or-archive --spec <spec-id> --archive` (moves the directory to `.archive/specs/<spec-id>-<slug>/` and updates `spec_folder` in `specs.yaml`).
356
+ - **Prune:** `/wdi-prune-or-archive --spec <spec-id> --prune` (removes the completed spec directory from git and disk while preserving RTM history in `specs.yaml`).
357
+ If the maintainer declines or defers, leave the directory in `.scratch/`.
358
+
359
+ The retrospective step is **repealed**, and `RTR-` with it. It was the only thing size `L` decided, and the
360
+ only thing `V19` checked.
361
+
362
+ - You MUST NOT close a spec with an open distillation row. The whole point of an ephemeral working layer is that
363
+ durable truth leaves it first.
364
+ - You MUST NOT reopen a closed spec to add scope. Scope arriving late opens a new spec, or goes through
365
+ `wdi-decision` if it invalidates what is already planned.
366
+ - A change invalidating more than 30% of a spec's tickets MUST go through `wdi-decision`, not a patch to
367
+ `specs.yaml`.
368
+ - Fast Path work is recorded as `fastpath` with no gates. If an `FR` turns out to be touched, the work MUST stop
369
+ and be raised to a spec `S`.
370
+
371
+ ## Red Flags — STOP
372
+
373
+ - "One reviewer approved, good enough"
374
+ - Judging Step 1 or Step 2 from a report instead of from the test suite
375
+ - **Counting `/implement`'s own `/code-review` as the panel** — that is the builder reviewing itself
376
+ - Writing `SPEC.md` at size `S`, or skipping it at `M` and up
377
+ - Landing a ticket with no `satisfies` — the RTM chain breaks silently and nothing else notices
378
+ - Amending what a ticket `satisfies` to make a must-fix go away
379
+ - A ticket that slices one layer instead of cutting through all of them, outside a wide refactor
380
+ - Running a wide refactor's batches in parallel
381
+ - Claiming this skill invoked `to-spec`, `to-tickets`, or `implement` — it cannot; the owner runs them, or under
382
+ a mandate a builder reads and follows them, and the ledger says so
383
+ - A builder editing `.what/`, `.how/`, or an `applied` `DEC-` to make its code fit
384
+ - Fixing a failing test without knowing why it failed
385
+ - Opening a PR with an unresolved must-fix, or before the ticket-closing checklist is answered
386
+ - Editing a guard, a test, or an assertion to turn something green
387
+ - Reporting green without checking the head SHA, or reading green `korpus.yml` as a passing build
388
+ - Leaving a dispatched step able to stall on a question nobody is there to answer
389
+ - Naming an orchestration tool as this skill's requirement, or restating a CLI/model mapping the Agent Rules own
390
+ - Closing the spec without the registry catch-up in Phase 4 — that is where five checklist items now live
391
+ - Letting the contract state something `.what/` and `.how/` do not, or restate it without a reference
392
+
393
+ **Each of these means: stop, return to the step or phase that owns it, or escalate to the owner.**
394
+
395
+ ## Output
396
+
397
+ MUST follow the Agent Rules `Answer Closing` block, carrying these additions:
398
+
399
+ - **what was done** — spec, `FR` satisfied, every ticket with its branch and PR URL, what the code now does
400
+ - **what blocked it** — every step that looped, every dismissed finding and why, anything left red, and every
401
+ Phase 4 item that did not pass
402
+ - **what comes next** — every finding recorded as follow-up, every entry in a contract's `deferred` list, every
403
+ ticket-closing item routed to another skill, and the plan-versus-code inventory differences. A follow-up
404
+ absent here is a lost finding.