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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scope-architect
|
|
3
|
-
description: "Use this skill to map
|
|
3
|
+
description: "Use this skill to map the vertical scopes of a feature — Shape Up's \"map the scopes\" (step 8) as committed, mechanically enforceable contracts. Triggers on: \"map the scopes\", \"write the scope contracts\", \"scope contract\", \"the discovered tasks don't fit any scope\", \"re-slice the substrate\" (operations map-scopes). Writes the committed scopes/*.md contracts by import-graph slicing along business flow, with write-whitelist substrates and e2e fixtures. NOT for decomposing a pitch into tasks (ba-pitch-analyzer) or cutting scope at ship time (scope-hammer)."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Scope Architect (pure worker v1.0)
|
|
@@ -13,17 +13,15 @@ harness enforces mechanically: the sandbox hook denies writes outside a substrat
|
|
|
13
13
|
runs the fixtures, the evaluator asserts only against the affordance manifest. This skill is
|
|
14
14
|
the **sole writer** of scope contracts — a distinct authority from the planner (task
|
|
15
15
|
decomposition) and a distinct failure mode (directory-thinking, PA1) deserving its own
|
|
16
|
-
|
|
16
|
+
the ship report's census table.
|
|
17
17
|
|
|
18
18
|
## Input contract — the WorkOrder
|
|
19
19
|
|
|
20
20
|
| Field | What it is |
|
|
21
21
|
|---|---|
|
|
22
|
-
| `operation` | `map-scopes`
|
|
22
|
+
| `operation` | `map-scopes` — the only operation this skill has. It covers first slicing after the board exists, folding discovered items in, and re-slicing a stuck scope; the payload says which of those you are doing |
|
|
23
23
|
| `payload.feature` / `payload.spec_folder` | Slug + committed spec (read ux-behavior.md for manifests; usecases for flows) |
|
|
24
|
-
| `payload.tasks[]` | The board's tasks with their touched files — the slicing
|
|
25
|
-
| `payload.discovered_ledger` | (remap) items that fit no existing substrate |
|
|
26
|
-
| `payload.scope_id` | (split-scope) the stuck scope (`rounds_at_position ≥ 3`, or an approved substrate-expansion) |
|
|
24
|
+
| `payload.tasks[]` | The board's tasks with their touched files — the slicing INPUT only. Each carries `use_case_refs`; those UC ids are what you write into the contract. Never copy a task id into a contract |
|
|
27
25
|
| `substrate.allowed` | `scopes/*.md` + `scope-board.md` — your ONLY write surface |
|
|
28
26
|
|
|
29
27
|
## Core process
|
|
@@ -39,7 +37,23 @@ anti-rationalization table.
|
|
|
39
37
|
scalars and [a, b] lists, a `## Affordances` table for affordance_manifest, and a
|
|
40
38
|
short `## Why this slice` paragraph. A reviewer must be able to read the substrate
|
|
41
39
|
in a PR; regeneration preserves prose under headings you do not own.
|
|
42
|
-
scope_id, topology_type
|
|
40
|
+
scope_id, topology_type — the stable join key is the scope
|
|
41
|
+
use_cases[] — the UC ids this scope implements.
|
|
42
|
+
THE ONLY LINK YOU WRITE TO THE
|
|
43
|
+
WORK: never task ids. The contract
|
|
44
|
+
is committed and the board is not,
|
|
45
|
+
so a TASK-NNN here dangles on
|
|
46
|
+
every other clone (spec-lint
|
|
47
|
+
TIER-DIRECTION reds it). The
|
|
48
|
+
scope's tasks are re-derived from
|
|
49
|
+
the board's own use_case_refs
|
|
50
|
+
covers[] — optional REQ-ids from
|
|
51
|
+
requirements.md this scope answers
|
|
52
|
+
for; stable, never renumbered
|
|
53
|
+
depends_on[] — scope_ids this scope builds AFTER.
|
|
54
|
+
This is the build ORDER — declare
|
|
55
|
+
it whenever one scope consumes
|
|
56
|
+
another's output, or the two race
|
|
43
57
|
allowed_file_substrate[] — exact globs; the sandbox hook's
|
|
44
58
|
write-whitelist; wrong here =
|
|
45
59
|
a legitimate ESCALATE later
|
|
@@ -59,17 +73,30 @@ anti-rationalization table.
|
|
|
59
73
|
a fixture for unbuilt behavior
|
|
60
74
|
hill_phase: "UPHILL_UNKNOWN" — ALWAYS; phase is derived from
|
|
61
75
|
T0/T1/seesaw facts later,
|
|
62
|
-
never authored
|
|
63
|
-
4 LINT node "${CLAUDE_PLUGIN_ROOT}/
|
|
64
|
-
→ PA1 (directory alignment), PA2 (>~15 files), DISJOINT (undeclared overlap)
|
|
76
|
+
never authored
|
|
77
|
+
4 LINT node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" verify spec --slug <slug>
|
|
78
|
+
→ PA1 (directory alignment), PA2 (>~15 files), DISJOINT (undeclared overlap),
|
|
79
|
+
SCOPE-ANCHOR (empty/unresolvable use_cases), TIER-DIRECTION (a task id in a
|
|
80
|
+
committed contract), SCOPE-DEPS (depends_on naming a scope that isn't here).
|
|
65
81
|
Fix reds by re-slicing, not by silencing.
|
|
66
|
-
5 BOARD regenerate scope-board.md
|
|
82
|
+
5 BOARD regenerate scope-board.md — a VIEW of the contracts, nothing more:
|
|
83
|
+
|
|
84
|
+
| scope_id | topology | use_cases | depends_on | files | lint |
|
|
85
|
+
|
|
86
|
+
Every column restates a field the contract already declares, so the board can be thrown
|
|
87
|
+
away and rebuilt. Do NOT add a `wave` column: waves are Kahn levels of `depends_on` and
|
|
88
|
+
`probe resume` derives them at dispatch — a hand-written copy of a derived value drifts,
|
|
89
|
+
which is exactly why `unlocks` stopped being authored. The BUILD ORDER lives in each
|
|
90
|
+
contract's `depends_on`; the board only shows it.
|
|
91
|
+
|
|
92
|
+
A `TASK-` id anywhere in a contract or the board — a column, a cell, or a sentence in
|
|
93
|
+
the prose — is spec-lint TIER-DIRECTION red. The board is committed; ids are not.
|
|
67
94
|
```
|
|
68
95
|
|
|
69
|
-
**
|
|
96
|
+
**Folding in a discovered item:** it joins the nearest scope only if the flow matches (extend that
|
|
70
97
|
substrate minimally); otherwise propose a NEW scope — never silently widen an existing one.
|
|
71
|
-
**
|
|
72
|
-
old one `superseded_by: [ids]` — never delete (branch and T0 history stay attributable).
|
|
98
|
+
**Re-slicing a stuck scope:** re-run step 1 on just that scope's task+file set → N new contracts;
|
|
99
|
+
mark the old one `superseded_by: [ids]` — never delete (branch and T0 history stay attributable).
|
|
73
100
|
|
|
74
101
|
## Anti-rationalization table
|
|
75
102
|
|
|
@@ -80,19 +107,31 @@ old one `superseded_by: [ids]` — never delete (branch and T0 history stay attr
|
|
|
80
107
|
| "I'll widen the substrate a little so the doer stops escalating" | A wide substrate is no substrate. Split or add a shared_substrate entry, deliberately. |
|
|
81
108
|
| "This scope looks downhill, I'll set the phase" | hill_phase is UPHILL_UNKNOWN at write, always. Facts move dots, not authors. |
|
|
82
109
|
| "The old contract is superseded, delete it" | supersede-never-delete. History must stay attributable. |
|
|
110
|
+
| "Both scopes implement that UC, the tasks will sort themselves out" | They will not — both scopes get every task of that UC and three of four writes get denied. Give each scope its own use cases, or say so in deviations[] so the board can be stamped. |
|
|
111
|
+
| "I'll list the task ids so the contract says what it builds" | The board is gitignored and renumbers per machine; the contract is committed. Cite the UCs — the tasks are re-derived from them. |
|
|
112
|
+
| "Build order is obvious from the slice, I'll leave depends_on empty" | Nothing infers it any more. An undeclared edge means the two scopes are released into the same wave and race. |
|
|
83
113
|
| "Fixtures can come later, leave the field empty" | Fixture at contract time or an explicit TBD flag — silence is how T0 goes blind. |
|
|
84
114
|
|
|
85
115
|
## Output contract — the WorkResult
|
|
86
116
|
|
|
117
|
+
**Escalation rule.** If you return `status: "escalated"`, the **first** entry in `deviations[]`
|
|
118
|
+
must be the blocker: one specific, answerable question plus the context needed to answer it.
|
|
119
|
+
Nothing else in the envelope carries it — there is no `escalates[]` field — so a vague entry, or
|
|
120
|
+
the question buried under other notes, reaches the human as "something went wrong" and costs a
|
|
121
|
+
round. Write it so someone without your context can answer it in one reply.
|
|
122
|
+
|
|
123
|
+
|
|
87
124
|
`scopes/*.md` + `scope-board.md` in your substrate, then
|
|
88
125
|
`.shapeup/<slug>/results/<order-suffix>.json`: `status`, `artifacts[]` (the contracts
|
|
89
|
-
written/superseded), `
|
|
90
|
-
territory
|
|
126
|
+
written/superseded), `deviations[]` (e.g. a discovered item implying a new UC — the planner's
|
|
127
|
+
territory — and any lint warn left standing, with why). You never touch task files,
|
|
91
128
|
`tasks/_index.md`, spec docs, or run-state.
|
|
92
129
|
|
|
93
130
|
## Verification checklist
|
|
94
131
|
|
|
95
132
|
- [ ] Every scope crosses layers or is declared CHOWDER; spec-lint PA1 = 0 red
|
|
133
|
+
- [ ] Every scope names ≥1 `use_cases` that resolves on disk, and NO contract carries a task id
|
|
134
|
+
- [ ] Every scope that consumes another's output declares it in `depends_on`
|
|
96
135
|
- [ ] Substrates disjoint except declared shared_substrate (DISJOINT = 0 red)
|
|
97
136
|
- [ ] Every interactive element in scope screens appears in exactly one affordance_manifest
|
|
98
137
|
- [ ] Every scope has fixtures or an explicit TBD flag
|
|
@@ -102,10 +141,10 @@ territory), `deviations[]` (any lint warn left standing and why). You never touc
|
|
|
102
141
|
## Invocation
|
|
103
142
|
|
|
104
143
|
```bash
|
|
105
|
-
# Orchestrated — compile-order --operation map-scopes
|
|
144
|
+
# Orchestrated — compile-order --operation map-scopes --worker scope-architect …
|
|
106
145
|
/scope-architect --order .shapeup/checkout-vnpay/orders/map-scopes.json
|
|
107
146
|
|
|
108
147
|
# Standalone shims (compile the same envelope)
|
|
109
148
|
/scope-architect --map shapeup/checkout-vnpay/
|
|
110
|
-
/scope-architect --split cart-creation shapeup/checkout-vnpay/
|
|
149
|
+
/scope-architect --map --split cart-creation shapeup/checkout-vnpay/ # re-slice one scope
|
|
111
150
|
```
|
|
@@ -11,7 +11,7 @@ live with today — not to a hypothetical perfect version. "Better than the base
|
|
|
11
11
|
enough to ship; "not as good as I imagined" is not a reason to keep building.
|
|
12
12
|
|
|
13
13
|
**Why this is its own skill, not tech-lead prose.** GATE H census pulls from several sources
|
|
14
|
-
that accumulate over a whole run (QA findings, discovered-task ledger,
|
|
14
|
+
that accumulate over a whole run (QA findings, discovered-task ledger, attempt-budget
|
|
15
15
|
overflows, per-scope inner-breaker trips) — a genuinely separate synthesis step from
|
|
16
16
|
orchestration. Splitting it out keeps `tech-lead` thin (it dispatches, this skill decides what
|
|
17
17
|
survives the hammer) and gives the census/cut-list/verdict logic one owner instead of being
|
|
@@ -22,10 +22,10 @@ re-derived inline at every SHIP.
|
|
|
22
22
|
## When this fires
|
|
23
23
|
|
|
24
24
|
```
|
|
25
|
-
1. All scopes reach FINISHED on the hill
|
|
25
|
+
1. All scopes reach FINISHED on the hill → normal stop, post-QA-hunt.
|
|
26
26
|
2. Outer circuit breaker trips: round_budget reaches 0 with scopes still uphill/downhill.
|
|
27
27
|
3. Inner circuit breaker trips: a scope's attempt_budget (default 5) is exhausted without a
|
|
28
|
-
T0-green result → queued as a hammer PROPOSAL (
|
|
28
|
+
T0-green result → queued as a hammer PROPOSAL (`hammer_proposals`),
|
|
29
29
|
judged here rather than immediately blocking the round.
|
|
30
30
|
```
|
|
31
31
|
Any of the three routes to this skill; the difference is only what's in the census (case 1 has
|
|
@@ -63,7 +63,7 @@ H0.1 Unresolved scopes (breaker cases only):
|
|
|
63
63
|
with the T0 failure that stalled them (from the last red t0/verdicts/*.json)
|
|
64
64
|
H0.2 QA findings (qa-edge-hunter's hunt-report.md, when present) — all `~` by default.
|
|
65
65
|
H0.3 Discovered-task ledger entries still open (discovery/ledger.md, `[+]`/`~` unresolved).
|
|
66
|
-
H0.4
|
|
66
|
+
H0.4 Attempt-budget hammer proposals (scopes that exhausted their T0 attempts during BUILD).
|
|
67
67
|
H0.5 Classify every item: MUST-HAVE (the pitch's core problem is unsolved without it) vs
|
|
68
68
|
NICE-TO-HAVE (`~`, improves but doesn't block the core promise). Default to NICE-TO-HAVE
|
|
69
69
|
unless the item traces directly to a pitch boundary or a scope's business_goal — a
|
|
@@ -87,7 +87,7 @@ customer suffers through today), never to a perfect ideal.
|
|
|
87
87
|
|
|
88
88
|
```
|
|
89
89
|
H1.1 Resolve the baseline: shapeup/<slug>/shaping/baseline.md if present (written at
|
|
90
|
-
shaping time
|
|
90
|
+
shaping time — first-class, not a pitch footnote). Absent →
|
|
91
91
|
degrade honestly: read the pitch's problem statement as the implicit baseline and flag
|
|
92
92
|
"baseline not first-class — comparison is approximate" in the report. Do not invent one.
|
|
93
93
|
H1.2 For each MUST-HAVE item from H0: "with this item cut/carried, is the shipped product
|
package/skills/shapeup/SKILL.md
CHANGED
|
@@ -33,7 +33,7 @@ This skill lazily loads detail from resource files. **Read the relevant resource
|
|
|
33
33
|
| `/shapeup breadboard-reflection` | `resources/breadboard-reflection.md` |
|
|
34
34
|
| `/shapeup full` | Read `resources/shaping.md` first, then `resources/breadboarding.md` before B-phases, and `resources/context-compaction.md` for the run digest |
|
|
35
35
|
|
|
36
|
-
> Resource paths are relative to this skill's directory.
|
|
36
|
+
> Resource paths are relative to this skill's directory (`resources/` beside this SKILL.md, wherever the plugin is installed).
|
|
37
37
|
> Multi-gate runs maintain a derived **decision digest** so each gate reads a compact slice instead of full prose — see `resources/context-compaction.md` and the "Run Workspace & Digest" section below.
|
|
38
38
|
|
|
39
39
|
---
|
|
@@ -374,8 +374,8 @@ Two roots, separated by artifact **nature** (full design →
|
|
|
374
374
|
- **Shared** root `shapeup/[slug]/` = what the team contributes to
|
|
375
375
|
(source + deliverable). **Local** root `.shapeup/[slug]/` = per-run scratch,
|
|
376
376
|
hidden and fully gitignorable. Add **one** line to `.gitignore`: `.shapeup/`.
|
|
377
|
-
No carve-out needed —
|
|
378
|
-
|
|
377
|
+
No carve-out needed — everything machine-written at run time, including the
|
|
378
|
+
harvest shards `.shapeup/metrics/*.jsonl`, lives under the local root.
|
|
379
379
|
- `digest.md` is the run's derived decision context (the 4-field, two-zone read
|
|
380
380
|
model the gates consume). It is **never** the source of truth and never crosses
|
|
381
381
|
a skill boundary — `ba-pitch-analyzer` reads `pitch.md`/`shaping.md`, never the
|
|
@@ -182,9 +182,10 @@ Everything keys off the feature `<slug>`. Two roots, split by **who needs it**:
|
|
|
182
182
|
- The **local** root `.shapeup/[slug]/` is per-run scratch + reports — hidden,
|
|
183
183
|
fully gitignorable, dies with the run. It is derived from the same `<slug>`.
|
|
184
184
|
- `.gitignore`: one line — `.shapeup/`. The whole local root is ignored; no
|
|
185
|
-
carve-out is needed because
|
|
186
|
-
signal
|
|
187
|
-
fact-only; see the tech-lead skill's SHIP step)
|
|
185
|
+
carve-out is needed because everything machine-written at run time lives there,
|
|
186
|
+
including the harvested signal shards `.shapeup/metrics/*.jsonl` (written by
|
|
187
|
+
the tech-lead at SHIP, fact-only; see the tech-lead skill's SHIP step). The
|
|
188
|
+
committed report surface is the frozen `shapeup/[slug]/REPORT.md`.
|
|
188
189
|
- All paths are **project-relative, resolved from the project root / cwd.** Never
|
|
189
190
|
`/mnt/...` — that is the claude.ai authoring sandbox and dies in a user repo.
|
|
190
191
|
|
|
@@ -7,9 +7,9 @@ description: "Use this skill to design how each use-case's engine integrates int
|
|
|
7
7
|
|
|
8
8
|
**Design the seam, or the engine ships orphaned.**
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
**zero call sites** in the app's composition root —
|
|
12
|
-
running application
|
|
10
|
+
This skill exists because a sizeable engine module can be built, fully tested, and still have
|
|
11
|
+
**zero call sites** in the app's composition root — green, and unreachable from the
|
|
12
|
+
running application; observed across multiple scopes in one run, not theorized. It closes that
|
|
13
13
|
hole at the front: before the scopes are sliced, it designs a committed **wiring map**
|
|
14
14
|
(`shapeup/<slug>/wiring-map.md`) that names, for every use case, the chain from the
|
|
15
15
|
engine module to a player-visible affordance — including **how** and **where** the engine attaches
|
|
@@ -23,13 +23,13 @@ orchestrator's `trace-lint` proves against real code at L1b. Your job is to make
|
|
|
23
23
|
|
|
24
24
|
Two payoffs, one artifact:
|
|
25
25
|
- **Reachability becomes checkable later.** Because you name each UC's `engine` (a real
|
|
26
|
-
repo-relative module path) and the profile declares the `entry_point`, `trace
|
|
26
|
+
repo-relative module path) and the profile declares the `entry_point`, `harness verify trace` can
|
|
27
27
|
fold this map into its oracle *after the build*: a UC whose engine does not reach the
|
|
28
28
|
`entry_point` via the import graph goes red. You supply the two anchors; the oracle does the
|
|
29
29
|
proving.
|
|
30
30
|
- **The slicer gets its integration seam up front.** Declaring each attachment *before*
|
|
31
31
|
`scope-architect` runs supplies the missing input behind the round-1 substrate-expansion
|
|
32
|
-
escalations —
|
|
32
|
+
escalations — repeated identical "declined by precedent" stalls. (This skill *front-loads* the
|
|
33
33
|
seam; it does not enforce the re-slice rule — that's a separate change.)
|
|
34
34
|
|
|
35
35
|
You are the **sole writer** of the wiring map, written **directly** (the same authority
|
|
@@ -70,17 +70,32 @@ guessed `main.js` would make the later oracle certify nothing.
|
|
|
70
70
|
the import graph, it does not parse this field)
|
|
71
71
|
affordance the player-visible thing this UC exposes once wired (the human
|
|
72
72
|
end of the chain — what a user can DO, not an internal call)
|
|
73
|
-
3 WRITE shapeup/<slug>/wiring-map.md (WiringMap):
|
|
74
|
-
entry_point (echo of the profile), entries[]
|
|
73
|
+
3 WRITE shapeup/<slug>/wiring-map.md (WiringMap): frontmatter for schema_version, feature
|
|
74
|
+
and entry_point (echo of the profile), then entries[] as ONE MARKDOWN TABLE under a
|
|
75
|
+
`## Wiring` heading — this exact shape, because it is the only one the reader parses:
|
|
76
|
+
|
|
77
|
+
## Wiring
|
|
78
|
+
|
|
79
|
+
| use_case | engine | wiring_seam | entry_call_site | affordance |
|
|
80
|
+
|---|---|---|---|---|
|
|
81
|
+
| UC-01 | src/parsing.mjs | argv dispatch calls parseEnv | bin/envlint.mjs | envlint <file> |
|
|
82
|
+
|
|
83
|
+
One ROW per use case + engine pair — a UC carried by two engines gets two rows, never
|
|
84
|
+
one cell naming both. `engine` is a bare repo-relative path and nothing else: the
|
|
85
|
+
oracle resolves that cell against disk, and a cell like "`a.mjs` and `b.mjs` — two pure
|
|
86
|
+
modules" resolves to no file and is reported unverifiable. Put the explanation in the
|
|
87
|
+
`## Deviations` prose, never in the cell.
|
|
88
|
+
|
|
89
|
+
A UC whose
|
|
75
90
|
engine has no attachment path is exactly the gap this artifact exists to surface —
|
|
76
|
-
write the entry with the seam you INTEND and raise it in deviations[]
|
|
91
|
+
write the entry with the seam you INTEND and raise it in deviations[], so
|
|
77
92
|
the build knows the wiring it must close. Your craft ends here: WRITE, then return the
|
|
78
93
|
WorkResult. You do not run trace-lint — the orchestrator runs it advisory at L1b.
|
|
79
94
|
```
|
|
80
95
|
|
|
81
96
|
**No use case is exempt.** If a UC's engine genuinely has no player-facing seam (a pure
|
|
82
97
|
background job), say so in `wiring_seam` and name the boot/cron/init attachment that starts it — a
|
|
83
|
-
cron registration, a boot hook. "It's internal" is how
|
|
98
|
+
cron registration, a boot hook. "It's internal" is how an engine stays orphaned; there
|
|
84
99
|
is always an attachment to the entry point, or the code never runs.
|
|
85
100
|
|
|
86
101
|
## Anti-rationalization table
|
|
@@ -96,11 +111,18 @@ is always an attachment to the entry point, or the code never runs.
|
|
|
96
111
|
|
|
97
112
|
## Output contract — the WorkResult
|
|
98
113
|
|
|
114
|
+
**Escalation rule.** If you return `status: "escalated"`, the **first** entry in `deviations[]`
|
|
115
|
+
must be the blocker: one specific, answerable question plus the context needed to answer it.
|
|
116
|
+
Nothing else in the envelope carries it — there is no `escalates[]` field — so a vague entry, or
|
|
117
|
+
the question buried under other notes, reaches the human as "something went wrong" and costs a
|
|
118
|
+
round. Write it so someone without your context can answer it in one reply.
|
|
119
|
+
|
|
120
|
+
|
|
99
121
|
`wiring-map.md` in your substrate, then `.shapeup/<slug>/results/<order-suffix>.json`:
|
|
100
|
-
`status`, `artifacts[]` (the wiring map written), `
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
122
|
+
`status`, `artifacts[]` (the wiring map written), `assumptions[]` (engine paths
|
|
123
|
+
inferred from the domain model where the spec was silent), `deviations[]` (a missing profile, a
|
|
124
|
+
UC whose engine the spec never names — the planner's territory — a UC left with an uncertain
|
|
125
|
+
seam, or an engine with no attachment path, and why). You never touch spec docs,
|
|
104
126
|
`scopes/*.md`, `project-profile.md`, task files, or run-state.
|
|
105
127
|
|
|
106
128
|
## Verification checklist
|
|
@@ -110,7 +132,7 @@ uncertain seam, or an engine with no attachment path, and why). You never touch
|
|
|
110
132
|
- [ ] `entry_call_site` is a symbolic composition-root attachment resolved against the profile's `entry_point` — no invented line number, no guessed entry point
|
|
111
133
|
- [ ] `entry_point` echoes the profile — no independently-chosen seam
|
|
112
134
|
- [ ] The profile was READ, not guessed; a missing profile in orchestrated mode → ESCALATE, not an invented entry point
|
|
113
|
-
- [ ] Any UC whose engine has no attachment path is raised in `deviations[]
|
|
135
|
+
- [ ] Any UC whose engine has no attachment path is raised in `deviations[]` (the wiring the build must close), never silently dropped
|
|
114
136
|
- [ ] The WorkResult validates against `work-result.schema.json`
|
|
115
137
|
|
|
116
138
|
## Invocation
|
|
@@ -125,5 +147,5 @@ uncertain seam, or an engine with no attachment path, and why). You never touch
|
|
|
125
147
|
# The reachability oracle is the ORCHESTRATOR's, run advisory at L1b — not part of your craft.
|
|
126
148
|
# Standalone, you MAY preview it after writing the map (it self-skips arms whose artifacts are
|
|
127
149
|
# absent, and is near-vacuous pre-build since the engine code does not exist yet):
|
|
128
|
-
# node "${CLAUDE_PLUGIN_ROOT}/
|
|
150
|
+
# node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" verify trace --slug checkout-vnpay
|
|
129
151
|
```
|
|
@@ -97,6 +97,15 @@ Done-when statements; `_index.md` Non-Go list. Which UCs are in scope comes from
|
|
|
97
97
|
trust a handed hash. A verdict on a scoped spec without a T0 citation is structurally
|
|
98
98
|
invalid, regardless of how convincing your own probing looked; generator prose ("tests
|
|
99
99
|
pass", "verified locally") is never admissible evidence.
|
|
100
|
+
- **When a criterion names a command, run THAT command.** Not the one that works, not the
|
|
101
|
+
equivalent, not the underlying tool the named one wraps. If the named command fails, that is
|
|
102
|
+
the finding — cite it with its exit code and output, and grade the criterion on it. Measured:
|
|
103
|
+
a contract's verification clause named `npm test`, that exact invocation failed on the host's
|
|
104
|
+
Node version, `node --test` passed 45/45, and the report cited the second one. The verdict was
|
|
105
|
+
right about the deliverable and wrong about what it had verified, so a broken entry point
|
|
106
|
+
shipped under a PASS. Substituting a working command for the specified one is the same move as
|
|
107
|
+
accepting generator prose: it replaces the evidence the criterion asked for with evidence that
|
|
108
|
+
was easier to get.
|
|
100
109
|
|
|
101
110
|
---
|
|
102
111
|
|
|
@@ -107,6 +116,7 @@ Done-when statements; `_index.md` Non-Go list. Which UCs are in scope comes from
|
|
|
107
116
|
| "The code clearly implements it, no need to run it" | Apps that look right still break when used. Probe the running app. |
|
|
108
117
|
| "It failed, but the feature mostly works" | One FAIL fails the dimension. Thresholds are hard. |
|
|
109
118
|
| "The generator says tests pass" | Generator prose is not evidence. Your probe or the T0 artifact is. |
|
|
119
|
+
| "`npm test` is broken but `node --test` passes, so the tests pass" | You graded a different criterion. Run the command the contract names; if it fails, that IS the finding. |
|
|
110
120
|
| "This criterion isn't really testable, count it as pass" | Untestable AC = spec defect → surface it; it blocks a clean PASS unless explicitly waived. |
|
|
111
121
|
| "The other dimensions are strong, round up" | Halo effect banned. Dimensions never average. |
|
|
112
122
|
| "The task file's checklist says done" | The checklist is the generator's paraphrase. Grade the committed UC text. |
|
|
@@ -116,6 +126,13 @@ Done-when statements; `_index.md` Non-Go list. Which UCs are in scope comes from
|
|
|
116
126
|
|
|
117
127
|
## Output contract — the WorkResult
|
|
118
128
|
|
|
129
|
+
**Escalation rule.** If you return `status: "escalated"`, the **first** entry in `deviations[]`
|
|
130
|
+
must be the blocker: one specific, answerable question plus the context needed to answer it.
|
|
131
|
+
Nothing else in the envelope carries it — there is no `escalates[]` field — so a vague entry, or
|
|
132
|
+
the question buried under other notes, reaches the human as "something went wrong" and costs a
|
|
133
|
+
round. Write it so someone without your context can answer it in one reply.
|
|
134
|
+
|
|
135
|
+
|
|
119
136
|
1. Write the report `.shapeup/<slug>/evaluation/EVAL-FEATURE-<slug>.md` (or
|
|
120
137
|
`EVAL-<task_id>.md` for a per-task run) per `references/report-schema.md`: verdict,
|
|
121
138
|
per-dimension criteria table with confidence, stability block (flips), bug list (severity,
|
|
@@ -143,10 +160,10 @@ Done-when statements; `_index.md` Non-Go list. Which UCs are in scope comes from
|
|
|
143
160
|
```
|
|
144
161
|
|
|
145
162
|
**Every FAIL criterion's `evidence` MUST carry a `file:line` locator** — schema-enforced, not
|
|
146
|
-
advice:
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
and enforced nowhere; it is now
|
|
163
|
+
advice: the envelope is validated against `work-result.schema.json` at ingest and a locatorless
|
|
164
|
+
FAIL is rejected before any write. A PASS may cite plain output. (Observed, not theorized: a
|
|
165
|
+
correct FAIL verdict with no locator anywhere is unactionable without re-investigating — the
|
|
166
|
+
rule used to live in prose and be enforced nowhere; it is now data in `domain.schema.json`.)
|
|
150
167
|
|
|
151
168
|
The orchestrator's ingest appends the verdict ledger, un-ticks the `refuted` boxes, and sets
|
|
152
169
|
`eval_verdict` frontmatter. You never touch a task file, a board, or run-state — and you
|
|
@@ -184,7 +201,7 @@ bug_template). Adding one (e.g. security) = write `references/dimensions/securit
|
|
|
184
201
|
/spec-evaluator --order .shapeup/checkout-vnpay/orders/evaluate-r2.json
|
|
185
202
|
|
|
186
203
|
# Standalone — the preamble shim compiles a minimal order, then the single code path runs:
|
|
187
|
-
# node "${CLAUDE_PLUGIN_ROOT}/
|
|
204
|
+
# node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" compile --operation evaluate --slug <slug> \
|
|
188
205
|
# --worker spec-evaluator [--payload '{"dimensions": [...], "run_cmd": "..."}']
|
|
189
206
|
/spec-evaluator --spec shapeup/checkout-vnpay/spec/ --task TASK-007
|
|
190
207
|
/spec-evaluator --spec shapeup/checkout-vnpay/spec/ --feature checkout-vnpay --single-pass
|
|
@@ -192,7 +209,7 @@ bug_template). Adding one (e.g. security) = write `references/dimensions/securit
|
|
|
192
209
|
|
|
193
210
|
Standalone keeps `--task` (per-task check, not round-gated) and `--single-pass` (feature-level)
|
|
194
211
|
— the shim maps them onto the order's payload; missing run command → ask. After writing the
|
|
195
|
-
WorkResult, run `node "${CLAUDE_PLUGIN_ROOT}/
|
|
212
|
+
WorkResult, run `node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" reduce ingest <result path>` and show its
|
|
196
213
|
summary — standalone has no orchestrator to ingest for you.
|
|
197
214
|
|
|
198
215
|
---
|
|
@@ -209,5 +226,5 @@ summary — standalone has no orchestrator to ingest for you.
|
|
|
209
226
|
| Probe the RUNNING app, not the source alone | Apps that look right still break when used |
|
|
210
227
|
| Re-probe every FAIL; flip ⇒ confidence low | A single snapshot lies; the ledger makes it visible |
|
|
211
228
|
| Verdict-ledger lines are returned, appended by ingest, never rewritten | Verdict history is how a single-snapshot judge becomes measurable |
|
|
212
|
-
| A verdict on a scoped spec without a T0 citation is structurally invalid | T0 is a machine fact the generator cannot fabricate
|
|
229
|
+
| A verdict on a scoped spec without a T0 citation is structurally invalid | T0 is a machine fact the generator cannot fabricate |
|
|
213
230
|
| UI assertions target affordances only (test_id/role/data-state) | Layer-3 styling is frozen; grading it resurrects the freeze through the judge |
|
|
@@ -9,9 +9,9 @@ command line overrides this table for a single run.
|
|
|
9
9
|
|----|---------|------|----------------------|-------|
|
|
10
10
|
| `spec-conformance` | ✅ true | `dimensions/spec-conformance.md` | all tasks | baseline correctness: AC + Done-when + contract shapes + non-go |
|
|
11
11
|
| `tdd-surface` | ✅ true | `dimensions/tdd-surface.md` | all tasks | suite green + companion test files for new code; TDD-1/2 critical, TDD-3 advisory |
|
|
12
|
-
| `integration` | ✅ true | `dimensions/integration.md` | `.be` and `.e2e` variants only | full-stack integration test +
|
|
12
|
+
| `integration` | ✅ true | `dimensions/integration.md` | `.be` and `.e2e` variants only | full-stack integration test + access boundary + enforcement-path integrity; stack read from the project profile, not hard-coded; runs only when variant matches |
|
|
13
13
|
| `completeness` | ⚙️ auto | `dimensions/completeness.md` | all tasks (lens lite/standard) | auto-ON when spec has UC `## Invariants` (v2.8+); no-op on older specs |
|
|
14
|
-
| `test-surface-conformance` | ⚙️ auto | `dimensions/test-surface-conformance.md` | all tasks (lens lite/standard) | auto-ON when spec has UC `## Test Surface` (v2.9+ or
|
|
14
|
+
| `test-surface-conformance` | ⚙️ auto | `dimensions/test-surface-conformance.md` | all tasks (lens lite/standard) | auto-ON when spec has UC `## Test Surface` (v2.9+ or a retrofit-surface order); no-op otherwise. Report must list every TS row probed — qa-edge-hunter's negative-space input |
|
|
15
15
|
| `security` | ⛔ false | `dimensions/security.md` | be / shared | stub — flip on when ready |
|
|
16
16
|
| `performance` | ⛔ false | `dimensions/performance.md` | be / web | stub — flip on when ready |
|
|
17
17
|
|
|
@@ -25,7 +25,7 @@ criteria?"* — it grades the tasks that exist. It cannot see the task that was
|
|
|
25
25
|
written. Shape Up's discovered-task philosophy says the real bulk of work is found while
|
|
26
26
|
building; an invariant declared on a UC but never backed by a regression task is exactly
|
|
27
27
|
that blind spot. This dimension converts "absence of a task" from invisible into a graded
|
|
28
|
-
**GAP** — the judge surfaces it; the planner (a ba-pitch-analyzer reconcile
|
|
28
|
+
**GAP** — the judge surfaces it; the planner (a ba-pitch-analyzer `reconcile` order) fills it.
|
|
29
29
|
Judge never fills it itself.
|
|
30
30
|
|
|
31
31
|
**Distinction held:** conformance = *the tasks that exist are correct*; completeness =
|