shapeup-sdlc 1.7.0 → 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.
Files changed (98) hide show
  1. package/.claude/settings.local.example.json +5 -5
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/AGENTS.md +17 -3
  4. package/README.md +124 -103
  5. package/SECURITY.md +37 -30
  6. package/bin/init.mjs +77 -47
  7. package/bin/lib/grant.mjs +145 -0
  8. package/commands/build.md +7 -6
  9. package/commands/ship.md +29 -16
  10. package/commands/wire.md +1 -1
  11. package/hooks/dispatch-receipt.mjs +195 -0
  12. package/hooks/gate-intake.mjs +3 -3
  13. package/hooks/gate-zerowork.mjs +25 -24
  14. package/hooks/hooks.json +9 -48
  15. package/hooks/lib/decision.mjs +19 -8
  16. package/hooks/safety-spine.mjs +3 -3
  17. package/hooks/sandbox-guard.mjs +84 -40
  18. package/{skills/tech-lead/scripts/compile-order.mjs → kernel/compile.mjs} +283 -41
  19. package/{skills/tech-lead/scripts/gate-answers.mjs → kernel/gate.mjs} +58 -14
  20. package/kernel/harness.mjs +134 -0
  21. package/{skills/tech-lead/scripts/fit-check.mjs → kernel/init/fit.mjs} +15 -12
  22. package/{skills/tech-lead/scripts/init-run.mjs → kernel/init/run.mjs} +152 -31
  23. package/{skills/tech-lead/scripts → kernel}/lib/argv.mjs +52 -31
  24. package/{skills/tech-lead/scripts/lib/contract-md.mjs → kernel/lib/contract.mjs} +251 -7
  25. package/kernel/lib/paths.mjs +491 -0
  26. package/kernel/probe/concurrency.mjs +510 -0
  27. package/{skills/tech-lead/scripts/aegis-digest.mjs → kernel/probe/digest.mjs} +9 -10
  28. package/kernel/probe/eval.mjs +77 -0
  29. package/kernel/probe/leg.mjs +125 -0
  30. package/{skills/tech-lead/scripts/resume-state.mjs → kernel/probe/resume.mjs} +204 -63
  31. package/{skills/tech-lead/scripts → kernel/probe}/stats.mjs +93 -11
  32. package/kernel/probe/t0.mjs +66 -0
  33. package/{skills/ba-pitch-analyzer/scripts/board-derive.mjs → kernel/reduce/board.mjs} +99 -23
  34. package/kernel/reduce/graph.mjs +437 -0
  35. package/{skills/tech-lead/scripts/hill-derive.mjs → kernel/reduce/hill.mjs} +28 -9
  36. package/kernel/reduce/ingest.mjs +633 -0
  37. package/{hooks/slop-cleaner.mjs → kernel/reduce/leftovers.mjs} +40 -57
  38. package/{skills/tech-lead/scripts/ship-report.mjs → kernel/reduce/ship.mjs} +61 -13
  39. package/{skills/tech-lead/scripts/run-snapshot.mjs → kernel/reduce/snapshot.mjs} +21 -15
  40. package/{skills/spec-evaluator/scripts/verdict-ledger.mjs → kernel/reduce/verdict.mjs} +13 -7
  41. package/kernel/report/export.mjs +325 -0
  42. package/kernel/report/facts.mjs +347 -0
  43. package/{skills/tech-lead/scripts/budget-check.mjs → kernel/verify/budget.mjs} +15 -12
  44. package/kernel/verify/dispatch.mjs +114 -0
  45. package/{skills/tech-lead/scripts/validate-envelope.mjs → kernel/verify/envelope.mjs} +20 -15
  46. package/{skills/tech-lead/scripts/lib → kernel/verify}/ratchet-tree.mjs +36 -14
  47. package/kernel/verify/skills.mjs +125 -0
  48. package/kernel/verify/spec.mjs +559 -0
  49. package/{skills/tech-lead/scripts/t0-verify.mjs → kernel/verify/t0.mjs} +134 -24
  50. package/{skills/tech-lead/scripts/trace-lint.mjs → kernel/verify/trace.mjs} +26 -11
  51. package/oracles/http-oracle.mjs +1 -1
  52. package/oracles/process-oracle.mjs +1 -1
  53. package/oracles/snapshot-oracle.mjs +1 -1
  54. package/oracles/test-oracle.mjs +1 -1
  55. package/package.json +11 -9
  56. package/skills/ba-pitch-analyzer/SKILL.md +5 -5
  57. package/skills/ba-pitch-analyzer/assets/templates/_index.tmpl.md +1 -1
  58. package/skills/ba-pitch-analyzer/assets/templates/api-feasibility.tmpl.md +12 -7
  59. package/skills/ba-pitch-analyzer/assets/templates/contracts/third-party-api.contract.tmpl.md +6 -3
  60. package/skills/ba-pitch-analyzer/assets/templates/cross-context/migration-plan.tmpl.md +5 -4
  61. package/skills/ba-pitch-analyzer/assets/templates/cross-context/team-handoff.tmpl.md +23 -13
  62. package/skills/ba-pitch-analyzer/assets/templates/scope-summary.tmpl.md +17 -12
  63. package/skills/ba-pitch-analyzer/assets/templates/synthesis.tmpl.md +17 -38
  64. package/skills/ba-pitch-analyzer/assets/templates/task.tmpl.md +3 -0
  65. package/skills/ba-pitch-analyzer/references/contract-patterns.md +8 -4
  66. package/skills/ba-pitch-analyzer/references/doc-schemas.md +2 -0
  67. package/skills/ba-pitch-analyzer/references/task-generation.md +2 -2
  68. package/skills/qa-edge-hunter/SKILL.md +7 -3
  69. package/skills/scope-architect/SKILL.md +40 -6
  70. package/skills/solution-architect/SKILL.md +19 -4
  71. package/skills/spec-evaluator/SKILL.md +12 -2
  72. package/skills/task-executor/SKILL.md +7 -6
  73. package/skills/tech-lead/SKILL.md +50 -38
  74. package/skills/tech-lead/references/gates.md +69 -20
  75. package/skills/tech-lead/references/protocol.md +832 -0
  76. package/skills/tech-lead/schemas/domain.schema.json +341 -66
  77. package/skills/tech-lead/schemas/work-order.schema.json +11 -2
  78. package/skills/tech-lead/schemas/work-result.schema.json +1 -1
  79. package/skills/tech-lead/workflows/shapeup-run.js +1313 -750
  80. package/hooks/anti-rationalization.mjs +0 -238
  81. package/hooks/compact-snapshot.mjs +0 -47
  82. package/hooks/gate-deadline.mjs +0 -147
  83. package/hooks/gate-l2.mjs +0 -161
  84. package/hooks/session-rehydrate.mjs +0 -108
  85. package/skills/ba-pitch-analyzer/scripts/spec-lint.mjs +0 -239
  86. package/skills/spec-evaluator/README.md +0 -93
  87. package/skills/tech-lead/README.md +0 -71
  88. package/skills/tech-lead/references/delegation.md +0 -261
  89. package/skills/tech-lead/references/hard-rules.md +0 -34
  90. package/skills/tech-lead/references/invocation.md +0 -45
  91. package/skills/tech-lead/references/ledger-schema.md +0 -213
  92. package/skills/tech-lead/references/round-protocol.md +0 -234
  93. package/skills/tech-lead/references/state-model.md +0 -66
  94. package/skills/tech-lead/scripts/ingest-result.mjs +0 -258
  95. package/skills/tech-lead/scripts/lib/is-main.mjs +0 -81
  96. package/skills/tech-lead/scripts/lib/paths.mjs +0 -280
  97. package/skills/tech-lead/scripts/run-workflow.mjs +0 -381
  98. package/skills/translator/README.md +0 -66
@@ -1,261 +0,0 @@
1
- # Delegation
2
-
3
- The tech lead invokes the build-phase skills and reads their handoff files. It never
4
- reimplements their logic. Each sub-skill keeps its own gates; pass `--auto` to a sub-skill
5
- only when the run's auto level is `--auto` or `--unattended`.
6
-
7
- ## Invocation mechanism — Agent, not Skill
8
-
9
- Every "Invoke:" line below means: call the **Agent** tool — a real subagent, on its own
10
- context and (where a role is named) its own model — whose prompt tells it to run
11
- `Skill(shapeup-sdlc-plugin:<name>)` with the given args and report back the artifacts. It does
12
- **not** mean the tech lead calls the `Skill` tool itself. A direct `Skill` call executes
13
- inline, in the tech lead's own turn, on the tech lead's own model — that silently drops GATE
14
- L0.8's model matrix (there is no per-role model left to route once the call is inline) and
15
- breaks the isolation the zero-memory-handoff design (`round-protocol.md`, the compiled
16
- WorkOrder in `orders/r<N>-a<M>.json`) already assumes every worker below has.
17
-
18
- Standard shape (pure-skill architecture v1.0 — the envelope port):
19
- ```
20
- 1. node "${CLAUDE_PLUGIN_ROOT}/skills/tech-lead/scripts/compile-order.mjs" <mode flags> # → orders/<id>.json
21
- 2. Agent({
22
- description: "<short task description>",
23
- subagent_type: "general-purpose",
24
- model: "<role model resolved at GATE L0.8>",
25
- prompt: "Call Skill(shapeup-sdlc-plugin:<skill>) --order <orders/<id>.json>.
26
- Report back: the WorkResult path (.shapeup/<slug>/results/<id>.json)."
27
- })
28
- 3. node "${CLAUDE_PLUGIN_ROOT}/skills/tech-lead/scripts/ingest-result.mjs" .shapeup/<slug>/results/<id>.json
29
- ```
30
- The WorkOrder carries everything the worker may rely on (payload, decisions, digested errors,
31
- substrate write-contract); the WorkResult carries everything the worker used to write into
32
- shared files. `validate-envelope.mjs` runs as a PreToolUse hook on Skill|Agent and DENIES a
33
- dispatch whose `--order` file is missing or schema-invalid. Workers write only their own
34
- domain artifacts inside their substrate — never boards, ledgers, or run-state.
35
-
36
- Role → model, resolved once at GATE L0.8 from the `orch`/`exec`/`eval`/`qa` matrix
37
- (`t0-verify.mjs` is mechanical tooling run directly via Bash, never an Agent — zero LLM
38
- tokens):
39
-
40
- | Skill | L0.8 role | Why this tier |
41
- |-------|-----------|---------------|
42
- | translator | exec | one-shot text transform — builder tier |
43
- | orient (Scout) | exec | reads/spikes code — builder tier, not judgment |
44
- | ba-pitch-analyzer | exec | planner — builder tier, not judgment |
45
- | scope-architect | exec | scope-contract author (sole writer of scopes/*.md) — builder tier |
46
- | task-executor | exec | the builder itself |
47
- | spec-evaluator | eval | the single judge (judge ≠ doer) — keep its own matrix key even if a PO points it at the same model as `exec`, so it can be split later without a harness change |
48
- | qa-edge-hunter | qa | cheapest tier by design — exploratory breadth over depth |
49
- | scope-hammer | exec | census + baseline comparison, proposes only — not a verdict |
50
- | coach | exec | categorization gate, not a verdict |
51
-
52
- The tech lead itself is `orch` — this conversation, never delegated to.
53
-
54
- The order is **Orient (7) → Map Scopes (8) → Build (9) → Eval**, faithful to Shape Up: the
55
- team orients before any board exists, so the planner's board is reality-born. The tech lead
56
- is the **sole writer of run-state** (`harness-run.md`) — it passes each worker the run
57
- metadata it needs (`feature`, `spec`, `stack`, `discovered_rounds`, `--auto`) as **args**;
58
- workers keep only their own product-idempotency key and emit domain artifacts.
59
-
60
- ## 0. LANGUAGE GATE → translator (GATE L0, only if non-English)
61
- ```
62
- Invoke via Agent (model: exec): Skill(shapeup-sdlc-plugin:translator) --check "<intake path>"
63
- # detect-only, writes nothing
64
- English → skip; ORIENT against the original.
65
- non-English → Agent (model: exec): Skill(shapeup-sdlc-plugin:translator) "<intake path>" [--auto]
66
- # full pass
67
- Writes: <name>.en.md (English copy; original untouched) + glossary.md
68
- + translation-report.md.
69
- ORIENT against the <name>.en.md copy.
70
- Read back: the detect table (--check) / the .en.md path + residual scan result (full pass).
71
- Authority: translator normalizes language only — it does not orient/plan/build/judge. The tech
72
- lead never translates itself; it only detects and sequences this step before ORIENT.
73
- ```
74
-
75
- ## 1. ORIENT → orient (the Scout, step 7) — runs BEFORE planning
76
- ```
77
- Invoke via Agent (model: exec): Skill(shapeup-sdlc-plugin:orient)
78
- --pitch "<kicked-off pitch path>" --spec <path> --stack "<hint>" [--auto]
79
- Owns: its own GATE O-A/O-B (or runs straight through under --auto)
80
- Writes: .shapeup/<slug>/orient/ → code-surface.md, spike-<area>.md, discovered-seed.md, hill-signal.md (LOCAL run-trace)
81
- Read back: hill-signal.md (render the area-level Hill at GATE L1a) + the spiked area/result.
82
- Why first: at Orient time NO board exists; the Scout's map + discovered seed make the planner's
83
- board reality-born instead of imagined. The four artifacts are the orient→ba contract.
84
- Authority: pure worker — no code, no board, no run-state, no reporting.
85
- ```
86
-
87
- ## 2. MAP SCOPES → ba-pitch-analyzer + scope-architect (step 8, orient-informed)
88
- ```
89
- Order A (the spec tree + board):
90
- compile-order --operation analyze --slug <slug> --worker ba-pitch-analyzer
91
- --payload '{"pitch": "<path>", "lens": "<lens>", "orient_dir": ".shapeup/<slug>/orient/"}'
92
- Agent (model: exec): Skill(shapeup-sdlc-plugin:ba-pitch-analyzer) --order <path>
93
- The order hands it code-surface.md (Phase-1 ingest, no re-scan), discovered-seed.md (task
94
- gen from reality), spike-<area>.md (feasibility/contracts).
95
- Writes (its substrate): spec_folder → _index.md, domain-model.md, ux-behavior.md, usecases/*,
96
- contracts/*.contract.md, scope-summary.md (+ api-feasibility.md if third-party) and the
97
- Returns: WorkResult (artifacts list + discoveries) → ingest-result.
98
- Order B (the scope contracts):
99
- compile-order --operation map-scopes --slug <slug> --worker scope-architect
100
- Agent (model: exec): Skill(shapeup-sdlc-plugin:scope-architect) --order <path>
101
- Writes (its substrate): shapeup/<slug>/scopes/*.md + scope-board.md — sole
102
- writer. Lint mechanically: node "${CLAUDE_PLUGIN_ROOT}/skills/ba-pitch-analyzer/scripts/spec-lint.mjs" <slug> (PA1/PA2 +
103
- substrate disjointness) before GATE L1b.
104
- Read back: .shapeup/<slug>/tasks/_index.md (the board) + scope-summary.md (Done-when)
105
- + the spec-lint verdict.
106
- Pass-through rule: do not coach the planner to over-specify implementation — keep tech high-level.
107
- ```
108
-
109
- ## 2b. RECONCILE → ba-pitch-analyzer (discovered task reconciliation, operation: reconcile)
110
- ```
111
- compile-order --operation reconcile --slug <slug> --worker ba-pitch-analyzer
112
- --payload '{"discovered_ledger": ".shapeup/<slug>/discovery/ledger.md"}'
113
- Agent (model: exec): Skill(shapeup-sdlc-plugin:ba-pitch-analyzer) --order <path>
114
- Effect: reconciles raw ledger discoveries into board tasks + appended UC invariants/TS rows,
115
- inside the reconcile write-contract (frozen zone enforced by the sandbox hook, not
116
- prose). Appetite Guard runs mechanically: node "${CLAUDE_PLUGIN_ROOT}/skills/ba-pitch-analyzer/scripts/board-derive.mjs".
117
- Returns: WorkResult → ingest-result (which updates the board and bumps discovered_rounds in
118
- harness-run.md — the worker holds no counter).
119
- Read back: updated tasks/_index.md + scope-summary.md before routing back to GATE L1b.
120
- ```
121
-
122
- Agent (model: exec): Skill(shapeup-sdlc-plugin:ba-pitch-analyzer) --order <path>
123
- Effect: regenerates the LOCAL task board fresh from the committed usecases/domain-model/scopes
124
- — no ledger, no reconciliation. Status bootstraps from committed T0/hill facts at
125
- SCOPE granularity; unlocks recomputed by node "${CLAUDE_PLUGIN_ROOT}/skills/ba-pitch-analyzer/scripts/board-derive.mjs" --write.
126
- Read back: the freshly regenerated tasks/_index.md before entering BUILD.
127
- ```
128
-
129
- ## 3. BUILD → task-executor (always through the envelope port)
130
- ```
131
- r=1 loop:
132
- compile-order --next --slug <slug> [--test-cmd "<cmd>"] # exit 2 = no ready task
133
- Agent (model: exec), one fresh subagent per order:
134
- Skill(shapeup-sdlc-plugin:task-executor) --order <path>
135
- ingest-result <results/<id>.json> # ticks ACs, marks done, updates board, propagates unblocks
136
- Repeat until compile-order --next reports no ready task (board all ✅).
137
-
138
- r>1 (fix) per bug:
139
- compile-order --task <id> --slug <slug> --operation fix --payload '{"bugs": [<entries>]}'
140
- → dispatch + ingest as above. Scope the change to the bug only.
141
-
142
- Scope contracts present (isolated attempt loop, per scope, per attempt):
143
- compile-order --scope shapeup/<slug>/scopes/<id>.md --round <N> --attempt <M>
144
- → orders/r<N>-a<M>.json inlines the scope contract, this scope's tasks, promoted ledger
145
- decisions, the previous attempt's AEGIS triples, and `trial_history` — the last 8 trials
146
- for this scope (score, status, delta, top-3 digest), CROSSING the round boundary so a fix
147
- round cannot re-propose a change the build round already reverted. The zero-memory
148
- handoff, compiled from facts only. Dispatch a fresh Agent per attempt (the isolation
149
- boundary):
150
- Skill(shapeup-sdlc-plugin:task-executor) --order <path>
151
- ingest-result — a WorkResult with status "escalated" leaves its artifact unwritten → see 3b below.
152
-
153
- Read back: ingest-result's summary line (tasks updated, ACs ticked, unblocked, discoveries) — not raw board
154
- files. SPIKE tasks close before the tasks they block can build (compile-order enforces the
155
- dependency order).
156
- ```
157
-
158
- ## 3b. A worker that cannot finish (scope contracts present, mid-attempt)
159
- ```
160
- There is NO adjudication dispatch. A worker has no port for "I cannot decide this": WorkResult
161
- carries no escalates field, so the question never reaches you as data.
162
- What you see: the phase produces no artifact. The workflow's post-condition
163
- (resume-state.mjs --require <phase>) fails and the run ABORTS, naming the phase.
164
- Do: read the phase's result file to find what it could not complete, resolve it yourself —
165
- by amending the spec, widening the scope contract, or answering the ambiguity in the
166
- round-ledger "Decisions" table — then relaunch. The fast-forward re-dispatches only
167
- what is still unfinished.
168
- Why it aborts rather than pauses: nothing persists an answer between launches, so a pause
169
- would relaunch into the same order and hit the same wall. Aborting puts the question
170
- in front of a human once instead of looping silently.
171
- ```
172
-
173
- ## 3c. T0 verify → scripts/t0-verify.mjs (skill-local; scope contracts present, every attempt)
174
- ```
175
- Invoke via Bash directly — NOT an Agent, this is deterministic tooling, not a worker:
176
- node "${CLAUDE_PLUGIN_ROOT}/skills/tech-lead/scripts/t0-verify.mjs" shapeup/<slug>/scopes/<scope-id>.md
177
- --round <N> --attempt <M> --seesaw-registry .shapeup/<slug>/seesaw/registry.json
178
- Effect: runs the scope's e2e fixtures + DB probe, then (on green) the seesaw regression check
179
- over every FINISHED scope's fixtures. Writes the verdict artifact spec-evaluator's
180
- T0-citation rule will require a citation to, appends one row to t0/trials.jsonl, and — this
181
- is the ratchet — scores the attempt against the last kept trial and snapshots or
182
- restores the working tree ITSELF. Zero LLM tokens — deterministic tooling, not a
183
- judge (this is what keeps "T1 once per round" true even though verification runs
184
- every attempt).
185
- Read back: the stdout JSON — {path, sha256, trial, overall, regression, score, status,
186
- baseline_trial, delta, tree_ref}. `status` (kept|reverted|rebased|crash) is what
187
- drives the attempt-loop branch in round-protocol.md "Isolated attempt loop"; by the
188
- time you read it the tree action has already happened. Never branch on the process
189
- exit code: it carries the T0 binary (0 green / 1 red / 2 bad argv, the oracles/*
190
- convention), so a `kept` red-but-improved attempt, the ratchet's own signature case,
191
- exits 1. On red, its `discovered_tasks` field is
192
- the AEGIS digest to fold into the next brief — no separate digester dispatch needed
193
- (t0-verify.mjs calls its sibling aegis-digest.mjs internally on failure).
194
- ```
195
-
196
- ## 4. EVAL → spec-evaluator (once per round)
197
- ```
198
- compile-order --operation evaluate --slug <slug> --worker spec-evaluator --round <r>
199
- --payload '{"dimensions": ["spec-conformance"], "run_cmd": "<cmd>", "t0_artifacts": [...]}'
200
- Invoke via Agent (model: eval), ONCE, after GATE L2:
201
- Skill(shapeup-sdlc-plugin:spec-evaluator) --order <path>
202
- Effect: one feature-level pass over the running app against all AC + Done-when; writes
203
- evaluation/EVAL-FEATURE-<slug>.md (verdict + bug list) + its WorkResult (criteria
204
- verdicts, refuted boxes, T0 citations). It touches NO task file and NO board.
205
- ingest-result <results/evaluate-r<r>.json>: appends the .verdicts JSONL ledger, un-ticks the
206
- refuted AC boxes, sets eval_verdict frontmatter — the judge returns data, ingest writes.
207
- Read back: EVAL-FEATURE-<slug>.md → verdict (pass|fail) + the bug list (each bug has
208
- task ref, severity, file:line, expected vs actual).
209
- ```
210
-
211
- > Dependency note: this uses spec-evaluator's **feature-level** pass (`--feature <slug>`),
212
- > which evaluates the whole board in one session rather than one task at a time. If your
213
- > installed spec-evaluator is the per-task v0.1, add the `--feature` mode (a small v0.2
214
- > patch: iterate the board's AC/Done-when in one probe+grade session, emit one
215
- > EVAL-FEATURE report) before wiring the tech lead to it. The per-task invocation still
216
- > works for ad-hoc checks, but the round loop expects one feature pass.
217
-
218
- ## 5. SHIP / GATE H → scope-hammer
219
- ```
220
- Invoke via Agent (model: exec): Skill(shapeup-sdlc-plugin:scope-hammer)
221
- --slug <slug> [--baseline <path>] [--breaker outer|inner --scope <id>]
222
- Effect: GATE H0 census (scopes + QA findings + discovered ledger + advisor-overflow flags) →
223
- H1 baseline comparison (never vs. a perfect ideal) → H2 cut list + verdict.
224
- Read back: the proposed cut list + verdict (SHIP now | SHIP after fixing ship-blocking items |
225
- CANNOT SHIP). The tech lead records the PO's decision in round-ledger.md and performs
226
- the actual close (SHIP S.1 onward) — scope-hammer proposes, it never ships.
227
- ```
228
-
229
- ## Authority boundaries (do not cross)
230
- - The Scout orients; it never plans, builds, or judges — it hands raw material to the planner.
231
- - The planner decides scope; the tech lead confirms it with the PO at GATE L1b.
232
- - The generator reports task outcomes in its WorkResult; `ingest-result.mjs` flips `status:
233
- done` from that report. The tech lead confirms the feature-level close at GATE L4.
234
- - The evaluator issues verdicts only; it never closes tasks. Judge ≠ doer.
235
- - The tech lead decides *when* and *whether* each skill runs and how rounds proceed, owns
236
- run-state + the Hill report — it does not decide *what* a task contains or *whether* a
237
- single AC passes.
238
-
239
- ## Handoff files (the shared state)
240
- | File | Written by | Read by |
241
- |------|-----------|---------|
242
- | `<name>.en.md` + `glossary.md` | translator (L0, if non-English) | tech lead (ORIENT input), Scout, planner |
243
- | `orient/code-surface.md` | Scout (step 7) | planner Phase 1 (ingest, no re-scan) |
244
- | `orient/spike-<area>.md` | Scout (step 7) | planner Phase 1b/contracts; tech lead (L1a) |
245
- | `orient/discovered-seed.md` | Scout (step 7) | planner Phase 6 (task gen) |
246
- | `orient/hill-signal.md` | Scout (step 7) | tech lead (renders L1a Hill) |
247
- | `orders/<id>.json` (WorkOrder) | **compile-order.mjs (mechanical)** | every worker (its ONLY pipeline input), validate-envelope hook |
248
- | `results/<id>.json` (WorkResult) | the dispatched worker (its ONLY pipeline output) | ingest-result.mjs (the single writer of everything below it) |
249
- | `.shapeup/<slug>/tasks/*` (LOCAL board, v3.2) | **ingest-result.mjs** (status, AC ticks, unblocks) + planner orders (task bodies) | tech lead (board status), compile-order (next task, ACs) |
250
- | `discovery/ledger.md` | **ingest-result.mjs** (from workers' `discoveries[]`) | reconcile orders (ba), scope-hammer (H0 census) |
251
- | `scope-summary.md` | planner (analyze/reconcile orders) | tech lead (Done-when), evaluator (Done-when criteria) |
252
- | `evaluation/EVAL-FEATURE-<slug>.md` + `.verdicts-*.jsonl` | evaluator (report) / **ingest-result.mjs** (verdict ledger, un-ticks) | tech lead (verdict), next fix order (bug list) |
253
- | `harness-run.md` | **tech lead (sole writer)** | tech lead (round ledger + Hill + run-state), PO (audit) |
254
- | `scopes/<scope-id>.md` | `scope-architect` (sole writer) | tech lead (substrate/sequence), sandbox hook (write-whitelist), compile-order (inlined into orders) |
255
- | `t0/verdicts/r<N>-a<M>-t<T>.json` | `scripts/t0-verify.mjs` (skill-local, mechanical — not a worker) | spec-evaluator (required citation), tech lead (hill derivation), compile-order (digested errors) |
256
- | `t0/trials.jsonl` (the ratchet ledger, append-only, `baseline_trial` as the parent link) | `scripts/t0-verify.mjs` (one row per attempt: score, status, delta, tree_ref) | compile-order (`trial_history` into the next order), ship-report (T0 + Ratchet sections), `stats.mjs --ratchet` |
257
- | `round-ledger.md` | **tech lead (sole writer)** | compile-order (decisions into every order), PO (audit) |
258
- | `hill/<scope-id>.yml` + `hill-chart.md` | **tech lead (sole writer)** | PO ("status without asking"), scope-hammer (H0 census) |
259
-
260
- > The single-writer rule is closed mechanically: no worker writes `run-state.md`, the board, or the ledger. A worker
261
- > performing a shared-state write is a defect — route it back through its WorkResult.
@@ -1,34 +0,0 @@
1
- # Hard Rules (never override without explicit user instruction)
2
-
3
- Moved out of `SKILL.md` when the round loop became a launchable script:
4
- most of what this table used to guard against — a partial board reaching EVAL, a gate crossed
5
- on the model's own authority, an evaluator called mid-BUILD — is now a property of
6
- `skills/tech-lead/workflows/shapeup-run.js`'s code, not a rule a model has to remember to obey.
7
- The table stays as the readable rationale for WHY the code is shaped the way it is; the runtime
8
- guarantee lives in the script and, where noted, in a hook.
9
-
10
- | Rule | Rationale |
11
- |------|-----------|
12
- | Orchestrates Building only (steps 7–11); shaping/betting/kick-off are PO-personal, upstream | Intake is a kicked-off pitch, not a raw idea — the tech lead does no shaping/planning-authority work |
13
- | ORIENT (step 7) runs before MAP SCOPES (step 8) | Roadmap: no pre-divided tasks at kick-off; the team orients first so the board is reality-born |
14
- | Intake must be English before ORIENT; tech lead does NOT translate — it delegates to `translator` at GATE L0 | Translation is a separate single-purpose skill; the intake conversation only detects + sequences it, before RunArgs is ever compiled |
15
- | Every worker dispatch goes through the envelope port: compile-order → `--order` → ingest-result; shared state is written ONLY by ingest | The single-writer rule is mechanically true: a worker that writes boards/ledgers/run-state is a defect, and a malformed envelope is denied by the validate-envelope hook before it can corrupt run truth. `shapeup-run.js` uses this same shape for every operation in the central registry — orient, wire, analyze, map-scopes, evaluate, hunt, hammer alike |
16
- | Progress is reported by Hill position, never by counting tasks | The roadmap forbids task-counting; a 90%-done slice can still be stuck uphill on the one unknown that matters |
17
- | Evaluator runs once per round, only after GATE L2 (board 100% done) | The whole point: cheap end-of-round QA, never per task. `shapeup-run.js`'s round loop dispatches spec-evaluator exactly once per iteration, after the GATE L2 resolution — there is no code path that calls it from inside the scope attempt loop |
18
- | Evaluator never called inside the BUILD loop | Keeps the build coherent and the run cheap |
19
- | r>1 builds bugs only, never the whole board | Don't re-do passing work; minimize churn — see round-protocol.md's regression rule for what DOES re-run (touched UCs' full Test Surface) |
20
- | Stop at max_rounds; escalate honestly | No infinite fix loops; `shapeup-run.js` returns `{status: "gate_h", breaker: "outer"}` rather than looping past the budget |
21
- | Tech lead delegates, never reimplements a sub-skill | Stays thin; each skill keeps its own gates and authority |
22
- | Every delegation to a sub-skill (except the mechanical `t0-verify.mjs`/`compile-order.mjs`/`ingest-result.mjs`) is a fresh Agent on the L0.8-resolved model | Isolation the zero-memory-handoff design assumes; a direct inline call would silently drop the model matrix — see references/delegation.md "Invocation mechanism" |
23
- | Planner stays high-level on tech | Spec errors cascade into every build round |
24
- | Never auto-deploy; "shipped" never silently means "deployed" | Deploy is outward-facing, PO-gated; record "deploy pending (PO)" otherwise |
25
- | "Shipped" names the dims NOT evaluated | `RunReturn`'s `dims_not_evaluated` field carries this; the L4 sign-off block shows it, never silently drops it |
26
- | Every gate emits the canonical `⏸ GATE LN — Title` block before any narrative | Composed by the workflow (`gateBlock()`), emitted VERBATIM by the skill — conversational re-summary is not a gate |
27
- | In interactive/--auto: a `paused` return stops and waits for PO confirmation | Never auto-proceed past a gate; the PO must cross each threshold explicitly — see "The pause protocol" in SKILL.md |
28
- | At GATE L3 FAIL: name scope (task + failed criterion), never prescribe fix options | Root cause analysis and fix paths belong to the implementer, not the orchestrator |
29
- | SHIP harvest records facts only — copies existing structured output, never computes a new verdict/score | A self-computed score = a second judge behind spec-evaluator (breaks single-judge, invites Goodhart); the eval suite interprets, harvest records |
30
- | Three-level circuit breaker: attempt_budget (inner, per scope) nests inside round_budget (outer), with an opt-in wall_clock_budget_s deadline | An exhausted scope queues a GATE H hammer proposal, it never blocks the round; only round_budget hitting 0 stops the whole run; the deadline breaker (checked every round boundary in `shapeup-run.js`) routes to GATE H so a run out of clock still ships what is green instead of being killed from outside |
31
- | The tech lead never hand-edits a scope contract | scope-architect is its sole writer (single-writer-per-file) |
32
- | Substrate-disjointness + PA1/PA2 lints are re-asserted at GATE L1b (spec-lint.mjs) even when scope-architect already checked them | A human may have hand-approved past a 🔴 at the architect's checkpoint; `shapeup-run.js` runs spec-lint itself, in code, before resolving L1b |
33
- | Hill phase is read from mechanical facts (T0/T1/seesaw), never declared by a worker | Closes the self-reported-confidence risk outright — facts move dots, not authors |
34
- | GATE H is delegated to scope-hammer, never adjudicated inline by the tech lead | Keeps the orchestrator thin; census/baseline-comparison/cut-list logic has one owner |
@@ -1,45 +0,0 @@
1
- # Tech-Lead Invocation
2
-
3
- Invocation examples and the complete flag table, extracted from `SKILL.md` (progressive
4
- disclosure). Read this when you need the exact CLI shape or a flag's effect.
5
-
6
- ---
7
-
8
- ## Invocation
9
-
10
- ```bash
11
- # Full build run from a kicked-off pitch, interactive (pause at every L-gate)
12
- /tech-lead --pitch shapeup/checkout-vnpay/shaping/shaping.md --spec shapeup/checkout-vnpay/spec/ --lens standard
13
-
14
- # Sub-skills unattended, tech lead pauses only at orient / plan / verdict / ship
15
- /tech-lead --pitch ... --spec ... --auto
16
-
17
- # Headless for CI (Agent SDK): auto-confirm all gates, stop on PASS / max_rounds / error
18
- /tech-lead --pitch ... --spec ... --unattended --max-rounds 3
19
-
20
- # Resume an existing run — start from a build-phase step
21
- /tech-lead --spec shapeup/checkout-vnpay/spec/ --from build
22
-
23
- # Skip evaluation for a trivial feature (tech-lead judgment / PO override)
24
- /tech-lead --pitch ... --spec ... --no-eval
25
- ```
26
-
27
- ### Flags
28
- | Flag | Effect |
29
- |------|--------|
30
- | `--pitch <path>` | Kicked-off pitch (shaped + bet by PO) — input to ORIENT then MAP SCOPES |
31
- | `--spec <path>` | Spec folder (orient/ + planner output + ledger location) |
32
- | `--lens lite\|standard\|cross-context` | Passed to ba-pitch-analyzer at step 8 |
33
- | `--auto` | Sub-skills run unattended; tech lead pauses at L1a/L1b/L3/L4 |
34
- | `--unattended` | Auto-confirm all L-gates (headless / CI) |
35
- | `--max-rounds N` | BUILD→EVAL cycles before escalating (default 3) — the OUTER breaker |
36
- | `--attempts N` | Per-scope T0 attempts before queuing a GATE H hammer proposal (default 5) — the INNER breaker; no-op on specs without scope contracts |
37
- | `--exec-model / --eval-model / --qa-model <name>` | Override L0.8's resolved model matrix (`RunArgs.models`: exec/eval/qa) for this run only — highest precedence. The orchestrator itself runs in-session; it has no model knob here |
38
- | `--from orient\|plan\|build\|eval` | Resume an in-progress run at a build-phase step |
39
- | `--no-eval` | Skip the evaluation pass this run (trivial feature) |
40
- | `--no-qa` | Skip the post-PASS /qa-edge-hunter pass (ledger records `qa: skipped`) |
41
- | `--tiny` | The small-change lane: orient (light) → single-task board → build → T0 → done. Implies `--no-eval --no-qa`, skips WIRE and scope contracts, collapses the gates to L0 + L4. See "The tiny lane" in SKILL.md — the L0 fit-check is mandatory and the ledger records `lane: tiny` |
42
- | `--dimensions <list>` | Eval dimensions, comma-separated (default `spec-conformance`). Passed straight through to `init-run.mjs --dimensions`, which records the set in the ledger's `eval_dimensions:` — that line is what every EVAL order is compiled from, so a dimension named anywhere else does not run. Ids the evaluator ships: `spec-conformance`, `tdd-surface`, `integration`, `completeness`, `test-surface-conformance`, `security`, `performance` (the last two are disabled stubs); a dimension you inject yourself is named here the same way |
43
-
44
- ---
45
-
@@ -1,213 +0,0 @@
1
- # Ledger Schema — `harness-run.md`
2
-
3
- The tech lead's run record. One per feature, lives in the LOCAL run-trace root
4
- `.shapeup/<slug>/harness-run.md` (hidden, gitignorable — it is ephemeral run-state,
5
- not a shared deliverable). It is the structured
6
- artifact that carries state across rounds and across sessions (so `--from` can resume), and
7
- the PO's audit of how the feature was built.
8
-
9
- **The tech lead is the sole writer of this file.** It is the authoritative
10
- run-state for the whole build phase — rounds, gate decisions, Hill positions, verdicts,
11
- `discovered_rounds`, config, language record. Workers never write here; the tech lead passes
12
- them what they need (`feature`, `spec`, `stack`, `discovered_rounds`) as args. The board
13
- (`tasks/_index.md`) remains the planner/generator's execution truth that the tech lead reads.
14
-
15
- ## Frontmatter
16
- ```yaml
17
- ---
18
- type: harness-run
19
- feature: [slug]
20
- spec_folder: [path to SHARED spec deliverable, e.g. shapeup/<slug>/spec/]
21
- lens: lite | standard | cross-context
22
- eval_dimensions: [spec-conformance] # the set from GATE L0.5 (init-run --dimensions); every EVAL order is compiled from THIS line
23
- max_rounds: 3
24
- auto_level: interactive | auto | unattended
25
- status: orienting | mapping | building | evaluating | shipped | escalated
26
- final_verdict: ~ | pass | fail | not-evaluated
27
- rounds_used: [N]
28
- discovered_rounds: [N]
29
- deploy: ~ | deployed | pending-po
30
- started_at: [ISO]
31
- closed_at: ~ | [ISO]
32
- ---
33
- ```
34
-
35
- ## Round table (the spine)
36
- Mirrors the long-running harness cost table — one row per phase, so you can see where time
37
- and tokens go and that EVAL is cheap relative to BUILD.
38
-
39
- ```
40
- ## Rounds
41
- | Phase | Round | Result | Duration | Notes |
42
- |------------------|-------|-------------------|----------|-------|
43
- | Orient | — | spiked VNPay seam | 18 min | spike resolved; 9 discovered tasks seeded |
44
- | Map Scopes | — | 14 tasks, 5 layers| 5 min | orient-informed; 1 SPIKE (VNPay) |
45
- | Build | 1 | 14/14 ✅ | 2 h 10 m | all tasks closed |
46
- | Eval | 1 | FAIL — 3 bugs | 9 min | EVAL-FEATURE-checkout-vnpay.md |
47
- | Build | 2 | 3 bugs fixed | 22 min | bug-only re-build |
48
- | Eval | 2 | PASS | 8 min | verdict pass |
49
- | Ship | — | built & verified | — | dims: spec-conformance; deploy pending (PO) |
50
- ```
51
-
52
- ## Hill report (the progress narrative — NOT task counts)
53
- The roadmap forbids reporting progress by counting tasks: a 90%-done slice can still be stuck
54
- uphill on the one unknown that matters. So the tech lead reports each slice's **position on
55
- the hill**, derived mechanically from open unknowns. Render it at every round boundary
56
- (area-level at GATE L1a — before slices exist; slice-level from GATE L1b onward).
57
-
58
- ```
59
- ## Hill — round 1
60
- | Slice | Position | Derived from |
61
- |--------------|-------------|--------------|
62
- | S1-spine | 🔽 downhill | spike closed + spine render-AC passed (crest crossed); 2 known tasks left |
63
- | S2-filters | 🔼 uphill | SPIKE-003 open: pagination approach unproven |
64
- | S3-export | 🔼 uphill | contract ⏳ TBD: file-format field |
65
- ```
66
-
67
- Position triggers:
68
- - 🔼 **Uphill** — open SPIKE / `⏳ TBD` contract / unresolved discovered task / approach unproven.
69
- - ⛰️ **Crest** — all unknowns resolved AND a concrete board fact (the spine slice's render-AC passes).
70
- - 🔽 **Downhill** — only known work remains, no open unknowns.
71
- - ✅ **Done** — slice clickable-done.
72
-
73
- Source: `orient/hill-signal.md` (area-level, at L1a) then the board + open SPIKE/contract state
74
- (slice-level, L1b onward). If slice IDs aren't on the board yet, report at
75
- task-group level and note the fallback here.
76
-
77
- ## Decisions log
78
- Every L-gate decision, for traceability.
79
- ```
80
- ## Decisions
81
- - GATE L1a: Orient accepted; spiked VNPay seam (resolved); S2-filters flagged uphill.
82
- - GATE L1b: PO accepted board; cut "guest checkout" task to phase 2.
83
- - GATE L2 (r1): board green; ran eval (feature not trivial).
84
- - GATE L3 (r1): FAIL → approved bug-only round 2.
85
- - GATE L3 (r2): PASS → ship.
86
- - GATE L4: built & verified; deploy pending (PO); closed.
87
- ```
88
-
89
- ## Bug carry-over (when FAIL)
90
- Links the current round's bug list so the next BUILD round has its worklist.
91
- ```
92
- ## Open bugs (round 1 → fix in round 2)
93
- → see evaluation/EVAL-FEATURE-checkout-vnpay.md
94
- - BUG-1 critical SC-DONE-WHEN apps/web/checkout/Pay.tsx:84
95
- - BUG-2 major SC-ERR apps/api/payments/handler.ts:51
96
- - BUG-3 minor SC-NONGO apps/api/shared/auth.ts:12
97
- ```
98
-
99
- ## Escalation block (only if max_rounds hit without PASS)
100
- ```
101
- ## Escalation
102
- Rounds used: 3/3 — still FAIL. Residual bugs: [N].
103
- Recommendation: [cut scope of feature X | accept minor bugs | extend max_rounds with PO approval].
104
- Decision owner: PO.
105
- ```
106
-
107
- ## Rules
108
- - The ledger is append-mostly: each round adds rows, never rewrites history.
109
- - `status` + `final_verdict` are the resume anchors for `--from`.
110
- - A `not-evaluated` final verdict (from `--no-eval`) is recorded plainly — never silently
111
- upgraded to `pass`.
112
-
113
- ---
114
-
115
- ## `round-ledger.md` (committed, Tier A — scope contracts only)
116
-
117
- Lives at `shapeup/<slug>/round-ledger.md` (SHARED root, tracked). Not a replacement
118
- for `harness-run.md` — a small, committed **subset** of it: the two things that must survive
119
- a `.shapeup/` wipe or a crash. Absent on specs with no scope
120
- contracts; `harness-run.md`'s existing Decisions log stays the only ledger there.
121
-
122
- ```yaml
123
- ---
124
- type: round-ledger
125
- feature: [slug]
126
- models: # L0.8 resolved matrix, recorded once, source noted
127
- orch: [model] (source: flags|settings.local|settings.json|default)
128
- exec: [model] (source: ...)
129
- eval: [model] (source: ...)
130
- qa: [model] (source: ...)
131
- digester: script | sonnet
132
- budgets:
133
- round_budget: [N] # outer breaker
134
- attempt_budget: [N] # inner breaker, per scope
135
- ---
136
- ```
137
-
138
- ```
139
- ## Decisions
140
- | Round | Scope | Kind | Question | Answer | Resolved by |
141
- |-------|-------|------|----------|--------|-------------|
142
- | 2 | cart-creation | design-decision | cart-total rounding | round half-up | PO (interactive) |
143
- | 2 | cart-creation | substrate-expansion | needs packages/shared/http.ts | approved → shared_substrate | PO (interactive) |
144
- ```
145
- **Promotion timing:** a row is appended the INSTANT the PO answers —
146
- never batched to round close. This is the file `task-executor`'s isolated briefs read back
147
- (the zero-memory handoff): an answer given once in round 2 must still be known in round 5's
148
- fresh-context attempt without replaying any chat history.
149
-
150
- ---
151
-
152
- ## Harvest row — `metrics/<machine-id>.jsonl` (written at SHIP)
153
-
154
- `harness-run.md` is ephemeral run-state — needed live for `--from` resume, the
155
- FAIL-loop, and QA reconcile; worthless after ship. At SHIP the tech-lead **harvests**
156
- the durable-mineable *signals* out of it into one append-only row:
157
-
158
- ```
159
- .shapeup/metrics/<machine-id>.jsonl # one row = one e2e run; LOCAL (gitignored)
160
- ```
161
-
162
- Path note: `metrics/` lives under the LOCAL root with the rest of the run trace — moved
163
- there by ADR-0001, because a committed shard keyed on `$HOSTNAME` only grows and puts a
164
- person's machine name in the repo. It outlives any single run (the per-slug run dirs are
165
- superseded run by run; the shard only appends), which is what makes it the durable signal
166
- feed. Sharded per machine so shards can be pooled deliberately without colliding on one
167
- filename; the read plane is `stats.mjs`, or `cat .shapeup/metrics/*.jsonl`.
168
- `schema_version` makes an old row readable by later skill versions.
169
-
170
- ### Two hard rules (same discipline as the Test Surface: *derived, never invented*)
171
- 1. **Harvest only fields that already exist as structured output at ship time.** If a
172
- field forces the tech-lead to *evaluate something new* → reject (judgment in disguise).
173
- 2. **Harvest records facts, never computes a new verdict.** A self-computed
174
- `run_quality_score` would be a second judge behind `spec-evaluator` → breaks the
175
- single-judge rule and invites Goodhart. The eval suite *interprets* downstream;
176
- harvest *records*.
177
-
178
- Scope: the harvest feeds **only the e2e pipeline measurement**. The per-skill functional
179
- fixtures run in isolation and do not consume it.
180
-
181
- ### Row schema (one JSON object per line)
182
- | Field | Existing source (copied, never re-graded) | Signal |
183
- |---|---|---|
184
- | `schema_version` | constant `1` | forward-compat |
185
- | `feature_slug` | run-state frontmatter | identity |
186
- | `terminal_state` | run-state final: `shipped` / `circuit_broken` / `abandoned` | circuit-breaker outcome |
187
- | `round_count` | round table | effort-to-PASS |
188
- | `final_audit_score` | final EVAL report (copied, not re-graded) | conformance |
189
- | `surprise_count` | `.shapeup/<slug>/discovery/ledger.md` | shaping quality — scope drift |
190
- | `spike_unresolved_count` | `SPIKE-UNRESOLVED` markers at bet | shaping quality — open risk into bet |
191
- | `scope_cut_count` | `~` items cut at SHIP S.0 | appetite pressure / scope hammer |
192
- | `qa_findings` | `.shapeup/<slug>/qa/hunt-report.md` + triage → `{total, promoted, held}` | edge quality |
193
- | `slice_count` | breadboard B5 (≤9) | **normalizer / denominator** |
194
- | `sources` | path to each **SHARED** source artifact — never a LOCAL `.shapeup/` path (the run-trace is superseded run by run, so a LOCAL path dangles by the time anyone reads the row; SHARED paths resolve on any clone — tier-direction rule) | auditability |
195
-
196
- - `slice_count` is the **denominator**: `round_count=4` on a 2-slice feature is alarming,
197
- on a 9-slice feature is normal. Without it, e2e comparisons are apples-to-oranges.
198
- Enables `round-per-slice`, `surprise-per-slice`.
199
- - `spike_unresolved_count` + `surprise_count` measure two of the three downhill
200
- conditions (open-risk-remaining, scope-drift-from-breadboard). A good shaping run
201
- drives both toward 0 — measured from the build trace, no manual grading.
202
- - **Rejected fields:** `time_spent` / velocity (no clock; Shape Up forbids counting hours
203
- — `round_count` is the legitimate effort proxy) and `run_quality_score` (second judge).
204
-
205
- ### Row template
206
- ```json
207
- {"schema_version":1,"feature_slug":"checkout-vnpay","terminal_state":"shipped","round_count":2,"final_audit_score":"PASS","surprise_count":3,"spike_unresolved_count":0,"scope_cut_count":1,"qa_findings":{"total":5,"promoted":1,"held":4},"slice_count":4,"sources":["shapeup/checkout-vnpay/shaping/shaping.md","shapeup/checkout-vnpay/shaping/breadboard.md"]}
208
- ```
209
-
210
- LOCAL artifacts (the EVAL report, discovery ledger, QA hunt report) are *harvest-time reads*:
211
- their **values** are copied into the row's fields (`final_audit_score`, `surprise_count`,
212
- `qa_findings`) but their paths are never recorded in `sources` — they are gitignored and
213
- wiped, so a committed pointer to them is dead on arrival.