shapeup-sdlc 3.18.2 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.example.json +2 -3
- package/.claude-plugin/plugin.json +1 -1
- package/AGENTS.md +115 -56
- package/README.md +101 -143
- package/SECURITY.md +16 -25
- package/agents/orient.md +14 -0
- package/agents/qa-edge-hunter.md +13 -0
- package/agents/spec-evaluator.md +14 -0
- package/agents/task-executor.md +14 -0
- package/bin/init.mjs +13 -16
- package/bin/lib/grant.mjs +8 -19
- package/commands/build.md +9 -14
- package/commands/eval.md +3 -3
- package/commands/hammer.md +9 -5
- package/commands/retro.md +12 -11
- package/commands/scopes.md +1 -12
- package/commands/ship.md +45 -88
- package/commands/wire.md +1 -8
- package/hooks/dispatch-receipt.mjs +94 -8
- package/hooks/hooks.json +0 -41
- package/hooks/lib/decision.mjs +6 -9
- package/hooks/lib/tier.mjs +50 -0
- package/hooks/sandbox-guard.mjs +140 -64
- package/kernel/gate.mjs +203 -22
- package/kernel/harness.mjs +20 -67
- package/kernel/init/run.mjs +175 -523
- package/kernel/lib/contract.mjs +9 -93
- package/kernel/lib/floor.mjs +64 -0
- package/kernel/lib/paths.mjs +39 -112
- package/kernel/order.mjs +157 -0
- package/kernel/probe/digest.mjs +2 -38
- package/kernel/schemas/domain.schema.json +146 -1125
- package/kernel/schemas/work-order.schema.json +8 -4
- package/kernel/schemas/work-result.schema.json +1 -1
- package/kernel/verify/envelope.mjs +2 -2
- package/kernel/verify/skills.mjs +27 -8
- package/kernel/verify/t0.mjs +2 -2
- package/package.json +4 -2
- package/skills/building/SKILL.md +144 -0
- package/skills/building/resources/gates.md +76 -0
- package/skills/building/resources/guidance.md +23 -0
- package/skills/{translator/references/preservation-rules.md → building/resources/intake-preservation.md} +1 -1
- package/skills/building/resources/intake.md +157 -0
- package/skills/building/resources/orders.md +69 -0
- package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/doc-schemas.md +1 -1
- package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/task-generation.md +13 -13
- package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/test-surface.md +6 -7
- package/skills/building/resources/plan-scopes.md +95 -0
- package/skills/building/resources/plan-spec.md +102 -0
- package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/_index.tmpl.md +1 -1
- package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/assess-report.tmpl.md +10 -11
- package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/run-state.tmpl.md +4 -4
- package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/scope-summary.tmpl.md +2 -2
- package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/synthesis.tmpl.md +4 -4
- package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/usecase.tmpl.md +2 -2
- package/skills/building/resources/plan-wire.md +82 -0
- package/skills/building/resources/plan.md +98 -0
- package/skills/building/resources/retro-research.md +60 -0
- package/skills/building/resources/retro-scan.md +49 -0
- package/skills/building/resources/retro.md +225 -0
- package/skills/building/resources/rounds.md +78 -0
- package/skills/building/resources/stop.md +127 -0
- package/skills/orient/SKILL.md +37 -37
- package/skills/qa-edge-hunter/SKILL.md +29 -14
- package/skills/shapeup/SKILL.md +5 -5
- package/skills/shapeup/resources/breadboarding.md +1 -1
- package/skills/shapeup/resources/context-compaction.md +5 -5
- package/skills/shapeup/resources/shaping.md +1 -1
- package/skills/spec-evaluator/SKILL.md +17 -21
- package/skills/spec-evaluator/references/dimension-contract.md +1 -1
- package/skills/spec-evaluator/references/dimensions/completeness.md +3 -3
- package/skills/spec-evaluator/references/dimensions/spec-conformance.md +1 -1
- package/skills/spec-evaluator/references/dimensions/test-surface-conformance.md +5 -5
- package/skills/task-executor/SKILL.md +11 -15
- package/commands/hill.md +0 -10
- package/hooks/gate-intake.mjs +0 -109
- package/hooks/gate-zerowork.mjs +0 -349
- package/hooks/tier-guard.mjs +0 -162
- package/kernel/compile.mjs +0 -1419
- package/kernel/init/fit.mjs +0 -199
- package/kernel/init/run-args.mjs +0 -206
- package/kernel/lib/breadboard.mjs +0 -165
- package/kernel/probe/attempts.mjs +0 -161
- package/kernel/probe/concurrency.mjs +0 -535
- package/kernel/probe/eval.mjs +0 -405
- package/kernel/probe/hunt.mjs +0 -104
- package/kernel/probe/leg.mjs +0 -229
- package/kernel/probe/owner.mjs +0 -142
- package/kernel/probe/requirements.mjs +0 -328
- package/kernel/probe/resume.mjs +0 -1110
- package/kernel/probe/rounds.mjs +0 -115
- package/kernel/probe/staged.mjs +0 -83
- package/kernel/probe/stats.mjs +0 -477
- package/kernel/probe/t0.mjs +0 -115
- package/kernel/reduce/board.mjs +0 -350
- package/kernel/reduce/graph.mjs +0 -482
- package/kernel/reduce/hill.mjs +0 -322
- package/kernel/reduce/ingest.mjs +0 -767
- package/kernel/reduce/leftovers.mjs +0 -159
- package/kernel/reduce/ship.mjs +0 -529
- package/kernel/reduce/snapshot.mjs +0 -291
- package/kernel/reduce/verdict.mjs +0 -172
- package/kernel/report/export.mjs +0 -384
- package/kernel/report/facts.mjs +0 -234
- package/kernel/verify/budget.mjs +0 -153
- package/kernel/verify/build.mjs +0 -428
- package/kernel/verify/dispatch.mjs +0 -114
- package/kernel/verify/spec.mjs +0 -975
- package/kernel/verify/trace.mjs +0 -604
- package/skills/ba-pitch-analyzer/SKILL.md +0 -204
- package/skills/coach/SKILL.md +0 -397
- package/skills/hill-chart/SKILL.md +0 -154
- package/skills/hill-chart/assets/dashboard.template.html +0 -1432
- package/skills/scope-architect/SKILL.md +0 -174
- package/skills/scope-hammer/SKILL.md +0 -231
- package/skills/solution-architect/SKILL.md +0 -158
- package/skills/tech-lead/SKILL.md +0 -151
- package/skills/tech-lead/references/gates.md +0 -605
- package/skills/tech-lead/references/protocol.md +0 -889
- package/skills/tech-lead/references/tiny-lane.md +0 -53
- package/skills/tech-lead/workflows/shapeup-run.js +0 -2187
- package/skills/translator/SKILL.md +0 -258
- /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/contract-patterns.md +0 -0
- /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/ddd-patterns.md +0 -0
- /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/integration-analysis.md +0 -0
- /package/skills/{ba-pitch-analyzer/references → building/resources/plan-references}/ux-behavior-patterns.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/api-feasibility.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/contracts/be-service.contract.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/contracts/offline-storage.contract.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/contracts/third-party-api.contract.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/context-map.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/event-choreography.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/migration-plan.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/cross-context/team-handoff.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/domain-model.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/feedback.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/integration.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/task-board.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/task-spike.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/task.tmpl.md +0 -0
- /package/skills/{ba-pitch-analyzer/assets/templates → building/resources/plan-templates}/ux-behavior.tmpl.md +0 -0
|
@@ -1,605 +0,0 @@
|
|
|
1
|
-
# Tech-Lead Gate Playbooks
|
|
2
|
-
|
|
3
|
-
The full collect-lists, gate-output blocks, and delegation scripts for every gate and delegation
|
|
4
|
-
step, extracted from `SKILL.md` (progressive disclosure). **Read the relevant section when you
|
|
5
|
-
reach that gate** — `SKILL.md` carries the workflow spine and the hard rules; this file carries the
|
|
6
|
-
step-by-step playbooks. The L2/L4 gates stay hook-enforced regardless of where the prose lives.
|
|
7
|
-
|
|
8
|
-
**Which lane these playbooks serve.** The gate blocks below are lane-independent: every
|
|
9
|
-
lane emits them verbatim, and on the scoped lane `shapeup-run.js` returns the `block` field for
|
|
10
|
-
`SKILL.md` to print unchanged. What differs is who runs the loop *between* the gates:
|
|
11
|
-
|
|
12
|
-
| lane | BUILD → GATE L2 → EVAL is | read |
|
|
13
|
-
|---|---|---|
|
|
14
|
-
| a spec with committed `scopes/*.md` (the common case) | **code** — `skills/tech-lead/workflows/shapeup-run.js`'s round loop | that script's comments |
|
|
15
|
-
| `--tiny`, or a spec with no scope contracts yet | **prose**, unchanged and non-regression | `references/protocol.md` (`:11-22` states the same split) |
|
|
16
|
-
|
|
17
|
-
Order matches the run: GATE L0 → ORIENT → GATE L1a → ANALYZE → WIRE/L1a.5 → MAP SCOPES →
|
|
18
|
-
GATE L1b → (BUILD → GATE L2 → EVAL — see the table above) → GATE L3 → SHIP → GATE L4.
|
|
19
|
-
|
|
20
|
-
⟐ **ANALYZE runs before WIRE.** MAP SCOPES' two dispatches split around
|
|
21
|
-
L1a.5: `analyze` writes the spec tree, then `wire` reads its `usecases/` — one wiring-map entry per
|
|
22
|
-
use case — then `map-scopes` slices. Dispatching WIRE first hands `solution-architect` an empty
|
|
23
|
-
spec folder, which its own input contract excludes (`skills/solution-architect/SKILL.md:43-44`); it
|
|
24
|
-
escalates, writes nothing, and every relaunch re-dispatches it.
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## GATE L0 — Intake & Run Config
|
|
29
|
-
|
|
30
|
-
**Purpose:** Pin everything the run needs once, up front, so the loop never has to guess.
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
Collect (explicit — never inferred):
|
|
34
|
-
L0.1 Kicked-off pitch source: `shaping.md` — and its `breadboard.md`, which the run finds
|
|
35
|
-
beside it (or in `shaping/`) or takes from `--breadboard`; a `pitch.md` may carry the
|
|
36
|
-
breadboard inline. Already shaped + bet by PO.
|
|
37
|
-
Not a raw idea — shaping (1-4) / betting (5) / kick-off (6) are PO-personal, upstream.
|
|
38
|
-
L0.1a Language gate, BEFORE init run: Agent (model: exec) → Skill(shapeup-sdlc-plugin:translator)
|
|
39
|
-
--check over the pitch AND its breadboard.
|
|
40
|
-
English → use both as-is.
|
|
41
|
-
non-English → Agent (model: exec) → Skill(shapeup-sdlc-plugin:translator) <pitch> <breadboard>
|
|
42
|
-
(--auto under auto/unattended), then open the run on the produced
|
|
43
|
-
<name>.en.md — init run prefers a breadboard.en.md beside it, and warns
|
|
44
|
-
when it can find only the untranslated breadboard. The run's intake is
|
|
45
|
-
what every planning worker reads, so a translation made after the run
|
|
46
|
-
opened reaches nobody: re-open with --force naming the .en.md. Log in ledger.
|
|
47
|
-
L0.1b Appetite: read the `appetite` field from the pitch's YAML frontmatter (set by /shapeup).
|
|
48
|
-
Surface it in the gate output. Use it to:
|
|
49
|
-
- Contextualise the scope at L1b (right-size cuts to the budget).
|
|
50
|
-
- Anchor max_rounds suggestion: 1-week → 2 rounds, 2-week → 3, 6-week → 4.
|
|
51
|
-
If appetite is missing or "TBD (uncapped)": flag as a risk and note it in the ledger;
|
|
52
|
-
proceed, but the PO should set scope expectations manually at GATE L1b.
|
|
53
|
-
L0.2 Workspace roots (both keyed off <slug>, set here and threaded to every worker as args):
|
|
54
|
-
- SHARED shapeup/<slug>/ — durable source + deliverable (committed):
|
|
55
|
-
shaping/ (from /shapeup), spec/ (where ba-pitch-analyzer writes the spec tree:
|
|
56
|
-
_index, domain-model, usecases/, contracts/, scopes/, scope-summary.md — NOT tasks/)
|
|
57
|
-
- LOCAL .shapeup/<slug>/ — run-trace (hidden, gitignorable):
|
|
58
|
-
harness-run.md (this ledger), digest, orient/, evaluation/, qa/,
|
|
59
|
-
discovery/ledger.md, orders/ + results/ (the envelope port), tasks/ (the task
|
|
60
|
-
spec_folder = shapeup/<slug>/spec/ (the deliverable arg passed to ba/eval/exec)
|
|
61
|
-
L0.3 lens: lite | standard | cross-context (passed to planner at step 8)
|
|
62
|
-
L0.4 stack hint (e.g. "pnpm, Next 16 web :3000") — aims orient's code-surface sweeps + run commands
|
|
63
|
-
L0.5 eval dimensions: default `auto` — each EVAL order resolves the set from the spec
|
|
64
|
-
(spec-conformance + tdd-surface always; integration for .be/.e2e tasks; completeness
|
|
65
|
-
when a UC has Invariants; test-surface-conformance when one has a Test Surface).
|
|
66
|
-
Name a set only if the user asks. It must reach `harness init run --dimensions <a,b>`
|
|
67
|
-
— it is recorded in the ledger's `eval_dimensions:` line and replaces the resolved
|
|
68
|
-
set, so a set agreed in conversation and not passed to the flag grades nothing. Shipped ids:
|
|
69
|
-
spec-conformance, tdd-surface, integration, completeness, test-surface-conformance
|
|
70
|
-
(security + performance ship disabled). Whatever is left out is reported at L4 as
|
|
71
|
-
`dims_not_evaluated` — "shipped" never silently means "verified for all".
|
|
72
|
-
L0.6 max_rounds: default 3, appetite-informed (see L0.1b)
|
|
73
|
-
L0.7 auto level:
|
|
74
|
-
interactive (default) — pause at every L-gate; sub-skills keep their own gates
|
|
75
|
-
--auto — sub-skills run unattended (--auto); tech lead still pauses
|
|
76
|
-
at L1a/L1b (orient+plan), L3 (verdict), L4 (ship)
|
|
77
|
-
--unattended — auto-confirm all L-gates too; stop only on PASS,
|
|
78
|
-
max_rounds, or hard error (for headless / Agent SDK / CI)
|
|
79
|
-
L0.8 Model & budget resolution (four layers, highest precedence
|
|
80
|
-
first) — resolve ONCE here, record the resulting matrix in the ledger header:
|
|
81
|
-
/ship flags → .claude/settings.local.json (per-member, Tier C) →
|
|
82
|
-
.claude/settings.json (team defaults, committed) → skill-shipped defaults
|
|
83
|
-
Env knobs read at this layer: SHAPEUP_ORCH_MODEL, SHAPEUP_EXEC_MODEL,
|
|
84
|
-
SHAPEUP_EVAL_MODEL, SHAPEUP_QA_MODEL, SHAPEUP_ATTEMPT_BUDGET (default 5),
|
|
85
|
-
SHAPEUP_DIGESTER_MODEL (default "script" — harness probe digest's regex pass; falls
|
|
86
|
-
back to a Sonnet dispatch only when the digester reports unrecognized log formats).
|
|
87
|
-
A requested model unavailable on the member's plan → degrade to the next tier down,
|
|
88
|
-
record the degrade in the ledger (R2 — invariants are code paths, so adherence
|
|
89
|
-
survives even when the model tier doesn't).
|
|
90
|
-
L0.9 attempt_budget: the INNER circuit breaker, nested inside
|
|
91
|
-
max_rounds (the OUTER breaker, unchanged, L0.6). Default 5 — the number of T0 verify
|
|
92
|
-
attempts a single scope gets inside one round before its attempt loop trips and
|
|
93
|
-
queues a hammer PROPOSAL for GATE H rather than blocking the round. Only meaningful
|
|
94
|
-
when the spec folder has scope contracts; a spec with none skips the attempt loop
|
|
95
|
-
entirely and BUILD behaves exactly as in v0.2.6 (task-executor --next, no T0).
|
|
96
|
-
no_progress_k (v1.5): the STAGNATION term of the same inner breaker. Default 2 — the
|
|
97
|
-
number of consecutive non-`kept` trials after which a scope ends early and queues the
|
|
98
|
-
same GATE H proposal. attempt_budget counts ATTEMPTS and cannot see that the last two
|
|
99
|
-
produced nothing; this term can, and on a flailing scope it saves three of five
|
|
100
|
-
attempts. Set per scope (`no_progress_k` on the contract) or per run in the payload.
|
|
101
|
-
L0.10 knowledge base (read, never obeyed): if `shapeup/knowledge-base/tech-lead.md` exists,
|
|
102
|
-
read it now. Its **Workflow guidance** may add a question, a check or a warning line to
|
|
103
|
-
any gate block below and may name the spike to insist on at L1a; its **Suggested run
|
|
104
|
-
config** lines are PROPOSALS for L0.2–L0.9 and the profile — confirm each with the PO
|
|
105
|
-
before pinning it, and record `(source: knowledge-base)` beside a value taken from there.
|
|
106
|
-
Nothing in that file answers a gate: the answer set resolves exactly as it would without
|
|
107
|
-
it, and a line that could only be honoured by skipping, reordering or relaxing a gate is
|
|
108
|
-
reported as a suspected harness defect, not applied. If `shapeup/knowledge-base/` has no
|
|
109
|
-
file at all, offer the optional seed once — `/retro --scan` (the coach's scan operation)
|
|
110
|
-
drafts guidelines from the project on disk, or `/retro --research <stack>` (its
|
|
111
|
-
research operation) from the platform's official documentation when the project has no
|
|
112
|
-
build file to scan; both put every rule through GATE COACH-1 — and continue whether or
|
|
113
|
-
not the PO takes it. A Suggested run config line with `web-research` provenance has
|
|
114
|
-
never run in this project: confirm it like any other, and expect the first round build
|
|
115
|
-
gate to be its first execution.
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
**L0.9b — the launch record.** Every switch the operator typed to *this launch* becomes a `RunArgs`
|
|
119
|
-
field, or it does nothing at all: the workflow cannot read a config file and cannot ask a follow-up,
|
|
120
|
-
so a flag that stops at the skill boundary was accepted and ignored. That is not hypothetical —
|
|
121
|
-
`--no-qa` was documented in seven places across the shipped set and inert in all of them, because no
|
|
122
|
-
line of this protocol ever put `noQa` into the record. `--wall-clock-budget` is the one flag below
|
|
123
|
-
that is not a `RunArgs` field at all — it is consumed earlier, at `init run` itself, and never
|
|
124
|
-
needed to reach this launch; see its row for where it actually lands.
|
|
125
|
-
|
|
126
|
-
| Flag | `RunArgs` field |
|
|
127
|
-
|---|---|
|
|
128
|
-
| `--no-eval` | `noEval: true` |
|
|
129
|
-
| `--no-qa` | `noQa: true` |
|
|
130
|
-
| `--parallel-scopes N` | `maxParallelScopes: N` — how many scopes build at once (default 4; `1` = sequential) |
|
|
131
|
-
| `--adversarial-verify` | `adversarialVerify: true` |
|
|
132
|
-
| `--rounds N` / `--attempts N` | `budgets.{maxRounds,attemptBudget}` |
|
|
133
|
-
| `--gate-answers <set>` | `answers` |
|
|
134
|
-
| `--wall-clock-budget S` | *(not a `RunArgs` field)* — typed once, on the `harness init run` command line itself, not on this launch; it lands straight in the run receipt as `wall_clock_budget_s`, and the deadline breaker reads that receipt field directly — consumed by `kernel/verify/budget.mjs` as `wall_clock_budget_s`. `budgets` declares only `maxRounds`/`attemptBudget` — the schema, `SKILL.md`'s own RunArgs contract line and this script's own header comment all agree there is no third member |
|
|
135
|
-
| `--orch-model/--exec-model/--eval-model/--qa-model` | `models.{…}` (L0.8) |
|
|
136
|
-
|
|
137
|
-
`harness init run-args` (invoked at Step 2 of `SKILL.md`) is the sole writer of the assembled
|
|
138
|
-
object: it takes the resolved values above, writes `.shapeup/<slug>/run-args.json` fresh on every
|
|
139
|
-
launch and relaunch, and prints the same object back so the launch never re-assembles it by hand. It
|
|
140
|
-
is the only artifact that records what a run was configured with; the ship report, a resumed session
|
|
141
|
-
and any later measurement all read it, and none of them can recover a value that only ever existed
|
|
142
|
-
as an argument. Step 2 is not merely advisory: `shapeup-run.js`'s own Preflight refuses to dispatch
|
|
143
|
-
ORIENT (or anything past it) when this file is missing at the run's local root — a launch that
|
|
144
|
-
skipped this step aborts there rather than proceeding on a silent default.
|
|
145
|
-
|
|
146
|
-
**L0.0 — intake precondition (before any other L0 collection):**
|
|
147
|
-
```
|
|
148
|
-
resolve intake from, in order:
|
|
149
|
-
1. --pitch <path> (a shaping/pitch file on disk)
|
|
150
|
-
2. --spec <folder> (an existing spec tree)
|
|
151
|
-
3. <intake> requirement text passed to the skill
|
|
152
|
-
none resolvable -> ABORT. Print the ✋ NO INTAKE block from SKILL.md and stop.
|
|
153
|
-
Do NOT emit the GATE L0 block. Do NOT list downstream gates.
|
|
154
|
-
Do NOT describe the pipeline that "will" run.
|
|
155
|
-
```
|
|
156
|
-
An orchestrator with no spec has nothing to orchestrate. Narrating the gate list in that state
|
|
157
|
-
produces output that reads exactly like a successful run and contains no work. Fail loudly instead.
|
|
158
|
-
|
|
159
|
-
**GATE L0 Output:**
|
|
160
|
-
```
|
|
161
|
-
⏸ GATE L0 — Intake & Run Config
|
|
162
|
-
Feature : [slug] (kicked-off pitch: [path])
|
|
163
|
-
Intake lang : [English | translated via /translator → <name>.en.md]
|
|
164
|
-
Appetite : [~1 week | ~2 weeks | ~6 weeks | ⚠️ missing — scope uncapped]
|
|
165
|
-
Spec folder : [path] (lens: [lite|standard])
|
|
166
|
-
Eval dims : [auto | the named set] max_rounds: [N, appetite-informed] auto: [interactive|auto|unattended]
|
|
167
|
-
Run commands : [web: ... | api: ... | mobile: ...] (run_cmd → the round build gate, every round before EVAL)
|
|
168
|
-
Build gate : build_probe [set | —] launch_probe [set | — ⚠ mobile: the install/launch risk has no owner]
|
|
169
|
-
Model matrix : orch=[model] exec=[model] eval=[model] qa=[model] digester=[script|sonnet] (source: [flags|settings.local|settings.json|default])
|
|
170
|
-
Budgets : round_budget=[N] (outer) attempt_budget=[N] (inner, per scope)
|
|
171
|
-
Knowledge : [tech-lead.md — N workflow rules, M suggested values (confirmed above) | none — `/retro --scan` or `/retro --research <stack>` seeds it (optional)]
|
|
172
|
-
```
|
|
173
|
-
**Resolve it** — this gate is this skill's own (the workflow never sees it), so it is this skill
|
|
174
|
-
that runs the same tool every other gate resolves through, not a paragraph read as a stand-in for
|
|
175
|
-
one: `node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" gate --resolve L0 --slug <slug>
|
|
176
|
-
[--file <path>|--preset <name>]`. Exit 4 (`ask`) is the confirmation this block already asks for —
|
|
177
|
-
put it to the PO and wait, same as the paragraph above always meant. Exit 0 (`decision=proceed`) —
|
|
178
|
-
continue straight to ORIENT, which is what `--unattended`'s pre-answered set resolves to. Exit 5
|
|
179
|
-
(`abort`) — stop; do not launch. Either way, the gate's own ledger row is what lets a later reader
|
|
180
|
-
see the decision that opened the run, not only the decisions that closed it.
|
|
181
|
-
|
|
182
|
-
---
|
|
183
|
-
|
|
184
|
-
## ORIENT (step 7) — delegate to orient (the Scout)
|
|
185
|
-
|
|
186
|
-
The Shape Up Building phase opens with **Orient, not planning**: the team reads the real code
|
|
187
|
-
and spikes the scary parts *before* any board exists, so the board comes out reality-born.
|
|
188
|
-
|
|
189
|
-
```
|
|
190
|
-
Invoke via Agent (model: exec — see references/protocol.md "Invocation mechanism"):
|
|
191
|
-
Skill(shapeup-sdlc-plugin:orient) --pitch <intake> --spec <path> --stack "<hint>" [--auto]
|
|
192
|
-
Owns: its own GATE O-A/O-B; runs straight through under --auto.
|
|
193
|
-
Writes: .shapeup/<slug>/orient/ → code-surface.md, spike-<area>.md, discovered-seed.md, hill-signal.md.
|
|
194
|
-
Record in ledger: orient duration + the spiked area + spike result (resolved | SPIKE-UNRESOLVED).
|
|
195
|
-
```
|
|
196
|
-
The four artifacts are the **orient → ba contract**: `ba` (step 8) consumes them instead of
|
|
197
|
-
re-scanning the codebase. Pass `--auto` only when the run level is `--auto`/`--unattended`.
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
## GATE L1a — Orient Review
|
|
202
|
-
|
|
203
|
-
**Purpose:** PO sees where the pitch lands in real code and what's still unknown — *before*
|
|
204
|
-
committing to a scope map. This is the first Hill read (area-level — slices don't exist yet).
|
|
205
|
-
|
|
206
|
-
```
|
|
207
|
-
Read .shapeup/<slug>/orient/. Render the 🗻 Hill from hill-signal.md (see protocol.md "Hill report"):
|
|
208
|
-
- each suspected area → uphill (open unknowns) | crest (approach proven by the spike) | downhill
|
|
209
|
-
Print: `Breadboard: <source> | none` (how init run found the pitch's breadboard — flag, sibling,
|
|
210
|
-
shaping-dir, shared-root, embedded — or none), the code-surface headline (where it lands),
|
|
211
|
-
the spiked area + result, the riskiest open unknowns going into mapping.
|
|
212
|
-
Ask (max 2): is the riskiest area the right one to have spiked? any unknown that must be
|
|
213
|
-
resolved (another spike) before we map scopes?
|
|
214
|
-
```
|
|
215
|
-
Do NOT enter MAP SCOPES until Orient is accepted.
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## WIRE (step 7.5) + traceability spine ✚ — delegate to solution-architect
|
|
220
|
-
|
|
221
|
-
**Active only when the spine is in use** — on a legacy spec skip it; `trace-lint` self-skips every arm whose artifact is absent (non-regression).
|
|
222
|
-
|
|
223
|
-
```
|
|
224
|
-
1. PROFILE (you write it at L0 — compile-order stays pipeline-blind): SHARED project-profile.md
|
|
225
|
-
= {schema_version:1, archetype, entry_point, source_extensions?, build_probe?, launch_probe?}.
|
|
226
|
-
archetype ∈ {client-only-game|web-service|mobile|library|data-pipeline}; entry_point is the
|
|
227
|
-
reachability seam (a game's main.js is NOT a service's src/server.ts). Validate the enum — a
|
|
228
|
-
typo must fail, not silently disable the check. entry_point is also the root reachability walks
|
|
229
|
-
the import graph from, so where some module does compose the app, name that one rather than the
|
|
230
|
-
file the platform happens to start. Where the screens are registered in a MANIFEST instead (a
|
|
231
|
-
route map, a plugin table, a string-loaded page), no entry point roots an import walk at all —
|
|
232
|
-
measured on a real ArkTS app, where the navigation host imports nothing and every screen arrives
|
|
233
|
-
through route_map.json. The arm then reports that it could not check, and that is the correct
|
|
234
|
-
end state for such a project rather than a profile to keep re-declaring.
|
|
235
|
-
source_extensions is optional and only needed when the project's modules end in something the
|
|
236
|
-
entry point does not (e.g. [".ets"] when the entry is a .ts file); leaving it out costs a
|
|
237
|
-
skipped arm, never a false red. The two probes feed the round build gate (`harness verify
|
|
238
|
-
build`, every round before EVAL): build_probe asserts the BUILT ARTIFACT covers what the run
|
|
239
|
-
wrote (a green exit code is not proof the feature compiled when the toolchain compiles only what
|
|
240
|
-
an entry point reaches); launch_probe installs, starts and asserts the first screen. A `mobile`
|
|
241
|
-
profile without a launch_probe is warned about every round — nothing else in the loop launches
|
|
242
|
-
the app.
|
|
243
|
-
2. WIRE — compile-order --operation wire --slug <slug> (worker→solution-architect), payload
|
|
244
|
-
{project_profile, breadboard?}. Sole writer of committed wiring-map.md (per-UC engine → seam → entry-point
|
|
245
|
-
call site → affordance). ⏸ GATE L1a.5: confirm each UC has a declared seam before slicing.
|
|
246
|
-
⟐ PRECONDITION: MAP SCOPES step 1 (ANALYZE) has already run and usecases/ is
|
|
247
|
-
populated. WIRE writes one entry per use case, so dispatching it against an empty spec folder
|
|
248
|
-
is an escalation, not a wiring map — and a phase that writes no artifact is re-dispatched on
|
|
249
|
-
every relaunch. Verify: node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" probe resume
|
|
250
|
-
--slug <slug> --require analyze (exit 0 = the spec tree is there; exit 6 = do not dispatch WIRE).
|
|
251
|
-
Post-check the same way after the dispatch: --require wire.
|
|
252
|
-
requirements.md registry (atomic REQ clauses, frozen ids).
|
|
253
|
-
4. trace-lint — node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" verify trace --slug <slug>. ADVISORY at L1b:
|
|
254
|
-
covers-closure (every covered REQ named by ≥1 AC's covers:) + reachability (every UC engine
|
|
255
|
-
reaches entry_point). Promote to --gate only once covers: is populated. Reachability reports
|
|
256
|
-
checked:false with a reason rather than a verdict in two cases, both warns: an import it could
|
|
257
|
-
not follow (the graph is incomplete) and no engine reachable at all (nothing controls the walk,
|
|
258
|
-
so an orphan and a wrong root look identical). Read either as "re-declare the profile", never
|
|
259
|
-
as a clean arm. When it does run it also reports, per scope, how many of that scope's own source
|
|
260
|
-
files the app reaches, and warns (SCOPE-UNREACHABLE) on a scope it reaches none of — a scope's
|
|
261
|
-
build fixture can be green while its code never compiles, on any toolchain that compiles only
|
|
262
|
-
what the entry point reaches. Warn only: the wiring may be a later scope's job by design.
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
---
|
|
266
|
-
|
|
267
|
-
## MAP SCOPES (step 8) — delegate to ba-pitch-analyzer (orient-informed)
|
|
268
|
-
|
|
269
|
-
⟐ **Step 1 runs BEFORE the WIRE section above; step 2 runs after it.** The two
|
|
270
|
-
dispatches sit either side of L1a.5: ANALYZE writes the use cases WIRE reads, and MAP SCOPES slices
|
|
271
|
-
against the seams WIRE declared. Sequence: ORIENT → L1a → **ANALYZE** → **WIRE** → L1a.5 →
|
|
272
|
-
**MAP SCOPES** → L1b.
|
|
273
|
-
|
|
274
|
-
```
|
|
275
|
-
Two orders, two workers, one step (both model: exec — see references/protocol.md):
|
|
276
|
-
1. ANALYZE + BOARD — compile-order --operation analyze --slug <slug> --worker ba-pitch-analyzer
|
|
277
|
-
--payload '{"pitch": "<path>", "breadboard": "<the path init run printed, when it printed one>", "lens": "<lens>", "orient_dir": ".shapeup/<slug>/orient/"}'
|
|
278
|
-
dispatch: Skill(shapeup-sdlc-plugin:ba-pitch-analyzer) --order <path>. The order hands it
|
|
279
|
-
code-surface.md (Phase-1 ingest consumes the map, does not re-scan), discovered-seed.md
|
|
280
|
-
(task gen starts from reality), spike-<area>.md (feasibility/contracts).
|
|
281
|
-
Output expected: spec_folder populated with _index, domain-model, usecases/, contracts/,
|
|
282
|
-
scope-summary.md (all SHARED/committed) + tasks/TASK-NNN*.md, tasks/_index.md (board)
|
|
283
|
-
written to the LOCAL root .shapeup/<slug>/tasks/ (v3.2) + a WorkResult → ingest.
|
|
284
|
-
2. MAP SCOPES — compile-order --operation map-scopes --slug <slug> --worker scope-architect
|
|
285
|
-
dispatch: Skill(shapeup-sdlc-plugin:scope-architect) --order <path>. Sole writer of the
|
|
286
|
-
committed scopes/<scope-id>.md contracts (import-graph slicing, substrate whitelists,
|
|
287
|
-
affordance manifest, fixtures, PA1/PA2 — mechanically linted by harness verify spec).
|
|
288
|
-
Record in ledger: planner duration + task count + scope count.
|
|
289
|
-
```
|
|
290
|
-
Faithful note: keep the planner ambitious on scope but high-level on tech — do not push it
|
|
291
|
-
to over-specify implementation. Errors baked into the spec cascade into every build round.
|
|
292
|
-
Honest deviation: `ba` is heavier than Shape Up's light "map scopes" bucketing — that extra
|
|
293
|
-
upfront spec-traceability is a deliberate trade for an LLM builder, not
|
|
294
|
-
"pure Shape Up". State it; don't pretend otherwise.
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
## GATE L1b — Board Review (Plan Acceptance)
|
|
299
|
-
|
|
300
|
-
**Purpose:** PO sees the shape of the work before a single line of code. This is where scope
|
|
301
|
-
is cut or confirmed — cheap here, expensive later.
|
|
302
|
-
|
|
303
|
-
**v3.2 (local-tasks-architecture):** on a spec with
|
|
304
|
-
scope contracts, the PO reviews the SHARED, committed plan — `usecases/_index.md` +
|
|
305
|
-
`scopes/*.md` + `scope-summary.md`'s Done-when headlines — never the LOCAL task board
|
|
306
|
-
(`tasks/_index.md`, gitignored, per-machine run-trace). Implementation-level task detail stays
|
|
307
|
-
hidden at this gate by design; the PO signs off on the UCs covered and how they're cut into
|
|
308
|
-
scopes, not a line-by-line task list. A pre-v0.3.0 spec (no scope contracts) has no scope
|
|
309
|
-
board to substitute for — this gate still reads `tasks/_index.md` directly, unchanged from
|
|
310
|
-
v0.2.6 (non-regression).
|
|
311
|
-
|
|
312
|
-
**Bootstrap check (local tasks board) — run BEFORE the read below, always:**
|
|
313
|
-
```
|
|
314
|
-
`.shapeup/<slug>/tasks/_index.md` missing AND `shapeup/<slug>/spec/usecases/`
|
|
315
|
-
exists → a teammate (or a `--from build` resumed run) has the SHARED spec via git but no LOCAL
|
|
316
|
-
task board on this machine — `.shapeup/` is gitignored and never travels with a branch.
|
|
317
|
-
Agent (model: exec): Skill(shapeup-sdlc-plugin:ba-pitch-analyzer) --order <path> + ingest —
|
|
318
|
-
regenerates the board from the committed usecases/domain-model/scopes. Record the bootstrap in
|
|
319
|
-
the ledger. No-op on a fresh r=1 run (MAP SCOPES just wrote the board on this same machine) or
|
|
320
|
-
any machine that already has one — this only fires for the second-developer / resumed-run case.
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
```
|
|
324
|
-
Scope contracts present:
|
|
325
|
-
Read usecases/_index.md + scopes/*.md (scope-board.md) + scope-summary.md. Print:
|
|
326
|
-
- UC count + actors (usecases/_index.md)
|
|
327
|
-
- scope board: scope_id, topology_type, substrate file count (scopes/*.md / scope-board.md)
|
|
328
|
-
- any SPIKE blockers (scope-summary.md)
|
|
329
|
-
- scope-summary "Done when" headline statements
|
|
330
|
-
- the Deferred Places from ux-behavior.md (breadboard Places this shape will not build) —
|
|
331
|
-
each one needs the PO's yes; a rejected deferral goes back to the planner as a screen
|
|
332
|
-
- the REQ → AC table from requirements.md, one row per registered requirement: REQ-id, the
|
|
333
|
-
source clause it came from (`REQ-12 ← shaping.md R12`), and the acceptance criterion that
|
|
334
|
-
grades it — or the scope that claims it, or CUT (PO-approved). Omitted entirely when the run
|
|
335
|
-
has no registry. A requirement with none of the three is already a red below; this table is
|
|
336
|
-
what the PO reads to answer it — cover it, or cut it on the record. Printed, never asked:
|
|
337
|
-
the table decides nothing at this gate
|
|
338
|
-
No scope contracts (pre-v0.3.0, unchanged from v0.2.6):
|
|
339
|
-
Read tasks/_index.md (LOCAL root). Print:
|
|
340
|
-
- task count by package/variant (.shared / .be / .web / .mobile / .e2e)
|
|
341
|
-
- layer distribution (Layer 1→6) and the critical dependency path
|
|
342
|
-
- any SPIKE tasks (third-party feasibility) that block others
|
|
343
|
-
- scope-summary "Done when" headline statements
|
|
344
|
-
|
|
345
|
-
Substrate-disjointness assertion (only when
|
|
346
|
-
shapeup/<slug>/scopes/*.md exist — scope-architect's lint pass already ran;
|
|
347
|
-
this is the orchestrator's own re-confirmation before committing to a build sequence):
|
|
348
|
-
- Run `node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" verify spec --slug <slug>`: DISJOINT (a file in two
|
|
349
|
-
scopes' `allowed_file_substrate` without BOTH declaring it `shared_substrate` — PA3
|
|
350
|
-
waiting to happen), PA1 (directory-aligned scope), PA2 (size cap), SCOPE-ANCHOR (a scope
|
|
351
|
-
naming no committed use case, or one that does not resolve), TIER-DIRECTION (a committed
|
|
352
|
-
contract naming LOCAL task ids), SCOPE-DEPS (a build-order id naming a scope that is not
|
|
353
|
-
in this run), REQ-UNCOVERED (a requirement in requirements.md that no acceptance criterion
|
|
354
|
-
grades and no scope claims — the PO's two ways out are an AC carrying `(covers: REQ-…)` or
|
|
355
|
-
`CUT (PO-approved)` in the registry; silent on a run with no registry),
|
|
356
|
-
CONTRACT-SCHEMA (a scope contract that parses but not into the shape a WorkOrder carries —
|
|
357
|
-
most often a list written bare in a table cell where the dialect wants `[a, b]`; without
|
|
358
|
-
this the compiler refuses the order later and the scope is never dispatched at all, with
|
|
359
|
-
the board green and the leg reporting done), CONTRACT-UNREADABLE (a table the parser could
|
|
360
|
-
not see, or a table field also declared in frontmatter where nothing reads it),
|
|
361
|
-
BREADBOARD-PLACE (a breadboard Place with UI affordances has no
|
|
362
|
-
`## Screen: … (P#)` in ux-behavior.md and is not deferred), BREADBOARD-UI (a U# not
|
|
363
|
-
specified on a screen of its own Place). Any red → HARD STOP, past a 🔴 at the
|
|
364
|
-
architect's own checkpoint. The breadboard reds are the planner's to fix — add the screen
|
|
365
|
-
or defer the Place; never fold it into another screen.
|
|
366
|
-
- Lock the build SEQUENCE riskiest-first: order scopes by open-unknowns count (from
|
|
367
|
-
hill/<scope-id>.yml if present, else the orient hill signal), not by file count or
|
|
368
|
-
alphabetical — Shape Up's "solve in the right sequence" (step 10).
|
|
369
|
-
DEPENDENCIES CONSTRAIN THAT ORDER, and each contract declares its own: scope A follows scope
|
|
370
|
-
B when A names B in `depends_on`. The order lives in the same committed tier as the contracts
|
|
371
|
-
it orders, so it survives a clone. Risk orders the scopes; the dependencies decide when each one is
|
|
372
|
-
RELEASED — a scope starts as soon as the scopes it consumes have settled, not when its whole
|
|
373
|
-
level has, so a scope may well start while a sibling is still building. A scope that consumes
|
|
374
|
-
the others' output (an entry point wiring up command modules) therefore cannot be scheduled
|
|
375
|
-
alongside them however low its unknowns count. It fails open: a contract declaring no
|
|
376
|
-
`depends_on`, or naming a scope that is not in this run, falls back to releasing a level at a
|
|
377
|
-
time, and then to no constraint at all (spec-lint SCOPE-DEPS reports the dangling id).
|
|
378
|
-
|
|
379
|
-
Ask (max 2): scope cuts? lens correct? any SPIKE to resolve before build?
|
|
380
|
-
Scope-hammer framing: reference the appetite from the pitch
|
|
381
|
-
(e.g. "Given a ~1-week appetite, which of these scopes feels right-sized?").
|
|
382
|
-
Also surface any rabbit holes identified in the pitch — they flag where scope
|
|
383
|
-
may expand unexpectedly if not cut now. A scope cut here is cheap; after
|
|
384
|
-
BUILD round 1 it's expensive.
|
|
385
|
-
```
|
|
386
|
-
Do NOT enter BUILD until the board is accepted.
|
|
387
|
-
|
|
388
|
-
---
|
|
389
|
-
|
|
390
|
-
## GATE L2 — Board 100% Done (Pre-Eval)
|
|
391
|
-
|
|
392
|
-
**Purpose:** The single exit point from the BUILD loop into EVAL. It ensures every scope is green before invoking the evaluator.
|
|
393
|
-
|
|
394
|
-
**Output:**
|
|
395
|
-
```
|
|
396
|
-
⏸ GATE L2 — Board 100% ✅ + T0-green
|
|
397
|
-
Feature : [slug]
|
|
398
|
-
Round : [r]
|
|
399
|
-
Scopes : [N] green, [M] queued for hammer
|
|
400
|
-
Build gate: [green | red — <failing step> | undeclared]
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
The build gate is `harness verify build --slug <slug> --round <r>` — the ledger's `run_cmd`, then
|
|
404
|
-
the profile's `build_probe` and `launch_probe`, stopping at the first failure. It runs before this
|
|
405
|
-
gate so the block shows it; `red` means EVAL is NOT dispatched this round (the judge grades a running
|
|
406
|
-
feature) and the failing step is compiled into round r+1's orders as `payload.bugs`. `undeclared`
|
|
407
|
-
means L0 pinned no run command and the profile names no probe — the round proceeds over an
|
|
408
|
-
unproven build, and the block says so.
|
|
409
|
-
|
|
410
|
-
Under `--interactive` / `--auto`, the gate block carries the board facts — `green_scopes`, `hammer_proposals` — and requires explicit PO approval to proceed. Under `--unattended` the answer set resolves it. **There is no hook behind this gate**: the `PreToolUse` warning it used to carry was retired into the block in v2.0, so what an unfinished board costs you here is a human reading the numbers, not a machine refusing the call.
|
|
411
|
-
|
|
412
|
-
---
|
|
413
|
-
|
|
414
|
-
## GATE L3 — Verdict & Loop
|
|
415
|
-
|
|
416
|
-
```
|
|
417
|
-
Render the 🗻 Hill report (slice-level) — NOT a task count. Scope contracts present → read
|
|
418
|
-
committed hill/<scope-id>.yml shards (mechanical phases from GATE L2, never authored). No contracts →
|
|
419
|
-
fall back to the board + open-unknowns heuristic (uphill/crest/downhill/done). See
|
|
420
|
-
references/protocol.md "Hill report". Roadmap rule unchanged either way: progress is
|
|
421
|
-
reported by hill position, never by "N/M tasks done".
|
|
422
|
-
|
|
423
|
-
Read EVAL-FEATURE-<slug>.md verdict.
|
|
424
|
-
|
|
425
|
-
PASS:
|
|
426
|
-
→ first PASS of the run AND not --no-qa:
|
|
427
|
-
delegate ▶ QA EDGE HUNT → Agent (model: qa — see references/protocol.md
|
|
428
|
-
"Invocation mechanism"): Skill(shapeup-sdlc-plugin:qa-edge-hunter) (pure worker; see
|
|
429
|
-
round-protocol "QA edge hunt"). Args: spec folder, EVAL report path, ledger path, app URL.
|
|
430
|
-
Its GATE Q0/Q1 pauses surface here. Output: `~` findings → .shapeup/<slug>/discovery/ledger.md
|
|
431
|
-
+ .shapeup/<slug>/qa/hunt-report.md. No verdict — the run's verdict stays this EVAL's PASS.
|
|
432
|
-
→ then proceed to SHIP (triage of QA findings happens at SHIP S.0/GATE L4).
|
|
433
|
-
→ subsequent PASS (a promoted-findings fix round): Agent (model: qa):
|
|
434
|
-
→ --no-qa or skill absent: proceed straight to SHIP; ledger records `qa: skipped`.
|
|
435
|
-
|
|
436
|
-
FAIL:
|
|
437
|
-
→ a round whose build gate was red never reached the judge: the block carries `build_gate: red`,
|
|
438
|
-
the "bug list" is the gate's failing step (its command, exit and output tail), and round r+1
|
|
439
|
-
is a fix round over exactly that. Nothing the evaluator would have said is missing — it was
|
|
440
|
-
never asked.
|
|
441
|
-
→ print the bug list grouped by task/severity. For each bug: task ID + failed Done-when criterion + repro.
|
|
442
|
-
DO NOT prescribe fix options or root cause hypotheses — that is the implementer's job.
|
|
443
|
-
The tech lead names scope; the implementer diagnoses and fixes.
|
|
444
|
-
→ ask (max 1): approve fixing these in BUILD round r+1? (or cut scope / waive a bug)
|
|
445
|
-
→ if r+1 > max_rounds: STOP. Escalate to PO with the residual bug list — do not loop
|
|
446
|
-
forever. The harness reports honestly that it hit its round budget.
|
|
447
|
-
→ else: go to BUILD round r+1 (bug-only).
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
**GATE L3 Output:**
|
|
451
|
-
```
|
|
452
|
-
⏸ GATE L3 — Verdict (round [r])
|
|
453
|
-
🗻 Hill : S1-spine 🔽 downhill · S2-filters ⛰️ crest · S3-export 🔼 uphill
|
|
454
|
-
Verdict : [PASS | FAIL] bugs: [N] (rounds used: [r]/[max])
|
|
455
|
-
Decision : [SHIP | re-build bugs in round r+1 | escalate: max rounds hit]
|
|
456
|
-
```
|
|
457
|
-
The Hill is the progress narrative; the board's `N/N ✅` is execution substrate (it gates
|
|
458
|
-
EVAL at L2), never the headline. Slices come from `ba`'s board; if slice IDs aren't present
|
|
459
|
-
yet, report at task-group level and note the fallback in the ledger.
|
|
460
|
-
|
|
461
|
-
---
|
|
462
|
-
|
|
463
|
-
## SHIP (step 11) — close out
|
|
464
|
-
|
|
465
|
-
```
|
|
466
|
-
S.0 GATE H — delegate to scope-hammer (this IS Shape Up's "Decide When to Stop", step 11):
|
|
467
|
-
Invoke via Agent (model: exec — see references/protocol.md "Invocation mechanism"):
|
|
468
|
-
Skill(shapeup-sdlc-plugin:scope-hammer) --slug <slug> --baseline <shaping/baseline.md if present>
|
|
469
|
-
[--breaker outer] when round_budget hit 0 with scopes still open
|
|
470
|
-
[--breaker inner --scope <id>] once per queued hammer proposal (attempt_budget
|
|
471
|
-
exhausted scopes accumulated during BUILD)
|
|
472
|
-
(no --breaker flag) normal stop — all scopes FINISHED, post-QA-hunt
|
|
473
|
-
Feeds it: qa/hunt-report.md findings (when present), discovery/ledger.md open items,
|
|
474
|
-
the hammer-proposal queue from BUILD (attempt-budget exhaustions).
|
|
475
|
-
Ownership facts in its census — "no scope owns X", "X belongs to scope Y" — come from
|
|
476
|
-
node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" probe owner --slug <slug> [--path <p>]...
|
|
477
|
-
which elects the owner from the committed contracts' substrates, never from prose.
|
|
478
|
-
Reads back: its GATE H0/H1/H2 output — census, baseline comparison, cut list + verdict.
|
|
479
|
-
Authority: scope-hammer proposes; the tech lead records the PO's decision in
|
|
480
|
-
round-ledger.md and performs the actual close (S.1 onward). It never ships on its own.
|
|
481
|
-
- Cut list confirmed → all cuts carried to discovery/ledger.md as raw ideas (debt-free).
|
|
482
|
-
- Verdict = CANNOT SHIP (a must-have item failed H1.2) → do NOT proceed to S.1; escalate
|
|
483
|
-
to PO honestly with scope-hammer's ship-blocking list, same spirit as a max-rounds
|
|
484
|
-
escalation.
|
|
485
|
-
Pre-v0.3.0 spec (no scope contracts) → scope-hammer still runs; H0's only census sources
|
|
486
|
-
are QA + discovery ledger (no scope/attempt-budget inputs), equivalent to the old inline
|
|
487
|
-
triage this step used to do.
|
|
488
|
-
S.1 Confirm board green + latest eval verdict = PASS.
|
|
489
|
-
S.1b Checklist-hygiene assert: `grep -c "^- \[ \]" .shapeup/<slug>/tasks/TASK-*.md` →
|
|
490
|
-
every count must be 0 on a shipping board. An unchecked AC box on a done task means
|
|
491
|
-
either an unverified criterion (real gap — back to BUILD/EVAL) or an ingest miss (the
|
|
492
|
-
WorkResult's ac_results never covered it — re-run ingest-result on that result, or route
|
|
493
|
-
back to the owning worker for a corrected result; the tech lead does not tick boxes
|
|
494
|
-
itself). Do not SHIP past a non-zero count without logging the reason in the ledger.
|
|
495
|
-
S.2 Print a feature summary: tasks shipped, rounds used, final verdict, dims evaluated
|
|
496
|
-
(and explicitly: dims NOT evaluated, so "shipped" is never read as "verified for all").
|
|
497
|
-
S.3 Point to the traceability: tasks/_index.md (all ✅) + EVAL-FEATURE-<slug>.md (PASS) +
|
|
498
|
-
harness-run.md (the round ledger).
|
|
499
|
-
S.4 task-executor's own verification checklist remains the formal per-task close; the tech
|
|
500
|
-
lead confirms the feature-level close.
|
|
501
|
-
S.5 Deploy truth — "done means deployed", honestly. Building stops at "built & verified";
|
|
502
|
-
deployment is an outward-facing action gated to the PO. Either:
|
|
503
|
-
- PO says yes → run the project's own deploy procedure and record "deployed".
|
|
504
|
-
- otherwise → record "built & verified — deploy pending (PO)".
|
|
505
|
-
NEVER auto-deploy; "shipped" must never silently mean "deployed".
|
|
506
|
-
(Baseline-anchored scope-hammering at ship time is deliberately deferred; for now,
|
|
507
|
-
`ba`'s Appetite Guard covers overflow and cuts go to synthesis "Hammered Out".)
|
|
508
|
-
S.6 Harvest one signal row → append to `.shapeup/metrics/<machine-id>.jsonl`
|
|
509
|
-
(LOCAL root, gitignored since ADR-0001 — a committed shard keyed on a hostname only
|
|
510
|
-
grows and publishes a machine name; sharded per machine so shards can be pooled
|
|
511
|
-
deliberately without colliding on one filename. The read plane is
|
|
512
|
-
`harness probe stats`, or `cat .shapeup/metrics/*.jsonl`).
|
|
513
|
-
Copy fields that ALREADY exist as structured output (run-state, final EVAL report,
|
|
514
|
-
discovery ledger, qa/hunt-report, and the receipt's `breadboard.ids.V` for `slice_count` —
|
|
515
|
-
the slices init run counted in the staged breadboard, never a hand copy). Two hard rules:
|
|
516
|
-
1. Harvest only fields that already exist at ship time — never evaluate something new.
|
|
517
|
-
2. Record facts, never compute a new verdict (no `run_quality_score` — that would be
|
|
518
|
-
a second judge behind spec-evaluator). The eval suite interprets; harvest records.
|
|
519
|
-
`final_audit_score` is COPIED from the EVAL report, never re-graded.
|
|
520
|
-
ALSO copy two run-quality measurements, both produced by scripts at zero model tokens:
|
|
521
|
-
node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" probe stats --ratchet --slug <slug>
|
|
522
|
-
→ `ratchet`: {trials, scopes_multi_trial, improvement_rate, monotone_rate,
|
|
523
|
-
sawtooth_count, mean_trials_to_green}
|
|
524
|
-
node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" probe stats --hooks
|
|
525
|
-
→ `hooks`: {evaluations, denials, errors, per_hook}
|
|
526
|
-
Harvest them HERE or lose them: both read per-run working ledgers (t0/trials.jsonl,
|
|
527
|
-
decisions.jsonl) that the next run's bookkeeping supersedes, so a number left there
|
|
528
|
-
answers its question exactly once. The metrics shard is the one record that
|
|
529
|
-
accumulates across runs — and neither measurement is meaningful from a single run.
|
|
530
|
-
ALSO copy `run_id` from `receipt.json`. It is the row's only link to the run trace
|
|
531
|
-
that produced it: every other field here is a count, and `feature_slug` groups runs
|
|
532
|
-
TOGETHER rather than apart. It is what joins this row to the S.7 export.
|
|
533
|
-
→ full field list + row template: references/protocol.md "Harvest row".
|
|
534
|
-
S.7 Export the run's records → one keyed dataset, before the trace is superseded.
|
|
535
|
-
node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" report export --slug <slug>
|
|
536
|
-
Same argument as S.6, applied to the records the harvest row does NOT carry: orders,
|
|
537
|
-
results, T0 verdicts, trial rows, criterion verdicts and this run's hook decisions all
|
|
538
|
-
live in the LOCAL tier, which is regenerable and gets wiped.
|
|
539
|
-
The export freezes them as fact tables under `.shapeup/exports/<run_id>/` (JSONL, one
|
|
540
|
-
object per line), keyed by run id so a second run of the same feature is a second
|
|
541
|
-
dataset rather than an overwrite. `--out <dir>` sends it somewhere durable instead.
|
|
542
|
-
It is READ-ONLY: it writes nothing into the trace, so it may be re-run at any time.
|
|
543
|
-
NOT COST/WALL-CLOCK. This harness carries no run-economics record — the design once
|
|
544
|
-
called for one derived from a per-agent-call journal, but nothing in the pipeline ever
|
|
545
|
-
wrote that journal, so the derivation and its reporting command were removed rather than
|
|
546
|
-
left presenting nulls as measurements. Even a real cost record would not belong in the
|
|
547
|
-
harvest row's schema either way — that row's contract rejects clock fields on purpose
|
|
548
|
-
(see protocol.md "Rejected fields"), because a signal feed that carried a duration would
|
|
549
|
-
become a velocity feed on the next person who read it.
|
|
550
|
-
```
|
|
551
|
-
|
|
552
|
-
---
|
|
553
|
-
|
|
554
|
-
## GATE L4 — Ship Sign-Off
|
|
555
|
-
|
|
556
|
-
```
|
|
557
|
-
⏸ GATE L4 — Ship Sign-Off
|
|
558
|
-
Feature : [slug] — [SHIPPED (deployed) | BUILT & VERIFIED — deploy pending (PO)]
|
|
559
|
-
Rounds : [r] (build+eval cycles)
|
|
560
|
-
Verdict : PASS (dims: [dims_evaluated]; not evaluated: [dims_not_evaluated])
|
|
561
|
-
QA : [hunt done — N findings, M promoted+fixed, rest ~ | skipped (--no-qa) | n/a (pre-QA spec)]
|
|
562
|
-
Requirements: [15/17 PASS · 1 CUT (PO) · 1 no evidence (REQ-12 ← R12) | n/a (no registry)]
|
|
563
|
-
Ledger : harness-run.md
|
|
564
|
-
```
|
|
565
|
-
The Requirements line is TRANSCRIBED, never composed — run
|
|
566
|
-
`node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" probe requirements --slug <slug> --format table`
|
|
567
|
-
and copy its `Requirements:` summary. It joins each registered clause to the acceptance criterion
|
|
568
|
-
that covers it and to the criterion the judge graded, over the run named in its own output. It
|
|
569
|
-
decides nothing here: a requirement with no PASS evidence is a fact GATE H's census and the
|
|
570
|
-
baseline comparison weigh, not a ship blocker.
|
|
571
|
-
Question (max 1): "Anything to record before I close the run? (y/n) or provide feedback for the next sprint."
|
|
572
|
-
On confirm:
|
|
573
|
-
- If the PO provides substantive feedback (not just 'y' or empty) → automatically delegate via Agent (model: exec — see references/protocol.md "Invocation mechanism"): Skill(shapeup-sdlc-plugin:coach) with the provided feedback for RLHF. The coach runs its own GATE COACH-1 to have the PO categorize each rule, then files it under the responsible skill in `shapeup/knowledge-base/<skill>.md` (committed → team-shared). Coachable: `task-executor`, `ba-pitch-analyzer`, `qa-edge-hunter`, `orient`, `scope-architect`, `solution-architect` (each reads its own file at the top of its next run) and `tech-lead` (workflow guidance, read at the next GATE L0). Guidance never decides a gate: a filed rule may add a question or a check to a gate block, never an answer. The tech lead does not categorize the feedback itself — that is the coach's gate, by design (no assumptions).
|
|
574
|
-
- Then output → `✅ [slug] [shipped & deployed | built & verified, deploy pending] — [r] rounds, verdict PASS.`
|
|
575
|
-
|
|
576
|
-
**A launched run already crossed L4 — never resolve it again after a `shipped` or `escalated`
|
|
577
|
-
return; a second row after the close is a second sign-off.** In the prose lane, **resolve the gate
|
|
578
|
-
itself before any of the above** — this is the decision that shipped the run,
|
|
579
|
-
and without it the trace holds no record of that decision at all: `node
|
|
580
|
-
"${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" gate --resolve L4 --slug <slug>
|
|
581
|
-
[--file <path>|--preset <name>]`. Exit 0 (`decision=ship|hold`) — render the block above and close
|
|
582
|
-
the run: `node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" probe resume --slug <slug> --close shipped
|
|
583
|
-
--cause "verdict=<verdict> rounds=<r> decision=<ship|hold>"`. **This applies to the prose lane
|
|
584
|
-
only.** A launched run (`shapeup-run.js`) resolves L4 itself, on both the PASS path and a breaker
|
|
585
|
-
path: it dispatches the census, crosses GATE H, writes the ship report with the verdict as it is,
|
|
586
|
-
crosses L4, and only then closes — `shipped` when the census and L4 clear it, `escalated` naming
|
|
587
|
-
the census when they do not. A run that returned `{status: "shipped"}` or `{status: "gate_h"}` is
|
|
588
|
-
already closed; do not close it again, and do not run the census by hand after it.
|
|
589
|
-
The close itself is a once-only fact IN THE KERNEL (`closeRun`'s own guard reads a `closed_status:`
|
|
590
|
-
line that only `closeRun` ever writes — never the mutable `status:` line every phase rewrites, this
|
|
591
|
-
call included), not a conditional this instruction has to get right: if this run_id was NOT already
|
|
592
|
-
closed, this call performs the close, fresh. If it was already closed `shipped` (or `aborted`) and
|
|
593
|
-
the cause text is byte-identical to what is already on the ledger, this call is a true idempotent
|
|
594
|
-
no-op. If it was already closed with the SAME status but a genuinely different cause — a run closed
|
|
595
|
-
more than once across relaunches, the ordinary shape a `gate_h` hand-off after an earlier abort takes
|
|
596
|
-
— this call SUPERSEDES it: the new cause is written, the prior one is folded into the same
|
|
597
|
-
`close_cause` line rather than lost, and the kernel call itself still exits 0 (only the RunReturn a
|
|
598
|
-
launch's own `withWarnings` wraps carries the resulting `state_warning` — a prose-driven close like
|
|
599
|
-
this one has no RunReturn to attach it to, so read `close_cause` by hand if this branch matters to
|
|
600
|
-
you). If it was already closed with a DIFFERENT status altogether, this call is refused outright —
|
|
601
|
-
cause intact, never silently flipped. Exit 4 (`ask`) — the block above IS that stop; put it to the
|
|
602
|
-
PO and wait, same as always. L4's answer set carries no `abort`.
|
|
603
|
-
|
|
604
|
-
---
|
|
605
|
-
|