@gtrabanco/pi-agentic-workflow 0.31.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/package.json +1 -1
  2. package/skills/audit-pr/SKILL.md +1 -1
  3. package/skills/audit-pr/references/03_AUDIT_PROCESS.md +3 -2
  4. package/skills/execute-phase/SKILL.md +12 -7
  5. package/skills/execute-phase/references/EXECUTION_CONTRACT.md +15 -9
  6. package/skills/execute-phase/references/FOLDING.md +11 -8
  7. package/skills/execute-phase/references/PREFLIGHT.md +7 -3
  8. package/skills/fold-findings/SKILL.md +28 -17
  9. package/skills/fold-findings/references/FOLD_PROCESS.md +5 -3
  10. package/skills/orchestration-envelope/references/TURN_CONTRACT.md +2 -1
  11. package/skills/pre-execution-review/SKILL.md +1 -1
  12. package/skills/pre-execution-review/references/LEDGERS.md +30 -2
  13. package/skills/review-change/SKILL.md +1 -1
  14. package/skills/review-change/references/OUTPUT_AND_GUARDRAILS.md +2 -1
  15. package/skills/review-change/references/PERSIST_AND_DECIDE.md +30 -9
  16. package/skills/review-change/references/REVIEW_PROCESS.md +14 -6
  17. package/skills/review-implementation/SKILL.md +10 -2
  18. package/skills/review-implementation/references/CLASSIFY.md +21 -4
  19. package/skills/triage-issue/SKILL.md +18 -12
  20. package/skills/triage-issue/references/FOLD_LEDGER.md +11 -3
  21. package/skills/triage-issue/references/ISSUE_PROCESS.md +3 -2
  22. package/skills/triage-issue/references/REVIEW_FINDING_PROCESS.md +17 -8
  23. package/skills/unit-lane/SKILL.md +7 -5
  24. package/skills/unit-lane/references/DESIGN.md +1 -1
  25. package/skills/unit-lane/references/EVIDENCE.md +7 -3
  26. package/skills/unit-lane/references/PLAN.md +11 -1
  27. package/skills/unit-lane/references/RESEARCH.md +3 -3
  28. package/skills/verification-contract/SKILL.md +9 -7
  29. package/skills/workflow-status/SKILL.md +4 -2
  30. package/skills/workflow-status/references/ENVELOPE_FIELDS.md +3 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtrabanco/pi-agentic-workflow",
3
- "version": "0.31.0",
3
+ "version": "0.34.0",
4
4
  "description": "Pi package: canonical agentic-workflow skills, friendly slash commands, and per-command model routing.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: audit-pr
3
3
  user-invocable: true
4
- version: 5.6.2
4
+ version: 5.6.3
5
5
  argument-hint: <pr-number> (optional — defaults to the current branch's PR)
6
6
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
@@ -29,8 +29,9 @@
29
29
  - **BLOCKED** — one or more gates fail; output the ranked blocker list.
30
30
  6. **Persist blockers to the fold ledger (BLOCKED verdict only).** Every blocker
31
31
  on a **BLOCKED** verdict is, by definition, fix-now — merge is gated on it.
32
- Append each to the unit's fix-now fold ledger `review-findings.md` (same
33
- location and fixed schema
32
+ Append each to the unit's fix-now fold ledger — its `## Findings` section for
33
+ a migrated unit (issue #308), `review-findings.md` for a legacy one; probe the
34
+ doc first and write to exactly one carrier (same fixed schema
34
35
  `| id | file:line | axis | severity | class | route | folded |` as
35
36
  `review-change`'s persist step) — the **same ledger**, not a separate one
36
37
  (D4: the fold cycle consumes one list). **Merged unit → no write** — check
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: execute-phase
3
3
  user-invocable: true
4
- version: 6.2.1
4
+ version: 6.2.2
5
5
  argument-hint: <NN-slug> [P<k>|step] [--max-attempts N] [--force]
6
6
  allowed-tools: [Bash, Read, Edit, Write, MultiEdit]
7
7
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
@@ -35,7 +35,8 @@ done:
35
35
 
36
36
  ```
37
37
  ✓ Required user inputs were answered concretely (not defaulted). Nothing here
38
- is inferred: a gap runs `node scripts/needs-input.mjs <unit-dir>` and the
38
+ is inferred: a gap runs `bun scripts/needs-input.mjs <unit-dir>` (node fallback
39
+ if bun is not installed) and the
39
40
  `open-questions@1` block is pasted, then the run stops.
40
41
  ✓ Triage verified — unit doc Evidence section header matches
41
42
  `bun scripts/unit-route.mjs --triage <slug>` output block (PREFLIGHT.md)
@@ -66,8 +67,8 @@ This skill **never interviews**. It reads its inputs — the unit doc's `Tasks`,
66
67
  one is a **gap**, resolved in one fixed order and never by inference:
67
68
  **(0) provenance** (search the repo's own docs and record where) →
68
69
  **(1) research** (2–3 concrete options with trade-offs; asking for more research
69
- is a legitimate answer) → **(2) halt**: run `node scripts/needs-input.mjs
70
- <unit-dir>`, paste the `open-questions@1` block verbatim, stop. Interactive the
70
+ is a legitimate answer) → **(2) halt**: run `bun scripts/needs-input.mjs
71
+ <unit-dir>` (node fallback if bun is not installed), paste the `open-questions@1` block verbatim, stop. Interactive the
71
72
  block is the pause point, unattended it is a hard fail. Grammar and exit codes:
72
73
  `orchestration-envelope`'s `references/TURN_CONTRACT.md` §Open questions.
73
74
 
@@ -81,9 +82,13 @@ path-protection checkpoint.
81
82
  ## Step 0 — Discover the project
82
83
 
83
84
  Per the agent guide's **Workflow conventions** + **documentation map**, read the
84
- unit doc at `docs/features/<NN-slug>/SPEC.md`. Verify it carries `## Tasks` (P1…Pn),
85
- `## Evidence`, and `## Progress` sections. If absent, the unit is not ready —
86
- stop and suggest `unit-lane` triage first.
85
+ unit doc at `docs/features/<NN-slug>/SPEC.md`. Verify it carries `## Tasks` (P1…Pn)
86
+ **and the receipt sections of the shape it is written in** (#308 accepts both):
87
+ the legacy shape carries `## Evidence` + `## Progress log`, a re-cut unit doc carries
88
+ `## Specs`, `## Findings` + `## Log` (its evidence and gate runs are `E`/`G` log
89
+ lines, its progress is `P` lines). If neither pair is present, the unit is not ready —
90
+ stop and suggest `unit-lane` triage first. `scripts/unit-route.mjs` resolves the
91
+ shape; never judge a re-cut unit by the legacy headings and stop it.
87
92
 
88
93
  ## Process
89
94
 
@@ -52,8 +52,10 @@ Something forbidden looks necessary → stop, record it in `decisions.md` or
52
52
 
53
53
  ## Step completion gate
54
54
 
55
- The step completion gate verifies that Evidence rows are complete for the
56
- step's acceptance criteria, the unit doc is committed clean, and the diff guard
55
+ The step completion gate verifies that the step's acceptance criteria have
56
+ complete evidence in the unit's own carrier — the `## Evidence` table rows for a
57
+ legacy-shape unit, `## Log` `E` lines (command, exit, ≤2 lines of output) for a
58
+ re-cut one (#308) — that the unit doc is committed clean, and that the diff guard
57
59
  (if applicable) passed. The mark's shape, ownership, and reuse rule are
58
60
  declared in `LEDGERS.md` (§gate-ran@1).
59
61
 
@@ -76,7 +78,8 @@ GATE-RAN | HEAD <40-hex sha> | <cmds> | exit <code>
76
78
  ✓ Verification gate green — type-check + tests + build actually RUN (paste exit
77
79
  status), never assumed
78
80
  ✓ Every task of this step checked off in the unit doc's `Tasks` section, each
79
- mapped to an Evidence row (code path or test name)
81
+ mapped to an Evidence row (legacy shape) or an `E` log line (re-cut shape) —
82
+ code path or test name
80
83
  ✓ Tests updated/added for every behavior this step changed
81
84
  ✓ Tests-first red run recorded (core/domain + orchestration steps, n/a for
82
85
  test-after UI/adapter steps) — the failing first run's command, exit status,
@@ -88,10 +91,12 @@ GATE-RAN | HEAD <40-hex sha> | <cmds> | exit <code>
88
91
  consumers)
89
92
  ✓ Architecture doc respected (dependency directions, layer boundaries)
90
93
  ✓ Architectural invariants preserved or backed by an explicit recorded decision
91
- ✓ Evidence rows complete for the step's ACs — unit doc committed clean
92
- (one dated `YYYY-MM-DD HH:MM` Progress entry, all Evidence rows current)
93
- ✓ Docs COMMITTED with the step — the unit doc carries all required sections
94
- (Tasks, Evidence, Progress, References); no orphan files remain
94
+ ✓ The step's ACs have complete evidence in the unit's carrier — unit doc committed
95
+ clean (one dated `YYYY-MM-DD HH:MM` Progress entry or `P` log line, all evidence
96
+ current)
97
+ ✓ Docs COMMITTED with the step — the unit doc carries all required sections of its
98
+ own shape (Tasks + Evidence + Progress + References for legacy; Specs + Tasks +
99
+ Findings + Log + References for re-cut); no orphan files remain
95
100
  ```
96
101
 
97
102
  A step that cannot tick every box is **not done**: fix within the step's
@@ -123,8 +128,9 @@ planned work, and inference never prove implementation. A present ledger whose
123
128
  status is `draft`, `contradicted`, or `resolved` stops implementation and routes
124
129
  to discovery or resolution first. If no ledger exists, inspect the repository
125
130
  directly and record `n/a: no normalized repository state`; NRS is optional.
126
- Unit doc evidence rows (Evidence, Progress) are the single source of truth
127
- for step completion — no separate ACCEPTANCE.md, progress.md, or TASKS.md.
131
+ Unit doc evidence is the single source of truth for step completion — the
132
+ `## Evidence`/`## Progress log` sections of a legacy-shape doc, the `## Log` lines of
133
+ a re-cut one (#308) — never a separate ACCEPTANCE.md, progress.md, or TASKS.md.
128
134
 
129
135
  ## Architectural invariants
130
136
 
@@ -24,10 +24,12 @@ findings end up "solved" locally but absent from the merged PR:
24
24
  ✓ Gate RUN and green (exit codes pasted)
25
25
  ✓ Never edit an existing test's expectation to match behaviour — a setup
26
26
  repair keeps assertions at least as strong and never touches expectations
27
- ✓ Evidence rows updated where the finding touched them (the finding's row
28
- in the unit doc's Evidence ledger flipped `folded: no → yes` — the one and
29
- only state transition, `ledger-ownership@1` / `fold-findings:folded-flag`
30
- is the sole writer)
27
+ ✓ Evidence rows updated where the finding touched them, in the unit's own findings
28
+ carrier: a legacy row flipped `folded: no → yes`; a migrated unit's row leaves
29
+ `## Findings` and its fold is a `## Log` `F` line naming the fold commit — that
30
+ carrier has no `folded` column to flip (#308). Either close is the one and only
31
+ state transition, and `ledger-ownership@1` / `fold-findings:folded-flag` is the
32
+ sole writer of it
31
33
  ✓ Progress log advanced with a dated entry noting the fold
32
34
  ✓ `git add` + `git commit` RUN (sha pasted) — e.g.
33
35
  `fix(<scope>): fold review findings — <summary>`
@@ -56,8 +58,9 @@ No auto-merge. Explicit `P<k>` stops after one step; omitted-step mode gates
56
58
  and commits every remaining step before the same final review.
57
59
  ## Gate-run marks (gate-ran@1)
58
60
 
59
- Every verification gate this cycle runs records a `GATE-RAN` mark in the unit
60
- doc's Evidence section at the head it actually ran:
61
+ Every verification gate this cycle runs records a `GATE-RAN` mark at the head it
62
+ actually ran — a row in the legacy `review-findings.md`, a `## Log` `G` line for a
63
+ re-cut unit (#308):
61
64
  `GATE-RAN | HEAD <40-hex sha> | <cmds> | exit <code>`. A green run is recorded;
62
65
  a red run is also recorded (exit code ≠ 0 is evidence, not silence). Any skill
63
66
  may consume a green mark only at the identical HEAD — a changed head re-runs
@@ -70,5 +73,5 @@ the gate. The recorders are `execute-phase:gate-ran-marks` and
70
73
  When the final triaged step closes: mark the unit done, push the branch, and
71
74
  open the PR with `gh pr create` (per the project's Workflow conventions) —
72
75
  regardless of the review still to come. The PR body carries the unit doc's
73
- Evidence section as its verification record and closes the unit's tracked
74
- issues via `Closes #N`.
76
+ verification record (its `## Evidence` rows, or a re-cut unit's `## Log` `E`/`G`
77
+ lines) and closes the unit's tracked issues via `Closes #N`.
@@ -125,7 +125,10 @@ block text, no-forgery and legacy detail:
125
125
  Consume `skills/verification-contract/SKILL.md`. For a current-format unit,
126
126
  the Evidence section in the unit doc **is** the acceptance manifest — each
127
127
  acceptance criterion has a corresponding Evidence row with command, exit/digest,
128
- and output. No sibling file; the unit doc's Evidence section header carries the
128
+ and output. A re-cut unit (#308) has no Evidence section by design: its acceptance
129
+ manifest is `## Specs`, and each criterion's receipt is a `## Log` `E` line; the
130
+ gate below reads that carrier instead, and never stops a migrated unit for lacking
131
+ a section its own template retired. No sibling file; the unit doc's Evidence section header carries the
129
132
  last-reviewed sha. The unit doc's triage block (pasted verbatim from
130
133
  `scripts/unit-route.mjs --triage`) is the step authority: `execute-phase` runs
131
134
  only what the triage block demands.
@@ -136,8 +139,9 @@ only what the triage block demands.
136
139
  - Missing/mismatched Evidence (unit doc has been edited since last execution)
137
140
  → print the verification contract's fixed `EVIDENCE GATE` block and stop.
138
141
  `--force` never bypasses a changed acceptance state.
139
- - Unit with no Evidence section → the unit doc template was incomplete;
140
- create the section before proceeding.
142
+ - Unit with no Evidence section and no `## Log` → the unit doc template was
143
+ incomplete; create the section its shape requires before proceeding. A doc with
144
+ `## Log` is the re-cut shape: its `E`/`G` lines are the rows, never a gap.
141
145
 
142
146
  Run this check before each step in whole-unit mode. The executor may add tests
143
147
  but may not narrow acceptance criteria, weaken assertions, or edit the Acceptance
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: fold-findings
3
3
  user-invocable: true
4
- version: 1.9.0
4
+ version: 1.9.2
5
5
  argument-hint: [finding-id …]
6
6
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
@@ -49,19 +49,30 @@ postpone/wontfix/promote/documented-tradeoff rows; those belong to `/triage-issu
49
49
 
50
50
  Per Workflow conventions, read:
51
51
 
52
- 1. The unit's `review-findings.md` under `docs/features/<NN>-<slug>/` or
53
- `docs/fix/<n>-<topic>/`; schema is owned by `review-change`/`audit-pr`:
54
-
55
- ```
56
- | id | file:line | axis | severity | class | route | folded |
57
- ```
58
-
59
- After `VERDICT: BLOCKED`, append missing rows (`class: fix-now`, `folded: no`,
60
- next free `Fn`, dedupe `file:line`+axis), commit as
61
- `docs(<unit>): reconstruct fold ledger from audit-pr blockers`, then fold;
62
- never report “no findings”.
63
- 2. Queue `folded: no` rows; explicit IDs restrict it and leave other rows
64
- untouched. Group by root cause, verifier and rollback boundary.
52
+ 1. The unit's findings carrier: a migrated unit (issue #308) keeps its OPEN rows
53
+ in its own `SPEC.md` under `## Findings`, with folded history and marks as
54
+ `## Log` lines; a legacy unit keeps `review-findings.md` under
55
+ `docs/features/<NN>-<slug>/` or `docs/fix/<n>-<topic>/`. Probe the doc first and
56
+ fall back to the file — a unit with the section never reads both. Each carrier
57
+ has **its own** schema, owned by `review-change`/`audit-pr` and stated for both
58
+ shapes in `pre-execution-review/references/LEDGERS.md`:
59
+
60
+ - legacy (7 cols): `\| id \| file:line \| axis \| severity \| class \| route \| folded \|`
61
+ — closing a row flips `folded: no → yes`, and this skill is that flip's sole writer
62
+ - migrated (6 cols, `findings-table@1`): `\| id \| S# / file:line \| axis \| severity \|
63
+ class \| route \|` — every row it holds is OPEN; closing one **deletes the row** and
64
+ appends a `## Log` `F` line naming the fold commit. There is no `folded` column to
65
+ flip, and `class` here is the repairing owner (`product`/`plan`/`source`/
66
+ `environment`/`runtime`), not a disposition.
67
+
68
+ Never write one carrier's row into the other's grammar. After `VERDICT: BLOCKED`,
69
+ append missing rows in the carrier's own schema (next free `Fn`, dedupe
70
+ `file:line`+axis; legacy `class: fix-now`, `folded: no`), commit as
71
+ `docs(<unit>): reconstruct fold ledger from audit-pr blockers`, then fold; never
72
+ report “no findings”.
73
+ 2. Queue the carrier's open rows — a legacy `folded: no` row, a migrated row of
74
+ `## Findings` (all of them are open); explicit IDs restrict the queue and leave
75
+ other rows untouched. Group by root cause, verifier and rollback boundary.
65
76
  3. The project's verification gate and forge CLI (use the declared forge).
66
77
  4. Whether the branch has an open PR; this decides immediate push after commit.
67
78
 
@@ -126,7 +137,7 @@ conclusion the already-run router printed, never the invocation itself: on
126
137
  `route: replan` the planner command it printed — `/unit-lane <slug>` for a
127
138
  feature unit or `/unit-lane --fix <n>` for a fix unit; on `route: decision` stop
128
139
  and surface the decision to the user, never a planner. `<unit>` is the bare folder number or the full slug (both resolve). The invocation
129
- `node scripts/unit-route.mjs <unit>` is the discovery step the fold already
140
+ `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed) is the discovery step the fold already
130
141
  ran; it is never the recommendation.
131
142
 
132
143
  **Freeze-batch (product owner present).** Any taken `fix-now` row whose `Route`
@@ -212,8 +223,8 @@ decision to skip.
212
223
 
213
224
  | Batch state | Branch | `→ Next:` (consumer) |
214
225
  |---|---|---|
215
- | freeze-batch (≥ 1 product-owned row) | `PRODUCT-ROUTE` | `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) when the router concludes `product` — the lane repairs the half through its `design` step, its `review` step re-judges it; the conclusion printed by `node scripts/unit-route.mjs <unit>` (discovery step the fold already ran) |
216
- | freeze-batch (≥ 1 replan-class row) | `REPLAN-ROUTE` | `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) when the router concludes `replan` — user confirms, the lane's `plan` step appends the phases and its `review` step gates, then `/execute-phase` on this unit; on `route: decision` stop and surface the decision to the user — the conclusion printed by `node scripts/unit-route.mjs <unit>` (discovery step the fold already ran) |
226
+ | freeze-batch (≥ 1 product-owned row) | `PRODUCT-ROUTE` | `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) when the router concludes `product` — the lane repairs the half through its `design` step, its `review` step re-judges it; the conclusion printed by `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed; discovery step the fold already ran) |
227
+ | freeze-batch (≥ 1 replan-class row) | `REPLAN-ROUTE` | `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) when the router concludes `replan` — user confirms, the lane's `plan` step appends the phases and its `review` step gates, then `/execute-phase` on this unit; on `route: decision` stop and surface the decision to the user — the conclusion printed by `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed; discovery step the fold already ran) |
217
228
  | `all-repair-in-place` + docs-only + no folded row severity `high` + prior consumer skip decision | `RE-REVIEW-SKIPPED` | skip — consumer has explicitly decided to skip the re-review |
218
229
  | `all-repair-in-place` + docs-only + no folded row severity `high` | `RE-REVIEW-OPTIONAL` | `/review-change` (default, delta mode) — or the consumer's recorded skip decision |
219
230
  | empty batch (class `none`) | `RE-REVIEW-OPTIONAL` | `/review-change` by default — safe: the head is unchanged |
@@ -43,8 +43,10 @@
43
43
 
44
44
  | Condition over the taken batch | Batch class | Fold behavior |
45
45
  |---|---|---|
46
- | ≥ 1 row with frozen class `replan-in-unit` or `decision-required` | `frozen (replan present)` | **freeze-batch** — nothing folds, no `folded: yes` flips, no commits; the receipt records the REPLAN-ROUTE and every retained (unfolded) row id; the loop stops; the consumer is the conclusion printed by `node scripts/unit-route.mjs <unit>` (discovery step the fold already ran), where `<unit>` is the bare folder number or the full slug (both resolve): on `route: replan` the planner command the router printed — `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) — the lane appends the phases and its `review` step gates, then `/execute-phase` on this unit; on `route: decision` stop and surface the decision to the user, never a planner |
47
- | ≥ 1 row with frozen class `fix-now` whose `Route` cell begins `product owner`, `product-owned` or `owned by product` (head-anchored, identical to `scripts/unit-route.mjs`'s `PRODUCT_ROUTE` regex: `/^(?:product[- ]owner\|product[- ]owned\|owned by product)\b/i`, per `#293`) | `frozen (product owner present)` | **freeze-batch** — nothing folds, no `folded: yes` flips, no commits; the receipt records the PRODUCT-ROUTE and every retained (unfolded) row id; the loop stops; the consumer is the conclusion printed by `node scripts/unit-route.mjs <unit>`: `route: product` and the lane hand-off — `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) — the lane repairs the half, its `review` step re-judges it, then `/execute-phase` on this unit |
46
+ | ≥ 1 row with frozen class `replan-in-unit` or `decision-required` | `frozen (replan present)` | **freeze-batch** — nothing folds, no `folded: yes` flips, no commits; the receipt records the REPLAN-ROUTE and every retained (unfolded) row id; the loop stops; the consumer is the conclusion printed by `bun scripts/unit-route.mjs <unit>` (node fallback
47
+ if bun is not installed) (discovery step the fold already ran), where `<unit>` is the bare folder number or the full slug (both resolve): on `route: replan` the planner command the router printed — `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) — the lane appends the phases and its `review` step gates, then `/execute-phase` on this unit; on `route: decision` stop and surface the decision to the user, never a planner |
48
+ | ≥ 1 row with frozen class `fix-now` whose `Route` cell begins `product owner`, `product-owned` or `owned by product` (head-anchored, identical to `scripts/unit-route.mjs`'s `PRODUCT_ROUTE` regex: `/^(?:product[- ]owner\|product[- ]owned\|owned by product)\b/i`, per `#293`) | `frozen (product owner present)` | **freeze-batch** — nothing folds, no `folded: yes` flips, no commits; the receipt records the PRODUCT-ROUTE and every retained (unfolded) row id; the loop stops; the consumer is the conclusion printed by `bun scripts/unit-route.mjs <unit>` (node fallback
49
+ if bun is not installed): `route: product` and the lane hand-off — `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) — the lane repairs the half, its `review` step re-judges it, then `/execute-phase` on this unit |
48
50
  | all taken rows foldable, none replan-class | `all-repair-in-place` | fold as today (group → fix → gate → commit → flip) |
49
51
  | empty queue (zero findings taken) | `none` | receipt only |
50
52
 
@@ -60,7 +62,7 @@
60
62
  `DISPUTED <evidence → user decision>`; never edit classification or create an
61
63
  issue.
62
64
  9. **Replan.** If the smallest correct group exceeds a reviewable correction,
63
- run `node scripts/unit-route.mjs <unit>` — its `route: replan` line prints the
65
+ run `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed) — its `route: replan` line prints the
64
66
  planner command (`/unit-lane <slug>` for a feature, `/unit-lane --fix <n>` for
65
67
  a fix) that appends the proposed
66
68
  phases to the unit's SPEC. The `<unit>` argument accepts the bare folder number
@@ -17,7 +17,8 @@
17
17
  ```
18
18
 
19
19
  **A box that runs a command discloses what the command needs.** When a box
20
- invokes a script with a placeholder (`node scripts/x.mjs <unit-dir>`), the same
20
+ invokes a script with a placeholder (`bun scripts/x.mjs <unit-dir>`; node fallback
21
+ if bun is not installed), the same
21
22
  skill's text must name the artifact that placeholder requires — the script
22
23
  declares it (`PREREQUISITES` in `scripts/needs-input.mjs`) and
23
24
  `scripts/promise-coherence.mjs` checks the disclosure. A box that instructs a
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: pre-execution-review
3
3
  user-invocable: false
4
- version: 2.8.0
4
+ version: 2.8.2
5
5
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
6
6
  license: MIT
7
7
  description: >
@@ -8,13 +8,35 @@ Plan snapshot binds them, and `execute-phase` may not invent a substitute.
8
8
  |---|---|---|---|
9
9
  | Planning evidence | `### Planning evidence` inside the unit doc (XS/S) · separate file (M/L) | `unit-lane:planning-evidence` | `execute-phase`, `fold-findings`, `audit-pr` |
10
10
  | Obligations | `### Obligations` inside the unit doc (XS/S) · separate file (M/L) | `unit-lane:obligations` | `execute-phase`, `fold-findings`, `audit-pr` |
11
- | Findings | `review-findings.md` (one per unit, both stages) | reviewers append; only the stage's author resolves | `execute-phase` on re-review, `audit-pr` |
11
+ | Findings | the unit doc's `## Findings` (a migrated unit, issue #308) · `review-findings.md` (a legacy unit) | reviewers append; only the stage's author resolves | `execute-phase` on re-review, `audit-pr` |
12
12
 
13
13
  XS/S embeds both tables in the SPEC to stay within the size's artifact budget;
14
14
  the Plan snapshot then binds them through the whole-SPEC row (kind `spec`), and
15
15
  the `planning-evidence` / `obligations` snapshot rows are `absent`, not forged.
16
16
  M/L freeze the separate files and bind them with their own rows. Never both.
17
17
 
18
+ **One findings carrier per unit, one read path.** A unit opened after the
19
+ `spec-by-reference` re-cut (issue #308) carries its OPEN rows in the unit doc's
20
+ `## Findings` table and its folded history, review marks (`REVIEW-RAN`), finding
21
+ marks (`VF-<n>`) and gate runs (`GATE-RAN`) as `## Log` lines whose kind token is
22
+ the `log-kind@1` vocabulary. That unit has **no `review-findings.md`**. A legacy
23
+ unit keeps the side ledger it was written with and is never rewritten to migrate
24
+ it. Readers probe the doc first and fall back to the file; a unit with the
25
+ section never reads both, so a stale side file can never outvote the doc. The
26
+ carrier change retires nothing the review machinery produces: each mark a legacy
27
+ ledger row carried is a log line here, with the same identifier, the same head
28
+ SHA and the same exit code — no new receipt enters without one retiring.
29
+
30
+ Both carriers are **one truth class**: the `review-findings` row below owns the
31
+ writers of the OPEN rows and every mark in either carrier — the map keys one *file* per
32
+ class, so a migrated unit's `## Findings`/`## Log` are that ledger inside the unit doc,
33
+ never a new class or a second owner set. One mark, two grammars: review run =
34
+ `review-mark@1` row / `## Log` `R` line; gate run = `gate-ran@1` row / `G` line; finding
35
+ verification = `finding-mark@1` row / `V` line; folded finding = the `folded: no → yes`
36
+ flip / the row leaving for an `F` line; OPEN finding = seven-column row / six-column
37
+ `findings-table@1` row. A migrated unit has no `folded` cell to flip; a legacy unit has
38
+ no `R`/`V` grammar.
39
+
18
40
  ### 1. Planning evidence
19
41
 
20
42
  Row shape — the base row, the closed `authority-kind` / `freshness` vocabularies,
@@ -167,7 +189,9 @@ documentation, not by this map.
167
189
  A review that ends with no fix-now finding writes no finding row, so the map gives
168
190
  it a row of its own in the unit's `review-findings.md` ledger, under
169
191
  `review-change:review-mark`. [POLICY.md](POLICY.md) §8 owns *when* an act marks;
170
- this owns the shape:
192
+ this owns the shape. A **migrated** unit writes the same mark as a `## Log` `R` line —
193
+ `- **R<n>** — <date>, review at HEAD <40-hex> · verdict <verdict> · cycle <n> · gate
194
+ exit <code>` — and `scripts/workflow-status.mjs` reads either carrier, never both:
171
195
 
172
196
  ```text
173
197
  review-mark@1
@@ -203,6 +227,10 @@ or a re-review trigger. The mark's `confirmed | refuted` value and the
203
227
  `recheck` cell (the method the finding's axis demands) are what let a driver
204
228
  outside the repo consume the verification the review performed.
205
229
 
230
+ A **migrated** unit signs the same way as a `## Log` `V` line — `- **V<n>** —
231
+ <file:line> · reviewer <name> · HEAD <40-hex> · recheck <method + reproducer> ·
232
+ confirmed | refuted` — whose `recheck` cell `fold-findings` consumes.
233
+
206
234
  `fold-findings` reads the `recheck` cell to **materialize** the finding's
207
235
  reproducer as its regression check — it never re-derives it; a `recheck` cell
208
236
  that cannot be materialized yields `BLOCKED <missing input>`. This consumption
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: review-change
3
3
  user-invocable: true
4
- version: 3.12.1
4
+ version: 3.13.0
5
5
  argument-hint: <path-or-glob> [--adversarial N] [--synthesize]
6
6
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
@@ -27,7 +27,8 @@ lost, and none becomes reviewer-created backlog (D3):
27
27
  always fix-now / replan-in-unit — never a postpone/tradeoff/wontfix/new-issue
28
28
  escape.
29
29
  - **fix-now / `replan-in-unit`** (too large to fold as-is) → keeps its fix-now
30
- class and ledger row; run `node scripts/unit-route.mjs <unit>` — its
30
+ class and ledger row; run `bun scripts/unit-route.mjs <unit>` (node fallback
31
+ if bun is not installed) — its
31
32
  `route: replan` line prints the planner command (`/unit-lane <unit>` for a
32
33
  feature, `/unit-lane --fix <n>` for a fix). The lane re-runs its plan step on
33
34
  this branch, the user confirms the appended SPEC phase(s), its review step
@@ -4,16 +4,35 @@ When the unit's review receipt is missing or stale, the re-entry command is the
4
4
  **emitted** `next.continuation` (`rendering` for display) — quote it, never author
5
5
  exact command tokens.
6
6
 
7
- 11. **Persist fix-now findings to the fold ledger.** The unit's **fix-now fold
8
- ledger** is `review-findings.md`, located beside its other docs
7
+ 11. **Persist fix-now findings to the fold ledger.** A migrated unit (issue #308)
8
+ carries the ledger in its own `SPEC.md`: OPEN rows in `## Findings`, and the
9
+ review, gate and finding-verification marks as `## Log` lines (the `R`, `G` and
10
+ `V` kinds of the published `log-kind@1` vocabulary) carrying their exit codes and
11
+ head SHA. A legacy unit keeps the side file beside its other docs
9
12
  (`docs/features/<NN>-<slug>/review-findings.md` for a feature,
10
- `docs/fix/<n>-<topic>/review-findings.md` for a fix), fixed schema:
11
-
13
+ `docs/fix/<n>-<topic>/review-findings.md` for a fix). Probe the doc first and
14
+ write to exactly one carrier — a unit with the `## Findings` section never
15
+ gains a side file. Each carrier has **its own** fixed schema; a row is never
16
+ written in the other's grammar:
12
17
 
13
18
  ```
14
19
  | id | file:line | axis | severity | class | route | folded |
15
20
  ```
16
21
 
22
+ is the legacy schema, and only a legacy unit is written with it. A migrated unit
23
+ writes `findings-table@1` — six columns, no `folded` cell, and `class` holding
24
+ the owner that repairs the row (`product`/`plan`/`source`/`environment`/`runtime`)
25
+ while `route` holds the disposition (`fold`/`replan-in-unit`/`decision-required`/
26
+ `product owner — …`) — the grammar the unit doc itself publishes:
27
+
28
+ ```
29
+ | id | S# / file:line | axis | severity | class | route |
30
+ ```
31
+
32
+ `folded: no → yes` is therefore a **legacy-only** flip: in a migrated carrier a
33
+ closing fold deletes the row and appends its `## Log` `F` line, and `ledger-ownership@1`
34
+ / `fold-findings:folded-flag` stays the sole writer of whichever close it is.
35
+
17
36
  **Merged unit → no write** (a PR exists and its state is `MERGED` — check
18
37
  `gh pr view --json state` when a PR is open; otherwise the unit is unmerged
19
38
  by definition). Otherwise, for each **fix-now** finding of severity `high`
@@ -22,11 +41,12 @@ exact command tokens.
22
41
  `CLASSIFY.md`):
23
42
  append a row
24
43
  (create the file with the header row when missing), carrying the
25
- verbatim `Sev` value into `severity`; `folded` always starts `no` — that
44
+ verbatim `Sev` value into `severity`; a legacy row's `folded` always starts `no`
45
+ (a migrated row has no such cell — every row in `## Findings` is open) — that
26
46
  row comes from a **confirmed** candidate only and carries its
27
- `finding-mark@1` signature on a **separate `VF-` row** (reviewer, head SHA,
28
- recheck + reproducer), as modeled in `LEDGERS.md` (§finding-mark@1) and the
29
- fixture.
47
+ `finding-mark@1` signature as a **separate `VF-` row** in a legacy carrier, or as
48
+ a `## Log` `V` line in a migrated one (reviewer, head SHA, recheck + reproducer),
49
+ as modeled in `LEDGERS.md` (§finding-mark@1) and the fixture.
30
50
  `ledger-ownership@1` / `fold-findings:folded-flag` is the sole writer of
31
51
  the `folded: no → yes` flip.
32
52
  A `low` finding is **never persisted to the fold ledger** — report-only
@@ -138,7 +158,8 @@ exact command tokens.
138
158
  fix); the lane re-runs its plan step on this branch, its review step
139
159
  gates, then `/execute-phase <unit>` (yes: list the finding ids; no: omit
140
160
  this line)
141
- · any finding owned by product? → `node scripts/unit-route.mjs <unit>` prints
161
+ · any finding owned by product? → `bun scripts/unit-route.mjs <unit>` (node fallback
162
+ if bun is not installed) prints
142
163
  `route: product` + the lane hand-off — `/unit-lane <unit>` for a feature,
143
164
  `/unit-lane --fix <n>` for a fix: the lane repairs the half, its review
144
165
  step re-judges it (yes: list the ids; no: omit this line)
@@ -170,12 +170,20 @@ cycles without convergence, the review prints
170
170
  LOOP CAP REACHED — <unit>
171
171
  - Finding ids: <every open id>
172
172
  - Cycles: 2 (REVIEW-RAN marks + forge receipts)
173
- - Route: /triage-issue --prioritize-now <unit> F<k> … (or the programmatic outer driver)
173
+ - Expected diff: <per finding: files cited and whether it hits a normative surface>
174
+ - Decision: the owner decides — no route is auto-selected
174
175
  ```
175
176
 
176
177
  A **third cycle never starts** unless the user explicitly instructs it — it is
177
- the user's escape, never a reviewer election. The residue routes to
178
- `triage-issue --prioritize-now` (or the programmatic outer driver), and a unit
179
- that needs a third cycle has a planning or root-cause defect, not a review
180
- deficit. Re-runs count **separate review invocations**, not in-session steps:
181
- `/review-change` is invoked by the user in a fresh turn each time.
178
+ the user's escape, never a reviewer election. The cap **stops and hands the
179
+ decision back**, emitting no route of its own: this is the moment with the least
180
+ evidence about the findings, and an auto-selected escape is how a fix escapes
181
+ its own gate (F34).
182
+
183
+ **`--prioritize-now` is an escape, never the default.** The owner may force
184
+ `/triage-issue --prioritize-now <unit> F<k>` for an **in-scope** finding whose
185
+ expected diff is small: at most two files, no `normative-surfaces@1` surface, no
186
+ published contract or package version. Size is the only gate — a `security` or
187
+ `package` row is never "too expensive to fold now".
188
+ Re-runs are **separate review invocations** and not in-session steps:
189
+ `/review-change` is invoked by the user in a fresh turn.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: review-implementation
3
3
  user-invocable: false
4
- version: 1.11.1
4
+ version: 1.12.0
5
5
  argument-hint: <path-or-glob>
6
6
  allowed-tools: Read, Grep, Glob, Bash, WebFetch
7
7
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
@@ -69,6 +69,13 @@ then the current-unit contract (fix-now / replan-in-unit / decision-required
69
69
  for in-scope work), then `proposal` for genuinely independent future
70
70
  capabilities. One pass — no per-pass or per-reviewer classification.
71
71
 
72
+ Every classified row also carries an explicit `scope: in-unit | new-unit` cell
73
+ (`#308` review, F33) filled from evidence — the row's `file:line` against the
74
+ unit's `## Impact` set and the files the unit's own commits touch — never from
75
+ an impression of size or axis. Scope decides disposition (in-unit is always
76
+ `fix-now`); size decides only whether that fix folds directly or needs
77
+ `replan-in-unit`. `triage-issue` consumes the cell and never re-derives it.
78
+
72
79
  ## Context budget
73
80
 
74
81
  The input is the synthesized table, not the diff. Read at most 10 non-diff
@@ -97,7 +104,8 @@ each classification as its table row immediately and drop raw file content.
97
104
  rubric.
98
105
  - Sits in **Stage 4** of the feature workflow (verification & review).
99
106
  - `fix-now` folds into the current unit; `replan-in-unit` runs
100
- `node scripts/unit-route.mjs <unit>`, whose `route: replan` line names the
107
+ `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed),
108
+ whose `route: replan` line names the
101
109
  planner that appends user-confirmed phases before `execute-phase`;
102
110
  `decision-required` blocks for the user; independent work becomes proposals
103
111
  the user routes to `triage-issue` (D3).
@@ -96,6 +96,22 @@ reviewer-created issue creation are **forbidden** (AC 10). A previously approved
96
96
  trade-off is **cited as existing evidence**, never reinvented by review.
97
97
  `disputed` remains a later fold/user outcome, not a reviewer shortcut.
98
98
 
99
+ ### Scope is evidence, not impression (F33)
100
+
101
+ Every classified row carries a `scope: in-unit | new-unit` cell, contrasted
102
+ with what the unit declared:
103
+
104
+ | Answer | Test |
105
+ |---|---|
106
+ | **in-unit** | path in the unit's `## Impact` set, in files its commits touch, or a surface it created/moved/claimed unchanged |
107
+ | **new-unit** | path outside that set **and** the defect already exists at the base commit |
108
+ | **undecidable** | the set is missing or the path is ambiguous — state the gap; never guess `new-unit` to escape |
109
+
110
+ **Scope decides disposition, never size:** an in-unit defect is `fix-now`
111
+ whatever its axis (`security`/`package` included); size only chooses fold vs
112
+ `replan-in-unit`. "The unit did it" outranks "the path looks foreign".
113
+ `triage-issue` consumes the cell, never re-derives it.
114
+
99
115
  ### Step 3 — Independent future capabilities → proposals, never issues
100
116
 
101
117
  Only a **truly independent future capability** — work the current unit does not
@@ -109,7 +125,7 @@ the user routes a proposal to `triage-issue`.
109
125
  An in-scope fix-now too large to fold as-is (multi-file redesign, or evidence
110
126
  the unit should have been split) keeps its **fix-now** class — size is never a
111
127
  reason to downgrade. Set its `Route` to **`replan-in-unit`**: run
112
- `node scripts/unit-route.mjs <unit>` — its `route: replan` line prints the
128
+ `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed) — its `route: replan` line prints the
113
129
  planner command (`/unit-lane <unit>` for a feature, `/unit-lane --fix <n>` for a
114
130
  fix) — and the unit's SPEC `## Phases`
115
131
  ledger gets one or more new phases covering the work, on the SAME branch, the
@@ -152,7 +168,8 @@ your domains):
152
168
 
153
169
  - **fix-now** → fold directly into the current unit's open phase; never a
154
170
  tracked issue, never a standalone planner (AC 12).
155
- - **fix-now / `replan-in-unit`** → `node scripts/unit-route.mjs <unit>` prints
171
+ - **fix-now / `replan-in-unit`** → `bun scripts/unit-route.mjs <unit>` (node fallback
172
+ if bun is not installed) prints
156
173
  `route: replan`; the planner command it prints re-cuts the SPEC `## Phases`
157
174
  ledger
158
175
  (user confirms), the lane's `review` step gates, then `execute-phase`
@@ -174,8 +191,8 @@ finding in its `Route` cell.
174
191
  | Owning stage | Hand-off | Never |
175
192
  |---|---|---|
176
193
  | `source` | fold locally: `/fold-findings`, then re-run `/review-change` on the changed HEAD | — |
177
- | `plan` | run `node scripts/unit-route.mjs <unit>` → `route: replan`; the planning author re-cuts the artifact (SPEC `## Phases`, an obligation row, an acceptance mapping, a ledger) on the same branch with the user's confirmation, then the lane's **`review` step** precedes `execute-phase` | fold it in code and leave the plan describing the old build |
178
- | `product` | run `node scripts/unit-route.mjs <unit>` → `route: product` → `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix): the lane repairs the half through its `design` step, its `review` step re-judges it | patch the product claim into agreement in code |
194
+ | `plan` | run `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed) → `route: replan`; the planning author re-cuts the artifact (SPEC `## Phases`, an obligation row, an acceptance mapping, a ledger) on the same branch with the user's confirmation, then the lane's **`review` step** precedes `execute-phase` | fold it in code and leave the plan describing the old build |
195
+ | `product` | run `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed) → `route: product` → `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix): the lane repairs the half through its `design` step, its `review` step re-judges it | patch the product claim into agreement in code |
179
196
  | `environment` / `runtime` | the existing retry/`BLOCKED` paths | translate into a PASS, or an issue |
180
197
 
181
198
  - `fix-now` with a `plan` or `product` owner keeps its severity but is **not**
@@ -1,15 +1,16 @@
1
1
  ---
2
2
  name: triage-issue
3
3
  user-invocable: true
4
- version: 2.11.0
4
+ version: 2.12.0
5
5
  argument-hint: <issue-number> [more issue numbers…] | <audit-id> F<k> [F<j>…] | --prioritize-now <unit> F<k> [F<j>…]
6
6
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
8
8
  description: >
9
9
  Verify an issue, persisted audit finding, or unresolved review finding against
10
10
  current code, classify it, and write only the contracted forge/ledger
11
- outcome. Supports independent batches and an immediate-fix review-finding
12
- route. Triggers: "triage-issue", "triage issue N", "triage this finding",
11
+ outcome. Supports independent batches and a routed review-finding
12
+ route: a `fix-now` row is handed to `/fold-findings`, never implemented
13
+ here. Triggers: "triage-issue", "triage issue N", "triage this finding",
13
14
  "is this trigger met".
14
15
  ---
15
16
 
@@ -25,7 +26,7 @@ premature work (acting on a deferred item whose trigger is unmet) and silent rot
25
26
  ✓ One fixed-format verdict block per issue (Trigger / Checked / Evidence / VERDICT / Action) — plus the summary table when batched
26
27
  ✓ Nothing deferred was implemented inline
27
28
  ✓ Audit-finding mode (`<audit-id> F<k>`): the audit file carries its `↳ triaged` note, and any opened issue cites `Origin: product audit <id>, finding F<k>`
28
- ✓ Review-finding mode (`--prioritize-now <unit> F<k>`): every named unresolved finding gets a verdict, an immediate-fix attempt, or an explicit replan/user-decision route
29
+ ✓ Review-finding mode (`--prioritize-now <unit> F<k>`): every named unresolved finding gets a verdict **and a route** — a `fix-now` row is routed to `/fold-findings` (or an explicit `/execute-phase <unit> P<n>`), never implemented in this turn
29
30
  ✓ Batched input? The closing recommendation maps every issue/finding ID to its own next command, joined with ` + `; it never collapses to one generic action
30
31
  ✓ Artifact language: explicit user instruction > the project's declared docs language > English. The CONVERSATION language never decides — a Spanish prompt still produces English PRs/issues/commits/SPECs unless one of the first two says otherwise
31
32
  ✓ The closing `→ Next:` block is printed as the ABSOLUTE last output
@@ -47,10 +48,14 @@ first on purpose).
47
48
  from a persisted `product-audit` report instead of existing issues (see
48
49
  *Audit-finding mode* below). Batching works the same way.
49
50
  - **Review findings** — `triage-issue --prioritize-now <unit> F<k> [F<j> …]`
50
- triages unresolved rows from the current feature/fix unit's
51
- `review-findings.md`. This route is for findings that `fold-findings` could
52
- not close. `--prioritize-now` means attempt to resolve every named finding
53
- immediately; it does not permit a downgrade, postponement, or silent drop.
51
+ triages unresolved rows from the current feature/fix unit's findings carrier:
52
+ its `## Findings` section in `SPEC.md` for a migrated unit (issue #308), or
53
+ `review-findings.md` for a legacy one — probe the doc first, never both. This
54
+ route is for findings that `fold-findings` could not close. `--prioritize-now`
55
+ forces the fold route for the named rows in this turn instead of queuing them
56
+ for a later turn; it does not permit a downgrade, postponement, or silent
57
+ drop, and it never authorizes implementing them here — the fold owns the fix
58
+ and the `folded:` flip.
54
59
 
55
60
 
56
61
  ## Step 0 — Discover the project (always first)
@@ -86,7 +91,7 @@ read another `references/` path. After Step 0:
86
91
  - Before applying an urgency or disposition label, read
87
92
  [label vocabulary](references/LABELS.md); this file is the sole definition of
88
93
  names, colors, and mutation rules.
89
- - Only when the verdict is `fix-in-unit`, read
94
+ - Only when the verdict writes a row (`fix-in-unit` or `fix-now`), read
90
95
  [fold ledger](references/FOLD_LEDGER.md) before writing the row.
91
96
 
92
97
  Every resource is one hop from this file. A missing source artifact or required
@@ -121,9 +126,10 @@ triage-issue ────┤ or fold-findings (ledger row)
121
126
  └─ wontfix ─────────▶ propose close
122
127
  ```
123
128
 
124
- In review-finding mode, `replan-in-unit` runs `node scripts/unit-route.mjs
125
- <unit>`: its `route: replan` line prints the planner command — `/unit-lane
126
- <unit>` for a feature, `/unit-lane --fix <n>` for a fix — which re-runs the
129
+ In review-finding mode, `replan-in-unit` runs `bun scripts/unit-route.mjs
130
+ <unit>` (node fallback if bun is not installed): its `route: replan` line prints
131
+ the planner command — `/unit-lane <unit>` for a feature, `/unit-lane --fix <n>`
132
+ for a fix — which re-runs the
127
133
  lane's `plan` catalog step and appends new `P<n>` phases to the same unit. The
128
134
  lane's own `review` step is the gate before execution. The user manually runs
129
135
  those phases; this skill never implements them.
@@ -1,14 +1,22 @@
1
1
  ## Ledger-append mechanism (`fix-in-unit` → fold-into-ledger sub-route)
2
2
 
3
3
  When the *fold into the unit's ledger* sub-route (step 3 above) applies,
4
- append one row to the open unit's `review-findings.md` — the same fold ledger
5
- `review-change` and `audit-pr` write to, in their **fixed 7-column schema,
6
- never redefined here**:
4
+ append one row to the open unit's findings carrier — probe the unit doc first: a
5
+ migrated unit (#308) carries its OPEN rows in `SPEC.md ## Findings` and never gains
6
+ a side file, a legacy unit keeps `review-findings.md`. It is the same fold ledger
7
+ `review-change` and `audit-pr` write to, in the **carrier's own fixed schema, never
8
+ redefined here** — the legacy 7-column row:
7
9
 
8
10
  ```
9
11
  | id | file:line | axis | severity | class | route | folded |
10
12
  ```
11
13
 
14
+ and the migrated 6-column `findings-table@1` row (`id`, `S# / file:line`, `axis`,
15
+ `severity`, `class` = the owner that repairs it, `route` = the disposition), whose
16
+ rows are open by definition: closing one deletes the row and appends a `## Log` `F`
17
+ line. Writing a 7-column row, or a `folded` flip, into a migrated unit's table is a
18
+ carrier violation, not a formatting slip.
19
+
12
20
  The appended row: `folded` starts `no` (this skill never sets `folded: yes` —
13
21
  that transition belongs solely to `/fold-findings`), and the `route` cell
14
22
  carries a **provenance marker** identifying this row was born from a triage
@@ -22,8 +22,9 @@
22
22
  issue on that unit's own branch, never as a new standalone unit. Pick
23
23
  exactly one of these sub-routes:
24
24
  - *repairable as-is* → **fold into the unit's** current/next phase, or
25
- append a provenance-marked row to the unit's `review-findings.md` (see
26
- *Ledger-append mechanism* below).
25
+ append a provenance-marked row to the unit's findings carrier — `SPEC.md
26
+ ## Findings` for a migrated unit (#308), `review-findings.md` for a legacy
27
+ one, never both (see *Ledger-append mechanism* below).
27
28
  - *changes the unit's shape* → **incremental replan** on the same unit:
28
29
  name the exact command — `/unit-lane <slug>` (the lane re-reads the
29
30
  SPEC, re-triages, and re-runs its `design`/`plan` catalog steps) — or a
@@ -4,8 +4,12 @@ Use this route only for `/triage-issue --prioritize-now <unit> F<k> [F<j> …]`
4
4
  after `/fold-findings` leaves rows unresolved.
5
5
 
6
6
  1. Read the target unit's SPEC, frozen acceptance, current PR HEAD, the full
7
- `review-findings.md`, and the evidence for every named row. Confirm that
8
- each row is still `folded: no`; never triage a row already folded.
7
+ findings carrier — the unit doc's `## Findings` for a migrated unit (#308),
8
+ `review-findings.md` for a legacy one, probed in that order and never both —
9
+ and the evidence for every named row. Confirm the row is still open in its own
10
+ carrier: `folded: no` in a legacy ledger, still present in `## Findings` for a
11
+ migrated unit (a folded row has left that table for a `## Log` `F` line); never
12
+ triage a row already folded.
9
13
  2. Reproduce or verify every finding against the current code. Keep the
10
14
  finding's original ID, severity, class, and route in the report. Do not
11
15
  turn a review finding into a generic issue just to make it disappear.
@@ -13,11 +17,16 @@ after `/fold-findings` leaves rows unresolved.
13
17
 
14
18
  - A complete correction that fits the current unit and is reviewable now
15
19
  remains on the current unit. Route it to `/fold-findings` or an explicit
16
- `/execute-phase <unit> P<n>`.
20
+ `/execute-phase <unit> P<n>` — **never implement it in this turn**. The
21
+ fold owns the fix, the gate and the `folded:` flip: writing the flip here
22
+ would make this skill the second owner of a state
23
+ `ledger-ownership@1` assigns solely to `fold-findings:folded-flag`
24
+ (`LEDGERS.md`), so a row this skill appends starts `folded: no` and stays
25
+ that way until the fold closes it.
17
26
  - A correction too large for the current fold is `replan-in-unit`. Run
18
- `node scripts/unit-route.mjs <unit>`; its `route: replan` line prints the
19
- planner command — `/unit-lane <unit>` for a feature, `/unit-lane --fix <n>`
20
- for a fix — which re-runs the lane's `plan` step and appends concrete
27
+ `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed);
28
+ its `route: replan` line prints the planner command — `/unit-lane <unit>` for a
29
+ feature, `/unit-lane --fix <n>` for a fix — which re-runs the lane's `plan` step and appends concrete
21
30
  `P<n>` phases to the unit's SPEC, preserving the finding's acceptance
22
31
  evidence. The lane's `review` step gates execution.
23
32
  - A product, architecture, or acceptance decision that blocks safe work is
@@ -26,8 +35,8 @@ after `/fold-findings` leaves rows unresolved.
26
35
  and show the evidence; do not mark it folded or silently delete it.
27
36
  - A `fix-now` finding whose owning stage is `product` — the finding is
28
37
  against the product half, not the code — is `product-repair` (#293). Run
29
- `node scripts/unit-route.mjs <unit>`; its `route: product` line prints the
30
- lane hand-off (`/unit-lane <unit>` for a feature, `/unit-lane --fix <n>`
38
+ `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed);
39
+ its `route: product` line prints the lane hand-off (`/unit-lane <unit>` for a feature, `/unit-lane --fix <n>`
31
40
  for a fix): the lane repairs the half, its review step re-judges it. Never
32
41
  fold it into the current unit — the fold loop repairs source, not
33
42
  authority (`pre-execution-review` POLICY §4).
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: unit-lane
3
3
  user-invocable: true
4
- version: 2.4.1
4
+ version: 2.4.3
5
5
  argument-hint: <NN-slug | "<idea>"> [--retriage] | --fix <issue-number> | --from-issue <issue-number>
6
6
  description: >
7
7
  One-shot lane conductor for a delivery unit: triage, implement, evidence, and
@@ -23,8 +23,9 @@ done:
23
23
  ```
24
24
  ✓ Required user inputs were answered concretely (not defaulted). Nothing here
25
25
  is inferred: a gap re-enters provenance → research, and a gap surviving both
26
- runs `node scripts/needs-input.mjs <unit-dir>` and stops with the
27
- `open-questions@1` block routed back to the owning stage.
26
+ runs `bun scripts/needs-input.mjs <unit-dir>` (node fallback if bun is not
27
+ installed) and stops with the `open-questions@1` block routed back to the
28
+ owning stage.
28
29
  ✓ Every claim the SPEC or the plan asserts (objective, why, ACs, tasks) cites
29
30
  its source — `path:line`, a doc, or an owner answer in the unit folder's
30
31
  `sources.md`. A claim with none is a question, never a default.
@@ -37,8 +38,9 @@ done:
37
38
  if new, with all mandatory sections filled or n/a)
38
39
  ✓ Guard ran (bun scripts/diff-guard.mjs --base <ref>) after each implement step;
39
40
  on BREACH: re-triage or record exception, never shrink the diff
40
- ✓ Unit doc's Evidence rows updated (command → exit/digest → output → verified-by)
41
- and Progress log updated (dated entry) before every commit
41
+ ✓ The unit's evidence carrier updated (Evidence rows, or `## Log` `E` lines for a
42
+ re-cut unit — command → exit/digest → output → verified-by) and its progress
43
+ recorded (dated Progress entry, or a `## Log` `P` line) before every commit
42
44
  ✓ Memory boundaries ran — probe verdict once, saves at unit start / each phase
43
45
  transition / close under `unit/<NN-slug>/doc`, degradation recorded as pending
44
46
  ✓ → Next: block printed as the absolute last output
@@ -6,7 +6,7 @@ A blank or vague scope or acceptance-criteria input is a gap, not a licence to
6
6
  infer. The order is fixed: search the repository's own docs first and append an
7
7
  `open-question` row to the unit folder's `decisions.md` recording where; research
8
8
  an external gap into 2–3 concrete options. A gap surviving both runs
9
- `node scripts/needs-input.mjs <unit-dir>`, pastes the `open-questions@1` block
9
+ `bun scripts/needs-input.mjs <unit-dir>` (node fallback if bun is not installed), pastes the `open-questions@1` block
10
10
  and stops — route `design` for scope/architecture questions. "Decide for me" is
11
11
  a legitimate answer: the lane chooses and records the choice with its reason.
12
12
  Cheap-to-change defaults are recorded as assumptions, never silent.
@@ -7,12 +7,16 @@ output (≤2 lines), verified-by. A reviewer re-runs it.
7
7
 
8
8
  ## Inputs
9
9
 
10
- - The unit's Acceptance criteria
11
- - The Evidence section (where evidence rows are appended)
10
+ - The unit's Acceptance criteria (`## Acceptance criteria`, or `## Specs` for a
11
+ re-cut unit — `scripts/unit-route.mjs` resolves the shape)
12
+ - The unit's evidence carrier: the `## Evidence` section (legacy shape) or the
13
+ `## Log` section (re-cut shape, where each run is one `E` line)
12
14
 
13
15
  ## Fixed output contract
14
16
 
15
- Append to the unit doc's **Evidence** table. One row per AC:
17
+ Append one row per AC to the unit doc's **Evidence** table (legacy shape). A
18
+ re-cut unit (#308) has no Evidence section: append one `## Log` `E` line per AC in
19
+ the same order, carrying the same five facts.
16
20
 
17
21
  | AC | What was run | Exit / digest | Output (≤2 lines) | Verified-by |
18
22
  |---|---|---|---|---|
@@ -166,7 +166,17 @@ name those files instead.
166
166
  - [ ] Each task names its validator (a backticked command plus its expected outcome)
167
167
  - [ ] Final task is verification (proves the whole unit works)
168
168
  - [ ] No task reaches into a future-phase concern (docs, release, migrations)
169
- - [ ] Phases labeled P1, P2, … (never S1, Step 1)
169
+ - [ ] Phases labeled P1, P2, … — `#308`: `S#` is the requirement id (a spec),
170
+ `P#` is the phase label (a task); the two vocabularies never swap roles
171
+ - [ ] Each requirement is cut from the request verbatim: numbered `S#` in
172
+ `## Specs`, one per distinct ask, with the requester's own words as its
173
+ quote and no requirement the request did not make
174
+ - [ ] A later correction is appended under its own id (`S1a`) and leaves the
175
+ requirement it corrects untouched
176
+ - [ ] Every task bullet names the `S#` it delivers on its `(Implements: …)` line
177
+ - [ ] The `## Log` is opened with `L1` = the request verbatim, and later entries
178
+ append (never rewrite) in the `log-kind@1` vocabulary
179
+ - [ ] `## Findings` is present and carries only OPEN rows (empty at plan time)
170
180
  - [ ] Both planning ledgers are cut (planning evidence + obligations), in the
171
181
  sizing rule's home, with stable ids
172
182
 
@@ -7,9 +7,9 @@ them, not the user. A blank or missing objective/scope is therefore a **document
7
7
  defect**: stop and repair the SPEC (`/unit-lane <unit>` — its §1 writes the
8
8
  objective/why/user-outcome) or re-triage. Never infer unit scope, and never
9
9
  turn a doc defect into a question the user cannot answer. A gap that survives
10
- the repair runs `node scripts/needs-input.mjs <unit-dir>`, pastes the
11
- `open-questions@1` block and stops, routed to `design` or `unit-lane` by the
12
- owning stage.
10
+ the repair runs `bun scripts/needs-input.mjs <unit-dir>` (node fallback if bun is
11
+ not installed), pastes the `open-questions@1` block and stops, routed to `design`
12
+ or `unit-lane` by the owning stage.
13
13
 
14
14
  ## Purpose
15
15
 
@@ -1,15 +1,16 @@
1
1
  ---
2
2
  name: verification-contract
3
3
  user-invocable: false
4
- version: 1.4.3
4
+ version: 1.5.0
5
5
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
6
6
  license: MIT
7
7
  description: >
8
8
  Internal contract: the acceptance artifact per delivery unit — legacy (pre-
9
9
  feature 61) units may carry a frozen `ACCEPTANCE.md` (binding if present);
10
10
  post-feature 61 units use the unit doc's `## Acceptance criteria` section as
11
- the canonical acceptance source; the unit doc's `## Evidence` table serves as
12
- the execution receipt. Consumed by planners, execute-phase, and review-change.
11
+ the canonical acceptance source; the unit doc's evidence carrier — `## Evidence`
12
+ table, or `## Log` `E` lines for a re-cut unit (#308) — serves as the execution
13
+ receipt. Consumed by planners, execute-phase, and review-change.
13
14
  ---
14
15
 
15
16
  # Verification Contract (internal)
@@ -63,9 +64,10 @@ v1` is needed: property/fuzz rides the existing `commands` class.
63
64
 
64
65
  ## Freeze and receipt
65
66
 
66
- The unit doc's `## Evidence` table is the execution receipt: each Evidence row
67
- records a validator command, its exit code or blob digest, output excerpt, and
68
- who verified it. A frozen criterion's receipt is the Evidence row for that
67
+ The unit doc's own evidence carrier is the execution receipt: the `## Evidence`
68
+ table for a legacy-shape unit, the `## Log` `E` lines for a re-cut one (#308). Each
69
+ row or line records a validator command, its exit code or blob digest, output
70
+ excerpt, and who verified it. A frozen criterion's receipt is the Evidence row for that
69
71
  criterion — exact match continues; missing/mismatched evidence stops before
70
72
  edits:
71
73
 
@@ -122,4 +124,4 @@ semantics are verified against authoritative documentation **before a test encod
122
124
 
123
125
  ## Done when
124
126
 
125
- Execution receipt (unit doc `## Evidence` table for post-feature 61 units; legacy `ACCEPTANCE.md` manifest binding-if-present) + named validators + literal quality floor; executor and reviewer evaluate identical evidence.
127
+ Execution receipt (unit doc `## Log` `E` lines for a re-cut unit, `## Evidence` table for a post-feature 61 one; legacy `ACCEPTANCE.md` manifest binding-if-present) + named validators + literal quality floor; executor and reviewer evaluate identical evidence.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: workflow-status
3
3
  user-invocable: true
4
- version: 3.9.2
4
+ version: 3.9.4
5
5
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
6
6
  license: MIT
7
7
  argument-hint: "[--json-only] [--last-envelope <json|path>] [--compact]"
@@ -69,7 +69,9 @@ bytes on a mature repo); the exact keep/drop set is in
69
69
  Per the agent guide's **Workflow conventions** + **documentation map**. The
70
70
  script reads what THIS skill needs (`docs/features/ROADMAP.md`, the fix index
71
71
  `docs/fix/README.md`, every in-flight feature folder's `TASKS.md` +
72
- `progress.md` + `review-findings.md`, and `docs/workflow/REPOSITORY_STATE.md`);
72
+ `progress.md` and its findings carrier — `SPEC.md` `## Findings` + `## Log` for a
73
+ migrated unit (issue #308), `review-findings.md` for a legacy one — and
74
+ `docs/workflow/REPOSITORY_STATE.md`);
73
75
  read them yourself only to interpret a field the script emitted.
74
76
 
75
77
  ## Progressive loading — fixed sensor route
@@ -104,7 +104,9 @@ Exactly two fields change:
104
104
  `in-progress` stays in both modes, so `detail.startable_now` and
105
105
  `detail.blocked_units` keep naming every unit either way.
106
106
  - `findings.fix_now[].route`: the reviewer's multi-paragraph evidence memo becomes
107
- `...(N char evidence, see the unit review-findings.md)`, keeping the original
107
+ `...(N char evidence, see the unit review-findings.md)` for a legacy carrier and
108
+ `...(N char evidence, see the unit SPEC.md ## Findings)` for a migrated one (#308),
109
+ keeping the original
108
110
  length visible. `id`, `file`, `axis`, `severity`, `class` and `suggested_tier`
109
111
  are untouched, and the memo is on disk in the unit's `review-findings.md`, which
110
112
  is where the fold reads it.