shapeup-sdlc 1.7.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/.claude/settings.local.example.json +5 -5
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/AGENTS.md +17 -3
  4. package/README.md +124 -103
  5. package/SECURITY.md +37 -30
  6. package/bin/init.mjs +77 -47
  7. package/bin/lib/grant.mjs +145 -0
  8. package/commands/build.md +7 -6
  9. package/commands/ship.md +29 -16
  10. package/commands/wire.md +1 -1
  11. package/hooks/dispatch-receipt.mjs +195 -0
  12. package/hooks/gate-intake.mjs +3 -3
  13. package/hooks/gate-zerowork.mjs +25 -24
  14. package/hooks/hooks.json +9 -48
  15. package/hooks/lib/decision.mjs +19 -8
  16. package/hooks/safety-spine.mjs +3 -3
  17. package/hooks/sandbox-guard.mjs +84 -40
  18. package/{skills/tech-lead/scripts/compile-order.mjs → kernel/compile.mjs} +283 -41
  19. package/{skills/tech-lead/scripts/gate-answers.mjs → kernel/gate.mjs} +58 -14
  20. package/kernel/harness.mjs +134 -0
  21. package/{skills/tech-lead/scripts/fit-check.mjs → kernel/init/fit.mjs} +15 -12
  22. package/{skills/tech-lead/scripts/init-run.mjs → kernel/init/run.mjs} +152 -31
  23. package/{skills/tech-lead/scripts → kernel}/lib/argv.mjs +52 -31
  24. package/{skills/tech-lead/scripts/lib/contract-md.mjs → kernel/lib/contract.mjs} +251 -7
  25. package/kernel/lib/paths.mjs +491 -0
  26. package/kernel/probe/concurrency.mjs +510 -0
  27. package/{skills/tech-lead/scripts/aegis-digest.mjs → kernel/probe/digest.mjs} +9 -10
  28. package/kernel/probe/eval.mjs +77 -0
  29. package/kernel/probe/leg.mjs +125 -0
  30. package/{skills/tech-lead/scripts/resume-state.mjs → kernel/probe/resume.mjs} +204 -63
  31. package/{skills/tech-lead/scripts → kernel/probe}/stats.mjs +14 -9
  32. package/kernel/probe/t0.mjs +66 -0
  33. package/{skills/ba-pitch-analyzer/scripts/board-derive.mjs → kernel/reduce/board.mjs} +99 -23
  34. package/kernel/reduce/graph.mjs +437 -0
  35. package/{skills/tech-lead/scripts/hill-derive.mjs → kernel/reduce/hill.mjs} +28 -9
  36. package/kernel/reduce/ingest.mjs +633 -0
  37. package/{hooks/slop-cleaner.mjs → kernel/reduce/leftovers.mjs} +40 -57
  38. package/{skills/tech-lead/scripts/ship-report.mjs → kernel/reduce/ship.mjs} +61 -13
  39. package/{skills/tech-lead/scripts/run-snapshot.mjs → kernel/reduce/snapshot.mjs} +21 -15
  40. package/{skills/spec-evaluator/scripts/verdict-ledger.mjs → kernel/reduce/verdict.mjs} +13 -7
  41. package/kernel/report/export.mjs +321 -0
  42. package/kernel/report/facts.mjs +209 -0
  43. package/{skills/tech-lead/scripts/budget-check.mjs → kernel/verify/budget.mjs} +15 -12
  44. package/kernel/verify/dispatch.mjs +114 -0
  45. package/{skills/tech-lead/scripts/validate-envelope.mjs → kernel/verify/envelope.mjs} +20 -15
  46. package/{skills/tech-lead/scripts/lib → kernel/verify}/ratchet-tree.mjs +36 -14
  47. package/kernel/verify/skills.mjs +125 -0
  48. package/kernel/verify/spec.mjs +559 -0
  49. package/{skills/tech-lead/scripts/t0-verify.mjs → kernel/verify/t0.mjs} +134 -24
  50. package/{skills/tech-lead/scripts/trace-lint.mjs → kernel/verify/trace.mjs} +26 -11
  51. package/oracles/http-oracle.mjs +1 -1
  52. package/oracles/process-oracle.mjs +1 -1
  53. package/oracles/snapshot-oracle.mjs +1 -1
  54. package/oracles/test-oracle.mjs +1 -1
  55. package/package.json +11 -9
  56. package/skills/ba-pitch-analyzer/SKILL.md +5 -5
  57. package/skills/ba-pitch-analyzer/assets/templates/_index.tmpl.md +1 -1
  58. package/skills/ba-pitch-analyzer/assets/templates/api-feasibility.tmpl.md +12 -7
  59. package/skills/ba-pitch-analyzer/assets/templates/contracts/third-party-api.contract.tmpl.md +6 -3
  60. package/skills/ba-pitch-analyzer/assets/templates/cross-context/migration-plan.tmpl.md +5 -4
  61. package/skills/ba-pitch-analyzer/assets/templates/cross-context/team-handoff.tmpl.md +23 -13
  62. package/skills/ba-pitch-analyzer/assets/templates/scope-summary.tmpl.md +17 -12
  63. package/skills/ba-pitch-analyzer/assets/templates/synthesis.tmpl.md +17 -38
  64. package/skills/ba-pitch-analyzer/assets/templates/task.tmpl.md +3 -0
  65. package/skills/ba-pitch-analyzer/references/contract-patterns.md +8 -4
  66. package/skills/ba-pitch-analyzer/references/doc-schemas.md +2 -0
  67. package/skills/ba-pitch-analyzer/references/task-generation.md +2 -2
  68. package/skills/qa-edge-hunter/SKILL.md +7 -3
  69. package/skills/scope-architect/SKILL.md +40 -6
  70. package/skills/solution-architect/SKILL.md +19 -4
  71. package/skills/spec-evaluator/SKILL.md +12 -2
  72. package/skills/task-executor/SKILL.md +7 -6
  73. package/skills/tech-lead/SKILL.md +50 -38
  74. package/skills/tech-lead/references/gates.md +71 -20
  75. package/skills/tech-lead/references/protocol.md +832 -0
  76. package/skills/tech-lead/schemas/domain.schema.json +341 -66
  77. package/skills/tech-lead/schemas/work-order.schema.json +11 -2
  78. package/skills/tech-lead/schemas/work-result.schema.json +1 -1
  79. package/skills/tech-lead/workflows/shapeup-run.js +1327 -750
  80. package/hooks/anti-rationalization.mjs +0 -238
  81. package/hooks/compact-snapshot.mjs +0 -47
  82. package/hooks/gate-deadline.mjs +0 -147
  83. package/hooks/gate-l2.mjs +0 -161
  84. package/hooks/session-rehydrate.mjs +0 -108
  85. package/skills/ba-pitch-analyzer/scripts/spec-lint.mjs +0 -239
  86. package/skills/spec-evaluator/README.md +0 -93
  87. package/skills/tech-lead/README.md +0 -71
  88. package/skills/tech-lead/references/delegation.md +0 -261
  89. package/skills/tech-lead/references/hard-rules.md +0 -34
  90. package/skills/tech-lead/references/invocation.md +0 -45
  91. package/skills/tech-lead/references/ledger-schema.md +0 -213
  92. package/skills/tech-lead/references/round-protocol.md +0 -234
  93. package/skills/tech-lead/references/state-model.md +0 -66
  94. package/skills/tech-lead/scripts/ingest-result.mjs +0 -258
  95. package/skills/tech-lead/scripts/lib/is-main.mjs +0 -81
  96. package/skills/tech-lead/scripts/lib/paths.mjs +0 -280
  97. package/skills/tech-lead/scripts/run-workflow.mjs +0 -381
  98. package/skills/translator/README.md +0 -66
@@ -12,7 +12,7 @@ lane emits them verbatim, and on the scoped lane `shapeup-run.js` returns the `b
12
12
  | lane | BUILD → GATE L2 → EVAL is | read |
13
13
  |---|---|---|
14
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/round-protocol.md` (`:11-22` states the same split) |
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
16
 
17
17
  Order matches the run: GATE L0 → ORIENT → GATE L1a → ANALYZE → WIRE/L1a.5 → MAP SCOPES →
18
18
  GATE L1b → (BUILD → GATE L2 → EVAL — see the table above) → GATE L3 → SHIP → GATE L4.
@@ -55,7 +55,7 @@ Collect (explicit — never inferred):
55
55
  L0.3 lens: lite | standard | cross-context (passed to planner at step 8)
56
56
  L0.4 stack hint (e.g. "pnpm, Next 16 web :3000") — aims orient's code-surface sweeps + run commands
57
57
  L0.5 eval dimensions: default [spec-conformance]; only add if user asks. An added dimension
58
- must reach `init-run.mjs --dimensions <a,b>` — it is recorded in the ledger's
58
+ must reach `harness init run --dimensions <a,b>` — it is recorded in the ledger's
59
59
  `eval_dimensions:` line and every EVAL order is compiled from there, so a set agreed
60
60
  in conversation and not passed to the flag grades nothing. Shipped ids:
61
61
  spec-conformance, tdd-surface, integration, completeness, test-surface-conformance
@@ -74,7 +74,7 @@ Collect (explicit — never inferred):
74
74
  .claude/settings.json (team defaults, committed) → skill-shipped defaults
75
75
  Env knobs read at this layer: SHAPEUP_ORCH_MODEL, SHAPEUP_EXEC_MODEL,
76
76
  SHAPEUP_EVAL_MODEL, SHAPEUP_QA_MODEL, SHAPEUP_ATTEMPT_BUDGET (default 5),
77
- SHAPEUP_DIGESTER_MODEL (default "script" — aegis-digest.mjs's regex pass; falls
77
+ SHAPEUP_DIGESTER_MODEL (default "script" — harness probe digest's regex pass; falls
78
78
  back to a Sonnet dispatch only when the digester reports unrecognized log formats).
79
79
  A requested model unavailable on the member's plan → degrade to the next tier down,
80
80
  record the degrade in the ledger (R2 — invariants are code paths, so adherence
@@ -92,6 +92,27 @@ Collect (explicit — never inferred):
92
92
  attempts. Set per scope (`no_progress_k` on the contract) or per run in the payload.
93
93
  ```
94
94
 
95
+ **L0.9b — the launch record.** Every switch the operator typed becomes a `RunArgs` field, or it
96
+ does nothing at all: the workflow cannot read a config file and cannot ask a follow-up, so a flag
97
+ that stops at the skill boundary was accepted and ignored. That is not hypothetical — `--no-qa` was
98
+ documented in seven places across the shipped set and inert in all of them, because no line of this
99
+ protocol ever put `noQa` into the record.
100
+
101
+ | Flag | `RunArgs` field |
102
+ |---|---|
103
+ | `--no-eval` | `noEval: true` |
104
+ | `--no-qa` | `noQa: true` |
105
+ | `--parallel-scopes N` | `maxParallelScopes: N` — how many scopes build at once (default 4; `1` = sequential) |
106
+ | `--adversarial-verify` | `adversarialVerify: true` |
107
+ | `--rounds N` / `--attempts N` / `--wall-clock-budget S` | `budgets.{maxRounds,attemptBudget,wallClockS}` |
108
+ | `--gate-answers <set>` | `answers` |
109
+ | `--orch-model/--exec-model/--eval-model/--qa-model` | `models.{…}` (L0.8) |
110
+
111
+ The assembled object is written to `.shapeup/<slug>/run-args.json` before the launch, fresh on every
112
+ launch and relaunch. It is the only artifact that records what a run was configured with; the ship
113
+ report, a resumed session and any later measurement all read it, and none of them can recover a
114
+ value that only ever existed as an argument.
115
+
95
116
  **L0.0 — intake precondition (before any other L0 collection):**
96
117
  ```
97
118
  resolve intake from, in order:
@@ -127,7 +148,7 @@ The Shape Up Building phase opens with **Orient, not planning**: the team reads
127
148
  and spikes the scary parts *before* any board exists, so the board comes out reality-born.
128
149
 
129
150
  ```
130
- Invoke via Agent (model: exec — see references/delegation.md "Invocation mechanism"):
151
+ Invoke via Agent (model: exec — see references/protocol.md "Invocation mechanism"):
131
152
  Skill(shapeup-sdlc-plugin:orient) --pitch <intake> --spec <path> --stack "<hint>" [--auto]
132
153
  Owns: its own GATE O-A/O-B; runs straight through under --auto.
133
154
  Writes: .shapeup/<slug>/orient/ → code-surface.md, spike-<area>.md, discovered-seed.md, hill-signal.md.
@@ -144,7 +165,7 @@ re-scanning the codebase. Pass `--auto` only when the run level is `--auto`/`--u
144
165
  committing to a scope map. This is the first Hill read (area-level — slices don't exist yet).
145
166
 
146
167
  ```
147
- Read .shapeup/<slug>/orient/. Render the 🗻 Hill from hill-signal.md (see ledger-schema.md "Hill report"):
168
+ Read .shapeup/<slug>/orient/. Render the 🗻 Hill from hill-signal.md (see protocol.md "Hill report"):
148
169
  - each suspected area → uphill (open unknowns) | crest (approach proven by the spike) | downhill
149
170
  Print: the code-surface headline (where it lands), the spiked area + result, the riskiest
150
171
  open unknowns going into mapping.
@@ -170,11 +191,11 @@ Do NOT enter MAP SCOPES until Orient is accepted.
170
191
  ⟐ PRECONDITION: MAP SCOPES step 1 (ANALYZE) has already run and usecases/ is
171
192
  populated. WIRE writes one entry per use case, so dispatching it against an empty spec folder
172
193
  is an escalation, not a wiring map — and a phase that writes no artifact is re-dispatched on
173
- every relaunch. Verify: node "${CLAUDE_PLUGIN_ROOT}/skills/tech-lead/scripts/resume-state.mjs"
194
+ every relaunch. Verify: node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" probe resume
174
195
  --slug <slug> --require analyze (exit 0 = the spec tree is there; exit 6 = do not dispatch WIRE).
175
196
  Post-check the same way after the dispatch: --require wire.
176
197
  requirements.md registry (atomic REQ clauses, frozen ids).
177
- 4. trace-lint — node "${CLAUDE_PLUGIN_ROOT}/skills/tech-lead/scripts/trace-lint.mjs" --slug <slug>. ADVISORY at L1b:
198
+ 4. trace-lint — node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" verify trace --slug <slug>. ADVISORY at L1b:
178
199
  covers-closure (every covered REQ named by ≥1 AC's covers:) + reachability (every UC engine
179
200
  reaches entry_point). Promote to --gate only once covers: is populated.
180
201
  ```
@@ -189,7 +210,7 @@ against the seams WIRE declared. Sequence: ORIENT → L1a → **ANALYZE** → **
189
210
  **MAP SCOPES** → L1b.
190
211
 
191
212
  ```
192
- Two orders, two workers, one step (both model: exec — see references/delegation.md):
213
+ Two orders, two workers, one step (both model: exec — see references/protocol.md):
193
214
  1. ANALYZE + BOARD — compile-order --operation analyze --slug <slug> --worker ba-pitch-analyzer
194
215
  --payload '{"pitch": "<path>", "lens": "<lens>", "orient_dir": ".shapeup/<slug>/orient/"}'
195
216
  dispatch: Skill(shapeup-sdlc-plugin:ba-pitch-analyzer) --order <path>. The order hands it
@@ -201,7 +222,7 @@ Two orders, two workers, one step (both model: exec — see references/delegatio
201
222
  2. MAP SCOPES — compile-order --operation map-scopes --slug <slug> --worker scope-architect
202
223
  dispatch: Skill(shapeup-sdlc-plugin:scope-architect) --order <path>. Sole writer of the
203
224
  committed scopes/<scope-id>.md contracts (import-graph slicing, substrate whitelists,
204
- affordance manifest, fixtures, PA1/PA2 — mechanically linted by spec-lint.mjs).
225
+ affordance manifest, fixtures, PA1/PA2 — mechanically linted by harness verify spec).
205
226
  Record in ledger: planner duration + task count + scope count.
206
227
  ```
207
228
  Faithful note: keep the planner ambitious on scope but high-level on tech — do not push it
@@ -254,13 +275,24 @@ No scope contracts (pre-v0.3.0, unchanged from v0.2.6):
254
275
  Substrate-disjointness assertion (only when
255
276
  shapeup/<slug>/scopes/*.md exist — scope-architect's lint pass already ran;
256
277
  this is the orchestrator's own re-confirmation before committing to a build sequence):
257
- - Run `node "${CLAUDE_PLUGIN_ROOT}/skills/ba-pitch-analyzer/scripts/spec-lint.mjs" --slug <slug>`: DISJOINT (a file in two
278
+ - Run `node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" verify spec --slug <slug>`: DISJOINT (a file in two
258
279
  scopes' `allowed_file_substrate` without BOTH declaring it `shared_substrate` — PA3
259
- waiting to happen), PA1 (directory-aligned scope), PA2 (size cap). Any red → HARD STOP,
260
- past a 🔴 at the architect's own checkpoint.
280
+ waiting to happen), PA1 (directory-aligned scope), PA2 (size cap), SCOPE-ANCHOR (a scope
281
+ naming no committed use case, or one that does not resolve), TIER-DIRECTION (a committed
282
+ contract naming LOCAL task ids), SCOPE-DEPS (a build-order id naming a scope that is not
283
+ in this run). Any red → HARD STOP, past a 🔴 at the architect's own checkpoint.
261
284
  - Lock the build SEQUENCE riskiest-first: order scopes by open-unknowns count (from
262
285
  hill/<scope-id>.yml if present, else the orient hill signal), not by file count or
263
286
  alphabetical — Shape Up's "solve in the right sequence" (step 10).
287
+ DEPENDENCIES CONSTRAIN THAT ORDER, and each contract declares its own: scope A follows scope
288
+ B when A names B in `depends_on`. The order lives in the same committed tier as the contracts
289
+ it orders, so it survives a clone. Risk orders the scopes; the dependencies decide when each one is
290
+ RELEASED — a scope starts as soon as the scopes it consumes have settled, not when its whole
291
+ level has, so a scope may well start while a sibling is still building. A scope that consumes
292
+ the others' output (an entry point wiring up command modules) therefore cannot be scheduled
293
+ alongside them however low its unknowns count. It fails open: a contract declaring no
294
+ `depends_on`, or naming a scope that is not in this run, falls back to releasing a level at a
295
+ time, and then to no constraint at all (spec-lint SCOPE-DEPS reports the dangling id).
264
296
 
265
297
  Ask (max 2): scope cuts? lens correct? any SPIKE to resolve before build?
266
298
  Scope-hammer framing: reference the appetite from the pitch
@@ -295,14 +327,14 @@ Under `--interactive` / `--auto`, the hook warns if the board is not truly green
295
327
  Render the 🗻 Hill report (slice-level) — NOT a task count. Scope contracts present → read
296
328
  committed hill/<scope-id>.yml shards (mechanical phases from GATE L2, never authored). No contracts →
297
329
  fall back to the board + open-unknowns heuristic (uphill/crest/downhill/done). See
298
- references/ledger-schema.md "Hill report". Roadmap rule unchanged either way: progress is
330
+ references/protocol.md "Hill report". Roadmap rule unchanged either way: progress is
299
331
  reported by hill position, never by "N/M tasks done".
300
332
 
301
333
  Read EVAL-FEATURE-<slug>.md verdict.
302
334
 
303
335
  PASS:
304
336
  → first PASS of the run AND not --no-qa:
305
- delegate ▶ QA EDGE HUNT → Agent (model: qa — see references/delegation.md
337
+ delegate ▶ QA EDGE HUNT → Agent (model: qa — see references/protocol.md
306
338
  "Invocation mechanism"): Skill(shapeup-sdlc-plugin:qa-edge-hunter) (pure worker; see
307
339
  round-protocol "QA edge hunt"). Args: spec folder, EVAL report path, ledger path, app URL.
308
340
  Its GATE Q0/Q1 pauses surface here. Output: `~` findings → .shapeup/<slug>/discovery/ledger.md
@@ -338,7 +370,7 @@ yet, report at task-group level and note the fallback in the ledger.
338
370
 
339
371
  ```
340
372
  S.0 GATE H — delegate to scope-hammer (this IS Shape Up's "Decide When to Stop", step 11):
341
- Invoke via Agent (model: exec — see references/delegation.md "Invocation mechanism"):
373
+ Invoke via Agent (model: exec — see references/protocol.md "Invocation mechanism"):
342
374
  Skill(shapeup-sdlc-plugin:scope-hammer) --slug <slug> --baseline <shaping/baseline.md if present>
343
375
  [--breaker outer] when round_budget hit 0 with scopes still open
344
376
  [--breaker inner --scope <id>] once per queued hammer proposal (attempt_budget
@@ -380,7 +412,7 @@ S.6 Harvest one signal row → append to `.shapeup/metrics/<machine-id>.jsonl`
380
412
  (LOCAL root, gitignored since ADR-0001 — a committed shard keyed on a hostname only
381
413
  grows and publishes a machine name; sharded per machine so shards can be pooled
382
414
  deliberately without colliding on one filename. The read plane is
383
- `stats.mjs`, or `cat .shapeup/metrics/*.jsonl`).
415
+ `harness probe stats`, or `cat .shapeup/metrics/*.jsonl`).
384
416
  Copy fields that ALREADY exist as structured output (run-state, final EVAL report,
385
417
  discovery ledger, qa/hunt-report, breadboard B5). Two hard rules:
386
418
  1. Harvest only fields that already exist at ship time — never evaluate something new.
@@ -388,16 +420,35 @@ S.6 Harvest one signal row → append to `.shapeup/metrics/<machine-id>.jsonl`
388
420
  a second judge behind spec-evaluator). The eval suite interprets; harvest records.
389
421
  `final_audit_score` is COPIED from the EVAL report, never re-graded.
390
422
  ALSO copy two run-quality measurements, both produced by scripts at zero model tokens:
391
- node "${CLAUDE_PLUGIN_ROOT}/skills/tech-lead/scripts/stats.mjs" --ratchet --slug <slug>
423
+ node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" probe stats --ratchet --slug <slug>
392
424
  → `ratchet`: {trials, scopes_multi_trial, improvement_rate, monotone_rate,
393
425
  sawtooth_count, mean_trials_to_green}
394
- node "${CLAUDE_PLUGIN_ROOT}/skills/tech-lead/scripts/stats.mjs" --hooks
426
+ node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" probe stats --hooks
395
427
  → `hooks`: {evaluations, denials, errors, per_hook}
396
428
  Harvest them HERE or lose them: both read per-run working ledgers (t0/trials.jsonl,
397
429
  decisions.jsonl) that the next run's bookkeeping supersedes, so a number left there
398
430
  answers its question exactly once. The metrics shard is the one record that
399
431
  accumulates across runs — and neither measurement is meaningful from a single run.
400
- full field list + row template: references/ledger-schema.md "Harvest row".
432
+ ALSO copy `run_id` from `receipt.json`. It is the row's only link to the run trace
433
+ that produced it: every other field here is a count, and `feature_slug` groups runs
434
+ TOGETHER rather than apart. It is what joins this row to the S.7 export.
435
+ → full field list + row template: references/protocol.md "Harvest row".
436
+ S.7 Export the run's records → one keyed dataset, before the trace is superseded.
437
+ node "${CLAUDE_PLUGIN_ROOT}/kernel/harness.mjs" report export --slug <slug>
438
+ Same argument as S.6, applied to the records the harvest row does NOT carry: orders,
439
+ results, T0 verdicts, trial rows, criterion verdicts and this run's hook decisions all
440
+ live in the LOCAL tier, which is regenerable and gets wiped.
441
+ The export freezes them as fact tables under `.shapeup/exports/<run_id>/` (JSONL, one
442
+ object per line), keyed by run id so a second run of the same feature is a second
443
+ dataset rather than an overwrite. `--out <dir>` sends it somewhere durable instead.
444
+ It is READ-ONLY: it writes nothing into the trace, so it may be re-run at any time.
445
+ NOT COST/WALL-CLOCK. This harness carries no run-economics record — the design once
446
+ called for one derived from a per-agent-call journal, but nothing in the pipeline ever
447
+ wrote that journal, so the derivation and its reporting command were removed rather than
448
+ left presenting nulls as measurements. Even a real cost record would not belong in the
449
+ harvest row's schema either way — that row's contract rejects clock fields on purpose
450
+ (see protocol.md "Rejected fields"), because a signal feed that carried a duration would
451
+ become a velocity feed on the next person who read it.
401
452
  ```
402
453
 
403
454
  ---
@@ -414,7 +465,7 @@ Ledger : harness-run.md
414
465
  ```
415
466
  Question (max 1): "Anything to record before I close the run? (y/n) or provide feedback for the next sprint."
416
467
  On confirm:
417
- - If the PO provides substantive feedback (not just 'y' or empty) → automatically delegate via Agent (model: exec — see references/delegation.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 skills: `task-executor`, `ba-pitch-analyzer`, `qa-edge-hunter`; each reads its own file at the top of its next run. The tech lead does not categorize the feedback itself — that is the coach's gate, by design (no assumptions).
468
+ - 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 skills: `task-executor`, `ba-pitch-analyzer`, `qa-edge-hunter`; each reads its own file at the top of its next run. The tech lead does not categorize the feedback itself — that is the coach's gate, by design (no assumptions).
418
469
  - Then output → `✅ [slug] [shipped & deployed | built & verified, deploy pending] — [r] rounds, verdict PASS.`
419
470
 
420
471
  ---