@gtrabanco/pi-agentic-workflow 0.30.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 (45) hide show
  1. package/README.md +41 -0
  2. package/dist/config/defaults.js +3 -0
  3. package/dist/config/merge.js +5 -0
  4. package/dist/config/schema.d.ts +0 -5
  5. package/dist/config/schema.js +31 -1
  6. package/dist/config/types.d.ts +15 -0
  7. package/dist/extension/engram.d.ts +119 -0
  8. package/dist/extension/engram.js +187 -0
  9. package/dist/extension/index.js +70 -3
  10. package/dist/settings/console.js +68 -22
  11. package/package.json +1 -1
  12. package/skills/audit-pr/SKILL.md +1 -1
  13. package/skills/audit-pr/references/03_AUDIT_PROCESS.md +3 -2
  14. package/skills/execute-phase/SKILL.md +22 -8
  15. package/skills/execute-phase/references/EXECUTION_CONTRACT.md +15 -9
  16. package/skills/execute-phase/references/FOLDING.md +11 -8
  17. package/skills/execute-phase/references/PREFLIGHT.md +7 -3
  18. package/skills/fold-findings/SKILL.md +28 -17
  19. package/skills/fold-findings/references/FOLD_PROCESS.md +5 -3
  20. package/skills/init-workspace/SKILL.md +13 -2
  21. package/skills/init-workspace/references/BOOTSTRAP_WRITE.md +11 -5
  22. package/skills/init-workspace/references/ENGRAM.md +107 -0
  23. package/skills/log-session/SKILL.md +17 -1
  24. package/skills/orchestration-envelope/references/TURN_CONTRACT.md +2 -1
  25. package/skills/pre-execution-review/SKILL.md +1 -1
  26. package/skills/pre-execution-review/references/LEDGERS.md +30 -2
  27. package/skills/review-change/SKILL.md +1 -1
  28. package/skills/review-change/references/OUTPUT_AND_GUARDRAILS.md +2 -1
  29. package/skills/review-change/references/PERSIST_AND_DECIDE.md +30 -9
  30. package/skills/review-change/references/REVIEW_PROCESS.md +14 -6
  31. package/skills/review-implementation/SKILL.md +10 -2
  32. package/skills/review-implementation/references/CLASSIFY.md +21 -4
  33. package/skills/triage-issue/SKILL.md +18 -12
  34. package/skills/triage-issue/references/FOLD_LEDGER.md +11 -3
  35. package/skills/triage-issue/references/ISSUE_PROCESS.md +3 -2
  36. package/skills/triage-issue/references/REVIEW_FINDING_PROCESS.md +17 -8
  37. package/skills/unit-lane/SKILL.md +23 -5
  38. package/skills/unit-lane/references/DESIGN.md +1 -1
  39. package/skills/unit-lane/references/EVIDENCE.md +7 -3
  40. package/skills/unit-lane/references/MEMORY.md +179 -0
  41. package/skills/unit-lane/references/PLAN.md +11 -1
  42. package/skills/unit-lane/references/RESEARCH.md +3 -3
  43. package/skills/verification-contract/SKILL.md +9 -7
  44. package/skills/workflow-status/SKILL.md +4 -2
  45. package/skills/workflow-status/references/ENVELOPE_FIELDS.md +3 -1
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: log-session
3
3
  user-invocable: true
4
- version: 2.2.1
4
+ version: 2.3.0
5
5
  argument-hint: "[note to prepend to the entry]"
6
6
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
@@ -124,6 +124,22 @@ the HEAD sha and start time at session open.
124
124
  open a PR just for a log entry, and never `git add -A` here — a concurrent
125
125
  conversation's work must not be swept into a log commit.
126
126
 
127
+ ## The canonical split — this skill's half (feature 66, D2)
128
+
129
+ Two writers exist on purpose; neither mirrors the other:
130
+
131
+ - **`docs/LOGS.md` (this skill)** is the **human/team journal** — what a session
132
+ set out to do, what it decided, where to resume. It travels with git, so a
133
+ teammate or a fresh clone reads it with no local state.
134
+ - **Engram (`mem_session_summary`, and the lane's `unit/<NN-slug>/doc` topic)**
135
+ is **local decision and gotcha recall keyed by unit id**, written by
136
+ `unit-lane` and `execute-phase` at unit boundaries. It stays on the machine.
137
+
138
+ Engram never mirrors this log, and this log never mirrors Engram: team memory
139
+ travels with git, agent recall stays local. Write the journal half here; the
140
+ protocol half (boundaries, recall order, degradation) lives in the lane's
141
+ memory reference, `../unit-lane/references/MEMORY.md`.
142
+
127
143
  ## Guardrails
128
144
 
129
145
  - **Never use an expensive model for this.** It's summarization; `qwen3.6`
@@ -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.3.0
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,11 @@ 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
44
+ ✓ Memory boundaries ran — probe verdict once, saves at unit start / each phase
45
+ transition / close under `unit/<NN-slug>/doc`, degradation recorded as pending
42
46
  ✓ → Next: block printed as the absolute last output
43
47
  ```
44
48
 
@@ -167,6 +171,20 @@ Before every commit:
167
171
  - **Progress log**: `YYYY-MM-DD HH:MM — <what was done> → <commit sha> — next:
168
172
  <what is next>`
169
173
 
174
+ ### 5b. Memory boundaries
175
+
176
+ Engram is the required memory substrate; a down layer never blocks a unit —
177
+ follow [the memory protocol](references/MEMORY.md).
178
+
179
+ - **Probe once**, before the first memory read: `agentic-workflow memory probe`
180
+ → paste the verdict into Evidence; `degraded` is recorded and said once.
181
+ - **Save at unit start, each phase transition, and close** under
182
+ `topic_key: "unit/<NN-slug>/doc"`, with explicit `project` and explicit
183
+ session attribution (§5 names what carries it on each write surface).
184
+ - **Recall** `mem_context` → scoped search → one explicit `all_projects: true`
185
+ retry → `mem_get_observation` → the unit doc wins. A miss is keyword-bound,
186
+ never proof nothing was saved; an unavailable mirror is marked pending.
187
+
170
188
  ### 6. Close the unit — the close-out ladder
171
189
 
172
190
  When all triaged steps are done, in order:
@@ -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
  |---|---|---|---|---|