shapeup-sdlc 3.18.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/.claude/settings.local.example.json +2 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/AGENTS.md +115 -56
  4. package/README.md +101 -143
  5. package/SECURITY.md +16 -25
  6. package/agents/orient.md +14 -0
  7. package/agents/qa-edge-hunter.md +13 -0
  8. package/agents/spec-evaluator.md +14 -0
  9. package/agents/task-executor.md +14 -0
  10. package/bin/init.mjs +13 -16
  11. package/bin/lib/grant.mjs +8 -19
  12. package/commands/build.md +9 -14
  13. package/commands/eval.md +3 -3
  14. package/commands/hammer.md +9 -5
  15. package/commands/retro.md +12 -11
  16. package/commands/scopes.md +1 -12
  17. package/commands/ship.md +45 -88
  18. package/commands/wire.md +1 -8
  19. package/hooks/dispatch-receipt.mjs +94 -8
  20. package/hooks/hooks.json +0 -41
  21. package/hooks/lib/decision.mjs +6 -9
  22. package/hooks/lib/tier.mjs +50 -0
  23. package/hooks/sandbox-guard.mjs +140 -64
  24. package/kernel/gate.mjs +203 -22
  25. package/kernel/harness.mjs +20 -67
  26. package/kernel/init/run.mjs +175 -523
  27. package/kernel/lib/contract.mjs +9 -93
  28. package/kernel/lib/floor.mjs +64 -0
  29. package/kernel/lib/paths.mjs +39 -112
  30. package/kernel/order.mjs +157 -0
  31. package/kernel/probe/digest.mjs +2 -38
  32. package/kernel/schemas/domain.schema.json +146 -1125
  33. package/kernel/schemas/work-order.schema.json +8 -4
  34. package/kernel/schemas/work-result.schema.json +1 -1
  35. package/kernel/verify/envelope.mjs +2 -2
  36. package/kernel/verify/skills.mjs +27 -8
  37. package/kernel/verify/t0.mjs +2 -2
  38. package/package.json +4 -2
  39. package/skills/building/SKILL.md +144 -0
  40. package/skills/building/resources/gates.md +76 -0
  41. package/skills/building/resources/guidance.md +23 -0
  42. package/skills/{translator/references/preservation-rules.md → building/resources/intake-preservation.md} +1 -1
  43. package/skills/building/resources/intake.md +157 -0
  44. package/skills/building/resources/orders.md +69 -0
  45. package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/doc-schemas.md +1 -1
  46. package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/task-generation.md +13 -13
  47. package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/test-surface.md +6 -7
  48. package/skills/building/resources/plan-scopes.md +95 -0
  49. package/skills/building/resources/plan-spec.md +102 -0
  50. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/_index.tmpl.md +1 -1
  51. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/assess-report.tmpl.md +10 -11
  52. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/run-state.tmpl.md +4 -4
  53. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/scope-summary.tmpl.md +2 -2
  54. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/synthesis.tmpl.md +4 -4
  55. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/usecase.tmpl.md +2 -2
  56. package/skills/building/resources/plan-wire.md +82 -0
  57. package/skills/building/resources/plan.md +98 -0
  58. package/skills/building/resources/retro-research.md +60 -0
  59. package/skills/building/resources/retro-scan.md +49 -0
  60. package/skills/building/resources/retro.md +225 -0
  61. package/skills/building/resources/rounds.md +78 -0
  62. package/skills/building/resources/stop.md +127 -0
  63. package/skills/orient/SKILL.md +37 -37
  64. package/skills/qa-edge-hunter/SKILL.md +14 -14
  65. package/skills/shapeup/SKILL.md +5 -5
  66. package/skills/shapeup/resources/breadboarding.md +1 -1
  67. package/skills/shapeup/resources/context-compaction.md +5 -5
  68. package/skills/shapeup/resources/shaping.md +1 -1
  69. package/skills/spec-evaluator/SKILL.md +17 -21
  70. package/skills/spec-evaluator/references/dimension-contract.md +1 -1
  71. package/skills/spec-evaluator/references/dimensions/completeness.md +3 -3
  72. package/skills/spec-evaluator/references/dimensions/spec-conformance.md +1 -1
  73. package/skills/spec-evaluator/references/dimensions/test-surface-conformance.md +5 -5
  74. package/skills/task-executor/SKILL.md +11 -15
  75. package/commands/hill.md +0 -10
  76. package/hooks/gate-intake.mjs +0 -109
  77. package/hooks/gate-zerowork.mjs +0 -349
  78. package/hooks/tier-guard.mjs +0 -162
  79. package/kernel/compile.mjs +0 -1419
  80. package/kernel/init/fit.mjs +0 -199
  81. package/kernel/init/run-args.mjs +0 -206
  82. package/kernel/lib/breadboard.mjs +0 -165
  83. package/kernel/probe/attempts.mjs +0 -161
  84. package/kernel/probe/concurrency.mjs +0 -535
  85. package/kernel/probe/eval.mjs +0 -405
  86. package/kernel/probe/hunt.mjs +0 -104
  87. package/kernel/probe/leg.mjs +0 -229
  88. package/kernel/probe/owner.mjs +0 -142
  89. package/kernel/probe/requirements.mjs +0 -328
  90. package/kernel/probe/resume.mjs +0 -1110
  91. package/kernel/probe/rounds.mjs +0 -115
  92. package/kernel/probe/staged.mjs +0 -83
  93. package/kernel/probe/stats.mjs +0 -477
  94. package/kernel/probe/t0.mjs +0 -115
  95. package/kernel/reduce/board.mjs +0 -350
  96. package/kernel/reduce/graph.mjs +0 -482
  97. package/kernel/reduce/hill.mjs +0 -322
  98. package/kernel/reduce/ingest.mjs +0 -767
  99. package/kernel/reduce/leftovers.mjs +0 -159
  100. package/kernel/reduce/ship.mjs +0 -529
  101. package/kernel/reduce/snapshot.mjs +0 -291
  102. package/kernel/reduce/verdict.mjs +0 -172
  103. package/kernel/report/export.mjs +0 -384
  104. package/kernel/report/facts.mjs +0 -234
  105. package/kernel/verify/budget.mjs +0 -153
  106. package/kernel/verify/build.mjs +0 -428
  107. package/kernel/verify/dispatch.mjs +0 -114
  108. package/kernel/verify/spec.mjs +0 -975
  109. package/kernel/verify/trace.mjs +0 -604
  110. package/skills/ba-pitch-analyzer/SKILL.md +0 -204
  111. package/skills/coach/SKILL.md +0 -397
  112. package/skills/hill-chart/SKILL.md +0 -154
  113. package/skills/hill-chart/assets/dashboard.template.html +0 -1432
  114. package/skills/scope-architect/SKILL.md +0 -174
  115. package/skills/scope-hammer/SKILL.md +0 -231
  116. package/skills/solution-architect/SKILL.md +0 -158
  117. package/skills/tech-lead/SKILL.md +0 -151
  118. package/skills/tech-lead/references/gates.md +0 -605
  119. package/skills/tech-lead/references/protocol.md +0 -889
  120. package/skills/tech-lead/references/tiny-lane.md +0 -53
  121. package/skills/tech-lead/workflows/shapeup-run.js +0 -2187
  122. package/skills/translator/SKILL.md +0 -258
  123. /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/contract-patterns.md +0 -0
  124. /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/ddd-patterns.md +0 -0
  125. /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/integration-analysis.md +0 -0
  126. /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/ux-behavior-patterns.md +0 -0
  127. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/api-feasibility.tmpl.md +0 -0
  128. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/contracts/be-service.contract.tmpl.md +0 -0
  129. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/contracts/offline-storage.contract.tmpl.md +0 -0
  130. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/contracts/third-party-api.contract.tmpl.md +0 -0
  131. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/context-map.tmpl.md +0 -0
  132. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/event-choreography.tmpl.md +0 -0
  133. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/migration-plan.tmpl.md +0 -0
  134. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/team-handoff.tmpl.md +0 -0
  135. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/domain-model.tmpl.md +0 -0
  136. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/feedback.tmpl.md +0 -0
  137. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/integration.tmpl.md +0 -0
  138. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/task-board.tmpl.md +0 -0
  139. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/task-spike.tmpl.md +0 -0
  140. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/task.tmpl.md +0 -0
  141. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/ux-behavior.tmpl.md +0 -0
package/README.md CHANGED
@@ -10,9 +10,8 @@ Your agent says it's done. It isn't. This is a [Claude Code](https://code.claude
10
10
  that runs a full Shape Up lifecycle — idea → pitch → build → evaluate → ship — where the
11
11
  important rules are enforced by the runtime instead of asked for in a prompt.
12
12
 
13
- The ceremony is right-sized: `/ship` runs the full gated pipeline for real features, and
14
- `/ship --tiny` runs a two-gate lane (orient → build → smoke-test → done) for the one-file
15
- fixes where the gates would have nothing to say.
13
+ The ceremony is sized by the pitch's appetite: `/ship` runs the full gated loop, and a small
14
+ pitch is a one-scope run with a short round budget — the gates and the verification floor are the same.
16
15
 
17
16
  <p align="center">
18
17
  <img src="docs/assets/demo-gate.svg" alt="Terminal recording: a worker tries to edit a file outside the scope it was given, a PreToolUse hook denies the write and names the path, and the next edit inside the scope is permitted." width="700">
@@ -33,17 +32,16 @@ prompt-based harness:
33
32
  **1. A worker cannot act on an order nobody compiled.** Every dispatch carries a schema-validated
34
33
  WorkOrder, and a `PreToolUse` hook hard-denies the call when that order is missing or malformed —
35
34
  the tool call never reaches the worker. The same layer denies any write the order's own substrate
36
- does not permit, and blocks a session that dispatched the orchestrator and left no run receipt.
35
+ does not permit. A run that left no receipt did not happen.
37
36
  → *Prevents: an agent inventing its own brief, then reporting against it.*
38
37
 
39
- (GATE L2, the board-green check before evaluation, is advisory: it warns when a round's evaluation
38
+ (The Round Close gate, the board-green check before evaluation, is advisory: it warns when a round's evaluation
40
39
  runs over unfinished tasks rather than denying it. The board is local to the machine running the
41
- harness — see [ADR-0001](docs/design/adr/0001-consumer-file-organization.md).)
40
+ harness.)
42
41
 
43
- **2. Progress is measured, not claimed.** A scope counts as built only when `t0-verify` runs
42
+ **2. Progress is measured, not claimed.** A scope counts as built only when `verify t0` runs
44
43
  its fixtures and its DB probe and writes an artifact to disk — with each command's exit code,
45
- its captured output, and whether it ran at all. The evaluator must cite that artifact, and the
46
- hill phase is derived from artifacts rather than from a worker's own account of its progress.
44
+ its captured output, and whether it ran at all. The evaluator must cite that artifact, and a worker's own account of its progress counts for nothing.
47
45
  Two limits, stated here because the point of this section is that a claim without a mechanism
48
46
  behind it is the thing this harness exists to prevent: a citation is re-hashed from disk, checked
49
47
  against the scope, round and run the artifact records, and refused unless it names a file this
@@ -57,7 +55,7 @@ told from a regression. That block measures and judges nothing.
57
55
  → *Prevents: "done" asserted with nothing behind it.*
58
56
 
59
57
  **3. Parallel work can't corrupt shared state.** Each scope gets a write-whitelist of files
60
- enforced by a hook, and one script performs every board/ledger/verdict write.
58
+ enforced by a hook, and the loop alone applies every board and ledger change.
61
59
  → *Prevents: two parallel executors both rewriting the board, and one's completions vanishing.*
62
60
 
63
61
  Under the hood this rests on a typed worker envelope and a single-writer state layer. Those
@@ -92,18 +90,10 @@ quickstart.
92
90
  > npx shapeup-sdlc init -d . -y
93
91
  > ```
94
92
  >
95
- > **And lift the print-mode background ceiling, or the run is killed at ten minutes.** `claude -p`
96
- > terminates a session's background tasks after 600 s by default, and the whole pipeline runs as
97
- > one background launch — so an unattended run dies mid-BUILD with the CLI reporting nothing worse
98
- > than "background tasks still running after 600s; terminating". Measured, on a run that had
99
- > reached WIRE:
100
93
  >
101
- > ```bash
102
- > CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0 claude -p "/shapeup-sdlc-plugin:ship …" …
103
- > ```
104
- >
105
- > Nothing is lost when it happens — resume state is on disk, so relaunching fast-forwards past the
106
- > phases that finished. It costs a relaunch, not a run.
94
+ > The loop runs in your own session, in the foreground, so print mode's background-task ceiling does
95
+ > not apply to it. A killed session loses nothing: `/ship` again over the open run reads the artifacts on
96
+ > disk and carries on from the first step that is not done.
107
97
 
108
98
  Want to see a full run before installing anything? **[docs/quickstart.md](docs/quickstart.md)**
109
99
  walks one small feature end to end — including what the hooks do to a premature eval, a FAIL round
@@ -117,9 +107,9 @@ installer, and troubleshooting are in
117
107
  ## Agent support
118
108
 
119
109
  The harness targets **Claude Code only**. The reason is the row that never travelled when we
120
- compiled to other CLIs: hooks. The 13 skills, 11 slash commands and the kernel are
121
- portable prose and plain Node — but hook-enforced gates (envelope validation, substrate
122
- sandbox, safety spine, the zero-work block) are a per-CLI mechanism, and without them every gate degrades from
110
+ compiled to other CLIs: hooks. The 6 skills, 10 slash commands and the kernel are
111
+ portable prose and plain Node — but hook-enforced gates (envelope validation, the substrate
112
+ fence, the safety spine, dispatch receipts) are a per-CLI mechanism, and without them every gate degrades from
123
113
  **enforced** to **instructed** — the same honor system every other framework runs on
124
114
  everywhere. If the deny hooks are why you're here, that means Claude Code.
125
115
 
@@ -130,16 +120,15 @@ rest of this README after this table and nothing will be a surprise.
130
120
 
131
121
  | Term | In plain English |
132
122
  |---|---|
133
- | **board** | The round's task list. "Green" means every task is done. GATE L2's hook reads this before an evaluation and warns if it is not green. |
123
+ | **board** | The round's task list. "Green" means every task is done. The Round Close gate reads this before an evaluation and warns if it is not green. |
134
124
  | **round** | One build → evaluate cycle. A FAIL verdict starts round *r+1*. |
135
125
  | **T0** | The smoke test a scope must pass before it counts as built: its fixtures and a DB probe. Writes an artifact to disk that the evaluator must cite. |
136
126
  | **substrate** | The exact list of files one dispatch is allowed to write, stamped into its work order. A hook blocks anything outside it — and anything the order marks frozen. |
137
127
  | **scope contract** | The file defining one vertical slice: its substrate, its fixtures, its affordances. |
138
128
  | **affordance** | The thing a user can actually click, type or call. UI is graded on affordances, not on looks. |
139
- | **hill / hill phase** | How much of a scope is still *unknown* versus merely *unfinished*. Derived from T0 facts — never self-reported. |
140
- | **gate (L0–L4)** | A numbered checkpoint in a run. Most pause for you; GATE L2 is the one a hook observes and reports on. |
141
- | **covers-closure** | Every requirement clause has at least one task claiming to cover it. Nothing silently drops. |
142
- | **wiring reachability** | Every engine has a call site reachable from the app's real entry point. Catches "built, but never wired up". Reports itself unchecked, with a reason, when the import walk cannot be rooted — an unfollowable import, or no reachable engine to control it. |
129
+ | **hill / hill phase** | How much of a scope is still *unknown* versus merely *unfinished*. The Scout reports a signal at orient; nothing later derives it. |
130
+ | **gate** | A checkpoint in a run, called by its plain name: Intake & Config, Orient Review, Wiring Review, Board Review, Round Close, Verdict, QA Edge Hunt, Cut-List Review, Ship Sign-off and Retro Ownership. [`AGENTS.md`'s Gate names](AGENTS.md#gate-names) says what each one checks. Most pause for you; the Round Close gate is advisory: it can be crossed over unfinished work, recorded as a flagged `warn`. |
131
+ | **covers-closure** | Every requirement clause is graded by at least one acceptance criterion or claimed by a scope, or the PO marks it `CUT`. The loop reads the plan back for this before the board review; nothing silently drops. |
143
132
  | **discovery ledger** | The one file everything found mid-run gets written to, so nothing is lost between rounds. |
144
133
 
145
134
  A longer version, including the internals, is in [docs/glossary.md](docs/glossary.md).
@@ -153,41 +142,36 @@ document as a whole starts at [`docs/design/`](docs/design/README.md). This diag
153
142
  full phase and gate mechanism — simpler than that per-attempt detail, but the whole pipeline:
154
143
 
155
144
  <p align="center">
156
- <img src="docs/assets/workflow-mechanism.svg" alt="The shapeup-sdlc harness pipeline from raw idea to Coach Retro: Shaping produces a Pitch, the Betting Table bets into the tech-lead-orchestrated run or rejects back to raw idea, Kick-off through Ship Sign-off cross gates L0, L1a, L1a.5, L1b, advisory L2, L3, GATE H and L4, the Build/Evaluate round loops on FAIL, and a circuit breaker routes straight to GATE H — bypassing QA — when the round or wall-clock budget runs out." width="900">
145
+ <img src="docs/assets/workflow-mechanism.svg" alt="The shapeup-sdlc harness pipeline from raw idea to Retro: Shaping produces a Pitch, the Betting Table bets into the loop-driven run or rejects back to raw idea, Kick-off through Ship Sign-off cross gates Intake & Config, Orient Review, Wiring Review, Board Review, the advisory Round Close, Verdict, Cut-List Review and Ship Sign-off, the Build/Evaluate round loops on FAIL, and a circuit breaker routes straight to Cut-List Review — bypassing QA — when the round budget runs out." width="900">
157
146
  </p>
158
147
 
159
148
  <p align="center"><sub>
160
149
  Plan-phase skills in blue, build-phase in green, QA-phase in pink; amber pills are gates —
161
- the outlined <b>L2</b> is advisory, the rest block. The dashed region marks what
162
- <code>/tech-lead</code> orchestrates end to end.
150
+ the outlined <b>Round Close</b> gate is advisory, the rest block. The dashed region marks what
151
+ <code>/ship</code> drives end to end.
163
152
  </sub></p>
164
153
 
165
- Since v1.3 the pipeline carries a **traceability spine**: `ba-pitch-analyzer`'s `coverage`
166
- operation writes a requirement registry (`requirements.md`), `solution-architect` commits a
167
- per-use-case wiring map (`wiring-map.md`, gate L1a.5) resolved against the L0
168
- `project-profile.md`, and the covers-closure + reachability oracle
169
- `kernel/verify/trace.mjs` checks that no engine ships orphaned. It runs
170
- advisory (warn-only) and is promoted to a blocking gate only once `covers:` is populated;
171
- every arm is skipped when its artifact is absent, so older specs are unaffected.
154
+ Since v1.3 the pipeline carries a **traceability spine**: the plan activity's requirements
155
+ substep writes a requirement registry (`requirements.md`), its wire substep commits a
156
+ per-use-case wiring map (`wiring-map.md`, the Wiring Review gate) resolved against the Intake & Config `project-profile.md`, and the loop reads the plan back at the board review for a
157
+ registered requirement that no acceptance criterion grades. It is advisory until `covers:` is
158
+ populated; every arm is skipped when its artifact is absent, so older specs are unaffected.
172
159
 
173
160
  ## What's included
174
161
 
175
162
  ### Skills
176
163
 
177
- | Phase | Skill | Version | What it does |
178
- |-------|-------|---------|--------------|
179
- | Shaping (1–4) | `shapeup` | — | Frame the problem, breadboard affordances, spike risks, write the pitch. Sub-commands: `full`, `shaping`, `spike`, `breadboarding`, `framing-doc`, `kickoff-doc`, `breadboard-reflection`. |
180
- | Intake (GATE L0) | `translator` | — | Normalizes non-English intake (pitch/PRD/transcript) to faithful English before planning. The harness is English-only downstream. |
181
- | Orient (7) | `orient` | — | Builder-led recon: reads the code, spikes the single riskiest area, emits a code-surface map, spike findings, discovered-task seed, and a hill signal. Writes no production code. |
182
- | Wire (GATE L1a.5) | `solution-architect` | v1.1 | Sole writer of the committed wiring map (`wiring-map.md`): per-UC engine → integration seam → entry-point call site → player-visible affordance, resolved against `project-profile.md`. Front-loads the integration seam so no engine ships orphaned; the reachability input `harness verify trace` checks. Operation: wire. |
183
- | Map Scopes (8) | `ba-pitch-analyzer` | v4.0 | The spec-analyzer (pure worker). Decomposes a pitch into a linked DDD document tree (domain model → use cases → tasks) with BDD scenarios, a UC system flow, and a derived `## Test Surface`. One craft, four order-selected operations (analyze / reconcile / retrofit-surface / coverage — the last writes the shared `requirements.md` registry for covers-closure); graph math + audits delegated to `harness reduce board`/`harness verify spec`. |
184
- | Map Scopes (8) | `scope-architect` | v1.0 | Sole writer of committed, write-whitelisted scope contracts (`scopes/*.md`): import-graph slicing by flow, substrates, affordance manifests, fixtures. Operation: map-scopes. |
185
- | Build (9) | `task-executor` | v2.0 | Pure worker: work order in → code out. Assumption scan, minimum-code/surgical-change discipline, Layer 1/2/3 UI rules, substrate-sandboxed, zero-memory. Never writes boards/ledgers/run-state. |
186
- | Evaluate (GATE L3) | `spec-evaluator` | v1.0 | The single judge (pure worker). Verifies spec-conformance, TDD surface, and integration against the running app — skeptical, files `file:line` bugs, runs exactly once per build round. Requires a T0 artifact citation, grades UI affordance-only; verdict + refuted boxes return as data. |
187
- | QA (post-PASS) | `qa-edge-hunter` | v1.1 | Exploratory edge hunt on the running app through six fixed lenses, charting edges *outside* what the evaluator probed. Findings go to the ledger as `~`; never blocks ship. |
188
- | Stop (11) | `scope-hammer` | v0.1 | GATE H: must-have census → baseline comparison (never vs. the ideal) → cut list + ship verdict. Handles the normal stop and both circuit-breaker triggers. |
189
- | Retro (post-L4) | `coach` | — | RLHF for the harness: turns raw PO/TL feedback at Ship Sign-off into per-skill guidelines under committed `shapeup/knowledge-base/<skill>.md`, read back by six coachable workers on their next run and by `tech-lead` at GATE L0 (workflow guidance, never a gate answer). `--scan` seeds the same files from the project on disk before the first run; `--research <stack>` seeds them from the platform's official documentation when the project has nothing to scan, and cross-checks a scan's rules when it has. GATE COACH-1 asks the PO which skill owns each rule — never assumes; mechanism defects are filed to the harness-defect register instead. |
190
- | Orchestrator | `tech-lead` | v1.0 | Owns the run end-to-end: PLAN once → BUILD all tasks → EVAL once per round, looping on FAIL. Three-level circuit breaker (rounds / T0 attempts / wall clock), T0-verified build rounds, mechanical hill derivation. Sole writer of run-state. |
164
+ | Phase | Skill | What it does |
165
+ |-------|-------|--------------|
166
+ | Shaping | `shapeup` | Frame the problem, breadboard affordances, spike risks, write the pitch. Sub-commands: `full`, `shaping`, `spike`, `breadboarding`, `framing-doc`, `kickoff-doc`, `breadboard-reflection`. |
167
+ | Intake & Config | `building` | The `intake` sub-command, done by the loop itself: a non-English intake (pitch/PRD/transcript) becomes a faithful English `<name>.en.md` plus a persisted glossary, verified (residual-language scan, structural diff) before the run opens on it. The harness is English-only downstream. |
168
+ | Orient | `orient` | Builder-led recon: reads the code, spikes the single riskiest area, emits a code-surface map, spike findings, discovered-task seed, and a hill signal. Writes no production code. |
169
+ | Plan (Wiring Review, Board Review) | `building` | The loop that drives a run in your session, reading the run's files to decide what comes next. Planning is its `plan` activity, done in the loop's own context — no sub-agent — under a write fence (a fence-only `plan` order): requirements registry (`requirements.md`) → linked DDD spec tree + board (use cases with BDD scenarios, a system flow and a derived `## Test Surface`) → the committed wiring map (`wiring-map.md`: per-UC engine → seam → entry-point call site → affordance, resolved against `project-profile.md`) → write-whitelisted scope contracts (`scopes/*.md`). The loop reads the plan back against each substep's checklist; no script lints it. |
170
+ | Build | `task-executor` | Pure worker: work order in → code out. Assumption scan, minimum-code/surgical-change discipline, Layer 1/2/3 UI rules, substrate-sandboxed, zero-memory. Never writes boards/ledgers/run-state. |
171
+ | Evaluate (Verdict) | `spec-evaluator` | The single judge (pure worker). Verifies spec-conformance, TDD surface, and integration against the running app — skeptical, files `file:line` bugs, runs exactly once per build round. Requires a T0 artifact citation, grades UI affordance-only; verdict + refuted boxes return as data. |
172
+ | QA (post-PASS) | `qa-edge-hunter` | Exploratory edge hunt on the running app through six fixed lenses, charting edges *outside* what the evaluator probed. Findings go to the ledger as QA findings; never blocks ship. |
173
+ | Stop (Cut-List Review) | `building` | The `stop` sub-command — the Cut-List Review gate, done by the loop itself: must-have census (every ownership, exhaustion and requirement claim names the file it came from) → baseline comparison (never vs. the ideal) → cut list + ship verdict, written as data that the Ship Sign-off gate reads. Handles the normal stop and both circuit-breaker triggers. |
174
+ | Retro (after Ship Sign-off) | `building` | The `retro` sub-command — RLHF for the harness: turns raw PO/TL feedback at Ship Sign-off into per-reader guidelines under committed `shapeup/knowledge-base/<reader>.md` (readers: `task-executor`, `orient`, `qa-edge-hunter`, the `plan` activity, and the loop itself at the Intake & Config gate — workflow guidance, never a gate answer). `--scan` seeds the same files from the project on disk before the first run; `--research <stack>` seeds them from the platform's official documentation when the project has nothing to scan, and cross-checks a scan's rules when it has. The Retro Ownership gate asks the PO which reader owns each rule — never assumes; mechanism defects are filed to the harness-defect register instead. |
191
175
 
192
176
  ### Commands
193
177
 
@@ -198,15 +182,15 @@ learnable from `/`-completion alone. Names are written short here; the real name
198
182
  | Command | Phase | Description |
199
183
  |---------|-------|-------------|
200
184
  | `/ship` | all | Run the full harness on a pitch (interactive gates by default; `--auto`, `--unattended`). |
201
- | `/shape` | 1 | Shape a raw idea into a pitch: boundaries → breadboard → spike → `pitch.md`. |
202
- | `/orient` | 7 | Builder-led recon; spikes the riskiest area, writes no production code. |
203
- | `/wire` | L1a.5 | Write the wiring map — engine → seam → entry-point call site, per use case. |
204
- | `/scopes` | 8 | Spec tree + board (`ba-pitch-analyzer`), then scope contracts (`scope-architect`). |
205
- | `/build` | 9 | Implement one task's acceptance criteria exactly. |
206
- | `/eval` | L3 | The single judge. Round mode is hook-gated — see the demo above. |
185
+ | `/shape` | Shaping | Shape a raw idea into a pitch: boundaries → breadboard → spike → `pitch.md`. |
186
+ | `/orient` | Orient | Builder-led recon; spikes the riskiest area, writes no production code. |
187
+ | `/wire` | Wiring Review | Alias of `/ship plan`, through the wiring map — engine → seam → entry-point call site, per use case. |
188
+ | `/scopes` | Board Review | Alias of `/ship plan`: spec tree + board, then scope contracts. |
189
+ | `/build` | Build | Implement one task's acceptance criteria exactly. |
190
+ | `/eval` | Verdict | The single judge. Round mode crosses the Round Close gate first. |
207
191
  | `/qa` | post-PASS | Exploratory edge hunt; findings never block ship. |
208
- | `/hammer` | H | Must-have census, baseline comparison, cut list + ship verdict. |
209
- | `/retro` | post-L4 | File ship-gate feedback into the per-skill knowledge base. |
192
+ | `/hammer` | Cut-List Review | Must-have census, baseline comparison, cut list + ship verdict. |
193
+ | `/retro` | after Ship Sign-off | File ship-gate feedback into the per-reader knowledge base; `--scan` and `--research <stack>` seed it. |
210
194
 
211
195
  ### What is enforced, and by what
212
196
 
@@ -216,34 +200,29 @@ the layer that carries it, and the three layers here fail differently:
216
200
  | Layer | Works when | Fails how |
217
201
  |---|---|---|
218
202
  | **Wall** — a hook | Under every permission mode, including `bypassPermissions`. The CLI runs it; the model cannot decline it. | Fail-OPEN on anything ambiguous, and every evaluation writes a decision row, so "permitted" never looks like "never ran". |
219
- | **Runtime** — the kernel and the run script | When the run goes through the harness. A schema rejection or a non-zero exit stops the step. | A lane that never calls the kernel is never checked — which is why the hooks below cover the doors, not the steps. |
203
+ | **Runtime** — the kernel | When the run goes through the harness. A schema rejection or a non-zero exit stops the step. | A lane that never calls the kernel is never checked — which is why the hooks below cover the doors, not the steps. |
220
204
  | **Advisory** — a report section | When somebody reads the artifact. | Silently, if nobody does. It is a cleanup list, never a verdict. |
221
205
 
222
- **Five walls.** These are hooks because nothing in the runtime can substitute for them:
206
+ **Four walls.** These are hooks because nothing in the runtime can substitute for them:
223
207
 
224
- - `PreToolUse` (`Skill`) — **`hooks/gate-intake.mjs` denies a `tech-lead` dispatch that carries no
225
- pitch, no spec folder, and no requirement text.** Observed, not theorized: when the requirement
226
- text is dropped on the hand-off and only a flag survives, the run prints the gate list, builds
227
- nothing, and reads like a success while leaving every defect in the deliverable.
228
208
  - `PreToolUse` (`Skill|Agent`) — **`harness verify envelope` denies any worker dispatch whose order
229
209
  file is missing or fails the WorkOrder schema.** A malformed envelope never reaches a worker.
230
210
  - `PreToolUse` (`Edit|Write|MultiEdit`) — **`hooks/sandbox-guard.mjs` blocks a write that no LIVE
231
- order's substrate permits.** It reads every order that is compiled and not yet answered — a result
232
- at least as new as the order itself — rather than a pointer to one, so scopes building
233
- concurrently are each held to their own contract and a finished run fences nothing. A phase
234
- dispatch the run has already moved past stops fencing too: once a later phase compiles its order,
235
- an evaluation or a QA leg that never returned a result no longer holds the board. `frozen` is
236
- checked first and outranks everything, across every live contract — including the carve-out that
237
- otherwise keeps the active feature's own run trace writable, so a path a live order froze stays
238
- frozen wherever it lives. An order's own result answers to the sub-agent that took its
239
- dispatch, so with two legs live neither can write the other's.
240
- - `PreToolUse` (`Edit|Write|MultiEdit`) — **`hooks/tier-guard.mjs` refuses a committed-tier write
241
- whose content names a path into the local run trace or a board id.** Same rule spec-lint reds at
242
- GATE L1b, asked at the moment of writing: four different producers wrote a committed file their
243
- own lint then rejected, and one of them did it twice in one session, an hour apart, after fixing
244
- the first occurrence itself. A worker carries no lesson across a dispatch, so the remedy is a
245
- refusal the writer can act on while it still knows what it meant to say. The knowledge base is
246
- outside it — those files are instructions, not references a reader has to resolve.
211
+ order's substrate permits.** It reads every order that is written and not yet answered rather than
212
+ a pointer to one, so scopes building concurrently are each held to their own contract and a finished
213
+ run fences nothing. `frozen` is checked first and outranks everything, across every live contract,
214
+ and an order's own result answers to the sub-agent that took its dispatch, so with two legs live
215
+ neither can write the other's. The fence is armed by a pointer the loop sets with `harness order open`
216
+ and retires with `harness order close`; with no pointer it allows every write, which is why those are
217
+ commands that read the pointer back rather than a file the loop edits. The close that records a
218
+ `shipped` ending refuses unless a Ship Sign-off row of the same run says `ship`, so the gate's
219
+ refusals cannot be walked around by ending the run.
220
+ - `PreToolUse` (`Edit|Write|MultiEdit`) — **the same hook also refuses a committed-tier write whose
221
+ content names a path into the local run trace or a board id.** Four different producers wrote a
222
+ committed file that a later check rejected, and one did it twice in a session, because a worker carries
223
+ no lesson across a dispatch; the remedy is a refusal the writer can act on while it still knows what
224
+ it meant to say. The knowledge base is outside it — those files are instructions, not references a
225
+ reader has to resolve.
247
226
  - `PreToolUse` (`Bash|Read|Write|Edit|MultiEdit`) — **`hooks/safety-spine.mjs` denies destructive
248
227
  commands** (`rm -rf` on unrecoverable targets, force-push/push-to-main, `git reset --hard`,
249
228
  `DROP TABLE`) and secret-file reads. A machine guard, not a pipeline guard; the escape hatch is
@@ -251,38 +230,27 @@ the layer that carries it, and the three layers here fail differently:
251
230
 
252
231
  **One recorder**, which denies nothing and is what makes a wall possible one layer down:
253
232
 
254
- - `PostToolUse` (`Skill|Agent`) — **`hooks/dispatch-receipt.mjs` writes down which skill actually
233
+ - `PostToolUse` (`Skill|Agent`) — **`hooks/dispatch-receipt.mjs` writes down which agent actually
255
234
  ran.** Until it existed, a dispatch that failed — plugin absent, disabled, or a different version
256
- loaded — was indistinguishable from one that succeeded: the sub-agent would do the craft itself
257
- from the prose in its own prompt, the artifacts landed in exactly the place the order permitted, so
258
- the order gate and the sandbox guard both passed and the run advanced having applied none of the
259
- shipped craft. A green run was consistent with zero worker craft. The hook appends
260
- `{order_id, worker_declared, skill_invoked, dispatch_ok, at}` to `.shapeup/<slug>/receipts/`, and
261
- `harness reduce ingest` refuses an orchestrated result with no matching receipt. A failed dispatch
262
- never reaches `PostToolUse` at all, so the receipt's *existence* is the evidence. It has no deny
263
- path, every write is guarded, and `--no-receipt-check` is the documented way through when the
264
- channel itself fails.
265
-
266
- **One blocking Stop hook**, and it is the narrowest thing in the repo:
267
-
268
- - `Stop` — **`hooks/gate-zerowork.mjs` blocks a session that dispatched the orchestrator and left
269
- no run receipt.** Its predicate is mechanical — orchestrator dispatched AND no
270
- `.shapeup/<slug>/receipt.json` — so it never judges quality; it reports that no work exists to
271
- judge. It exists because this harness was repeatedly observed describing its own pipeline instead
272
- of running it: a narrated run that reads like a clean success. Fails open on everything
273
- ambiguous, and `stop_hook_active` caps it at one block per stop chain.
274
-
275
- **What the runtime carries instead** (v2.0 retired six hooks whose work moved here):
276
-
277
- | Was a hook | Is now | What changed |
278
- |---|---|---|
279
- | `gate-l2` (EVAL over an unfinished board) | The GATE L2 block, which names `green_scopes` and `hammer_proposals` | It was advisory either way; now the same facts reach the human who answers the gate rather than a warning line above it. |
280
- | `gate-deadline` (deny builds past the wall clock) | `harness verify budget --strict`, checked at every round boundary | **A real coverage change, stated rather than hidden:** the round loop stops the run from opening ANOTHER round, but no longer interrupts a single build leg that runs long. `attempt_budget` bounds that leg by attempts instead. |
281
- | `session-rehydrate` + `compact-snapshot` | `harness reduce graph --slug <slug> --subgraph run` | A hook fired at two moments the platform chose; a command answers whenever the question is asked, including the moments a hook never saw. |
282
- | `anti-rationalization` (claims the facts contradict) | The ship report's census, derived from the board and the T0 artifacts | The facts are in an artifact a teammate finds on `git pull`, not in a transcript nobody re-reads. |
283
- | `slop-cleaner` (TODO/`console.log` leftovers) | The ship report's **Leftovers** section | Same scan, same added-lines-only rule; it lands somewhere checkable. |
284
-
285
- **Nothing load-bearing depends on permission mode.** The five walls plus the zero-work gate run
235
+ loaded — was indistinguishable from one that succeeded: the sub-agent would do the craft itself from
236
+ the prose in its own prompt, the artifacts landed where the order permitted, so the order gate and the
237
+ fence both passed and the run advanced having applied none of the shipped craft. The hook appends
238
+ `{order_id, worker_declared, skill_invoked, dispatch_ok, usage, model_requested, at}` to `.shapeup/<slug>/receipts/`,
239
+ with the tokens, duration and model the host measured beside the model the call asked for (the
240
+ agents inherit the session's model unless the dispatch names one, and Ship Sign-off reads what ran
241
+ against the launch record). A failed dispatch never reaches `PostToolUse`
242
+ at all, so the receipt's *existence* is the evidence. The loop counts an attempt against a receipt, not
243
+ against the artifact. It has no deny path and every write is guarded.
244
+
245
+ **What the runtime no longer carries.** Earlier versions also checked, with scripts, that a spec was
246
+ well-linked at the board review, that a worker's result was applied exactly once, that a run's attempts
247
+ and rounds were counted from attested records, that the build and launch probes were green before
248
+ evaluation, and that a ship report matched the board. Those are now the loop's own discipline, written
249
+ in the `building` skill and checked by the PO and the evaluator. A measured comparison found the scripted
250
+ sequencing completed more runs than the same loop reading its own table, at lower cost; the scripted
251
+ engine was removed on the PO's decision anyway, and the record of that decision names the result.
252
+
253
+ **Nothing load-bearing depends on permission mode.** The walls run
286
254
  under every mode. The kernel needs a grant to be *invoked* — two Bash lines `npx shapeup-sdlc init`
287
255
  writes — but a session that never gets that grant is a session that cannot run the pipeline at all,
288
256
  not one that runs it unguarded.
@@ -304,30 +272,19 @@ These hold across the harness and are the reason it stays predictable:
304
272
  - **Ledger is the single source of truth** — orient, task-executor, and QA all write to `discovery/ledger.md`.
305
273
  - **QA is a level-up, not a gate** — `--no-qa` skips it; the circuit breaker outranks the hunter; findings default to `~`.
306
274
  - **Role separation** — evaluator grades, task-executor fixes, QA discovers; no one does another's job.
307
- - **Three-level circuit breaker** — an outer `round_budget` (build+eval cycles) nests an inner
308
- per-scope `attempt_budget` (T0 attempts); an exhausted scope queues a GATE H proposal instead
309
- of blocking the round. An opt-in third breaker bounds the **wall clock**, because the other two
310
- count events and neither can notice a single round running for half an hour — tripping it routes
311
- to GATE H, so a run out of time ships what is green instead of being killed and shipping nothing.
312
- - **Hill phase is mechanical, never self-reported** — derived only from T0/T1 facts, closing the
313
- self-reported-confidence risk. A scope with no
314
- discovery ledger derives no phase rather than a solved one, so absence no longer reads as
315
- progress on that arm.
316
- - **One writer per shared file** — every board/ledger/verdict write goes through
317
- `harness reduce ingest`; workers return data and never touch shared state.
318
- - **Traceability is oracle-checked, opt-in** — `harness verify trace` verifies covers-closure and
319
- wiring reachability from the committed spine artifacts; it ships advisory (warn-only) and every
320
- arm is skipped when its artifact is absent, so older specs are non-regressed. Reachability also
321
- skips when it cannot root its walk — an import it cannot follow, or no reachable engine to
322
- control the result — because "every engine is orphaned" and "this is the wrong entry point" are
323
- the same evidence, and a check that cannot tell them apart must say so rather than pick.
275
+ - **Two circuit breakers** — an outer `round_budget` (build+eval cycles) nests an inner per-scope
276
+ `attempt_budget` (T0 attempts); an exhausted scope queues a Cut-List Review proposal instead of
277
+ blocking the round, and running out of rounds routes to the Cut-List Review too, so a run out of budget ships what is
278
+ green instead of being killed and shipping nothing.
279
+ - **The witness is mechanical** — a T0 verdict is a command's exit code and a hash, not a report; the
280
+ evaluator re-hashes the artifact it cites.
281
+ - **One writer per shared file** — the loop applies every board and ledger change; workers return data
282
+ and never touch shared state.
324
283
 
325
284
  ## Known rough edges
326
285
 
327
286
  Stated plainly, because you will hit them:
328
287
 
329
- - **The `--tiny` lane is young.** It right-sizes the ceremony (two gates instead of eight) but
330
- keeps the T0 verification floor; its fit-check heuristics will need tuning against real use.
331
288
  - **Nothing here measures skill quality or activation.** There is no number for whether a
332
289
  skill's description makes it fire on the right request, no measured craft delta, and no CI
333
290
  check enforcing the honesty invariant on such numbers. The structural suite is the coverage
@@ -353,27 +310,28 @@ claude --plugin-dir . # load this working copy without installing
353
310
  .claude-plugin/
354
311
  plugin.json # plugin manifest
355
312
  marketplace.json # marketplace listing (points at this repo)
356
- skills/<name>/SKILL.md # the 13 harness skills (+ references/ and assets/)
357
- skills/tech-lead/workflows/shapeup-run.js # the BUILD-phase pipeline, on the native Workflow runtime
313
+ skills/<name>/SKILL.md # the 6 harness skills (+ references/, resources/ and assets/)
314
+ agents/<worker>.md # the 4 workers as plugin subagents: each preloads its skill; a dispatch names the agent
358
315
  kernel/harness.mjs # ONE entry point for every deterministic step; the whole permission grant
359
- kernel/{verify,reduce,probe,init,report}/ # its subcommands, plus compile and gate at the root
316
+ kernel/{verify,init}/ # its subcommands: the T0 witness, the envelope check, the roster check, init run
317
+ kernel/{gate,order}.mjs # the gate resolver, and the verb that arms and retires the fence
360
318
  kernel/lib/ # argv (the typed CLI boundary), paths (+ the run key), contract (shape)
361
319
  kernel/schemas/ # the envelope port: WorkOrder, WorkResult, domain registry
362
320
  commands/*.md # slash commands (/ship + the 9 phase commands)
363
- hooks/ # hooks.json + the five walls: safety-spine, gate-intake, sandbox-guard,
364
- # tier-guard (PreToolUse) + gate-zerowork (Stop, the one blocking hook)
365
- # + dispatch-receipt (PostToolUse, denies nothing, attests which skill ran)
321
+ hooks/ # hooks.json + the three walls: safety-spine, sandbox-guard (the substrate fence and the
322
+ # committed-tier write check) — PreToolUse, beside the kernel's `verify envelope`
323
+ # + dispatch-receipt (PostToolUse, denies nothing, attests which worker ran and what the host measured)
366
324
  # + lib/decision.mjs (every hook records allow / deny / error)
367
325
  oracles/ # the evaluation-contract oracle registry (test · snapshot · http · process)
368
- bin/init.mjs # `npx shapeup-sdlc init` — scaffolds all three CLI targets
326
+ bin/init.mjs # `npx shapeup-sdlc init` — the permission grant, the AGENTS.md harness block, the ignore rules
369
327
  scripts/install-harness.sh, migrate.sh # stable public entrypoints (fresh install / update)
370
328
  scripts/shapeup-sdlc/lib/ # shell libs both entrypoints source
371
329
  tools/ # repo-only: demo/
372
330
  # demo/record-demo.mjs (regenerates docs/assets/demo-gate.svg)
373
- tests/structural.mjs, tests/structural/*.mjs # Tier 0 — 880+ checks, zero LLM calls
331
+ tests/structural.mjs, tests/structural/*.mjs # Tier 0 — ten modules, zero LLM calls
374
332
  docs/install.md, upgrading.md, glossary.md
375
- docs/design/ # the design document (pipeline, gates, circuit breaker, ERD) + adr/
376
- docs/visualize/ # rendered views of the tree and the pipeline
333
+ docs/design/ # the design document (pipeline, gates, circuit breaker, ERD)
334
+ docs/visualize/ # the before-and-after view of the v4 loop
377
335
  .github/workflows/ # CI + release (release publishes to npm via OIDC)
378
336
  ```
379
337
 
package/SECURITY.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Security
2
2
 
3
- This plugin installs **eight hook entries (seven Node scripts + one `echo`)**: five in a
4
- `PreToolUse` position, **all five of which can deny a tool call**, one `PostToolUse` hook that has no
5
- deny path at all, and one `Stop`-position hook that can block a session from ending. That is the
3
+ This plugin installs **four hook entries (three Node scripts + the kernel's `verify envelope`)**: three in a
4
+ `PreToolUse` position, **all three of which can deny a tool call**, and one `PostToolUse` hook that has no
5
+ deny path at all. No hook can block a session from ending. That is the
6
6
  product — and it is also exactly the kind of surface a careful reviewer should want spelled out
7
7
  before installing. This page is that spelling-out.
8
8
 
@@ -13,14 +13,14 @@ it to four walls and updated the table below without updating the sentence above
13
13
  ```bash
14
14
  node -e "const h=require('./hooks/hooks.json').hooks;
15
15
  for (const [e,gs] of Object.entries(h)) for (const g of gs) for (const x of g.hooks)
16
- console.log(e, g.matcher||'*', x.command.match(/[^/ ]+\.mjs/)?.[0] ?? '(echo)')"
16
+ console.log(e, g.matcher||'*', x.command.match(/[^/ ]+\.mjs/)?.[0])"
17
17
  ```
18
18
 
19
19
  ## Reporting a vulnerability
20
20
 
21
21
  Use [GitHub private vulnerability reporting](https://github.com/nguyenvanphituoc/shapeup-sdlc-plugin/security/advisories/new)
22
22
  for anything exploitable — especially anything that would let a run **escape a deny** (write
23
- outside a substrate, dispatch on an uncompiled order, widen its own safety overrides) or
23
+ outside a substrate, dispatch without a schema-valid order, widen its own safety overrides) or
24
24
  exfiltrate data.
25
25
  For non-sensitive hardening ideas, an ordinary issue is fine.
26
26
 
@@ -38,23 +38,20 @@ test against machines you don't own.
38
38
  3. **Every hook is fail-open by design.** Unparseable input, missing state files, or an
39
39
  unrecognized invocation shape → the hook defers and the normal permission flow proceeds. A
40
40
  hook denies only when it can positively prove its condition (a matched destructive command, a
41
- path no live order's substrate permits, an invalid order file, an empty intake).
41
+ path no live order's substrate permits, an invalid order file).
42
42
  4. **The model cannot widen its own safety envelope.** The escape hatch
43
43
  (`.shapeup/safety-overrides.json`) is human-authored; `safety-spine` itself denies any
44
44
  write/move/delete touching that file, a malformed overrides file is treated as absent
45
45
  (override channel fails closed), and every exercised override is logged. The same principle
46
46
  covers `.shapeup/active-order`, which `sandbox-guard` reads to find the run whose orders fence
47
47
  a worker's writes: it sits outside the run-trace carve-out, so a worker cannot repoint its own
48
- sandbox. The `last-run` breadcrumb a terminal close leaves beside it is read for one purpose — keying a decision row to the run that just ended, marked `run_closed` — and arms nothing: liveness is derived from the order set and the pointer, never from that file. Every hook resolves that pointer, the decision ledger and the substrate globs against
48
+ sandbox. The `close.json` a terminal close writes beside the run's records names the ending and arms nothing: liveness is derived from the order set and the pointer, never from that file, and the close retires the pointer. Every hook resolves that pointer, the decision ledger and the substrate globs against
49
49
  the project root it finds above the tool call's working directory (a run pointer, the committed
50
50
  tier, or a git boundary) — a worker that `cd`s into a sub-folder is fenced exactly as one at the
51
51
  top, and its receipts land in the same ledger.
52
- 5. **Exactly one hook can block, and only on a mechanical absence.** `gate-zerowork` returns
53
- `decision: "block"` in one state: the session dispatched the orchestrator and left no run
54
- receipt on disk. It makes no judgement about quality — it reports that there is no work to
55
- judge. `stop_hook_active` caps it at one block per stop chain. Every other check that used to
56
- emit an advisory `systemMessage` at `Stop` now lands in the ship report instead, where it is a
57
- section a person can read afterwards rather than a line in a transcript.
52
+ 5. **No hook can block a session from ending.** A session that narrates a run instead of opening one
53
+ is not stopped by the runtime; `building` opens its run as its first act and the receipt it writes is
54
+ what every later guard reads.
58
55
  6. **Every hook decision is recorded.** `hooks/lib/decision.mjs` is the only exit path a hook
59
56
  has, so allow, deny, block and error each leave a row in `.shapeup/decisions.jsonl`. An
60
57
  inert hook and a permitting hook are therefore distinguishable — which matters, because
@@ -73,14 +70,9 @@ sitting, and reading them is the recommended review.
73
70
  | Hook | Event (matcher) | Reads | Can deny | Never does |
74
71
  |---|---|---|---|---|
75
72
  | [`safety-spine.mjs`](hooks/safety-spine.mjs) | PreToolUse (`Bash\|Read\|Write\|Edit\|MultiEdit`) | The proposed command/path; `.shapeup/safety-overrides.json` | Yes — provably destructive ops only: `rm -rf` on unrecoverable targets, `git push --force` / push to main, `git reset --hard`, `git clean -fdx`, `DROP TABLE`/`TRUNCATE`, reads of `.env`/keys/cloud credentials, and any write to its own overrides file | Never blocks an unmatched command; `--force-with-lease` stays allowed |
76
- | [`gate-intake.mjs`](hooks/gate-intake.mjs) | PreToolUse (`Skill`) | The `tech-lead` dispatch's own arguments | Yes — an orchestrator dispatch carrying no resolvable intake (no pitch, spec, resume or requirement text) | Fails open on `--order` and on any ambiguous arg shape |
77
73
  | [`harness verify envelope`](kernel/verify/envelope.mjs) | PreToolUse (`Skill\|Agent`) | The `--order` file named in the dispatch; the JSON schemas | Yes — a worker dispatch whose order file is missing or schema-invalid | Never gates a dispatch that carries no `--order` (standalone skill use stays free) |
78
- | [`sandbox-guard.mjs`](hooks/sandbox-guard.mjs) | PreToolUse (`Edit\|Write\|MultiEdit`) | The target path, resolved through the filesystem before it is compared — symlinks followed, the unborn tail re-attached to its real ancestor, case folded where the filesystem folds case — so a spelling variant of a frozen file is the frozen file; the `substrate` block of every LIVE order — compiled, with no result at least as new as the order's own `compiled_at`, and, for a run-level phase dispatch, not yet superseded by a later phase's order | Yes — any write no live order permits: inside any `frozen`, outside every `allowed`/`shared`, or a `Write` to an `append_only` path. `frozen` is checked FIRST, so it also outranks the run-trace carve-out. An order's own paths (its result first) are writable only by the sub-agent its dispatch receipt names, so one live leg cannot write another's result; a write with no sub-agent id, or an order with no receipt, keeps the path-only rule | No-op unless an order is live, which a finished run no longer is: the pointer names the run, never a dispatch. The active feature's own `.shapeup/<slug>/` run trace is writable EXCEPT where a live order freezes a path inside it. Appends denials to the local pathology log |
79
- | [`tier-guard.mjs`](hooks/tier-guard.mjs) | PreToolUse (`Edit\|Write\|MultiEdit`) | The target path; the text the call is about to write (`content`, `new_string`, or any edit in a `MultiEdit` batch) | Yes — a write into `shapeup/<slug>/` whose content names a `.shapeup/` path or a `TASK-NNN` board id: the same tier-direction rule spec-lint reds at GATE L1b, refused at the moment of writing, with the offending token quoted back | No-op outside `shapeup/<slug>/`, on file forms the lint does not scan, and on `shapeup/knowledge-base/` (instructions to a worker, not references). Reads nothing off disk and writes only its decision row; it never inspects a file it is not being asked to write |
80
- | [`dispatch-receipt.mjs`](hooks/dispatch-receipt.mjs) | PostToolUse (`Skill\|Agent`) | The `--order` file named in the dispatch; the tool result's own report of which skill ran | **No — it has no deny path at all.** It records that the shipped skill ran, so `harness reduce ingest` can refuse a result no dispatch produced | Never writes an attestation for a result that does not name a resolved skill; never fails the call it observes (every write is inside `try`/`catch`) |
81
- | [`gate-zerowork.mjs`](hooks/gate-zerowork.mjs) | Stop | Run receipts on disk; the session transcript; the decision ledger | **Yes — the one blocking hook.** Returns `decision:"block"` when the session dispatched the orchestrator and produced no run receipt | Defers the moment any receipt exists; `stop_hook_active` caps it at one block per stop chain |
82
-
83
- (The remaining `hooks.json` entry is a plain `echo` on SessionStart confirming the plugin loaded.)
74
+ | [`sandbox-guard.mjs`](hooks/sandbox-guard.mjs) | PreToolUse (`Edit\|Write\|MultiEdit`) | The target path, resolved through the filesystem before it is compared — symlinks followed, the unborn tail re-attached to its real ancestor, case folded where the filesystem folds case — so a spelling variant of a frozen file is the frozen file; the `substrate` block of every LIVE order — written, with no result at least as new as the order's own `compiled_at`, and, for a run-level phase dispatch, not yet superseded by a later phase's order | Yes — any write no live order permits: inside any `frozen`, outside every `allowed`/`shared`, or a `Write` to an `append_only` path. `frozen` is checked FIRST, so it also outranks the run-trace carve-out. An order's own paths (its result first) are writable only by the sub-agent its dispatch receipt names, so one live leg cannot write another's result; a write with no sub-agent id, or an order with no receipt, keeps the path-only rule. Independently of any order, a write into `shapeup/<slug>/` whose content names a `.shapeup/` path or a `TASK-NNN` board id: the tier-direction rule, refused at the moment of writing with the offending token quoted back | The substrate fence is a no-op unless an order is live, which a finished run no longer is: the pointer names the run, never a dispatch. The active feature's own `.shapeup/<slug>/` run trace is writable EXCEPT where a live order freezes a path inside it. Appends denials to the local pathology log. The tier check is a no-op outside `shapeup/<slug>/`, on file forms the lint does not scan, and on `shapeup/knowledge-base/` (instructions to a worker, not references); it never inspects a file it is not being asked to write |
75
+ | [`dispatch-receipt.mjs`](hooks/dispatch-receipt.mjs) | PostToolUse (`Skill\|Agent`) | The `--order` file named in the dispatch; the tool result's own report of which skill ran | **No — it has no deny path at all.** It records that the shipped skill ran, so the loop counts an attempt only against a dispatch that produced it | Never writes an attestation for a result that does not name a resolved skill; never fails the call it observes (every write is inside `try`/`catch`) |
84
76
 
85
77
  ## Data handling
86
78
 
@@ -90,11 +82,10 @@ sitting, and reading them is the recommended review.
90
82
  any kind.
91
83
  - **The safety-spine actively blocks secret reads** (`.env`, `*.pem`, `*.key`, ssh/cloud
92
84
  credentials) rather than merely not making them.
93
- - **The script the run executes is a copy, and the copy is the shipped file.** Opening a run
94
- copies the plugin's own workflow scripts into the gitignored `.shapeup/workflows/`, because the
95
- Workflow tool loads a script only from a directory the session may already read and the plugin
96
- installs outside your project. They are copied byte for byte — never generated, templated or
97
- rewritten — so what you review in the plugin is what runs, and nothing else is added to your tree.
85
+ - **Nothing is copied into your project to run.** The run is driven by the loop in your session
86
+ through two kernel Bash rules, so there is no script staged into your tree, no launch to authorise,
87
+ and no unscoped `Workflow` permission to grant: the installer writes the two rules and nothing else,
88
+ and a `Workflow` token you already have is yours and is left alone.
98
89
  - The installer (`scripts/install-harness.sh`) writes only into the target project
99
90
  (`.claude/`, `shapeup/`, `.gitignore`) and tells you what it
100
91
  is going to do first; the `curl | bash` form requires an explicit `--yes` for exactly that
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: orient
3
+ description: The Scout. Dispatched by the run loop with a WorkOrder path to map the code surface a pitch touches and to run its spikes before any board exists. Never invoke by hand; use /ship.
4
+ tools: Read, Write, Edit, Bash, Grep, Glob
5
+ model: inherit
6
+ skills:
7
+ - orient
8
+ ---
9
+
10
+ You are the `orient` worker of a Shape Up run. Your craft is the `orient` skill, which is already loaded
11
+ into this context. Your whole brief is the WorkOrder path and the note you were dispatched with: follow the
12
+ skill against that order, write the artifacts the order names, write your WorkResult where the order says,
13
+ and return one line. You were told nothing about the run's history or the other workers, and you should not
14
+ go looking for it.
@@ -0,0 +1,13 @@
1
+ ---
2
+ name: qa-edge-hunter
3
+ description: The edge hunter. Dispatched by the run loop after the first PASS with a WorkOrder path to explore the running app for what the evaluator did not probe. Never invoke by hand; use /ship.
4
+ tools: Read, Write, Edit, Bash, Grep, Glob
5
+ model: inherit
6
+ skills:
7
+ - qa-edge-hunter
8
+ ---
9
+
10
+ You are the `qa-edge-hunter` worker of a Shape Up run. Your craft is the `qa-edge-hunter` skill, which is
11
+ already loaded into this context. Your whole brief is the WorkOrder path and the note you were dispatched
12
+ with: follow the skill against that order, log what you find with a repro and no verdict, write your
13
+ WorkResult where the order says, and return one line. You discover; you never block and never score.
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: spec-evaluator
3
+ description: The single judge. Dispatched by the run loop with a WorkOrder path to grade a round against the spec and the Test Surface. Never invoke by hand; use /ship.
4
+ tools: Read, Write, Edit, Bash, Grep, Glob
5
+ model: inherit
6
+ skills:
7
+ - spec-evaluator
8
+ ---
9
+
10
+ You are the `spec-evaluator` worker of a Shape Up run. Your craft is the `spec-evaluator` skill, which is
11
+ already loaded into this context. Your whole brief is the WorkOrder path and the note you were dispatched
12
+ with: follow the skill against that order, cite the T0 artifacts the order lists by re-hashing them
13
+ yourself, write your WorkResult where the order says, and return one line. You did not build what you
14
+ grade, and you should not fix it.
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: task-executor
3
+ description: The builder. Dispatched by the run loop with a WorkOrder path to implement one scope's acceptance criteria inside its write substrate. Never invoke by hand; use /ship.
4
+ tools: Read, Write, Edit, Bash, Grep, Glob
5
+ model: inherit
6
+ skills:
7
+ - task-executor
8
+ ---
9
+
10
+ You are the `task-executor` worker of a Shape Up run. Your craft is the `task-executor` skill, which is
11
+ already loaded into this context. Your whole brief is the WorkOrder path and the note you were dispatched
12
+ with: follow the skill against that order, write only inside the substrate the order declares, write your
13
+ WorkResult where the order says, and return one line. You were told nothing about the run's history or the
14
+ other scopes, and you should not go looking for it.