shapeup-sdlc 3.18.2 → 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 +29 -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
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: spec-evaluator
3
- description: "Use this skill whenever the user wants to evaluate, QA, or verify that an implemented task actually matches its spec and acceptance criteria — the judge in a planner→generator→evaluator harness. Trigger on: \"evaluate task TASK-NNN\", \"QA TASK-NNN\", \"verify against spec\", \"check acceptance criteria\", \"does this match the spec\", \"grade this build\", \"run evaluator\", or a tech-lead --order dispatch. Skeptical by default — absence of evidence is a FAIL; probes the running app and files file:line bugs."
3
+ description: "Use this skill whenever the user wants to evaluate, QA, or verify that an implemented task actually matches its spec and acceptance criteria — the judge in a planner→generator→evaluator harness. Trigger on: \"evaluate task TASK-NNN\", \"QA TASK-NNN\", \"verify against spec\", \"check acceptance criteria\", \"does this match the spec\", \"grade this build\", \"run evaluator\", or a loop --order dispatch. Skeptical by default — absence of evidence is a FAIL; probes the running app and files file:line bugs."
4
4
  ---
5
5
 
6
6
  # Spec Evaluator (the single judge, pure worker v1.0)
@@ -9,7 +9,7 @@ description: "Use this skill whenever the user wants to evaluate, QA, or verify
9
9
 
10
10
  The **judge** in a planner → generator → evaluator loop. It reads the committed spec, exercises
11
11
  the **running** app, and returns a hard-threshold verdict plus a file:line bug list — as a
12
- WorkResult envelope the orchestrator ingests. The generator fixes; the evaluator re-runs.
12
+ WorkResult envelope the orchestrator applies. The generator fixes; the evaluator re-runs.
13
13
 
14
14
  **Core guarantee — skeptical by default.** Out-of-the-box an LLM is a lenient QA: it finds a
15
15
  real defect, then talks itself into approving anyway. This skill inverts that posture. A
@@ -20,7 +20,7 @@ criterion with no collected evidence is a **FAIL**, never a pass-by-assumption.
20
20
  > **Dimension contract (injection interface)** → `references/dimension-contract.md`.
21
21
  > Where any reference file describes *writing* shared state (task files, `.verdicts` ledger,
22
22
  > run-state), the pure-worker contract overrides it: that data returns in the WorkResult and
23
- > the orchestrator's ingest script performs the write. Old gate names in reference files map
23
+ > the orchestrator performs the write. Old gate names in reference files map
24
24
  > 1:1 onto the core process below: GATE V0/V0.5 = input contract + dimension resolution,
25
25
  > GATE V1 = CONTRACT, Phase A = PROBE, GATE V2 = VERDICT, Phase B = REPORT; GATE V3
26
26
  > (sign-off) is retired — pausing is the caller's `interaction` policy.
@@ -42,7 +42,7 @@ Invoked as `--order <path>`. Fields you may rely on (absent = unknown, never inf
42
42
  | `payload.launch_cmd` | The project profile's launch probe: installs the built artifact, starts it and asserts the first screen. This is how the app is brought up for `[ui]` probing. A non-zero exit is a finding to cite, not a reason to try another way. Absent → the profile declares none; fall back to `run_cmd` |
43
43
  | `payload.build_gate` | This run's newest round build gate artifact — each step's exit code and output tail. It records that the build ran and whether the app launched, and the launch step's output names what it captured. Read it before grading any `[ui]` row NO EVIDENCE: a launch that succeeded is evidence the app can be probed, and the row is graded on the app, not on its absence. Absent → the gate never ran |
44
44
  | `payload.revised_checks[]` | Rows that FAILed in one trial of this round and PASS in a later one whose own check file changed in between — a pass obtained by editing the check. Read each listed file against its row's Expect before you let its PASS count; a check that no longer asserts what the row asks makes that row a FAIL, and the bug names the check. Absent → no check was rewritten |
45
- | `payload.t0_artifacts[]` | Per-scope T0 verdict paths for this round (scoped specs), compiled from each scope's green verdict. An artifact listed but missing/red on disk, or a scoped spec with none listed → the round is NOT gradeable: return `status: failed` with the reason, naming the scope, as your FIRST deviation — a structural precondition, not a criterion |
45
+ | `payload.t0_artifacts[]` | Per-scope T0 verdict paths for this round (scoped specs), listed by the orchestrator from each scope's latest verdict. An artifact listed but missing/red on disk, or a scoped spec with none listed → the round is NOT gradeable: return `status: failed` with the reason, naming the scope, as your FIRST deviation — a structural precondition, not a criterion |
46
46
  | `payload.scopes_without_t0[]` | Scopes with no green T0 this round while others have one. The round IS gradeable: grade every row such a scope owns as FAIL, evidence "no green T0 for scope <id>" with the scope contract as its locator (`…/scopes/<id>.md:1`). Never refuse the round for them — a refusal ends the run before the next round or GATE H can act. Absent → every scope is green |
47
47
  | `payload.browser` | `cli` (default, ~4x cheaper) \| `mcp` \| `none` |
48
48
  | `payload.tasks[]` | Traceability only (which UCs a task claims): NEVER a grading source — the committed UC text is the criterion, a paraphrase mismatch is a finding |
@@ -101,15 +101,13 @@ Done-when statements; `_index.md` Non-Go list. Which UCs are in scope comes from
101
101
  - Re-probe every FAIL once before finalizing: agree → confidence high; disagree → keep FAIL
102
102
  (no stable pass = FAIL), confidence low, note flaky.
103
103
  - Read any existing `.verdicts-*.jsonl` (read-only) to detect flips vs prior runs — a flip
104
- forces confidence low and a stability note. The new lines return in your envelope; ingest
104
+ forces confidence low and a stability note. The new lines return in your envelope; the loop
105
105
  appends them (never rewrite history).
106
106
  - Dimension threshold from its file (spec-conformance: 100% of [cmd]/[ui]/[data] criteria +
107
107
  contract triplet + Non-Go). Overall PASS only if ALL active dimensions pass — the halo
108
108
  effect is banned; a strong dimension never lifts a failing one.
109
109
  - **T0 citation (scoped specs).** Recompute each cited artifact's sha256 from disk — never
110
- trust a handed hash. Use any hasher you may run; when none is available to you,
111
- `harness probe t0 --slug <slug> --scope <scope_id> --round <r>` prints the digest of that
112
- scope's green verdict as the file is at that moment. A digest from any other place — a ledger
110
+ trust a handed hash. Use any hasher you may run (`shasum -a 256 <path>`, or `node -e` with `node:crypto`). A digest from any other place — a ledger
113
111
  line, an earlier report, an error message — is a handed hash, however correct it looks. A verdict on a scoped spec without a T0 citation is structurally
114
112
  invalid, regardless of how convincing your own probing looked; generator prose ("tests
115
113
  pass", "verified locally") is never admissible evidence.
@@ -177,8 +175,8 @@ round. Write it so someone without your context can answer it in one reply.
177
175
  ```
178
176
 
179
177
  **Every Test Surface row is its own criterion.** Name the row's id (`TS-05-05`) in `criterion`, one
180
- row per entry — never a range (`TS-01-04/05`) and never a group ("device rows"). Ingest refuses a
181
- PASS that leaves any row of the spec unnamed, because the requirement matrix, the next round's bugs
178
+ row per entry — never a range (`TS-01-04/05`) and never a group ("device rows"). A PASS that
179
+ leaves any row of the spec unnamed is incomplete, because the requirement matrix, the next round's bugs
182
180
  and the rewritten-check list all read the verdict one row at a time.
183
181
 
184
182
  **`traces_to` is copied, not invented.** Fill it from the `(covers: REQ-…)` clause of the
@@ -188,15 +186,15 @@ clause yields no anchor — leave the array empty rather than guessing, and neve
188
186
  supply one. This changes nothing you grade: the anchor is a navigation path, never a grading input,
189
187
  and a criterion passes or fails on its evidence exactly as before. It matters downstream because
190
188
  the requirement matrix at GATE L4 and the census at GATE H are projected from these anchors; a
191
- verdict that drops them grades the build and says nothing about what the pitch asked for. Ingest refuses a verdict that anchors no criterion at all while the board's ACs carry `covers:` clauses, and you are sent back once.
189
+ verdict that drops them grades the build and says nothing about what the pitch asked for. A verdict that anchors no criterion at all while the board's ACs carry `covers:` clauses has dropped the link the loop reads.
192
190
 
193
191
  **Every FAIL criterion's `evidence` MUST carry a `file:line` locator** — schema-enforced, not
194
- advice: the envelope is validated against `work-result.schema.json` at ingest and a locatorless
192
+ advice: the envelope is validated against `work-result.schema.json` when the loop reads it and a locatorless
195
193
  FAIL is rejected before any write. A PASS may cite plain output. (Observed, not theorized: a
196
194
  correct FAIL verdict with no locator anywhere is unactionable without re-investigating — the
197
195
  rule used to live in prose and be enforced nowhere; it is now data in `domain.schema.json`.)
198
196
 
199
- The orchestrator's ingest appends the verdict ledger, un-ticks the `refuted` boxes, and sets
197
+ The orchestrator's the loop appends the verdict ledger, un-ticks the `refuted` boxes, and sets
200
198
  `eval_verdict` frontmatter. You never touch a task file, a board, or run-state — and you
201
199
  NEVER set `status: done`: the judge issues verdicts; closure belongs elsewhere. That
202
200
  separation is the whole point of the architecture.
@@ -212,7 +210,7 @@ separation is the whole point of the architecture.
212
210
  - [ ] Every FAIL was re-probed once; confidence assigned per the ledger rule
213
211
  - [ ] Scoped spec → T0 citations present with recomputed sha256 (else the run returned `failed`)
214
212
  - [ ] Report written inside `evaluation/**` only; no other file touched
215
- - [ ] `refuted[]` lists exactly the boxes your evidence disproves (un-ticking is ingest's act)
213
+ - [ ] `refuted[]` lists exactly the boxes your evidence disproves (un-ticking is the loop's act)
216
214
  - [ ] The WorkResult validates against `work-result.schema.json`
217
215
 
218
216
  ---
@@ -233,17 +231,15 @@ bug_template). Adding one (e.g. security) = write `references/dimensions/securit
233
231
  # Orchestrated (once per round, after GATE L2) — the canonical form
234
232
  /spec-evaluator --order .shapeup/checkout-vnpay/orders/evaluate-r2.json
235
233
 
236
- # Standalone — the preamble shim compiles a minimal order, then the single code path runs:
237
- # node "<kernel>" compile --operation evaluate --slug <slug> \
238
- # --worker spec-evaluator [--payload '{"dimensions": [...], "run_cmd": "..."}']
234
+ # Standalone — the preamble shim writes a minimal order by hand, then the single code path runs:
239
235
  /spec-evaluator --spec shapeup/checkout-vnpay/spec/ --task TASK-007
240
236
  /spec-evaluator --spec shapeup/checkout-vnpay/spec/ --feature checkout-vnpay --single-pass
241
237
  ```
242
238
 
243
239
  Standalone keeps `--task` (per-task check, not round-gated) and `--single-pass` (feature-level)
244
240
  — the shim maps them onto the order's payload; missing run command → ask. After writing the
245
- WorkResult, run `node "<kernel>" reduce ingest <result path>` and show its
246
- summary — standalone has no orchestrator to ingest for you.
241
+ WorkResult, show the user its
242
+ summary — standalone has no orchestrator to apply it for you.
247
243
 
248
244
  ---
249
245
 
@@ -254,10 +250,10 @@ summary — standalone has no orchestrator to ingest for you.
254
250
  | Absence of evidence = FAIL | Kills pass-by-assumption, the core QA failure mode |
255
251
  | Halo effect banned | A strong dimension never lifts a failing one |
256
252
  | Disabled dimensions are out of scope | No silent scope creep |
257
- | Evaluator never sets `status: done`, never edits task files/boards | Judge ≠ doer; refuted boxes return as data, ingest writes |
253
+ | Evaluator never sets `status: done`, never edits task files/boards | Judge ≠ doer; refuted boxes return as data, the loop writes |
258
254
  | Untestable AC blocks a clean PASS | Forces the spec to be verifiable, not vibes |
259
255
  | Probe the RUNNING app, not the source alone | Apps that look right still break when used |
260
256
  | Re-probe every FAIL; flip ⇒ confidence low | A single snapshot lies; the ledger makes it visible |
261
- | Verdict-ledger lines are returned, appended by ingest, never rewritten | Verdict history is how a single-snapshot judge becomes measurable |
257
+ | Verdict-ledger lines are returned, appended by the loop, never rewritten | Verdict history is how a single-snapshot judge becomes measurable |
262
258
  | A verdict on a scoped spec without a T0 citation is structurally invalid | T0 is a machine fact the generator cannot fabricate |
263
259
  | UI assertions target affordances only (test_id/role/data-state) | Layer-3 styling is frozen; grading it resurrects the freeze through the judge |
@@ -16,7 +16,7 @@ enabled: true # core loads it only if true (or named in --dime
16
16
  weight: 1.0 # informational; thresholds are hard, not weighted averages
17
17
  hard_threshold: all-pass # see "Threshold vocabulary" below
18
18
  applies_to: # scoping — omit a key to mean "all"
19
- lens: [lite, standard] # which ba-pitch-analyzer lenses
19
+ lens: [lite, standard] # which planning lenses
20
20
  package: any # apps/api | apps/web | apps/mobile | packages/shared | any
21
21
  variant: any # shared | be | web | mobile | e2e | any
22
22
  requires_browser: true # does this dimension need the running app in a browser?
@@ -14,7 +14,7 @@ requires_browser: false
14
14
  # Completeness Dimension
15
15
 
16
16
  > **Auto-enable rule (read at GATE V0.5):** This dimension stays `enabled: false` by
17
- > default so it is a no-op on every spec generated before `ba-pitch-analyzer` v2.8.
17
+ > default so it is a no-op on every spec generated before the planner wrote Invariants sections.
18
18
  > The core flips it ON for a run **only when** the spec's `usecases/` contains at least
19
19
  > one `## Invariants` section. A pre-v2.8 spec has no invariants → this dimension never
20
20
  > activates → existing audit scores and verdicts are unchanged (non-regression guarantee).
@@ -25,7 +25,7 @@ criteria?"* — it grades the tasks that exist. It cannot see the task that was
25
25
  written. Shape Up's discovered-task philosophy says the real bulk of work is found while
26
26
  building; an invariant declared on a UC but never backed by a regression task is exactly
27
27
  that blind spot. This dimension converts "absence of a task" from invisible into a graded
28
- **GAP** — the judge surfaces it; the planner (a ba-pitch-analyzer `reconcile` order) fills it.
28
+ **GAP** — the judge surfaces it; the planner (a plan spec step in `reconcile` mode) fills it.
29
29
  Judge never fills it itself.
30
30
 
31
31
  **Distinction held:** conformance = *the tasks that exist are correct*; completeness =
@@ -98,5 +98,5 @@ location: [usecases/UC-Name.md#Invariants INV-NN | usecases/UC-Name.md | discove
98
98
  repro: <how the gap was detected — e.g. "grep use_case_refs across tasks/ found 0 backing TASK for INV-02">
99
99
  expected: <e.g. "≥1 regression task referencing UC-ConnectObjects covering INV-02">
100
100
  actual: <e.g. "no task references INV-02; invariant declared but unverified">
101
- next: <handoff — e.g. "a ba-pitch-analyzer reconcile order over <ledger> to generate the missing regression task">
101
+ next: <handoff — e.g. "a plan spec step in reconcile mode over <ledger> to generate the missing regression task">
102
102
  ```
@@ -77,7 +77,7 @@ dimensions, off by default.
77
77
  Inspect the diff / changed files. No file outside the feature's declared package/scope is
78
78
  modified, and no item in _index.md's ## Non-Go list is touched. Any out-of-scope change
79
79
  FAILS with file:line. (A local task file's own Non-Go section, when present, is consistent
80
- with _index.md by construction — ba-pitch-analyzer derives it from the pitch — but the
80
+ with _index.md by construction — the plan activity derives it from the pitch — but the
81
81
  committed _index.md is the grading source since the task file may not exist locally.)
82
82
  source: index
83
83
 
@@ -14,9 +14,9 @@ requires_browser: true
14
14
  # Test Surface Conformance Dimension
15
15
 
16
16
  > **Auto-enable rule (read at GATE V0.5):** stays `enabled: false` by default — a no-op on
17
- > every spec generated before `ba-pitch-analyzer` v2.9. The core flips it ON for a run
17
+ > every spec generated before the planner wrote a Test Surface. The core flips it ON for a run
18
18
  > **only when** the spec's `usecases/` contains at least one `## Test Surface` section
19
- > (fresh v2.9 spec, or a pre-v2.9 spec retrofitted via a retrofit-surface order). Pre-surface
19
+ > (fresh v2.9 spec, or a pre-v2.9 spec retrofitted by a plan spec step in `retrofit-surface` mode). Pre-surface
20
20
  > specs → never activates → existing verdicts unchanged (non-regression guarantee).
21
21
  > Explicit `--dimensions ...,test-surface-conformance` always wins over the auto rule.
22
22
 
@@ -27,7 +27,7 @@ that the spec already implies. The BA now derives that matrix into each UC's
27
27
  `## Test Surface` (D1 Invariants · D2 Error Cases · D3 Contract shapes · D4 No-gos,
28
28
  mechanical-only); this dimension is the judge-side half: probe every derived row against
29
29
  the running app. Judge probes; it never authors rows — a missing or thin Test Surface is
30
- reported as a finding and routed back to the planner's retrofit-surface operation, never filled in here.
30
+ reported as a finding and routed back to the planner's `retrofit-surface` spec mode, never filled in here.
31
31
 
32
32
  **Distinctions held:**
33
33
  - conformance = *the AC that were written pass* · test-surface = *the matrix the spec
@@ -63,7 +63,7 @@ reported as a finding and routed back to the planner's retrofit-surface operatio
63
63
  pass_rule: >
64
64
  Cross-check each UC: Invariants ↔ TS-INV rows, Error Cases codes ↔ TS-ERR rows, and
65
65
  every row's Source cites D1–D4. A UC with `## Test Surface` whose own sources are
66
- uncovered → FAIL at `major` with `next: retrofit-surface order (ba)` (judge surfaces the gap;
66
+ uncovered → FAIL at `major` with `next: a plan spec step in retrofit-surface mode` (judge surfaces the gap;
67
67
  generator fills it — this dimension NEVER authors rows). A UC carrying the explicit
68
68
  empty-sources line passes TSC-2 vacuously. A v2.9+ spec UC with NO `## Test Surface`
69
69
  section at all → FAIL at `major`, same routing.
@@ -90,7 +90,7 @@ ts_row: <the full row probed, verbatim>
90
90
  repro: <probe executed — command / UI steps>
91
91
  expected: <the Expect cell>
92
92
  actual: <observed evidence — response, state, screenshot ref>
93
- next: <TSC-1 → task-executor fix via tech-lead round r+1 | TSC-2 → retrofit-surface order re-run>
93
+ next: <TSC-1 → task-executor fix via the loop round r+1 | TSC-2 → retrofit-surface re-run>
94
94
  ```
95
95
 
96
96
  ## Report obligation (the QA handoff)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: task-executor
3
- description: "Use this skill whenever a user wants to execute, implement, or run a specific task generated by the ba-pitch-analyzer skill. Triggers on: \"execute task TASK-NNN\", \"implement TASK-NNN\", \"run this task\", \"start working on TASK-NNN\", \"implement the task in [folder]\", \"run task from spec folder\", \"pick up the next task\", or a tech-lead --order dispatch. Implements a task's acceptance criteria exactly — minimum code, surgical diffs, verified observable outcomes."
3
+ description: "Use this skill whenever a user wants to execute, implement, or run a specific task generated by the plan activity (`/ship plan`). Triggers on: \"execute task TASK-NNN\", \"implement TASK-NNN\", \"run this task\", \"start working on TASK-NNN\", \"implement the task in [folder]\", \"run task from spec folder\", \"pick up the next task\", or a loop --order dispatch. Implements a task's acceptance criteria exactly — minimum code, surgical diffs, verified observable outcomes."
4
4
  ---
5
5
 
6
6
  # Task Executor (pure worker, v2.0)
@@ -23,8 +23,8 @@ rely on (anything absent = **unknown**; never invent it):
23
23
 
24
24
  | Field | What it is |
25
25
  |---|---|
26
- | `payload.tasks[]` | The task(s) to implement: `id`, `body_path` (read it fully), `acceptance_criteria[]` |
27
- | `payload.scope_contract` | The active scope: `affordance_manifest`, `e2e_verification_fixtures`, topology |
26
+ | `payload.tasks[]` | The task(s) to implement: `id` and `body_path` — read the file fully; its acceptance criteria are in it |
27
+ | `payload.scope_contract` | The path of the active scope's contract (`scopes/<id>.md`) — read it: `affordance_manifest`, `e2e_verification_fixtures`, topology |
28
28
  | `substrate.allowed` / `substrate.shared` | The ONLY globs you may write. A needed file outside them → ESCALATE, never a write (a sandbox hook blocks it anyway) |
29
29
  | `payload.decisions[]` | Adjudicated answers from prior escalations — binding precedent, apply them |
30
30
  | `payload.digested_errors[]` | `{file, line, core_message}` triples from the previous attempt's failed verification (a test that failed by name with no file:line — `FAIL TS-05-05 step 4: …` — arrives with `file: null` and the whole line as its message) — your starting bug list |
@@ -165,13 +165,13 @@ suffix come from `order_id`) matching `work-result.schema.json`, and print its p
165
165
  }
166
166
  ```
167
167
 
168
- `ac` carries the checkbox text **verbatim** — the ingest script ticks boxes by matching it.
168
+ `ac` carries the checkbox text **verbatim** — the loop ticks boxes by matching it.
169
169
  Failing/skipped ACs are reported as such, never omitted. Discovered work is *reported*, never
170
170
  self-planned: no new task files, no spec edits — one raw line per discovery.
171
171
 
172
172
  You do NOT: tick AC boxes, edit `tasks/_index.md`, write `run-state.md`, touch the discovery
173
173
  ledger, mark anything done outside your result, or update any other spec document. The
174
- orchestrator's `harness reduce ingest` does all of that from your envelope.
174
+ orchestrator's loop does all of that from your envelope.
175
175
 
176
176
  ---
177
177
 
@@ -191,20 +191,16 @@ orchestrator's `harness reduce ingest` does all of that from your envelope.
191
191
  ## Invocation
192
192
 
193
193
  ```bash
194
- # Orchestrated (tech-lead's build loop) — the canonical form
194
+ # Orchestrated (the loop's build step) — the canonical form
195
195
  /task-executor --order .shapeup/checkout-vnpay/orders/r2-a3.json
196
196
 
197
- # Standalone — the preamble shim compiles a minimal WorkOrder from the flags, then the
198
- # single code path above runs. Requires the harness scripts (plugin install):
199
- # node "<kernel>" compile --task TASK-003 --slug checkout-vnpay
200
- # node "<kernel>" compile --next --slug checkout-vnpay
197
+ # Standalone — the preamble shim writes a minimal WorkOrder by hand from the flags (the loop's
198
+ # `resources/orders.md` has the shape), then the single code path above runs:
201
199
  /task-executor --spec shapeup/checkout-vnpay/spec/ --task TASK-003
202
200
  /task-executor --spec shapeup/checkout-vnpay/spec/ --next
203
201
  ```
204
202
 
205
- Standalone shim: derive `<slug>` from the `--spec` path (`shapeup/<slug>/spec`),
206
- run `harness compile` with the matching flags (mode becomes `standalone`), then proceed
207
- against the compiled order exactly as if dispatched. After writing the WorkResult, run
208
- `node "<kernel>" reduce ingest <result path>` yourself and show the user its
209
- summary — standalone has no orchestrator to ingest for you. One code path inside; two entry
203
+ Standalone shim: derive `<slug>` from the `--spec` path (`shapeup/<slug>/spec`), write a minimal order
204
+ by hand with `"mode": "standalone"`, then proceed against it exactly as if dispatched. After writing the
205
+ WorkResult, show the user its summary — standalone has no orchestrator to apply it for you. One code path inside; two entry
210
206
  points outside.
package/commands/hill.md DELETED
@@ -1,10 +0,0 @@
1
- ---
2
- description: Render the Hill Chart dashboard — a portfolio of pitches, or one pitch's detail
3
- ---
4
- Use the **hill-chart** skill on $ARGUMENTS.
5
-
6
- Renders a self-contained dashboard from committed hill shards (`shapeup/<slug>/hill/*.yml`) and
7
- each pitch's local run graph (`.shapeup/<slug>/graph.jsonl`): a portfolio card per pitch, and
8
- per-pitch detail with a mechanical Hill Chart, an attention list, a scope board, round history,
9
- and the full run graph one click deeper. Give a slug to render one pitch only; no argument
10
- renders the whole portfolio.
@@ -1,109 +0,0 @@
1
- #!/usr/bin/env node
2
- // GATE L0.0 — intake precondition. PreToolUse hook.
3
- //
4
- // Denies a `tech-lead` dispatch that carries no pitch, no spec folder, and no requirement text.
5
- //
6
- // WHY THIS EXISTS (reproduced, not theorized). The orchestrator was reached as
7
- //
8
- // Skill(tech-lead, args: "--unattended")
9
- //
10
- // — the flag survived the hand-off, the requirement text did not. With nothing to orchestrate,
11
- // the run printed the gate names, a confident plan, and wrote no code, while *looking* like a
12
- // successful run. The same harness invoked with --pitch/--spec built the feature. Whether a model
13
- // happens to inline the text and recover is a property of the model, not of the harness.
14
- //
15
- // That is the "agent claims done" failure this project exists to prevent, happening at the
16
- // project's own front door. Every other invariant that matters here lives in the runtime; this one
17
- // was living in a prompt, and a prompt is exactly what gets dropped on a hand-off. So it becomes a
18
- // hook, like GATE L2.
19
- //
20
- // Design mirrors the GATE L2 block deliberately:
21
- // • Scope — only `Skill` → tech-lead. Anything else defers instantly.
22
- // • Fail-CLOSED only on a provably empty intake, with an actionable re-invocation in the reason.
23
- // • Fail-OPEN on anything ambiguous (unparseable payload, unknown arg shape, an envelope
24
- // --order). A gate that blocks legitimate runs gets disabled, and a disabled gate enforces
25
- // nothing.
26
- //
27
- // Contract: PreToolUse stdin JSON { tool_name, tool_input:{skill_name|skill, skill_args|args}, ... }
28
- // Deny via { hookSpecificOutput: { hookEventName, permissionDecision:"deny", permissionDecisionReason } }.
29
-
30
- // RECEIPTS (v1.5). This gate has been scored `No effect` on a re-run where the acceptance rate did
31
- // not move — because the hook CORRECTLY never fired and the cause was elsewhere. That distinction
32
- // is unprovable from a hook that answers "inspected and permitted" and "never ran" with the same
33
- // silence. Every decision below is now recorded (hooks/lib/decision.mjs).
34
-
35
- import { runHook, readStdin, settle } from "./lib/decision.mjs";
36
-
37
- await runHook("gate-intake", async () => {
38
- /** Fail-open, with the reason on the record. */
39
- const defer = (reason, rule) => settle({ verdict: "allow", event: "PreToolUse", tool: p?.tool_name ?? null, reason, rule });
40
-
41
- const raw = await readStdin();
42
-
43
- let p;
44
- try { p = JSON.parse(raw || "{}"); }
45
- catch (e) { settle({ verdict: "error", event: "PreToolUse", reason: `unparseable payload: ${e.message}` }); }
46
-
47
- if (p.tool_name !== "Skill") defer(`not a Skill call (${p.tool_name ?? "no tool_name"}) — out of scope`);
48
-
49
- // The Skill tool's field names differ by surface: `skill_name`/`skill_args` in the hook payload,
50
- // `skill`/`args` in the model-facing stream. Accept both — assuming one was already wrong once.
51
- const skillRaw = p.tool_input?.skill_name ?? p.tool_input?.skill ?? "";
52
- const args = String(p.tool_input?.skill_args ?? p.tool_input?.args ?? "");
53
-
54
- // Plugin skills arrive namespaced, e.g. "shapeup-sdlc-plugin:tech-lead".
55
- const skill = String(skillRaw).split(":").pop();
56
- if (skill !== "tech-lead") defer(`Skill(${skill}) is not the orchestrator — out of scope`);
57
-
58
- // The envelope port supplies its own intake; `harness verify envelope` owns that path.
59
- if (/--order\b/.test(args)) defer("envelope dispatch — validate-envelope owns this path", "--order");
60
-
61
- // Intake is satisfied by ANY of: a pitch path, a spec folder, or free requirement text.
62
- const hasPitch = /--pitch\s+\S/.test(args);
63
- const hasSpec = /--spec\s+\S/.test(args);
64
- const hasResume = /--from\s+\S/.test(args); // resuming an existing run has its state on disk
65
-
66
- // Free text = anything left once flags and their values are removed.
67
- // Every flag that TAKES A VALUE must be listed here. A flag whose value is not stripped reads as
68
- // free requirement text, and the gate then defers on an empty intake — the exact dispatch it
69
- // exists to deny. This is a live failure mode, not a hypothetical: adding `--gate-answers` and
70
- // `--wall-clock-budget` without listing them here silently blinded the gate, and the very next run
71
- // reached tech-lead as `args:"--unattended --gate-answers ci --wall-clock-budget 2400"` — no
72
- // requirement text at all — and was waved straight through, because "ci" and "2400" counted as
73
- // the spec.
74
- // Adding a valued flag anywhere in the harness means adding it here, and structural test §39
75
- // enforces exactly that against commands/ship.md.
76
- const VALUED_FLAGS = /--(pitch|spec|from|lens|rounds|attempts|parallel-scopes|orch-model|exec-model|eval-model|qa-model|feature|task|gate-answers|wall-clock-budget|slug|auto-level|max-rounds|intake-file|intake-text|spec-folder|cwd|out|by|preset|file|order|breadboard)\s+\S+/g;
77
- const BARE_FLAGS = /--[a-z0-9-]+/g;
78
- const freeText = args.replace(VALUED_FLAGS, " ").replace(BARE_FLAGS, " ").trim();
79
-
80
- if (hasPitch || hasSpec || hasResume || freeText.length > 0) {
81
- const via = hasPitch ? "--pitch" : hasSpec ? "--spec" : hasResume ? "--from" : "free requirement text";
82
- defer(`intake resolvable via ${via} — inspected and permitted`, via);
83
- }
84
-
85
- // Provably empty intake → deny, and say exactly how to fix it.
86
- const reason = [
87
- "✋ GATE L0.0 — NO INTAKE. tech-lead was dispatched with no pitch, no spec folder, and no",
88
- "requirement text; only flags survived the hand-off (args: " + JSON.stringify(args.slice(0, 80)) + ").",
89
- "",
90
- "An orchestrator with no spec has nothing to orchestrate. Proceeding would print the gate list",
91
- "and build nothing — output that reads like a successful run and contains no work.",
92
- "",
93
- "Re-dispatch with the requirement text or an on-disk spec:",
94
- " Skill(tech-lead, \"<the full requirement text>\")",
95
- " Skill(tech-lead, \"--pitch <shaping.md> --spec <spec/>\")",
96
- ].join("\n");
97
-
98
- return {
99
- verdict: "deny", event: "PreToolUse", tool: "Skill", subject: "tech-lead", rule: "empty-intake",
100
- reason: "no pitch, no spec folder, and no requirement text survived the hand-off",
101
- payload: {
102
- hookSpecificOutput: {
103
- hookEventName: "PreToolUse",
104
- permissionDecision: "deny",
105
- permissionDecisionReason: reason,
106
- },
107
- },
108
- };
109
- });