shapeup-sdlc 1.6.2

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 (135) hide show
  1. package/.claude/settings.local.example.json +20 -0
  2. package/.claude-plugin/marketplace.json +16 -0
  3. package/.claude-plugin/plugin.json +18 -0
  4. package/.env.shapeup.example +14 -0
  5. package/AGENTS.md +133 -0
  6. package/LICENSE +21 -0
  7. package/README.md +362 -0
  8. package/SECURITY.md +72 -0
  9. package/bin/init.mjs +329 -0
  10. package/commands/build.md +14 -0
  11. package/commands/eval.md +15 -0
  12. package/commands/hammer.md +12 -0
  13. package/commands/orient.md +11 -0
  14. package/commands/qa.md +12 -0
  15. package/commands/retro.md +13 -0
  16. package/commands/scopes.md +14 -0
  17. package/commands/shape.md +12 -0
  18. package/commands/ship.md +53 -0
  19. package/commands/wire.md +11 -0
  20. package/hooks/anti-rationalization.mjs +244 -0
  21. package/hooks/compact-snapshot.mjs +47 -0
  22. package/hooks/gate-deadline.mjs +151 -0
  23. package/hooks/gate-intake.mjs +110 -0
  24. package/hooks/gate-l2.mjs +161 -0
  25. package/hooks/gate-zerowork.mjs +264 -0
  26. package/hooks/hooks.json +118 -0
  27. package/hooks/lib/decision.mjs +183 -0
  28. package/hooks/safety-spine.mjs +296 -0
  29. package/hooks/sandbox-guard.mjs +172 -0
  30. package/hooks/session-rehydrate.mjs +109 -0
  31. package/hooks/slop-cleaner.mjs +176 -0
  32. package/oracles/_shared.mjs +46 -0
  33. package/oracles/http-oracle.mjs +155 -0
  34. package/oracles/index.mjs +36 -0
  35. package/oracles/process-oracle.mjs +146 -0
  36. package/oracles/snapshot-oracle.mjs +119 -0
  37. package/oracles/test-oracle.mjs +138 -0
  38. package/package.json +49 -0
  39. package/skills/advisor-protocol/SKILL.md +171 -0
  40. package/skills/ba-pitch-analyzer/SKILL.md +175 -0
  41. package/skills/ba-pitch-analyzer/assets/templates/_index.tmpl.md +84 -0
  42. package/skills/ba-pitch-analyzer/assets/templates/api-feasibility.tmpl.md +65 -0
  43. package/skills/ba-pitch-analyzer/assets/templates/assess-report.tmpl.md +127 -0
  44. package/skills/ba-pitch-analyzer/assets/templates/contracts/be-service.contract.tmpl.md +62 -0
  45. package/skills/ba-pitch-analyzer/assets/templates/contracts/offline-storage.contract.tmpl.md +92 -0
  46. package/skills/ba-pitch-analyzer/assets/templates/contracts/third-party-api.contract.tmpl.md +66 -0
  47. package/skills/ba-pitch-analyzer/assets/templates/cross-context/context-map.tmpl.md +64 -0
  48. package/skills/ba-pitch-analyzer/assets/templates/cross-context/event-choreography.tmpl.md +77 -0
  49. package/skills/ba-pitch-analyzer/assets/templates/cross-context/migration-plan.tmpl.md +104 -0
  50. package/skills/ba-pitch-analyzer/assets/templates/cross-context/team-handoff.tmpl.md +79 -0
  51. package/skills/ba-pitch-analyzer/assets/templates/domain-model.tmpl.md +79 -0
  52. package/skills/ba-pitch-analyzer/assets/templates/feedback.tmpl.md +87 -0
  53. package/skills/ba-pitch-analyzer/assets/templates/integration.tmpl.md +64 -0
  54. package/skills/ba-pitch-analyzer/assets/templates/run-state.tmpl.md +77 -0
  55. package/skills/ba-pitch-analyzer/assets/templates/scope-summary.tmpl.md +105 -0
  56. package/skills/ba-pitch-analyzer/assets/templates/synthesis.tmpl.md +215 -0
  57. package/skills/ba-pitch-analyzer/assets/templates/task-board.tmpl.md +35 -0
  58. package/skills/ba-pitch-analyzer/assets/templates/task-spike.tmpl.md +86 -0
  59. package/skills/ba-pitch-analyzer/assets/templates/task.tmpl.md +84 -0
  60. package/skills/ba-pitch-analyzer/assets/templates/usecase.tmpl.md +105 -0
  61. package/skills/ba-pitch-analyzer/assets/templates/ux-behavior.tmpl.md +65 -0
  62. package/skills/ba-pitch-analyzer/references/contract-patterns.md +152 -0
  63. package/skills/ba-pitch-analyzer/references/ddd-patterns.md +173 -0
  64. package/skills/ba-pitch-analyzer/references/doc-schemas.md +275 -0
  65. package/skills/ba-pitch-analyzer/references/integration-analysis.md +152 -0
  66. package/skills/ba-pitch-analyzer/references/task-generation.md +623 -0
  67. package/skills/ba-pitch-analyzer/references/test-surface.md +102 -0
  68. package/skills/ba-pitch-analyzer/references/ux-behavior-patterns.md +269 -0
  69. package/skills/ba-pitch-analyzer/scripts/board-derive.mjs +241 -0
  70. package/skills/ba-pitch-analyzer/scripts/spec-lint.mjs +239 -0
  71. package/skills/coach/SKILL.md +202 -0
  72. package/skills/orient/SKILL.md +262 -0
  73. package/skills/qa-edge-hunter/SKILL.md +369 -0
  74. package/skills/scope-architect/SKILL.md +111 -0
  75. package/skills/scope-hammer/SKILL.md +186 -0
  76. package/skills/shapeup/SKILL.md +403 -0
  77. package/skills/shapeup/resources/breadboard-reflection.md +88 -0
  78. package/skills/shapeup/resources/breadboarding.md +334 -0
  79. package/skills/shapeup/resources/context-compaction.md +240 -0
  80. package/skills/shapeup/resources/framing-doc.md +92 -0
  81. package/skills/shapeup/resources/kickoff-doc.md +95 -0
  82. package/skills/shapeup/resources/shaping.md +194 -0
  83. package/skills/shapeup/resources/spike.md +86 -0
  84. package/skills/solution-architect/SKILL.md +129 -0
  85. package/skills/spec-evaluator/README.md +93 -0
  86. package/skills/spec-evaluator/SKILL.md +213 -0
  87. package/skills/spec-evaluator/references/anti-leniency.md +50 -0
  88. package/skills/spec-evaluator/references/dimension-contract.md +126 -0
  89. package/skills/spec-evaluator/references/dimensions/_registry.md +40 -0
  90. package/skills/spec-evaluator/references/dimensions/completeness.md +102 -0
  91. package/skills/spec-evaluator/references/dimensions/integration.md +129 -0
  92. package/skills/spec-evaluator/references/dimensions/performance.md +48 -0
  93. package/skills/spec-evaluator/references/dimensions/security.md +60 -0
  94. package/skills/spec-evaluator/references/dimensions/spec-conformance.md +134 -0
  95. package/skills/spec-evaluator/references/dimensions/tdd-surface.md +110 -0
  96. package/skills/spec-evaluator/references/dimensions/test-surface-conformance.md +100 -0
  97. package/skills/spec-evaluator/references/probing.md +177 -0
  98. package/skills/spec-evaluator/references/report-schema.md +101 -0
  99. package/skills/spec-evaluator/references/verdict-ledger.md +92 -0
  100. package/skills/spec-evaluator/scripts/verdict-ledger.mjs +166 -0
  101. package/skills/task-executor/SKILL.md +194 -0
  102. package/skills/tech-lead/README.md +71 -0
  103. package/skills/tech-lead/SKILL.md +459 -0
  104. package/skills/tech-lead/references/delegation.md +254 -0
  105. package/skills/tech-lead/references/gates.md +379 -0
  106. package/skills/tech-lead/references/invocation.md +45 -0
  107. package/skills/tech-lead/references/ledger-schema.md +214 -0
  108. package/skills/tech-lead/references/round-protocol.md +184 -0
  109. package/skills/tech-lead/references/state-model.md +66 -0
  110. package/skills/tech-lead/references/tiny-lane.md +52 -0
  111. package/skills/tech-lead/schemas/domain.schema.json +2294 -0
  112. package/skills/tech-lead/schemas/gate-answers.schema.json +92 -0
  113. package/skills/tech-lead/schemas/work-order.schema.json +21 -0
  114. package/skills/tech-lead/schemas/work-result.schema.json +40 -0
  115. package/skills/tech-lead/scripts/aegis-digest.mjs +124 -0
  116. package/skills/tech-lead/scripts/budget-check.mjs +156 -0
  117. package/skills/tech-lead/scripts/compile-order.mjs +518 -0
  118. package/skills/tech-lead/scripts/fit-check.mjs +196 -0
  119. package/skills/tech-lead/scripts/gate-answers.mjs +338 -0
  120. package/skills/tech-lead/scripts/ingest-result.mjs +270 -0
  121. package/skills/tech-lead/scripts/init-run.mjs +326 -0
  122. package/skills/tech-lead/scripts/lib/argv.mjs +224 -0
  123. package/skills/tech-lead/scripts/lib/contract-md.mjs +481 -0
  124. package/skills/tech-lead/scripts/lib/is-main.mjs +82 -0
  125. package/skills/tech-lead/scripts/lib/paths.mjs +278 -0
  126. package/skills/tech-lead/scripts/lib/ratchet-tree.mjs +112 -0
  127. package/skills/tech-lead/scripts/run-snapshot.mjs +269 -0
  128. package/skills/tech-lead/scripts/ship-report.mjs +275 -0
  129. package/skills/tech-lead/scripts/stats.mjs +423 -0
  130. package/skills/tech-lead/scripts/t0-verify.mjs +470 -0
  131. package/skills/tech-lead/scripts/trace-lint.mjs +367 -0
  132. package/skills/tech-lead/scripts/validate-envelope.mjs +283 -0
  133. package/skills/translator/README.md +66 -0
  134. package/skills/translator/SKILL.md +258 -0
  135. package/skills/translator/references/preservation-rules.md +102 -0
@@ -0,0 +1,262 @@
1
+ ---
2
+ name: orient
3
+ description: "Use this skill for Shape Up step 7 (Orient) — the builder-led reconnaissance pass that runs AFTER kick-off and BEFORE any task board exists. Triggers on: \"orient on this feature\", \"scout the codebase for this pitch\", \"where does this pitch touch the code\", \"do an orient pass\", \"recon before we plan\", \"spike the riskiest part before mapping scopes\". The tech-lead orchestrator invokes it at step 7 before delegating to ba-pitch-analyzer (Map Scopes, step 8). Use it even when the user describes \"read the code first and surface the unknowns\" without naming Orient. Also accepts a tech-lead --order dispatch."
4
+ ---
5
+
6
+ # Orient — the Scout (Shape Up step 7)
7
+
8
+ In Shape Up, the team that builds also **orients**: after kick-off they read the real code,
9
+ spike the scary parts, and let reality generate **Discovered tasks** — which outnumber the
10
+ imagined ones. This skill is that pass, made explicit. It exists because the orchestrator
11
+ (`tech-lead`) must *delegate* orientation, and the generator (`task-executor`) can't host it:
12
+ its first gate needs a task file, and **at Orient time no board exists yet** — the board is
13
+ mapped *after* this pass, by `ba-pitch-analyzer` at step 8.
14
+
15
+ So the Scout's whole job is to make the planner's board **reality-born instead of imagined**.
16
+ It hands `ba` a map of where the pitch lands in real code, the findings from de-risking the
17
+ single scariest area, and a seed list of tasks (imagined + already-discovered). Nothing more.
18
+
19
+ ```
20
+ PO: shaping → bet → kick-off ──► tech-lead ──► ORIENT (you) ──► ba (Map Scopes) ──► build
21
+ reads code, spikes, seeds
22
+ ```
23
+
24
+ ---
25
+
26
+ ## What the Scout is and is not
27
+
28
+ | Does | Does NOT |
29
+ |------|----------|
30
+ | Read the kicked-off pitch + breadboard | Re-shape, re-bet, or question the appetite (PO already did) |
31
+ | Trace pitch elements to real files/modules | Write production code |
32
+ | Spike the **single** riskiest area, time-boxed | Build the scope board / tasks (that is `ba`, step 8) |
33
+ | Seed the discovered-task list (imagined + discovered) | Keep `run-state` (tech-lead owns it) |
34
+ | Emit raw hill **signal** (per-area unknowns) | Render the hill **report** (tech-lead renders it) |
35
+
36
+ The Scout is a **pure worker** (the harness rule: stateless workers, one stateful
37
+ orchestrator). It receives run metadata — `feature`, `spec` folder, `stack` — as **arguments**
38
+ from `tech-lead`; it never reads or writes a shared run-state file.
39
+
40
+ ---
41
+
42
+ ## Input contract (pure worker)
43
+
44
+ Orchestrated, you are invoked as `--order <path>` (a WorkOrder): `payload.pitch` (the
45
+ kicked-off pitch path), `payload.stack` (sweep hint), and `substrate.allowed` naming your one
46
+ write surface — the orient output dir. Anything absent = unknown: confirm at GATE O-A
47
+ (standalone) or report it in the result's `deviations`, never guess. Standalone, the
48
+ `--pitch/--spec/--stack` flags below carry the same fields; the output dir derives from the
49
+ spec path (`.shapeup/<feat>/orient/`).
50
+
51
+ ## Output — the four artifacts (the `orient → ba` contract) + a WorkResult
52
+
53
+ All four land in the orient output dir (orchestrated: the order's substrate; standalone:
54
+ `.shapeup/<feat>/orient/`). These ARE the contract `ba` Phase 1 consumes, so `ba` does
55
+ not re-scan the codebase. Keep them factual and link real `file:line` so the planner can trust
56
+ them. When dispatched with an order, also write the WorkResult envelope
57
+ (`.shapeup/<feat>/results/<order-suffix>.json`, `work-result.schema.json`): `status`,
58
+ `artifacts[]` (the four paths), and any pitch-level gaps as `deviations[]`.
59
+
60
+ | File | Purpose | Consumed by |
61
+ |------|---------|-------------|
62
+ | `orient/code-surface.md` | where the pitch lands in real code: modules, files, existing entities, seams | `ba` Phase 1 (ingest), Phase 2 (DDD) |
63
+ | `orient/spike-<area>.md` | findings from de-risking the single riskiest area | `ba` Phase 1b / contracts; tech-lead L1a |
64
+ | `orient/discovered-seed.md` | imagined + already-discovered tasks, grouped by suspected scope | `ba` Phase 6 (task gen) |
65
+ | `orient/hill-signal.md` | per-area inventory of open unknowns (raw signal, not a report) | `tech-lead` GATE L1a hill render |
66
+
67
+ ---
68
+
69
+ ## Workflow
70
+
71
+ ```
72
+ INTAKE: kicked-off pitch (+ breadboard) + codebase + args(feature, spec, stack)
73
+
74
+ ⏸ GATE O-A │ Locate & validate ──► confirm pitch path, breadboard (if any), spec target, codebase root
75
+
76
+ Phase 1 │ Read the shape ──────► extract elements/places/slices to ground in code
77
+ Phase 2 │ Code-surface scan ───► map each element → real file:line / module / entity
78
+ │ → write orient/code-surface.md
79
+ Phase 3 │ Risk triage ─────────► rank areas by unknowns × integration risk; pick the ONE riskiest
80
+
81
+ ⏸ GATE O-B │ Spike scope ─────────► confirm the area + question + time-box before spiking
82
+ │ (no-risk path: declare SPIKE-NOT-NEEDED, skip Phase 4)
83
+
84
+ Phase 4 │ Spike ───────────────► time-boxed investigation in real code; answer the question
85
+ │ → write orient/spike-<area>.md (or spike-not-needed.md)
86
+ Phase 5 │ Seed discovered tasks ► imagined + discovered, grouped by suspected scope
87
+ │ → write orient/discovered-seed.md
88
+ Phase 6 │ Emit hill signal ────► per-area open-unknown inventory
89
+ │ → write orient/hill-signal.md
90
+ ✅ Done └─► 4 artifacts in .shapeup/<feat>/orient/ — hand back to tech-lead for GATE L1a
91
+ ```
92
+
93
+ Under `--auto` (passed by `tech-lead` when its run level is `--auto`/`--unattended`), run
94
+ straight through, auto-confirming O-A and O-B with sensible defaults.
95
+
96
+ ---
97
+
98
+ ## GATE O-A — Locate & validate
99
+
100
+ ```
101
+ Confirm (do not guess):
102
+ - kicked-off pitch path (shaping.md / pitch.md)
103
+ Shaped signal: frontmatter status: shaped AND bet: <S1|S2|...> (or equivalent).
104
+ If the pitch lacks appetite AND solution boundaries → STOP and tell tech-lead:
105
+ "Orient runs on a kicked-off pitch, not a raw idea. Shape/bet first (PO upstream)."
106
+ - breadboard.md path — read it if it exists; record "no breadboard" if absent
107
+ - spec folder target (create orient/ if absent)
108
+ - codebase root
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Phase 1 — Read the shape
114
+
115
+ Read the pitch and breadboard (if present). Extract the concrete things to find in code:
116
+
117
+ - **With breadboard**: the **places** and **affordances** (U[N]/N[N] IDs), **slices** (if B5
118
+ named them), named entities, third-party mentions.
119
+ - **No breadboard**: extract the pitch's *problem statement*, *solution shape* (the key
120
+ verbs/nouns), and any named entities or actions. These become your elements to ground.
121
+
122
+ You are listing *what to look for* — not solutions.
123
+
124
+ ## Phase 2 — Code-surface scan → `code-surface.md`
125
+
126
+ For each element, locate where it lands in the real codebase. Bias toward breadth over depth —
127
+ the goal is a reliable **map**, not a deep read.
128
+
129
+ ```
130
+ Useful sweeps (adapt to the stack arg):
131
+ find . -path "*/schema*" -o -path "*/domain*" # existing entities / aggregates
132
+ find . -path "*/repository*" -o -path "*/usecase*" # seams to extend
133
+ find . -path "*<feature-keyword>*" # prior art for this feature
134
+ grep -rn "<entity or affordance keyword>" <src dirs>
135
+ ```
136
+
137
+ Write `code-surface.md`: one row per pitch element → `file:line` it touches (or "NEW — no
138
+ existing home"), the seam it extends, and whether it's new vs. existing. Flag every place the
139
+ map is uncertain — uncertainty is signal for Phase 3, not something to hide.
140
+
141
+ > **Output location.** All four orient artifacts are run-trace (recon scratch), so they
142
+ > go to the **LOCAL** root `.shapeup/<feat>/orient/` (hidden, gitignorable) — *not*
143
+ > into the shared `--spec` dir. `<feat>` is the feature slug (parent of the `--spec`
144
+ > deliverable dir). The bare filenames below are all relative to `.shapeup/<feat>/orient/`.
145
+
146
+ ## Phase 3 — Risk triage
147
+
148
+ Rank candidate areas by **(open unknowns) × (integration risk)**. The riskiest is usually
149
+ where the pitch meets an unproven seam: a third-party API, a data-shape you can't confirm from
150
+ code, a cross-layer contract, a performance assumption. Pick the **single** highest — the
151
+ Scout spikes one thing well, not five things shallowly. List the rest as known unknowns (they
152
+ feed the hill signal and `ba`'s rabbit-hole handling).
153
+
154
+ ## GATE O-B — Spike scope
155
+
156
+ ```
157
+ No-spike path: if every area has confirmed prior art and no genuine unknown (Phase 3
158
+ returned rank 0 risk), declare SPIKE-NOT-NEEDED. Write orient/spike-not-needed.md
159
+ (one paragraph: why no spike is needed + what prior art covers the riskiest seam).
160
+ Then skip Phase 4 and proceed to Phase 5.
161
+
162
+ Spike path: if a risky area exists, confirm before spiking:
163
+ Area : [the one riskiest area]
164
+ Question : [the single question — phrased so the answer is checkable]
165
+ Time-box : [hard cap, e.g. 30–60 min of investigation]
166
+ Fallback : [what ba plans around if spike can't resolve it]
167
+ ```
168
+
169
+ ## Phase 4 — Spike → `spike-<area>.md`
170
+
171
+ Investigate in the **real code** — read the actual library/SDK, trace the actual data shape,
172
+ write a throwaway probe if needed. This is `shapeup /spike` technique, but build-time and
173
+ code-grounded rather than shaped-solution-time. Answer the question or declare it
174
+ `SPIKE-UNRESOLVED` with the fallback. Cite `file:line` and any external source. Stay inside
175
+ the time-box; a partial answer with a clear residual unknown is a valid result.
176
+
177
+ ## Phase 5 — Seed discovered tasks → `discovered-seed.md`
178
+
179
+ Write the task seed `ba` Phase 6 will turn into the board. Two kinds, clearly labelled:
180
+ - **Imagined** — what you'd expect from the pitch alone.
181
+ - **Discovered** — what the code-surface scan and spike actually surfaced (the higher-value
182
+ set; in Shape Up these dominate). **Every discovered task must cite `file:line` or seam.**
183
+ If you can't cite a real location, it belongs in Imagined, not Discovered.
184
+
185
+ Group by **suspected scope** so `ba` can map scopes naturally. Do **not** assign IDs, order,
186
+ or dependencies — that is the planner's job. You are handing over raw material, not a plan.
187
+
188
+ > This is the seed for the planner's first board. The *in-build* discovered-task loop
189
+ > (build WorkResults' discoveries[] ingested into the live ledger, reconciled by a planner
190
+ reconcile order) is
191
+ > a separate, later mechanism — don't conflate the two.
192
+
193
+ ## Phase 6 — Emit hill signal → `hill-signal.md`
194
+
195
+ For each suspected scope/area, list its **open unknowns** (unresolved spike question, `⏳ TBD`
196
+ data shape, unproven seam, ambiguous requirement). This is the raw input `tech-lead` renders
197
+ into the Hill at GATE L1a — a scope with open unknowns sits **uphill**; one whose approach the
198
+ spike proved sits toward the **crest**. Emit the *facts*; let `tech-lead` position the dots.
199
+ Keep it per-area (not per-slice) — slices don't exist until `ba` maps them at step 8.
200
+
201
+ ---
202
+
203
+ ## Done — completion output
204
+
205
+ When all four artifacts are written, emit this summary (to tech-lead or directly to the user
206
+ in standalone mode):
207
+
208
+ ```
209
+ ✅ Orient complete — .shapeup/<feat>/orient/
210
+
211
+ Artifacts:
212
+ code-surface.md — <N> pitch elements mapped; <M> NEW / <K> EXISTING seams
213
+ spike-<area>.md — [RESOLVED | SPIKE-NOT-NEEDED | SPIKE-UNRESOLVED: <fallback>]
214
+ discovered-seed.md — <N imagined> + <M discovered> tasks seeded across <K> scopes
215
+ hill-signal.md — <summary line from hill, e.g. "No uphill areas; spike at crest.">
216
+
217
+ Ready for ba (step 8):
218
+ Pass --orient-dir .shapeup/<feat>/orient/ to ba-pitch-analyzer.
219
+ ba Phase 1 skips its own codebase scan and reads code-surface.md as its authoritative map.
220
+ ```
221
+
222
+ Tech-lead uses this to render the GATE L1a Hill and confirm the spike before handing to `ba`.
223
+
224
+ ---
225
+
226
+ ## Hard rules
227
+
228
+ | Rule | Why |
229
+ |------|-----|
230
+ | Runs on a kicked-off (shaped + bet) pitch only | Shaping/betting are PO-personal, upstream of Orient |
231
+ | Writes the four artifacts, nothing else | The Scout is a pure worker; no code, no board, no run-state, no report |
232
+ | Spike exactly one area OR declare SPIKE-NOT-NEEDED | Depth on the scariest unknown beats shallow coverage; don't spike for its own sake |
233
+ | Every Discovered task in the seed cites `file:line` | If no real location exists, it belongs in Imagined, not Discovered |
234
+ | Never assign task IDs/order/deps in the seed | Mapping scopes is `ba`'s job (step 8) — the Scout hands over raw material |
235
+ | Receives `feature`/`spec`/`stack` as args; never touches run-state | `tech-lead` is the sole run-state writer |
236
+ | Emits hill *signal*, never a hill *report* | `tech-lead` renders progress; workers emit facts |
237
+
238
+ ---
239
+
240
+ ## Invocation
241
+
242
+ ```bash
243
+ # Invoked by tech-lead at step 7 (canonical) — compile-order --operation orient --slug <feat> …
244
+ /orient --order .shapeup/<feat>/orders/orient.json
245
+
246
+ # Standalone flags (the preamble shim compiles the same envelope)
247
+ /orient --pitch shapeup/<feat>/shaping/shaping.md --spec shapeup/<feat>/spec/ --stack "pnpm, Next 16 web :3000"
248
+
249
+ # Standalone recon (no orchestrator) — still writes only the four artifacts
250
+ /orient --pitch shapeup/<feat>/shaping/shaping.md --spec shapeup/<feat>/spec/
251
+
252
+ # Auto (tech-lead passes this under --auto/--unattended): run straight through
253
+ /orient --pitch ... --spec ... --auto
254
+ ```
255
+
256
+ ### Flags
257
+ | Flag | Effect |
258
+ |------|--------|
259
+ | `--pitch <path>` | The kicked-off pitch (+ sibling `breadboard.md` if present) |
260
+ | `--spec <path>` | SHARED spec deliverable dir (shapeup/<feat>/spec/); orient *artifacts* are written to the LOCAL root `.shapeup/<feat>/orient/` |
261
+ | `--stack <hint>` | Stack hint to aim the code-surface sweeps |
262
+ | `--auto` | Auto-confirm O-A and O-B; run straight through |
@@ -0,0 +1,369 @@
1
+ ---
2
+ name: qa-edge-hunter
3
+ description: "Use this skill for the post-PASS exploratory QA pass — Shape Up's \"QA is for the edges\", made explicit for the harness. Triggers on: \"hunt edge cases\", \"QA pass on this feature\", \"exploratory test the running app\", \"edge hunt before ship\", \"run qa-edge-hunter\", \"the evaluator passed — what did it miss?\". tech-lead invokes it after the run's first PASS at GATE L3, before SHIP; it also runs standalone given a spec folder, a PASS EVAL report, and a running app, or on a tech-lead --order dispatch. It charters edges OUTSIDE what the evaluator probed and hunts them through six fixed lenses. NOT for checking AC (spec-evaluator), deriving test cases (ba), or fixing bugs (task-executor)."
4
+ ---
5
+
6
+ # QA Edge Hunter — the post-PASS edge pass (v1.1)
7
+
8
+ Shape Up, Ch. 13: QA comes in **toward the end**, hunts **edge cases outside the core**,
9
+ and its issues are **nice-to-haves by default** that the team triages. This skill is that
10
+ role for the harness. It exists because the judge (`spec-evaluator`) is skeptical only
11
+ *within the spec it is handed* — absence of evidence is a FAIL, but absence of a *test
12
+ case* is invisible to it. The Hunter covers exactly that blind spot: behavior the spec
13
+ never wrote down.
14
+
15
+ ```
16
+ tech-lead: ... GATE L2 → EVAL → GATE L3 PASS ──► QA EDGE HUNT (you) ──► SHIP S.0 triage → L4
17
+ charters · hunts · ~ findings → ledger
18
+ GATE L3 FAIL → fix round (never reaches you — conformance first, edges after)
19
+ ```
20
+
21
+ **Division of labor (settled at the QA meeting, 2026-06-11):**
22
+
23
+ | Tier | Owner | When |
24
+ |---|---|---|
25
+ | Derivable tests (boundaries, error codes, no-go breaches the spec implies) | `ba` `## Test Surface` + evaluator `test-surface-conformance` | spec time / every EVAL |
26
+ | **Exploratory edges (this skill)** | `/qa-edge-hunter` | once, post-first-PASS |
27
+
28
+ ---
29
+
30
+ ## What the Hunter is and is not
31
+
32
+ | Does | Does NOT |
33
+ |------|----------|
34
+ | Read EVAL-*.md to map covered territory — then hunt OUTSIDE it | Re-probe anything the evaluator already graded |
35
+ | Charter edges via six fixed lenses, minus covered territory | Author or extend `## Test Surface` (that is the planner's retrofit-surface operation) |
36
+ | Execute charters on the **running app** (session-based exploratory) | Read-only speculate from code ("this looks racy") — every finding needs a live repro |
37
+ | Return each finding in the WorkResult's `discoveries[]`, **always `~`** | Promote `~` → must-have (PO/TL at SHIP S.0; severity-hint is advice, not a decision) |
38
+ | Emit `qa/hunt-report.md` — charters run/cut, findings by lens | Render a verdict, score, or PASS/FAIL of any kind |
39
+ | `--recheck`: re-probe ONLY items promoted+fixed after triage | Run a second full hunt in the same cycle; fix code; touch task files; keep run-state |
40
+
41
+ Pure worker (harness rule: stateless workers, one stateful orchestrator). Its WorkOrder
42
+ carries `payload.feature`, `payload.spec_folder`, `payload.eval_report`, `payload.app_url`,
43
+ `payload.kb_rules_path` (+ read-only ledger path for covered-territory context); its write surface is
44
+ `.shapeup/<feature>/qa/**` only. The Hunter never touches the discovery ledger itself —
45
+ ingest appends its `discoveries[]` under a `## Discovered` section, preserving single-writer
46
+ mechanically.
47
+
48
+ ---
49
+
50
+ ## Workflow
51
+
52
+ ```
53
+ ⏸ GATE Q0 │ Preflight ────► hard: app running? EVAL verdict PASS? ledger exists?
54
+ │ soft: Test Surface present? absent → DEGRADED MODE offer
55
+ Phase Q1 │ Charter Map ──► 6 lenses × UC tree − covered territory (EVAL-probed rows/AC)
56
+ ⏸ GATE Q1 │ Charter Review► PO/TL hammer the charter list (QA's own appetite is fixed too)
57
+ Phase Q2 │ Hunt ─────────► session per charter on the running app; findings → ledger LIVE
58
+ Phase Q3 │ Report ───────► qa/hunt-report.md — no score, no verdict
59
+ ```
60
+
61
+ ---
62
+
63
+ ## GATE Q0 — Preflight
64
+
65
+ ```
66
+ HARD (any miss → STOP, report which):
67
+ ✅ app reachable at the given URL (one real request, not a ping)
68
+ ✅ EVAL-FEATURE-<slug>.md exists with verdict: PASS
69
+ ✅ if discovery/ledger.md exists: ledger.feature == <feature> (read-only context check —
70
+ a missing ledger is fine; ingest creates it when your findings land)
71
+ SOFT:
72
+ ⚠️ any usecases/UC-*.md has `## Test Surface`?
73
+ NO → DEGRADED MODE:
74
+ "Test Surface absent — derivable cases (boundaries, error codes, no-go breaches)
75
+ were never systematically probed. Lenses ① and ⑤ will widen to compensate
76
+ (charters tagged [derivable-fallback]). Better: run
77
+ a ba-pitch-analyzer retrofit-surface order + one evaluator pass first, then hunt
78
+ with a narrower charter. Continue degraded? [y/n]"
79
+ Degraded is first-class, not an error — for old specs, a degraded hunt beats no hunt.
80
+ Questions: max 2. The standing one: "Any areas OUT OF BOUNDS for exploratory testing?
81
+ (e.g. real payments, real emails, production data)" — out-of-bounds areas are excluded
82
+ from charters and listed in the report, never silently skipped.
83
+ ```
84
+
85
+ **Output:**
86
+ ```
87
+ ⏸ GATE Q0 — Preflight
88
+ App : [url] ✅ reachable
89
+ EVAL : EVAL-FEATURE-[slug].md — PASS (dims: [...])
90
+ Ledger : [✅ feature match | absent — ingest will create it]
91
+ Surface : [present | ABSENT → degraded mode]
92
+ Out-of-bounds? (max 2 questions) …
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Phase Q1 — Charter Map
98
+
99
+ A **charter** is a hunting ground + a mission — NOT a test case (test cases are the
100
+ derivable tier; writing them here would re-do `ba`'s job badly). Generate charters by
101
+ crossing the UC tree with the **six fixed lenses**, then subtract covered territory.
102
+
103
+ | Lens | Mission | Typical prey |
104
+ |---|---|---|
105
+ | ① Boundary overflow | Inputs the contract never bounded | very long strings, unicode/emoji, 0/negative where unstated, paste-bombs, huge files |
106
+ | ② Concurrency | Same action, twice, at once | double-submit, two tabs editing one aggregate, rapid re-click on mutation CTAs |
107
+ | ③ State interruption | Break the flow mid-stride | refresh mid-wizard, back button after submit, session expiry mid-form, network drop on save |
108
+ | ④ Cross-UC journey | Chain UCs end-to-end | create→edit→delete→recreate same entity; output of UC-A as adversarial input to UC-B |
109
+ | ⑤ No-go probing | Is the excluded path truly absent? | direct URLs, API calls bypassing the UI, role escalation to no-go'd features |
110
+ | ⑥ Data residue | What survives that shouldn't? | deleted data via old links/exports, prior-session state bleeding, cache after logout |
111
+
112
+ The six lenses are **fixed** (simplicity as a hard constraint) — scoping happens by
113
+ cutting charters at GATE Q1, not by configuring lenses.
114
+
115
+ **Charter quality** — before generating, internalize the target altitude:
116
+ - Good: "What happens to the order record if the user refreshes the page after clicking
117
+ Confirm but before the server responds?" → one specific risk, concrete mission,
118
+ achievable in one session, requires a running app to test.
119
+ - Too broad: "Test the checkout flow" → maps 1:1 with a UC; that is the evaluator's job.
120
+ - Too narrow: "Verify the Confirm button is disabled after click" → this is a derivable
121
+ test case; it belongs in `## Test Surface`, not a charter.
122
+ A charter is a license to deviate within a hunting ground; a test case is a script.
123
+
124
+ ```
125
+ Q1.0 Read team guidelines: the file at `payload.kb_rules_path` (if present; absent field = none).
126
+ `/coach`-distilled edge classes that kept biting past features (e.g. "session-expiry
127
+ mid-form keeps surfacing"). Use them to PRIORITIZE charters within the six fixed lenses —
128
+ never to add a seventh lens or skip covered-territory subtraction. Absent = none recorded.
129
+ Q1.1 Parse EVAL-*.md → covered set: every TS row probed (test-surface-conformance
130
+ section) + every AC/Done-when graded (spec-conformance section).
131
+ Q1.2 Per UC × lens: draft a charter ONLY where the covered set leaves territory.
132
+ Lens ⑤ vs Test Surface D4: TS-NOGO rows probe the no-go AS SPECIFIED; the charter
133
+ hunts UNSPECIFIED breach routes (other URLs, API bypass, role tricks) — overlap
134
+ with a probed row = drop the charter.
135
+ Q1.3 Degraded mode: add [derivable-fallback] charters for the uncovered derivable tier
136
+ (lens ① boundary basics; lens ⑤ no-go-as-specified) — tagged so GATE Q1 sees
137
+ exactly which bulk is owed to the missing surface.
138
+ Q1.4 Drop charters touching Q0 out-of-bounds areas; list them in the report as
139
+ "excluded (out of bounds)".
140
+ Q1.5 Time-box each charter (default 1 session unit ≈ one focused pass; a charter that
141
+ wants more must say why).
142
+ ```
143
+
144
+ ---
145
+
146
+ ## ⏸ GATE Q1 — Charter Review
147
+
148
+ The scope hammer applied to QA itself — the Hunter's appetite is as fixed as everyone
149
+ else's.
150
+
151
+ ```
152
+ ⏸ GATE Q1 — Charter Review [DEGRADED MODE] ← shown only when degraded
153
+ Charters: [N] ([D] derivable-fallback) · est: [N] session units
154
+ C-01 [①boundary] UC-04 amount field beyond contract silence …
155
+ C-02 [②concurr] UC-04 double-submit Confirm …
156
+ C-03 [⑤no-go] export via unauthenticated direct URL … [derivable-fallback]
157
+
158
+ Excluded (out of bounds): [list from Q0]
159
+ Question (max 1): "Cut or add any charters? (ids / add <desc> / none)"
160
+ ```
161
+
162
+ Cut charters appear in the report under "Hammered out (not hunted)" — visible cuts, never
163
+ silent ones.
164
+
165
+ ---
166
+
167
+ ## Phase Q2 — Hunt
168
+
169
+ Session-based exploratory testing per approved charter, on the running app.
170
+
171
+ ```
172
+ Per charter:
173
+ H.1 Execute the mission within its time box. Vary, provoke, chain — follow the scent;
174
+ a charter is a license to deviate INSIDE its ground, not a script.
175
+ H.2 Suspected finding → reproduce it (≥1 clean repro) before recording. No repro →
176
+ log in session notes as "unconfirmed observation", NOT a finding.
177
+ H.3 Confirmed → record it IMMEDIATELY (in the growing WorkResult, not batched to the end
178
+ of the hunt — a crashed session must not lose confirmed findings):
179
+
180
+ { "marker": "~",
181
+ "lens": "②concurrency",
182
+ "line": "[QA-NNN] [UC-04] Double-click \"Confirm\" creates 2 orders",
183
+ "repro": "<numbered steps, shortest path>",
184
+ "severity_hint": "data-integrity | boundary-breach | ux-degradation | cosmetic",
185
+ "test_gap": "unit | integration | exploratory-only" }
186
+
187
+ Always `~` — ingest appends these to the discovery ledger verbatim; you never open
188
+ the ledger file. severity_hint is the Hunter's advice to triage — the promotion
189
+ decision is PO/TL's at SHIP S.0, never made here.
190
+ test_gap is advisory for reconciliation: unit = a targeted unit test would have
191
+ caught this; integration = a cross-layer test would; exploratory-only = only
192
+ discoverable through live session dynamics.
193
+ H.4 A finding that contradicts a PASSED criterion (the evaluator graded it PASS, the
194
+ hunt shows otherwise) → set `"contradicts": "<EVAL criterion id>"` on the entry.
195
+ Do NOT edit EVAL-*.md or un-tick anything — the judge's record is the judge's; the
196
+ contradiction flag routes it back through triage.
197
+ H.5 Time box expires mid-scent → stop, note "charter exhausted time with open scent"
198
+ in the report. The circuit breaker applies to hunting too.
199
+ ```
200
+
201
+ ### Lens-specific hunting techniques
202
+
203
+ Use these as your toolbox when executing a charter. The goal is to provoke the app
204
+ in ways a spec author wouldn't think to write down.
205
+
206
+ **① Boundary overflow** — things the contract never bounded
207
+ - Strings: paste 10 KB of text, emoji sequences (🏳️‍🌈 multi-codepoint), RTL Unicode (؀؁),
208
+ null bytes (`\x00` via DevTools console injection), leading/trailing whitespace
209
+ - Numbers: try -1, 0, 2147483647 (MAX_INT), 2147483648 (MAX_INT+1), floats where
210
+ integers are expected, strings that look like numbers ("1e9", "Infinity")
211
+ - Files: 0-byte file, file with wrong extension but correct MIME type, size exactly at
212
+ the stated limit and size+1 byte above it
213
+ - API: send the field missing entirely vs. `null` vs. `""` — three different cases even
214
+ if the UI treats them the same
215
+
216
+ **② Concurrency** — same action, twice, at once
217
+ - Open two tabs or two browsers sharing the same session; navigate both to the same
218
+ mutation form; submit within milliseconds of each other
219
+ - Rapid double-click on a mutation CTA: check DevTools → Network for duplicate POSTs
220
+ - Optimistic UI: click Save, navigate away immediately before the response arrives;
221
+ return — was state lost, duplicated, or correctly reconciled?
222
+ - Two different roles editing the same aggregate simultaneously — last-write-wins vs.
223
+ conflict detection
224
+
225
+ **③ State interruption** — break the flow mid-stride
226
+ - Browser Back after submitting step N of a multi-step wizard; then Forward again —
227
+ is unsaved state preserved, lost, or doubled?
228
+ - Refresh immediately after clicking Submit (before the response) — race between
229
+ browser reload and server confirmation
230
+ - Network drop mid-save: DevTools → Network → Offline → toggle back; does the app
231
+ retry, error gracefully, or show stale data?
232
+ - Session expiry mid-form: delete the session cookie (DevTools → Application →
233
+ Cookies → Delete) then attempt to submit — graceful redirect or silent failure?
234
+ - Tab sleep: leave the tab idle for 10–15 minutes, return, and try a mutation
235
+
236
+ **④ Cross-UC journey** — chain UCs end-to-end
237
+ - Create → Edit → Delete → Re-create the same entity with the same name/ID — does
238
+ the second Create fail with an ID collision, ghost the deleted record, or succeed?
239
+ - Use the output of UC-A as adversarial input to UC-B: if UC-A allows a 500-char name,
240
+ does UC-B's display truncate, wrap, or break layout?
241
+ - Partial completion of UC-A → switch to UC-B → return to UC-A — is the partial state
242
+ saved, cleared, or corrupted?
243
+
244
+ **⑤ No-go probing** — is the excluded path truly absent?
245
+ - Direct URL: type a protected route into the address bar while unauthenticated or as a
246
+ lower-privilege role
247
+ - API replay: in DevTools → Network, copy a privileged request as cURL, strip the auth
248
+ cookie, replay — does the server reject it?
249
+ - DOM enable: find a disabled/hidden UI element, `element.disabled = false` or
250
+ `element.style.display = 'block'` in the console, submit — does the server validate
251
+ server-side?
252
+ - Path traversal in URL params (`../`, `%2F..`) for file/export endpoints
253
+
254
+ **⑥ Data residue** — what survives that shouldn't?
255
+ - Delete an entity, then navigate to its detail URL via browser history — 404, redirect,
256
+ or stale cached data?
257
+ - Log out, log back in (same browser, same session storage) — does the new session show
258
+ any leftover state from the prior session?
259
+ - DevTools → Application → Cache Storage / Local Storage / IndexedDB after logout —
260
+ is sensitive data cleared?
261
+ - Re-download a previously generated export URL after the source data was deleted —
262
+ does the export still serve the old data?
263
+
264
+ ---
265
+
266
+ ## Phase Q3 — Report + WorkResult
267
+
268
+ Write `.shapeup/<feature>/qa/hunt-report.md` (your substrate) and, when dispatched with
269
+ an order, the WorkResult envelope `.shapeup/<feature>/results/<order-suffix>.json`:
270
+ `status: done`, `discoveries[]` (every confirmed finding from H.3), `artifacts:
271
+ ["qa/hunt-report.md"]`. The report:
272
+
273
+ ```markdown
274
+ # Hunt Report — [feature] (round [r], [date])
275
+ mode: [full | degraded | recheck]
276
+ charters: [run]/[approved] · session units spent: [n]
277
+ out of bounds (excluded): […]
278
+ hammered out at GATE Q1 (not hunted): […]
279
+
280
+ ## Findings by lens
281
+ | Lens | Hunted | Findings | Of which contradicts-EVAL |
282
+ |---|---|---|---|
283
+ | ① Boundary | C-01, C-05 | 2 | 0 |
284
+ | … | | | |
285
+ → details live in .shapeup/<feature>/discovery/ledger.md ## QA Edge Findings (round [r])
286
+
287
+ ## Shaping-quality signal (advisory, for the PO — next cycle's input)
288
+ - lens ⑤ findings ≈ No-gos written loosely (breach routes left open)
289
+ - lens ④ findings ≈ UC decomposition cut too disjointly (journeys fall in the seams)
290
+ - lens ① in degraded mode ≈ owed to the missing Test Surface, not to shaping
291
+
292
+ ## Session notes
293
+ [per charter: what was tried, unconfirmed observations, open scents]
294
+ ```
295
+
296
+ No verdict line exists in this file by design. The Hunter's last words:
297
+ `✅ hunt complete — [N] findings (all ~) → ledger · triage at SHIP S.0 / GATE L4.`
298
+
299
+ ---
300
+
301
+ ## `--recheck` mode (after triage promoted + fixed items)
302
+
303
+ ```
304
+ Input: the promoted finding ids (from tech-lead) + the fix round's PASS EVAL report.
305
+ Q0 : hard checks only (app up, new EVAL PASS); no soft check, no charter map.
306
+ Hunt : re-run EXACTLY the recorded repro of each promoted finding — nothing else.
307
+ fixed → discoveries[] entry `{ "marker": "~", "line": "[QA-NNN] ✦ fixed r[N], verified" }`
308
+ (ingest annotates the ledger — annotate, never delete; the ledger is history)
309
+ not fixed → `{ "marker": "~", "line": "[QA-NNN] ✦ NOT fixed r[N]", "repro": "<fresh evidence>" }`
310
+ back to triage.
311
+ Report: append a `## Recheck (round [r])` section to .shapeup/<feature>/qa/hunt-report.md.
312
+ NEVER a second full hunt in the same cycle — new edges found while rechecking are
313
+ recorded `~` like any finding and wait for triage; they don't restart the loop.
314
+ ```
315
+
316
+ ---
317
+
318
+ ## Invocation
319
+
320
+ ```bash
321
+ # Orchestrated (how tech-lead calls it after first PASS) — the canonical form:
322
+ # compile-order --operation hunt --slug checkout-vnpay --worker qa-edge-hunter \
323
+ # --payload '{"eval_report": "…/EVAL-FEATURE-checkout-vnpay.md", "app_url": "http://localhost:3000"}'
324
+ /qa-edge-hunter --order .shapeup/checkout-vnpay/orders/hunt.json
325
+
326
+ # Standalone flags (the preamble shim compiles the same envelope)
327
+ /qa-edge-hunter --feature checkout-vnpay --spec shapeup/checkout-vnpay/spec/ \
328
+ --eval .shapeup/checkout-vnpay/evaluation/EVAL-FEATURE-checkout-vnpay.md \
329
+ --ledger .shapeup/checkout-vnpay/discovery/ledger.md --app http://localhost:3000
330
+
331
+ # Standalone (same arguments, human-invoked)
332
+ /qa-edge-hunter --feature checkout-vnpay --spec shapeup/checkout-vnpay/spec/ --app http://localhost:3000
333
+ # (--eval/--ledger default to the conventional paths under the LOCAL root .shapeup/<feature>/)
334
+
335
+ # Recheck after triage promoted + fixed findings
336
+ /qa-edge-hunter --recheck QA-001,QA-004 --feature checkout-vnpay --spec ... --app ...
337
+
338
+ # Escape hatches
339
+ --auto # skip GATE Q1 pause (charter list logged, not reviewed) — Q0 hard
340
+ # checks and the out-of-bounds question are NEVER skipped
341
+ --lenses-note # there is deliberately NO --lenses flag: the 6 lenses are fixed;
342
+ # narrow by cutting charters at GATE Q1 (or --auto + report)
343
+ ```
344
+
345
+ ### Progress Markers
346
+ ```
347
+ ⏸ GATE Q0 Preflight (hard + soft checks, out-of-bounds question)
348
+ ▶ Phase Q1 Charter Map ⏸ GATE Q1 Charter Review
349
+ ▶ Phase Q2 Hunt — C-01 ✅ C-02 🔍 … (findings stream to ledger live)
350
+ ▶ Phase Q3 Report
351
+ ✅ hunt complete — [N] findings (all ~) → ledger · triage at SHIP S.0 / GATE L4
352
+ ```
353
+
354
+ ---
355
+
356
+ ## Hard rules (the never-list)
357
+
358
+ 1. **Never a verdict.** The run's verdict is the evaluator's PASS. One judge.
359
+ 2. **Never promote.** Every finding is born `~`. severity-hint advises; PO/TL decide.
360
+ 3. **Never fix.** Read-only on code; execute-only on the app; write-only to
361
+ qa/hunt-report.md + its own WorkResult (findings return as data; ingest owns the ledger).
362
+ 4. **Never block ship.** A hunt with 40 findings and a hunt with 0 both end the same way:
363
+ report, then triage at L4. The circuit breaker outranks the Hunter.
364
+ 5. **Never re-probe covered territory.** EVAL-*.md territory is subtracted at Q1; an
365
+ exception requires a `contradicts:` suspicion arising mid-hunt, not curiosity.
366
+ 6. **Never run on FAIL.** Conformance first; edges after.
367
+ 7. **Never invent severity from code reading.** Every finding has a live repro on the
368
+ running app.
369
+ 8. **Never gate on Test Surface.** Its absence degrades the hunt; it never blocks it.