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.
- package/.claude/settings.local.example.json +5 -5
- package/.claude-plugin/plugin.json +1 -1
- package/AGENTS.md +54 -107
- package/README.md +165 -151
- package/SECURITY.md +49 -27
- package/bin/init.mjs +93 -108
- package/bin/lib/grant.mjs +145 -0
- package/commands/build.md +20 -0
- package/commands/eval.md +5 -4
- package/commands/scopes.md +5 -4
- package/commands/shape.md +1 -1
- package/commands/ship.md +53 -7
- package/commands/wire.md +1 -1
- package/hooks/dispatch-receipt.mjs +195 -0
- package/hooks/gate-intake.mjs +16 -17
- package/hooks/gate-zerowork.mjs +107 -25
- package/hooks/hooks.json +9 -48
- package/hooks/lib/decision.mjs +38 -19
- package/hooks/safety-spine.mjs +4 -4
- package/hooks/sandbox-guard.mjs +130 -50
- package/{skills/tech-lead/scripts/compile-order.mjs → kernel/compile.mjs} +344 -55
- package/{skills/tech-lead/scripts/gate-answers.mjs → kernel/gate.mjs} +69 -26
- package/kernel/harness.mjs +134 -0
- package/{skills/tech-lead/scripts/fit-check.mjs → kernel/init/fit.mjs} +25 -22
- package/kernel/init/run.mjs +489 -0
- package/{skills/tech-lead/scripts → kernel}/lib/argv.mjs +52 -31
- package/{skills/tech-lead/scripts/lib/contract-md.mjs → kernel/lib/contract.mjs} +261 -17
- package/kernel/lib/paths.mjs +491 -0
- package/kernel/probe/concurrency.mjs +510 -0
- package/{skills/tech-lead/scripts/aegis-digest.mjs → kernel/probe/digest.mjs} +10 -11
- package/kernel/probe/eval.mjs +77 -0
- package/kernel/probe/leg.mjs +125 -0
- package/kernel/probe/resume.mjs +528 -0
- package/{skills/tech-lead/scripts → kernel/probe}/stats.mjs +102 -21
- package/kernel/probe/t0.mjs +66 -0
- package/{skills/ba-pitch-analyzer/scripts/board-derive.mjs → kernel/reduce/board.mjs} +104 -28
- package/kernel/reduce/graph.mjs +437 -0
- package/kernel/reduce/hill.mjs +152 -0
- package/kernel/reduce/ingest.mjs +633 -0
- package/{hooks/slop-cleaner.mjs → kernel/reduce/leftovers.mjs} +40 -57
- package/{skills/tech-lead/scripts/ship-report.mjs → kernel/reduce/ship.mjs} +93 -14
- package/{skills/tech-lead/scripts/run-snapshot.mjs → kernel/reduce/snapshot.mjs} +22 -21
- package/{skills/spec-evaluator/scripts/verdict-ledger.mjs → kernel/reduce/verdict.mjs} +14 -8
- package/kernel/report/export.mjs +325 -0
- package/kernel/report/facts.mjs +347 -0
- package/{skills/tech-lead/scripts/budget-check.mjs → kernel/verify/budget.mjs} +22 -25
- package/kernel/verify/dispatch.mjs +114 -0
- package/{skills/tech-lead/scripts/validate-envelope.mjs → kernel/verify/envelope.mjs} +20 -15
- package/{skills/tech-lead/scripts/lib → kernel/verify}/ratchet-tree.mjs +36 -14
- package/kernel/verify/skills.mjs +125 -0
- package/kernel/verify/spec.mjs +559 -0
- package/{skills/tech-lead/scripts/t0-verify.mjs → kernel/verify/t0.mjs} +138 -28
- package/{skills/tech-lead/scripts/trace-lint.mjs → kernel/verify/trace.mjs} +28 -13
- package/oracles/_shared.mjs +1 -1
- package/oracles/http-oracle.mjs +2 -2
- package/oracles/index.mjs +1 -1
- package/oracles/process-oracle.mjs +2 -2
- package/oracles/snapshot-oracle.mjs +2 -2
- package/oracles/test-oracle.mjs +2 -2
- package/package.json +11 -13
- package/skills/ba-pitch-analyzer/SKILL.md +24 -19
- package/skills/ba-pitch-analyzer/assets/templates/_index.tmpl.md +1 -1
- package/skills/ba-pitch-analyzer/assets/templates/api-feasibility.tmpl.md +12 -7
- package/skills/ba-pitch-analyzer/assets/templates/contracts/third-party-api.contract.tmpl.md +6 -3
- package/skills/ba-pitch-analyzer/assets/templates/cross-context/migration-plan.tmpl.md +5 -4
- package/skills/ba-pitch-analyzer/assets/templates/cross-context/team-handoff.tmpl.md +23 -13
- package/skills/ba-pitch-analyzer/assets/templates/scope-summary.tmpl.md +17 -12
- package/skills/ba-pitch-analyzer/assets/templates/synthesis.tmpl.md +17 -38
- package/skills/ba-pitch-analyzer/assets/templates/task.tmpl.md +3 -0
- package/skills/ba-pitch-analyzer/references/contract-patterns.md +8 -4
- package/skills/ba-pitch-analyzer/references/doc-schemas.md +3 -1
- package/skills/ba-pitch-analyzer/references/task-generation.md +8 -8
- package/skills/ba-pitch-analyzer/references/test-surface.md +1 -1
- package/skills/coach/SKILL.md +3 -3
- package/skills/orient/SKILL.md +2 -1
- package/skills/qa-edge-hunter/SKILL.md +15 -41
- package/skills/scope-architect/SKILL.md +57 -18
- package/skills/scope-hammer/SKILL.md +5 -5
- package/skills/shapeup/SKILL.md +3 -3
- package/skills/shapeup/resources/context-compaction.md +4 -3
- package/skills/solution-architect/SKILL.md +37 -15
- package/skills/spec-evaluator/SKILL.md +24 -7
- package/skills/spec-evaluator/references/dimensions/_registry.md +2 -2
- package/skills/spec-evaluator/references/dimensions/completeness.md +1 -1
- package/skills/spec-evaluator/references/dimensions/integration.md +98 -67
- package/skills/spec-evaluator/references/dimensions/spec-conformance.md +4 -4
- package/skills/spec-evaluator/references/dimensions/test-surface-conformance.md +1 -1
- package/skills/spec-evaluator/references/probing.md +42 -23
- package/skills/spec-evaluator/references/report-schema.md +2 -2
- package/skills/task-executor/SKILL.md +32 -18
- package/skills/tech-lead/SKILL.md +127 -438
- package/skills/tech-lead/references/gates.md +140 -49
- package/skills/tech-lead/references/protocol.md +832 -0
- package/skills/tech-lead/schemas/domain.schema.json +645 -198
- package/skills/tech-lead/schemas/gate-answers.schema.json +2 -2
- package/skills/tech-lead/schemas/work-order.schema.json +11 -2
- package/skills/tech-lead/schemas/work-result.schema.json +56 -18
- package/skills/tech-lead/workflows/shapeup-run.js +1474 -0
- package/skills/translator/SKILL.md +2 -2
- package/hooks/anti-rationalization.mjs +0 -244
- package/hooks/compact-snapshot.mjs +0 -47
- package/hooks/gate-deadline.mjs +0 -151
- package/hooks/gate-l2.mjs +0 -161
- package/hooks/session-rehydrate.mjs +0 -109
- package/skills/advisor-protocol/SKILL.md +0 -171
- package/skills/ba-pitch-analyzer/scripts/spec-lint.mjs +0 -239
- package/skills/spec-evaluator/README.md +0 -93
- package/skills/tech-lead/README.md +0 -71
- package/skills/tech-lead/references/delegation.md +0 -254
- package/skills/tech-lead/references/invocation.md +0 -45
- package/skills/tech-lead/references/ledger-schema.md +0 -214
- package/skills/tech-lead/references/round-protocol.md +0 -184
- package/skills/tech-lead/references/state-model.md +0 -66
- package/skills/tech-lead/scripts/ingest-result.mjs +0 -270
- package/skills/tech-lead/scripts/init-run.mjs +0 -326
- package/skills/tech-lead/scripts/lib/is-main.mjs +0 -82
- package/skills/tech-lead/scripts/lib/paths.mjs +0 -278
- 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 |
|
|
18
|
-
|
|
19
|
-
| API-01 | [ServiceName] | [What pitch claims this API can do] | ❓ UNVERIFIED |
|
|
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
|
-
**
|
|
53
|
-
<!--
|
|
54
|
-
|
|
55
|
-
|
|
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
|
package/skills/ba-pitch-analyzer/assets/templates/contracts/third-party-api.contract.tmpl.md
CHANGED
|
@@ -5,7 +5,9 @@ feature: "[feature-slug]"
|
|
|
5
5
|
repository: "[RepoName]"
|
|
6
6
|
service: "[ServiceName]"
|
|
7
7
|
feasibility_ref: "API-[NN]"
|
|
8
|
-
|
|
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]]
|
|
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
|
|
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
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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]] |
|
|
25
|
-
| [Team B] (API) | [Team A] (API) | `EventName` schema |
|
|
26
|
-
| [Team B] (Mobile) | QA | E2E test cases |
|
|
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
|
|
34
|
-
until [Team A] completes
|
|
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
|
-
|
|
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]:
|
|
50
|
-
[Team B]:
|
|
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
|
|
53
|
-
[Team B]:
|
|
54
|
-
[Team C]:
|
|
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
|
-
|
|
|
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
|
-
- [ ]
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 |
|
|
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
|
|
175
|
+
## S-03 — Dependency Shape
|
|
176
176
|
|
|
177
|
-
> Open this section when **Dependency** is 🟡 or
|
|
177
|
+
> Open this section when **Dependency** is 🟡 or 🔴.
|
|
178
178
|
|
|
179
|
-
Derived from: `depends_on`
|
|
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
|
-
|
|
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
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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 |
|
|
121
|
-
|
|
122
|
-
| [[FramerPageRepository]] | third-party-api | Framer REST API | ⚠️ speculative |
|
|
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
|
|
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 (
|
|
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,
|
|
365
|
-
`board
|
|
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
|
-
(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
618
|
-
`null` until a scope-architect
|
|
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
|
|
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
|
|
package/skills/coach/SKILL.md
CHANGED
|
@@ -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` |
|
|
45
|
-
| `ba-pitch-analyzer` | `shapeup/knowledge-base/ba-pitch-analyzer.md` | Phase 1 (
|
|
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 (
|
|
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
|
package/skills/orient/SKILL.md
CHANGED
|
@@ -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),
|
|
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
|
|
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
|
|
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` (
|
|
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:
|
|
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
|
|
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
|
-
#
|
|
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
|
-
|
|
342
|
-
|
|
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
|