shapeup-sdlc 1.6.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/.claude/settings.local.example.json +5 -5
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/AGENTS.md +54 -107
  4. package/README.md +165 -151
  5. package/SECURITY.md +49 -27
  6. package/bin/init.mjs +93 -108
  7. package/bin/lib/grant.mjs +145 -0
  8. package/commands/build.md +20 -0
  9. package/commands/eval.md +5 -4
  10. package/commands/scopes.md +5 -4
  11. package/commands/shape.md +1 -1
  12. package/commands/ship.md +53 -7
  13. package/commands/wire.md +1 -1
  14. package/hooks/dispatch-receipt.mjs +195 -0
  15. package/hooks/gate-intake.mjs +16 -17
  16. package/hooks/gate-zerowork.mjs +107 -25
  17. package/hooks/hooks.json +9 -48
  18. package/hooks/lib/decision.mjs +38 -19
  19. package/hooks/safety-spine.mjs +4 -4
  20. package/hooks/sandbox-guard.mjs +130 -50
  21. package/{skills/tech-lead/scripts/compile-order.mjs → kernel/compile.mjs} +344 -55
  22. package/{skills/tech-lead/scripts/gate-answers.mjs → kernel/gate.mjs} +69 -26
  23. package/kernel/harness.mjs +134 -0
  24. package/{skills/tech-lead/scripts/fit-check.mjs → kernel/init/fit.mjs} +25 -22
  25. package/kernel/init/run.mjs +489 -0
  26. package/{skills/tech-lead/scripts → kernel}/lib/argv.mjs +52 -31
  27. package/{skills/tech-lead/scripts/lib/contract-md.mjs → kernel/lib/contract.mjs} +261 -17
  28. package/kernel/lib/paths.mjs +491 -0
  29. package/kernel/probe/concurrency.mjs +510 -0
  30. package/{skills/tech-lead/scripts/aegis-digest.mjs → kernel/probe/digest.mjs} +10 -11
  31. package/kernel/probe/eval.mjs +77 -0
  32. package/kernel/probe/leg.mjs +125 -0
  33. package/kernel/probe/resume.mjs +528 -0
  34. package/{skills/tech-lead/scripts → kernel/probe}/stats.mjs +102 -21
  35. package/kernel/probe/t0.mjs +66 -0
  36. package/{skills/ba-pitch-analyzer/scripts/board-derive.mjs → kernel/reduce/board.mjs} +104 -28
  37. package/kernel/reduce/graph.mjs +437 -0
  38. package/kernel/reduce/hill.mjs +152 -0
  39. package/kernel/reduce/ingest.mjs +633 -0
  40. package/{hooks/slop-cleaner.mjs → kernel/reduce/leftovers.mjs} +40 -57
  41. package/{skills/tech-lead/scripts/ship-report.mjs → kernel/reduce/ship.mjs} +93 -14
  42. package/{skills/tech-lead/scripts/run-snapshot.mjs → kernel/reduce/snapshot.mjs} +22 -21
  43. package/{skills/spec-evaluator/scripts/verdict-ledger.mjs → kernel/reduce/verdict.mjs} +14 -8
  44. package/kernel/report/export.mjs +325 -0
  45. package/kernel/report/facts.mjs +347 -0
  46. package/{skills/tech-lead/scripts/budget-check.mjs → kernel/verify/budget.mjs} +22 -25
  47. package/kernel/verify/dispatch.mjs +114 -0
  48. package/{skills/tech-lead/scripts/validate-envelope.mjs → kernel/verify/envelope.mjs} +20 -15
  49. package/{skills/tech-lead/scripts/lib → kernel/verify}/ratchet-tree.mjs +36 -14
  50. package/kernel/verify/skills.mjs +125 -0
  51. package/kernel/verify/spec.mjs +559 -0
  52. package/{skills/tech-lead/scripts/t0-verify.mjs → kernel/verify/t0.mjs} +138 -28
  53. package/{skills/tech-lead/scripts/trace-lint.mjs → kernel/verify/trace.mjs} +28 -13
  54. package/oracles/_shared.mjs +1 -1
  55. package/oracles/http-oracle.mjs +2 -2
  56. package/oracles/index.mjs +1 -1
  57. package/oracles/process-oracle.mjs +2 -2
  58. package/oracles/snapshot-oracle.mjs +2 -2
  59. package/oracles/test-oracle.mjs +2 -2
  60. package/package.json +11 -13
  61. package/skills/ba-pitch-analyzer/SKILL.md +24 -19
  62. package/skills/ba-pitch-analyzer/assets/templates/_index.tmpl.md +1 -1
  63. package/skills/ba-pitch-analyzer/assets/templates/api-feasibility.tmpl.md +12 -7
  64. package/skills/ba-pitch-analyzer/assets/templates/contracts/third-party-api.contract.tmpl.md +6 -3
  65. package/skills/ba-pitch-analyzer/assets/templates/cross-context/migration-plan.tmpl.md +5 -4
  66. package/skills/ba-pitch-analyzer/assets/templates/cross-context/team-handoff.tmpl.md +23 -13
  67. package/skills/ba-pitch-analyzer/assets/templates/scope-summary.tmpl.md +17 -12
  68. package/skills/ba-pitch-analyzer/assets/templates/synthesis.tmpl.md +17 -38
  69. package/skills/ba-pitch-analyzer/assets/templates/task.tmpl.md +3 -0
  70. package/skills/ba-pitch-analyzer/references/contract-patterns.md +8 -4
  71. package/skills/ba-pitch-analyzer/references/doc-schemas.md +3 -1
  72. package/skills/ba-pitch-analyzer/references/task-generation.md +8 -8
  73. package/skills/ba-pitch-analyzer/references/test-surface.md +1 -1
  74. package/skills/coach/SKILL.md +3 -3
  75. package/skills/orient/SKILL.md +2 -1
  76. package/skills/qa-edge-hunter/SKILL.md +15 -41
  77. package/skills/scope-architect/SKILL.md +57 -18
  78. package/skills/scope-hammer/SKILL.md +5 -5
  79. package/skills/shapeup/SKILL.md +3 -3
  80. package/skills/shapeup/resources/context-compaction.md +4 -3
  81. package/skills/solution-architect/SKILL.md +37 -15
  82. package/skills/spec-evaluator/SKILL.md +24 -7
  83. package/skills/spec-evaluator/references/dimensions/_registry.md +2 -2
  84. package/skills/spec-evaluator/references/dimensions/completeness.md +1 -1
  85. package/skills/spec-evaluator/references/dimensions/integration.md +98 -67
  86. package/skills/spec-evaluator/references/dimensions/spec-conformance.md +4 -4
  87. package/skills/spec-evaluator/references/dimensions/test-surface-conformance.md +1 -1
  88. package/skills/spec-evaluator/references/probing.md +42 -23
  89. package/skills/spec-evaluator/references/report-schema.md +2 -2
  90. package/skills/task-executor/SKILL.md +32 -18
  91. package/skills/tech-lead/SKILL.md +127 -438
  92. package/skills/tech-lead/references/gates.md +140 -49
  93. package/skills/tech-lead/references/protocol.md +832 -0
  94. package/skills/tech-lead/schemas/domain.schema.json +645 -198
  95. package/skills/tech-lead/schemas/gate-answers.schema.json +2 -2
  96. package/skills/tech-lead/schemas/work-order.schema.json +11 -2
  97. package/skills/tech-lead/schemas/work-result.schema.json +56 -18
  98. package/skills/tech-lead/workflows/shapeup-run.js +1474 -0
  99. package/skills/translator/SKILL.md +2 -2
  100. package/hooks/anti-rationalization.mjs +0 -244
  101. package/hooks/compact-snapshot.mjs +0 -47
  102. package/hooks/gate-deadline.mjs +0 -151
  103. package/hooks/gate-l2.mjs +0 -161
  104. package/hooks/session-rehydrate.mjs +0 -109
  105. package/skills/advisor-protocol/SKILL.md +0 -171
  106. package/skills/ba-pitch-analyzer/scripts/spec-lint.mjs +0 -239
  107. package/skills/spec-evaluator/README.md +0 -93
  108. package/skills/tech-lead/README.md +0 -71
  109. package/skills/tech-lead/references/delegation.md +0 -254
  110. package/skills/tech-lead/references/invocation.md +0 -45
  111. package/skills/tech-lead/references/ledger-schema.md +0 -214
  112. package/skills/tech-lead/references/round-protocol.md +0 -184
  113. package/skills/tech-lead/references/state-model.md +0 -66
  114. package/skills/tech-lead/scripts/ingest-result.mjs +0 -270
  115. package/skills/tech-lead/scripts/init-run.mjs +0 -326
  116. package/skills/tech-lead/scripts/lib/is-main.mjs +0 -82
  117. package/skills/tech-lead/scripts/lib/paths.mjs +0 -278
  118. package/skills/translator/README.md +0 -66
@@ -14,9 +14,12 @@ dependent implementation tasks can proceed.*
14
14
 
15
15
  ## Detected Third-Party Dependencies
16
16
 
17
- | # | Service | Capability Claimed | Status | SPIKE Task |
18
- |---|---------|-------------------|--------|------------|
19
- | API-01 | [ServiceName] | [What pitch claims this API can do] | ❓ UNVERIFIED | [[TASK-001-spike-[api]]] |
17
+ | # | Service | Capability Claimed | Status | Spike |
18
+ |---|---------|-------------------|--------|-------|
19
+ | API-01 | [ServiceName] | [What pitch claims this API can do] | ❓ UNVERIFIED | open |
20
+
21
+ <!-- The Spike column records STATUS (⏳ open / ✅ done / — none), never a task id.
22
+ This document is committed; the board is not, and its ids renumber per machine. -->
20
23
 
21
24
  ---
22
25
 
@@ -49,10 +52,12 @@ Specifically: [quote or paraphrase relevant pitch sentence].
49
52
  | Partially supported | [Describe workaround] | +[N]h |
50
53
  | Not supported | [Describe alternative or de-scope] | [TBD with PO] |
51
54
 
52
- **Dependent Tasks:**
53
- <!-- List all tasks blocked until this investigation is complete -->
54
- - [[TASK-NNN]] [reason blocked]
55
- - [[TASK-NNN]] [reason blocked]
55
+ **Blocked Use Cases:**
56
+ <!-- What cannot be built until this investigation resolves. Name the committed UC, never
57
+ a task id: this doc is committed and task ids are machine-local. The tasks are found
58
+ by inverting use_case_refs over the LOCAL board. -->
59
+ - [[usecases/UC-Name]] — [reason blocked]
60
+ - [[usecases/UC-Name]] — [reason blocked]
56
61
 
57
62
  **Decision Gate:**
58
63
  - All questions answered + capability confirmed → update `contracts/[repo].contract.md`, remove ⏳ TBD fields, notify SPIKE complete
@@ -5,7 +5,9 @@ feature: "[feature-slug]"
5
5
  repository: "[RepoName]"
6
6
  service: "[ServiceName]"
7
7
  feasibility_ref: "API-[NN]"
8
- spike_task: "[[TASK-NNN-spike-[api]]]"
8
+ spike_status: open # open | done — STATUS, never a task id: this contract is
9
+ # committed and board ids renumber per machine. The spike is
10
+ # reached through feasibility_ref above.
9
11
  status: speculative # → confirmed after SPIKE done
10
12
  skill_version: "2.3"
11
13
  ---
@@ -14,13 +16,14 @@ skill_version: "2.3"
14
16
 
15
17
  ## Source Type: `third-party-api`
16
18
  ## Service: [ServiceName] ([REST API / SDK])
17
- ## Feasibility: ⏳ UNVERIFIED → see [[api-feasibility#API-NN]] + [[TASK-NNN-spike-[api]]]
19
+ ## Feasibility: ⏳ UNVERIFIED → see [[api-feasibility#API-NN]]
18
20
 
19
21
  ---
20
22
 
21
23
  > ⚠️ **SPECULATIVE CONTRACT**
22
24
  > Fields marked `⏳ TBD` are derived from pitch assumptions and community references.
23
- > All `⏳ TBD` entries MUST be confirmed and replaced during [[TASK-NNN-spike-[api]]].
25
+ > All `⏳ TBD` entries MUST be confirmed and replaced by the spike tracked at
26
+ > [[api-feasibility#API-NN]].
24
27
  > Implementation tasks depending on this repository are **blocked** until no `⏳ TBD` remains.
25
28
 
26
29
  ---
@@ -13,7 +13,8 @@ status: draft
13
13
  # Migration Plan: FEATURE TITLE
14
14
 
15
15
  > Generated only when feature modifies existing production schema.
16
- > Each migration task maps to a TASK-M0N in tasks/_index.md.
16
+ > Each migration step anchors to a committed use case; the tasks that carry it are found
17
+ > by inverting `use_case_refs` over the LOCAL board, never linked from here.
17
18
 
18
19
  ---
19
20
 
@@ -31,7 +32,7 @@ status: draft
31
32
 
32
33
  ## Migration Tasks
33
34
 
34
- ### TASK-M01 — [description, e.g. Add nullable columns]
35
+ ### STEP-1 — [description, e.g. Add nullable columns]
35
36
 
36
37
  ```sql
37
38
  -- UP
@@ -46,7 +47,7 @@ Safe to run: during deploy / after deploy / off-hours only
46
47
 
47
48
  ---
48
49
 
49
- ### TASK-M02 — [description, e.g. Backfill existing rows]
50
+ ### STEP-2 — [description, e.g. Backfill existing rows]
50
51
 
51
52
  ```sql
52
53
  -- UP (run in batches of 1000 to avoid lock escalation)
@@ -66,7 +67,7 @@ Estimated rows: ~N | Estimated time: ~Ns | Lock: none
66
67
 
67
68
  ---
68
69
 
69
- ### TASK-M03 — [description, e.g. Enforce NOT NULL constraint]
70
+ ### STEP-3 — [description, e.g. Enforce NOT NULL constraint]
70
71
 
71
72
  ```sql
72
73
  -- UP — only run after M02 verified
@@ -21,19 +21,29 @@ status: draft
21
21
 
22
22
  | From Team | To Team | Artifact | Ready When | Blocker Risk |
23
23
  |-----------|---------|----------|-----------|-------------|
24
- | [Team A] (API) | [Team B] (Mobile) | [[contracts/[repo].contract.md]] | TASK-00N done | 🔴 blocks Mobile TASK-00N |
25
- | [Team B] (API) | [Team A] (API) | `EventName` schema | TASK-00N done | 🟡 blocks integration test |
26
- | [Team B] (Mobile) | QA | E2E test cases | TASK-00N done | 🟡 blocks QA sprint entry |
24
+ | [Team A] (API) | [Team B] (Mobile) | [[contracts/[repo].contract.md]] | [[usecases/UC-Name]] green | 🔴 blocks Mobile [[usecases/UC-Name]] |
25
+ | [Team B] (API) | [Team A] (API) | `EventName` schema | [[usecases/UC-Name]] green | 🟡 blocks integration test |
26
+ | [Team B] (Mobile) | QA | E2E test cases | [[usecases/UC-Name]] green | 🟡 blocks QA sprint entry |
27
+
28
+ <!-- Readiness is stated against a committed UC (or a scope_id), never a task id: this
29
+ register is committed and shared across teams, and board ids are per-machine. -->
27
30
 
28
31
  ---
29
32
 
30
33
  ## Blocking Dependencies
31
34
 
35
+ <!--
36
+ Key every row on a USE CASE or a scope_id, never a task id. This document is committed and
37
+ crosses a team boundary; board ids live in the gitignored tier and each team's board numbers
38
+ its own, so one board id names a different piece of work on every machine that reads this.
39
+ spec-lint reds a board id anywhere in the committed tree (TIER-DIRECTION).
40
+ -->
41
+
32
42
  ```
33
- [Team B] CANNOT start TASK-00N ([description])
34
- until [Team A] completes TASK-00N ([description])
43
+ [Team B] CANNOT start [UC-x] ([description])
44
+ until [Team A] completes [UC-y] ([description])
35
45
  Mitigation: use contract stub from [[contracts/[repo].contract.md]]
36
- Stub ready: TASK-00N (unblocked — no dependency)
46
+ Ready now: [UC-z] (unblocked — no dependency)
37
47
 
38
48
  [Team C] CANNOT start integration tests
39
49
  until [Team A] EventName schema is stable
@@ -46,12 +56,12 @@ status: draft
46
56
 
47
57
  ```
48
58
  Wave 1 — No cross-team dependencies (start immediately):
49
- [Team A]: TASK-001, TASK-002, TASK-003
50
- [Team B]: TASK-004, TASK-005 (using contract stub)
59
+ [Team A]: [UC-a], [UC-b], [UC-c]
60
+ [Team B]: [UC-d], [UC-e] (using contract stub)
51
61
 
52
- Wave 2 — After Team A TASK-003 done:
53
- [Team B]: TASK-006 (replace stub with real contract)
54
- [Team C]: TASK-007 (integration tests real contract available)
62
+ Wave 2 — After Team A [UC-c] done:
63
+ [Team B]: [UC-f] (replace stub with real contract)
64
+ [Team C]: integration tests (real contract available)
55
65
 
56
66
  Wave 3 — After Wave 2 complete:
57
67
  QA: E2E test suite
@@ -64,7 +74,7 @@ Wave 3 — After Wave 2 complete:
64
74
  | Trigger | Owner | Notify | Channel |
65
75
  |---------|-------|--------|---------|
66
76
  | Contract changes after stub distributed | [Team A] | [Team B], QA | [channel] |
67
- | TASK-00N delayed > 1 day | [Team A] | [Team B] | [channel] |
77
+ | A wave-1 use case delayed > 1 day | [Team A] | [Team B] | [channel] |
68
78
  | Schema breaking change detected | Any | All teams | [channel] |
69
79
 
70
80
  ---
@@ -72,7 +82,7 @@ Wave 3 — After Wave 2 complete:
72
82
  ## Definition of Done (Cross-Context)
73
83
 
74
84
  Feature is complete when ALL of the following are true:
75
- - [ ] All TASK-MNN migrations run and verified in staging
85
+ - [ ] Every migration STEP run and verified in staging
76
86
  - [ ] All contracts have no remaining ⏳ TBD fields
77
87
  - [ ] Event choreography happy path verified end-to-end
78
88
  - [ ] All dead-letter scenarios have runbooks
@@ -35,14 +35,15 @@ audit_score: 0
35
35
 
36
36
  The longest sequential chain — minimum time to complete if parallelized optimally.
37
37
 
38
- ```
39
- TASK-NNN → TASK-NNN → TASK-NNN → TASK-NNN
40
- Nh Nh Nh Nh
41
- ```
42
-
43
- **Critical path estimate:** Nh total
38
+ **Critical path estimate:** Nh total, N steps
44
39
  *(All other work can happen in parallel alongside this chain)*
45
40
 
41
+ <!-- Record the DERIVED numbers only — total hours and step count, both from
42
+ `harness reduce board`. The chain's task ids belong to the LOCAL board
43
+ (.shapeup/<slug>/tasks/), which is gitignored and renumbers per machine; this
44
+ document is committed, so an id written here dangles on every other clone
45
+ (spec-lint TIER-DIRECTION). Read the id-level chain off the board itself. -->
46
+
46
47
  ---
47
48
 
48
49
  ## Package Distribution
@@ -58,12 +59,16 @@ TASK-NNN → TASK-NNN → TASK-NNN → TASK-NNN
58
59
 
59
60
  ## Parallel Opportunities
60
61
 
61
- Tasks with no interdependency that can run simultaneously:
62
+ How much of the board can run simultaneously — **counts and use cases, never task ids.** This file
63
+ is COMMITTED; the board is not, and its ids renumber per machine (spec-lint TIER-DIRECTION).
64
+
65
+ | Group | Use cases | Tasks | Can start after |
66
+ |-------|-----------|-------|-----------------|
67
+ | Group A | UC-x, UC-y | N | nothing — no dependency |
68
+ | Group B | UC-z | N | Group A |
62
69
 
63
- | Group | Tasks | Can start after |
64
- |-------|-------|----------------|
65
- | Group A | TASK-NNN, TASK-NNN | TASK-NNN completes |
66
- | Group B | TASK-NNN | TASK-NNN completes |
70
+ The per-scope release order is `scope-board.md`'s, keyed on `scope_id`. Cite it rather than
71
+ restating it here.
67
72
 
68
73
  ---
69
74
 
@@ -94,7 +99,7 @@ Carried from [[_index#Rabbit-Holes]]:
94
99
 
95
100
  ## Execution Recommendation
96
101
 
97
- <!-- Filled from spec-lint.mjs output -->
102
+ <!-- Filled from harness verify spec output -->
98
103
 
99
104
  **Audit Score: N/100**
100
105
 
@@ -166,50 +166,29 @@ Derived from: `_index.md` rabbit holes + `api-feasibility.md` SPIKE blocks + `in
166
166
 
167
167
  | Cut | At | Reason | Traded for (if any) |
168
168
  |-----|-----|-------|---------------------|
169
- | ~~[cut capability]~~ | GATE-N | appetite overflow — saved for a later bet | TASK-NNN |
169
+ | ~~[cut capability]~~ | GATE-N | appetite overflow — saved for a later bet | [UC or scope it was traded for] |
170
170
 
171
171
  *A Cut is a healthy shaping signal, not debt. Revisit it at the betting table next cycle.*
172
172
 
173
173
  ---
174
174
 
175
- ## S-03 — Dependency Graph
175
+ ## S-03 — Dependency Shape
176
176
 
177
- > Open this section when **Dependency** is 🟡 or 🔴, or when planning parallel work.
177
+ > Open this section when **Dependency** is 🟡 or 🔴.
178
178
 
179
- Derived from: `depends_on` and `unlocks` in every task frontmatter + `estimated_hours`.
179
+ Derived from: `depends_on` in every task frontmatter. **Counts and shape only — no task ids.**
180
+ This document is COMMITTED and the board is not: ids live in the gitignored tier and renumber on
181
+ every regeneration, so an id written here resolves on the machine that wrote it and nowhere else.
182
+ spec-lint reds a `TASK-` id anywhere in the committed tree (TIER-DIRECTION).
180
183
 
181
- ### Critical Path
184
+ | Metric | Value |
185
+ |---|---|
186
+ | Critical path | N tasks · NN hours · NN% of total estimated hours |
187
+ | Widest parallel wave | N tasks |
188
+ | Tasks with no dependency | N |
189
+ | Single points of failure (block > 2 downstream) | N |
182
190
 
183
- ```
184
- Critical path: N tasks · NN hours · NN% of total estimated hours
185
-
186
- TASK-001 [SPIKE] spike-[api]-feasibility 2h
187
- └─ blocks ──► TASK-004, TASK-005, TASK-006
188
- TASK-002 [TASK] shared-schema 3h ← parallel (no dependency on 001)
189
- TASK-003 [TASK] contract-stub 2h ← parallel
190
- TASK-004 [FEAT] implement-[repo] ⏳ blocked by TASK-001 4h
191
- └─ blocks ──► TASK-005
192
- TASK-005 [FEAT] [use-case]-service ⏳ blocked by TASK-004 6h
193
- └─ blocks ──► TASK-006, TASK-007
194
- TASK-006 [FEAT] [feature]-ui ⏳ blocked by TASK-005 8h
195
- TASK-007 [FEAT] [feature]-ui-edge-cases ⏳ blocked by TASK-005 4h
196
- ```
197
-
198
- ### Parallel Opportunities
199
-
200
- Tasks at the same dependency depth with no interdependency — can be executed in parallel:
201
-
202
- | Wave | Tasks | Total Hours | Can Parallelize |
203
- |------|-------|-------------|-----------------|
204
- | Wave 1 (no deps) | TASK-001, TASK-002, TASK-003 | Nh | ✅ yes — 3 agents |
205
- | Wave 2 (after 001) | TASK-004 | Nh | — single task |
206
- | Wave 3 (after 004) | TASK-005 | Nh | — single task |
207
- | Wave 4 (after 005) | TASK-006, TASK-007 | Nh | ✅ yes — 2 agents |
208
-
209
- ### Single Points of Failure
210
-
211
- Tasks whose delay cascades to > 2 downstream tasks:
212
-
213
- | Task | Blocks | Cascaded Hours at Risk |
214
- |------|--------|----------------------|
215
- | TASK-NNN | TASK-NNN, TASK-NNN, TASK-NNN | Nh |
191
+ **The per-scope build order — which scopes go in which wave, and what each waits on — lives in
192
+ `scope-board.md`, not here.** `scope-architect` writes that board and is the only worker that knows
193
+ the scope ids; it runs after this document, so the ordering cannot be expressed here in a key that
194
+ survives a clone. Cite the board, never restate it.
@@ -9,6 +9,9 @@ priority: N
9
9
  depends_on: []
10
10
  unlocks: []
11
11
  use_case_refs: []
12
+ scope_id: "" # optional — set ONLY when several scopes share this task's use
13
+ # case and spec-lint SCOPE-PARTITION says the UC anchor cannot
14
+ # decide who builds it. Names a committed scope_id (LOCAL→SHARED).
12
15
  entities: []
13
16
  repositories: []
14
17
  linked_docs: []
@@ -117,11 +117,15 @@ Every contracts folder must have an `_index.md` registry:
117
117
  ```markdown
118
118
  # Contract Registry — [feature-slug]
119
119
 
120
- | Repository | Source Type | Service / Engine | Status | SPIKE Task |
121
- |-----------|------------|-----------------|--------|------------|
122
- | [[FramerPageRepository]] | third-party-api | Framer REST API | ⚠️ speculative | [[TASK-001]] |
120
+ | Repository | Source Type | Service / Engine | Status | Spike |
121
+ |-----------|------------|-----------------|--------|-------|
122
+ | [[FramerPageRepository]] | third-party-api | Framer REST API | ⚠️ speculative | open |
123
123
  | [[PageCacheRepository]] | offline-storage | SQLite/Drizzle | ✅ confirmed | — |
124
124
  | [[UserSessionRepository]] | be-service | apps/api /auth | ✅ confirmed | — |
125
+
126
+ The Spike column carries a STATUS, not a task id. The registry is committed; the board is
127
+ not, and its ids renumber on every regeneration — so a task id recorded here resolves on
128
+ the machine that wrote it and nowhere else (spec-lint TIER-DIRECTION).
125
129
  ```
126
130
 
127
131
  This registry is the entry point for the spec-lint structure checks.
@@ -147,6 +151,6 @@ Every implementation task that uses a repository MUST:
147
151
 
148
152
  3. If contract is still `speculative` at task-generation time:
149
153
  ```markdown
150
- > ⏳ BLOCKED by [[TASK-001-spike-framer-feasibility]]
154
+ > ⏳ BLOCKED spike open, see [[api-feasibility#API-01]]
151
155
  > Unblock condition: [[contracts/framer-page.contract.md]] has no remaining ⏳ TBD fields
152
156
  ```
@@ -152,7 +152,7 @@ status: draft | ready
152
152
  > tasks carry `use_case_refs` (LOCAL, per-machine board); reverse lookup is always computed
153
153
  > live (synthesis S-01, audit coverage) — never stored on the committed UC. Rule: **never
154
154
  > declare a bidirectional field across the committed/local boundary** — task IDs renumber
155
- > per machine (generate-board bootstrap), so a stored back-link is wrong on every machine
155
+ > per machine (the board is regenerated locally), so a stored back-link is wrong on every machine
156
156
  > but one. Tolerate (ignore) the field on pre-v3.3 specs; do not emit or update it.
157
157
 
158
158
  Required sections: Summary (1 sentence), Preconditions, Input (TS interface), Steps
@@ -217,6 +217,8 @@ depends_on: [] # other TASK IDs: [TASK-001, TASK-002] — the
217
217
  unlocks: [] # DERIVED — inverse of the board's depends_on graph, recomputed
218
218
  # on every board write; never hand-authored (v3.3)
219
219
  use_case_refs: [] # UC IDs this task implements: [UC-CreateOrder]
220
+ scope_id: "" # optional disambiguator — the scope that builds this task.
221
+ # Needed only when >1 scope shares a use case (SCOPE-PARTITION).
220
222
  entities: []
221
223
  repositories: []
222
224
  linked_docs: [] # [[usecase]], [[domain-model#section]]
@@ -361,12 +361,12 @@ Slug rules:
361
361
  ## Link-Field Integrity (v3.3)
362
362
 
363
363
  **`depends_on` is the single authoritative edge; `unlocks` is derived, never hand-authored.**
364
- On EVERY board write — analyze, generate-board, reconcile — recompute (via
365
- `board-derive.mjs --write`, never by hand) the `unlocks` field of every task on the board as the
364
+ On EVERY board write — analyze, reconcile — recompute (via
365
+ `harness reduce board --write`, never by hand) the `unlocks` field of every task on the board as the
366
366
  exact inverse of the full board's `depends_on` graph, then write it. Adding one task that
367
367
  declares `depends_on: [TASK-007]` therefore rewrites `TASK-007.unlocks` in the same pass.
368
368
  "Write both sides when you remember" allows drift; a derived field cannot drift
369
- (island-escape shipped 10 asymmetric edges under the old rule). Audit L3-06 fails the board
369
+ (the old rule shipped boards carrying ten asymmetric edges). Audit L3-06 fails the board
370
370
  on any asymmetric edge.
371
371
 
372
372
  The same discipline has a boundary: it applies only when both sides live in the SAME root
@@ -563,7 +563,7 @@ tasks). Scope (Basecamp sense) maps onto a UC; an invariant lives *inside* the U
563
563
  task-executor / the tech lead; this mode only surfaces the disagreement.
564
564
  9. Regenerate ONLY the derived files: tasks/_index.md, scope-summary.md, synthesis.md
565
565
  (+ the unlocks frontmatter recompute from step 7).
566
- 10. Run board-derive.mjs (Appetite Guard arithmetic, below); report overflow as a discovery.
566
+ 10. Run harness reduce board (Appetite Guard arithmetic, below); report overflow as a discovery.
567
567
  ```
568
568
 
569
569
  **Appetite Guard (forcing function, not a report):**
@@ -584,12 +584,12 @@ This is scope hammering at the gate boundary — the overflow is surfaced, never
584
584
  **Naming note:** the discovery ledger's "scope" sections (above) predate the formal Scope
585
585
  Contract artifact below and name the same thing — a `discovery/ledger.md` scope heading MUST
586
586
  match an existing `scope_id` from a `scopes/<scope-id>.md` contract, or (a Keep item
587
- introducing new flow) become the seed for a new one via a scope-architect remap order. One concept, two touch points.
587
+ introducing new flow) become the seed for a new one via a scope-architect `map-scopes` order. One concept, two touch points.
588
588
 
589
589
  **Import/flow slicing (PA1 countermeasure).** Build a lightweight import graph over the task
590
590
  board's touched files: for each file a task writes, note what it imports and what imports it
591
591
  (grep for `import .* from ['"](\.\.?/[^'"]+)`-class patterns is sufficient — a full AST parser
592
- is an optimization, not a prerequisite, per design spec R6). Two files are in the same flow if
592
+ is an optimization, not a prerequisite). Two files are in the same flow if
593
593
  they sit on one call chain: a UI component → the API route it calls → the use case that route
594
594
  invokes → the repository that use case depends on. Group tasks by flow, not by which top-level
595
595
  directory their file lives in. A scope whose `allowed_file_substrate` is entirely `apps/web/**`
@@ -614,8 +614,8 @@ or entirely `apps/api/**` with no cross-layer flow is the PA1 failure mode — r
614
614
  }
615
615
  ```
616
616
  `hill_phase` is always written `UPHILL_UNKNOWN` at generation time — it is derived later from
617
- mechanical T0/T1/seesaw facts, never declared by `ba` (design spec DD-10). `superseded_by` stays
618
- `null` until a scope-architect split-scope order retires this contract in favor of its replacements.
617
+ mechanical T0/T1/seesaw facts, never declared by `ba`. `superseded_by` stays
618
+ `null` until a scope-architect `map-scopes` order retires this contract in favor of its replacements.
619
619
 
620
620
  **PA2 size lint:** a scope whose `allowed_file_substrate` glob set resolves to more than ~15
621
621
  files gets a ⚠️ from spec-lint PA2 (hard-cap configurable via pitch frontmatter `scope_size_cap`, default
@@ -7,7 +7,7 @@ source row below, it does not belong here (it belongs to exploratory QA, post-bu
7
7
  **Why it exists.** `spec-conformance` grades the AC that were written; it cannot expand
8
8
  them. The Test Surface is the systematic expansion — boundary values, negative cases,
9
9
  error-code coverage — done once at spec time so the evaluator (`test-surface-conformance`
10
- dimension) can probe it. Division of labor settled at the QA meeting (2026-06-11):
10
+ dimension) can probe it. Division of labor, a settled design decision:
11
11
  derivable tests = BA + Evaluator (this file); exploratory edges = `/qa-edge-hunter`,
12
12
  post-PASS, on the running app.
13
13
 
@@ -41,8 +41,8 @@ they are the **complete** set of categories the gate may offer:
41
41
 
42
42
  | Category | File | The worker reads it at | Good for |
43
43
  |----------|------|------------------------|----------|
44
- | `task-executor` | `shapeup/knowledge-base/task-executor.md` | Phase 1 (Context Load) | implementation discipline, code style, surgical-change habits, recurring over/under-engineering |
45
- | `ba-pitch-analyzer` | `shapeup/knowledge-base/ba-pitch-analyzer.md` | Phase 1 (Ingest & Scan) | scoping, task decomposition, DDD/spec habits, missed test-surface patterns |
44
+ | `task-executor` | `shapeup/knowledge-base/task-executor.md` | PLAN (context load) | implementation discipline, code style, surgical-change habits, recurring over/under-engineering |
45
+ | `ba-pitch-analyzer` | `shapeup/knowledge-base/ba-pitch-analyzer.md` | Phase 1 (INGEST) | scoping, task decomposition, DDD/spec habits, missed test-surface patterns |
46
46
  | `qa-edge-hunter` | `shapeup/knowledge-base/qa-edge-hunter.md` | Phase Q1 (Charter Map) | recurring edge classes, lenses that keep finding bugs, areas worth probing |
47
47
 
48
48
  **Not coachable.** `spec-evaluator` is deliberately excluded — the harness has a **single-judge**
@@ -54,7 +54,7 @@ say so plainly — do **not** force-fit it into a coachable category.
54
54
  **Harness defect ≠ worker steering.** When the feedback's root cause is the *mechanism itself* —
55
55
  a hook that fail-opens, a gate that reads the wrong file, two skill contracts that contradict
56
56
  each other — no amount of steering a worker fixes it, and filing it as a KB rule misdiagnoses a
57
- defect as a habit (island-escape's KB-BA-002 filed an orchestration/hook defect as BA guidance,
57
+ defect as a habit (a real case: an orchestration/hook defect filed as BA guidance,
58
58
  on a premise the skill contracts contradict). That is what the `harness-defect` category below is
59
59
  for: the coach records it in the committed defect register as a drafted **raw idea** for the
60
60
  Betting Table — the debt-free path ("remaining findings + new feedback → new raw idea") — and it
@@ -42,7 +42,8 @@ from `tech-lead`; it never reads or writes a shared run-state file.
42
42
  ## Input contract (pure worker)
43
43
 
44
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
45
+ kicked-off pitch path), `payload.stack` (sweep hint), `payload.spec_folder` (the SHARED spec
46
+ deliverable dir) and `payload.feature` (the run slug), plus `substrate.allowed` naming your one
46
47
  write surface — the orient output dir. Anything absent = unknown: confirm at GATE O-A
47
48
  (standalone) or report it in the result's `deviations`, never guess. Standalone, the
48
49
  `--pitch/--spec/--stack` flags below carry the same fields; the output dir derives from the
@@ -18,7 +18,7 @@ tech-lead: ... GATE L2 → EVAL → GATE L3 PASS ──► QA EDGE HUNT (you)
18
18
  GATE L3 FAIL → fix round (never reaches you — conformance first, edges after)
19
19
  ```
20
20
 
21
- **Division of labor (settled at the QA meeting, 2026-06-11):**
21
+ **Division of labor (a settled design decision, not a convention):**
22
22
 
23
23
  | Tier | Owner | When |
24
24
  |---|---|---|
@@ -33,14 +33,17 @@ tech-lead: ... GATE L2 → EVAL → GATE L3 PASS ──► QA EDGE HUNT (you)
33
33
  |------|----------|
34
34
  | Read EVAL-*.md to map covered territory — then hunt OUTSIDE it | Re-probe anything the evaluator already graded |
35
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 |
36
+ | Execute charters against the **running deliverable** (session-based exploratory) | Read-only speculate from code ("this looks racy") — every finding needs a live repro |
37
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
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
39
 
41
40
  Pure worker (harness rule: stateless workers, one stateful orchestrator). Its WorkOrder
42
41
  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
42
+ `payload.kb_rules_path`, and `payload.ledger` (the discovery ledger, READ-ONLY covered-territory
43
+ context so a hunt does not re-report what is already known). **`app_url` is null when the
44
+ deliverable is not served over HTTP** — a CLI, a library, a batch job. That is a normal order, not a
45
+ malformed one: drive the built entry point instead, exactly as the Test Surface's process rows do.
46
+ Do not refuse the hunt, and do not invent a URL. Its write surface is
44
47
  `.shapeup/<feature>/qa/**` only. The Hunter never touches the discovery ledger itself —
45
48
  ingest appends its `discoveries[]` under a `## Discovered` section, preserving single-writer
46
49
  mechanically.
@@ -50,7 +53,8 @@ mechanically.
50
53
  ## Workflow
51
54
 
52
55
  ```
53
- ⏸ GATE Q0 │ Preflight ────► hard: app running? EVAL verdict PASS? ledger exists?
56
+ ⏸ GATE Q0 │ Preflight ────► hard: deliverable reachable (one real request at `app_url`, or one
57
+ │ real invocation of the entry point when it is null)? EVAL PASS? ledger?
54
58
  │ soft: Test Surface present? absent → DEGRADED MODE offer
55
59
  Phase Q1 │ Charter Map ──► 6 lenses × UC tree − covered territory (EVAL-probed rows/AC)
56
60
  ⏸ GATE Q1 │ Charter Review► PO/TL hammer the charter list (QA's own appetite is fixed too)
@@ -272,7 +276,6 @@ an order, the WorkResult envelope `.shapeup/<feature>/results/<order-suffix>.jso
272
276
 
273
277
  ```markdown
274
278
  # Hunt Report — [feature] (round [r], [date])
275
- mode: [full | degraded | recheck]
276
279
  charters: [run]/[approved] · session units spent: [n]
277
280
  out of bounds (excluded): […]
278
281
  hammered out at GATE Q1 (not hunted): […]
@@ -282,7 +285,8 @@ hammered out at GATE Q1 (not hunted): […]
282
285
  |---|---|---|---|
283
286
  | ① Boundary | C-01, C-05 | 2 | 0 |
284
287
  | … | | | |
285
- → details live in .shapeup/<feature>/discovery/ledger.md ## QA Edge Findings (round [r])
288
+ → details live in .shapeup/<feature>/discovery/ledger.md under the `## Discovered` section
289
+ ingest appends for this hunt's order
286
290
 
287
291
  ## Shaping-quality signal (advisory, for the PO — next cycle's input)
288
292
  - lens ⑤ findings ≈ No-gos written loosely (breach routes left open)
@@ -298,48 +302,18 @@ No verdict line exists in this file by design. The Hunter's last words:
298
302
 
299
303
  ---
300
304
 
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
305
  ## Invocation
319
306
 
320
307
  ```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
308
  /qa-edge-hunter --feature checkout-vnpay --spec shapeup/checkout-vnpay/spec/ --app http://localhost:3000
333
309
  # (--eval/--ledger default to the conventional paths under the LOCAL root .shapeup/<feature>/)
334
310
 
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
311
+ # Escape hatch
339
312
  --auto # skip GATE Q1 pause (charter list logged, not reviewed) — Q0 hard
340
313
  # 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)
314
+
315
+ # There is deliberately NO --lenses flag: the 6 lenses are fixed; narrow by cutting
316
+ # charters at GATE Q1 (or --auto + report).
343
317
  ```
344
318
 
345
319
  ### Progress Markers