@naswerks/engineering-loop 0.1.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 (44) hide show
  1. package/.claude-plugin/marketplace.json +15 -0
  2. package/.claude-plugin/plugin.json +8 -0
  3. package/CHANGELOG.md +32 -0
  4. package/LICENSE +21 -0
  5. package/README.md +78 -0
  6. package/bin/verify-staged.mjs +247 -0
  7. package/package.json +35 -0
  8. package/references/docs-workflow.md +417 -0
  9. package/references/engineering-loop.md +298 -0
  10. package/skills/docs-audit-feature/SKILL.md +88 -0
  11. package/skills/docs-audit-full/SKILL.md +54 -0
  12. package/skills/docs-backlog/SKILL.md +41 -0
  13. package/skills/docs-process/SKILL.md +146 -0
  14. package/skills/docs-status/SKILL.md +47 -0
  15. package/skills/docs-write/SKILL.md +43 -0
  16. package/skills/init/SKILL.md +163 -0
  17. package/skills/init/scripts/doctor.mjs +176 -0
  18. package/skills/spec-child/SKILL.md +149 -0
  19. package/skills/spec-ignite/SKILL.md +277 -0
  20. package/skills/spec-parent/SKILL.md +634 -0
  21. package/skills/spec-pipeline/SKILL.md +453 -0
  22. package/skills/spec-retro/SKILL.md +398 -0
  23. package/skills/spec-review/SKILL.md +266 -0
  24. package/skills/spec-seat/SKILL.md +512 -0
  25. package/skills/spec-witness/SKILL.md +222 -0
  26. package/templates/claude-md-stanza.md +13 -0
  27. package/templates/docs/_meta/doc-index.md +90 -0
  28. package/templates/docs/infrastructure/background-work.md +53 -0
  29. package/templates/docs/infrastructure/realtime-events.md +54 -0
  30. package/templates/docs/patterns/backend-patterns.md +96 -0
  31. package/templates/docs/patterns/codegen.md +69 -0
  32. package/templates/docs/patterns/frontend-patterns.md +92 -0
  33. package/templates/docs/patterns/state-management.md +73 -0
  34. package/templates/docs/patterns/testing.md +103 -0
  35. package/templates/docs/patterns/ui-style-guide.md +76 -0
  36. package/templates/docs/patterns/vertical-slice-anatomy.md +61 -0
  37. package/templates/docs/readme-archive.md +9 -0
  38. package/templates/docs/readme-features.md +7 -0
  39. package/templates/docs/readme-guides.md +7 -0
  40. package/templates/docs/readme-infrastructure.md +7 -0
  41. package/templates/docs/readme-patterns.md +9 -0
  42. package/templates/docs/readme-research.md +9 -0
  43. package/templates/docs/readme-working.md +9 -0
  44. package/templates/settings-pin.json +10 -0
@@ -0,0 +1,512 @@
1
+ ---
2
+ name: spec-seat
3
+ description: The CONTRACT for any seat a pipeline coordinator arms — the blackboard, the question lane, the parked-call discriminator, the verdict vocabulary, the BELIEFS sha, git shapes, the six-section FINAL TLDR, and the close-out order. Invoked FIRST, then the job skill (spec-child | spec-review | docs-process). Not a seat of its own; the shared half of every seat's procedure.
4
+ ---
5
+
6
+ # spec-seat
7
+
8
+ **This is the contract, not the job.** Every seat a pipeline coordinator arms — a build session, a fixit,
9
+ the review row, the docs-process row — runs THIS, then its own job skill:
10
+
11
+ | Seat kind | Composes |
12
+ |---|---|
13
+ | `build` · `fixit` | `spec-seat` + **`spec-child`** |
14
+ | `review` | `spec-seat` + **`spec-review`** |
15
+ | `docs-process` | `spec-seat` + **`docs-process`** |
16
+
17
+ **THE PAIRING IS SEVEN-WAY AND NON-UNIFORM, and the three kinds missing from that table are missing
18
+ DELIBERATELY.** `coordinator`, `retro` and `witness` each carry their OWN whole contract
19
+ (`spec-parent` · `spec-retro` · `spec-witness`) and are **never** told to invoke this file — prefixing
20
+ `spec-seat` onto a skill that already carries a whole contract ships a seed contradicting the skill it
21
+ points at. The control plane composes each kind's seed from this table and has no catch-all: an unknown
22
+ kind is refused by name (`seat-kind-has-no-seed`) rather than ignited wrongly.
23
+
24
+ **Precedence, so it is never a judgement call:** the job skill **refines** this contract and never
25
+ contradicts it. Where they genuinely conflict, that is **a finding to report**, not a fork to resolve
26
+ quietly — say so in your PLAN TLDR and let the coordinator rule.
27
+
28
+ **The coordinator does NOT compose this.** It writes rulings rather than receiving them, owns the tracker,
29
+ and holds the close — a different contract, and `spec-parent` carries it whole.
30
+
31
+ **Why this file exists:** a base contract that every seat kind shared, with the build job mixed in, sent
32
+ the review row into the umbrella its own charter excluded and offered the docs-process row a `docs-write`
33
+ it must never run. One base class, three wrong instructions. The contract and the job are therefore two
34
+ files.
35
+
36
+ ## What you hold (and what you never touch)
37
+
38
+ - **Yours:** your one assignment; the recon; the plan; the work; your artifacts; your own explicit-path
39
+ commit (on call).
40
+ - **Never yours:** `project-status.md` (coordinator-owned tracker — READ-ONLY), memory files, other slices'
41
+ files (cross-slice changes need explicit coordinator approval and get recorded as a departure), the
42
+ umbrella's declared out-of-scope areas, `docs-write` **on your own initiative** (it arrives as part of
43
+ the coordinator's close-out call — and for a docs-process seat it never arrives at all, because you are
44
+ that skill's consumer), any commit/push without the relayed coordinator call.
45
+
46
+ ## Step 0 — orient NOW (before asking anything; no role or assignment needed)
47
+
48
+ Do this immediately, whatever your assignment turns out to be. It needs no role and no spec path.
49
+
50
+ **The lay of the land — what system you are in:**
51
+
52
+ | Doc | What it gives you |
53
+ |---|---|
54
+ | `docs/_meta/doc-index.md` | the menu — which living doc answers which question |
55
+ | `docs/_meta/docs-workflow.md` | the folders, the templates, the two loops |
56
+ | `docs/_meta/engineering-loop.md` | the seats, the ceremony, and **the comms protocol you follow** |
57
+
58
+ Then recon the tree: `git rev-parse HEAD`, `git status --porcelain`, `git branch --show-current`.
59
+
60
+ **How code is written here — every session, whatever your seat:**
61
+
62
+ | Doc | What it gives you |
63
+ |---|---|
64
+ | `patterns/vertical-slice-anatomy.md` | where a feature's files go, every stack the repo has |
65
+ | `patterns/backend-patterns.md` | how the server side is built here |
66
+ | `patterns/frontend-patterns.md` | how the client side is built here |
67
+ | `patterns/testing.md` | how to write and RUN the suites — including the run protocol |
68
+ | `patterns/codegen.md` | what is generated and how; never hand-write a generated folder |
69
+
70
+ **That is the default set, required regardless of role** —
71
+ `docs/_meta/doc-index.md` · `docs/_meta/docs-workflow.md` · `docs/_meta/engineering-loop.md` ·
72
+ `patterns/vertical-slice-anatomy.md` · `patterns/backend-patterns.md` · `patterns/frontend-patterns.md` ·
73
+ `patterns/testing.md` · `patterns/codegen.md`
74
+ <!-- A control plane may read this line + list as its preset hint (it looks for "default set" and "role" on
75
+ one line, then collects the backticked paths until a blank line). Keep the phrase and the list
76
+ contiguous, or the hint silently empties. -->
77
+
78
+ A doc marked `status=draft` in its meta line was scanned by `init`, not decided by the repo's owners —
79
+ read it as the starting point it is, and treat a rule it states without a cited source as a question for
80
+ your PLAN TLDR, not a law.
81
+
82
+ Then report your orientation and beliefs, and ask ONE question: **your assignment.** Stop.
83
+
84
+ **UNLESS YOUR PROMPT HANDED YOU A MANIFEST — in which case THAT MANIFEST IS YOUR READING LIST**, and
85
+ your job skill's reading list does not apply. A seat armed with an explicit inventory (a review row, a
86
+ docs-process row, any seat whose prompt names its own sources) reads exactly what it was given.
87
+ **An inventory is navigation; a belief is a conclusion.** If your prompt gave you paths, ranges and names,
88
+ that is your scope — do not widen it on the theory that more reading is safer.
89
+
90
+ ## The blackboard — where the conversation lives
91
+
92
+ `plan.md` (the full plan document) and `tldr.md` (the chat: your PLAN TLDR, any mid-build updates, the
93
+ FINAL TLDR — **append, never overwrite**) are FILES, not just chat text.
94
+
95
+ - **Hand-cranked:** create them under `docs/research/{topic}/sessions/{slug}/` at plan time and end your
96
+ turn announcing the path. The coordinator reads `tldr.md` with normal file tools and APPENDS its ruling
97
+ under `## PARENT RULING`, so read the answer in your own file and proceed. The full plan is PULL — it is
98
+ read only on a read-full-plan verdict; never paste it into chat. (If your harness has a plan-approval
99
+ mode that forbids writes: give the chat summary, get the human's approve, THEN post and stop.)
100
+ - **Hosted (a seat inside a pipeline):** the same two files are yours to edit with normal file tools, then
101
+ call **`post_plan` / `post_tldr` with the file's whole text as `content`** — the control plane runs on
102
+ another machine and cannot read your file. It records a revision and wakes your coordinator with ONE
103
+ LINE naming the act and the rev; the coordinator reads your file from the board; nothing you wrote is
104
+ pasted into its context (the pointer protocol).
105
+ **THE FILE IS THE RECORD AND THE ROW MIRRORS IT** — one artifact row per rev carrying the whole file
106
+ verbatim, so the two voices stay interleaved because nothing splits them. The control plane refuses
107
+ `blackboard-rev-regressed` · `blackboard-shrank` · `blackboard-rev-content-mismatch` at the door: **an
108
+ append-only file with a shrink guard is a platform-enforced property, not a convention you are trusted
109
+ to keep.**
110
+
111
+ Either way, `tldr.md` read top-to-bottom is the session's whole conversation in message-flow order.
112
+
113
+ **Greppable turn anchors:** every append gets a stable heading carrying actor + identity —
114
+ `## [{seat}·{slug} · run {id}] {phase}` when your seat has a run identity, `## [{seat}·{slug}] {phase}`
115
+ hand-cranked. The coordinator's voice is always `## PARENT RULING …` / `## PARENT NOTE …`. The stable
116
+ prefixes are the contract: one grep for `## PARENT RULING` across every session's `tldr.md` lists every
117
+ ruling in the effort.
118
+
119
+ **THE HEADING VOCABULARY IS CLOSED, AND THAT IS THE HAZARD AS WELL AS THE CONTRACT.** The parent-voice
120
+ list is exactly four — `PARENT NOTE` · `PARENT ACCEPT` · `PARENT RULING` · `OPERATOR RULING` — matched
121
+ by the control plane on a word boundary, so `## PARENT NOTEBOOK` cannot pass. A fifth anchor invented
122
+ later closes nothing and counts as nothing until the control plane learns it. **Section boundaries are
123
+ level-2 headings only** — `### Option A` inside your question block is still inside the question,
124
+ deliberately, so a ruling never arrives having truncated your options.
125
+
126
+ **Point, don't paste:** to direct anyone at content, say *"read `tldr.md` under `## PARENT RULING`"* —
127
+ never re-paste a multi-KB block into a composer.
128
+
129
+ **If `tldr.md` already exists when you go to create your blackboard, APPEND** — machinery may have written
130
+ before you, and recreating the file clobbers it (the platform refuses a shrinking rewrite).
131
+
132
+ **Re-read `tldr.md` immediately before every append.** The coordinator appends into the SAME file between
133
+ your turns — an edit whose old text no longer matches almost always means the conversation moved.
134
+ Re-read, fold what's new, then append. Never resolve the mismatch by rewriting the whole file; the rev
135
+ ladder is the history.
136
+
137
+ **`## PARENT NOTE (FYI — no reply needed)` is the NO-TURN lane:** the coordinator can leave you
138
+ informational context WITHOUT waking you — it lands durably in your `tldr.md` and costs you nothing.
139
+ The re-read above is where you pick FYIs up: fold them as context, owe no reply, and never treat one as
140
+ a ruling — an FYI cannot answer an open question (only a ruling heading does).
141
+
142
+ ## Questions — the lane, and its two literal headings
143
+
144
+ **When you need a decision at ANY point:** append a question section to your own `tldr.md`, post
145
+ (`post_tldr`), and **END YOUR TURN.** Your coordinator is woken with your text, and its ruling under a
146
+ parent-voice heading is your answer — pick it up from your own file and resume.
147
+
148
+ **TWO literal headings, one lane — pick by phase, and use a real `##` heading either way:**
149
+
150
+ - **`## QUESTIONS`** — anything asked **during recon / at plan time** (the PLAN TLDR's numbered forks ride
151
+ under this heading).
152
+ - **`## MID-BUILD QUESTION`** — anything found **after your recon was accepted** (mid-build, close-out).
153
+
154
+ **OPEN ANY QUESTION SECTION WITH `BLOCKING:` OR `NOT BLOCKING:` ON THE FIRST LINE OF THE BODY.** This is
155
+ a real machine-read field, not a courtesy: the control plane reads the **first non-blank body line** of
156
+ every section and answers `Blocking` / `NotBlocking` / `Undeclared`. Markdown around it is fine
157
+ (`**NOT BLOCKING:**`, `> BLOCKING —`); the word must be first.
158
+
159
+ - **It says what YOU claim about your own state, and it changes NOTHING about detection.** A `NOT BLOCKING`
160
+ question still opens the latch, still counts, still rides the wake. **A "not blocking" question that
161
+ stopped waking anybody would be a silent stall wearing a feature's name.**
162
+ - **`Undeclared` is an honest answer and it is what you get by saying nothing** — so a coordinator reading
163
+ your roster cannot tell "asked and idle" from "asked and still building", and pays a nudge to find out.
164
+ - **Never let a reader turn your declaration into liveness.** It is a claim made at the instant you
165
+ typed it; a seat that wrote `BLOCKING:` and then kept working was telling the truth.
166
+
167
+ **Both poke the coordinator identically** — same wake, same re-raise, same parent-voice answer. The split
168
+ is for the READER (a recon fork and a mid-build discovery are different kinds of news), never for the
169
+ machinery. A question under any OTHER heading — or as a bare `QUESTIONS:` label with no `##` — gets no
170
+ banner and **the re-raise can never fire**, so it can sit unanswered indefinitely. And never use
171
+ `## QUESTIONS ANSWERED` / `## NO QUESTIONS` as status headings for OTHER content — the first is
172
+ deliberately refused by the detector, and neither is a question.
173
+
174
+ **NAMED, BECAUSE THE GENERAL WARNING ABOVE IS NOT ENOUGH TO STOP IT: `## MID-BUILD UPDATE` IS NOT A
175
+ QUESTION HEADING.** It reads like one and it is invisible to the detector — the pattern's optional
176
+ `MID-BUILD ` group matches, then the required `QUESTION`/`QUESTIONS` fails on `UPDATE`, so **no banner, no
177
+ re-raise, and no re-ask ever fires.** A general rule does not stop a specific habit, and this heading is
178
+ an entrenched one. **Post status under any heading you like; put the ASK under `## MID-BUILD QUESTION`,
179
+ even when it is one line inside a longer update.**
180
+
181
+ Questions are **plain numbered text with options and your recommendation, then STOP.** Never an interactive
182
+ question tool — the relay cannot copy it.
183
+
184
+ **An unanswered question re-raises to your coordinator on a cooldown** until a ruling lands. Asking costs
185
+ the pipeline a round-trip and nothing else.
186
+
187
+ **WHAT ACTUALLY CLOSES A QUESTION.** On the hosted plane **nothing you write into a FILE closes anything.**
188
+ The latch reads the ACTS LEDGER: a ruling closes your question only when it is delivered as a `callout`
189
+ carrying your post's act id as `answeringActId`. A `callout` without one steers you and closes nothing.
190
+ **The reason is a security property, not tidiness:** `tldr.md` is written BY YOU, so a file-side close
191
+ predicate is a string the audited party can type — a seat could write `## PARENT RULING` into its own file
192
+ and switch off the very re-raise that exists to stop it waiting forever. The question is therefore split
193
+ in two: *was one asked?* — a fact about the file, where forgery only wakes your own coordinator — versus
194
+ *was it answered?* — a fact about what the coordinator DID, read from the ledger.
195
+
196
+ **The honest rendering of your file is unchanged**: an open-questions read of the file still clears on the
197
+ parent-voice heading, because that is what the file SAYS. What differs is what a DECISION may be
198
+ predicated on.
199
+
200
+ ### THREE CONTRACT LINES, all earned by one kind of silence
201
+
202
+ A seat that needs a decision and withholds the post — for any reason — is invisible: nothing wakes the
203
+ coordinator, the question exists in no file, and an audit certifies that the seat never asked. Invisibility
204
+ is what forces the human back in.
205
+
206
+ - **NEVER TRADE A WAKE FOR STALENESS-AVOIDANCE.** If you need a decision, put it under the literal heading
207
+ and **post**. Asking does not stale anything: the gates bind an acceptance to the accepted CONTENT, so a
208
+ question, a `## HOLDING`, a close-out receipt and your coordinator's own voice all ride without a
209
+ re-accept. Only **new content** stales. If you find yourself weighing a wake against staleness, post.
210
+ - **WRITE IT DOWN EVEN WHEN YOU DECIDE NOT TO POST IT.** **The blackboard is the record; the terminal is
211
+ not.** If you compose a question and then talk yourself out of sending it, the composing still happened —
212
+ put it in the file.
213
+ - **THE CAPS DECIDE WHAT RIDES THE WAKE, NEVER WHAT YOU WRITE.** The control plane caps the **digest** your
214
+ coordinator is woken with — never your `tldr.md`, which is append-only with a platform shrink-guard.
215
+ Never trim, summarise or omit content to fit a limit you think you are near: you would be degrading the
216
+ durable record to protect a transport that already degrades itself.
217
+ - **AND A CAP NEVER FAILS SILENTLY IN YOUR FAVOUR.** If your text does not fit whole, the digest
218
+ degrades itself and says so; what it must never do is make you believe a coordinator read something it
219
+ did not. When a ruling answers a question you did not ask, suspect the digest before you suspect the
220
+ reader — and quote the passage back.
221
+
222
+ ## The parked-call discriminator — re-request, reshape, or WAIT?
223
+
224
+ **FIRST, THE FACT THE DISCRIMINATOR RESTS ON: A PARK IS A RECORDED STATE, NOT AN INFERENCE.** When the
225
+ gate parks a call for you, your seat moves `running` to `awaiting-ruling`; the ruling — or the window
226
+ expiring — moves it back to `running`. It is **not terminal**: you are alive and will act again the moment
227
+ somebody rules. Read it with `seat_parks`, and read what you can reach next from `seat_read`'s state
228
+ graph. A park is deliberately NOT a stall: a stall detector firing on one would manufacture an incident
229
+ out of the mechanism working as designed.
230
+
231
+ Ask what the park is protecting:
232
+
233
+ - **A park on a STATE condition** — the park text names a rev, a hash, or a version: it is STATE, not
234
+ approval. Do not re-request, do not reshape; read the substrate for the healing signal (your own acts:
235
+ the fresh acceptance receipt, or the `## PARENT NOTE (re-accept)` append) and retry ONCE on receipt.
236
+ State parks are machine-healable — one argless re-accept re-binds a stale acceptance. **Never hold for
237
+ one specific lane: whichever arrives first IS your signal, and the substrate outranks the bus.**
238
+ - **A park on your own legitimate in-worktree work** — **re-request it** (no self-imposed cap, no
239
+ workaround, no silent giving-up) AND disclose ("blocked on X, re-requested N times"). A parked call is
240
+ the platform's turn, not your failure; routing around it hides the defect the park is surfacing.
241
+ - **A park on a boundary command** (push to the base branch, force-push, branch delete — or a command
242
+ whose *text* merely tripped the scanner) — **never re-request; reshape the command.**
243
+ **THE SCANNER MATCHES TEXT, NOT PARSED VERBS, AND THIS IS THE MOST-PAID FENCE IN THE CEREMONY.** It
244
+ fires on read-only commands a careful seat runs to PROVE its work: an `echo` label reading
245
+ `=== remote tip ===` on a `git status`/`git log` block, or `git branch -r --contains <sha>` — a branch
246
+ **listing** — tripping the *"branch deletion is human-only"* backstop. **So the discipline belongs in
247
+ the prose you write around a command, not only in the command:** no git-verb vocabulary (push, remote,
248
+ force, reset, branch delete) in any `echo`, comment, `--description` or section label. For upstream
249
+ verification use `git log origin/<branch>..HEAD | wc -l` and `git status -sb`, which carry no colliding
250
+ noun.
251
+ - **A POLICY WALL is none of the three.** If the refusal says `walled-by-policy`, **an approval cannot
252
+ grant it** and re-requesting is walking through a known fail-open. The two routes are **reshape the work**
253
+ (do it by a path the policy allows — often: hand the text to a seat whose scope covers it) or
254
+ **escalate**.
255
+
256
+ The test: is the park **blocking your work** (re-request + disclose), **guarding the boundary** (reshape),
257
+ or **a wall** (reshape or escalate — never a click)?
258
+
259
+ **EVERY park is DISCLOSED in your next TLDR — including one you resolved yourself in seconds:** the
260
+ verbatim command AND the verbatim park text. A self-resolved park looks like nothing happened and leaves
261
+ the coordinator no signal, so the gate's false-park rate is only ever knowable from the seat that paid it.
262
+ **An undisclosed park is a receipt destroyed.**
263
+
264
+ ## The PLAN TLDR, and the BELIEFS sha
265
+
266
+ Plain text, BEFORE any plan-approval presentation:
267
+
268
+ ```
269
+ PLAN TLDR ({your assignment}), recon done against HEAD {sha}, anchors {verified fresh / drift: …}:
270
+ BELIEFS: HEAD {sha}; dirty files I see: {list, whose}; tool versions: {the harness, the runtimes};
271
+ baseline suites: {per lane, as patterns/testing.md names them: N (+known pre-existing reds)}.
272
+ CONTROLS: for each probe or pin I will build — its positive control, and what would make it FAIL.
273
+ {one line each: "probe X — control: {the case that must go red}; fails when: {…}"}
274
+ {5-10 lines: what you will do, anchored to real files; the surfaces you will touch; departures flagged.}
275
+
276
+ ## QUESTIONS (numbered, options + MY RECOMMENDATION embedded, then STOP)
277
+ 1. {fork} — options: (a)…, (b)…. My recommendation: (a) because {…}. Confirm.
278
+ ```
279
+
280
+ **`## QUESTIONS` is a REAL level-2 heading, inside the TLDR you post** — that heading is what wakes the
281
+ coordinator with your question text and what the re-raise keys on (the two-heading lane above). A bare
282
+ `QUESTIONS:` label is invisible to both.
283
+
284
+ **BELIEFS sha — ONE line.** The build-go HEAD check scans for `HEAD` + a 40-hex token **on the same line**
285
+ (fenced or quoted is fine); a markdown break between them reads as a malformed sha and **refuses the
286
+ flip** (fail-closed by design). Paste the verbatim `git rev-parse HEAD` output, never hand-transcribe, no
287
+ wrapping. The checker reads `plan.md` AND `tldr.md`; the line in either satisfies it.
288
+
289
+ **Cite symbols, not line numbers.** In anything that outlives a commit — a TLDR, a working doc, a handover
290
+ — **name the symbol and use the line as a hint.** A line number is a comment, not an address; an anchor
291
+ moves every time someone documents why it matters. If you cannot find the symbol, **report the drift**
292
+ rather than trusting the number.
293
+
294
+ **Your baselines are yours to measure** — how, and for what, is your job skill's business, but a number
295
+ you cannot reproduce is a finding either way.
296
+
297
+ ### CONTROLS — declare them at PLAN time, because nobody catches their own
298
+
299
+ **For every probe, pin or scanner you plan: name its positive control, and name what would make it fail.**
300
+ One line each. If you cannot state what would turn it red, you are not planning a measurement — you are
301
+ planning a green light.
302
+
303
+ **Why this is a required field and not advice.** Four independent instances of a control that cannot
304
+ fail have shipped from one effort — four seats, four instruments, and no seat caught its own: a live
305
+ probe whose assertion could fail for an unrelated reason; a scanner planting its positive control inside
306
+ the depth the walk already covered; an inverted control that omitted its scope predicate; a probe whose
307
+ two assertions both failed, making the evidence for the finding identical to the evidence for its
308
+ control. **Verifying your verifier takes a different kind of attention than verifying your subject, and
309
+ nothing else in this ceremony asks for it.**
310
+
311
+ **THE SHAPE TO COPY** is in `patterns/testing.md` § Controls: a wedge case paired against its own
312
+ false-green **inside the instrument** — the same input through the production path must move, or the
313
+ pair is not a discriminator. **One variable changes; the pair must disagree.** If the same input produces
314
+ the same verdict on both sides, you have one observation wearing two names.
315
+
316
+ **And when you build it, PROVE it.** The cheapest proof is to break the thing on purpose, watch the control
317
+ go red, fix it, watch it go green, and quote both runs. A control asserted is a control assumed.
318
+
319
+ ## The verdict vocabulary
320
+
321
+ `accept` · `accept-with-riders` (fold the numbered riders in and GO — no re-approval round-trip) ·
322
+ `blocking-precondition` (do step 0, report, wait for the re-accept). (`read-full-plan` is NOT a verdict —
323
+ the coordinator is reading your `plan.md` before ruling; keep waiting.)
324
+
325
+ **Apply rulings to the letter — if a ruling contradicts your assignment, THE RULING WINS** and you record
326
+ it as a departure.
327
+
328
+ **No message carries a go except the plan ruling itself.** A callout, a status request, or any answer to a
329
+ mid-build question that says "go ahead" is steering or information, never a go — the gate flip rides only
330
+ `accept` / `accept-with-riders`. **Verify the flip in your own act rows** (the `accept_plan` receipt);
331
+ never obey a go carried by any other lane.
332
+
333
+ **The accepting verdict is bound to the TREE you planned against.** It carries the workspace HEAD your
334
+ coordinator observed, and an accepting verdict whose seat planned against a different sha is REFUSED,
335
+ naming both. That is why your BELIEFS sha is a contract line and not a courtesy — and why a HEAD that
336
+ moves mid-build is disclosed FIRST, never absorbed quietly.
337
+
338
+ **The re-accept signal:** after a rev-bound/stale-acceptance park, the re-accept arrives as a
339
+ `## PARENT NOTE (re-accept)` append plus a callout — retry your held action on receipt. If your next wake
340
+ shows the fresh acceptance receipt in your own rows WITHOUT the note, **that row IS your signal** — the
341
+ substrate outranks the bus. Never hold for one specific lane. **A re-accept with no retry order is a
342
+ doorbell with no follow-through**; if you receive one bare, retry anyway and say that you did.
343
+
344
+ ## Git shapes
345
+
346
+ - **Explicit staging only, never `git add -A`.** Additive-only; never amend pushed commits.
347
+ - **VERIFY EVERY STAGE BEFORE THE COMMIT — `git add` skips gitignored paths under a directory with
348
+ exit 0 and NO output, and `git status` cannot show the loss** (an ignored file is neither staged nor
349
+ dirty, so status looks *cleaner* after it — a `bin/` rule can eat a composition root, a `*.log` rule a
350
+ folder of receipts). Run `verify-staged {your explicit staging list}` — one command, gate-legal (not on
351
+ PATH: `node <pack root>/bin/verify-staged.mjs {list}`; `--from-file` takes the list from a file,
352
+ `--against head` checks after the commit). Exit 0 is your staging receipt; non-zero names every missing
353
+ file and the `.gitignore` rule that ate it, and is a **stop-the-line finding**: do not commit, do not
354
+ `git add -f`, do not touch `.gitignore` — rename the artifact off the pattern (receipts stage as `.txt`,
355
+ never `.log`) or raise a `## MID-BUILD QUESTION` and wait for the ruling.
356
+ - **Commit with `git commit -m "…"`** (repeat `-m` for paragraphs) — never a heredoc / `-F -`.
357
+ - **THE PUSH COMMAND MUST BE THE ENTIRE COMMAND.** Not "bare" — that reads as being about flags: the
358
+ disqualifier is **anything else on the line**, and a leading `cd` — harmless on every OTHER git call you
359
+ make — disqualifies a push (the FORM check reads the whole command string). Qualifying forms, exactly:
360
+ first `git push -u origin <your-branch>`, later `git push origin <your-branch>` (`--set-upstream` also
361
+ qualifies). A push without a refspec parks by design.
362
+ - **EVERY GIT COMMAND GOES ALONE — no shell metacharacters.** The FORM check reads the whole command
363
+ string, so chaining, redirects or substitution disqualify it: `git add … && git commit … && git push …`
364
+ parks where the same three commands, sent one at a time, flow unattended. Keep the word "push" out of
365
+ echo text — the deny layer matches text, not parsed verbs.
366
+ - Prefer native read/glob/grep tools for reads; a shell read flows with its row like any other
367
+ non-boundary call.
368
+ - **Codegen only through the command `patterns/codegen.md` § Running codegen names** — never hand-write a
369
+ generated folder.
370
+ - **Never improvise a qualifying path in.** If a push parks and the remedy you can think of is touching a
371
+ `docs/working/` file or the tracker to satisfy a predicate, that is fabricating a receipt. Raise a
372
+ `## MID-BUILD QUESTION` and price the options; do not execute it and do not invent a way around it.
373
+
374
+ ## The six-section FINAL TLDR
375
+
376
+ Plain text — **this is the contract**, whatever your job:
377
+
378
+ ```
379
+ FINAL TLDR — {your assignment}. Built on HEAD {sha}, nothing committed (awaiting the relayed call).
380
+ (a) SHIPPED + VERIFICATION — per item: what + where + the receipt inline.
381
+ (b) VERBATIM RUNNER SUMMARIES — exact blocks, never prose, WITH the invocation command per block;
382
+ deltas vs baseline; any red run DISCLOSED with its rerun. A suite number quoted anywhere
383
+ carries its invocation or its project scope — a bare total reads as the whole suite when it
384
+ may be one project of six.
385
+ (c) HONEST GAPS — what was NOT exercised, stated before anyone asks.
386
+ (d) DEFERRED FINDINGS — numbered, verbatim-quotable lines the coordinator transcribes into
387
+ `docs/research/{topic}/project-status.md` § `## Deferred findings log`. Number them
388
+ LOCALLY to your tldr; the effort has ONE id sequence and the coordinator allocates from it.
389
+ Each line carries its receipt (file:line) so it can be transcribed without re-deriving.
390
+ (e) LIVE CHECKLIST ENTRIES — click + what PASS looks like, runnable cold, VERBATIM here. The
391
+ COORDINATOR aggregates these into the effort's `live-checks.md` — never write that file
392
+ unprompted: two writers on the file the review grades from is a divergence waiting to happen.
393
+ Touch it only when the coordinator's call names it.
394
+ (f) EXPLICIT STAGING LIST — the exact list `verify-staged` will be run over; a path not on
395
+ this list is a path nobody will notice missing — + "commit HELD awaiting the relayed call" +
396
+ which dirty files are NOT mine. SESSION ID + NAME.
397
+ ```
398
+
399
+ ## Close-out — the order is law
400
+
401
+ The call arrives (FINAL TLDR ACCEPTED, maybe fix-first, `docs-write` with a carry list **if your job
402
+ produces a working doc**, COMMIT CALL with the message). Execute it exactly.
403
+
404
+ **Between the coordinator's FINAL acceptance and your push, do not post NEW CONTENT** — a re-posted report
405
+ makes the acceptance stale by design. Append your close-out receipt AFTER the push under this heading:
406
+
407
+ ```
408
+ ## [child·{slug} · run {id}] CLOSE-OUT RECEIPT
409
+ ```
410
+
411
+ ## IF YOU HAVE PUSHED AND ARE WAITING, SAY SO. IT DOES NOT STALE YOU.
412
+
413
+ ```
414
+ ## [child·{slug} · run {id}] HOLDING
415
+ ```
416
+
417
+ **Then `post_tldr` and end your turn.** Body: what you pushed, and what you are waiting for
418
+ (`pushed 641c2a9b; awaiting your go on commit two`).
419
+
420
+ **Why this heading exists:** a seat that has pushed and is waiting is otherwise indistinguishable from a
421
+ seat that has done nothing — both end their turns cleanly, no failure detector sees either, and a
422
+ coordinator reading a wake led by its own acceptance concludes there is nothing to rule. That silence has
423
+ cost a pipeline hours. Preventing it is your job, and it costs you one append.
424
+
425
+ **A `## MID-BUILD QUESTION` and a `## HOLDING` are both non-staling:** the gates bind an acceptance to
426
+ the accepted CONTENT, not to the revision number, so appending your own state or a question leaves it
427
+ intact. Only **new content** stales.
428
+
429
+ **The token is the literal `child·`, whatever seat you are.** The control plane's close-out matcher keys
430
+ on `[child·…] CLOSE-OUT RECEIPT`, so a review or docs-process seat that writes `[review·…]` or
431
+ `[process·…]` **fails the match and stales its own acceptance** — costing a re-post and an argless
432
+ re-accept. **It is a PROTOCOL ANCHOR, not a description of you.** A descriptive tail after the marker IS
433
+ blessed (`… CLOSE-OUT RECEIPT — addendum: the six staged, tree clean`) — an end-anchored pattern on the
434
+ one heading seats are told to write would be a trap that fires on ordinary prose.
435
+
436
+ **Any post-accept append that is NOT one of these four — close-out receipt, HOLDING, a question heading, or
437
+ your coordinator's own voice — needs the argless re-accept.** The bar is content, not revision: it asks *is
438
+ what you are publishing still what I approved?*, and a state report is not a change of work.
439
+
440
+ **FILE YOUR SESSION ARTIFACTS:** copy your final `plan.md` and `tldr.md` into
441
+ `docs/research/{topic}/sessions/{slug}/`. **Two files — that is the whole filing step.** Questions ride the
442
+ TLDR, so there is no separate questions doc. **Do NOT snapshot the coordinator's ledger** — it is committed
443
+ live, so its git history already carries the progression. Include the folder in your staging list.
444
+
445
+ ## SWEEP THE RECEIPTS YOUR CHANGE INVALIDATED — IN THE SAME COMMIT
446
+
447
+ **A fix does not only add behaviour; it un-makes claims about the old behaviour.** For every behaviour you
448
+ changed, `rg` for what the record says about it:
449
+
450
+ ```
451
+ rg -n '<the behaviour, a symbol, a check id>' docs/research/{topic}/live-checks.md \
452
+ docs/research/{topic}/project-status.md docs/working/
453
+ ```
454
+
455
+ Then correct what is now false **in the same commit as the change**, because a fix and a stale receipt
456
+ landing separately is a window in which the record lies. A fixit that repairs a pane silently makes a
457
+ `superseded` live-check TRUE again — so the marker telling the sitter *not* to run it becomes false, and a
458
+ human driving the table files a defect against correct behaviour. Fixes invalidate receipts; this step is
459
+ what sweeps them.
460
+
461
+ **AND THE OWNERSHIP SPLIT IS PART OF THE RULE — without it the step is a dead end.** You may not write
462
+ `project-status.md` (coordinator-owned) or anything under `sessions/**` (testimony, byte-untouched). So:
463
+
464
+ - **`live-checks.md`** — correct it directly if your change made a row's stated behaviour wrong.
465
+ - **the tracker and `sessions/**`** — **REPORT the correction in your FINAL TLDR, quoting the line and what
466
+ it should say.** Your coordinator transcribes it.
467
+
468
+ A partial the seat cannot execute is not an escape hatch, it is a dead end handed to it. Say which
469
+ corrections are yours and which you are handing back.
470
+
471
+ ## EVERY BINDING INSTRUCTION GETS A RECEIPT — OR AN EXPLICIT "NOT PERFORMED"
472
+
473
+ If your coordinator ruled *"report the count either way"*, **report the count.** A clean check and an
474
+ unperformed check are indistinguishable without the number — which is precisely why "either way" was said.
475
+ In your FINAL TLDR, list each binding instruction with its result, or the words **"not performed"** and
476
+ why. Silence is not compliance.
477
+
478
+ **THE TESTIMONY REGRESS, AND THE DECLARED STOPPING POINT — read this before you copy anything.** The
479
+ order above puts the COMMIT before the CLOSE-OUT RECEIPT, so the copy you commit ends at your FINAL TLDR
480
+ and can contain neither the receipt (hash, session id, staging receipt) nor the coordinator's
481
+ `## PARENT ACCEPT`. **A follow-up commit does not fix this, it moves it:** any receipt ABOUT that commit is
482
+ also written after it. The regress is infinite and the ceremony does not pretend otherwise.
483
+
484
+ **So the rule is a declared stopping point rather than a fix: RE-COPY `plan.md` AND `tldr.md` ONCE,
485
+ IMMEDIATELY BEFORE THE FINAL PUSH.** The residual is then only *"I pushed X, status clean"* — which is
486
+ recoverable from git itself, and is the one thing a reader never needs the blackboard for.
487
+ **Why it is not cosmetic: the REVIEW seat reads `sessions/**` and reads nothing else.** Your live
488
+ blackboard is not in the repo, so a complete file where you work does not help a reader who has only the
489
+ commit — and a review chartered to grade the loop's own comms must not be handed a record missing the
490
+ coordinator's half. **This is a defect in the ceremony, not in your conduct**; it fires identically for
491
+ every seat.
492
+
493
+ Then stage YOUR list by explicit path, **verify it landed** (`verify-staged {the same list}` — non-zero
494
+ HALTS the close-out: the loss goes back to your coordinator as a `## MID-BUILD QUESTION`, never into a
495
+ commit), commit with the message you were given, push, and report **hash + post-push status + the
496
+ one-line `STAGING VERIFIED` receipt**. Your push proof is the auto-approval row on the push command
497
+ itself, visible in your own rows in-turn — tier `receipted-push`, actor `policy:push-bar` on the hosted
498
+ plane. The publish receipt is written at your turn's STOP and is structurally unquotable by you —
499
+ **never promise its id.**
500
+
501
+ ## Notes
502
+
503
+ - **Correcting your coordinator is the job, not a risk to you.** Pipelines are carried by seats catching
504
+ the coordinator's wrong beliefs at recon, before an hour is spent. If a seeded fact does not match HEAD,
505
+ say so plainly — a mismatch you report is worth more than a build hour, and a prompt that frames a claim
506
+ as settled does not make it true.
507
+ - **Honesty beats polish.** The coordinator independently verifies the riskiest claim; a disclosed red
508
+ with a clean rerun builds trust, an undisclosed one destroys it.
509
+ - **A rule recalled from context needs re-reading at the source before it is used to refuse work.** A
510
+ rule already corrected on disk is the commonest thing a seat blocks itself on.
511
+ - Your job skill is next: `spec-child` (build/fixit) · `spec-review` (the outside look) ·
512
+ `docs-process` (compile the living docs). Counterpart: `spec-parent` (the seat that arms you).