shapeup-sdlc 1.6.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.example.json +5 -5
- package/.claude-plugin/plugin.json +1 -1
- package/AGENTS.md +54 -107
- package/README.md +165 -151
- package/SECURITY.md +49 -27
- package/bin/init.mjs +93 -108
- package/bin/lib/grant.mjs +145 -0
- package/commands/build.md +20 -0
- package/commands/eval.md +5 -4
- package/commands/scopes.md +5 -4
- package/commands/shape.md +1 -1
- package/commands/ship.md +53 -7
- package/commands/wire.md +1 -1
- package/hooks/dispatch-receipt.mjs +195 -0
- package/hooks/gate-intake.mjs +16 -17
- package/hooks/gate-zerowork.mjs +107 -25
- package/hooks/hooks.json +9 -48
- package/hooks/lib/decision.mjs +38 -19
- package/hooks/safety-spine.mjs +4 -4
- package/hooks/sandbox-guard.mjs +130 -50
- package/{skills/tech-lead/scripts/compile-order.mjs → kernel/compile.mjs} +344 -55
- package/{skills/tech-lead/scripts/gate-answers.mjs → kernel/gate.mjs} +69 -26
- package/kernel/harness.mjs +134 -0
- package/{skills/tech-lead/scripts/fit-check.mjs → kernel/init/fit.mjs} +25 -22
- package/kernel/init/run.mjs +489 -0
- package/{skills/tech-lead/scripts → kernel}/lib/argv.mjs +52 -31
- package/{skills/tech-lead/scripts/lib/contract-md.mjs → kernel/lib/contract.mjs} +261 -17
- package/kernel/lib/paths.mjs +491 -0
- package/kernel/probe/concurrency.mjs +510 -0
- package/{skills/tech-lead/scripts/aegis-digest.mjs → kernel/probe/digest.mjs} +10 -11
- package/kernel/probe/eval.mjs +77 -0
- package/kernel/probe/leg.mjs +125 -0
- package/kernel/probe/resume.mjs +528 -0
- package/{skills/tech-lead/scripts → kernel/probe}/stats.mjs +102 -21
- package/kernel/probe/t0.mjs +66 -0
- package/{skills/ba-pitch-analyzer/scripts/board-derive.mjs → kernel/reduce/board.mjs} +104 -28
- package/kernel/reduce/graph.mjs +437 -0
- package/kernel/reduce/hill.mjs +152 -0
- package/kernel/reduce/ingest.mjs +633 -0
- package/{hooks/slop-cleaner.mjs → kernel/reduce/leftovers.mjs} +40 -57
- package/{skills/tech-lead/scripts/ship-report.mjs → kernel/reduce/ship.mjs} +93 -14
- package/{skills/tech-lead/scripts/run-snapshot.mjs → kernel/reduce/snapshot.mjs} +22 -21
- package/{skills/spec-evaluator/scripts/verdict-ledger.mjs → kernel/reduce/verdict.mjs} +14 -8
- package/kernel/report/export.mjs +325 -0
- package/kernel/report/facts.mjs +347 -0
- package/{skills/tech-lead/scripts/budget-check.mjs → kernel/verify/budget.mjs} +22 -25
- package/kernel/verify/dispatch.mjs +114 -0
- package/{skills/tech-lead/scripts/validate-envelope.mjs → kernel/verify/envelope.mjs} +20 -15
- package/{skills/tech-lead/scripts/lib → kernel/verify}/ratchet-tree.mjs +36 -14
- package/kernel/verify/skills.mjs +125 -0
- package/kernel/verify/spec.mjs +559 -0
- package/{skills/tech-lead/scripts/t0-verify.mjs → kernel/verify/t0.mjs} +138 -28
- package/{skills/tech-lead/scripts/trace-lint.mjs → kernel/verify/trace.mjs} +28 -13
- package/oracles/_shared.mjs +1 -1
- package/oracles/http-oracle.mjs +2 -2
- package/oracles/index.mjs +1 -1
- package/oracles/process-oracle.mjs +2 -2
- package/oracles/snapshot-oracle.mjs +2 -2
- package/oracles/test-oracle.mjs +2 -2
- package/package.json +11 -13
- package/skills/ba-pitch-analyzer/SKILL.md +24 -19
- package/skills/ba-pitch-analyzer/assets/templates/_index.tmpl.md +1 -1
- package/skills/ba-pitch-analyzer/assets/templates/api-feasibility.tmpl.md +12 -7
- package/skills/ba-pitch-analyzer/assets/templates/contracts/third-party-api.contract.tmpl.md +6 -3
- package/skills/ba-pitch-analyzer/assets/templates/cross-context/migration-plan.tmpl.md +5 -4
- package/skills/ba-pitch-analyzer/assets/templates/cross-context/team-handoff.tmpl.md +23 -13
- package/skills/ba-pitch-analyzer/assets/templates/scope-summary.tmpl.md +17 -12
- package/skills/ba-pitch-analyzer/assets/templates/synthesis.tmpl.md +17 -38
- package/skills/ba-pitch-analyzer/assets/templates/task.tmpl.md +3 -0
- package/skills/ba-pitch-analyzer/references/contract-patterns.md +8 -4
- package/skills/ba-pitch-analyzer/references/doc-schemas.md +3 -1
- package/skills/ba-pitch-analyzer/references/task-generation.md +8 -8
- package/skills/ba-pitch-analyzer/references/test-surface.md +1 -1
- package/skills/coach/SKILL.md +3 -3
- package/skills/orient/SKILL.md +2 -1
- package/skills/qa-edge-hunter/SKILL.md +15 -41
- package/skills/scope-architect/SKILL.md +57 -18
- 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 +37 -15
- package/skills/spec-evaluator/SKILL.md +24 -7
- 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/task-executor/SKILL.md +32 -18
- package/skills/tech-lead/SKILL.md +127 -438
- package/skills/tech-lead/references/gates.md +140 -49
- package/skills/tech-lead/references/protocol.md +832 -0
- package/skills/tech-lead/schemas/domain.schema.json +645 -198
- package/skills/tech-lead/schemas/gate-answers.schema.json +2 -2
- package/skills/tech-lead/schemas/work-order.schema.json +11 -2
- package/skills/tech-lead/schemas/work-result.schema.json +56 -18
- package/skills/tech-lead/workflows/shapeup-run.js +1474 -0
- package/skills/translator/SKILL.md +2 -2
- package/hooks/anti-rationalization.mjs +0 -244
- package/hooks/compact-snapshot.mjs +0 -47
- package/hooks/gate-deadline.mjs +0 -151
- package/hooks/gate-l2.mjs +0 -161
- package/hooks/session-rehydrate.mjs +0 -109
- package/skills/advisor-protocol/SKILL.md +0 -171
- package/skills/ba-pitch-analyzer/scripts/spec-lint.mjs +0 -239
- package/skills/spec-evaluator/README.md +0 -93
- package/skills/tech-lead/README.md +0 -71
- package/skills/tech-lead/references/delegation.md +0 -254
- package/skills/tech-lead/references/invocation.md +0 -45
- package/skills/tech-lead/references/ledger-schema.md +0 -214
- package/skills/tech-lead/references/round-protocol.md +0 -184
- package/skills/tech-lead/references/state-model.md +0 -66
- package/skills/tech-lead/scripts/ingest-result.mjs +0 -270
- package/skills/tech-lead/scripts/init-run.mjs +0 -326
- package/skills/tech-lead/scripts/lib/is-main.mjs +0 -82
- package/skills/tech-lead/scripts/lib/paths.mjs +0 -278
- package/skills/translator/README.md +0 -66
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:
|
|
18
|
+
<img src="docs/assets/demo-gate.svg" alt="Terminal recording: a worker tries to edit a file outside the scope it was given, a PreToolUse hook denies the write and names the path, and the next edit inside the scope is permitted." width="700">
|
|
19
19
|
</p>
|
|
20
20
|
|
|
21
21
|
<p align="center"><sub>
|
|
22
|
-
The denial
|
|
22
|
+
The denial above is <b>verbatim stdout</b> from <code>hooks/sandbox-guard.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,52 +54,64 @@ 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
|
```
|
|
70
60
|
/plugin marketplace add nguyenvanphituoc/shapeup-sdlc-plugin
|
|
71
61
|
/plugin install shapeup-sdlc-plugin@nvptuoc-marketplace
|
|
72
|
-
/ship "add dark mode to the settings screen"
|
|
62
|
+
/shapeup-sdlc-plugin:ship "add dark mode to the settings screen"
|
|
73
63
|
```
|
|
74
64
|
|
|
75
|
-
|
|
65
|
+
That last one walks the whole lifecycle and pauses at each gate for you. That's the whole
|
|
66
|
+
quickstart.
|
|
67
|
+
|
|
68
|
+
> **The `shapeup-sdlc-plugin:` prefix is not optional.** A plugin's commands are namespaced by the
|
|
69
|
+
> plugin that ships them, so the bare `/ship` is not a command and answers `Unknown command: /ship`
|
|
70
|
+
> — measured on both a marketplace install and a `--plugin-dir` checkout. Interactively you will
|
|
71
|
+
> normally pick the command off `/`-completion and never type the prefix yourself; it matters when
|
|
72
|
+
> you are writing the command down, which is exactly what a headless `claude -p` invocation or a CI
|
|
73
|
+
> step does. **Everything below writes commands in the short form for readability — prepend
|
|
74
|
+
> `shapeup-sdlc-plugin:` to any of them you actually type.**
|
|
75
|
+
|
|
76
|
+
> **Running unattended?** The plugin install grants no permissions — every pipeline step is a Node
|
|
77
|
+
> script that ships *with* the plugin and therefore lives outside your project, so it needs
|
|
78
|
+
> approval. You click once interactively; headless there is nobody to click. Scaffold instead, which
|
|
79
|
+
> writes the grant:
|
|
80
|
+
>
|
|
81
|
+
> ```bash
|
|
82
|
+
> npx shapeup-sdlc init -d . -y
|
|
83
|
+
> ```
|
|
84
|
+
>
|
|
85
|
+
> **And lift the print-mode background ceiling, or the run is killed at ten minutes.** `claude -p`
|
|
86
|
+
> terminates a session's background tasks after 600 s by default, and the whole pipeline runs as
|
|
87
|
+
> one background launch — so an unattended run dies mid-BUILD with the CLI reporting nothing worse
|
|
88
|
+
> than "background tasks still running after 600s; terminating". Measured, on a run that had
|
|
89
|
+
> reached WIRE:
|
|
90
|
+
>
|
|
91
|
+
> ```bash
|
|
92
|
+
> CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0 claude -p "/shapeup-sdlc-plugin:ship …" …
|
|
93
|
+
> ```
|
|
94
|
+
>
|
|
95
|
+
> Nothing is lost when it happens — resume state is on disk, so relaunching fast-forwards past the
|
|
96
|
+
> phases that finished. It costs a relaunch, not a run.
|
|
76
97
|
|
|
77
98
|
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
|
|
99
|
+
walks one small feature end to end — including what the hooks do to a premature eval, a FAIL round
|
|
79
100
|
with real evaluator output, and the fix that turns it green.
|
|
80
101
|
|
|
81
102
|
<sub>No prerequisites for non-UI work — a browser (`npx playwright install chromium`) is needed
|
|
82
103
|
only when a run actually reaches a `[ui]` acceptance criterion. Team installs, the scaffolding
|
|
83
|
-
installer
|
|
104
|
+
installer, and troubleshooting are in
|
|
84
105
|
**[docs/install.md](docs/install.md)**; upgrading is **[docs/upgrading.md](docs/upgrading.md)**.</sub>
|
|
85
106
|
|
|
86
107
|
## Agent support
|
|
87
108
|
|
|
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.
|
|
109
|
+
The harness targets **Claude Code only**. The reason is the row that never travelled when we
|
|
110
|
+
compiled to other CLIs: hooks. The 12 skills, 10 slash commands and the kernel are
|
|
111
|
+
portable prose and plain Node — but hook-enforced gates (envelope validation, substrate
|
|
112
|
+
sandbox, safety spine, the zero-work block) are a per-CLI mechanism, and without them every gate degrades from
|
|
113
|
+
**enforced** to **instructed** — the same honor system every other framework runs on
|
|
114
|
+
everywhere. If the deny hooks are why you're here, that means Claude Code.
|
|
103
115
|
|
|
104
116
|
## Glossary
|
|
105
117
|
|
|
@@ -108,15 +120,15 @@ rest of this README after this table and nothing will be a surprise.
|
|
|
108
120
|
|
|
109
121
|
| Term | In plain English |
|
|
110
122
|
|---|---|
|
|
111
|
-
| **board** | The round's task list. "Green" means every task is done.
|
|
123
|
+
| **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
124
|
| **round** | One build → evaluate cycle. A FAIL verdict starts round *r+1*. |
|
|
113
125
|
| **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
126
|
| **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
|
|
127
|
+
| **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
128
|
| **scope contract** | The file defining one vertical slice: its substrate, its fixtures, its affordances. |
|
|
117
129
|
| **affordance** | The thing a user can actually click, type or call. UI is graded on affordances, not on looks. |
|
|
118
130
|
| **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
|
|
131
|
+
| **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
132
|
| **covers-closure** | Every requirement clause has at least one task claiming to cover it. Nothing silently drops. |
|
|
121
133
|
| **wiring reachability** | Every engine has a call site reachable from the app's real entry point. Catches "built, but never wired up". |
|
|
122
134
|
| **discovery ledger** | The one file everything found mid-run gets written to, so nothing is lost between rounds. |
|
|
@@ -128,37 +140,24 @@ A longer version, including the internals, is in [docs/glossary.md](docs/glossar
|
|
|
128
140
|
The harness walks a pitch from idea to ship. The full annotated pipeline — the build round,
|
|
129
141
|
the gate walkthrough, the circuit breaker — is
|
|
130
142
|
[`docs/design/04-functional-design.md`](docs/design/04-functional-design.md), and the design
|
|
131
|
-
document as a whole starts at [`docs/design/`](docs/design/README.md).
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
EVAL -- FAIL --> BUILD
|
|
144
|
-
EVAL -- PASS --> QA["Edge Hunt<br>/qa-edge-hunter"]
|
|
145
|
-
QA --> SHIP["Triage + Ship<br>/scope-hammer"]
|
|
146
|
-
SHIP --> RETRO["Coach Retro<br>/coach"]
|
|
147
|
-
TL["/tech-lead orchestrates Orient → Ship"] -.-> KO
|
|
148
|
-
|
|
149
|
-
classDef plan fill:#e3f2fd,stroke:#1e88e5;
|
|
150
|
-
classDef build fill:#e8f5e9,stroke:#43a047;
|
|
151
|
-
classDef qa fill:#fce4ec,stroke:#c2185b;
|
|
152
|
-
class S,WIRE,MAP plan;
|
|
153
|
-
class KO,BUILD build;
|
|
154
|
-
class QA,EVAL qa;
|
|
155
|
-
```
|
|
143
|
+
document as a whole starts at [`docs/design/`](docs/design/README.md). This diagram shows the
|
|
144
|
+
full phase and gate mechanism — simpler than that per-attempt detail, but the whole pipeline:
|
|
145
|
+
|
|
146
|
+
<p align="center">
|
|
147
|
+
<img src="docs/assets/workflow-mechanism.svg" alt="The shapeup-sdlc harness pipeline from raw idea to Coach Retro: Shaping produces a Pitch, the Betting Table bets into the tech-lead-orchestrated run or rejects back to raw idea, Kick-off through Ship Sign-off cross gates L0, L1a, L1a.5, L1b, advisory L2, L3, GATE H and L4, the Build/Evaluate round loops on FAIL, and a circuit breaker routes straight to GATE H — bypassing QA — when the round or wall-clock budget runs out." width="900">
|
|
148
|
+
</p>
|
|
149
|
+
|
|
150
|
+
<p align="center"><sub>
|
|
151
|
+
Plan-phase skills in blue, build-phase in green, QA-phase in pink; amber pills are gates —
|
|
152
|
+
the outlined <b>L2</b> is advisory, the rest block. The dashed region marks what
|
|
153
|
+
<code>/tech-lead</code> orchestrates end to end.
|
|
154
|
+
</sub></p>
|
|
156
155
|
|
|
157
156
|
Since v1.3 the pipeline carries a **traceability spine**: `ba-pitch-analyzer`'s `coverage`
|
|
158
157
|
operation writes a requirement registry (`requirements.md`), `solution-architect` commits a
|
|
159
158
|
per-use-case wiring map (`wiring-map.md`, gate L1a.5) resolved against the L0
|
|
160
159
|
`project-profile.md`, and the covers-closure + reachability oracle
|
|
161
|
-
`
|
|
160
|
+
`kernel/verify/trace.mjs` checks that no engine ships orphaned. It runs
|
|
162
161
|
advisory (warn-only) and is promoted to a blocking gate only once `covers:` is populated;
|
|
163
162
|
every arm is skipped when its artifact is absent, so older specs are unaffected.
|
|
164
163
|
|
|
@@ -171,13 +170,12 @@ every arm is skipped when its artifact is absent, so older specs are unaffected.
|
|
|
171
170
|
| Shaping (1–4) | `shapeup` | — | Frame the problem, breadboard affordances, spike risks, write the pitch. Sub-commands: `full`, `shaping`, `spike`, `breadboarding`, `framing-doc`, `kickoff-doc`, `breadboard-reflection`. |
|
|
172
171
|
| Intake (GATE L0) | `translator` | — | Normalizes non-English intake (pitch/PRD/transcript) to faithful English before planning. The harness is English-only downstream. |
|
|
173
172
|
| 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
|
-
| 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
|
|
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.
|
|
173
|
+
| Wire (GATE L1a.5) | `solution-architect` | v1.1 | Sole writer of the committed wiring map (`wiring-map.md`): per-UC engine → integration seam → entry-point call site → player-visible affordance, resolved against `project-profile.md`. Front-loads the integration seam so no engine ships orphaned; the reachability input `harness verify trace` checks. Operation: wire. |
|
|
174
|
+
| Map Scopes (8) | `ba-pitch-analyzer` | v4.0 | The spec-analyzer (pure worker). Decomposes a pitch into a linked DDD document tree (domain model → use cases → tasks) with BDD scenarios, a UC system flow, and a derived `## Test Surface`. One craft, four order-selected operations (analyze / reconcile / retrofit-surface / coverage — the last writes the shared `requirements.md` registry for covers-closure); graph math + audits delegated to `harness reduce board`/`harness verify spec`. |
|
|
175
|
+
| 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
176
|
| 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
177
|
| 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
178
|
| 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
179
|
| 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
180
|
| 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
181
|
| 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. |
|
|
@@ -185,7 +183,8 @@ every arm is skipped when its artifact is absent, so older specs are unaffected.
|
|
|
185
183
|
### Commands
|
|
186
184
|
|
|
187
185
|
`/ship` runs the whole lifecycle; the phase commands run one step each, so the pipeline is
|
|
188
|
-
learnable from `/`-completion alone.
|
|
186
|
+
learnable from `/`-completion alone. Names are written short here; the real name of each carries the
|
|
187
|
+
`shapeup-sdlc-plugin:` prefix, which `/`-completion fills in for you and a script must spell out.
|
|
189
188
|
|
|
190
189
|
| Command | Phase | Description |
|
|
191
190
|
|---------|-------|-------------|
|
|
@@ -200,58 +199,71 @@ learnable from `/`-completion alone.
|
|
|
200
199
|
| `/hammer` | H | Must-have census, baseline comparison, cut list + ship verdict. |
|
|
201
200
|
| `/retro` | post-L4 | File ship-gate feedback into the per-skill knowledge base. |
|
|
202
201
|
|
|
203
|
-
###
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
202
|
+
### What is enforced, and by what
|
|
203
|
+
|
|
204
|
+
The honest version of this table matters more than a long one. A guarantee is only as strong as
|
|
205
|
+
the layer that carries it, and the three layers here fail differently:
|
|
206
|
+
|
|
207
|
+
| Layer | Works when | Fails how |
|
|
208
|
+
|---|---|---|
|
|
209
|
+
| **Wall** — a hook | Under every permission mode, including `bypassPermissions`. The CLI runs it; the model cannot decline it. | Fail-OPEN on anything ambiguous, and every evaluation writes a decision row, so "permitted" never looks like "never ran". |
|
|
210
|
+
| **Runtime** — the kernel and the run script | When the run goes through the harness. A schema rejection or a non-zero exit stops the step. | A lane that never calls the kernel is never checked — which is why the hooks below cover the doors, not the steps. |
|
|
211
|
+
| **Advisory** — a report section | When somebody reads the artifact. | Silently, if nobody does. It is a cleanup list, never a verdict. |
|
|
212
|
+
|
|
213
|
+
**Four walls.** These are hooks because nothing in the runtime can substitute for them:
|
|
214
|
+
|
|
215
|
+
- `PreToolUse` (`Skill`) — **`hooks/gate-intake.mjs` denies a `tech-lead` dispatch that carries no
|
|
216
|
+
pitch, no spec folder, and no requirement text.** Observed, not theorized: when the requirement
|
|
217
|
+
text is dropped on the hand-off and only a flag survives, the run prints the gate list, builds
|
|
218
|
+
nothing, and reads like a success while leaving every defect in the deliverable.
|
|
219
|
+
- `PreToolUse` (`Skill|Agent`) — **`harness verify envelope` denies any worker dispatch whose order
|
|
220
|
+
file is missing or fails the WorkOrder schema.** A malformed envelope never reaches a worker.
|
|
221
|
+
- `PreToolUse` (`Edit|Write|MultiEdit`) — **`hooks/sandbox-guard.mjs` blocks a write that no LIVE
|
|
222
|
+
order's substrate permits.** It reads every compiled-but-not-yet-ingested order rather than a
|
|
223
|
+
pointer to one, so scopes building concurrently are each held to their own contract; `frozen`
|
|
224
|
+
outranks everything, across all of them.
|
|
225
|
+
- `PreToolUse` (`Bash|Read|Write|Edit|MultiEdit`) — **`hooks/safety-spine.mjs` denies destructive
|
|
226
|
+
commands** (`rm -rf` on unrecoverable targets, force-push/push-to-main, `git reset --hard`,
|
|
227
|
+
`DROP TABLE`) and secret-file reads. A machine guard, not a pipeline guard; the escape hatch is
|
|
228
|
+
the human-authored `.shapeup/safety-overrides.json`.
|
|
229
|
+
|
|
230
|
+
**One recorder**, which denies nothing and is what makes a wall possible one layer down:
|
|
231
|
+
|
|
232
|
+
- `PostToolUse` (`Skill|Agent`) — **`hooks/dispatch-receipt.mjs` writes down which skill actually
|
|
233
|
+
ran.** Until it existed, a dispatch that failed — plugin absent, disabled, or a different version
|
|
234
|
+
loaded — was indistinguishable from one that succeeded: the sub-agent would do the craft itself
|
|
235
|
+
from the prose in its own prompt, the artifacts landed in exactly the place the order permitted, so
|
|
236
|
+
the order gate and the sandbox guard both passed and the run advanced having applied none of the
|
|
237
|
+
shipped craft. A green run was consistent with zero worker craft. The hook appends
|
|
238
|
+
`{order_id, worker_declared, skill_invoked, dispatch_ok, at}` to `.shapeup/<slug>/receipts/`, and
|
|
239
|
+
`harness reduce ingest` refuses an orchestrated result with no matching receipt. A failed dispatch
|
|
240
|
+
never reaches `PostToolUse` at all, so the receipt's *existence* is the evidence. It has no deny
|
|
241
|
+
path, every write is guarded, and `--no-receipt-check` is the documented way through when the
|
|
242
|
+
channel itself fails.
|
|
243
|
+
|
|
244
|
+
**One blocking Stop hook**, and it is the narrowest thing in the repo:
|
|
245
|
+
|
|
246
|
+
- `Stop` — **`hooks/gate-zerowork.mjs` blocks a session that dispatched the orchestrator and left
|
|
247
|
+
no run receipt.** Its predicate is mechanical — orchestrator dispatched AND no
|
|
248
|
+
`.shapeup/<slug>/receipt.json` — so it never judges quality; it reports that no work exists to
|
|
249
|
+
judge. It exists because this harness was repeatedly observed describing its own pipeline instead
|
|
250
|
+
of running it: a narrated run that reads like a clean success. Fails open on everything
|
|
251
|
+
ambiguous, and `stop_hook_active` caps it at one block per stop chain.
|
|
252
|
+
|
|
253
|
+
**What the runtime carries instead** (v2.0 retired six hooks whose work moved here):
|
|
254
|
+
|
|
255
|
+
| Was a hook | Is now | What changed |
|
|
256
|
+
|---|---|---|
|
|
257
|
+
| `gate-l2` (EVAL over an unfinished board) | The GATE L2 block, which names `green_scopes` and `hammer_proposals` | It was advisory either way; now the same facts reach the human who answers the gate rather than a warning line above it. |
|
|
258
|
+
| `gate-deadline` (deny builds past the wall clock) | `harness verify budget --strict`, checked at every round boundary | **A real coverage change, stated rather than hidden:** the round loop stops the run from opening ANOTHER round, but no longer interrupts a single build leg that runs long. `attempt_budget` bounds that leg by attempts instead. |
|
|
259
|
+
| `session-rehydrate` + `compact-snapshot` | `harness reduce graph --slug <slug> --subgraph run` | A hook fired at two moments the platform chose; a command answers whenever the question is asked, including the moments a hook never saw. |
|
|
260
|
+
| `anti-rationalization` (claims the facts contradict) | The ship report's census, derived from the board and the T0 artifacts | The facts are in an artifact a teammate finds on `git pull`, not in a transcript nobody re-reads. |
|
|
261
|
+
| `slop-cleaner` (TODO/`console.log` leftovers) | The ship report's **Leftovers** section | Same scan, same added-lines-only rule; it lands somewhere checkable. |
|
|
262
|
+
|
|
263
|
+
**Nothing load-bearing depends on permission mode.** The four walls plus the zero-work gate run
|
|
264
|
+
under every mode. The kernel needs a grant to be *invoked* — two Bash lines `npx shapeup-sdlc init`
|
|
265
|
+
writes — but a session that never gets that grant is a session that cannot run the pipeline at all,
|
|
266
|
+
not one that runs it unguarded.
|
|
255
267
|
|
|
256
268
|
No hook makes a network request, none has dependencies, and all are plain, readable `.mjs`
|
|
257
269
|
files. **[SECURITY.md](SECURITY.md)** states what each hook reads, what it can deny, and what
|
|
@@ -278,8 +290,8 @@ These hold across the harness and are the reason it stays predictable:
|
|
|
278
290
|
- **Hill phase is mechanical, never self-reported** — derived only from T0/T1/seesaw facts, closing
|
|
279
291
|
the self-reported-confidence risk outright.
|
|
280
292
|
- **One writer per shared file** — every board/ledger/verdict write goes through
|
|
281
|
-
`ingest
|
|
282
|
-
- **Traceability is oracle-checked, opt-in** — `trace
|
|
293
|
+
`harness reduce ingest`; workers return data and never touch shared state.
|
|
294
|
+
- **Traceability is oracle-checked, opt-in** — `harness verify trace` verifies covers-closure and
|
|
283
295
|
wiring reachability from the committed spine artifacts; it ships advisory (warn-only) and every
|
|
284
296
|
arm is skipped when its artifact is absent, so older specs are non-regressed.
|
|
285
297
|
|
|
@@ -289,14 +301,13 @@ Stated plainly, because you will hit them:
|
|
|
289
301
|
|
|
290
302
|
- **The `--tiny` lane is young.** It right-sizes the ceremony (two gates instead of eight) but
|
|
291
303
|
keeps the T0 verification floor; its fit-check heuristics will need tuning against real use.
|
|
292
|
-
- **
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
fabricated results appear, and three earlier baselines were discarded rather than published.
|
|
304
|
+
- **Nothing here measures skill quality or activation.** There is no number for whether a
|
|
305
|
+
skill's description makes it fire on the right request, no measured craft delta, and no CI
|
|
306
|
+
check enforcing the honesty invariant on such numbers. The structural suite is the coverage
|
|
307
|
+
that exists, and it is about mechanism rather than quality — it proves a gate denies and an
|
|
308
|
+
oracle discriminates, never that a skill's output is good.
|
|
309
|
+
- **The gates are verified; the craft is not.** A hook that denies is proven by a test that
|
|
310
|
+
watches it deny. A skill that writes a good spec tree is, at present, taken on trust.
|
|
300
311
|
|
|
301
312
|
Contributions to any of these are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
302
313
|
|
|
@@ -315,37 +326,40 @@ claude --plugin-dir . # load this working copy without installing
|
|
|
315
326
|
.claude-plugin/
|
|
316
327
|
plugin.json # plugin manifest
|
|
317
328
|
marketplace.json # marketplace listing (points at this repo)
|
|
318
|
-
skills/<name>/SKILL.md # the
|
|
319
|
-
skills/tech-lead/
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
skills/spec-evaluator/scripts/ # verdict-ledger (reference impl of the flip/confidence grammar)
|
|
329
|
+
skills/<name>/SKILL.md # the 12 harness skills (+ references/ and assets/)
|
|
330
|
+
skills/tech-lead/schemas/ # the envelope port: WorkOrder, WorkResult, domain registry
|
|
331
|
+
skills/tech-lead/workflows/shapeup-run.js # the BUILD-phase pipeline, on the native Workflow runtime
|
|
332
|
+
kernel/harness.mjs # ONE entry point for every deterministic step; the whole permission grant
|
|
333
|
+
kernel/{verify,reduce,probe,init,report}/ # its subcommands, plus compile and gate at the root
|
|
334
|
+
kernel/lib/ # argv (the typed CLI boundary), paths (+ the run key), contract (shape)
|
|
325
335
|
commands/*.md # slash commands (/ship + the 9 phase commands)
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
#
|
|
329
|
-
#
|
|
330
|
-
|
|
336
|
+
hooks/ # hooks.json + the four walls: safety-spine, gate-intake, sandbox-guard
|
|
337
|
+
# (PreToolUse) + gate-zerowork (Stop, the one blocking hook)
|
|
338
|
+
# + dispatch-receipt (PostToolUse, denies nothing, attests which skill ran)
|
|
339
|
+
# + lib/decision.mjs (every hook records allow / deny / error)
|
|
340
|
+
oracles/ # the evaluation-contract oracle registry (test · snapshot · http · process)
|
|
341
|
+
bin/init.mjs # `npx shapeup-sdlc init` — scaffolds all three CLI targets
|
|
331
342
|
scripts/install-harness.sh, migrate.sh # stable public entrypoints (fresh install / update)
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
343
|
+
scripts/shapeup-sdlc/lib/ # shell libs both entrypoints source
|
|
344
|
+
tools/ # repo-only: demo/
|
|
345
|
+
# demo/record-demo.mjs (regenerates docs/assets/demo-gate.svg)
|
|
346
|
+
tests/structural.mjs, tests/structural/*.mjs # Tier 0 — 880+ checks, zero LLM calls
|
|
335
347
|
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
|
|
348
|
+
docs/design/ # the design document (pipeline, gates, circuit breaker, ERD) + adr/
|
|
349
|
+
docs/visualize/ # rendered views of the tree and the pipeline
|
|
350
|
+
.github/workflows/ # CI + release (release publishes to npm via OIDC)
|
|
339
351
|
```
|
|
340
352
|
|
|
341
353
|
## Release
|
|
342
354
|
|
|
343
|
-
1. Bump `version` in `.claude-plugin/plugin.json
|
|
355
|
+
1. Bump `version` in **both** `.claude-plugin/plugin.json` and `package.json` — the release
|
|
356
|
+
workflow fails if either disagrees with the tag.
|
|
344
357
|
2. Update `CHANGELOG.md`.
|
|
345
|
-
3. Tag and push: `git tag v1.
|
|
358
|
+
3. Tag and push: `git tag v1.7.0 && git push origin main --follow-tags`.
|
|
346
359
|
|
|
347
|
-
The
|
|
348
|
-
and publishes
|
|
360
|
+
The workflow validates the plugin, checks the tag against both manifests, publishes a GitHub
|
|
361
|
+
release, and publishes to npm through **trusted publishing (OIDC)** — no `NPM_TOKEN`, no OTP, with
|
|
362
|
+
a SLSA provenance attestation attached automatically.
|
|
349
363
|
|
|
350
364
|
## Credits
|
|
351
365
|
|
package/SECURITY.md
CHANGED
|
@@ -1,38 +1,61 @@
|
|
|
1
1
|
# Security
|
|
2
2
|
|
|
3
|
-
This plugin installs **
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
This plugin installs **seven hook entries (six Node scripts + one `echo`)**: four in a
|
|
4
|
+
`PreToolUse` position, **all four of which can deny a tool call**, one `PostToolUse` hook that has no
|
|
5
|
+
deny path at all, and one `Stop`-position hook that can block a session from ending. That is the
|
|
6
|
+
product — and it is also exactly the kind of surface a careful reviewer should want spelled out
|
|
7
|
+
before installing. This page is that spelling-out.
|
|
8
|
+
|
|
9
|
+
Count them yourself rather than taking the paragraph's word for it, because this paragraph has been
|
|
10
|
+
wrong before — it described a twelve-entry surface for the whole life of v2.0, after the hook diet cut
|
|
11
|
+
it to four walls and updated the table below without updating the sentence above it:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
node -e "const h=require('./hooks/hooks.json').hooks;
|
|
15
|
+
for (const [e,gs] of Object.entries(h)) for (const g of gs) for (const x of g.hooks)
|
|
16
|
+
console.log(e, g.matcher||'*', x.command.match(/[^/ ]+\.mjs/)?.[0] ?? '(echo)')"
|
|
17
|
+
```
|
|
7
18
|
|
|
8
19
|
## Reporting a vulnerability
|
|
9
20
|
|
|
10
21
|
Use [GitHub private vulnerability reporting](https://github.com/nguyenvanphituoc/shapeup-sdlc-plugin/security/advisories/new)
|
|
11
|
-
for anything exploitable — especially anything that would let a run **escape a deny** (
|
|
12
|
-
|
|
22
|
+
for anything exploitable — especially anything that would let a run **escape a deny** (write
|
|
23
|
+
outside a substrate, dispatch on an uncompiled order, widen its own safety overrides) or
|
|
24
|
+
exfiltrate data.
|
|
13
25
|
For non-sensitive hardening ideas, an ordinary issue is fine.
|
|
14
26
|
|
|
15
|
-
In scope: the hooks, the
|
|
16
|
-
|
|
17
|
-
|
|
27
|
+
In scope: the hooks, the kernel (`kernel/harness.mjs` and every subcommand beneath it), the
|
|
28
|
+
installer/migration shell scripts, and any prompt-injection path through skill files. Please do not
|
|
29
|
+
test against machines you don't own.
|
|
18
30
|
|
|
19
31
|
## The claims, stated so they can be falsified
|
|
20
32
|
|
|
21
|
-
1. **No hook or
|
|
33
|
+
1. **No hook or kernel subcommand makes a network request.** There is no `fetch`, no
|
|
22
34
|
`node:http(s)`, no `node:net`, no shelling out to `curl`/`wget` anywhere in `hooks/` or
|
|
23
|
-
`
|
|
35
|
+
`kernel/`. Verify: `grep -rnE "fetch|node:http|node:net|curl|wget" hooks/ kernel/`.
|
|
24
36
|
2. **No hook has dependencies.** Plain `.mjs`, Node standard library only, no `node_modules`,
|
|
25
37
|
no install-time scripts. What you read is what runs.
|
|
26
38
|
3. **Every hook is fail-open by design.** Unparseable input, missing state files, or an
|
|
27
39
|
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
|
-
|
|
40
|
+
hook denies only when it can positively prove its condition (a matched destructive command, a
|
|
41
|
+
path no live order's substrate permits, an invalid order file, an empty intake).
|
|
30
42
|
4. **The model cannot widen its own safety envelope.** The escape hatch
|
|
31
43
|
(`.shapeup/safety-overrides.json`) is human-authored; `safety-spine` itself denies any
|
|
32
44
|
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
|
-
|
|
45
|
+
(override channel fails closed), and every exercised override is logged. The same principle
|
|
46
|
+
covers `.shapeup/active-order`, which `sandbox-guard` reads to find the run whose orders fence
|
|
47
|
+
a worker's writes: it sits outside the run-trace carve-out, so a worker cannot repoint its own
|
|
48
|
+
sandbox.
|
|
49
|
+
5. **Exactly one hook can block, and only on a mechanical absence.** `gate-zerowork` returns
|
|
50
|
+
`decision: "block"` in one state: the session dispatched the orchestrator and left no run
|
|
51
|
+
receipt on disk. It makes no judgement about quality — it reports that there is no work to
|
|
52
|
+
judge. `stop_hook_active` caps it at one block per stop chain. Every other check that used to
|
|
53
|
+
emit an advisory `systemMessage` at `Stop` now lands in the ship report instead, where it is a
|
|
54
|
+
section a person can read afterwards rather than a line in a transcript.
|
|
55
|
+
6. **Every hook decision is recorded.** `hooks/lib/decision.mjs` is the only exit path a hook
|
|
56
|
+
has, so allow, deny, block and error each leave a row in `.shapeup/decisions.jsonl`. An
|
|
57
|
+
inert hook and a permitting hook are therefore distinguishable — which matters, because
|
|
58
|
+
"exit 0, no output" is what both used to look like.
|
|
36
59
|
|
|
37
60
|
If you find any of these to be false, that is a vulnerability — report it as claim #ⁿ.
|
|
38
61
|
|
|
@@ -44,25 +67,24 @@ sitting, and reading them is the recommended review.
|
|
|
44
67
|
| Hook | Event (matcher) | Reads | Can deny | Never does |
|
|
45
68
|
|---|---|---|---|---|
|
|
46
69
|
| [`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-
|
|
48
|
-
| [`
|
|
49
|
-
| [`sandbox-guard.mjs`](hooks/sandbox-guard.mjs) | PreToolUse (`Edit\|Write\|MultiEdit`) | The target path; the
|
|
50
|
-
| [`
|
|
51
|
-
| [`
|
|
52
|
-
| [`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 |
|
|
70
|
+
| [`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 |
|
|
71
|
+
| [`harness verify envelope`](kernel/verify/envelope.mjs) | PreToolUse (`Skill\|Agent`) | The `--order` file named in the dispatch; the JSON schemas | Yes — a worker dispatch whose order file is missing or schema-invalid | Never gates a dispatch that carries no `--order` (standalone skill use stays free) |
|
|
72
|
+
| [`sandbox-guard.mjs`](hooks/sandbox-guard.mjs) | PreToolUse (`Edit\|Write\|MultiEdit`) | The target path; the `substrate` block of every LIVE order (compiled, not yet ingested) | Yes — any write no live order permits: outside every `allowed`/`shared`, inside any `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 |
|
|
73
|
+
| [`dispatch-receipt.mjs`](hooks/dispatch-receipt.mjs) | PostToolUse (`Skill\|Agent`) | The `--order` file named in the dispatch; the tool result's own report of which skill ran | **No — it has no deny path at all.** It records that the shipped skill ran, so `harness reduce ingest` can refuse a result no dispatch produced | Never writes an attestation for a result that does not name a resolved skill; never fails the call it observes (every write is inside `try`/`catch`) |
|
|
74
|
+
| [`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 |
|
|
54
75
|
|
|
55
|
-
(The
|
|
76
|
+
(The remaining `hooks.json` entry is a plain `echo` on SessionStart confirming the plugin loaded.)
|
|
56
77
|
|
|
57
78
|
## Data handling
|
|
58
79
|
|
|
59
80
|
- **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
|
|
81
|
+
is a per-machine JSONL shard under `.shapeup/metrics/`, inside that same gitignored root,
|
|
82
|
+
so it travels only if you deliberately un-ignore and commit it. There is no phone-home of
|
|
83
|
+
any kind.
|
|
62
84
|
- **The safety-spine actively blocks secret reads** (`.env`, `*.pem`, `*.key`, ssh/cloud
|
|
63
85
|
credentials) rather than merely not making them.
|
|
64
86
|
- The installer (`scripts/install-harness.sh`) writes only into the target project
|
|
65
|
-
(`.claude/`,
|
|
87
|
+
(`.claude/`, `shapeup/`, `.gitignore`) and tells you what it
|
|
66
88
|
is going to do first; the `curl | bash` form requires an explicit `--yes` for exactly that
|
|
67
89
|
reason.
|
|
68
90
|
|