shapeup-sdlc 3.18.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/.claude/settings.local.example.json +2 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/AGENTS.md +115 -56
  4. package/README.md +101 -143
  5. package/SECURITY.md +16 -25
  6. package/agents/orient.md +14 -0
  7. package/agents/qa-edge-hunter.md +13 -0
  8. package/agents/spec-evaluator.md +14 -0
  9. package/agents/task-executor.md +14 -0
  10. package/bin/init.mjs +13 -16
  11. package/bin/lib/grant.mjs +8 -19
  12. package/commands/build.md +9 -14
  13. package/commands/eval.md +3 -3
  14. package/commands/hammer.md +9 -5
  15. package/commands/retro.md +12 -11
  16. package/commands/scopes.md +1 -12
  17. package/commands/ship.md +45 -88
  18. package/commands/wire.md +1 -8
  19. package/hooks/dispatch-receipt.mjs +94 -8
  20. package/hooks/hooks.json +0 -41
  21. package/hooks/lib/decision.mjs +6 -9
  22. package/hooks/lib/tier.mjs +50 -0
  23. package/hooks/sandbox-guard.mjs +140 -64
  24. package/kernel/gate.mjs +203 -22
  25. package/kernel/harness.mjs +20 -67
  26. package/kernel/init/run.mjs +175 -523
  27. package/kernel/lib/contract.mjs +9 -93
  28. package/kernel/lib/floor.mjs +64 -0
  29. package/kernel/lib/paths.mjs +39 -112
  30. package/kernel/order.mjs +157 -0
  31. package/kernel/probe/digest.mjs +2 -38
  32. package/kernel/schemas/domain.schema.json +146 -1125
  33. package/kernel/schemas/work-order.schema.json +8 -4
  34. package/kernel/schemas/work-result.schema.json +1 -1
  35. package/kernel/verify/envelope.mjs +2 -2
  36. package/kernel/verify/skills.mjs +27 -8
  37. package/kernel/verify/t0.mjs +2 -2
  38. package/package.json +4 -2
  39. package/skills/building/SKILL.md +144 -0
  40. package/skills/building/resources/gates.md +76 -0
  41. package/skills/building/resources/guidance.md +23 -0
  42. package/skills/{translator/references/preservation-rules.md → building/resources/intake-preservation.md} +1 -1
  43. package/skills/building/resources/intake.md +157 -0
  44. package/skills/building/resources/orders.md +69 -0
  45. package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/doc-schemas.md +1 -1
  46. package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/task-generation.md +13 -13
  47. package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/test-surface.md +6 -7
  48. package/skills/building/resources/plan-scopes.md +95 -0
  49. package/skills/building/resources/plan-spec.md +102 -0
  50. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/_index.tmpl.md +1 -1
  51. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/assess-report.tmpl.md +10 -11
  52. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/run-state.tmpl.md +4 -4
  53. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/scope-summary.tmpl.md +2 -2
  54. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/synthesis.tmpl.md +4 -4
  55. package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/usecase.tmpl.md +2 -2
  56. package/skills/building/resources/plan-wire.md +82 -0
  57. package/skills/building/resources/plan.md +98 -0
  58. package/skills/building/resources/retro-research.md +60 -0
  59. package/skills/building/resources/retro-scan.md +49 -0
  60. package/skills/building/resources/retro.md +225 -0
  61. package/skills/building/resources/rounds.md +78 -0
  62. package/skills/building/resources/stop.md +127 -0
  63. package/skills/orient/SKILL.md +37 -37
  64. package/skills/qa-edge-hunter/SKILL.md +14 -14
  65. package/skills/shapeup/SKILL.md +5 -5
  66. package/skills/shapeup/resources/breadboarding.md +1 -1
  67. package/skills/shapeup/resources/context-compaction.md +5 -5
  68. package/skills/shapeup/resources/shaping.md +1 -1
  69. package/skills/spec-evaluator/SKILL.md +17 -21
  70. package/skills/spec-evaluator/references/dimension-contract.md +1 -1
  71. package/skills/spec-evaluator/references/dimensions/completeness.md +3 -3
  72. package/skills/spec-evaluator/references/dimensions/spec-conformance.md +1 -1
  73. package/skills/spec-evaluator/references/dimensions/test-surface-conformance.md +5 -5
  74. package/skills/task-executor/SKILL.md +11 -15
  75. package/commands/hill.md +0 -10
  76. package/hooks/gate-intake.mjs +0 -109
  77. package/hooks/gate-zerowork.mjs +0 -349
  78. package/hooks/tier-guard.mjs +0 -162
  79. package/kernel/compile.mjs +0 -1419
  80. package/kernel/init/fit.mjs +0 -199
  81. package/kernel/init/run-args.mjs +0 -206
  82. package/kernel/lib/breadboard.mjs +0 -165
  83. package/kernel/probe/attempts.mjs +0 -161
  84. package/kernel/probe/concurrency.mjs +0 -535
  85. package/kernel/probe/eval.mjs +0 -405
  86. package/kernel/probe/hunt.mjs +0 -104
  87. package/kernel/probe/leg.mjs +0 -229
  88. package/kernel/probe/owner.mjs +0 -142
  89. package/kernel/probe/requirements.mjs +0 -328
  90. package/kernel/probe/resume.mjs +0 -1110
  91. package/kernel/probe/rounds.mjs +0 -115
  92. package/kernel/probe/staged.mjs +0 -83
  93. package/kernel/probe/stats.mjs +0 -477
  94. package/kernel/probe/t0.mjs +0 -115
  95. package/kernel/reduce/board.mjs +0 -350
  96. package/kernel/reduce/graph.mjs +0 -482
  97. package/kernel/reduce/hill.mjs +0 -322
  98. package/kernel/reduce/ingest.mjs +0 -767
  99. package/kernel/reduce/leftovers.mjs +0 -159
  100. package/kernel/reduce/ship.mjs +0 -529
  101. package/kernel/reduce/snapshot.mjs +0 -291
  102. package/kernel/reduce/verdict.mjs +0 -172
  103. package/kernel/report/export.mjs +0 -384
  104. package/kernel/report/facts.mjs +0 -234
  105. package/kernel/verify/budget.mjs +0 -153
  106. package/kernel/verify/build.mjs +0 -428
  107. package/kernel/verify/dispatch.mjs +0 -114
  108. package/kernel/verify/spec.mjs +0 -975
  109. package/kernel/verify/trace.mjs +0 -604
  110. package/skills/ba-pitch-analyzer/SKILL.md +0 -204
  111. package/skills/coach/SKILL.md +0 -397
  112. package/skills/hill-chart/SKILL.md +0 -154
  113. package/skills/hill-chart/assets/dashboard.template.html +0 -1432
  114. package/skills/scope-architect/SKILL.md +0 -174
  115. package/skills/scope-hammer/SKILL.md +0 -231
  116. package/skills/solution-architect/SKILL.md +0 -158
  117. package/skills/tech-lead/SKILL.md +0 -151
  118. package/skills/tech-lead/references/gates.md +0 -605
  119. package/skills/tech-lead/references/protocol.md +0 -889
  120. package/skills/tech-lead/references/tiny-lane.md +0 -53
  121. package/skills/tech-lead/workflows/shapeup-run.js +0 -2187
  122. package/skills/translator/SKILL.md +0 -258
  123. /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/contract-patterns.md +0 -0
  124. /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/ddd-patterns.md +0 -0
  125. /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/integration-analysis.md +0 -0
  126. /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/ux-behavior-patterns.md +0 -0
  127. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/api-feasibility.tmpl.md +0 -0
  128. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/contracts/be-service.contract.tmpl.md +0 -0
  129. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/contracts/offline-storage.contract.tmpl.md +0 -0
  130. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/contracts/third-party-api.contract.tmpl.md +0 -0
  131. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/context-map.tmpl.md +0 -0
  132. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/event-choreography.tmpl.md +0 -0
  133. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/migration-plan.tmpl.md +0 -0
  134. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/team-handoff.tmpl.md +0 -0
  135. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/domain-model.tmpl.md +0 -0
  136. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/feedback.tmpl.md +0 -0
  137. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/integration.tmpl.md +0 -0
  138. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/task-board.tmpl.md +0 -0
  139. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/task-spike.tmpl.md +0 -0
  140. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/task.tmpl.md +0 -0
  141. /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/ux-behavior.tmpl.md +0 -0
@@ -9,12 +9,11 @@
9
9
  "SHAPEUP_ATTEMPT_BUDGET": "5",
10
10
  "SHAPEUP_DIGESTER_MODEL": "script"
11
11
  },
12
- "_permissions_readme": "The harness kernel ships with the plugin and therefore lives OUTSIDE your project. Under any permission mode short of bypassPermissions, running a script from outside the working directory needs approval \u2014 once per session interactively, and never in a headless run, where nobody is there to grant it. `npx shapeup-sdlc init` writes this block for you; it is reproduced here so you can see exactly what is being pre-approved. TWO Bash rules, because the trailing ` *` form requires at least one argument and the bare form is what covers a no-flag invocation. The leading `*` spans the install root, which differs between a marketplace install (a version-stamped cache directory) and a `--plugin-dir` checkout \u2014 that wildcard is what keeps the grant working across a plugin upgrade instead of silently expiring. Scope is one dependency-free, network-free script and nothing else \u2014 not a general Bash(node:*). The third entry, \"Workflow\", is what lets the tech-lead launch its run script without approving each launch; it is UNSCOPED (it authorises every dynamic workflow script in the project, not only this plugin's), so `npx shapeup-sdlc init --no-native-workflow` declines it and the harness stays fully usable interactively. This list is GENERATED by bin/lib/grant.mjs and verified by execution rather than by string comparison: npm run test:grant.",
12
+ "_permissions_readme": "The harness kernel ships with the plugin and therefore lives OUTSIDE your project. Under any permission mode short of bypassPermissions, running a script from outside the working directory needs approval \u2014 once per session interactively, and never in a headless run, where nobody is there to grant it. `npx shapeup-sdlc init` writes this block for you; it is reproduced here so you can see exactly what is being pre-approved. TWO Bash rules, because the trailing ` *` form requires at least one argument and the bare form is what covers a no-flag invocation. The leading `*` spans the install root, which differs between a marketplace install (a version-stamped cache directory) and a `--plugin-dir` checkout \u2014 that wildcard is what keeps the grant working across a plugin upgrade instead of silently expiring. Scope is one dependency-free, network-free script and nothing else \u2014 not a general Bash(node:*). There is no third entry: the run is driven by the loop in the session, so the plugin no longer asks for the unscoped \"Workflow\" token and leaves one you already have alone. This list is GENERATED by bin/lib/grant.mjs and verified by execution rather than by string comparison: npm run test:grant.",
13
13
  "permissions": {
14
14
  "allow": [
15
15
  "Bash(node \"*/kernel/harness.mjs\" *)",
16
- "Bash(node \"*/kernel/harness.mjs\")",
17
- "Workflow"
16
+ "Bash(node \"*/kernel/harness.mjs\")"
18
17
  ]
19
18
  }
20
19
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shapeup-sdlc-plugin",
3
3
  "displayName": "ShapeUp SDLC Plugin",
4
- "version": "3.18.3",
4
+ "version": "4.0.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
@@ -3,68 +3,137 @@
3
3
 
4
4
  ## Enforcement model
5
5
 
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
-
8
- Skills and commands are named short throughout this file; every one of them resolves only under the plugin's namespace — `Skill(shapeup-sdlc-plugin:orient)`, `/shapeup-sdlc-plugin:ship`. A bare name is not a typo you get a warning for: an unknown skill name is rejected upstream of the hook layer, so the dispatch fires no hook, leaves no decision row, and is answered by improvisation.
9
-
10
- - Hook-denied: dispatching a worker without a schema-valid WorkOrder, writing outside the scope's substrate, writing the result of a live order your own dispatch did not take, writing a committed file whose text names a run-trace path or a board id, stopping a run with no receipt (the run's first act writes one).
11
- - **The tier-direction rule is refused at the write, not argued at L1b.** A committed file cannot carry a `.shapeup/` path or a `TASK-NNN` id — boards renumber per machine and the run trace is gitignored, so either one resolves only where it was written. Spec-lint has always red'd this at Board Review; the same rule now also refuses the write itself, naming the token, because four producers hit it and one of them hit it twice in one session — a worker carries no lesson across a dispatch, and by L1b the phase that wrote the line is over. The knowledge base is outside the rule: those files are instructions, not references anyone resolves.
12
- - Attested, not assumed: a dispatch leaves a receipt naming the skill that ran, and ingest refuses an orchestrated result that has none. A dispatch that fails is answered by the sub-agent improvising the craft, which every other check accepts — so "the artifact exists" is not evidence that the shipped skill produced it. `--no-receipt-check` is the way through when the receipt channel itself fails.
13
- - **The single writer is asked, never assumed.** A dispatch's result is applied by exactly one act — the ingest step — and that act leaves a leg row. Every phase post-condition and every settled build scope asks the leg ledger whether the row exists before any verdict on the phase or the scope, whatever the worker reported: a planning leg that left its artifacts and no result at all is dispatched again once, told its artifacts stand; a result on disk that nothing applied is ingested there if the scope is green, and otherwise named at the close as `unapplied_results=N`, never folded into "not green". A round that ends with nothing green names `breaker=none` and `stalled=no_green` unless the attested attempt census says a scope tripped — the close cannot name a breaker the census denies. The run graph carries a `Leg` node with an `INGESTED` edge from its `Result`, and the export a `leg` table, so "which results were never read" is one query.
14
- - 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.
15
- - 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.
16
- - **Every ending a run does not come back from records a close** — its status, its cause and its timestamp — derived from the ending itself rather than from a hand-kept pair, so an ending nobody enumerated cannot silently record nothing. The same close derives the ledger's verdict, its round count and its Rounds and Decisions tables from the run's own records — the ones the export reads — so the file a teammate opens first cannot contradict its own close line. A breaker trip that routes to GATE H closes the run as `escalated`, carrying the breaker in its cause; a pause records no close **by design**, because a relaunch resumes it. A relaunch that resumes a run which *did* close reopens it on the record: the earlier close is kept under `prior_closes`, the close fields clear, the run pointer the close retired comes back (so the resumed run's hook decisions carry its key again), and the run's next ending is recorded as its own — so a run that aborted, was resumed and then shipped reads `shipped` with the abort beside it, never an abort under a `shipped` status. Opening a run over one that closed says it is closed, not open.
17
- - **Your scope cut decides your concurrency, not the dial.** Two scopes that both declare a write to one path never build at the same time: `shared` substrate is the sanctioned escape from disjointness, and an edit is read-modify-write, so concurrent writers silently drop each other's work. An entry point listed as writable by five scopes therefore builds five scopes one at a time whatever `--parallel-scopes` says. The run states the ceiling its contracts actually permit before dispatching anything, as a BUILD-order line — a peak below that ceiling is a dispatch problem, a ceiling below the dial is a scope-cut problem, and only the second is fixable by re-cutting. The fix is a cut where exactly one scope owns each entry point. Note the ceiling is narrated, not gated: it does not travel in the ⏸ L1b block, so an unattended run carries it only in its log.
18
- - 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. **An attempt is spent only when the attested channels say so** — a dispatch receipt, plus a leg row or a WorkResult. A compiled order and a T0 verdict are both writable by the scope being judged, so neither counts on its own, and an attempt still in flight holds the breaker open rather than tripping it. Opening the next attempt over an unanswered one is refused outright, because grading a tree the previous attempt may still be writing spends a budget on work nobody did.
6
+ A three-phase Shape Up loop driven by `/ship` — the `building` skill, in your own session. The loop is guidance you follow; the runtime holds five things and nothing more, so expect hook denials and gate answers, not arguments:
7
+
8
+ - **The receipt.** Opening a run writes a receipt (with the run's id, the intake's digest and the plugin copy that answered), the launch record, and the pointer every hook reads. A run that left no receipt did not happen.
9
+ - **The gate resolver.** Every gate resolves from an answer set or stops for the PO, and the decision's source is written to a ledger. An answer chooses among the answers a gate allows; it never supplies the evidence that makes one allowed.
10
+ - **The T0 witness.** A scope's fixtures are run, scored against the last kept attempt, and the artifact is hashed. The tree moves forward only when the score strictly improves.
11
+ - **The write fence.** While an order has no result, a write outside that order's substrate is refused. Writing a committed file whose text names a run-trace path or a board id is refused at the write.
12
+ - **The dispatch receipts.** Each dispatch leaves a row naming the agent the host says ran, with the tokens, duration and model the host measured beside the model the call asked for, so "the artifact exists" is never mistaken for "the shipped worker produced it", and "the record asked for this model" is never mistaken for "this model ran".
13
+
14
+ Everything else in the workflow below — sequencing the phases, applying a worker's result to the board, counting attempts against the budget, linting the spec, the census, the ship report — is the loop's own discipline, written down in the skill and checked by nothing but the PO and the evaluator. Where this file says "the loop does X", no script verifies it.
15
+
16
+ - Hook-denied: dispatching a worker without a schema-valid WorkOrder; writing outside the live order's substrate; writing a path a different dispatch's order owns; writing a committed file whose text names a run-trace path or a board id.
17
+ - **The tier-direction rule is refused at the write.** A committed file cannot carry a `.shapeup/` path or a `TASK-NNN` id — boards renumber per machine and the run trace is gitignored, so either one resolves only where it was written. The knowledge base is outside the rule: those files are instructions, not references anyone resolves.
18
+ - **Attested, not assumed.** A dispatch leaves a receipt naming the plugin's own agent as the host resolved it. A dispatch that fails is answered by the sub-agent improvising the craft, which every other check accepts — so the receipt, not the artifact, is the evidence the shipped skill produced it.
19
+ - 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. The Round Close gate is advisory over unfinished tasks and warns instead of blocking, but a board with no tasks at all can never cross it; the Ship Sign-off gate reads the census file, the run's QA record (was a hunt owed, and did it run a charter or get an explicit `skip`) and the models on the dispatch receipts (no `exec` or `eval` worker ran below the floor; a model other than the one the launch record asked for is written into the gate's row, not refused) and nothing else before any answer set may say `ship`.
20
+ - **Every run ends on a record.** Closing a run writes its status, its cause and its timestamp, and retires the fence's pointer, so an ended run stops fencing the checkout. A `shipped` ending is refused unless a Ship Sign-off row of the same run says `ship`, and the record names that sign-off; `escalated` and `aborted` need none. A gate waiting for the PO records no close by design — it is answered in the session that reached it.
21
+ - **Your scope cut decides your concurrency.** Two scopes that both declare a write to one path never build at the same time: an edit is read-modify-write and concurrent writers silently drop each other's work. The fence enforces each scope's substrate; reading the contracts for overlap before releasing scopes together is the loop's job.
22
+ - The build+eval loop breaks only two ways: the evaluation passes → QA → Ship; or the outer `round_budget` is exhausted. A scope exhausting its per-scope `attempt_budget` queues a Cut-List Review proposal and never blocks the round; budget trips route to the Cut-List Review, so what is green ships and the run is never killed from outside.
23
+
24
+ ### Workflow at a Glance
25
+
26
+ ```mermaid
27
+ flowchart TD
28
+ Shaping["Phase 1 — Shaping\n(Set Boundaries, Find the Elements, Risks & Rabbit Holes)"]
29
+ Betting{"Phase 2 — Betting\nPO decides"}
30
+ Intake["Intake & Config"]
31
+ Orient["Orient Review"]
32
+ Requirements["Requirements + Analyze\n(reviewed at Board Review)"]
33
+ Wiring["Wiring Review"]
34
+ Board["Board Review"]
35
+ Round["BUILD round\n(dispatch, T0-verify)"]
36
+ Close["Round Close"]
37
+ Verdict["Verdict"]
38
+ QA["QA Edge Hunt"]
39
+ Cut["Cut-List Review"]
40
+ Ship["Ship Sign-off"]
41
+ Retro["Retro Ownership"]
42
+
43
+ Shaping --> Betting
44
+ Betting -- bet --> Intake
45
+ Betting -- reject --> Shaping
46
+ Intake --> Orient --> Requirements --> Wiring --> Board --> Round
47
+ Round --> Close --> Verdict
48
+ Verdict -- FAIL --> Round
49
+ Verdict -- PASS --> QA --> Cut
50
+ Round -- "round_budget exhausted" --> Cut
51
+ Cut --> Ship --> Retro
52
+ ```
53
+
54
+ ### Gate names
55
+
56
+ Every gate below pauses the run for a PO decision unless a pre-recorded gate-answer preset
57
+ resolves it (`ci`/`guarded`/`interactive`). This document and the commands call a gate by its
58
+ plain name; the last column is the machine id the same gate carries in `decisions.jsonl`,
59
+ `gates.jsonl` and any gate-answers file, and is the only place an id appears here.
60
+
61
+ | Gate | What it checks | Who answers | Id in ledgers and answer files |
62
+ |------|-----------------|-------------|------|
63
+ | Intake & Config | Model/budget matrix set, worker roster confirmed on disk | PO | `L0` |
64
+ | Orient Review | The Scout's code-surface map and spike findings, before any board exists | PO | `L1a` |
65
+ | Wiring Review | `wiring-map.md` — every use case traced to its seam and entry point | PO | `L1a.5` |
66
+ | Board Review | The scope board and substrate disjointness — where scope is actually decided | PO | `L1b` |
67
+ | Round Close | Board 100% done and T0-green, before the round's work goes to evaluation (see note) | PO | `L2` |
68
+ | Verdict | The evaluator's PASS/FAIL judgment for the round | PO | `L3` |
69
+ | QA Edge Hunt | Exploratory findings outside what the evaluation already probed — never a verdict | PO | `QA` |
70
+ | Cut-List Review | The stop census and its baseline comparison — what ships, what's cut | TL/PO | `H` |
71
+ | Ship Sign-off | Final go/no-go, gated on the Cut-List Review's census | PO | `L4` |
72
+ | Retro Ownership | Which skill owns each retro rule, before it's written to the knowledge base | PO | `COACH-1` |
73
+
74
+ **Note on Round Close:** a board with literally zero tasks can never auto-proceed here — the resolver forces
75
+ a stop for the PO no matter what a preset says ("board 100%" of nothing proves nothing). A board
76
+ with real tasks still unfinished *can* proceed past Round Close if the operator explicitly allows it; that
77
+ choice is recorded as a flagged `warn`, not a silent pass — a signal that evaluation ran over
78
+ incomplete work, not a bug in the harness.
79
+
80
+ Four phrases recur below instead of symbols:
81
+
82
+ - **Needs scope contracts** — the step requires `shapeup/<slug>/scopes/*.md`; the write fence is skipped, not failed, when no order carries a substrate.
83
+ - **Test Surface** — the per-use-case rows the evaluation grades and QA and Ship status report against.
84
+ - **Preflight** — the refusals made before planning is paid for: the worker roster and the model floor.
85
+ - **QA finding** — logged with no verdict and no score; QA discovers, it never blocks.
19
86
 
20
87
  ### Phase 1 — Shaping (`/shapeup`)
21
88
  1. Set Boundaries → `/shapeup shaping`
22
89
  2. Find the Elements → `/shapeup breadboarding`
23
90
  3. Risks & Rabbit Holes → `/shapeup spike`
24
- (The completed pitch is formed by `shaping.md` + `breadboard.md`. A run takes both: `/ship` finds the breadboard beside the pitch or in `shaping/`, takes one named with `--breadboard`, or reads it inline in a single pitch file, and hands it to every planning worker. Each breadboard Place with UI affordances becomes its own screen in the spec — spec-lint stops the run at L1b when one is missing or folded into another screen — and a Place the shape will not build is deferred there, with the PO's yes.)
91
+ (The completed pitch is formed by `shaping.md` + `breadboard.md`. The loop finds the breadboard beside the pitch or in `shaping/`, takes one named with `--breadboard`, or reads it inline in a single pitch file, and hands it to every planning step. Each breadboard Place with UI affordances becomes its own screen in the spec, and a Place the shape will not build is deferred at Board Review with the PO's yes.)
25
92
 
26
93
  ### Phase 2 — Betting (PO governance, no skill)
27
94
  Betting Table: PO decides; rejected pitches loop back to raw idea.
28
95
 
29
96
  ### Phase 3 — Building
97
+ Rows marked *pauses* stop for the PO at the named gate.
98
+
30
99
  | Step | Gate | Action |
31
100
  |------|------|--------|
32
- | Kick-off | ⏸ **L0** — Intake & Config (L0.8 model/budget matrix) + worker roster ✧ | `/translator` if non-English |
33
- | Orient (Scout) | ⏸ **L1a** — Orient Review | `/orient` |
34
- | Requirements | — (reviewed at L1b) | `/ba-pitch-analyzer` (`coverage`): the pitch's clauses → committed `requirements.md`, one atomic clause per `REQ-<n>` row naming the pitch clause it came from, ids assigned once and frozen; dispatched once, ahead of Analyze because the acceptance criteria are what cite its ids. A registry already on disk is not re-dispatched |
35
- | Analyze | — (reviewed at L1b) | `/ba-pitch-analyzer` (`analyze`): spec tree + board (UC + Invariants + Test Surface ★); before Wire (needs its use cases). The tree is committed and the board is per-machine: a run that finds the tree on disk and no board dispatches `board`, which regenerates the board from the tree without re-deriving it — GATE L2 refuses `proceed` over a board with zero tasks. An acceptance criterion that grades a requirement carries `(covers: REQ-…)` — that clause is the edge the verdict travels back along. A board with no such clause beside a registry sends its writer back once, and one that still has none continues with a warning |
36
- | 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` |
37
- | Map Scopes | ⏸ **L1b** — Board Review (+ substrate disjointness lint) | `/scope-architect` (scope contracts ✦ — sole writer); traceability oracle advisory ✚. A registered requirement that no acceptance criterion grades and no scope claims is **red** here, and L1b prints the `REQ → AC` table: the two ways out are an AC carrying `(covers: REQ-…)` or the PO marking the clause `CUT (PO-approved)`. Red only where the plan is still cheap to change — after L1b nobody re-reads the pitch |
38
- | Build Vertically | ⏸ **L2** — Board 100% ✅ + T0-green ✦ | per dispatch: compile order → `/task-executor` (--order) → ingest result; T0-verified per attempt (fixtures + DB probe ✦), substrate-sandboxed ✦. Scopes build **concurrently** ✦ — `--parallel-scopes N` caps it (default 4), a scope is released the moment its own dependencies are green, and a scope green in this round is skipped rather than rebuilt. Then the **round build gate** ⚙: the ledger's run command, then the profile's `build_probe` and `launch_probe`, run once per round before EVAL — a red gate ends the round with no verdict and its failing step is compiled into the next round's orders as bugs; a `mobile` profile with no `launch_probe` is warned about every round, so the install/launch risk has an owner |
39
- | EVAL (once per round) | ⏸ **L3** — Verdict | `/spec-evaluator` (--order), only over a round whose build gate ⚙ is not red: spec- + test-surface-conformance ★, T0 citation ✦; the order names the dimensions it grades — the set the PO named at L0, or else the set the spec calls for (a Test Surface turns on test-surface-conformance, Invariants turn on completeness, and the test-surface and suite checks are always on), and L4 lists the ones left out. A PASS that grades no criterion under a dimension its order named is refused, and the judge is sent back once; refuted boxes/verdict applied by ingest. The order names the round's build gate artifact and the profile's `launch_probe`, so a `[ui]` row is graded on the app the gate launched rather than recorded as no evidence — a project with no `launch_probe` still gets no on-device grade. A PASS names every Test Surface row as its own criterion: one that grades the surface as a group is refused, and the judge is sent back once with the reason. A scope that did not go green in the round has its rows graded FAIL, and the order names such scopes, so one red scope never makes the whole round ungradeable |
40
- | FAIL → round r+1 | — | regression rule ★: bugs + full Test Surface of touched UC. Every criterion the verdict graded FAIL reaches the round, whether or not the judge filed a bug for it, addressed to the scope that owns its use case — a round with a FAIL verdict and nothing to fix is how a run stalls. A row whose check the scope rewrote between a failing trial and a passing one is listed for the judge, who reads it against the row before the pass counts |
101
+ | Kick-off | *pauses* at **Intake & Config** — the worker roster is checked first (preflight) | `/ship intake` — a non-English pitch is made English by the loop itself: `<name>.en.md` + a glossary, and the run opens on the copy |
102
+ | Orient (Scout) | *pauses* at **Orient Review** | `/orient` |
103
+ | Requirements | — (reviewed at Board Review) | **plan** (`requirements`), done by `/ship`'s loop in its own session, no sub-agent: the pitch's clauses → committed `requirements.md`, one atomic clause per `REQ-<n>` row naming the pitch clause it came from, ids assigned once and frozen |
104
+ | Analyze | — (reviewed at Board Review) | **plan** (`spec`): spec tree + board (use cases + invariants + Test Surface); before Wire (needs its use cases). An acceptance criterion that grades a requirement carries `(covers: REQ-…)` — that clause is the edge the verdict travels back along |
105
+ | Wire | *pauses* at **Wiring Review** | **plan** (`wire`): committed `wiring-map.md` — per-use-case engine → seam → entry-point call site → affordance |
106
+ | Map Scopes | *pauses* at **Board Review** | **plan** (`scopes`): scope contracts (needs scope contracts). The loop reads the plan back before the gate: substrates disjoint, every scope anchored to a use case, every requirement graded by a criterion or claimed by a scope or marked `CUT (PO-approved)` — and prints the requirement → criterion table |
107
+ | Build Vertically | *pauses* at **Round Close** | per dispatch: write the order → open it for the fence → `/task-executor` (--order) → check the result's envelope → apply it. T0-verified per attempt, substrate-fenced (needs scope contracts). Scopes build concurrently where their contracts do not overlap (`--parallel-scopes N` caps it, default 4); a scope green in this round is skipped rather than rebuilt. Before evaluation the loop builds and launches the feature with the project profile's commands: a red step ends the round with no verdict and becomes the next round's bug |
108
+ | Evaluation (once per round) | *pauses* at **Verdict** | `/spec-evaluator` (--order): spec- and Test Surface conformance, T0 citation — the order names the dimensions it grades (the set the PO named at Intake & Config, else the set the spec calls for) and Ship Sign-off lists the ones left out. A PASS names every Test Surface row as its own criterion. A scope that did not go green in the round has its rows graded FAIL |
109
+ | FAIL → round r+1 | — | regression rule (Test Surface): bugs + full Test Surface of the touched use case. Every criterion the verdict graded FAIL reaches the round, whether or not the judge filed a bug for it, addressed to the scope that owns its use case |
41
110
 
42
- ✦ = 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).
111
+ Traceability stays advisory until `covers:` is populated. Absent artifact ⇒ arm skipped (non-regression).
43
112
 
44
- ✧ **Two refusals, and they answer different questions.** Opening a run refuses outright when the worker skills are not on disk — the roster comes from the schema that defines it, so it cannot drift from a hand-kept list. That alone passes green on the two states that actually happen (installed but disabled, or a different version loaded), so the run's first act is one live canary dispatch, and the evidence is the hook layer's rather than the sub-agent's account of it. A run that cannot reach its workers stops before it spends anything, instead of reporting phases complete while none of the shipped craft was applied. The same Preflight then runs the profile's `build_probe` and `launch_probe` once, from a sub-agent through the session's own grant, and writes nothing: a missing package install, a probe outside the grant or an absent device is reported before planning is paid for, not at the first round gate. It warns rather than refuses — a baseline can be red for a reason the feature is meant to fix — and whether a permission exists is judged by that run, never by reading a settings file.
113
+ **Planning runs under its own write fence.** Each of the four **plan** substeps is opened by an order that stamps that substep's write contract — nothing is dispatched. While one is open, the staged pitch and breadboard, the project profile, the run's receipts and ledgers and the order and result files are frozen, and each substep may write only its own artifact.
45
114
 
115
+ **Two preflight refusals, before anything is spent.** Opening a run refuses outright when the worker skills are not on disk — the roster comes from the schema that defines it, so it cannot drift from a hand-kept list — and when the launch record's `exec` or `eval` model is below the floor (sonnet or above; `qa` is not checked, and `eval` is not under `--no-eval`). A worker agent is defined with `model: inherit`, so the loop passes the launch record's model for the role on every dispatch, and the receipt records both the model the call asked for and the one the host says ran. Ship Sign-off reads the second: a worker that ran below the floor refuses `ship`, and a model other than the record's is written into the gate's row and the ship report — the record states what was asked for; only the receipts say what ran.
46
116
 
47
117
  ### QA Edge Hunt (`/qa-edge-hunter`, post-PASS, pre-ship)
48
- **Q0** Preflight → **Q1** Charter (6 lenses − EVAL-covered) → **Hunt** (repro required, findings `~` → ledger) → report (no verdict, no score). Skip with `--no-qa`. A hunt that reached the app and ran no charter is sent back once; if it still ran none, the report and the run's close say `not-hunted`, never that QA ran.
118
+ **Q0** Preflight → **Q1** Charter (6 lenses − the ones the evaluation covered) → **Hunt** (repro required, QA findings → ledger) → report (no verdict, no score). Skip with `--no-qa`. A hunt that reached the app and ran no charter is a failed hunt: the loop sends it back once, and the report says `not-hunted`, never that QA ran. A run whose round passed cannot cross Ship Sign-off with `ship` unless the hunt ran a charter or the QA Edge Hunt gate was answered `skip` — a ledgered decision, not a silent omission.
49
119
 
50
120
  ### Ship & Triage
51
- - **SHIP S.0 / GATE H** — `/scope-hammer`: census (QA findings + discovered ledger + attempt-budget proposals ✦; every "no scope owns X" cites `probe owner`, which derives ownership from the contracts) → baseline comparison (never the ideal) → cut list; TL/PO promotes selected items only. The census is written as data beside the report, and GATE L4 reads that file — and nothing else — before any answer set may say `ship`. A breaker does not end the run: the run itself dispatches the census, crosses GATE H, writes the ship report with the verdict as it is, crosses L4, and only then closes — `shipped` with the cut list when the census clears it, `escalated` naming the census when it does not.
52
- - ⏸ **L4** — Ship Sign-off (shows QA status ★).
53
- - **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`, `/orient`, `/scope-architect`, `/solution-architect`, and `/tech-lead` (workflow guidance read at L0, plus suggested L0 values it confirms before pinning); `/spec-evaluator` is not (single judge) and neither is `/scope-hammer` (its census cites `probe owner`). **Guidance never decides a gate**: a rule may add a question or a check to a gate block, never an answer, a skip or a wider substrate. `/retro --scan` seeds the same files from the project on disk before the first run, and `/retro --research <stack>` from the platform's official documentation when there is nothing on disk yet (a source, never a verification: nothing it reads runs until the tech lead pins it at L0), optional, every rule confirmed at COACH-1. Mechanism defects file to `knowledge-base/harness-defects.md` as Betting Table raw ideas, never worker steering.
54
- - Post-fix: `eval --single-pass` → remaining `~` + new feedback → new raw idea.
121
+ - **Cut-List Review** — `/hammer` (`/ship stop`), done by the loop in its own session, no sub-agent: census (QA findings + discovered ledger + attempt-budget proposals; every claim names the file it came from — ownership comes from the scope contracts, exhaustion from the dispatch receipts) → baseline comparison (never the ideal) → cut list; TL/PO promotes selected items only. The census is written as data and Ship Sign-off reads that file — and the run's QA record and the models on its dispatch receipts, nothing else — before any answer set may say `ship`. The loop then writes the ship report (`REPORT.md`, frozen at Ship Sign-off: a shipped FAIL says so in its first line) and closes the run with its verdict.
122
+ - **Ship Sign-off** (shows QA status).
123
+ - **Retro** — Ship Sign-off feedback → `/retro`, done by the loop itself; the Retro Ownership gate asks the PO which skill owns each rule (never assumes) → committed `shapeup/knowledge-base/<name>.md` (team inherits on pull). Categories: `/task-executor`, `/qa-edge-hunter`, `/orient`, **plan** (read at every planning step), and **building** (the loop's workflow guidance read at Intake & Config, plus suggested values it confirms before pinning); `/spec-evaluator` is not (single judge) and neither is the stop census. **Guidance never decides a gate**: a rule may add a question or a check to a gate block, never an answer, a skip or a wider substrate. `/retro --scan` seeds the same files from the project on disk before the first run, and `/retro --research <stack>` from the platform's official documentation when there is nothing on disk yet (a source, never a verification: nothing it reads runs until the PO pins it at Intake & Config), optional, every rule confirmed at Retro Ownership.
124
+ - Post-fix: `eval --single-pass` → remaining QA findings + new feedback → new raw idea.
55
125
 
56
126
  ### Discovered Tasks
57
- 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 ★.
127
+ Everything discovered funnels into `.shapeup/<slug>/discovery/ledger.md` (Orient, task-executor, QA); the loop appends each worker's discoveries from its result. A new invariant triggers a **plan** `spec` step in `reconcile` mode → `TS-INV-NN` Test Surface row.
58
128
 
59
129
  ### Architectural Invariants
60
130
  - **Single judge** — verdict belongs to `spec-evaluator`; QA has no verdict, no score.
61
- - **EVAL exactly once per round** — QA sits after PASS, outside the loop.
62
- - **Ledger = single source of truth** — every discovery flow writes only its own section.
63
- - **QA is a level-up, not a gate** — `--no-qa` skips it; circuit breaker outranks the Hunter.
131
+ - **Evaluation exactly once per round** — QA sits after PASS, outside the loop.
132
+ - **Ledger = single source of truth** — every discovery flow writes only its own section, and the loop is the only writer of it.
133
+ - **QA is a level-up, not a gate** — it never blocks on what it finds; `--no-qa` or a `skip` answer skips it on the record; the round budget outranks the Hunter. What it cannot do is go missing unrecorded: Ship Sign-off refuses `ship` over an owed hunt that never ran.
64
134
  - **Role separation** — Evaluator grades, task-executor fixes, QA discovers.
65
- - **The requirements matrix is a projection, never a verdict** — `REQ → AC → criterion → verdict` is derived from files for one named run (the registry, the board's `covers:` clauses, the run's verdict rows, the T0 citations), never narrated and never passed in. `covers:` is the authoritative join: a criterion anchored to a requirement no AC covers is printed for reconciliation and counted as nothing. A verdict that anchors no criterion at all, beside a board whose ACs carry `covers:`, is sent back to the judge once. L4 reads one line off it, GATE H's census takes the clauses with no evidence, `REPORT.md` freezes the table — and none of that blocks a ship. A clause with no PASS evidence is a fact the baseline comparison weighs, not a veto.
66
- - **Hill phase is mechanical ✦** — derived only from T0/T1 artifacts, never self-reported, and a T0-green from a round whose build gate ⚙ is red moves no dot (a green fixture in a round the feature did not build is evidence about the fixture); the evaluator cites a T0 artifact it re-hashes itself, from the list its order carries. A scoped verdict citing none is refused: its round stays open and is evaluated again, never advanced.
67
- - **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.
135
+ - **Envelope port** — every dispatch is WorkOrder in / WorkResult out; a malformed order is hook-denied; the loop checks a result against the schema before it applies it. Workers: stateless, craft-only, pipeline-blind.
136
+ - **The witness is mechanical** — a verdict that cites T0 cites an artifact whose hash the evaluator re-computes; a green T0 is evidence about the fixtures, not about whether the feature was built.
68
137
 
69
138
  ## Setup & Execution
70
139
 
@@ -76,24 +145,14 @@ Everything discovered funnels into `.shapeup/<slug>/discovery/ledger.md` (Orient
76
145
  tells you, because trusting a directory to run code from is your decision to make, never a package's
77
146
  to make for you. Above workspace trust sits Claude Code's own **auto-mode classifier**, which can
78
147
  still block a call the grant already covers, invisibly to anything this plugin ships — no rule or
79
- hook here can see it, let alone override it. When either layer stops an automated run, the
80
- documented fallback is to drive Build by hand: the same per-dispatch cycle named in the Build
81
- Vertically step above — compile, dispatch, ingest, verify — run one call at a time instead of
82
- through the chained launch, until the run can resume unattended again.
83
- - 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, and the run scripts staged for launch).
84
- - **The run launches from a copy inside your project, and it has to.** The Workflow tool loads a script only from a directory the session may already read; the plugin installs outside your project, so naming the shipped path is refused before the run begins and no permission rule repairs it — the grant authorises the tool, not what it may read. Opening a run therefore re-copies the run scripts to `.shapeup/workflows/` and reports the path the launch names. A run in flight keeps the copy it started with: an upgrade reaches the next run, not the current round.
85
- - **A write the substrate does not cover is denied for as long as the dispatch is in flight, and no longer.** A dispatch is live from the moment its order is compiled until a result for *that* dispatch lands, and liveness is read off the run's order set — not off the pointer that names the run, which outlives it. A run closed any other way than shipping — escalated, aborted, killed outright — leaves an order still open by construction, and the pointer is what decides whether that still fences: the fence is enforced only while the pointer exists on disk, so a close that removes it releases the fence whatever the order set says, and restoring the pointer flips it straight back to denying. **Every terminal close retires it** (3.7.1 onward), not only a ship — an escalated or aborted run stops fencing the checkout the moment it closes, and a close that cannot remove a pointer says so in its own return rather than failing. Retiring the pointer does not orphan what follows: the close leaves a breadcrumb naming the run it ended, so the hook decisions taken in the census and ship phase after it still carry that run's key, marked as taken over a closed run. Retiring is not answering, though, and the difference is the whole reason there are still two levers: the pointer says a run is in flight, the missing result says nobody came back, and only the first stops being true at a close. An order the run left unanswered stays genuinely unresolved — un-fenced, but not done — until `init run --force` writes a synthetic result for it, which is also what lets the attempt census keep telling work nobody did apart from work that failed. What the fence actually gates is narrower than "the project," too — it is this assistant's own edit path (a direct file write or edit call) outside the live order's substrate; a shell command, `git`, or any other editor still writes straight through it. Re-dispatch is fenced again, and the committed tier is never a worker's to write either way: those files belong to the orchestrator, whose window is a phase boundary rather than the middle of somebody else's order.
86
- - Every run has a `run_id` — the receipt mints it, and orders, T0 artifacts, trial rows and hook decisions all carry it. It is the only key that separates two runs of the same feature: everything else (`order_id`, round/attempt) repeats. It is **not** a time boundary — a relaunch resumes the same run and reuses the key, so one `run_id` legitimately spans every launch after a paused gate or a kill, with hours of wall clock between them, and `orders/<id>.json` is rewritten by each. Anything measuring elapsed time reads the append-only records, never the span of a key. SHIP S.7 exports the run's records as fact tables under `.shapeup/exports/<run_id>/` before the run trace is superseded — and so does **every other terminal ending**: a run that aborts, escalates or stops at GATE H exports on its close, because the runs whose records are worth most are the ones that never reach the Ship phase. The export is advisory at every one of them: a failed export degrades the trace and is reported in the run's state warnings, but never turns a close into a non-close. A WorkResult carries no `run_id` and reaches it through `order_id`.
87
- - Every run projects a **run graph** — `.shapeup/<slug>/graph.jsonl`, append-only, written only by
88
- `reduce graph`. Two families kept separate: work lineage (Run, Order, Result, Leg, Verdict,
89
- Trial, GateDecision) and domain (Scope, UseCase, Requirement, Seam). It is derived from the artifacts,
90
- never authored, so it can be deleted and rebuilt — and a run recorded before it existed backfills
91
- on first touch. `--subgraph run` is the fast-forward as one bounded query; `--trace <node>` walks
92
- a verdict back to the objective, the plan, the source, the execution record and the gate that
93
- crossed it.
94
- - `/hill-chart` (skill `hill-chart`, not a pipeline worker — invoked directly, like `shapeup`) renders both the committed hill shards (`shapeup/<slug>/hill/<scope-id>.yml`, the mechanical phase from the invariant above) and the local run graph as one dashboard: a portfolio card per pitch, and per-pitch a Hill Chart, an attention list, a scope board, round history, and the run graph one click deeper. A pitch whose local run trace was cleaned up after shipping still renders — marked Archived — from its committed hill shards alone.
95
- - Contracts: markdown on disk, JSON on the wire; a single library reads/writes the file form.
148
+ hook here can see it, let alone override it. When either layer stops an automated run, drive the
149
+ Build step by hand — write the order, dispatch, check the result, run T0 — one call at a time, until
150
+ the run can resume unattended again.
151
+ - Two storage tiers: COMMITTED `shapeup/<slug>/` (shaping, spec, scopes, wiring-map, project-profile, requirements, `REPORT.md` frozen at Ship Sign-off) vs GITIGNORED `.shapeup/` (board, orders/results, T0/eval/QA artifacts, ledgers, metrics, gate answers, and the launch record).
152
+ - **Opening a run stages nothing.** The run is driven by the loop in your session, so there is no script to copy into your project and no launch to authorise beyond the two kernel Bash rules; opening writes the run's own trace and the **launch record** (`.shapeup/<slug>/run-args.json` — the models, budgets, dial and skip switches the run was launched with), and a run already open keeps the record it has.
153
+ - **A write the substrate does not cover is denied for as long as the dispatch is in flight, and no longer.** A dispatch is live from the moment its order is written until a result for *that* dispatch lands. The fence is armed by a pointer the loop sets when it opens an order, and it is enforced only while the pointer exists on disk: a missing pointer allows every write, which is why the loop sets and retires it through a command that reads it back instead of writing it by hand. **Every close retires the pointer**, so an escalated or aborted run stops fencing the checkout the moment it ends. An order the run left unanswered stays genuinely unresolved — un-fenced, but not done — until re-opening the run with `--force` writes a synthetic result for it, which is also what lets a count of attempts tell work nobody did apart from work that failed. What the fence gates is narrower than "the project": it is this assistant's own edit path (a direct file write or edit call) outside the live order's substrate; a shell command, `git`, or any other editor still writes straight through it. The committed tier is never a worker's to write: those files belong to the orchestrator, whose window is a phase boundary rather than the middle of somebody else's order.
154
+ - Every run has a `run_id` — the receipt mints it, and orders, T0 artifacts, trial rows and hook decisions all carry it. It is the only key that separates two runs of the same feature: everything else (`order_id`, round/attempt) repeats. It is **not** a time boundary — `/ship` over an open run resumes the same run and reuses the key, so one `run_id` legitimately spans every session after a kill.
155
+ - Contracts: markdown on disk, JSON on the wire.
96
156
  - Never hard-code a storage root — generated paths resolve through the shared path resolver.
97
- - Hooks file under the project root they find above the shell's working directory (a run pointer, the committed tier, or a git boundary), never under the folder a worker happened to `cd` into — so a sub-folder shell neither splits the decision ledger nor slips the substrate fence. `probe stats --hooks` lists any stray ledger it still finds.
98
- - The traceability oracle emits `.shapeup/<slug>/trace/report.json` from the spine artifacts.
157
+ - Hooks file under the project root they find above the shell's working directory (a run pointer, the committed tier, or a git boundary), never under the folder a worker happened to `cd` into — so a sub-folder shell neither splits the decision ledger nor slips the substrate fence.
99
158
  <!-- HARNESS_END -->