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,174 +0,0 @@
1
- ---
2
- name: scope-architect
3
- description: "Use this skill to map the vertical scopes of a feature — Shape Up's \"map the scopes\" (step 8) as committed, mechanically enforceable contracts. Triggers on: \"map the scopes\", \"write the scope contracts\", \"scope contract\", \"the discovered tasks don't fit any scope\", \"re-slice the substrate\" (operations map-scopes). Writes the committed scopes/*.md contracts by import-graph slicing along business flow, with write-whitelist substrates and e2e fixtures. NOT for decomposing a pitch into tasks (ba-pitch-analyzer) or cutting scope at ship time (scope-hammer)."
4
- ---
5
-
6
- # Scope Architect (pure worker v1.0)
7
-
8
- **Slice by flow, never by directory — and write it as a contract a hook can enforce.**
9
-
10
- Groups a feature's tasks into independent, vertically-sliced **scopes** and writes each as a
11
- committed contract (`shapeup/<slug>/scopes/<scope-id>.md`) the rest of the
12
- harness enforces mechanically: the sandbox hook denies writes outside a substrate, t0-verify
13
- runs the fixtures, the evaluator asserts only against the affordance manifest. This skill is
14
- the **sole writer** of scope contracts — a distinct authority from the planner (task
15
- decomposition) and a distinct failure mode (directory-thinking, PA1) deserving its own
16
- the ship report's census table.
17
-
18
- ## Input contract — the WorkOrder
19
-
20
- **Kernel commands.** `<kernel>` below is the absolute path in your order's `kernel` field: run every kernel command as `node "<kernel>" …`. Never spell it `${CLAUDE_PLUGIN_ROOT}` — a command carrying a variable is refused in a headless session before any permission rule is read, and the query your contract requires never runs. With no order (invoked by hand), the kernel is `kernel/harness.mjs` two directories above this skill's base directory.
21
-
22
- | Field | What it is |
23
- |---|---|
24
- | `operation` | `map-scopes` — the only operation this skill has. It covers first slicing after the board exists, folding discovered items in, and re-slicing a stuck scope; the payload says which of those you are doing |
25
- | `payload.feature` / `payload.spec_folder` | Slug + committed spec (read ux-behavior.md for manifests; usecases for flows) |
26
- | `payload.breadboard` | When present, every U# the spec places is one manifest entry's `source`; record which scopes deliver each V# slice in `scope-board.md` (your write surface — `scope-summary.md` is the planner's) |
27
- | `payload.tasks[]` | The board's tasks with their touched files — the slicing INPUT only. Each carries `use_case_refs`; those UC ids are what you write into the contract. Never copy a task id into a contract |
28
- | `payload.kb_rules_path` | Team guidelines (read if the file exists) — slicing habits for this codebase, config files that must have exactly one owner, fixtures that have proved vacuous. Steering, never spec: a guideline cannot widen a substrate or stand in for the lint; conflict → the spec and the lint win, noted in `deviations` |
29
- | `substrate.allowed` | `scopes/*.md` + `scope-board.md` — your ONLY write surface |
30
-
31
- ## Core process
32
-
33
- ```
34
- 0 READ the team guidelines at payload.kb_rules_path, if the file exists — they aim the
35
- slicing and name the config seams that must have one owner; absent = none recorded.
36
- 1 SLICE build an import/business-flow graph over the tasks' touched files (grep heuristic
37
- is fine; AST is an optimization). One scope = one call chain: the UI screen + the
38
- API route + the use case + the repository it drives. Scopes aligning 1:1 with a
39
- top-level directory (all-frontend, all-backend) FAIL — that is layer-thinking.
40
- 2 CLASSIFY topology_type: LAYER_CAKE (thin balanced UI+backend) | ICEBERG (complexity on one
41
- side) | CHOWDER (true strays with no shared flow — the one deliberate exception)
42
- 3 CONTRACT per scope, write scopes/<scope-id>.md — MARKDOWN (ADR-0001): frontmatter for
43
- scalars and [a, b] lists, a `## Affordances` table for affordance_manifest, and a
44
- short `## Why this slice` paragraph. A reviewer must be able to read the substrate
45
- in a PR; regeneration preserves prose under headings you do not own.
46
- ► affordance_manifest lives in the TABLE and NOWHERE ELSE. Do not also write it in
47
- the frontmatter: nothing reads it there, so the copy is discarded — and a run has
48
- been lost to exactly that. The frontmatter copy said required_states: [idle], the
49
- table cell said a bare idle, the table won, the value was a string where an array
50
- was required, and four scopes were never dispatched — the board green, the contract
51
- lint-clean, each leg reporting done with no error, every round, until EVAL refused
52
- to grade a round whose scopes had never run. A contract declaring no affordances
53
- writes `affordance_manifest: []` in frontmatter and no table.
54
- ► A LIST INSIDE A TABLE CELL IS WRITTEN `[a, b]`, brackets and all — `[idle]`, never
55
- `idle`. A bare word in that cell is a string, and required_states is an array.
56
- scope_id, topology_type — the stable join key is the scope
57
- use_cases[] — the UC ids this scope implements.
58
- THE ONLY LINK YOU WRITE TO THE
59
- WORK: never task ids. The contract
60
- is committed and the board is not,
61
- so a TASK-NNN here dangles on
62
- every other clone (spec-lint
63
- TIER-DIRECTION reds it). The
64
- scope's tasks are re-derived from
65
- the board's own use_case_refs
66
- covers[] — optional REQ-ids from
67
- requirements.md this scope answers
68
- for; stable, never renumbered.
69
- WRITE THE REGISTRY'S OWN KEY:
70
- `REQ-12`, not the pitch's `R12`.
71
- Both resolve — readers normalise —
72
- but one spelling in the committed
73
- contract is one thing to read
74
- depends_on[] — scope_ids this scope builds AFTER.
75
- This is the build ORDER — declare
76
- it whenever one scope consumes
77
- another's output, or the two race
78
- allowed_file_substrate[] — exact globs; the sandbox hook's
79
- write-whitelist; wrong here =
80
- a legitimate ESCALATE later
81
- shared_substrate[] — files ≥2 scopes both touch;
82
- declaring one costs concurrency:
83
- they build one at a time
84
- affordance_manifest — from ux-behavior.md state
85
- tables: every interactive
86
- element as {test_id, role} +
87
- required_states [idle, loading,
88
- success, error, empty]
89
- + `source` — the U# the
90
- ux-behavior row cites
91
- e2e_verification_fixtures[] — the command(s)/spec file(s)
92
- that drive this scope
93
- end-to-end (T0 layer); too
94
- speculative to fixture → mark
95
- TBD and flag it, never invent
96
- a fixture for unbuilt behavior
97
- hill_phase: "UPHILL_UNKNOWN" — ALWAYS; phase is derived from
98
- T0/T1 facts later,
99
- never authored
100
- 4 LINT node "<kernel>" verify spec --slug <slug>
101
- → PA1 (directory alignment), PA2 (>~15 files), DISJOINT (undeclared overlap),
102
- SCOPE-ANCHOR (empty/unresolvable use_cases), TIER-DIRECTION (a task id in a
103
- committed contract), SCOPE-DEPS (depends_on naming a scope that isn't here).
104
- Fix reds by re-slicing, not by silencing.
105
- 5 BOARD regenerate scope-board.md — a VIEW of the contracts, nothing more:
106
-
107
- | scope_id | topology | use_cases | depends_on | files | lint |
108
-
109
- Every column restates a field the contract already declares, so the board can be thrown
110
- away and rebuilt. Do NOT add a `wave` column: waves are Kahn levels of `depends_on` and
111
- `probe resume` derives them at dispatch — a hand-written copy of a derived value drifts,
112
- which is exactly why `unlocks` stopped being authored. The BUILD ORDER lives in each
113
- contract's `depends_on`; the board only shows it.
114
-
115
- A `TASK-` id anywhere in a contract or the board — a column, a cell, or a sentence in
116
- the prose — is spec-lint TIER-DIRECTION red. The board is committed; ids are not.
117
- ```
118
-
119
- **Folding in a discovered item:** it joins the nearest scope only if the flow matches (extend that
120
- substrate minimally); otherwise propose a NEW scope — never silently widen an existing one.
121
- **Re-slicing a stuck scope:** re-run step 1 on just that scope's task+file set → N new contracts;
122
- mark the old one `superseded_by: [ids]` — never delete (branch and T0 history stay attributable).
123
-
124
- ## Anti-rationalization table
125
-
126
- | Excuse | Reality |
127
- |---|---|
128
- | "The discovered item obviously fits scope A" | Run the flow match. 'Obviously' is how substrates silently widen. |
129
- | "One scope per directory is cleaner" | That's PA1 — a layer, not a flow. A scope must ship something a user can do. |
130
- | "I'll widen the substrate a little so the doer stops escalating" | A wide substrate is no substrate. Split or add a shared_substrate entry, deliberately. |
131
- | "This scope looks downhill, I'll set the phase" | hill_phase is UPHILL_UNKNOWN at write, always. Facts move dots, not authors. |
132
- | "The old contract is superseded, delete it" | supersede-never-delete. History must stay attributable. |
133
- | "Both scopes implement that UC, the tasks will sort themselves out" | They will not — both scopes get every task of that UC and three of four writes get denied. Give each scope its own use cases, or say so in deviations[] so the board can be stamped. |
134
- | "I'll list the task ids so the contract says what it builds" | The board is gitignored and renumbers per machine; the contract is committed. Cite the UCs — the tasks are re-derived from them. |
135
- | "Build order is obvious from the slice, I'll leave depends_on empty" | Nothing infers it any more. An undeclared edge means the two scopes are released into the same wave and race. |
136
- | "Fixtures can come later, leave the field empty" | Fixture at contract time or an explicit TBD flag — silence is how T0 goes blind. |
137
-
138
- ## Output contract — the WorkResult
139
-
140
- **Escalation rule.** If you return `status: "escalated"`, the **first** entry in `deviations[]`
141
- must be the blocker: one specific, answerable question plus the context needed to answer it.
142
- Nothing else in the envelope carries it — there is no `escalates[]` field — so a vague entry, or
143
- the question buried under other notes, reaches the human as "something went wrong" and costs a
144
- round. Write it so someone without your context can answer it in one reply.
145
-
146
-
147
- `scopes/*.md` + `scope-board.md` in your substrate, then
148
- `.shapeup/<slug>/results/<order-suffix>.json`: `status`, `artifacts[]` (the contracts
149
- written/superseded), `deviations[]` (e.g. a discovered item implying a new UC — the planner's
150
- territory — and any lint warn left standing, with why). You never touch task files,
151
- `tasks/_index.md`, spec docs, or run-state.
152
-
153
- ## Verification checklist
154
-
155
- - [ ] Every scope crosses layers or is declared CHOWDER; spec-lint PA1 = 0 red
156
- - [ ] Every scope names ≥1 `use_cases` that resolves on disk, and NO contract carries a task id
157
- - [ ] Every scope that consumes another's output declares it in `depends_on`
158
- - [ ] Substrates disjoint except declared shared_substrate (DISJOINT = 0 red)
159
- - [ ] Every interactive element in scope screens appears in exactly one affordance_manifest
160
- - [ ] Every U# the spec places is some manifest entry's `source`
161
- - [ ] Every scope has fixtures or an explicit TBD flag
162
- - [ ] Every hill_phase written is UPHILL_UNKNOWN; superseded contracts kept
163
- - [ ] The WorkResult validates against `work-result.schema.json`
164
-
165
- ## Invocation
166
-
167
- ```bash
168
- # Orchestrated — compile-order --operation map-scopes --worker scope-architect …
169
- /scope-architect --order .shapeup/checkout-vnpay/orders/map-scopes.json
170
-
171
- # Standalone shims (compile the same envelope)
172
- /scope-architect --map shapeup/checkout-vnpay/
173
- /scope-architect --map --split cart-creation shapeup/checkout-vnpay/ # re-slice one scope
174
- ```
@@ -1,231 +0,0 @@
1
- ---
2
- name: scope-hammer
3
- description: "Use this skill whenever a Shape Up build run reaches its stop condition — the circuit breaker (round budget or a scope's attempt budget) trips, or all scopes finish and it's time to decide when to stop (step 11) — and needs a must-have census, a baseline-anchored cut list, and a ship verdict. Trigger on: \"scope hammer\", \"hammer this down to must-haves\", \"decide when to stop\", \"cut list vs baseline\", \"circuit breaker tripped, what do we ship\", \"compare against the baseline not the ideal\", \"GATE H\", \"census the open items\". Also triggers on tech-lead's GATE H at SHIP. Compares the product to the pitch's baseline (what customers live with today, not a perfect ideal) and returns a cut list + ship verdict."
4
- ---
5
-
6
- # Scope Hammer (GATE H — Decide When to Stop)
7
-
8
- The mechanism behind Shape Up step 11: as the appetite/round budget runs out, cut back on
9
- perfectionist ambitions by comparing the *actual* product to the **baseline** — what customers
10
- live with today — not to a hypothetical perfect version. "Better than the baseline" is good
11
- enough to ship; "not as good as I imagined" is not a reason to keep building.
12
-
13
- **Why this is its own skill, not tech-lead prose.** GATE H census pulls from several sources
14
- that accumulate over a whole run (QA findings, discovered-task ledger, attempt-budget
15
- overflows, per-scope inner-breaker trips) — a genuinely separate synthesis step from
16
- orchestration. Splitting it out keeps `tech-lead` thin (it dispatches, this skill decides what
17
- survives the hammer) and gives the census/cut-list/verdict logic one owner instead of being
18
- re-derived inline at every SHIP.
19
-
20
- ---
21
-
22
- ## When this fires
23
-
24
- ```
25
- 1. All scopes reach FINISHED on the hill → normal stop, post-QA-hunt.
26
- 2. Outer circuit breaker trips: round_budget reaches 0 with scopes still uphill/downhill.
27
- 3. Inner circuit breaker trips: a scope's attempt_budget (default 5) is exhausted without a
28
- T0-green result → queued as a hammer PROPOSAL (`hammer_proposals`),
29
- judged here rather than immediately blocking the round.
30
- ```
31
- Any of the three routes to this skill; the difference is only what's in the census (case 1 has
32
- no unresolved scopes; cases 2/3 do, and those become explicit CUT or CARRY candidates below).
33
-
34
- ---
35
-
36
- ## Workflow
37
-
38
- ```
39
- INPUT: run's finished/unfinished scopes + baseline + census sources
40
- │
41
- ⏸ GATE H0 │ Census ──────────────► collect every open item, classify must-have / nice-to-have
42
- │
43
- ⏸ GATE H1 │ Baseline Comparison ──► for each unresolved must-have, is the product still
44
- │ better than the baseline without it?
45
- │
46
- ⏸ GATE H2 │ Cut List & Verdict ───► propose cuts (PO confirms), ship / carry-to-next-cycle verdict
47
- │
48
- ✅ Done └─► cut list + verdict handed to tech-lead SHIP; PO owns the final call
49
- ```
50
-
51
- ---
52
-
53
- ## GATE H0 — Census
54
-
55
- **Kernel commands.** `<kernel>` below is the absolute path in your order's `kernel` field: run every kernel command as `node "<kernel>" …`. Never spell it `${CLAUDE_PLUGIN_ROOT}` — a command carrying a variable is refused in a headless session before any permission rule is read, and the query your contract requires never runs. With no order (invoked by hand), the kernel is `kernel/harness.mjs` two directories above this skill's base directory.
56
-
57
- **Purpose:** Gather every open item into one list before judging any of them. Never judge
58
- piecemeal — a partial view produces a wrong cut.
59
-
60
- ```
61
- H0.0 Ownership is DERIVED, never stated. Before the census says "no scope owns X" or "X is
62
- scope Y's", run
63
- node "<kernel>" probe owner --slug <slug> [--path <p>]...
64
- and cite its row. With no --path it answers for every engine and entry call site the wiring
65
- map names plus the profile's entry point; `writers: []` is an unowned seam and `missing`
66
- lists seams the wiring names that are not on disk — owned but never written. A census that
67
- narrated ownership from memory once told the PO no scope owned a screen directory that a
68
- committed contract listed in plain sight — and pointed the ship decision at the wrong gap.
69
- H0.1 Unresolved scopes (breaker cases only):
70
- - uphill/downhill scopes when round_budget hit 0 → CARRY candidates (their own hill
71
- phase + open unknowns, from hill/<scope-id>.yml)
72
- - scopes with hammer_proposals (attempt_budget exhausted) → CARRY candidates. Exhaustion
73
- is DERIVED, never read off `t0/verdicts/*.json` directly — a compiled order or a T0
74
- verdict is writable by the very scope being judged and proves nothing on its own. Run
75
- node "<kernel>" probe attempts --slug <slug> \
76
- --scope <scope-id> --round <n> --attempt-budget <n>
77
- and cite its `spent`/`tripped` fields (exit 1 = tripped) — an attempt counts only when a
78
- dispatch receipt AND either a leg-completion row or a WorkResult attest it, so a leg still
79
- in flight holds it open rather than reading as exhausted. This is the SAME derivation the
80
- round loop's own inner breaker reads, so the census and the breaker cannot disagree about
81
- the same exhaustion the way a live run once measured.
82
- H0.2 QA findings (qa-edge-hunter's hunt-report.md, when present) — all `~` by default.
83
- H0.3 Discovered-task ledger entries still open (discovery/ledger.md, `[+]`/`~` unresolved).
84
- H0.4 Attempt-budget hammer proposals (scopes that exhausted their T0 attempts during BUILD).
85
- H0.4b Requirements with no PASS evidence — the pitch clauses the run never showed working. Run
86
- node "<kernel>" probe requirements --slug <slug> --format table
87
- and take its `no evidence` rows; cite the row, the same way H0.0 cites ownership. Each is a
88
- census item carrying its source clause (`REQ-12 ← shaping.md R12`). A `cut` row is an answer
89
- the PO already gave — not an item. An inconsistency row (a criterion anchored to a
90
- requirement no acceptance criterion covers) is reported to the PO as a reconciliation, never
91
- counted as evidence and never promoted as a finding. No registry on disk → this input is
92
- empty and the census is unchanged (absent artifact ⇒ arm skipped).
93
- H0.5 Classify every item: MUST-HAVE (the pitch's core problem is unsolved without it) vs
94
- NICE-TO-HAVE (`~`, improves but doesn't block the core promise). Default to NICE-TO-HAVE
95
- unless the item traces directly to a pitch boundary or a scope's business_goal — a
96
- generous must-have list defeats the point of hammering.
97
- ```
98
-
99
- **GATE H0 Output:**
100
- ```
101
- ⏸ GATE H0 — Census
102
- Must-have (unresolved) : [N] — [list, each with source: scope | QA | discovered | requirement |
103
- advisor-overflow]
104
- Nice-to-have (~) : [M]
105
- Carry candidates : [scopes still uphill/downhill, or exhausted attempt budget]
106
- ```
107
-
108
- ---
109
-
110
- ## GATE H1 — Baseline Comparison
111
-
112
- **Purpose:** The trade-off algorithm from step 11 — compare to the baseline (status quo the
113
- customer suffers through today), never to a perfect ideal.
114
-
115
- ```
116
- H1.1 Resolve the baseline: shapeup/<slug>/shaping/baseline.md if present (written at
117
- shaping time — first-class, not a pitch footnote). Absent →
118
- degrade honestly: read the pitch's problem statement as the implicit baseline and flag
119
- "baseline not first-class — comparison is approximate" in the report. Do not invent one.
120
- H1.2 For each MUST-HAVE item from H0: "with this item cut/carried, is the shipped product
121
- still strictly better than the baseline for the pitch's core problem?"
122
- YES → safe to cut/carry — demote to a cut-list candidate anyway (H2 still asks the PO).
123
- NO → this one item blocks shipping as-is; it is not hammer-cuttable. Options are:
124
- fix it now (one more focused attempt, not a full extra round) or the run
125
- genuinely fails the appetite — escalate to PO honestly, do not ship anyway.
126
- H1.3 NICE-TO-HAVE items never block H1 — they are cut-list candidates by construction.
127
- ```
128
-
129
- ---
130
-
131
- ## GATE H2 — Cut List & Verdict
132
-
133
- **Purpose:** Turn H0+H1 into a decision, owned by the PO — this skill proposes, it never cuts
134
- unilaterally.
135
-
136
- ```
137
- ⏸ GATE H2 — Cut List & Verdict
138
- Baseline : [shapeup/<slug>/shaping/baseline.md | approximate — pitch problem statement]
139
- Ship-blocking : [none | list of MUST-HAVE items that fail H1.2 — these are NOT cuttable]
140
- Proposed cuts : [N nice-to-have + N cuttable must-have, each: item — source — one-line why safe]
141
- Carry-forward : [scopes/items proposed for the next cycle's raw-idea list, debt-free]
142
- Verdict : [SHIP now | SHIP after fixing ship-blocking items | CANNOT SHIP — escalate to PO]
143
- ```
144
- Ask (max 1): "Confirm this cut list? (approve all / list ids to keep / none)". PO can keep any
145
- proposed cut — this skill never overrides that. On confirm, everything NOT kept becomes:
146
- - Nice-to-haves + safe must-have cuts → carried to the discovery ledger as raw ideas
147
- (debt-free — never silently dropped, never silently promoted back into scope).
148
- - Ship-blocking items (if any survived because PO overrode SHIP anyway) → logged explicitly
149
- as a known gap in the ship report, never hidden.
150
-
151
- Authority boundary: this skill produces the proposal; `tech-lead` records the PO's decision in
152
- the round-ledger and performs the actual SHIP close. Scope-hammer does not write status: done,
153
- does not deploy, and does not itself decide to ship — same judge/doer separation as the rest of
154
- the harness (this is neither the generator nor the evaluator).
155
-
156
- ---
157
-
158
- ## Envelope contract — the domain layer
159
-
160
- Orchestrated, this skill is dispatched like every worker: a **WorkOrder** in (`--order <path>`,
161
- operation `hammer`), a **WorkResult** out. The standalone flags below map 1:1 onto the payload
162
- fields registered for this worker in the central domain registry
163
- (`kernel/schemas/domain.schema.json`, `x-payload-by-worker`):
164
-
165
- | Payload field | Standalone flag | Meaning |
166
- |---|---|---|
167
- | `payload.feature` | `--slug` | The feature slug (resolves scopes/, hill/, ledger paths) |
168
- | `payload.baseline` | `--baseline` | `shaping/baseline.md` — comparison anchor (absent → the pitch's problem statement, flagged approximate) |
169
- | `payload.breaker` | `--breaker` | `outer` \| `inner` — which circuit breaker fired (absent = normal stop) |
170
- | `payload.scope_id` | `--scope` | With `--breaker inner`, the scope whose attempt budget was exhausted |
171
-
172
- The WorkResult may carry only `files_touched`, `artifacts`, `assumptions`, `deviations`
173
- (`x-result-by-worker`): the census, cut list, and ship verdict live in the report artifact as a
174
- **proposal** — promotion and shipping stay a human call, never envelope data ingest acts on.
175
-
176
- **The census is also written as data**, at `.shapeup/<slug>/reports/hammer-census.json` (inside
177
- this operation's substrate), shape `HammerCensus` in the domain registry:
178
-
179
- ```json
180
- { "schema_version": 1, "order_id": "<the order>", "verdict": "ship-now | ship-after-fixes | cannot-ship",
181
- "cut_list": ["…"], "ship_blocking": ["…"], "breaker": "outer | inner | deadline | null", "baseline": "<path or null>" }
182
- ```
183
-
184
- GATE L4's resolver reads this file — and nothing else — before it lets any answer set say `ship`.
185
- It is the same proposal as the H2 block, written by the same hand, in a shape a gate can read:
186
- a census that lives only in printed blocks cannot be read by a gate, and a run that reached L4
187
- with a green census could only be recorded as `ask`. Still a proposal: the file grants nothing.
188
-
189
- ---
190
-
191
- ## Invocation
192
-
193
- ```bash
194
- # Normal stop — all scopes FINISHED, after QA hunt
195
- /scope-hammer --slug checkout-vnpay --baseline shapeup/checkout-vnpay/shaping/baseline.md
196
-
197
- # Circuit breaker tripped — some scopes still open
198
- /scope-hammer --slug checkout-vnpay --breaker outer # round_budget exhausted
199
- /scope-hammer --slug checkout-vnpay --breaker inner --scope cart-creation # attempt_budget exhausted
200
-
201
- # Headless — no PO available; still refuses to auto-ship a ship-blocking item
202
- /scope-hammer --slug checkout-vnpay --unattended
203
-
204
- # The ownership query every census claim cites (H0.0)
205
- node "<kernel>" probe owner --slug checkout-vnpay --format table
206
- node "<kernel>" probe owner --slug checkout-vnpay --path src/pages/Cart.ets
207
- ```
208
-
209
- ### Flags
210
- | Flag | Effect |
211
- |------|--------|
212
- | `--slug <name>` | The run's feature slug (resolves scopes/, hill/, ledger paths) |
213
- | `--baseline <path>` | Explicit baseline doc (default: `shaping/baseline.md`, else approximate) |
214
- | `--breaker outer\|inner` | Which circuit breaker triggered this call (changes H0.1 census scope) |
215
- | `--scope <id>` | With `--breaker inner`, the scope whose attempt budget was exhausted |
216
- | `--unattended` | No PO available — still HARD STOPS rather than auto-shipping a ship-blocking item |
217
-
218
- ---
219
-
220
- ## Hard Rules (never override without explicit user instruction)
221
-
222
- | Rule | Rationale |
223
- |------|-----------|
224
- | Compare to the baseline, never to a perfect ideal | Step 11's actual trade-off algorithm — "better than what customers live with today" is the bar |
225
- | Default classification is NICE-TO-HAVE unless traced to a pitch boundary or business_goal | A generous must-have list defeats the point of hammering |
226
- | A MUST-HAVE that fails H1.2 is never cut silently | The one case where scope-hammer refuses to make the run "look" shippable |
227
- | Cuts are proposals; the PO confirms every one | This skill never overrides the human at the ship gate |
228
- | Every ownership claim in the census cites `harness probe owner` | Ownership is what the contracts' substrates say — the same election `harness compile` uses to address a bug — never what the report remembers |
229
- | Cut items are carried to the discovery ledger, never silently dropped | Cool-down must stay debt-free — an idea deferred is still recorded |
230
- | Never sets status: done, never deploys, never ships unilaterally | Judge/doer/advisor separation holds even at the very last gate |
231
- | An overridden ship-blocking item is logged explicitly in the ship report | "Shipped" must never quietly mean "shipped with a known must-have gap" |
@@ -1,158 +0,0 @@
1
- ---
2
- name: solution-architect
3
- description: "Use this skill to design how each use-case's engine integrates into the running application — the wiring map that guarantees no engine ships orphaned. Triggers on: \"write the wiring map\", \"declare the integration seam for each use case\", \"how does each use case get wired in\", \"map engines to the entry point\", \"which use cases are reachable from the composition root\", \"the asset pipeline has zero call sites\", \"front-load the integration seam before we slice scopes\", or a tech-lead --order dispatch (operation wire) at gate L1a.5. Writes the per-use-case wiring map: engine → integration seam → composition-root attachment → player-visible affordance, resolved against the project profile's entry_point. NOT for slicing scopes (scope-architect) or decomposing a pitch into tasks (ba-pitch-analyzer)."
4
- ---
5
-
6
- # Solution Architect (pure worker v1.1)
7
-
8
- **Design the seam, or the engine ships orphaned.**
9
-
10
- This skill exists because a sizeable engine module can be built, fully tested, and still have
11
- **zero call sites** in the app's composition root — green, and unreachable from the
12
- running application; observed across multiple scopes in one run, not theorized. It closes that
13
- hole at the front: before the scopes are sliced, it designs a committed **wiring map**
14
- (`shapeup/<slug>/wiring-map.md`) that names, for every use case, the chain from the
15
- engine module to a player-visible affordance — including **how** and **where** the engine attaches
16
- to the application's entry point.
17
-
18
- You work at **design time (gate L1a.5), before any code exists.** Your output is *intended*
19
- architecture — the seam the build must create — not a description of code already written. You do
20
- **not** verify reachability and you do **not** run any oracle: that is a build-time fact the
21
- orchestrator's `trace-lint` proves against real code at L1b. Your job is to make the seam
22
- *explicit and buildable*.
23
-
24
- Two payoffs, one artifact:
25
- - **Reachability becomes checkable later.** Because you name each UC's `engine` (a real
26
- repo-relative module path) and the profile declares the `entry_point`, `harness verify trace` can
27
- fold this map into its oracle *after the build*: a UC whose engine does not reach the
28
- `entry_point` via the import graph goes red. You supply the two anchors; the oracle does the
29
- proving.
30
- - **The slicer gets its integration seam up front.** Declaring each attachment *before*
31
- `scope-architect` runs supplies the missing input behind the round-1 substrate-expansion
32
- escalations — repeated identical "declined by precedent" stalls. (This skill *front-loads* the
33
- seam; it does not enforce the re-slice rule — that's a separate change.)
34
-
35
- You are the **sole writer** of the wiring map, written **directly** (the same authority
36
- `scope-architect` has over `scopes/*.md` — you bypass `ingest-result`). Everything else you
37
- return as a WorkResult.
38
-
39
- ## Input contract — the WorkOrder
40
-
41
- **Kernel commands.** `<kernel>` below is the absolute path in your order's `kernel` field: run every kernel command as `node "<kernel>" …`. Never spell it `${CLAUDE_PLUGIN_ROOT}` — a command carrying a variable is refused in a headless session before any permission rule is read, and the query your contract requires never runs. With no order (invoked by hand), the kernel is `kernel/harness.mjs` two directories above this skill's base directory.
42
-
43
- | Field | What it is |
44
- |---|---|
45
- | `operation` | `wire` (author/refresh the wiring map after `analyze`, before `map-scopes`) |
46
- | `payload.feature` / `payload.spec_folder` | Slug + committed spec — read `usecases/` for the UCs and the engine each one needs, `domain-model.md`/`synthesis.md` for the module surface |
47
- | `payload.breadboard` | When present, name each UC's `affordance` by its U# and Place |
48
- | `payload.kb_rules_path` | Team guidelines (read if the file exists) — the seams this codebase actually wires through, entry points that are not where the template says. Steering, never spec: the profile's `entry_point` still wins, and a guideline that disagrees with it is reported in `deviations`, not applied |
49
- | `payload.project_profile` | Path to the SHARED `project-profile.md`. Its `entry_point` is the composition root every engine must attach to — **archetype-specific** (a client-only game's `main.js` is not a web-service's `src/server.ts`). Read it; never guess the entry point |
50
- | `substrate.allowed` | `wiring-map.md` — your ONLY write surface (the spec core, scopes, and the profile are frozen) |
51
-
52
- **If the profile is absent in an orchestrated run, ESCALATE (spec-ambiguity) — do not invent an
53
- entry point.** The whole point is that the seam resolves against a *declared* composition root; a
54
- guessed `main.js` would make the later oracle certify nothing.
55
-
56
- ## Core process
57
-
58
- ```
59
- 1 READ the team guidelines at payload.kb_rules_path if the file exists (absent = none),
60
- then the project profile → entry_point + archetype. Read every use case in usecases/.
61
- For each UC, identify the engine module that carries its core logic (the file that
62
- WILL exist, named from the domain model / synthesis surface — not a guess at a folder).
63
- 2 DESIGN for each UC, design the integration path from the entry_point inward:
64
- engine the module implementing the UC (repo-relative path — the ONE
65
- field the later reachability oracle resolves; name the real path)
66
- wiring_seam HOW it attaches — the mechanism: an event handler, a route
67
- registration, an init hook, a subscription, a DI registration, a
68
- CLI command, a cron trigger (prose the slicer reads)
69
- entry_call_site WHERE it attaches — the composition root it registers into, named
70
- from the profile's entry_point as design intent, e.g.
71
- "src/server.ts — POST /checkout route" or "main.js — game-loop
72
- init hook". This is the seam the build will CREATE, symbolic, not
73
- an existing coordinate. Never invent a line number; the concrete
74
- file:line is a build-time fact (the oracle proves reachability by
75
- the import graph, it does not parse this field)
76
- affordance the player-visible thing this UC exposes once wired (the human
77
- end of the chain — what a user can DO, not an internal call);
78
- with a breadboard, name it by U# and Place —
79
- `U1 Pay (P1) → P2 Payment Sheet`
80
- 3 WRITE shapeup/<slug>/wiring-map.md (WiringMap): frontmatter for schema_version, feature
81
- and entry_point (echo of the profile), then entries[] as ONE MARKDOWN TABLE under a
82
- `## Wiring` heading — this exact shape, because it is the only one the reader parses:
83
-
84
- ## Wiring
85
-
86
- | use_case | engine | wiring_seam | entry_call_site | affordance |
87
- |---|---|---|---|---|
88
- | UC-01 | src/parsing.mjs | argv dispatch calls parseEnv | bin/envlint.mjs | envlint <file> |
89
-
90
- One ROW per use case + engine pair — a UC carried by two engines gets two rows, never
91
- one cell naming both. `engine` is a bare repo-relative path and nothing else: the
92
- oracle resolves that cell against disk, and a cell like "`a.mjs` and `b.mjs` — two pure
93
- modules" resolves to no file and is reported unverifiable. Put the explanation in the
94
- `## Deviations` prose, never in the cell.
95
-
96
- A UC whose
97
- engine has no attachment path is exactly the gap this artifact exists to surface —
98
- write the entry with the seam you INTEND and raise it in deviations[], so
99
- the build knows the wiring it must close. Your craft ends here: WRITE, then return the
100
- WorkResult. You do not run trace-lint — the orchestrator runs it advisory at L1b.
101
- ```
102
-
103
- **No use case is exempt.** If a UC's engine genuinely has no player-facing seam (a pure
104
- background job), say so in `wiring_seam` and name the boot/cron/init attachment that starts it — a
105
- cron registration, a boot hook. "It's internal" is how an engine stays orphaned; there
106
- is always an attachment to the entry point, or the code never runs.
107
-
108
- ## Anti-rationalization table
109
-
110
- | Excuse | Reality |
111
- |---|---|
112
- | "The engine is imported somewhere, that's enough" | Reachability (proven later) is from the *entry_point*, transitively. Imported by a sibling that nothing runs is still orphaned. Design the attachment to the composition root. |
113
- | "I'll guess the entry point is main.js" | The profile declares it. A game's `main.js` is not a service's `src/server.ts`. Read the profile or ESCALATE. |
114
- | "I'll write the call site as main.js:42" | You design at L1a.5 — that code does not exist yet, so a line number is a fabrication no oracle reads. Name the composition root + mechanism as intent; leave the concrete line to the build. |
115
- | "This UC has no visible affordance, skip it" | Then name its boot/cron/init attachment. A UC with no entry point is a UC that never runs. |
116
- | "I'll run trace-lint to check my map" | Not your step. You design the seam; the orchestrator runs the reachability oracle against real code at L1b. Pre-build there is no code to trace — running it here proves nothing. |
117
- | "I'll also slice the scopes while I'm here" | Not your authority. You design seams; scope-architect slices. Cross-role work is a defect. |
118
-
119
- ## Output contract — the WorkResult
120
-
121
- **Escalation rule.** If you return `status: "escalated"`, the **first** entry in `deviations[]`
122
- must be the blocker: one specific, answerable question plus the context needed to answer it.
123
- Nothing else in the envelope carries it — there is no `escalates[]` field — so a vague entry, or
124
- the question buried under other notes, reaches the human as "something went wrong" and costs a
125
- round. Write it so someone without your context can answer it in one reply.
126
-
127
-
128
- `wiring-map.md` in your substrate, then `.shapeup/<slug>/results/<order-suffix>.json`:
129
- `status`, `artifacts[]` (the wiring map written), `assumptions[]` (engine paths
130
- inferred from the domain model where the spec was silent), `deviations[]` (a missing profile, a
131
- UC whose engine the spec never names — the planner's territory — a UC left with an uncertain
132
- seam, or an engine with no attachment path, and why). You never touch spec docs,
133
- `scopes/*.md`, `project-profile.md`, task files, or run-state.
134
-
135
- ## Verification checklist
136
-
137
- - [ ] Every use case in `usecases/` has exactly one wiring-map entry
138
- - [ ] Every entry names a real repo-relative `engine` and a `wiring_seam` (attachment mechanism); a player-facing UC also names an `affordance`
139
- - [ ] `entry_call_site` is a symbolic composition-root attachment resolved against the profile's `entry_point` — no invented line number, no guessed entry point
140
- - [ ] `entry_point` echoes the profile — no independently-chosen seam
141
- - [ ] The profile was READ, not guessed; a missing profile in orchestrated mode → ESCALATE, not an invented entry point
142
- - [ ] Any UC whose engine has no attachment path is raised in `deviations[]` (the wiring the build must close), never silently dropped
143
- - [ ] The WorkResult validates against `work-result.schema.json`
144
-
145
- ## Invocation
146
-
147
- ```bash
148
- # Orchestrated — compile-order --operation wire --worker solution-architect (or resolved by op) …
149
- /solution-architect --order .shapeup/checkout-vnpay/orders/wire.json
150
-
151
- # Standalone shim (compiles the same envelope)
152
- /solution-architect --wire shapeup/checkout-vnpay/
153
-
154
- # The reachability oracle is the ORCHESTRATOR's, run advisory at L1b — not part of your craft.
155
- # Standalone, you MAY preview it after writing the map (it self-skips arms whose artifacts are
156
- # absent, and is near-vacuous pre-build since the engine code does not exist yet):
157
- # node "<kernel>" verify trace --slug checkout-vnpay
158
- ```