@naswerks/engineering-loop 0.7.0 → 0.8.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 (37) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +125 -0
  4. package/README.md +12 -7
  5. package/bin/verify-staged.mjs +136 -23
  6. package/bin/witness-acts.mjs +64 -0
  7. package/bin/witness-bodycheck.mjs +78 -0
  8. package/bin/witness-edits.mjs +60 -0
  9. package/bin/witness-extract-cmd.mjs +57 -0
  10. package/bin/witness-extract-seed.mjs +65 -0
  11. package/bin/witness-file-ledger.mjs +57 -0
  12. package/bin/witness-gaps.mjs +57 -0
  13. package/bin/witness-latency.mjs +55 -0
  14. package/bin/witness-lib.mjs +124 -0
  15. package/bin/witness-plane-window.mjs +57 -0
  16. package/bin/witness-procs.mjs +71 -0
  17. package/bin/witness-spawn-task.mjs +61 -0
  18. package/bin/witness-tx.mjs +60 -0
  19. package/bin/witness-watch.mjs +405 -0
  20. package/bin/witness-writes.mjs +64 -0
  21. package/package.json +1 -1
  22. package/references/docs-workflow.md +44 -24
  23. package/references/engineering-loop.md +41 -24
  24. package/skills/docs-audit-full/SKILL.md +2 -1
  25. package/skills/docs-process/SKILL.md +13 -7
  26. package/skills/docs-write/SKILL.md +1 -1
  27. package/skills/init/scripts/doctor.mjs +17 -5
  28. package/skills/init/scripts/owned.mjs +10 -0
  29. package/skills/spec-build/SKILL.md +8 -4
  30. package/skills/spec-coordinator/SKILL.md +125 -66
  31. package/skills/spec-ignite/SKILL.md +25 -21
  32. package/skills/spec-pipeline/SKILL.md +128 -80
  33. package/skills/spec-retro/SKILL.md +9 -4
  34. package/skills/spec-review/SKILL.md +22 -10
  35. package/skills/spec-seat/SKILL.md +63 -31
  36. package/skills/spec-witness/SKILL.md +267 -212
  37. package/templates/docs/readme-research.md +2 -2
@@ -21,8 +21,9 @@ touches the tracker or commits unprompted; you never write feature code — you
21
21
 
22
22
  **Who carries the messages depends on the mode, and the rest of this skill is written for both:**
23
23
 
24
- - **Hand-cranked** — a human relays every message, clicks plan-approve, and authorizes the push. The
25
- ceremony below is the same; the human is the bus.
24
+ - **Hand-cranked** — a human relays every message and approves each plan; an approved seat then runs to
25
+ done, its commits and branch pushes included (§ The hand-cranked relay). The ceremony below is the same;
26
+ the human is the bus.
26
27
  - **Hosted (including unattended)** — **your own verbs are the relay and the gate.** You spawn each seat's
27
28
  session, rule its plan (which is what flips its gate), steer it, receipt its final TLDR and reap it; the
28
29
  retro, the commit and the PR are yours. Pushes ride the unattended lane and are receipted, so they do
@@ -46,22 +47,24 @@ cannot spot a hand-written generated file.
46
47
  **Step 1 — the effort**, in order:
47
48
 
48
49
  1. `docs/research/{topic}/project-status.md` — the tracker. **You own it.**
49
- 2. `00-ignition-brief.md` if there is one — this run's standing orders.
50
- 3. `01-{topic}.md` — the umbrella. Its settled decisions govern; don't relitigate them.
51
- 4. **EVERY numbered spec, before arming the first seat.** You judge plans against them and
52
- cut each prompt from the previous session's actual shapes — you cannot do either from the tracker
53
- alone. Specs cross-reference: reading them as they come up means ruling on slice 3 without knowing
54
- slice 6 depends on its column name.
55
-
56
- **Then run the SHAPE COHERENCE CHECK — it takes seconds and it has caught real defects.** The shape
57
- lives in exactly three places:
58
-
59
- > the brief's `## The sequence` · the umbrella's row table · the tracker's `## Session status`
60
-
61
- **They must list the same rows, in the same order.** Check it now, and again before you cut the retro. **A
62
- disagreement is a finding, not a typo** — it means one seat changed the shape and the other two still
63
- describe the old one, and the seat most likely to act on the stale copy is the one reading only that file.
64
- Say which is right, fix the others, and journal it.
50
+ 2. `00-ignition-brief.md` — **your spec, and the charter every seat reads.** Its sections down to
51
+ § Platform state bind every seat; the owner's rulings in it are settled — don't relitigate them; the
52
+ sections after § Platform state are your orders.
53
+ 3. **EVERY numbered spec, before arming the first seat.** Every numbered file is one build seat's spec.
54
+ You judge plans against them and cut each prompt from the previous session's actual shapes — you cannot
55
+ do either from the tracker alone. Specs cross-reference: reading them as they come up means ruling on
56
+ slice 3 without knowing slice 6 depends on its column name.
57
+
58
+ **When no ignition copilot verified the brief — a run by hand — the GATE is yours.** Check that the
59
+ predecessor merged (only that: never a gate on another pipeline's seats), re-verify § Reference against
60
+ HEAD, and re-measure § Baselines, before the first seat is armed. A seat cites those baselines; it measures
61
+ only a lane the brief does not name.
62
+
63
+ **Then run the SHAPE CHECK — one comparison, seconds, and it has caught real defects.** The sequence is
64
+ written once, in the brief's `## The sequence`; the tracker's `## Session status` carries one status line
65
+ per row, by the brief's ids. **Every row has its status line and every status line has its row.** Check it
66
+ now, and again before you cut the retro. **A disagreement is a finding, not a typo** — it means the shape
67
+ changed in one place and not the other. Say which is right, fix the other, and journal it.
65
68
 
66
69
  Then produce a **5-line status readback** — shipped / in flight / next action / next prompt you expect to
67
70
  cut. Hand-cranked that goes to the human so they can confirm the seat transferred; hosted it is your
@@ -84,15 +87,16 @@ plus the human relay.
84
87
 
85
88
  | Verb | What it does | The part that bites |
86
89
  |---|---|---|
87
- | `seat_spawn` | Opens a DECLARED sibling's session | **It can never CREATE a seat** — the topology is the create door's, decided by a human — and you may only drive seats you `supervises`/`reviews` |
88
- | `accept_plan` | The verdict act: `accept` · `accept-with-riders` · `blocking-precondition`, **and NOTHING ELSE carries a go** — and it DELIVERS ITSELF: the seat's live session receives a one-line pointer to the ruling, for an accepting verdict and for any verdict that filed a ruling in the seat's file | Write the ruling into the seat's `tldr.md` FIRST (`## COORDINATOR RULING (plan rev N — {verdict})`), then call with a one-line `ruling`: the file is mirrored before your act and the pointer names your section. Pass the workspace HEAD you observed (a backticked sha is fine); an accepting verdict whose seat planned against a different tree is REFUSED, naming both shas. READ THE REPLY'S `delivery:` and `file:` LINES — `NOT DELIVERED` means the seat is idle and only a `callout` reaches it |
89
- | `accept` | The rev-bound FINAL receipt — and it TELLS the seat, so it carries your commit call | Put the next instruction (commit, push, close-out) in `ruling`, or write it under `## COORDINATOR ACCEPT` in the seat's `tldr.md` first — the receipt then binds to that mirrored revision. It binds to the seat's CURRENT tldr revision, so if the seat posts NEW CONTENT again your acceptance no longer covers what it publishes. **Re-accept — it is idempotent and cheap.** This receipt is what the push bar reads; prose is not a receipt |
90
+ | `seat_spawn` | Opens a DECLARED sibling's session | **It can never CREATE a seat** — the topology is the create door's, decided by a human — and you may only drive seats you `supervises`/`reviews`. With no `hostId` it opens on the host carrying your own session; `model` and `effort` override the seat's own for this session, judged against what the runner offers |
91
+ | `accept_plan` | The verdict act: `accept` · `accept-with-riders` · `blocking-precondition`, **and NOTHING ELSE carries a go** — and it DELIVERS ITSELF: the seat's live session receives a one-line pointer to the ruling, for an accepting verdict and for any verdict that filed a ruling in the seat's file | Write the ruling into the seat's `tldr.md` FIRST (`## COORDINATOR RULING (plan rev N — {verdict})`), then call with a one-line `ruling`: the file is mirrored before your act and the pointer names your section. Pass the workspace HEAD you observed (a backticked sha is fine); an accepting verdict whose seat planned against a different tree is REFUSED, naming both shas. READ THE REPLY'S `delivery:` and `file:` LINES — `NOT DELIVERED` means the seat is idle and only a `callout` reaches it. When the verdict also answers the seat's question, pass `answeringActId` — one act rules and closes it |
92
+ | `accept` | The rev-bound FINAL receipt — and it TELLS the seat, so it carries your commit call | Put the next instruction (commit, push, close-out) in `ruling`, or write it under `## COORDINATOR ACCEPT` in the seat's `tldr.md` first — the receipt then binds to that mirrored revision. It binds to the seat's CURRENT tldr revision, so if the seat posts NEW CONTENT again your acceptance no longer covers what it publishes. **Re-accept — it is idempotent and cheap.** This receipt is what the push bar reads; prose is not a receipt. `answeringActId` closes the question it answers, as on `accept_plan` |
90
93
  | `complete` | The reap, and it is HONEST | It re-reads the seat and reports ok only after the terminal state is OBSERVED |
91
94
  | `callout` | **THE ONLY WAY YOU REACH A CHARGE** (besides the pointers `accept_plan` and `accept` send) | A charge that posted and ended its turn cannot resume any other way — without this verb it waits for a human. Your ruling must carry a DETERMINATE NEXT ACTION it can execute without inference. **Write it into the seat's `tldr.md` first and pass a one-line `ruling`:** the file is mirrored before your act and the seat is pointed at your section. Without a file, KEEP IT TO A LINE: over 600 chars the body is stored as a `ruling` artifact on the board and the seat receives a POINTER — the seat reads the body once, never twice |
92
95
 
93
- **A QUESTION IS CLOSED BY AN ACT, NOT BY A FILE.** Answer a charge's question with a `callout` carrying
94
- that post's act id as `answeringActId` — **that act IS the answer**, and it is the only thing that stops
95
- the re-raise. A `callout` without one steers and closes nothing, and **nothing you write into a file
96
+ **A QUESTION IS CLOSED BY AN ACT, NOT BY A FILE.** Answer a charge's question with a `callout` — or an
97
+ `accept_plan` / `accept` that rules at the same time — carrying that post's act id as `answeringActId`:
98
+ **that act IS the answer**, and it is the only thing that stops the re-raise. An act without one steers or
99
+ rules and closes nothing — a forgotten id costs one re-raise — and **nothing you write into a file
96
100
  closes anything**: the latch reads the ledger, so a ruling you never sent is a question still open no
97
101
  matter what any blackboard says.
98
102
 
@@ -105,6 +109,11 @@ the verb carries your words. **The act still decides** — a section closes noth
105
109
 
106
110
  **`seat_acts` IS YOUR CENSUS.** Your mint carries `acts:read`: take counts, human touches and receipts from
107
111
  the ledger, never from a seat's report about itself, and name the lane any count you publish came from.
112
+ Beside it, read for yourself what the owner used to check for you: `seat_timeline` (a seat's two lanes —
113
+ *the reap ended the process* is the runner's `ended` row, cause `stop_requested`, after your reap act),
114
+ `needs_you` (the owner's Needs-you tab, Active and History), argless `seat_usage` (every seat's spend and
115
+ the pipeline's total), `seat_parks` with a charge's `seatId` or `all: true` (its parks, and the rows that
116
+ ADMITTED a push), and the argless roster's host and `re-raises` per seat.
108
117
 
109
118
  **WAKES:** you are woken when a charge posts its plan or its tldr, and a one-line pointer rides the wake —
110
119
  the revision and the sections it added. Read what is new (`read_blackboard` with `sinceRev`, or the file) and
@@ -114,7 +123,9 @@ answer on first receipt rather than spending a round-trip.
114
123
  not a refusal: call it once more, and journal it if it fails again. A refusal has a name; a dropped
115
124
  connection does not.
116
125
 
117
- **THE TRACKER IS YOURS ALONE.** Advance it at every seat boundary; never reconstruct it at the close.
126
+ **THE TRACKER IS YOURS ALONE.** Advance it at every seat boundary and **commit it yourself — after each
127
+ reap, before the next spawn — never in a seat's commit call**, so it is never frozen between an acceptance
128
+ and a seat's close-out. Never reconstruct it at the close.
118
129
 
119
130
  ## The loop (per seat)
120
131
 
@@ -126,7 +137,12 @@ connection does not.
126
137
  opening line and appends nothing of its own to your text, because you are the one who knows the prior
127
138
  rows' shapes. **The seed names skills; it never restates ceremony.** A seed that inlines procedure is a
128
139
  defect even when it works: there are then two sources for one contract and only one of them gets
129
- corrected.
140
+ corrected. **Hosted, the control plane's opening line already names the skills and the role** — start
141
+ your text at the spec, and never restate either.
142
+
143
+ **Keep each seed as you sent it.** Save the task text verbatim in the effort's record (the tracker's
144
+ session entry, or a `seed.md` beside the seat's board) at the moment you send it. The review and the
145
+ retro grade what each seat was told, and a seed reconstructed later from memory is not that.
130
146
 
131
147
  **Pick the docs:** the floor and the loop's standard docs are settled (`spec-seat`'s Step 0 +
132
148
  `spec-build`'s role table). **This repository's own docs are yours to seed, by path, every time:** copy
@@ -136,7 +152,7 @@ connection does not.
136
152
  seat guessing.
137
153
 
138
154
  **The seed-retirement rule:** each new seed restates ONLY what OVERRIDES a default (every seat
139
- re-acquires the defaults from the skill + umbrella from scratch) and DROPS what merely confirms them.
155
+ re-acquires the defaults from the skill + the brief from scratch) and DROPS what merely confirms them.
140
156
  A correction the platform has since absorbed retires from the seed the session after it ships — seeds
141
157
  carry deltas, not history. By session 15 an accreted seed is unreadable.
142
158
 
@@ -186,10 +202,10 @@ connection does not.
186
202
  **Advance the tracker AT EVERY CHECKPOINT.** Plan accepted: the row says so; final TLDR accepted: the
187
203
  row says so; push confirmed: SHIPPED with the hash. A stale tracker is your omission.
188
204
 
189
- **REAPING A HUMAN ROW: TAKE THE RECEIPT, DO NOT WRITE IT.** A human row has no seat to post a TLDR,
190
- so the temptation is to transcribe the sitting into your tracker and call the row recorded. **That
191
- leaves the row with ONE voice — yours — and it is the only row in the effort with one.** Ask the human
192
- for `sessions/{slug}/receipt.md` in the row's own commit: each check id, what was run, the literal
205
+ **CLOSING A HUMAN STEP: TAKE THE RECEIPT, DO NOT WRITE IT.** A `step` row has no seat to post a TLDR,
206
+ so the temptation is to transcribe the sitting into your tracker and call the step recorded. **That
207
+ leaves it with ONE voice — yours — and it is the only row in the effort with one.** Ask the human
208
+ for `sessions/{step-slug}/receipt.md` in the step's own commit: each check id, what was run, the literal
193
209
  result, who observed it. Your tracker entry then reads *against* it, the way you read every other row's
194
210
  tldr.
195
211
 
@@ -204,8 +220,8 @@ connection does not.
204
220
  `plan.md` + `tldr.md` immediately before the FINAL push**, leaving a residual git already records.
205
221
 
206
222
  **AND TRANSCRIBE THE SEAT'S RECEIPT SWEEP.** A seat's close-out reports which receipts its
207
- change made false. It can correct `live-checks.md` itself; it may **not** write `project-status.md` or
208
- `sessions/**`, so **those corrections arrive as a list in its FINAL TLDR and they are yours to apply.**
223
+ change made false. It may **not** write `project-status.md`, `sessions/**` or a row of `live-checks.md`
224
+ (the owner's), so **those corrections arrive as a list in its FINAL TLDR and they are yours to apply.**
209
225
  Do not hand a seat "just fix the false receipts" without checking who owns them — a coordinator that
210
226
  does finds the receipts are its own or immutable, and has handed the seat a dead end. Likewise
211
227
  **check off every BINDING instruction you gave**: if you said "report the count either way" and no
@@ -295,13 +311,15 @@ connection does not.
295
311
  nothing in that column is the pass's first finding. Then read your own session entries: **if any of
296
312
  them needs superseding, stop and record that as a finding** — it means the ledger was not kept, and
297
313
  the retro must say so rather than quietly correcting it.
298
- 2. **Aggregate the effort's `live-checks.md` — YOURSELF, with ordinary edits.** The effort home's
299
- `.md` files (`live-checks.md`, the numbered specs, the umbrella) are inside your scoped write path —
300
- same gate, same receipt as your ledger. **This also means a line you have PROVEN false in a spec or
301
- a live-check row is yours to strike at the source.** Research stage only — after docs-process
302
- files the folder, only the ledger remains writable.
303
- Every session's TLDR section (e) row belongs there, plus any status only you observed. Unaggregated
304
- rows are the most common thing to fall through, and the human's sitting is what they are for.
314
+ 2. **Offer the owner a short, ordered quick pass — in the chat.** Live checks are the owner's, never
315
+ a seat's job and never a row you aggregate. From the seats' section (e) ("what the owner could try")
316
+ pick the few that matter most and write them as a numbered pass the owner can follow cold: what to
317
+ open, what to do, what passing looks like. A long list nobody can follow is the failure this
318
+ replaces. `live-checks.md` holds only the rows the owner dictates; write a row there only when the
319
+ owner dictates it. The effort home's `.md` files (`live-checks.md`, the numbered specs, the brief)
320
+ are inside your scoped write path — same gate, same receipt as your ledger — so **a line you have
321
+ PROVEN false in a spec, or a dictated row a seat reported false, is yours to strike at the source.**
322
+ Research stage only — after docs-process files the folder, only the ledger remains writable.
305
323
  3. **Run `spec-retro`.** It is written FROM the tracker, which is why step 1 comes first — a retro
306
324
  assembled from a stale ledger invents. It is a READ: findings become proposed fixits, and it fixes
307
325
  nothing. **If the effort had a review, your retro may cite `sessions/code-review.md` — and the two
@@ -323,7 +341,7 @@ connection does not.
323
341
 
324
342
  **P MOVES THE EFFORT HOME OUT OF YOUR REACH — the tracker pass in step 1 is your LAST chance at
325
343
  the specs and live-checks.** P `git mv`s `docs/research/{topic}/` to the archive home
326
- `docs/_meta/docs-workflow.md` § The archive convention (repository-owned) names, or to the umbrella's
344
+ `docs/_meta/docs-workflow.md` § The archive convention (repository-owned) names, or to the brief's
327
345
  `Archive:` line when it carries one. The ledger survives the
328
346
  rename (its write predicate admits `docs/{research|archive}/*/project-status.md`; a home elsewhere
329
347
  is outside it, so there P's write to the tracker is the last one), but the effort-home lane
@@ -341,11 +359,17 @@ connection does not.
341
359
  is not reversible by the seat that does it, and a check the human runs afterwards confirms the damage
342
360
  instead of preventing it. **A live-check row is confirmation; this is prevention.** Never hold the
343
361
  run waiting for a human to verify this first — you have the list, so you are the gate.
344
-
345
- **The human hand-tests.** Live verification is the human's role, not a seat's claim — when a slice
346
- ships something clickable, tell the human concretely what to drive (the 2-3 highest-value clicks), and
347
- make sure user-run smokes accumulate in the effort's `live-checks.md` rather than piling up in chat —
348
- **written by you with ordinary edits, gated and receipted like your ledger.**
362
+ 8. **Hosted, `finish` is your last call** — once every other seat, P included, is reaped. Pass the PR's
363
+ URL: it records the pipeline done with evidence it reads from the ledger, moves it to `reviewing`,
364
+ closes your own session and ends your process, and the PR's merge closes the pipeline. **Nothing you
365
+ send after it is admitted** — commit your tracker and report first. It refuses, recording nothing,
366
+ while any seat is still live or when none shipped. Hand-cranked there is no `finish`; the human closes
367
+ the effort.
368
+
369
+ **The human hand-tests.** Live verification is the owner's, not a seat's claim and not a seat's job —
370
+ when a slice ships something clickable, tell the owner concretely what to drive (the 2-3 highest-value
371
+ clicks), in the chat. A check becomes a row of `live-checks.md` only when the owner dictates it, and then
372
+ you write it, with ordinary edits, gated and receipted like your ledger.
349
373
 
350
374
  ## What you will have to prove at close — make it runnable NOW
351
375
 
@@ -381,7 +405,21 @@ so read them as run-time obligations, not close-out ones:
381
405
 
382
406
  - Plan TLDR as **plain text BEFORE any plan-approval mode**; questions as **plain numbered text, then
383
407
  STOP** — never an interactive question tool (the human can't copy from it).
384
- - **No commit/push without your relayed call.** Explicit staging only — never `git add -A`.
408
+ - **Approved work includes its commit, its push and the PR — you do not ask for them.** Hand-cranked, an
409
+ approved seat commits and pushes its branch itself (the relay, below); hosted, the commit call rides your
410
+ acceptance. The PR is yours at the close. The merge is the human's, always. Explicit staging only —
411
+ never `git add -A` — and never a push to the base branch.
412
+ - **One pipeline at a time.** A brief's GATE checks only that its predecessor merged; never gate a run on
413
+ another pipeline's seats, and never run two pipelines over one another.
414
+ - **Never advise or run a runner restart while a seat is live.** A restart ends every live session on that
415
+ runner, and the plane may not notice. "Restarting it is fine" said to the human in that state is how a
416
+ run loses every seat at once; say instead which seats are live and that the restart waits.
417
+ - **When your plane calls fail, stop — never sleep-poll.** Journal the failure, report it, and end your
418
+ turn. A timer that wakes you to retry a plane that is not answering spends a whole context on every wake
419
+ and produces nothing; the human resumes you when the plane is back.
420
+ - **An escalation is an act, never chat text alone.** Write it where it is read — the seat's board under a
421
+ coordinator-voice heading, and the tracker — and carry it with a verb the owner's queue shows. Text in
422
+ your own terminal reaches the owner only if they happen to read that terminal.
385
423
  - **This repository's rails add to these rules.** `docs/_meta/engineering-loop.md` § This repository's rails
386
424
  (repository-owned) names the policy, the gates a commit passes, the suite before a PR, the PR route and
387
425
  any stricter staging — bake every rail in beside these, and never let one subtract from them.
@@ -391,8 +429,8 @@ so read them as run-time obligations, not close-out ones:
391
429
  flow. Pushes always name the refspec; a push without one parks by design. Keep git-verb words out of
392
430
  echo text and section labels — **including `branch`**, which parks a read-only branch LISTING on the
393
431
  branch-deletion backstop. The fence fires on the commands a careful seat runs to PROVE its work.
394
- - Seats never edit `project-status.md` or memory files; never run `docs-write` unprompted; respect the
395
- umbrella's out-of-scope list; codegen only through the command `patterns/codegen.md` § Running codegen
432
+ - Seats never edit `project-status.md`, `live-checks.md` or memory files; never run `docs-write` unprompted;
433
+ respect the brief's § What this effort does NOT do; codegen only through the command `patterns/codegen.md` § Running codegen
396
434
  names (when the repo has one); component files laid out as `patterns/frontend-patterns.md` § Component files states. Run the
397
435
  suite lanes SERIALLY.
398
436
  - Cross-slice changes (touching a shipped spec's files) need your explicit approval and get recorded as
@@ -420,6 +458,12 @@ so read them as run-time obligations, not close-out ones:
420
458
  catch. Cite, and your beliefs become checkable too.
421
459
  - **No message of yours carries a build order except the plan ruling itself.** Answers, callouts, and
422
460
  status requests are steering or information; the go IS the `accept`/`accept-with-riders` verdict.
461
+ - **A ruling that binds a running seat goes onto that seat's board in the same act as your tracker entry.**
462
+ Recorded is not delivered: a ruling that lives only in your tracker never reaches the seat it binds.
463
+ Hosted, write it into the seat's file and call the verb (a `callout` when no verdict carries it).
464
+ - **A ruling counts only when its act lands.** Write it into the file, call the verb, and say "landed" only
465
+ from the verb's reply. A ruling written ahead of its act — a claim about a build that has not finished, a
466
+ verdict the verb then refuses — is a board ahead of the ledger, and the seat may act on the board.
423
467
  - **If the next action is yours and nothing gates it, TAKE it — do not describe it.** Any turn of
424
468
  yours that ends with a plan instead of an act is a defect, and not a close-out quirk: a coordinator
425
469
  that rules a fixit IN, writes the brief, and ends the turn sits idle with nothing gating it. The human
@@ -460,10 +504,11 @@ The ceremony rides the **`spec-build` skill** — the prompt is an IGNITER, not
460
504
  ```
461
505
  You are a BUILD SEAT in a coordinator-run effort: invoke the spec-build skill with
462
506
  role={backend | frontend | mixed} before anything else, and ALWAYS after `spec-seat`: the seat header
463
- names `spec-seat` first, the job skill second.
507
+ names `spec-seat` first, the job skill second. <- hand-cranked only; hosted, start at the spec
464
508
 
465
509
  Your spec: {absolute path to the spec}
466
- Pipeline context: {umbrella path} (settled decisions — don't relitigate) + {project-status.md path}
510
+ Pipeline context: {brief path} — the charter: its sections down to § Platform state bind you, and the owner's
511
+ rulings in it are settled (don't relitigate) + {project-status.md path}
467
512
  (READ-ONLY, coordinator-owned — prior rows, deferred findings, and process incidents are your contract).
468
513
 
469
514
  EXTRA DOCS for this task (beyond your role's floor — read them):
@@ -479,7 +524,7 @@ MY BELIEFS, WITH PROVENANCE (a mismatch is worth more than a build hour — repo
479
524
 
480
525
  STANDING RECON QUESTION (answer in your PLAN TLDR): {if any}
481
526
  Known coordinator-owned dirty files (never stage): {list}
482
- Baselines: {per lane, as patterns/testing.md names them: N (+known pre-existing reds)}
527
+ Baselines (cite, don't re-measure): {per lane, from the brief's § Baselines: N (+known pre-existing reds)}
483
528
 
484
529
  THE TASK: {compressed spec restatement with the load-bearing specifics inline.}
485
530
  ```
@@ -502,6 +547,8 @@ second** — this is the whole point of the row.
502
547
  REVIEW row (R):
503
548
  You are the REVIEW SEAT: invoke the spec-review skill before anything else.
504
549
  Topic: {topic} · branch: {branch} · diff range: {base}...{branch}
550
+ The brief, down to § Platform state and never past it (read as claims, not facts):
551
+ docs/research/{topic}/00-ignition-brief.md
505
552
  Specs (read as claims, not facts): {every numbered spec path}
506
553
  Session artifacts: docs/research/{topic}/sessions/ (each seat's plan.md + tldr.md)
507
554
  Working docs for THIS effort: {explicit list of docs/working/*.md}
@@ -512,7 +559,8 @@ REVIEW row (R):
512
559
  DOCS-PROCESS row (P):
513
560
  You are the DOCS-PROCESS seat: invoke the docs-process skill before anything else.
514
561
  Effort: {topic} · archive target: {per docs/_meta/docs-workflow.md § The archive convention
515
- (repository-owned), or the umbrella's Archive: line when it carries one} · shape: {as that section says}
562
+ (repository-owned), or the brief's Archive: line when it carries one} · shape: {as that section says}
563
+ Your board: docs/research/{topic}/sessions/docs-process/ (plan.md + tldr.md; never a gitignored folder)
516
564
  Working docs for THIS effort, and ONLY these: {explicit list — docs/working/ is a shared
517
565
  queue and may hold other efforts' docs; do not infer membership from the folder}
518
566
  Research/spec docs to archive: docs/research/{topic}/
@@ -538,7 +586,7 @@ Answers:
538
586
  mandatory: seats generalize from the WHY to the next hundred micro-decisions.}
539
587
  2. ...
540
588
  {Optional call-outs that don't block.}
541
- Go build. Ending ceremony as before; no commit without the relayed call.
589
+ {Hand-cranked: the run-to-done order (the relay, below). Hosted: Go build; the ending ceremony as before.}
542
590
  ```
543
591
 
544
592
  Rules: one numbered ruling per question, decision-first then rationale, never leave a question
@@ -552,9 +600,10 @@ still open, however good the prose; the seat is still holding and the re-raise i
552
600
  **The blackboard append.** Hand-cranked, the seat's `plan.md` and `tldr.md` are live FILES at
553
601
  `docs/research/{topic}/sessions/{spec-slug}/` — read the TLDR there with normal file tools instead of
554
602
  asking for a paste (`read-full-plan` = read `plan.md`, a pull, never force-fed). Deliver every ruling by
555
- **APPENDING it verbatim to the seat's `tldr.md`**, right under the questions it answers. Hosted, the same
556
- append, then the verb: the control plane mirrors the file before your act and points the seat at the
557
- section (§ Your hands, the coordinator's append).
603
+ **APPENDING it verbatim at the END of the seat's `tldr.md`** — never between its sections, not even under
604
+ the question it answers: the file is the conversation read top to bottom, in message order, and an insert
605
+ above a later post rewrites that order. Hosted, the same append, then the verb: the control plane mirrors
606
+ the file before your act and points the seat at the section (§ Your hands, the coordinator's append).
558
607
 
559
608
  **Anchor grammar (canonical — the witness greps these):** rulings land under
560
609
  `## COORDINATOR RULING (plan — {verdict})` hand-cranked, `## COORDINATOR RULING (plan rev N — {verdict})`
@@ -573,21 +622,31 @@ re-pasting a multi-KB block into a composer.
573
622
  before cutting each next prompt, sweep `sessions/*/tldr.md` mtimes for appends you were never nudged
574
623
  about. A missed nudge must cost one `ls`, not a wedged run.
575
624
 
576
- **Human relay mechanic:** when pasting a ruling into the seat's session, the human prepends *"Here
577
- is the response from the coordinator, take account for the notes and pop up the plan i will approve it."*
578
- — so the seat applies the rulings, then presents its plan for the human's explicit approve. This
579
- plan-approval click is the human's counterpart of the product's accept-gate — keep it.
625
+ **The hand-cranked relay.** A seat posts its PLAN TLDR and numbered questions **in the chat**, before any
626
+ plan-approval presentation. The human relays them, and you answer in **ONE message of notes**: the
627
+ verdict, the answers, the riders, and the standing run-to-done order. The seat folds them in and the human
628
+ approves its plan — that approval is the human's counterpart of the product's accept-gate. The seat then
629
+ writes `plan.md` and `tldr.md`, your notes transcribed verbatim under `## COORDINATOR RULING (plan —
630
+ {verdict})`, and **runs to done without a stop**: build, suites, `docs-write`, commits with
631
+ `verify-staged`, its branch pushes (never the base branch), and its FINAL TLDR in the chat. Its only stops
632
+ are a destructive act outside the effort's branches, a credential exposure, a host restart and a
633
+ `verify-staged` failure; a red it cannot fix takes its escape hatch, and it still closes out. A mid-build
634
+ question gets your ruling appended to its `tldr.md`. After its last push you review the FINAL against the
635
+ tree and write `## COORDINATOR ACCEPT (final — {slice})` into its `tldr.md` yourself. The hosted ceremony —
636
+ the acceptance that carries the commit call, the receipted push bar — is unchanged.
580
637
 
581
638
  ## Docs-write + commit call template
582
639
 
640
+ The hosted close-out call. Hand-cranked, the relay's run-to-done order carries the same content and the
641
+ seat closes out without waiting for it.
642
+
583
643
  ```
584
644
  COORDINATOR RESPONSE — FINAL TLDR ACCEPTED {(+ what I verified myself)}.
585
645
  1. Run docs-write. Carry: {departures, honest gaps, deferred findings verbatim, gotchas}.
586
- 2. COMMIT CALL — approved. Stage explicitly (never git add -A): YOUR diff + working doc,
587
- PLUS docs/research/{topic}/project-status.md — my ledger rides your commit,
588
- which is its only route to durability. You stage it; you never edit it. Other research
589
- notes stay untouched. Re-copy plan.md + tldr.md into sessions/{slug}/ ONCE, immediately
590
- before the final push.
646
+ 2. COMMIT CALL — approved. Stage explicitly (never git add -A): YOUR diff + working doc +
647
+ sessions/{slug}/. Never stage docs/research/{topic}/project-status.md — I commit my ledger
648
+ myself. Other research notes stay untouched. Re-copy plan.md + tldr.md into sessions/{slug}/
649
+ ONCE, immediately before the final push.
591
650
  VERIFY before committing: verify-staged {same list} — commit only on exit 0. Non-zero means
592
651
  git add silently dropped files (usually a .gitignore rule); STOP, report the output verbatim,
593
652
  and wait — do not force-add, do not widen .gitignore.
@@ -30,9 +30,10 @@ the named-finding discipline are UNCHANGED either way — **only the mouse hand
30
30
  1. Confirm the specs are **committed to the base branch** — seats read specs from their checkouts, so
31
31
  uncommitted specs reach no worktree. If they are not committed, that commit is the coordinator's call
32
32
  first.
33
- 2. Enumerate the **ignition gates** explicitly and check each: dependency efforts landed AND merged (name
34
- the PRs); known-blocker fixits landed (name them); the control plane up and a runner connected; the
35
- human's words per stage. Report any gate not yet green — you WAIT, never work around.
33
+ 2. Enumerate the **ignition gates** explicitly and check each: the predecessor merged (name the PR) — one
34
+ pipeline runs at a time, so that is the only gate on another pipeline, never one of its seats; known-blocker
35
+ fixits landed (name them); the control plane up and a runner connected; the human's words per stage.
36
+ Report any gate not yet green — you WAIT, never work around.
36
37
  3. **VERIFY the ignition brief — you do not author it.** `spec-pipeline` wrote `00-ignition-brief.md`
37
38
  complete, from the hot session that placed the specs. **You may be a cold session, and that is fine,
38
39
  because your job is the check:** re-run the **Baselines** and confirm the quoted numbers; re-verify each
@@ -53,32 +54,33 @@ the named-finding discipline are UNCHANGED either way — **only the mouse hand
53
54
  | Payload field | Derived from | Note |
54
55
  |---|---|---|
55
56
  | `topic` | the folder name (`docs/research/{topic}/`) | kebab-case, as authored |
56
- | `title` | the umbrella `01-*.md` H1 | |
57
+ | `title` | the brief's H1 (the pipeline's title) | |
57
58
  | `specPath` | `docs/research/{topic}/` | **the folder, trailing slash** — a seat's own spec is a different field |
58
59
  | `shape` | the brief's `## Birth` | closed set; the create door refuses an unknown by name |
59
60
  | `defaultModel` | the brief's `## Birth` | **allowlist-exact** — a near-miss is refused, not coerced |
60
61
  | `defaultEffort` | the brief's `## Birth` | |
61
62
  | `seats[0]` | **THE COORDINATOR — it is a SEAT, and it is not one of the numbered specs** | omit it and the start door answers `pipeline-has-no-coordinator`; two answer `pipeline-has-many-coordinators` |
62
- | `seats[1..]` | the brief's `## The sequence`, in order | one row per numbered spec, plus the review / docs-process rows if the pipeline has them |
63
+ | `seats[1..]` | the brief's `## The sequence`, in order | one row per numbered spec, plus the review / docs-process rows if the pipeline has them. **A `step` row is shown on the card and never staged** — it is a human act, not a seat |
63
64
  | `seats[].kind` | the sequence row's kind, **verbatim from the closed vocabulary** | `build · fixit · review · docs-process · coordinator · retro · witness`. A kind nobody has heard of composes NOTHING; `unknown-seat-kind` names it |
65
+ | `seats[].role` | the row's `Role` cell, when the sequence has the column | `backend · frontend · mixed`; omitted when absent, and the seat's default applies |
64
66
  | `seats[].title` | the spec's H1, or the sequence row's label | |
65
67
  | `seats[].specPath` | `docs/research/{topic}/NN-{slug}.md` | **the FILE.** Confirm each exists — a spec named in the sequence and missing from disk reaches no worktree |
66
68
  | `seats[].stageOrdinal` / `ordinal` | position in the sequence | sequential unless the brief declares stages |
67
69
  | `edges[]` | the shape + the sequence | `fromSeatIndex`/`toSeatIndex` are **indices into your own `seats` array**, not seat ids — the ids do not exist until the create answers. `unknown-seat-relation` names a bad relation |
68
70
 
69
- **A FIXIT ROW IS NEVER IN THE CREATE PAYLOAD.** `spec-pipeline` authors at most one and only as a
70
- possibility — *"MAY materialise… not authored up front; the coordinator charters it from the review's
71
- named list."* Staging a seat for it invents a seat the run may never want, and the coordinator cannot
72
- un-charter it.
71
+ **A CONDITIONAL FIXIT IS A PLANNED SEAT, NEVER A SPEC.** `spec-pipeline` authors at most one and only
72
+ as a possibility — *"MAY materialise… not authored up front; the coordinator charters it from the
73
+ review's named list."* When the card carries it, the control plane creates it as a planned seat the
74
+ coordinator supervises, shown as "if needed": it opens only when the coordinator charters it, and
75
+ `finish` closes it as not chartered when it never opened. Never give it a spec file, and never stage a
76
+ second one.
73
77
 
74
- **DERIVING THE CARD *IS* THE THREE-DOCUMENT CHECK, AND THAT IS WHY THIS SEAT DERIVES IT.**
75
- `spec-pipeline` requires the sequence to appear in THREE places and agree: the brief's
76
- `## The sequence`, the umbrella's row table, and the tracker's `## Session status`. Build the seat
77
- list from the brief, then read the other two and confirm they list the same rows in the same order.
78
- **A disagreement is a finding, reported to the authoring seat — never something you reconcile
79
- silently by picking one.** An effort whose three documents disagree has a seat acting on a shape the
80
- others have stopped describing, and the create you are about to stage would make one of them true by
81
- force.
78
+ **DERIVING THE CARD *IS* THE SHAPE CHECK, AND THAT IS WHY THIS SEAT DERIVES IT.** The sequence is
79
+ written once, in the brief's `## The sequence`; the tracker's `## Session status` carries one status
80
+ line per row by the brief's ids. Build the seat list from the brief, then confirm every row has its
81
+ status line and every status line its row. **A disagreement is a finding, reported to the authoring
82
+ seat — never something you reconcile silently by picking one** — the create you are about to stage
83
+ would make one of them true by force.
82
84
 
83
85
  **The card names only controls that exist.** A card that promises a budget cap or an artifact prefix
84
86
  the launcher cannot take hands over values the form refuses and omits the ones it needs. **If you want
@@ -105,7 +107,8 @@ the named-finding discipline are UNCHANGED either way — **only the mouse hand
105
107
  if a retry is needed, re-announce and say the failed attempts had zero side effects.
106
108
  9. Verify ignition receipts — the coordinator's opening ledger write, its first `seat_spawn`, any scripted
107
109
  probe's refusal — and **narrate each beat as it lands**, plain language. A loud row at ignite is
108
- information, not a failure.
110
+ information, not a failure. **When a witness is on duty, hand it the packet** (`spec-witness` § The
111
+ packet) before you go hands-off: it watches from outside the plane and cannot read the kick for itself.
109
112
  10. **HANDS OFF.** Heartbeats only (one line per phase change; long output to files, never into context).
110
113
  The human owns the parks, the reaps, and the kill-switch from the first second. If the run wedges:
111
114
  report state + STOP — the kill-switch is theirs.
@@ -130,9 +133,10 @@ reviewed the way a committed file can, so anything longer than a pointer is law
130
133
  place — and accumulated prompt-law breaks the coordinator it was meant to steer.
131
134
 
132
135
  **Your job is to READ it and confirm the brief behind it holds up** — the coordinator reviews the text
133
- before kick. Before you hand it over, check the brief actually covers: the sequence and roles · the
134
- coordinator's beliefs with provenance · effort-specific law and per-spec riders · verified baselines ·
135
- platform state · close-out (artifact filing, live-checks aggregation, what the PR must say). **A gap you
136
+ before kick. Before you hand it over, check the brief actually covers: why the effort exists · the
137
+ sequence and roles · the owner's rulings · the law and per-spec riders · the reference facts · what the
138
+ effort does not do · verified baselines · platform state · the coordinator's beliefs with provenance ·
139
+ close-out (artifact filing, what the PR must say, the owner's quick pass). **A gap you
136
140
  find is a finding to report, not a section for you to write** — send it back to the authoring seat.
137
141
 
138
142
  <!-- control-plane-specific -->