shapeup-sdlc 1.6.3 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/AGENTS.md +36 -103
  3. package/README.md +60 -67
  4. package/SECURITY.md +31 -16
  5. package/bin/init.mjs +24 -69
  6. package/commands/build.md +19 -0
  7. package/commands/eval.md +5 -4
  8. package/commands/scopes.md +5 -4
  9. package/commands/shape.md +1 -1
  10. package/commands/ship.md +37 -4
  11. package/hooks/anti-rationalization.mjs +7 -13
  12. package/hooks/compact-snapshot.mjs +5 -5
  13. package/hooks/gate-deadline.mjs +12 -16
  14. package/hooks/gate-intake.mjs +13 -14
  15. package/hooks/gate-l2.mjs +3 -3
  16. package/hooks/gate-zerowork.mjs +97 -16
  17. package/hooks/lib/decision.mjs +21 -13
  18. package/hooks/safety-spine.mjs +1 -1
  19. package/hooks/sandbox-guard.mjs +83 -47
  20. package/hooks/session-rehydrate.mjs +8 -9
  21. package/hooks/slop-cleaner.mjs +1 -1
  22. package/oracles/_shared.mjs +1 -1
  23. package/oracles/http-oracle.mjs +1 -1
  24. package/oracles/index.mjs +1 -1
  25. package/oracles/process-oracle.mjs +1 -1
  26. package/oracles/snapshot-oracle.mjs +1 -1
  27. package/oracles/test-oracle.mjs +1 -1
  28. package/package.json +3 -7
  29. package/skills/ba-pitch-analyzer/SKILL.md +20 -15
  30. package/skills/ba-pitch-analyzer/references/doc-schemas.md +1 -1
  31. package/skills/ba-pitch-analyzer/references/task-generation.md +6 -6
  32. package/skills/ba-pitch-analyzer/references/test-surface.md +1 -1
  33. package/skills/ba-pitch-analyzer/scripts/board-derive.mjs +5 -5
  34. package/skills/ba-pitch-analyzer/scripts/spec-lint.mjs +2 -2
  35. package/skills/coach/SKILL.md +3 -3
  36. package/skills/orient/SKILL.md +2 -1
  37. package/skills/qa-edge-hunter/SKILL.md +9 -39
  38. package/skills/scope-architect/SKILL.md +17 -12
  39. package/skills/scope-hammer/SKILL.md +5 -5
  40. package/skills/shapeup/SKILL.md +3 -3
  41. package/skills/shapeup/resources/context-compaction.md +4 -3
  42. package/skills/solution-architect/SKILL.md +18 -11
  43. package/skills/spec-evaluator/SKILL.md +12 -5
  44. package/skills/spec-evaluator/references/dimensions/_registry.md +2 -2
  45. package/skills/spec-evaluator/references/dimensions/completeness.md +1 -1
  46. package/skills/spec-evaluator/references/dimensions/integration.md +98 -67
  47. package/skills/spec-evaluator/references/dimensions/spec-conformance.md +4 -4
  48. package/skills/spec-evaluator/references/dimensions/test-surface-conformance.md +1 -1
  49. package/skills/spec-evaluator/references/probing.md +42 -23
  50. package/skills/spec-evaluator/references/report-schema.md +2 -2
  51. package/skills/spec-evaluator/scripts/verdict-ledger.mjs +1 -1
  52. package/skills/task-executor/SKILL.md +25 -12
  53. package/skills/tech-lead/SKILL.md +115 -438
  54. package/skills/tech-lead/references/delegation.md +38 -31
  55. package/skills/tech-lead/references/gates.md +75 -33
  56. package/skills/tech-lead/references/hard-rules.md +34 -0
  57. package/skills/tech-lead/references/invocation.md +2 -2
  58. package/skills/tech-lead/references/ledger-schema.md +17 -18
  59. package/skills/tech-lead/references/round-protocol.md +77 -27
  60. package/skills/tech-lead/references/state-model.md +1 -1
  61. package/skills/tech-lead/schemas/domain.schema.json +320 -148
  62. package/skills/tech-lead/schemas/gate-answers.schema.json +2 -2
  63. package/skills/tech-lead/schemas/work-result.schema.json +55 -17
  64. package/skills/tech-lead/scripts/aegis-digest.mjs +1 -1
  65. package/skills/tech-lead/scripts/budget-check.mjs +7 -13
  66. package/skills/tech-lead/scripts/compile-order.mjs +69 -22
  67. package/skills/tech-lead/scripts/fit-check.mjs +10 -10
  68. package/skills/tech-lead/scripts/gate-answers.mjs +11 -12
  69. package/skills/tech-lead/scripts/hill-derive.mjs +133 -0
  70. package/skills/tech-lead/scripts/ingest-result.mjs +7 -19
  71. package/skills/tech-lead/scripts/init-run.mjs +60 -18
  72. package/skills/tech-lead/scripts/lib/argv.mjs +1 -1
  73. package/skills/tech-lead/scripts/lib/contract-md.mjs +10 -10
  74. package/skills/tech-lead/scripts/lib/is-main.mjs +11 -12
  75. package/skills/tech-lead/scripts/lib/paths.mjs +15 -13
  76. package/skills/tech-lead/scripts/resume-state.mjs +387 -0
  77. package/skills/tech-lead/scripts/run-snapshot.mjs +1 -6
  78. package/skills/tech-lead/scripts/run-workflow.mjs +381 -0
  79. package/skills/tech-lead/scripts/ship-report.mjs +33 -2
  80. package/skills/tech-lead/scripts/stats.mjs +9 -10
  81. package/skills/tech-lead/scripts/t0-verify.mjs +4 -4
  82. package/skills/tech-lead/scripts/trace-lint.mjs +2 -2
  83. package/skills/tech-lead/workflows/shapeup-run.js +911 -0
  84. package/skills/translator/SKILL.md +2 -2
  85. package/skills/advisor-protocol/SKILL.md +0 -171
@@ -8,6 +8,17 @@ EVAL phase. The feature is done when an EVAL round returns PASS.
8
8
  > SHARED spec dir. See tech-lead SKILL.md GATE L1b for the bootstrap step that regenerates it
9
9
  > when missing.
10
10
 
11
+ **On a spec with committed scope contracts, this loop is now CODE, not prose** —
12
+ `skills/tech-lead/workflows/shapeup-run.js`'s own `while (round <= args.budgets.maxRounds)` loop
13
+ implements exactly the shape below (PASS → ship; `max_rounds` exceeded → GATE H `breaker: outer`;
14
+ else the next round builds bugs only), with the EVAL-timing rule, the regression rule, and the
15
+ three-level breaker all enforced as branches in that script rather than described here for a model
16
+ to follow. Read that script's own comments for the mechanics; this file keeps the historical
17
+ rationale and the parts of the protocol the script does not cover (ESCALATE adjudication,
18
+ discovered-task reconciliation mid-BUILD — see its banner
19
+ for the full list) — and, unchanged, the loop below for a `--tiny` run or a spec with no scope
20
+ contracts, which `shapeup-run.js` is out of scope for by design.
21
+
11
22
  ```
12
23
  round r = 1
13
24
  loop:
@@ -79,7 +90,6 @@ QA is a pure worker: no verdict, no score, no gate — it writes `~` findings to
79
90
  `discovery/ledger.md` and a `qa/hunt-report.md`. Triage happens at SHIP/GATE L4:
80
91
  - all findings stay `~` → SHIP; findings carry over as raw ideas (debt-free).
81
92
  - PO/TL promote any to must-have → a fix round r+1 (those items only) → EVAL
82
- `--single-pass` on them → `/qa-edge-hunter --recheck` (re-probe ONLY the promoted items;
83
93
  never a second full hunt) → back to L4.
84
94
  - Circuit breaker applies: out of rounds/appetite → ship with `~` findings recorded.
85
95
  QA never runs on a FAIL round — a build that hasn't passed conformance isn't worth
@@ -98,15 +108,17 @@ coherent to evaluate yet.
98
108
  (scope contracts present: also `/scope-hammer --breaker outer`). Do not start another
99
109
  build round automatically.
100
110
  3. **attempt_budget (INNER breaker, scope contracts only)** — a single scope's T0 attempt
101
- loop exhausts `--attempts` (default 5) without a green result does NOT stop the round;
102
- queues a hammer PROPOSAL for GATE H and moves to the next scope in sequence. See
103
- "Three-level circuit breaker" below.
111
+ loop exhausts `--attempts` (default 5) without reaching a trial that is both `kept` and
112
+ T0-green, **or** `no_progress_k` consecutive trials come back non-`kept` (the stagnation
113
+ term, default 2 — `compile-order.mjs` prints it as a JSON breaker object on stderr) →
114
+ does NOT stop the round; queues a hammer PROPOSAL for GATE H and moves to the next scope
115
+ in sequence. See "Three-level circuit breaker" below.
104
116
  4. **wall_clock_budget (DEADLINE breaker, opt-in)** — elapsed seconds since the run receipt
105
117
  exceed `--wall-clock-budget` → do NOT start another build round or another scope; go
106
118
  straight to GATE H (`/scope-hammer --breaker deadline`). Checked with
107
119
  `scripts/budget-check.mjs` at every round boundary and enforced by `hooks/gate-deadline.mjs`,
108
120
  which denies a `task-executor` dispatch past the deadline while leaving `spec-evaluator`,
109
- `scope-hammer`, `qa-edge-hunter` and `advisor-protocol` reachable — a run past its deadline
121
+ `scope-hammer` and `qa-edge-hunter` reachable — a run past its deadline
110
122
  must still be able to judge, hammer, and close. Off unless configured.
111
123
  5. **Hard error** — a sub-skill fails irrecoverably (e.g. spec folder gone, app won't
112
124
  build at all) → stop and report; do not retry blindly.
@@ -124,26 +136,29 @@ INNER attempt_budget (per scope) — decremented once per T0 attempt inside B
124
136
  inner breaker for that scope only: the scope is queued
125
137
  as a hammer PROPOSAL (not a hard stop) and the round
126
138
  moves on to the next scope in the L1b sequence.
139
+ no_progress_k (default 2) is COMPOSED INTO this same
140
+ breaker rather than added beside it as a fourth budget:
141
+ attempt_budget counts attempts and cannot see that the
142
+ last two produced nothing, so k consecutive non-`kept`
143
+ trials queue the same GATE H proposal early.
127
144
  DEADLINE wall_clock_budget_s — elapsed seconds since the run receipt. Opt-in; off
128
145
  unless set at L0. Tripping routes to GATE H with
129
146
  --breaker deadline. Enforced by hooks/gate-deadline.mjs.
130
147
  ```
131
148
 
132
- **Why the third one exists — it was measured, and it corrected an earlier diagnosis.** On the
133
- SDD harness benchmark (F3, Sonnet 5) this harness was killed at the declared 1800 s cap and
134
- published as a DNF. The natural reading was that it had stalled at a gate. Re-reading the
135
- retained transcript says otherwise: **327 turns, 262 tool calls, 37 file writes, 19 gate markers,
136
- last gate L3, and zero stall signals** — the least talkative shapeup run in the whole matrix. It
137
- was working when the clock ran out.
149
+ **Why the third one exists — and it corrects an earlier diagnosis.** A run killed at an external
150
+ time cap looks like a stall from outside: no verdict, nothing to show. The natural reading is that
151
+ it hung at a gate. Often the transcript says otherwise steady turns, steady writes, gate markers
152
+ advancing, zero stall signals. The run was working when the clock ran out.
138
153
 
139
154
  Both existing breakers count *events*, not time: `round_budget` moves once per round,
140
155
  `attempt_budget` once per T0 attempt. Neither can observe that round 1 has been running for
141
156
  twenty-nine minutes, so a run can burn its entire wall clock with both breakers untouched. The
142
- cost is not the DNF row — it is that a run killed from *outside* ships nothing, not even the
157
+ cost is not the missing verdict — it is that a run killed from *outside* ships nothing, not even the
143
158
  scopes that were already green. A breaker that trips from the inside routes to GATE H, where
144
159
  scope-hammer compares the shippable subset against the baseline and ships what works. Same clock,
145
160
  different ending.
146
- Nesting rationale (DD-9): a struggling scope should not freeze every other scope's progress
161
+ Nesting rationale: a struggling scope should not freeze every other scope's progress
147
162
  in the same round — only running out of *rounds* (the real six-week analog) stops the whole
148
163
  run. A scope that trips its inner breaker still gets judged fairly at GATE H: scope-hammer
149
164
  compares "ship without this scope" against the baseline, same as any other cut candidate — it
@@ -151,24 +166,56 @@ is never silently dropped, and it is never allowed to block scopes that ARE work
151
166
 
152
167
  ## Isolated attempt loop — one T0 attempt, in detail (scope contracts only)
153
168
 
169
+ **This is `shapeup-run.js`'s inner per-scope loop, as code**, with one addition the prose below
170
+ never had: before opening a scope's attempt loop, the script checks whether THIS round already
171
+ has a green T0 verdict for that scope on disk, and skips it when it does — the resumability a
172
+ mid-BUILD kill needs, that a session narrating this loop from memory could never guarantee.
173
+
174
+ Whichever runs it, the loop is a **ratchet**: every attempt is scored against the last kept one,
175
+ and the working tree moves forward only when the score strictly improves. `t0-verify.mjs` makes
176
+ that decision and acts on the tree itself, inside the runtime — its caller reads the decision, it
177
+ never makes it.
178
+
154
179
  ```
155
180
  compile-order --scope … --round N --attempt M
156
181
  → zero-memory WorkOrder (scope contract + this scope's
157
- tasks + digested errors + ledger decisions — compiled
158
- facts, no chat history by construction)
182
+ tasks + digested errors + ledger decisions +
183
+ trial_history: the last 8 trials for this scope, each
184
+ with score, status, delta and top-3 digest, CROSSING the
185
+ round boundary — compiled facts, no chat history by
186
+ construction)
159
187
  dispatch task-executor --order … → code within substrate; WorkResult in results/
160
- ingest-result <result> → board/ledger writes; escalates[] queued
161
- handle_escalations(≤3/scope/round) /advisor-protocol; answer promoted to round-ledger.md
162
- immediately (must survive the NEXT attempt's fresh
163
- context this is what "zero-memory" is compatible with
164
- escalation memory means, DD-8)
165
- t0-verify.mjs → fixtures + DB probe + (on green) seesaw
166
- green attempt loop breaks; scope reaches DOWNHILL_EXECUTION
167
- red, regression → git stash (never a hard discard) + retry; a FINISHED scope's fixture
168
- broke (PA5) — the whole point of running seesaw before declaring green
169
- red, own fixture → AEGIS-digest the failure into {file, line, core_message} triples,
170
- feed them into the NEXT attempt's brief; loop
188
+ ingest-result <result> → board/ledger writes
189
+ (a worker cannot escalate) WorkResult carries no escalates field. A phase that
190
+ cannot finish leaves no artifact, the post-condition
191
+ fails, and the run ABORTS naming the phase. Resolve it
192
+ yourself and record the answer in round-ledger.md, which
193
+ the NEXT attempt's fresh context reads back.
194
+ t0-verify.mjs fixtures + DB probe + (on green) seesaw, then scores the
195
+ attempt against the baseline trial and snapshots or
196
+ restores the tree. Branch on `status` from its stdout
197
+ JSON the tree action has ALREADY happened:
198
+ kept strictly better, INCLUDING red-but-improved (2/5 4/5 fixtures — the whole point
199
+ of the ratchet). Tree snapshotted to refs/shapeup/<scope_id>/kept.
200
+ overall=green → the attempt loop breaks; scope reaches DOWNHILL_EXECUTION.
201
+ Still red → loop, and attempt M+1 now builds ON attempt M.
202
+ reverted not better — and a tie is not better. Tree already restored from the last kept
203
+ snapshot. Subsumes the retired stash-and-retry branch: a FINISHED scope's broken
204
+ fixture raises score.regressions and reverts through this same rule, which
205
+ is why seesaw runs before anything is declared green.
206
+ rather than the code. Tree kept, baseline reset. Not a verdict, not a failure.
207
+ crash a fixture command failed to spawn or timed out; tree restored. Fix the fixture,
208
+ not the code.
209
+ (on any red, `discovered_tasks` carries the AEGIS {file, line, core_message} triples, which
210
+ compile-order folds into the NEXT attempt's order as digested_errors — no separate dispatch)
171
211
  ```
212
+
213
+ **The exit code is not the branch selector.** `t0-verify.mjs` exits 0 on T0-green and 1 on
214
+ T0-red (2 on bad argv), mirroring the `oracles/*` convention — so a `kept` red-but-improved
215
+ attempt, the exact case the ratchet exists for, exits 1. Branch on `status` from the stdout
216
+ JSON; never on `$?`, and never wire this call into a `set -e` / `&&` chain that would read a
217
+ non-zero exit as "stop".
218
+
172
219
  This replaces the old flat per-task loop for any scope that has a contract;
173
220
  scopes/specs without one keep the v0.2.6 behavior verbatim (see BUILD(r) table above).
174
221
 
@@ -176,9 +223,12 @@ scopes/specs without one keep the v0.2.6 behavior verbatim (see BUILD(r) table a
176
223
  A tech-lead judgment, surfaced at GATE L2: if the feature is clearly within what the model
177
224
  builds reliably solo, the evaluator is optional overhead. With `--no-eval`, after GATE L2
178
225
  the run goes straight to SHIP with verdict `not-evaluated` recorded in the ledger and a
179
- clear note that nothing was verified beyond the build's own task-executor GATE D checks.
226
+ clear note that nothing was verified beyond task-executor's own per-AC evidence checks.
180
227
 
181
228
  ## Round-cost intuition
182
229
  Build dominates; eval is cheap. Expect each EVAL round to cost a small fraction of a BUILD
183
230
  round. This is why running eval once per round (not per task) is the right trade: you pay a
184
231
  little QA at the end of each build and keep the expensive build coherent in between.
232
+
233
+ <!-- test requirement -->
234
+ kept|reverted|rebased|crash, decided in t0-verify.mjs decideStatus()
@@ -53,7 +53,7 @@ A second, committed `round-ledger.md` (`shapeup/<slug>/round-ledger.md`, SHARED,
53
53
  Tier A) holds only what must survive a crash or a `.shapeup/` wipe:
54
54
 
55
55
  - the resolved model/budget matrix (L0.8/L0.9),
56
- - the **Decisions** table — every gate crossing and every advisor-protocol ESCALATE answer,
56
+ - the **Decisions** table — every gate crossing and every PO answer to a blocked phase,
57
57
  promoted the instant it is given, never batched to round close.
58
58
 
59
59
  Gate crossings resolved from a **gate answer set** (`scripts/gate-answers.mjs`) are written here