shapeup-sdlc 1.6.3 → 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.
- package/.claude-plugin/plugin.json +1 -1
- package/AGENTS.md +36 -103
- package/README.md +60 -67
- package/SECURITY.md +31 -16
- package/bin/init.mjs +24 -69
- package/commands/build.md +19 -0
- package/commands/eval.md +5 -4
- package/commands/scopes.md +5 -4
- package/commands/shape.md +1 -1
- package/commands/ship.md +37 -4
- package/hooks/anti-rationalization.mjs +7 -13
- package/hooks/compact-snapshot.mjs +5 -5
- package/hooks/gate-deadline.mjs +12 -16
- package/hooks/gate-intake.mjs +13 -14
- package/hooks/gate-l2.mjs +3 -3
- package/hooks/gate-zerowork.mjs +97 -16
- package/hooks/lib/decision.mjs +21 -13
- package/hooks/safety-spine.mjs +1 -1
- package/hooks/sandbox-guard.mjs +83 -47
- package/hooks/session-rehydrate.mjs +8 -9
- package/hooks/slop-cleaner.mjs +1 -1
- package/oracles/_shared.mjs +1 -1
- package/oracles/http-oracle.mjs +1 -1
- package/oracles/index.mjs +1 -1
- package/oracles/process-oracle.mjs +1 -1
- package/oracles/snapshot-oracle.mjs +1 -1
- package/oracles/test-oracle.mjs +1 -1
- package/package.json +3 -7
- package/skills/ba-pitch-analyzer/SKILL.md +20 -15
- package/skills/ba-pitch-analyzer/references/doc-schemas.md +1 -1
- package/skills/ba-pitch-analyzer/references/task-generation.md +6 -6
- package/skills/ba-pitch-analyzer/references/test-surface.md +1 -1
- package/skills/ba-pitch-analyzer/scripts/board-derive.mjs +5 -5
- package/skills/ba-pitch-analyzer/scripts/spec-lint.mjs +2 -2
- package/skills/coach/SKILL.md +3 -3
- package/skills/orient/SKILL.md +2 -1
- package/skills/qa-edge-hunter/SKILL.md +9 -39
- package/skills/scope-architect/SKILL.md +17 -12
- package/skills/scope-hammer/SKILL.md +5 -5
- package/skills/shapeup/SKILL.md +3 -3
- package/skills/shapeup/resources/context-compaction.md +4 -3
- package/skills/solution-architect/SKILL.md +18 -11
- package/skills/spec-evaluator/SKILL.md +12 -5
- package/skills/spec-evaluator/references/dimensions/_registry.md +2 -2
- package/skills/spec-evaluator/references/dimensions/completeness.md +1 -1
- package/skills/spec-evaluator/references/dimensions/integration.md +98 -67
- package/skills/spec-evaluator/references/dimensions/spec-conformance.md +4 -4
- package/skills/spec-evaluator/references/dimensions/test-surface-conformance.md +1 -1
- package/skills/spec-evaluator/references/probing.md +42 -23
- package/skills/spec-evaluator/references/report-schema.md +2 -2
- package/skills/spec-evaluator/scripts/verdict-ledger.mjs +1 -1
- package/skills/task-executor/SKILL.md +25 -12
- package/skills/tech-lead/SKILL.md +115 -438
- package/skills/tech-lead/references/delegation.md +38 -31
- package/skills/tech-lead/references/gates.md +75 -33
- package/skills/tech-lead/references/hard-rules.md +34 -0
- package/skills/tech-lead/references/invocation.md +2 -2
- package/skills/tech-lead/references/ledger-schema.md +17 -18
- package/skills/tech-lead/references/round-protocol.md +77 -27
- package/skills/tech-lead/references/state-model.md +1 -1
- package/skills/tech-lead/schemas/domain.schema.json +320 -148
- package/skills/tech-lead/schemas/gate-answers.schema.json +2 -2
- package/skills/tech-lead/schemas/work-result.schema.json +55 -17
- package/skills/tech-lead/scripts/aegis-digest.mjs +1 -1
- package/skills/tech-lead/scripts/budget-check.mjs +7 -13
- package/skills/tech-lead/scripts/compile-order.mjs +69 -22
- package/skills/tech-lead/scripts/fit-check.mjs +10 -10
- package/skills/tech-lead/scripts/gate-answers.mjs +11 -12
- package/skills/tech-lead/scripts/hill-derive.mjs +133 -0
- package/skills/tech-lead/scripts/ingest-result.mjs +7 -19
- package/skills/tech-lead/scripts/init-run.mjs +60 -18
- package/skills/tech-lead/scripts/lib/argv.mjs +1 -1
- package/skills/tech-lead/scripts/lib/contract-md.mjs +10 -10
- package/skills/tech-lead/scripts/lib/is-main.mjs +11 -12
- package/skills/tech-lead/scripts/lib/paths.mjs +15 -13
- package/skills/tech-lead/scripts/resume-state.mjs +387 -0
- package/skills/tech-lead/scripts/run-snapshot.mjs +1 -6
- package/skills/tech-lead/scripts/run-workflow.mjs +381 -0
- package/skills/tech-lead/scripts/ship-report.mjs +33 -2
- package/skills/tech-lead/scripts/stats.mjs +9 -10
- package/skills/tech-lead/scripts/t0-verify.mjs +4 -4
- package/skills/tech-lead/scripts/trace-lint.mjs +2 -2
- package/skills/tech-lead/workflows/shapeup-run.js +911 -0
- package/skills/translator/SKILL.md +2 -2
- 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.
|
|
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
|
-
|
|
4
|
+
## Enforcement model
|
|
5
5
|
|
|
6
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
17
|
+
(The completed pitch is formed by `shaping.md` + `breadboard.md`)
|
|
53
18
|
|
|
54
19
|
### Phase 2 — Betting (PO governance, no skill)
|
|
55
|
-
|
|
20
|
+
Betting Table: PO decides; rejected pitches loop back to raw idea.
|
|
56
21
|
|
|
57
|
-
### Phase 3 — Building
|
|
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 |
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
|
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
|
-
|
|
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** —
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
-
|
|
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
|
-
|
|
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
|
|
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** —
|
|
95
|
-
- **QA is a level-up, not a gate** — `--no-qa`
|
|
96
|
-
- **Role separation** — Evaluator grades, task-executor fixes, QA discovers
|
|
97
|
-
- **
|
|
98
|
-
|
|
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
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
-
|
|
131
|
-
-
|
|
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
|
|
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
|
|
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
|
|
36
|
-
|
|
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
|
|
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
|
|
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
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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 Node — but 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.
|
|
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
|
|
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
|
|
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,
|
|
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.
|
|
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
|
-
|
|
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`
|
|
220
|
-
delegation
|
|
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
|
|
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
|
-
- **
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
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
|
|
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
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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/
|
|
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.
|
|
337
|
+
3. Tag and push: `git tag v1.7.0 && git push origin main --follow-tags`.
|
|
346
338
|
|
|
347
|
-
The
|
|
348
|
-
and publishes
|
|
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 **
|
|
4
|
-
|
|
5
|
-
|
|
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
|
|
29
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
61
|
-
commit it. There is no phone-home of
|
|
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/`,
|
|
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
|
|