shapeup-sdlc 1.6.2 → 1.7.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 (85) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/AGENTS.md +36 -103
  3. package/README.md +60 -67
  4. package/SECURITY.md +31 -16
  5. package/bin/init.mjs +24 -69
  6. package/commands/build.md +19 -0
  7. package/commands/eval.md +5 -4
  8. package/commands/scopes.md +5 -4
  9. package/commands/shape.md +1 -1
  10. package/commands/ship.md +37 -4
  11. package/hooks/anti-rationalization.mjs +7 -13
  12. package/hooks/compact-snapshot.mjs +5 -5
  13. package/hooks/gate-deadline.mjs +12 -16
  14. package/hooks/gate-intake.mjs +13 -14
  15. package/hooks/gate-l2.mjs +3 -3
  16. package/hooks/gate-zerowork.mjs +97 -16
  17. package/hooks/lib/decision.mjs +21 -13
  18. package/hooks/safety-spine.mjs +1 -1
  19. package/hooks/sandbox-guard.mjs +83 -47
  20. package/hooks/session-rehydrate.mjs +8 -9
  21. package/hooks/slop-cleaner.mjs +1 -1
  22. package/oracles/_shared.mjs +1 -1
  23. package/oracles/http-oracle.mjs +1 -1
  24. package/oracles/index.mjs +1 -1
  25. package/oracles/process-oracle.mjs +1 -1
  26. package/oracles/snapshot-oracle.mjs +1 -1
  27. package/oracles/test-oracle.mjs +1 -1
  28. package/package.json +3 -7
  29. package/skills/ba-pitch-analyzer/SKILL.md +20 -15
  30. package/skills/ba-pitch-analyzer/references/doc-schemas.md +1 -1
  31. package/skills/ba-pitch-analyzer/references/task-generation.md +6 -6
  32. package/skills/ba-pitch-analyzer/references/test-surface.md +1 -1
  33. package/skills/ba-pitch-analyzer/scripts/board-derive.mjs +5 -5
  34. package/skills/ba-pitch-analyzer/scripts/spec-lint.mjs +2 -2
  35. package/skills/coach/SKILL.md +3 -3
  36. package/skills/orient/SKILL.md +2 -1
  37. package/skills/qa-edge-hunter/SKILL.md +9 -39
  38. package/skills/scope-architect/SKILL.md +17 -12
  39. package/skills/scope-hammer/SKILL.md +5 -5
  40. package/skills/shapeup/SKILL.md +3 -3
  41. package/skills/shapeup/resources/context-compaction.md +4 -3
  42. package/skills/solution-architect/SKILL.md +18 -11
  43. package/skills/spec-evaluator/SKILL.md +12 -5
  44. package/skills/spec-evaluator/references/dimensions/_registry.md +2 -2
  45. package/skills/spec-evaluator/references/dimensions/completeness.md +1 -1
  46. package/skills/spec-evaluator/references/dimensions/integration.md +98 -67
  47. package/skills/spec-evaluator/references/dimensions/spec-conformance.md +4 -4
  48. package/skills/spec-evaluator/references/dimensions/test-surface-conformance.md +1 -1
  49. package/skills/spec-evaluator/references/probing.md +42 -23
  50. package/skills/spec-evaluator/references/report-schema.md +2 -2
  51. package/skills/spec-evaluator/scripts/verdict-ledger.mjs +1 -1
  52. package/skills/task-executor/SKILL.md +25 -12
  53. package/skills/tech-lead/SKILL.md +115 -438
  54. package/skills/tech-lead/references/delegation.md +38 -31
  55. package/skills/tech-lead/references/gates.md +75 -33
  56. package/skills/tech-lead/references/hard-rules.md +34 -0
  57. package/skills/tech-lead/references/invocation.md +2 -2
  58. package/skills/tech-lead/references/ledger-schema.md +17 -18
  59. package/skills/tech-lead/references/round-protocol.md +77 -27
  60. package/skills/tech-lead/references/state-model.md +1 -1
  61. package/skills/tech-lead/schemas/domain.schema.json +320 -148
  62. package/skills/tech-lead/schemas/gate-answers.schema.json +2 -2
  63. package/skills/tech-lead/schemas/work-result.schema.json +55 -17
  64. package/skills/tech-lead/scripts/aegis-digest.mjs +1 -1
  65. package/skills/tech-lead/scripts/budget-check.mjs +7 -13
  66. package/skills/tech-lead/scripts/compile-order.mjs +69 -22
  67. package/skills/tech-lead/scripts/fit-check.mjs +10 -10
  68. package/skills/tech-lead/scripts/gate-answers.mjs +11 -12
  69. package/skills/tech-lead/scripts/hill-derive.mjs +133 -0
  70. package/skills/tech-lead/scripts/ingest-result.mjs +7 -19
  71. package/skills/tech-lead/scripts/init-run.mjs +60 -18
  72. package/skills/tech-lead/scripts/lib/argv.mjs +1 -1
  73. package/skills/tech-lead/scripts/lib/contract-md.mjs +10 -10
  74. package/skills/tech-lead/scripts/lib/is-main.mjs +11 -12
  75. package/skills/tech-lead/scripts/lib/paths.mjs +15 -13
  76. package/skills/tech-lead/scripts/resume-state.mjs +387 -0
  77. package/skills/tech-lead/scripts/run-snapshot.mjs +1 -6
  78. package/skills/tech-lead/scripts/run-workflow.mjs +381 -0
  79. package/skills/tech-lead/scripts/ship-report.mjs +33 -2
  80. package/skills/tech-lead/scripts/stats.mjs +9 -10
  81. package/skills/tech-lead/scripts/t0-verify.mjs +4 -4
  82. package/skills/tech-lead/scripts/trace-lint.mjs +2 -2
  83. package/skills/tech-lead/workflows/shapeup-run.js +911 -0
  84. package/skills/translator/SKILL.md +2 -2
  85. package/skills/advisor-protocol/SKILL.md +0 -171
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shapeup-sdlc-plugin",
3
3
  "displayName": "ShapeUp SDLC Plugin",
4
- "version": "1.6.2",
4
+ "version": "1.7.0",
5
5
  "description": "Shape Up SDLC harness for Claude Code: shaping, intake, orient, scope-mapping, building (T0-verified, sandboxed, scope-contracted), evaluation and QA skills orchestrated by a tech-lead.",
6
6
  "author": {
7
7
  "name": "Liberty Nguyen",
package/AGENTS.md CHANGED
@@ -1,133 +1,66 @@
1
1
  <!-- HARNESS_START -->
2
2
  # Shape Up SDLC Local Harness
3
3
 
4
- This project is scaffolded with the Shape Up SDLC Harness for coding agents.
4
+ ## Enforcement model
5
5
 
6
- ## mechanism instruction
6
+ A three-phase Shape Up loop orchestrated by `/tech-lead`. Invariants live in the runtime, not this file — expect hook denials, not arguments.
7
7
 
8
- The harness follows a **three-phase Shape Up SDLC loop** orchestrated by `/tech-lead`.
9
-
10
- **The organising idea: every invariant that matters lives in the runtime, not in a prompt.**
11
- Three consequences, in the order a reader should meet them:
12
-
13
- 1. **Gates are enforced, not requested.** A `PreToolUse` hook
14
- (`skills/tech-lead/scripts/validate-envelope.mjs`) hard-denies any worker dispatch whose
15
- WorkOrder is missing or fails its schema — the malformed order never reaches a worker.
16
- `hooks/sandbox-guard.mjs` denies every write outside the active scope's substrate, and
17
- `hooks/gate-zerowork.mjs` blocks `Stop` on a run that left no receipt.
18
- *Prevents: a worker acting on an order nobody compiled; a scope overwriting another's work.*
19
- GATE L2 (`hooks/gate-l2.mjs`) is deliberately **advisory** — it reads the board from two
20
- independent sources and warns when the once-per-round EVAL runs over unfinished tasks, but it
21
- permits the call. The board is per-machine and the operator asked for the evaluation; see
22
- `docs/design/adr/0001-consumer-file-organization.md` for why the denial was traded for a signal.
23
- Sign-off itself is a file, not prose: `scripts/gate-answers.mjs` resolves each gate from a
24
- schema-validated answer set (`ci` / `guarded` / `interactive`) and the orchestrator branches on
25
- its exit code — 0 cross, 4 stop for the PO, 5 abort. Gates still emit their blocks and still
26
- record a decision; what changes is that the decision's **source** is named in the ledger.
27
- *Prevents: consent carried in a prompt paragraph, which gets paraphrased instead of acted on.*
28
- 2. **Progress is derived, never claimed.** Hill phase comes only from T0/T1/seesaw artifacts on
29
- disk, and the evaluator must cite a T0 artifact it re-hashes itself. *Prevents: a worker
30
- asserting "done" with nothing behind it.*
31
- And **starting** is itself a fact on disk: `scripts/init-run.mjs` writes
32
- `.shapeup/<slug>/receipt.json` as the run's first tool call, so a session that dispatched
33
- the orchestrator and left no receipt is blocked at `Stop` by `hooks/gate-zerowork.mjs`.
34
- *Prevents: the orchestrator describing its own pipeline in future tense and stopping — measured
35
- at 29% acceptance with 10 escaped defects while reading like a clean run.*
36
- 3. **Parallel work cannot corrupt shared state.** Per-scope substrate write-whitelists are hook-
37
- enforced, and exactly one script (`ingest-result.mjs`) performs every board/ledger/verdict
38
- write. *Prevents: two executors rewriting the board, one's completions vanishing.*
39
-
40
- Those three rest on one piece of plumbing — the **pure-skill architecture** (v1.0). The
41
- orchestrator owns ALL pipeline management and talks to workers through two JSON envelopes: a
42
- WorkOrder in (`compile-order.mjs`, schema-validated by a `validate-envelope.mjs` PreToolUse
43
- hook) and a WorkResult out (applied by `ingest-result.mjs`). Worker skills contain craft only —
44
- zero pipeline knowledge; everything they used to write into shared files they now return as data
45
- (D6 closed: single-writer is mechanically true). Treat the envelope as an implementation detail:
46
- it is what makes 1–3 mechanically true, and it should never be the first thing a user learns.
8
+ - Hook-denied: dispatching a worker without a schema-valid WorkOrder, writing outside the scope's substrate, stopping a run with no receipt (the run's first act writes one).
9
+ - GATE L2 is advisory — warns when EVAL runs over unfinished tasks, permits the call (per-machine board, operator asked; ADR-0001) — a signal, not a bug.
10
+ - Sign-off is a file: each gate resolves from the answer set (`ci`/`guarded`/`interactive`) — cross, stop for the PO, or abort; the decision's source is ledgered.
11
+ - The build+eval loop breaks only three ways ✦: EVAL PASS → QA → Ship; outer `round_budget` exhausted; opt-in `wall_clock_budget_s` tripped (the wall-clock axis event counters miss). Budget trips route to GATE H — ship what's green, never kill the run from outside. A scope exhausting its per-scope `attempt_budget` (T0 attempts) queues a GATE H proposal, never blocks the round.
47
12
 
48
13
  ### Phase 1 — Shaping (`/shapeup`)
49
14
  1. Set Boundaries → `/shapeup shaping`
50
15
  2. Find the Elements → `/shapeup breadboarding`
51
16
  3. Risks & Rabbit Holes → `/shapeup spike`
52
- 4. Write the Pitch `/generate-pitch` `pitch.md`
17
+ (The completed pitch is formed by `shaping.md` + `breadboard.md`)
53
18
 
54
19
  ### Phase 2 — Betting (PO governance, no skill)
55
- - PO decides at the Betting Table; rejected pitches loop back to raw idea.
20
+ Betting Table: PO decides; rejected pitches loop back to raw idea.
56
21
 
57
- ### Phase 3 — Building (orchestrated by `/tech-lead`)
22
+ ### Phase 3 — Building
58
23
  | Step | Gate | Action |
59
24
  |------|------|--------|
60
25
  | Kick-off | ⏸ **L0** — Intake & Config (L0.8 model/budget matrix) | `/translator` if non-English |
61
- | Orient (Scout) | ⏸ **L1a** — Orient Review | delegate → `/orient` |
62
- | Wire (Reachability) | ⏸ **L1a.5** Wiring Review | delegate → `/solution-architect` (`wire`): committed `wiring-map.md` per-UC engine seam entry-point call site affordance, against `project-profile.md` entry_point; front-loads the integration seam |
63
- | Map Scopes | ⏸ **L1b** — Board Review (+ substrate disjointness via `spec-lint.mjs`) | delegate → `/ba-pitch-analyzer` (spec tree + board: UC + Invariants + Test Surface ★; `coverage` op writes the `requirements.md` registry ✚) then `/scope-architect` (scope contracts sole writer). Traceability oracle `trace-lint.mjs` runs advisory ✚ |
64
- | Build Vertically | ⏸ **L2** — Board 100% + T0-green | per dispatch: compile-order → `/task-executor` (--order) ingest-result, T0-verified per attempt (fixtures + DB probe + seesaw ✦), sandboxed to each scope's substrate ✦ |
65
- | EVAL (once per round) | ⏸ **L3** — Verdict | delegate → `/spec-evaluator` (--order; spec-conformance + test-surface-conformance ★; requires a T0 artifact citation on scoped specs ✦); refuted boxes/verdict ledger applied by ingest |
66
- | FAIL fix round r+1 | — | regression rule ★: bugs + full Test Surface of touched UC |
26
+ | Orient (Scout) | ⏸ **L1a** — Orient Review | `/orient` |
27
+ | Analyze | — (reviewed at L1b) | `/ba-pitch-analyzer` (`analyze`): spec tree + board (UC + Invariants + Test Surface ★); before Wire (needs its use cases) |
28
+ | Wire | ⏸ **L1a.5** — Wiring Review | `/solution-architect` (`wire`): sole writer of committed `wiring-map.md` per-UC engine seam entry-point call site affordance, per `project-profile.md` |
29
+ | Map Scopes | ⏸ **L1b** — Board Review (+ substrate disjointness lint) | `/scope-architect` (scope contracts sole writer); traceability oracle advisory |
30
+ | Build Vertically | ⏸ **L2** — Board 100% ✅ + T0-green ✦ | per dispatch: compile order → `/task-executor` (--order) ingest result; T0-verified per attempt (fixtures + DB probe + seesaw ✦), substrate-sandboxed |
31
+ | EVAL (once per round) | ⏸ **L3** Verdict | `/spec-evaluator` (--order): spec- + test-surface-conformance ★, T0 citation ✦; refuted boxes/verdict applied by ingest |
32
+ | FAIL → round r+1 | — | regression rule ★: bugs + full Test Surface of touched UC |
33
+
34
+ ✦ = requires scope contracts (`shapeup/<slug>/scopes/*.md`); ✚ = requires the spine artifacts (`requirements.md`, `wiring-map.md`, `project-profile.md`). Traceability stays advisory until `covers:` is populated. Absent artifact ⇒ arm skipped (non-regression).
67
35
 
68
- ✦ = v0.3.0 mechanisms, active only when the spec folder has scope contracts
69
- (`shapeup/<slug>/scopes/*.md`); non-regression on older specs.
70
- ✚ = spine v1.3 traceability mechanisms (covers-closure + reachability), active only when the
71
- spine artifacts exist (`requirements.md`, `wiring-map.md`, `project-profile.md`); `trace-lint`
72
- ships advisory (warn-only) and is promoted to a blocking gate only once `covers:` is populated.
73
- Non-regression on older specs — every arm is skipped when its artifact is absent.
74
36
 
75
37
  ### QA Edge Hunt (`/qa-edge-hunter`, post-PASS, pre-ship)
76
- - **Q0** Preflight → **Q1** Charter (6 lenses − EVAL-covered) → **Hunt** (repro required, findings `~` → ledger) → report (no verdict, no score).
77
- - Skip with `--no-qa`.
38
+ **Q0** Preflight → **Q1** Charter (6 lenses − EVAL-covered) → **Hunt** (repro required, findings `~` → ledger) → report (no verdict, no score). Skip with `--no-qa`.
78
39
 
79
40
  ### Ship & Triage
80
- - **SHIP S.0 / GATE H** — delegated to `/scope-hammer`: census (QA findings + discovered ledger
81
- + attempt-budget hammer proposals ✦) baseline comparison (never vs. the ideal) → cut list;
82
- TL/PO confirms, promotes only selected items.
83
- - **L4** Gate Ship Sign-off (shows QA status ★).
84
- - **RLHF (Coach Retro)** — Post-sprint feedback from L4 Gate is processed by `/coach`, which runs a categorization gate (GATE COACH-1 — asks the PO which skill each rule belongs to, never assumes) and files each rule under the responsible skill in `shapeup/knowledge-base/<skill>.md`. These files are **committed** (not the gitignored `.shapeup/` run-trace), so the whole team inherits them on `git pull`. The `/tech-lead` automatically invokes `/coach` when it receives human feedback during the Ship Gate. Coachable skills — each reads its own file at the top of its next run — are `/task-executor` (Phase 1), `/ba-pitch-analyzer` (Phase 1), and `/qa-edge-hunter` (Phase Q1). `/spec-evaluator` is deliberately not coachable (single-judge rule: the KB is guidance, never an invariant). Feedback whose root cause is the mechanism itself (a gate, hook, or skill-contract defect) is categorized `harness-defect` at GATE COACH-1 and filed to the committed defect register (`knowledge-base/harness-defects.md`) as a drafted raw idea for the Betting Table — read by no worker, never worker steering.
85
- - Post-fix: `eval --single-pass` → `qa --recheck` (only re-probes promoted items ✦).
86
- - Remaining `~` findings + new feedback → new raw idea (debt-free).
41
+ - **SHIP S.0 / GATE H** — `/scope-hammer`: census (QA findings + discovered ledger + attempt-budget proposals ✦) → baseline comparison (never the ideal) → cut list; TL/PO promotes selected items only.
42
+ - **L4** Ship Sign-off (shows QA status ).
43
+ - **Coach retro** — L4 feedback → `/coach`; GATE COACH-1 asks the PO which skill owns each rule (never assumes) → committed `shapeup/knowledge-base/<skill>.md` (team inherits on pull). Coachable: `/task-executor`, `/ba-pitch-analyzer`, `/qa-edge-hunter`; `/spec-evaluator` is not (single judge). Mechanism defects file to `knowledge-base/harness-defects.md` as Betting Table raw ideas, never worker steering.
44
+ - Post-fix: `eval --single-pass` remaining `~` + new feedback → new raw idea.
87
45
 
88
46
  ### Discovered Tasks
89
- All discovered tasks are funnelled into `.shapeup/<slug>/discovery/ledger.md` (Orient, task-executor P3.7, QA). A new invariant triggers `ba --tasks-only --from-discovered` which appends a `TS-INV-NN` row to the Test Surface ★.
47
+ Everything discovered funnels into `.shapeup/<slug>/discovery/ledger.md` (Orient, task-executor P3.7, QA); a new invariant triggers `ba --tasks-only --from-discovered` `TS-INV-NN` Test Surface row ★.
90
48
 
91
49
  ### Architectural Invariants
92
- - **Single judge** — verdict belongs to `spec-evaluator`; QA has no verdict and no score.
50
+ - **Single judge** — verdict belongs to `spec-evaluator`; QA has no verdict, no score.
93
51
  - **EVAL exactly once per round** — QA sits after PASS, outside the loop.
94
- - **Ledger = single source of truth** — all discovery flows write only to their own section.
95
- - **QA is a level-up, not a gate** — `--no-qa` can skip it; circuit breaker outranks the Hunter.
96
- - **Role separation** — Evaluator grades, task-executor fixes, QA discovers; no cross-role work.
97
- - **Three-level circuit breaker ✦** — outer `round_budget` (build+eval cycles) nests an inner
98
- per-scope `attempt_budget` (T0 attempts); an exhausted scope queues a GATE H proposal, it
99
- never blocks the round. A third, opt-in `wall_clock_budget_s` breaker (`budget-check.mjs`,
100
- enforced by `hooks/gate-deadline.mjs`) covers the axis the other two cannot see — both count
101
- events, so neither notices a single round running for half an hour. Tripping it routes to
102
- GATE H rather than killing the run: a run killed from outside ships nothing, a run that trips
103
- its own breaker ships what is green.
104
- - **Hill phase is mechanical, never self-reported ✦** — derived only from T0/T1/seesaw facts.
105
- - **Envelope port (v1.0)** — every worker dispatch is WorkOrder in / WorkResult out; shared
106
- state is written only by `ingest-result.mjs`; a malformed envelope is denied by hook before
107
- it reaches a worker. Workers are stateless and pipeline-blind by construction.
108
-
109
- ## Installed Skills
110
-
111
- - **shapeup**: Run Shape Up workflows before writing code (S1-S4, B1-B5).
112
- - **ba-pitch-analyzer**: The spec-analyzer — pitch → DDD spec tree + board, one craft with five order-selected operations (analyze | generate-board | reconcile | retrofit-surface | coverage); graph math and audits delegated to `board-derive.mjs`/`spec-lint.mjs`; the `coverage` op writes the SHARED requirement registry (`requirements.md`) for covers-closure; stateless pure worker.
113
- - **scope-architect**: Sole writer of committed scope contracts (`scopes/*.md`) — import-graph slicing by flow, write-whitelist substrates, affordance manifests, fixtures; map-scopes | remap | split-scope operations.
114
- - **solution-architect**: Sole writer of the committed wiring map (`wiring-map.md`) at gate L1a.5 — per-UC engine → seam → entry-point call site → player-visible affordance, resolved against `project-profile.md`; the reachability input `trace-lint.mjs` checks so no engine ships orphaned; `wire` operation; stateless pure worker.
115
- - **task-executor**: Implement a work order's acceptance criteria exactly — WorkOrder in, code + WorkResult out; zero-memory, substrate-sandboxed, Layer 1/2/3 UI rules; never writes boards/ledgers/run-state.
116
- - **spec-evaluator**: The single judge — evaluates the running app against the committed spec; verdict + refuted boxes return as data; requires a T0 artifact citation and grades UI affordance-only on scoped specs.
117
- - **qa-edge-hunter**: Exploratory QA hunt.
118
- - **translator**: Bilingual Vietnamese/English gate at intake.
119
- - **tech-lead**: Orchestrate runs — envelope port (compile-order → dispatch → ingest-result), two-level circuit breaker, T0/seesaw-verified build rounds, mechanical hill derivation.
120
- - **coach**: Ingests L4 feedback, asks the PO to categorize each rule (GATE COACH-1), and files it under the responsible skill in committed `shapeup/knowledge-base/<skill>.md` for team-shared, read-back continuous learning (RLHF).
121
- - **advisor-protocol**: Adjudicates a worker's structured `ESCALATE` (design decision / spec ambiguity / substrate expansion) within a per-scope-per-round budget; persists answers to the committed round ledger.
122
- - **scope-hammer**: GATE H — must-have census, baseline comparison, cut list + ship verdict; handles the normal stop and both circuit-breaker triggers.
52
+ - **Ledger = single source of truth** — every discovery flow writes only its own section.
53
+ - **QA is a level-up, not a gate** — `--no-qa` skips it; circuit breaker outranks the Hunter.
54
+ - **Role separation** — Evaluator grades, task-executor fixes, QA discovers.
55
+ - **Hill phase is mechanical ✦** — derived only from T0/T1/seesaw artifacts, never self-reported; the evaluator cites a T0 artifact it re-hashes itself.
56
+ - **Envelope port (v1.0)** — every dispatch is WorkOrder in / WorkResult out; shared state has exactly one writer (the ingest step); malformed envelopes are hook-denied. Workers: stateless, craft-only, pipeline-blind.
123
57
 
124
58
  ## Setup & Execution
125
59
 
126
- - Envelope schemas ship inside the orchestrator skill: \`skills/tech-lead/schemas/\`; the pipeline scripts live beside their owning skill (\`skills/tech-lead/scripts/\`, \`skills/ba-pitch-analyzer/scripts/\`); orders/results live in \`.shapeup/<slug>/orders|results/\`
127
- - **Run entry points** — \`init-run.mjs\` (GATE L0.1, opens the run and writes the receipt), \`gate-answers.mjs\` (resolves a gate from the answer set), \`budget-check.mjs\` (the deadline breaker). Because these ship WITH the plugin they live outside your project, so they need a one-time permission grant; \`npx shapeup-sdlc init\` writes it into \`.claude/settings.json\` (\`permissions.allow\`). Without it a headless run cannot take its first step — measured, 26 approval denials in one session.
128
- - **Central domain registry** — \`skills/tech-lead/schemas/domain.schema.json\` defines every cross-boundary record type and payload field ONCE (annotated with tier/location/writer/readers, the \`x-erd\` relationship map, and the \`x-payload-by-worker\` table); the envelope schemas \`$ref\` it and no skill defines its own cross-boundary field
129
- - **Two storage tiers (ADR-0001) — prose is the team's, structured data is the machine's.** COMMITTED \`shapeup/<slug>/\`: \`shaping/\`, \`spec/\`, \`scopes/*.md\`, \`wiring-map.md\`, \`project-profile.md\`, \`requirements.md\`, \`hill/*.yml\`, and \`REPORT.md\` (frozen once at GATE L4 — the only run evidence a teammate sees). GITIGNORED \`.shapeup/\`: the board, orders/results, \`t0/\`, \`evaluation/\`, \`qa/\`, \`working/\`, \`round-ledger.md\`, \`metrics/\`, \`gate-answers.json\`, \`safety-overrides.json\`, \`decisions.jsonl\`
130
- - The three contracts are MARKDOWN on disk and JSON on the wire: frontmatter for scalars and \`[a, b]\` lists, a markdown table for the one array-of-objects field. \`skills/tech-lead/scripts/lib/contract-md.mjs\` is the only reader/writer of the file form; the envelope is unchanged
131
- - Every generated path resolves through \`skills/tech-lead/scripts/lib/paths.mjs\` never hard-code a storage root (structural test #45 enforces this)
132
- - **Traceability spine (v1.3)** — the covers-closure + reachability oracle \`skills/tech-lead/scripts/trace-lint.mjs\` reads three committed SHARED artifacts: the requirement registry \`shapeup/<slug>/requirements.md\` (RequirementClause rows, written by \`ba-pitch-analyzer coverage\`), the wiring map \`shapeup/<slug>/wiring-map.md\` (written by \`solution-architect wire\`), and \`shapeup/<slug>/project-profile.md\` (archetype + entry_point, written by \`tech-lead\` at L0). It emits the LOCAL run-trace \`.shapeup/<slug>/trace/report.json\`; ships advisory, promoted to a gate only once \`covers:\` is populated
60
+ - Orders/results live in `.shapeup/<slug>/orders|results/`; the envelope schemas ship inside the tech-lead skill.
61
+ - The plugin's run entry points need a one-time permission grant — `npx shapeup-sdlc init` writes it into `.claude/settings.json` (`permissions.allow`); without it a headless run stalls at step one.
62
+ - Two storage tiers (ADR-0001): COMMITTED `shapeup/<slug>/` (shaping, spec, scopes, wiring-map, project-profile, requirements, hill, `REPORT.md` frozen at L4) vs GITIGNORED `.shapeup/` (board, orders/results, T0/eval/QA artifacts, ledgers, metrics, gate answers).
63
+ - Contracts: markdown on disk, JSON on the wire; a single library reads/writes the file form.
64
+ - Never hard-code a storage root generated paths resolve through the shared path resolver.
65
+ - The traceability oracle emits `.shapeup/<slug>/trace/report.json` from the spine artifacts.
133
66
  <!-- HARNESS_END -->
package/README.md CHANGED
@@ -15,11 +15,11 @@ The ceremony is right-sized: `/ship` runs the full gated pipeline for real featu
15
15
  fixes where the gates would have nothing to say.
16
16
 
17
17
  <p align="center">
18
- <img src="docs/assets/demo-gate.svg" alt="Terminal recording: the agent tries to run EVAL with two tasks unfinished, and a PreToolUse hook denies the tool call outright." width="700">
18
+ <img src="docs/assets/demo-gate.svg" alt="Terminal recording: the agent tries to run EVAL with two tasks unfinished, and a PreToolUse hook names both unfinished tasks and records the evaluation as taken over a partial board." width="700">
19
19
  </p>
20
20
 
21
21
  <p align="center"><sub>
22
- The denial text above is <b>verbatim stdout</b> from <code>hooks/gate-l2.mjs</code> —
22
+ The GATE L2 text above is <b>verbatim stdout</b> from <code>hooks/gate-l2.mjs</code> —
23
23
  <a href="tools/demo/record-demo.mjs">the recorder runs the real hook</a> and fails rather than
24
24
  draw a picture. <a href="docs/assets/demo-gate.txt">Plain-text transcript.</a>
25
25
  </sub></p>
@@ -32,8 +32,8 @@ prompt-based harness:
32
32
 
33
33
  **1. A worker cannot act on an order nobody compiled.** Every dispatch carries a schema-validated
34
34
  WorkOrder, and a `PreToolUse` hook hard-denies the call when that order is missing or malformed —
35
- the tool call never reaches the worker. The same layer denies any write outside the active scope's
36
- file substrate, and blocks a session that dispatched the orchestrator and left no run receipt.
35
+ 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.
37
37
  → *Prevents: an agent inventing its own brief, then reporting against it.*
38
38
 
39
39
  (GATE L2, the board-green check before evaluation, is advisory: it warns when a round's evaluation
@@ -54,16 +54,6 @@ Under the hood this rests on a typed worker envelope and a single-writer state l
54
54
  are load-bearing plumbing, and you should not have to think about them to use the harness —
55
55
  they are documented for [contributors](CONTRIBUTING.md), not for users.
56
56
 
57
- > ### Just want the gate?
58
- >
59
- > The enforcement layer ships separately as the **[Anti-Lying Kit](plugins/anti-lying-kit/)** —
60
- > three hooks, no methodology, installable *alongside* spec-kit, OpenSpec, or your own
61
- > `tasks.md`. You should not have to adopt Shape Up to stop your agent claiming done.
62
- >
63
- > ```
64
- > /plugin install anti-lying-kit@nvptuoc-marketplace
65
- > ```
66
-
67
57
  ## Quickstart
68
58
 
69
59
  ```
@@ -74,32 +64,32 @@ they are documented for [contributors](CONTRIBUTING.md), not for users.
74
64
 
75
65
  `/ship` walks the whole lifecycle and pauses at each gate for you. That's the whole quickstart.
76
66
 
67
+ > **Running unattended?** The plugin install grants no permissions — every pipeline step is a Node
68
+ > script that ships *with* the plugin and therefore lives outside your project, so it needs
69
+ > approval. You click once interactively; headless there is nobody to click. Scaffold instead, which
70
+ > writes the grant:
71
+ >
72
+ > ```bash
73
+ > npx shapeup-sdlc init -d . -y
74
+ > ```
75
+
77
76
  Want to see a full run before installing anything? **[docs/quickstart.md](docs/quickstart.md)**
78
- walks one small feature end to end — including the hook denying a premature eval, a FAIL round
77
+ walks one small feature end to end — including what the hooks do to a premature eval, a FAIL round
79
78
  with real evaluator output, and the fix that turns it green.
80
79
 
81
80
  <sub>No prerequisites for non-UI work — a browser (`npx playwright install chromium`) is needed
82
81
  only when a run actually reaches a `[ui]` acceptance criterion. Team installs, the scaffolding
83
- installer (Claude Code / Antigravity / Codex), and troubleshooting are in
82
+ installer, and troubleshooting are in
84
83
  **[docs/install.md](docs/install.md)**; upgrading is **[docs/upgrading.md](docs/upgrading.md)**.</sub>
85
84
 
86
85
  ## Agent support
87
86
 
88
- The harness is written once and compiled to other agent CLIs (`npm run distribute` emits
89
- `dist/`; the [scaffolding installer](docs/install.md#local-scaffolding) wires targets in one
90
- run). The matrix is honestthe row that matters most does not travel:
91
-
92
- | | Claude Code | Cursor | Antigravity | Codex |
93
- |---|:---:|:---:|:---:|:---:|
94
- | The 13 skills | ✅ plugin | ✅ `.mdc` rules (references inlined) | ✅ subagent defs + skill files | ✅ skill files |
95
- | Slash commands | ✅ all 10 | ✅ VS Code/Cursor extension + rules | — | — |
96
- | Pipeline scripts (`t0-verify`, `trace-lint`, oracles) | ✅ | ✅ plain Node, run from any CLI | ✅ | ✅ |
97
- | **Hook-enforced gates** (deny on premature EVAL, substrate sandbox, safety spine) | ✅ | ❌ | ❌ | ❌ |
98
- | Advisory Stop hooks | ✅ | ❌ | ❌ | ❌ |
99
-
100
- Hooks are a per-CLI mechanism, so outside Claude Code the gates degrade from **enforced** to
101
- **instructed** — the same honor system every other framework runs on everywhere. If the deny
102
- hook is why you're here, that currently means Claude Code.
87
+ The harness targets **Claude Code only**. The reason is the row that never travelled when we
88
+ compiled to other CLIs: hooks. The 12 skills, 10 slash commands and pipeline scripts are
89
+ portable prose and plain Nodebut hook-enforced gates (envelope validation, substrate
90
+ sandbox, safety spine, the zero-work block) are a per-CLI mechanism, and without them every gate degrades from
91
+ **enforced** to **instructed** the same honor system every other framework runs on
92
+ everywhere. If the deny hooks are why you're here, that means Claude Code.
103
93
 
104
94
  ## Glossary
105
95
 
@@ -108,15 +98,15 @@ rest of this README after this table and nothing will be a surprise.
108
98
 
109
99
  | Term | In plain English |
110
100
  |---|---|
111
- | **board** | The round's task list. "Green" means every task is done. The deny hook reads this. |
101
+ | **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. |
112
102
  | **round** | One build → evaluate cycle. A FAIL verdict starts round *r+1*. |
113
103
  | **T0** | The smoke test a scope must pass before it counts as built: its fixtures + a DB probe + the seesaw. Writes an artifact to disk that the evaluator must cite. |
114
104
  | **seesaw** | The part of T0 that re-runs *other* scopes' fixtures — so a regression is never mistaken for progress. |
115
- | **substrate** | The exact list of files one scope is allowed to write. A hook blocks anything outside it. |
105
+ | **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. |
116
106
  | **scope contract** | The file defining one vertical slice: its substrate, its fixtures, its affordances. |
117
107
  | **affordance** | The thing a user can actually click, type or call. UI is graded on affordances, not on looks. |
118
108
  | **hill / hill phase** | How much of a scope is still *unknown* versus merely *unfinished*. Derived from T0 facts — never self-reported. |
119
- | **gate (L0–L4)** | A numbered checkpoint in a run. Most pause for you; GATE L2 is the one enforced by a hook. |
109
+ | **gate (L0–L4)** | A numbered checkpoint in a run. Most pause for you; GATE L2 is the one a hook observes and reports on. |
120
110
  | **covers-closure** | Every requirement clause has at least one task claiming to cover it. Nothing silently drops. |
121
111
  | **wiring reachability** | Every engine has a call site reachable from the app's real entry point. Catches "built, but never wired up". |
122
112
  | **discovery ledger** | The one file everything found mid-run gets written to, so nothing is lost between rounds. |
@@ -172,12 +162,11 @@ every arm is skipped when its artifact is absent, so older specs are unaffected.
172
162
  | Intake (GATE L0) | `translator` | — | Normalizes non-English intake (pitch/PRD/transcript) to faithful English before planning. The harness is English-only downstream. |
173
163
  | 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. |
174
164
  | 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 `trace-lint.mjs` checks. Operation: wire. |
175
- | 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, five order-selected operations (analyze / generate-board / reconcile / retrofit-surface / coverage — the last writes the shared `requirements.md` registry for covers-closure); graph math + audits delegated to `board-derive.mjs`/`spec-lint.mjs`. |
176
- | 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. Operations: map-scopes / remap / split-scope. |
165
+ | 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 `board-derive.mjs`/`spec-lint.mjs`. |
166
+ | 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. |
177
167
  | 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. |
178
168
  | 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. |
179
169
  | 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. |
180
- | Advisor (mid-build) | `advisor-protocol` | v0.1 | Adjudicates a worker's structured `ESCALATE` (design decision / spec ambiguity / substrate expansion) within a per-scope-per-round budget; persists answers to the committed round ledger so they survive a zero-memory reset. |
181
170
  | 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. |
182
171
  | 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 `task-executor` / `ba-pitch-analyzer` / `qa-edge-hunter` on their next run. GATE COACH-1 asks the PO which skill owns each rule — never assumes; mechanism defects are filed to the harness-defect register instead. |
183
172
  | 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/seesaw-verified build rounds, mechanical hill derivation. Sole writer of run-state. |
@@ -200,15 +189,10 @@ learnable from `/`-completion alone.
200
189
  | `/hammer` | H | Must-have census, baseline comparison, cut list + ship verdict. |
201
190
  | `/retro` | post-L4 | File ship-gate feedback into the per-skill knowledge base. |
202
191
 
203
- ### Agents
204
-
205
- | Agent | Description |
206
- |-------|-------------|
207
- | `reviewer` | Independent correctness/security code reviewer (returns findings, never edits). |
208
-
209
192
  ### Hooks
210
193
 
211
- Nine Node hooks. What each one reads and what it can deny:
194
+ Ten Node hooks in `hooks/`, plus `validate-envelope.mjs` which ships with the orchestrator skill.
195
+ What each one reads and what it can deny:
212
196
 
213
197
  - `SessionStart` — prints a load confirmation so you know the plugin is active; on
214
198
  `startup|compact|resume|clear`, `hooks/session-rehydrate.mjs` additionally injects the mid-run
@@ -216,8 +200,10 @@ Nine Node hooks. What each one reads and what it can deny:
216
200
  cold `startup` it leads with the stronger sentence — *a run is already open; resume it, do not
217
201
  re-open it* — because that is the failure a fresh session actually makes. Silent when no run is
218
202
  in flight, which is the ordinary case.
219
- - `PreToolUse` (matcher `Skill`) — **`hooks/gate-l2.mjs` hard-blocks the once-per-round EVAL
220
- delegation while the task board isn't fully green.** This is the gate in the demo above.
203
+ - `PreToolUse` (matcher `Skill`) — **`hooks/gate-l2.mjs` warns when the once-per-round EVAL
204
+ delegation runs over an unfinished task board**, naming the offending tasks and recording a
205
+ `warn` row. Advisory since ADR-0001 — the board is per-machine and the operator asked for the
206
+ call. This is the gate in the demo above.
221
207
  - `PreToolUse` (matcher `Skill`) — **`hooks/gate-intake.mjs` denies a `tech-lead` dispatch that
222
208
  carries no pitch, no spec folder, and no requirement text.** Measured on the SDD harness
223
209
  benchmark: when the requirement text was dropped on the hand-off and only a flag survived, the
@@ -226,7 +212,7 @@ Nine Node hooks. What each one reads and what it can deny:
226
212
  instead of narrating.
227
213
  - `PreToolUse` (matcher `Skill`) — **`hooks/gate-deadline.mjs` denies a `task-executor` dispatch
228
214
  once the run's opt-in wall-clock budget is spent**, routing to GATE H instead. `spec-evaluator`,
229
- `scope-hammer`, `qa-edge-hunter` and `advisor-protocol` stay reachable — a run past its deadline
215
+ `scope-hammer` and `qa-edge-hunter` stay reachable — a run past its deadline
230
216
  must still be able to judge, hammer and close. Off unless a budget is configured.
231
217
  - `PreToolUse` (matcher `Bash|Read|Write|Edit|MultiEdit`) — `hooks/safety-spine.mjs` denies
232
218
  destructive commands (`rm -rf` on unrecoverable targets, force-push/push-to-main,
@@ -289,14 +275,15 @@ Stated plainly, because you will hit them:
289
275
 
290
276
  - **The `--tiny` lane is young.** It right-sizes the ceremony (two gates instead of eight) but
291
277
  keeps the T0 verification floor; its fit-check heuristics will need tuning against real use.
292
- - **Only half the trigger-eval story is measured.** Skill *discrimination* is:
293
- **0 false activations across 75 cross-skill hard negatives** (Haiku 4.5, 2026-07-26 the
294
- thirteen descriptions do not steal each other's work). *Activation* rate is measured but
295
- confounded and deliberately not quoted as a headline: 38 of 74 positive cases point at a
296
- referent ("coach **this feedback**") the probe never supplies, so a model that names the right
297
- skill and asks for the missing input scores as a miss. Method, per-skill numbers, and the fix
298
- are in [evals/README.md](evals/README.md) the harness ships a CI test that *fails* if
299
- fabricated results appear, and three earlier baselines were discarded rather than published.
278
+ - **Nothing here measures skill quality or activation.** The repo used to carry two evidence
279
+ layers a Tier-1 activation dataset per skill, and a Day-1/Day-2 craft-and-efficacy register
280
+ and both have been removed. What that cost is worth stating plainly rather than leaving to be
281
+ discovered: there is now no number for whether a skill's description makes it fire on the right
282
+ request, no measured craft delta, and no CI check enforcing the honesty invariant on such
283
+ numbers. The structural suite (Tier 0) and the functional planted-bug fixtures (Tier 2) are the
284
+ coverage that remains, and both are about mechanism rather than quality.
285
+ - **The gates are verified; the craft is not.** A hook that denies is proven by a test that
286
+ watches it deny. A skill that writes a good spec tree is, at present, taken on trust.
300
287
 
301
288
  Contributions to any of these are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
302
289
 
@@ -315,7 +302,7 @@ claude --plugin-dir . # load this working copy without installing
315
302
  .claude-plugin/
316
303
  plugin.json # plugin manifest
317
304
  marketplace.json # marketplace listing (points at this repo)
318
- skills/<name>/SKILL.md # the 13 harness skills (+ references/ and assets/)
305
+ skills/<name>/SKILL.md # the 12 harness skills (+ references/ and assets/)
319
306
  skills/tech-lead/scripts|schemas/ # orchestrator pipeline: init-run, gate-answers,
320
307
  # budget-check, compile-order, ingest-result, validate-envelope,
321
308
  # t0-verify, trace-lint, aegis-digest, run-snapshot,
@@ -323,29 +310,35 @@ skills/tech-lead/scripts|schemas/ # orchestrator pipeline: init-run, gate
323
310
  skills/ba-pitch-analyzer/scripts/ # planner mechanics: board-derive, spec-lint
324
311
  skills/spec-evaluator/scripts/ # verdict-ledger (reference impl of the flip/confidence grammar)
325
312
  commands/*.md # slash commands (/ship + the 9 phase commands)
326
- agents/*.md # subagents (reviewer)
327
313
  hooks/ # hooks.json + safety-spine, gate-l2, gate-intake, gate-deadline,
328
314
  # sandbox-guard (PreToolUse),
329
315
  # gate-zerowork (Stop, blocking), anti-rationalization, slop-cleaner (Stop, advisory),
330
316
  # compact-snapshot (PreCompact), session-rehydrate (SessionStart)
317
+ # + lib/decision.mjs (every hook records allow / deny / error)
318
+ oracles/ # the evaluation-contract oracle registry (test · snapshot · http · process)
319
+ bin/init.mjs # `npx shapeup-sdlc init` — scaffolds all three CLI targets
331
320
  scripts/install-harness.sh, migrate.sh # stable public entrypoints (fresh install / update)
332
- tools/demo/record-demo.mjs # regenerates docs/assets/demo-gate.svg
333
- scripts/shapeup-sdlc/ # dev/CI tooling: lib/, migrations/, oracles/,
334
- # trigger-eval.mjs, distribute.js
321
+ scripts/shapeup-sdlc/lib/ # shell libs both entrypoints source
322
+ tools/ # repo-only: demo/
323
+ # demo/record-demo.mjs (regenerates docs/assets/demo-gate.svg)
324
+ evals/ # Tier-2 functional apparatus only: fixtures/, oracles/
325
+ tests/structural.mjs, tests/structural/*.mjs # Tier 0 — 880+ checks, zero LLM calls
335
326
  docs/install.md, upgrading.md, glossary.md
336
- docs/design/ # the design document (pipeline, gates, circuit breaker, ERD)
337
- docs/internal/launch/ # directory-submission copy
338
- .github/workflows/ # CI + release
327
+ docs/design/ # the design document (pipeline, gates, circuit breaker, ERD) + adr/
328
+ docs/visualize/ # rendered views of the tree and the pipeline
329
+ .github/workflows/ # CI + release (release publishes to npm via OIDC)
339
330
  ```
340
331
 
341
332
  ## Release
342
333
 
343
- 1. Bump `version` in `.claude-plugin/plugin.json`.
334
+ 1. Bump `version` in **both** `.claude-plugin/plugin.json` and `package.json` — the release
335
+ workflow fails if either disagrees with the tag.
344
336
  2. Update `CHANGELOG.md`.
345
- 3. Tag and push: `git tag v1.3.1 && git push origin v1.3.1`.
337
+ 3. Tag and push: `git tag v1.7.0 && git push origin main --follow-tags`.
346
338
 
347
- The release workflow validates the plugin, checks the tag matches the manifest version,
348
- and publishes a GitHub release.
339
+ The workflow validates the plugin, checks the tag against both manifests, publishes a GitHub
340
+ release, and publishes to npm through **trusted publishing (OIDC)** — no `NPM_TOKEN`, no OTP, with
341
+ a SLSA provenance attestation attached automatically.
349
342
 
350
343
  ## Credits
351
344
 
package/SECURITY.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Security
2
2
 
3
- This plugin installs **eight hook entries (seven Node scripts + one `echo`)**, four of them in
4
- a `PreToolUse` position where they can deny tool calls. That is the product — and it is also
5
- exactly the kind of surface a careful reviewer should want spelled out before installing.
6
- This page is that spelling-out.
3
+ This plugin installs **twelve hook entries (eleven Node scripts + one `echo`)**: six in a
4
+ `PreToolUse` position, of which **five can deny a tool call**, plus one `Stop`-position hook that
5
+ can block a session from ending. That is the product and it is also exactly the kind of surface
6
+ a careful reviewer should want spelled out before installing. This page is that spelling-out.
7
7
 
8
8
  ## Reporting a vulnerability
9
9
 
@@ -25,14 +25,25 @@ injection path through skill files. Please do not test against machines you don'
25
25
  no install-time scripts. What you read is what runs.
26
26
  3. **Every hook is fail-open by design.** Unparseable input, missing state files, or an
27
27
  unrecognized invocation shape → the hook defers and the normal permission flow proceeds. A
28
- hook denies only when it can positively prove its condition (a non-green board, a matched
29
- destructive command, a path outside a declared substrate, an invalid order file).
28
+ hook denies only when it can positively prove its condition (a matched destructive command, a
29
+ path the active order's substrate does not permit, an invalid order file, an empty intake, a
30
+ spent wall-clock budget).
30
31
  4. **The model cannot widen its own safety envelope.** The escape hatch
31
32
  (`.shapeup/safety-overrides.json`) is human-authored; `safety-spine` itself denies any
32
33
  write/move/delete touching that file, a malformed overrides file is treated as absent
33
- (override channel fails closed), and every exercised override is logged.
34
- 5. **Stop hooks never block.** The two Stop-position hooks are advisory: they emit at most a
35
- `systemMessage` and always exit 0.
34
+ (override channel fails closed), and every exercised override is logged. The same principle
35
+ covers `.shapeup/active-order`, the pointer `sandbox-guard` reads to decide what a worker may
36
+ write: it sits outside the run-trace carve-out, so a worker cannot repoint its own sandbox.
37
+ 5. **Exactly one hook can block, and only on a mechanical absence.** Two of the three
38
+ `Stop`-position hooks (`anti-rationalization`, `slop-cleaner`) are advisory — at most a
39
+ `systemMessage`, always exit 0. The third, `gate-zerowork`, **does** return
40
+ `decision: "block"`, and only in one state: the session dispatched the orchestrator and left
41
+ no run receipt on disk. It makes no judgement about quality — it reports that there is no work
42
+ to judge. `stop_hook_active` caps it at one block per stop chain.
43
+ 6. **Every hook decision is recorded.** `hooks/lib/decision.mjs` is the only exit path a hook
44
+ has, so allow, deny, block and error each leave a row in `.shapeup/decisions.jsonl`. An
45
+ inert hook and a permitting hook are therefore distinguishable — which matters, because
46
+ "exit 0, no output" is what both used to look like.
36
47
 
37
48
  If you find any of these to be false, that is a vulnerability — report it as claim #ⁿ.
38
49
 
@@ -44,25 +55,29 @@ sitting, and reading them is the recommended review.
44
55
  | Hook | Event (matcher) | Reads | Can deny | Never does |
45
56
  |---|---|---|---|---|
46
57
  | [`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 |
47
- | [`gate-l2.mjs`](hooks/gate-l2.mjs) | PreToolUse (`Skill`) | The round's task board (`.shapeup/<slug>/tasks/`) | Yes — the once-per-round EVAL dispatch while any task is unfinished | Never gates a single-task eval (`--task`); no board defers |
58
+ | [`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 |
59
+ | [`gate-deadline.mjs`](hooks/gate-deadline.mjs) | PreToolUse (`Skill`) | The run's opt-in `wall_clock_budget_s` and start time | Yes — a `task-executor` dispatch once the budget is spent, routing to the ship gate instead | Never denies `spec-evaluator`, `scope-hammer` or `qa-edge-hunter`; off entirely unless a budget is configured |
48
60
  | [`validate-envelope.mjs`](skills/tech-lead/scripts/validate-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) |
49
- | [`sandbox-guard.mjs`](hooks/sandbox-guard.mjs) | PreToolUse (`Edit\|Write\|MultiEdit`) | The target path; the active scope contract | Yes — writes outside the active scope's substrate whitelist | No-op unless a scope is active; the active feature's own `.shapeup/<slug>/` run-trace is always writable. Appends denials to the local pathology log |
61
+ | [`sandbox-guard.mjs`](hooks/sandbox-guard.mjs) | PreToolUse (`Edit\|Write\|MultiEdit`) | The target path; the active order's `substrate` block, via `.shapeup/active-order` | Yes — any write the order does not permit: outside `allowed`/`shared`, inside `frozen`, or a `Write` to an `append_only` path | No-op unless an order is live; the active feature's own `.shapeup/<slug>/` run-trace is always writable. Appends denials to the local pathology log |
62
+ | [`gate-l2.mjs`](hooks/gate-l2.mjs) | PreToolUse (`Skill`) | The round's task board (`.shapeup/<slug>/tasks/`) | **No** — advisory since ADR-0001. It detects a non-green board by two independent reads, names the unfinished tasks in a `systemMessage`, and permits the call | Never denies; records a `warn` row so "evaluated a partial board" stays countable |
63
+ | [`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 |
50
64
  | [`anti-rationalization.mjs`](hooks/anti-rationalization.mjs) | Stop | Board/T0 facts vs. the reply's completion claims | **No** — advisory `systemMessage` only | Never `decision:"block"`, never exit 2 |
51
65
  | [`slop-cleaner.mjs`](hooks/slop-cleaner.mjs) | Stop | The session's git diff (local `git diff`, via `spawnSync`) | **No** — advisory `systemMessage` flagging TODO / `console.log` / commented-out leftovers | Same — never blocks |
52
66
  | [`compact-snapshot.mjs`](hooks/compact-snapshot.mjs) | PreCompact | Run state | No — writes `.shapeup/<slug>/run-snapshot.json` before compaction | Touches nothing outside `.shapeup/` |
53
- | [`session-rehydrate.mjs`](hooks/session-rehydrate.mjs) | SessionStart (`compact\|resume`) | The saved run snapshot | No — injects the "trust the files, not the summary" hint when a run is in flight | Silent when no run is in flight |
67
+ | [`session-rehydrate.mjs`](hooks/session-rehydrate.mjs) | SessionStart (`startup\|compact\|resume\|clear`) | The saved run snapshot | No — injects the "trust the files, not the summary" hint when a run is in flight | Silent when no run is in flight |
54
68
 
55
- (The eighth `hooks.json` entry is a plain `echo` on SessionStart confirming the plugin loaded.)
69
+ (The twelfth `hooks.json` entry is a plain `echo` on SessionStart confirming the plugin loaded.)
56
70
 
57
71
  ## Data handling
58
72
 
59
73
  - **Nothing leaves the machine.** Run state lives in the gitignored `.shapeup/`; telemetry
60
- is a per-machine JSONL shard under `shapeup/metrics/` that travels only if you
61
- commit it. There is no phone-home of any kind.
74
+ is a per-machine JSONL shard under `.shapeup/metrics/`, inside that same gitignored root,
75
+ so it travels only if you deliberately un-ignore and commit it. There is no phone-home of
76
+ any kind.
62
77
  - **The safety-spine actively blocks secret reads** (`.env`, `*.pem`, `*.key`, ssh/cloud
63
78
  credentials) rather than merely not making them.
64
79
  - The installer (`scripts/install-harness.sh`) writes only into the target project
65
- (`.claude/`, `.agents/`, `.codex/`, `shapeup/`, `.gitignore`) and tells you what it
80
+ (`.claude/`, `shapeup/`, `.gitignore`) and tells you what it
66
81
  is going to do first; the `curl | bash` form requires an explicit `--yes` for exactly that
67
82
  reason.
68
83