@ikon85/agent-workflow-kit 0.27.1 → 0.28.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 (57) hide show
  1. package/.agents/skills/ask-matt/SKILL.md +2 -2
  2. package/.agents/skills/grill-me/SKILL.md +1 -1
  3. package/.agents/skills/grill-with-docs/SKILL.md +1 -1
  4. package/.agents/skills/kit-update/SKILL.md +12 -0
  5. package/.agents/skills/orchestrate-wave/SKILL.md +68 -21
  6. package/.agents/skills/orchestrate-wave/references/builder-contract.md +6 -4
  7. package/.agents/skills/retro/SKILL.md +24 -1
  8. package/.agents/skills/scale-check/SKILL.md +2 -2
  9. package/.agents/skills/setup-workflow/SKILL.md +44 -1
  10. package/.agents/skills/setup-workflow/workflow-overview.md +5 -5
  11. package/.agents/skills/tdd/SKILL.md +68 -14
  12. package/.agents/skills/to-issues/SKILL.md +2 -2
  13. package/.agents/skills/verify-spike/SKILL.md +1 -1
  14. package/.agents/skills/wrapup/SKILL.md +14 -2
  15. package/.claude/hooks/drift-guard.py +5 -2
  16. package/.claude/hooks/kit-origin-edit-hint.py +64 -0
  17. package/.claude/skills/ask-matt/SKILL.md +2 -2
  18. package/.claude/skills/grill-me/SKILL.md +1 -1
  19. package/.claude/skills/grill-with-docs/SKILL.md +1 -1
  20. package/.claude/skills/kit-update/SKILL.md +12 -0
  21. package/.claude/skills/orchestrate-wave/SKILL.md +68 -21
  22. package/.claude/skills/orchestrate-wave/references/builder-contract.md +6 -4
  23. package/.claude/skills/retro/SKILL.md +23 -0
  24. package/.claude/skills/scale-check/SKILL.md +2 -2
  25. package/.claude/skills/setup-workflow/SKILL.md +44 -1
  26. package/.claude/skills/setup-workflow/workflow-overview.md +5 -5
  27. package/.claude/skills/skill-manifest.json +1 -1
  28. package/.claude/skills/tdd/SKILL.md +68 -14
  29. package/.claude/skills/to-issues/SKILL.md +2 -2
  30. package/.claude/skills/verify-spike/SKILL.md +1 -1
  31. package/.claude/skills/wrapup/SKILL.md +14 -2
  32. package/README.md +47 -7
  33. package/agent-workflow-kit.package.json +49 -33
  34. package/docs/adr/0001-consumer-divergence-policy.md +49 -0
  35. package/docs/agents/wave-anchor-template.md +1 -1
  36. package/package.json +1 -1
  37. package/scripts/board-sync.py +184 -5
  38. package/scripts/pr-body-check.py +34 -6
  39. package/scripts/pr_body_e2e.py +83 -0
  40. package/scripts/test_board_sync.py +208 -0
  41. package/scripts/test_census_backstop.py +56 -3
  42. package/scripts/test_orchestrate_wave_contract.py +116 -0
  43. package/scripts/test_pr_body_check.py +245 -0
  44. package/scripts/test_retro_wrapup_contract.py +111 -0
  45. package/scripts/test_tdd_contract.py +78 -0
  46. package/src/cli.mjs +44 -8
  47. package/src/commands/diff.mjs +5 -2
  48. package/src/commands/init.mjs +12 -0
  49. package/src/commands/own.mjs +16 -0
  50. package/src/commands/uninstall.mjs +8 -1
  51. package/src/commands/update.mjs +37 -9
  52. package/src/lib/bundle.mjs +4 -0
  53. package/src/lib/consumerPath.mjs +30 -0
  54. package/src/lib/manifest.mjs +18 -0
  55. package/src/lib/ownedDiff.mjs +88 -0
  56. package/src/lib/updateCandidate.mjs +14 -0
  57. package/src/lib/updateReconcile.mjs +45 -6
@@ -53,7 +53,7 @@ Prefer the smallest depth that produces a clear next action.
53
53
  - **Deep:** `/grill-with-docs` followed by `/to-prd` and `/to-issues` when
54
54
  terminology, contracts, rollout order, or ownership are still uncertain.
55
55
  - **Medium:** `/to-issues` for a ready artefact that needs slicing.
56
- - **Light:** direct `/tdd` for a small, well-understood change.
56
+ - **Light:** direct `/implement` for a small, well-understood change.
57
57
  - **Gate:** insert `/verify-spike` or `/decision-gate` before any depth level
58
58
  when a slice hinges on an unresolved fact or trade-off.
59
59
 
@@ -75,7 +75,7 @@ A starting situation that generates work, then merges onto the main flow.
75
75
  - **Something's broken** → **`/diagnose`**. For the hard ones: the bug that resists a first glance, the intermittent flake, the regression between two known-good states. Refuses to theorise until it has a **tight feedback loop** — one command that already goes red on *this* bug — then fixes with a regression test. Its post-mortem hands off to **`/improve-codebase-architecture`** when the finding is that there's no good seam.
76
76
  - **A huge, foggy effort too big for one agent session** — a greenfield build or a sprawling feature where the way from here to the destination isn't yet visible, and it's still **pre-spec** (before any grill or PRD) → **`/wayfinder`** (user-invoked). It charts a **shared map** of investigation slices on the tracker and resolves them one at a time — producing **decisions, not deliverables** — until the fog lifts and the route is clear, then merges onto the main flow at **`/to-prd`** (or, if the effort turned out small enough, straight to **`/implement`**). Where `/grill-with-docs` sharpens an idea you can hold in one session, wayfinder is for the one you can't. Once an undertaking has already resolved into several independently-shippable waves, `/scale-check` → `/to-waves` stays the primary route.
77
77
  - **A backlog to cluster** → **`/board-to-waves`**. Groups an existing board into themed waves when you need to *find* the next wave rather than start fresh.
78
- - **A whole wave to LAND** → **`/orchestrate-wave`**. When a wave anchor (file-disjoint slices, specs already locked) is ready to build, verify and land end-to-end — often AFK: it dispatches an implementer per slice in its own worktree, integrates serially, verifies centrally, and lands the wave. The execute-and-land node of the wave ladder (`scale-check` → `to-waves`/`board-to-waves` → `orchestrate-wave`). A single slice just goes to `/tdd`.
78
+ - **A whole wave to LAND** → **`/orchestrate-wave`**. When a wave anchor (file-disjoint slices, specs already locked) is ready to build, verify and land end-to-end — often AFK: it dispatches an implementer per slice in its own worktree, integrates serially, verifies centrally, and lands the wave. The execute-and-land node of the wave ladder (`scale-check` → `to-waves`/`board-to-waves` → `orchestrate-wave`). A single slice just goes to `/implement`.
79
79
 
80
80
  ## Cross-model review (Codex)
81
81
 
@@ -48,7 +48,7 @@ Once all decisions are made (plan locked, before sign-off/handoff) and the sessi
48
48
 
49
49
  ## Re-grill reconcile — execute-ready (Wave 26)
50
50
 
51
- Applies when you **re-grill an issue that already exists** (a leaf of a grilled epic, or a child of an anchor) — the most common re-grill path, since campaign HITL slices route via `/grill-me → /tdd`. Goal: the rooted sub-graph comes out **execute-ready**, never silent drift. (grill-me has no docs layer — CONTEXT.md/ADR don't apply; core rules identical to grill-with-docs §"Re-Grill Reconcile".)
51
+ Applies when you **re-grill an issue that already exists** (a leaf of a grilled epic, or a child of an anchor) — the most common re-grill path, since campaign HITL slices route via `/grill-me → /implement`. Goal: the rooted sub-graph comes out **execute-ready**, never silent drift. (grill-me has no docs layer — CONTEXT.md/ADR don't apply; core rules identical to grill-with-docs §"Re-Grill Reconcile".)
52
52
 
53
53
  1. **Read parent-anchor decisions FIRST** — fetch the anchor body + its PRD/key decisions, take the seam decision **from there**. Do not re-derive the architecture from the leaf (lesson: a leaf whose central decision was never read got re-litigated through question rounds). For an atomic leaf, its own body/PRD is the reference.
54
54
  2. **Check the leaf for internal contradiction**: a body that contradicts itself ("no new UI" + "build a name field") or the anchor decision → **no execute**. Likewise a leaf that says *"final cut depends on #X"* via `<!-- final-cut-depends-on: #X -->` where **#X is closed** without resolving the cut.
@@ -136,6 +136,6 @@ Triggers when you **re-grill an issue that already exists in the graph** (a leaf
136
136
  2. **Check the leaf for internal contradiction** (Fix B): a body that contradicts itself ("no new UI" + "build a name field") or the anchor decision → **no execute**. Likewise a leaf that says *"final cut depends on #X"* via `<!-- final-cut-depends-on: #X -->` where **#X is closed** without resolving the cut.
137
137
  3. **On drift/contradiction:** update the affected issue(s), re-stamp `plan_revision`, set the correct bucket. An internal contradiction → set the leaf to **HITL** (remove `ready-for-agent`, add the `headings.vorBau` heading — board profile `docs/agents/board-sync.md`; <project> currently `## Vor Bau zu klären`); the drift-guard then blocks a build-handoff via `target_buildable`. So the contradiction flows through existing machinery — no semantic heuristic in the hook.
138
138
  4. **Audit, non-blocking:** `python3 scripts/execute-ready-check.py --issue <n> --mode audit` → visible two-liner. The **blocking** net is the drift-guard at handoff (`.claude/hooks/drift-guard.py`).
139
- 5. **Global `-codex` variant** can't change the repo → leave a pointer note ("reconcile the issues + re-stamp plan_revision, repo-side"); real enforcement = the repo hook. **Honest bound:** the hook fires at the handoff/session boundary, not at a "grill-exit" event; a same-session global-codex grill → direct `/tdd` (no handoff) is a documented residual (global follow-up).
139
+ 5. **Global `-codex` variant** can't change the repo → leave a pointer note ("reconcile the issues + re-stamp plan_revision, repo-side"); real enforcement = the repo hook. **Honest bound:** the hook fires at the handoff/session boundary, not at a "grill-exit" event; a same-session global-codex grill → direct `/implement` (no handoff) is a documented residual (global follow-up).
140
140
 
141
141
  **Markers used here** (HTML comments, grep-able): `<!-- guard-ack: #<n> r<N> reason:<text> by-user -->` (deliberate handoff override), `<!-- final-cut-depends-on: #<n> -->`, `<!-- handoff-intent: build|grill -->`, `<!-- guard-legacy -->` (grandfathered legacy-anchor → warn not block). **Canonical table of all markers:** module docstring of `scripts/execute-ready-check.py`.
@@ -40,6 +40,18 @@ release contain the same artifact.
40
40
  conflict manually; never auto-merge, delete a local edit, or silently choose
41
41
  the incoming copy.
42
42
 
43
+ For each conflicted kit-shipped file, always ask the user whether the local
44
+ edit is a generic improvement or project-specific; never decide or act
45
+ automatically. For a generic improvement, offer to file an issue in the
46
+ public kit repository and keep the local edit in place as a bridge until a
47
+ kit release containing the improvement lands. Before running
48
+ `gh issue create --repo <owner>/agent-workflow-kit`, show a sanitized preview
49
+ of the exact title and body with consumer identifiers and secrets stripped,
50
+ then require the user's explicit approval. The consumer user does not need
51
+ to be a kit maintainer. For a project-specific edit, recommend
52
+ `npx @ikon85/agent-workflow-kit@latest own <path>` so future updates treat
53
+ that path as consumer-owned.
54
+
43
55
  4. If a candidate is interrupted, discard its reported stage directory or
44
56
  resume the transaction through the update API's `resumeFrom` option. Do not
45
57
  copy staged files into the consumer by hand.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: orchestrate-wave
3
- "description": "Use when the user hands you a whole WAVE / cluster of pre-planned, file-disjoint slices and wants you to ORCHESTRATE building, verifying AND landing it end-to-end — often AFK / \"ultracode\". Triggers: \"orchestriere Welle #N\" (or any wording that delegates wave-landing responsibility to you), \"ultracode diese Welle / diesen Cluster\", or a wave-anchor issue (a cluster/umbrella issue with file-disjoint sub-issues whose specs are already locked) handed over to land. NOT for a single slice (just `tdd` it), NOT for finding/clustering a wave (that's `board-to-waves`), NOT for planning specs (that's `grill-with-docs`/`to-issues`)."
3
+ "description": "Use when the user hands you a whole WAVE / cluster of pre-planned, file-disjoint slices and wants you to ORCHESTRATE building, verifying AND landing it end-to-end — often AFK / \"ultracode\". Triggers: \"orchestriere Welle #N\" (or any wording that delegates wave-landing responsibility to you), \"ultracode diese Welle / diesen Cluster\", or a wave-anchor issue (a cluster/umbrella issue with file-disjoint sub-issues whose specs are already locked) handed over to land. NOT for a single slice (just `implement` it), NOT for finding/clustering a wave (that's `board-to-waves`), NOT for planning specs (that's `grill-with-docs`/`to-issues`)."
4
4
  ---
5
5
 
6
6
  # Orchestrate Wave
@@ -40,6 +40,10 @@ you must NOT paraphrase.
40
40
  - **Plan-level error** (integration/verify reveals a wrong LOCKED decision, not a
41
41
  slice bug): STOP the wave. No improvised redesign AFK — keep worktrees intact,
42
42
  report findings + options.
43
+ - **On ANY wave STOP/abort:** if this run planted the active-wave claim, remove
44
+ exactly that claim as part of shutdown. Never delete a claim marker observed
45
+ during a preflight collision, nor any sibling/foreign wave marker — those are
46
+ owned by another run. A stale marker owned by this run would block a safe retry.
43
47
  - **Routing = one axis: how expensive is a wrong result to catch?** Mechanically
44
48
  caught (test/screenshot/lint) → default tier at medium/low effort; plausible-but-
45
49
  wrong / subtle logic / architecture → top tier at high effort + main-thread
@@ -64,19 +68,30 @@ you must NOT paraphrase.
64
68
  **once** that `/setup-workflow` plus project maintenance fill the layer (the
65
69
  commands/tunnel/login can't be guessed). Never treat an empty heading as a
66
70
  verify recipe.
67
- 3. **Wave worktree**: reuse the planning worktree (never re-create; the handoff
71
+ 3. **Preflight refuse a wave already in flight, otherwise claim it.** Before
72
+ dispatch, inspect all three same-machine collision signals: **(a)** an existing
73
+ `wave-active/<anchor>` tag; **(b)** any slice branch ahead of the wave's current
74
+ base (`git rev-list --count <base>..<slice-branch>` > 0); **(c)** uncommitted
75
+ changes in any slice worktree (`git -C <worktree> status --porcelain` non-empty).
76
+ A hit not created by this run means another session may be building the wave:
77
+ **STOP**, report the exact tag/branch/worktree, and do not touch it. If clean,
78
+ record that this run owns the claim and plant a LOCAL annotated tag:
79
+ `git tag -a wave-active/<anchor> -m "orchestrating since <UTC timestamp>;
80
+ slices: <slice-branches>"`. It is local coordination state — never push it.
81
+ 4. **Wave worktree**: reuse the planning worktree (never re-create; the handoff
68
82
  points there). Bring its branch to current `main`:
69
83
  `git -C <wave> merge --ff-only origin/main` (if your repo guards destructive
70
84
  git, ff-merge is the safe path — not `reset --hard`). Install dependencies with
71
85
  your package manager after (the lockfile may have moved). A gitignored plan doc
72
86
  survives the merge.
73
- 4. **Run project setup steps (`§Setup`)** the later verify needs — e.g. a DB
87
+ 5. **Run project setup steps (`§Setup`)** the later verify needs — e.g. a DB
74
88
  tunnel or service the live-verify depends on. Absent layer → start whatever your
75
89
  live-verify environment requires before Phase 4.
76
90
 
77
91
  **Done when:** anchor + every sub-issue + plan read · project layer probed
78
- (filled → project recipe; stub/absent → generic + one-time warning) · wave branch
79
- ff'd to `origin/main` + deps installed · project setup steps running.
92
+ (filled → project recipe; stub/absent → generic + one-time warning) · preflight
93
+ clean + this run's local claim planted · wave branch ff'd to `origin/main` + deps
94
+ installed · project setup steps running.
80
95
 
81
96
  ## Phase 1 — Disjointness recon (the load-bearing step)
82
97
 
@@ -108,6 +123,13 @@ Zero merge conflicts later depends entirely on getting this right.
108
123
  "X already exists in `<file>` — do NOT add it, consume only." (Real case: all 14
109
124
  sub-issues claimed the same registry adds + 4 contradictions — hub expanded to
110
125
  own all 20 keys, batch merged conflict-free.)
126
+ - **Retirement slices require a valid topological deletion order.** Before
127
+ dispatching slices that delete a legacy cluster, map every to-delete module's
128
+ production importers and build the cluster's internal import graph. Order the
129
+ deletions so no pending slice imports a module already removed; zero remaining
130
+ production importers is the behavior-neutral proof. If mutually dependent
131
+ deletions form a cycle, separate each-slice-green steps are impossible: combine
132
+ the whole cycle into ONE atomic slice instead of landing dangling imports.
111
133
 
112
134
  **Done when:** FILE→SLICES table exists · every ≥2-slice file has exactly ONE
113
135
  owning slice · disjoint waves cut in dependency order · every dependent contract
@@ -225,15 +247,19 @@ checks pass · console 0/0 · DB outcome value compared.
225
247
  - **`Closes #N` needs the keyword before EACH issue, one per line** — `Closes #a,
226
248
  #b` only closes the first. Anchor → `Part of #<anchor>`, never `closes`
227
249
  (premature close).
228
- - **Anchor tracker: `python3 scripts/board-sync.py anchor-sync <anchor#>`** — first
229
- `--dry-run`, review the diff, then write; gate symbol + stable cells of freshly
230
- appended rows by hand. Mandatory at EVERY slice event: PR-create AND merge.
250
+ - **Anchor tracker sync is mandatory at EVERY slice event (PR-create AND merge).**
251
+ Use the project-layer command from `§Landing`: dry-run first, review the diff,
252
+ then write; preserve gate symbols and stable cells of freshly appended rows.
253
+ Absent a filled layer, use the tracker's native parent/table reconciliation.
231
254
  - **Stacked follow-up PRs** that build on the unmerged wave: base on the **wave
232
- branch** (not main) the platform auto-retargets them when the wave PR merges.
233
- Note the merge order in the body.
234
- - New issues via `scripts/board-sync.py` (never bare `gh issue create`); write
235
- multi-paragraph PR/issue bodies via `--body-file` (an inline body with backticks
236
- can crash the shell).
255
+ branch** (not main) and note the merge order in every PR body. **Do NOT rely on
256
+ auto-retarget:** deleting the merged base branch can close its stacked child.
257
+ Either merge the child before deleting the base, or expect the close and open a
258
+ FRESH PR from the child's still-existing head branch against the final base.
259
+ Keep any deploy/release/manual gate in the documented merge order.
260
+ - New issues go through the project-layer board command (`§Landing`; never a bare
261
+ tracker-create call that skips the board). Write multi-paragraph bodies through
262
+ a body file so shell metacharacters cannot alter them.
237
263
 
238
264
  **Done when:** PR(s) open with correct `Closes`/`Part of` lines · anchor-sync
239
265
  written · merge order documented.
@@ -243,19 +269,40 @@ written · merge order documented.
243
269
  - Stop the dev server(s) you started, by port (`lsof -ti:<port> | xargs kill` —
244
270
  your own processes, targeted by the worktree's assigned ports, never blind).
245
271
  Remove temp verify scripts (a login helper, DB-check scripts).
272
+ - **Remove only this run's claim marker.** If this run planted
273
+ `wave-active/<anchor>`, delete that exact local tag after success or abort. Never
274
+ delete a claim marker observed during a preflight collision or any other
275
+ `wave-active/*` marker; ownership, not a broad pattern, authorizes cleanup.
246
276
  - **Before removing any slice worktree, read its `ANNAHMEN.md`** (an assumptions
247
277
  log, gitignored at worktree-root) and propagate each build-time assumption marker
248
278
  to the sibling issue it carries. A hand-driven multi-PR / migration landing does
249
279
  NOT run `wrapup`'s assumption-propagation step — this is the only place it
250
280
  happens; `worktree remove` deletes the log.
251
- - **Post-merge:** run `anchor-sync` again; verify every leaf issue actually closed
252
- (the same checks `wrapup` runs, by hand when landing outside `wrapup`). The
253
- anchor closes manually a parent is not auto-closed on sub-issue completion.
254
- - A skill edited during the wave run `codex-adapter-sync` (lives in
255
- `.agents/skills/`) in the SAME PR the mirror-presence-parity lint is a
256
- pre-PR gate and blocks a dual-surface skill PR without its mirror.
281
+ - **Post-merge completion sync:** use `§Landing` to reconcile the anchor again and
282
+ verify every leaf actually closed. Then read the anchor's `Closing Conditions`,
283
+ `Done when`, and acceptance criteria and make an explicit closure decision:
284
+ - **No open manual gate:** close the anchor, set its project completion status to
285
+ the configured done role, and re-read the board item to verify both states.
286
+ Closing the tracker issue alone is not proof that its workflow field changed.
287
+ - **Open manual gate:** ask the user in the main thread, naming the exact gate and
288
+ condition. Confirmation follows the close/status/verify path above; otherwise
289
+ leave the anchor open and add exactly one completion marker explaining the
290
+ remaining gate and close condition.
291
+ - **Program propagation:** resolve the anchor's native parent with the
292
+ project-layer command from `§Landing`. If the parent is a Program-PRD, run the
293
+ project-layer program sync after the anchor decision. On closure, set the
294
+ anchor's completion status first so the program can observe the completed wave;
295
+ run program sync again after close even if landing ran it earlier. If a manual
296
+ gate remains open, propagation may refresh the program but must not claim wave
297
+ completion. Absent a filled layer, use equivalent tracker-native parent lookup,
298
+ completion-field update, re-read, and program propagation commands.
299
+ - A skill edited during the wave → sync its dual-surface mirror in the SAME PR
300
+ using the tool named by `§Landing` when present; mirror parity remains a pre-PR
301
+ gate.
257
302
  - Leave slice worktrees for the user to inspect, or note they're
258
303
  post-merge-removable.
259
304
 
260
- **Done when:** no orphan process · ANNAHMEN propagated · anchor reconciled + leaf
261
- closes verified · final report lists landed/pulled slices as **X of Y**.
305
+ **Done when:** no orphan process · this run's claim removed · ANNAHMEN propagated ·
306
+ anchor reconciled + leaf closes verified · anchor closure decided and documented ·
307
+ Program-PRD propagation completed or explicitly skipped · final report lists
308
+ landed/pulled slices as **X of Y**.
@@ -51,12 +51,14 @@ invocation for each in this prompt so the builder cannot guess a wrong one.
51
51
  2. Commit your ONE commit on the slice branch FIRST — before any longer verify
52
52
  (verify-then-forget-to-commit leaves the orchestrator hand-committing your
53
53
  worktree). Do NOT push. Do NOT `--no-verify` (pre-commit hooks must pass).
54
- 3. Run the commands above. Never end your turn with a background command still
55
- running.
54
+ 3. Run the commands above IN THE FOREGROUND never background a test/gate
55
+ command. Use a generous foreground timeout for a long suite and wait for every
56
+ completed command result. Never end your turn while a command is still running.
56
57
 
57
58
  ## Report back (concise)
58
- Files touched · decisions taken · test results (exact output) · commit SHA ·
59
- STOP items · what the orchestrator should visually verify.
59
+ Files touched · decisions taken · test results (exact completed command results
60
+ and exit status) · commit SHA · STOP items · what the orchestrator should visually
61
+ verify.
60
62
  ```
61
63
 
62
64
  Orchestrator notes:
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: retro
3
- disable-model-invocation: true
3
+ disable-model-invocation: false
4
4
  "description": "Use when the user explicitly asks for a retro after a session with PR-activity. Analyzes session friction and proposes concrete config mutations (Memory/Skill/CLAUDE.md/Hook) with per-patch approval. No file is written — findings live in the mutated config."
5
5
  ---
6
6
 
@@ -114,6 +114,25 @@ For **every** friction point (user-reported AND self-found), the agent analyzes:
114
114
 
115
115
  If the user's description in step 2a is ambiguous, the agent may ask **ONE** clarifying outcome question — e.g. "where was it most annoying — during setup, mid-work, or during cleanup?". Never multiple-choice with memory names, hook paths, or config classes.
116
116
 
117
+ ### 3a. Mechanical enforcement check (before target + weight)
118
+
119
+ Before placing a finding on the target/weight ladder, ask for every finding:
120
+
121
+ > **"Could a machine decide this — with a grep, parser, test, hook, or CI gate?"**
122
+
123
+ - **Yes, within the current patch:** implement the enforcement. Supporting prose
124
+ may explain the rule, but prose alone does not resolve a machine-checkable
125
+ finding.
126
+ - **Yes, but enforcement is too expensive for the current patch:** propose the
127
+ prose change **plus a tracked enforcement issue** and state the **explicit
128
+ trade-off** (why enforcement is deferred, what failure remains possible, and
129
+ when the issue should fire). Do not present the prose-only half as complete.
130
+ - **No:** record why judgment is required, then continue to the target/weight
131
+ ladder.
132
+
133
+ This check prevents detection without enforcement: a rule that a machine can
134
+ decide should not depend on a future reader remembering a sentence.
135
+
117
136
  ### 3b. Determine target + weight (threshold ladder)
118
137
 
119
138
  Before formulating a patch in step 4, place **every** friction point on the threshold ladder. **Weight** = how durable/far-reaching the rule is (drives the visible patch line in step 4 + the user's approval depth). **Target** = where the patch physically goes.
@@ -137,6 +156,10 @@ Before formulating a patch in step 4, place **every** friction point on the thre
137
156
 
138
157
  **A GitHub issue is NOT a weight tier.** A real follow-up = work to track → `python3 scripts/board-sync.py create` (step-4 table), **orthogonal** to the ladder; its "weight" follows the follow-up scope. The ladder classifies **config patches**, not "turn it into a ticket".
139
158
 
159
+ **Kit-repo routing target (always ask; never automatic).** When a finding lands on a kit-shipped file (a consumer-manifest entry with kit origin), ask whether the improvement is generic or project-specific. For a generic improvement, offer to file a lightweight issue against the public kit repo: a title plus a short body that states the finding, affected file, and why it is generic. For a project-specific improvement, recommend `own` (keep it consumer-owned). The consumer user does not need to be the kit maintainer.
160
+
161
+ Before any `gh issue create --repo <owner>/agent-workflow-kit` runs, show the user a **sanitized preview** of the exact title and body with consumer identifiers and secrets stripped. Create the issue only after the user explicitly approves that exact text; if the title or body changes, show the revised preview and ask again. This approval is additional to the per-patch approval in step 5.
162
+
140
163
  **Target missing in the project — separate two cases cleanly:**
141
164
  - **(a) Tier skill missing entirely** (e.g. a foreign project without `spec-self-critique`): no durable spec-time gate exists. **Memory is NOT a substitute** — passive recall doesn't catch a recurring spec defect before building. Report honestly: *"this project has no durable target for this tier"* + propose a `/setup-workflow` follow-up. **No fake guard via memory.**
142
165
  - **(b) Skill exists, project-layer file missing** (`docs/agents/skills/<skill>.md`): **create / append** — that is the normal retro-sink behavior that `spec-self-critique` step 0 expects anyway. **No** downgrade.
@@ -119,7 +119,7 @@ One behavior, already clear enough to build — no PRD, no slicing.
119
119
 
120
120
  ```
121
121
  Small change: <one-sentence behavior>.
122
- `tdd` — one behavior at a time, red → green → refactor. No PRD, no decomposition.
122
+ `implement` — build directly, one behavior at a time (red → green → refactor). No PRD, no decomposition.
123
123
  ```
124
124
 
125
125
  ### Bug (something that used to work)
@@ -134,7 +134,7 @@ Bug: <what's broken — expected vs. actual>.
134
134
  ```
135
135
  scale-check: verdict=<Program | Feature | Direct-Slice | Bug>
136
136
  criteria tripped=<C1,C2,… | none | n/a (bug/direct)>
137
- route=<program grill → to-prd → to-waves (all waves execute-ready by default) | grill-with-docs → to-prd → to-issues | tdd | diagnose>
137
+ route=<program grill → to-prd → to-waves (all waves execute-ready by default) | grill-with-docs → to-prd → to-issues | implement | diagnose>
138
138
  start-prompt: <the paste-ready block above, filled in>
139
139
  ```
140
140
 
@@ -27,6 +27,7 @@ This is a prompt-driven skill, not a deterministic script. Explore, present what
27
27
  | `.github/workflows/agent-workflow-kit-update.yml` | optional tested Kit update pull request for GitHub consumers (Section A2) |
28
28
  | `docs/agents/census.md` | optional-census choice, paths, state, and safe disable contract seeded from [census.md](./census.md) (Section A3) |
29
29
  | `docs/agents/workflow-capabilities.json` + capability assets | consumer-owned Worktree Lifecycle, Memory Lifecycle, Workflow Advisories, and Safety Guardrails choices (Sections A4–A7) |
30
+ | `.claude/settings.json` | additive activation of the advisory kit-origin Edit/Write hint (Section A8) |
30
31
 
31
32
  ## Idempotency contract — read before writing anything
32
33
 
@@ -57,7 +58,7 @@ Read the current state; don't assume. For every target file, read its first line
57
58
  - `CONTEXT.md`, `CONTEXT-MAP.md`, `docs/adr/` — domain-doc layout.
58
59
  - `docs/agents/`, `docs/agents/skills/`, `docs/conventions/` — prior output of this skill.
59
60
  - `docs/agents/census.md`, `.census/profile.json`, `.census/active.json` — an existing census choice or consumer-owned census to adopt.
60
- - `docs/agents/workflow-capabilities.json`, `.claude/settings.json`, `git config --get core.hooksPath` — existing capability choices/profile plus Worktree Lifecycle, Workflow Advisories, and Safety Guardrails wiring to adopt.
61
+ - `docs/agents/workflow-capabilities.json`, `.claude/settings.json`, `git config --get core.hooksPath` — existing capability choices/profile plus Worktree Lifecycle, Workflow Advisories, Safety Guardrails, and kit-origin hint wiring to adopt.
61
62
  - `.memory/active/`, `.memory/archive/`, and `.memory/receipts/` — consumer-owned Memory Lifecycle policies or recovery evidence to adopt without normalization.
62
63
  - `gh auth status` (if GitHub) — is `gh` authenticated, and with which scopes?
63
64
 
@@ -243,6 +244,42 @@ The seed's reference consumer uses the parity-on profile. Other consumers are
243
244
  opt-in/manual: never copy its package-manager, path, shim, surface, or outage
244
245
  decisions without repository evidence and user confirmation.
245
246
 
247
+ ### 2g. Section A8 — Advisory kit-origin edit hint (non-interactive)
248
+
249
+ > The shipped kit-origin hook asks the upstream-or-own question before an agent
250
+ > Edit/Write changes a file recorded with `origin: "kit"` in the consumer
251
+ > manifest. It is advisory only: it never blocks, reads the manifest once, uses
252
+ > no network, and silently fails open when the manifest cannot be read. Shell
253
+ > redirection, formatters, and IDE edits are knowingly outside its coverage; the
254
+ > skills remain the rule's primary carrier.
255
+
256
+ Activate the shipped hook by reconciling this exact entry into
257
+ `.claude/settings.json`:
258
+
259
+ ```json kit-origin-edit-hook-settings
260
+ {
261
+ "matcher": "Edit|Write",
262
+ "hooks": [
263
+ {
264
+ "type": "command",
265
+ "command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/kit-origin-edit-hint.py\""
266
+ }
267
+ ]
268
+ }
269
+ ```
270
+
271
+ This is an additive, idempotent settings edit, not a settings rewrite:
272
+
273
+ 1. Missing settings → create `{ "hooks": { "PreToolUse": [<entry>] } }`.
274
+ 2. Existing valid settings → preserve every consumer key, matcher, command,
275
+ hook event, ordering, and formatting byte-for-byte; append only `<entry>` to
276
+ `hooks.PreToolUse`.
277
+ 3. If any existing hook already contains the exact command above, do nothing,
278
+ regardless of its surrounding matcher. A rerun must be byte-identical.
279
+ 4. Unreadable/invalid settings, or a non-object `hooks` / non-array
280
+ `PreToolUse`, are consumer-owned conflicts: leave the file untouched and
281
+ report the skipped activation. Never replace or normalize them.
282
+
246
283
  ### 3. Section B — Triage labels
247
284
 
248
285
  > When `triage` processes an incoming issue it applies labels (or your tracker's equivalent). It needs strings you've actually configured, or it creates duplicates.
@@ -341,6 +378,12 @@ Do not copy templates with shell commands or edit the capability profile by
341
378
  hand. Report `seeded · adopted · skipped`; do not print memory contents or
342
379
  receipt contents.
343
380
 
381
+ For `.claude/settings.json`, run the Section A8 reconciliation on fresh and
382
+ already-initialized consumers. Report `activated · already active · skipped
383
+ (consumer-owned conflict)`. Do not make the hook conditional on an optional
384
+ capability choice: its self-filtering, fail-open behavior keeps it inert except
385
+ for matching kit-origin Edit/Write events.
386
+
344
387
  For the **`## Workflow`**, **`## Agent skills`**, and **`## Prod`** blocks, reconcile per section in **both** CLAUDE.md and AGENTS.md that exist:
345
388
 
346
389
  - If **both** files exist → write/update the block in **both** (keep them coherent — Codex is a first-class surface).
@@ -11,12 +11,12 @@ Use this section as the entry-point map for agent-assisted work. The individual
11
11
  - **Existing plan, PRD, or ready issue:** use `to-issues` to split it into independently buildable tracer-bullet slices.
12
12
  - **A Program-PRD with a wave plan:** use `to-waves` to unfold it into named wave stubs + slice leaves on the board, after a chat preview gate that shows the whole plan before any write.
13
13
  - **A backlog of open issues needs clustering into themed waves:** use `board-to-waves`.
14
- - **A whole wave anchor (file-disjoint slices, specs already locked) to build, verify and land end-to-end — often AFK:** use `orchestrate-wave` — it dispatches implementers per slice, integrates serially, verifies centrally, and lands. (A single slice just goes to `tdd`.)
14
+ - **A whole wave anchor (file-disjoint slices, specs already locked) to build, verify and land end-to-end — often AFK:** use `orchestrate-wave` — it dispatches implementers per slice, integrates serially, verifies centrally, and lands. (A single slice just goes to `implement`.)
15
15
  - **Bugs or requests piling up that you didn't create:** use `triage` to move them into agent-ready issues.
16
16
  - **Bug or regression:** use `diagnose` to reproduce, minimize, hypothesize, instrument, fix, and regression-test.
17
17
  - **A design question needs a runnable answer (state, business logic, a UI you have to see):** spike it with `prototype`, then fold what you learned back in.
18
- - **Multi-session build from a PRD or issue:** use `implement` to drive `tdd` end-to-end, one red-green slice at a time.
19
- - **Implementation slice:** use `tdd` for one behavior at a time: RED, GREEN, then refactor.
18
+ - **Multi-session build from a PRD or issue:** use `implement` to drive the build end-to-end, one red-green slice at a time.
19
+ - **Implementation slice:** use `implement` for one behavior at a time: RED, GREEN, then refactor.
20
20
  - **Build or refresh a project-local census:** use `census-update` to scan facts, resolve ambiguous decisions one at a time, and transactionally activate a counted census.
21
21
  - **Preview or restore consumer-owned memories:** use `memory-lifecycle` to classify every configured path without writing, then apply an explicitly approved collision-safe restore with a content-free receipt.
22
22
  - **Finished slice:** use `wrapup` to prepare the branch, PR, and cleanup steps your repo expects.
@@ -27,11 +27,11 @@ Use this section as the entry-point map for agent-assisted work. The individual
27
27
 
28
28
  ## Routing Rule
29
29
 
30
- Prefer the smallest workflow that produces a clear next action. A tiny fix can go straight to `tdd`; a cross-cutting feature should become a PRD and then slices before implementation. When a skill reports missing project context, run `setup-workflow` again and fill only the missing stub.
30
+ Prefer the smallest workflow that produces a clear next action. A tiny fix can go straight to `implement`; a cross-cutting feature should become a PRD and then slices before implementation. When a skill reports missing project context, run `setup-workflow` again and fill only the missing stub.
31
31
 
32
32
  ## Depth Ladder
33
33
 
34
- - **Light:** direct `tdd` for a small, well-understood change.
34
+ - **Light:** direct `implement` for a small, well-understood change.
35
35
  - **Medium:** `to-issues` for a ready artefact that needs slicing.
36
36
  - **Deep:** `grill-with-docs` followed by `to-prd` and `to-issues` when terminology, contracts, rollout order, or ownership are still uncertain.
37
37
  - **Gate:** insert `verify-spike` or `decision-gate` before any depth level when a slice hinges on an unresolved fact or trade-off.
@@ -60,6 +60,8 @@ Before writing any code:
60
60
 
61
61
  - [ ] Confirm with user what interface changes are needed
62
62
  - [ ] Confirm with user which behaviors to test (prioritize)
63
+ - [ ] Find the nearest existing tests for those behaviors
64
+ - [ ] Assign exactly one test-delta decision per behavior
63
65
  - [ ] Identify opportunities for [deep modules](deep-modules.md) (small interface, deep implementation)
64
66
  - [ ] Design interfaces for [testability](interface-design.md)
65
67
  - [ ] List the behaviors to test (not implementation steps)
@@ -69,34 +71,81 @@ Ask: "What should the public interface look like? Which behaviors are most impor
69
71
 
70
72
  **You can't test everything.** Confirm with the user exactly which behaviors matter most. Focus testing effort on critical paths and complex logic, not every possible edge case.
71
73
 
72
- ### 2. Tracer Bullet
73
-
74
- Write ONE test that confirms ONE thing about the system:
74
+ ### 2. Existing-Test-First Decision
75
+
76
+ TDD does not imply a new test file or a growing test count. Start at the nearest
77
+ existing behavioral test. For each planned behavior, record exactly one of these
78
+ test-delta decisions:
79
+
80
+ - **REUSE** — the existing public-behavior test already protects the change.
81
+ - **EXTEND** — add the missing boundary to the nearest suite or parameter table.
82
+ - **REPLACE** — establish equivalent protection at a smaller or more stable level,
83
+ then retire the duplicate.
84
+ - **NEW** — only for a distinct, previously unprotected risk; name the plausible
85
+ defect it catches.
86
+ - **RETIRE** — the behavior or contract is intentionally gone or already replaced;
87
+ delete its obsolete test.
88
+ - **NO-NEW-TEST** — a behavior-neutral refactor or removal without a durable
89
+ negative contract.
90
+
91
+ Do not create a new test file until the nearest existing owner has been inspected
92
+ and rejected with a reason. A feature, source file, component, method, or
93
+ acceptance-criterion line is not itself a test boundary.
94
+
95
+ Every executable new behavior and bug fix must begin with a failing assertion.
96
+ REUSE and NO-NEW-TEST never bypass this RED-first invariant. For a `REUSE`
97
+ candidate, run the existing assertion before implementation: if the requested
98
+ behavior is executable and the assertion is already green, an already-green
99
+ assertion does not prove the requested change; choose `EXTEND`, or choose `NEW`
100
+ after rejecting the nearest owner. `NO-NEW-TEST` is limited to behavior-neutral
101
+ work and removals without a durable absence contract.
102
+
103
+ For removals, delete the tests that specified the retired behavior. Add or keep a
104
+ negative assertion (`404`, forbidden, hidden) only when absence itself is a durable
105
+ security, API, or compatibility promise. Permanent skipped executable tests are
106
+ retired or moved to a runbook or issue, not parked in the green suite.
107
+
108
+ ### Worked decision matrix
109
+
110
+ | Behavior situation | Decision | Feedback proof |
111
+ |---|---|---|
112
+ | An existing regression test reproduces the bug | REUSE | Existing assertion is RED, then the minimal fix makes it GREEN |
113
+ | The nearest suite lacks one requested boundary | EXTEND | Added assertion is RED, then the minimal change makes it GREEN |
114
+ | A broad duplicate can become a stable focused check | REPLACE | Equivalent protection is proven before the duplicate is removed |
115
+ | A distinct risk has no suitable owner after documented inspection | NEW | New assertion is RED and names the plausible defect it catches |
116
+ | The specified behavior is intentionally removed | RETIRE | Obsolete test is removed with the obsolete behavior |
117
+ | An internal refactor preserves all observable behavior | NO-NEW-TEST | Relevant existing suite is GREEN before and after the change |
118
+
119
+ ### 3. First Feedback Cycle
120
+
121
+ Pick ONE behavior and use its decision's feedback loop:
75
122
 
76
123
  ```
77
- RED: Write test for first behaviortest fails
78
- GREEN: Write minimal code to passtest passes
124
+ REUSE, executable change: existing assertion REDminimal code → GREEN
125
+ EXTEND/NEW: assertion in nearest suite REDminimal code → GREEN
126
+ REUSE, neutral change: relevant suite GREEN → small refactor → stays GREEN
127
+ REPLACE: prove equivalent protection → remove duplicate → GREEN
128
+ RETIRE: remove obsolete behavior and its obsolete test → GREEN
129
+ NO-NEW-TEST: relevant suite GREEN → behavior-neutral change → stays GREEN
79
130
  ```
80
131
 
81
- This is your tracer bullet - proves the path works end-to-end.
132
+ The RED-to-GREEN cycle is the tracer bullet for each executable new behavior or
133
+ bug fix. It proves the path end to end without automatically creating another
134
+ test file.
82
135
 
83
- ### 3. Incremental Loop
136
+ ### 4. Incremental Loop
84
137
 
85
- For each remaining behavior:
86
-
87
- ```
88
- RED: Write next test → fails
89
- GREEN: Minimal code to pass → passes
90
- ```
138
+ Repeat one behavior at a time, using the matching feedback loop above.
91
139
 
92
140
  Rules:
93
141
 
94
142
  - One test at a time
143
+ - Prefer extending the existing owner or parameter matrix over adding a sibling file
95
144
  - Only enough code to pass current test
96
145
  - Don't anticipate future tests
97
146
  - Keep tests focused on observable behavior
98
147
 
99
- ### 4. Refactor
148
+ ### 5. Refactor
100
149
 
101
150
  After all tests pass, look for [refactor candidates](refactoring.md):
102
151
 
@@ -114,7 +163,12 @@ After all tests pass, look for [refactor candidates](refactoring.md):
114
163
  [ ] Test describes behavior, not implementation
115
164
  [ ] Test uses public interface only
116
165
  [ ] Test would survive internal refactor
166
+ [ ] Exactly one test-delta decision is recorded for this behavior
167
+ [ ] NEW names the distinct plausible defect; a new file has a justified owner boundary
117
168
  [ ] Code is minimal for this test
118
169
  [ ] No speculative features added
119
170
  [ ] Wave slice: a flipped/new assumption affecting an unbuilt sibling issue → log it to ANNAHMEN.md (worktree root; wrapup Step 0c reads it)
120
171
  ```
172
+
173
+ At handoff, list every behavior and its one decision, then report the counted
174
+ test delta: `Reused X · Extended Y · New Z · Replaced/retired W`.
@@ -54,7 +54,7 @@ Even when the slices were already cut upstream (a grill/PRD slice table), do NOT
54
54
  - **Seam ownership check (Fix A):** does any slice **replace/unify/retire a central mechanism**? If yes, it MUST be its own 🧊 grill-needed slice — NOT hidden in a behavior-preserving naming/tweak leaf. A byte-neutral slice does not discharge the seam.
55
55
  - **Blast-radius threshold:** for each slice, estimate the blast radius (~N files, from recon/grep — not a guess; workflow slices count SKILL.md + adapter mirrors + tests). **≥ 10 estimated files OR not estimable → check for a split.** If the slice stays deliberately large, it MUST be 🧊 **grill-needed** (HITL) with a "why indivisible" justification **in the issue body** — a guideline, not a hard block, but the deviation lives in the body, not in the agent's head. (Incident: a slice cut too coarse ballooned to 34 prod files at execute-recon, an emergency in-build split — no gate at the cut existed.) (Terminology note: this blast radius is a **slice estimate** — ~N files for this one cut — not a project-owned rollout-completeness census (e.g. an-style, code-derived "X of Y" census over all surfaces of a cross-cutting concept, if your repo runs one).)
56
56
  <!-- mirror-xform:start codex-escalation -->
57
- - **Gate type + sequencing (Retro):** every slice that is **not** a clean AFK build gets a gate tag — 🧭 **Design Grill** (a decision with alternatives, hard-to-reverse, ADR-worthy → `grill-with-docs`), 🔬 **Verify Spike** (a pure fact question, read-only), 📐 **Trade-off/Research** (a concrete trade-off choice OR "needs more research", **below** the grill threshold — read-only research + a documented trade-off in the issue), 📝 **Review Note** (a finding, **not** a build slice). A gate slice (🧭/🔬/📐) is cut as its **own slice**, sequenced **before** its dependent build slice, and blocks it (gate-before-build — published as a **native blocking edge** (§5a step 5), visible in the mirrored "Blocked by" section + table order). "Needs a decision / open call / research gap" while cutting → gate slice, **never** a blind AFK `/tdd`. (🔬 **Verify Spike** runs via the `verify-spike` skill — read-only fact question, throwaway harness, verdict as ADR/comment, the throwaway deleted. 📐 **Trade-off/Research** runs via the `decision-gate` skill — options + criteria, read-only research/measurement, a documented trade-off table, a reasoned decision as ADR/comment; throwaway measurement code deleted.)
57
+ - **Gate type + sequencing (Retro):** every slice that is **not** a clean AFK build gets a gate tag — 🧭 **Design Grill** (a decision with alternatives, hard-to-reverse, ADR-worthy → `grill-with-docs`), 🔬 **Verify Spike** (a pure fact question, read-only), 📐 **Trade-off/Research** (a concrete trade-off choice OR "needs more research", **below** the grill threshold — read-only research + a documented trade-off in the issue), 📝 **Review Note** (a finding, **not** a build slice). A gate slice (🧭/🔬/📐) is cut as its **own slice**, sequenced **before** its dependent build slice, and blocks it (gate-before-build — published as a **native blocking edge** (§5a step 5), visible in the mirrored "Blocked by" section + table order). "Needs a decision / open call / research gap" while cutting → gate slice, **never** a blind AFK `/implement`. (🔬 **Verify Spike** runs via the `verify-spike` skill — read-only fact question, throwaway harness, verdict as ADR/comment, the throwaway deleted. 📐 **Trade-off/Research** runs via the `decision-gate` skill — options + criteria, read-only research/measurement, a documented trade-off table, a reasoned decision as ADR/comment; throwaway measurement code deleted.)
58
58
  <!-- mirror-xform:end -->
59
59
  - **🧭-vs.-📐 discriminator:** if the decision replaces/unifies/retires a **central seam**, is a **one-way door** (hard/costly to reverse), or a **schema migration** → 🧭 Design Grill (ADR-worthy, see Seam Ownership above). Otherwise — a **bounded choice between concrete options**, easily revised → 📐 Trade-off/Research.
60
60
  - **Absence-before-build (Retro):** a slice cut as "build feature/page/endpoint/flow X" (or a gate "X gap unclear") MUST cite an **existence grep** — *absent* (`grep <pattern> = 0` across route **and** UI **and** repo) OR *partial* (`exists @<file>, gap = <Y>`). A hedge ("current state unclear → verify during build") is **not** a valid slice state: the check is cheap (minutes), so it happens **at the cut**, not deferred into a gate. (Incident: a gate was cut for a feature that greps already showed built — the gap was deferred instead of resolved.)
@@ -302,7 +302,7 @@ Reference the blocking ticket(s), or "None - can start immediately".
302
302
  <!-- mirror-xform:start codex-escalation -->
303
303
  ```
304
304
  Welle <N> · Slice <X> (<closes #x | refs #<prd#>, Parent #<prd#>>). Read #<prd#> for decisions.
305
- Start skill: 🧭 Design Grill → /grill-with-docs · 🔬 Verify Spike → /verify-spike · 📐 Trade-off/Research → /decision-gate · AFK → /tdd · HITL → /grill-me → /tdd. Recommended model: <Model [Effort]>.
305
+ Start skill: 🧭 Design Grill → /grill-with-docs · 🔬 Verify Spike → /verify-spike · 📐 Trade-off/Research → /decision-gate · AFK → /implement · HITL → /grill-me → /implement. Recommended model: <Model [Effort]>.
306
306
  Worktree: your project's worktree helper, or `git worktree add`
307
307
  Scope (<N> files) — REQUIRED FIELD, blast-radius estimate at cut time; the build session checks it against its own recon findings, >2x deviation → STOP:
308
308
  - <concrete file + change>
@@ -17,7 +17,7 @@ This is the "Verify First" rule with a runnable harness behind it: when you cann
17
17
  | "Which of these options, given these trade-offs?" / "I need to research this before I can choose." (bounded, sub-grill) | `decision-gate` |
18
18
  | "Does this design / state model / UI feel right?" (open-ended) | `prototype` |
19
19
  | "Why is this broken / slow?" (root-cause of a known defect) | `diagnose` |
20
- | "Build this behaviour, test-first." (new feature/fix) | `tdd` |
20
+ | "Build this behaviour, test-first." (new feature/fix) | `implement` |
21
21
 
22
22
  If the question is really "what should this be", it is not a verify-spike — those are open, not yes/no.
23
23
 
@@ -29,9 +29,21 @@ Hard stop (the only pure precondition): not in a feature worktree / on `main`
29
29
 
30
30
  ### 2 · Retro gate (blocking, optional retro-exit — before anything is committed)
31
31
  One reminder, not a merge confirmation:
32
- > "Already ran a retro? **(a)** yes / continue → landing now. **(b)** you want one first → clean abort here, run `/retro`, then `/wrapup` again — repo-file patches then travel in this PR."
32
+ > "Already ran a retro? **(a)** yes / continue → landing now. **(b)** you want one first → the retro starts now; afterwards, invoke `/wrapup` again — repo-file patches then travel in this PR."
33
33
 
34
- (b) → exit cleanly, touch nothing (a skill can't pause/resume another skill). **Never auto-run `/retro`.** The answer materializes as the mandatory `**Retro:**` PR-body line in step 4 — that's recording, not a second question. Why the gate lives here: in a foreign project this is the only portable retro touchpoint; a project-local "offer retro before PR" convention usually answers it already.
34
+ (b) → **invoke the `retro` skill immediately in this run.** Retro is
35
+ model-invocable and non-deploying, and every mutation still has its own approval
36
+ gate. After retro finishes, **land nothing in this run**. Require a **fresh
37
+ explicit `/wrapup` invocation** because retro may have changed the exact diff
38
+ that the next merge authorization covers.
39
+
40
+ General chaining rule: automatically chain only into a **model-invocable**,
41
+ **non-deploying** workflow. If the named target is user-only, deploys, or
42
+ depends on an external action, **return control to the user** and **state the
43
+ reason**. A forward chain never carries wrapup's merge/deploy authorization
44
+ into another run.
45
+
46
+ The answer materializes as the mandatory `**Retro:**` PR-body line in step 4 — that's recording, not a second question. Why the gate lives here: in a foreign project this is the only portable retro touchpoint; a project-local "offer retro before PR" convention usually answers it already.
35
47
 
36
48
  ### 3 · Commit (only if the tree is dirty)
37
49
  Judgment first, then the guarded commit:
@@ -48,8 +48,11 @@ GUARD_ACK_RE = re.compile(r"<!--\s*guard-ack:\s*#?\d+\s+r\d+\s+reason:.+\bby-use
48
48
  # Load the shared checker (hyphenated filename → importlib). Repo root = parents[2].
49
49
  _CHECKER_PATH = Path(__file__).resolve().parents[2] / "scripts" / "execute-ready-check.py"
50
50
  _CENSUS_MODULE_PATH = Path(__file__).resolve().parents[2] / "scripts" / "census" / "index.mjs"
51
- CENSUS_BRIDGE_TIMEOUT_SECONDS = 15
52
- CENSUS_PROOF_TIMEOUT_MS = 5_000
51
+ # Production repositories can need more than the former five-second proof and
52
+ # fifteen-second bridge budgets. Keep the default proof comfortably below the
53
+ # outer bridge so a hung repository-local proof still cannot wedge the hook.
54
+ CENSUS_BRIDGE_TIMEOUT_SECONDS = 30
55
+ CENSUS_PROOF_TIMEOUT_MS = 12_000
53
56
 
54
57
  _CENSUS_SCAN = r"""
55
58
  import { readFileSync } from 'node:fs';