@gtrabanco/pi-agentic-workflow 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.es.md +3 -3
  2. package/README.md +3 -3
  3. package/package.json +2 -1
  4. package/skills/design-feature/SKILL.md +31 -2
  5. package/skills/evidence-grounding/SKILL.md +7 -2
  6. package/skills/evidence-grounding/references/ROWS.md +1 -1
  7. package/skills/execute-phase/SKILL.md +6 -4
  8. package/skills/execute-phase/references/BATCH_AND_PORTABILITY.md +5 -4
  9. package/skills/execute-phase/references/CLOSEOUT.md +5 -4
  10. package/skills/execute-phase/references/FOLDING.md +3 -2
  11. package/skills/execute-phase/references/UNIT_LOOP.md +1 -2
  12. package/skills/fold-findings/SKILL.md +1 -1
  13. package/skills/fold-findings/references/FOLD_POLICY.md +7 -0
  14. package/skills/plan-feature-scaffold/SKILL.md +13 -1
  15. package/skills/plan-fix/SKILL.md +13 -1
  16. package/skills/pre-execution-review/SKILL.md +1 -1
  17. package/skills/pre-execution-review/references/LEDGERS.md +23 -1
  18. package/skills/pre-execution-review/references/POLICY.md +1 -1
  19. package/skills/review-change/SKILL.md +10 -7
  20. package/skills/review-change/references/PERSIST_AND_DECIDE.md +16 -9
  21. package/skills/review-change/references/REVIEW_PROCESS.md +41 -5
  22. package/skills/review-code/SKILL.md +3 -1
  23. package/skills/review-implementation/SKILL.md +1 -1
  24. package/skills/review-implementation/references/CLASSIFY.md +1 -1
  25. package/skills/review-plan/SKILL.md +1 -1
  26. package/skills/review-plan/references/OUTPUT.md +2 -2
  27. package/skills/review-spec/SKILL.md +1 -1
  28. package/skills/review-spec/references/OUTPUT.md +1 -1
  29. package/skills/ship-roadmap/SKILL.md +2 -2
  30. package/skills/ship-roadmap/references/ADVANCE.md +6 -5
  31. package/skills/ship-roadmap/references/MODEL_ROUTING.md +1 -1
  32. package/skills/triage-issue/SKILL.md +1 -1
  33. package/skills/triage-issue/references/REVIEW_FINDING_PROCESS.md +1 -1
  34. package/skills/verification-contract/SKILL.md +13 -2
  35. package/skills/loop-review-fold/SKILL.md +0 -200
package/README.es.md CHANGED
@@ -47,7 +47,6 @@ no reciben comando propio — los componen los de arriba:
47
47
  | `/generate-docs` | Generar guías incrementales basadas en el diff. |
48
48
  | `/init-workspace` | Adaptar el andamiaje del workflow a un repositorio. |
49
49
  | `/log-session` | Añadir una entrada de sesión estructurada a `docs/LOGS.md`. |
50
- | `/loop-review-fold` | Revisar una unidad y plegar lo que encontró. |
51
50
  | `/plan-feature` | Dirigir el trabajo diseñado a planificación y roadmap. |
52
51
  | `/plan-fix` | Redactar un SPEC de fix por fases desde uno o varios issues. |
53
52
  | `/product-audit` | Auditar la superficie del producto, no solo el diff. |
@@ -146,8 +145,9 @@ archivo de proyecto mientras el proyecto no sea de confianza.
146
145
 
147
146
  ## Notas
148
147
 
149
- - Probado con Pi 0.84.3 (`pi install`, skills de paquete, `sendUserMessage` con
150
- expansión de plantillas).
148
+ - Probado con Pi 0.85.0 (2026-09-04) (`pi install`, skills de paquete, registro de
149
+ comandos amigables, set/clear enrutado, round-trip de consola de ajustes,
150
+ `sendUserMessage` con expansión de plantillas).
151
151
  - El paquete declara Pi como peer dependency; no incluye ninguna copia de Pi.
152
152
  - Las skills pueden indicar al modelo que ejecute comandos. Revísalas como con
153
153
  cualquier paquete de terceros.
package/README.md CHANGED
@@ -45,7 +45,6 @@ their own — they are composed by the ones above:
45
45
  | `/generate-docs` | Generate incremental, diff-driven developer guides. |
46
46
  | `/init-workspace` | Adapt the workflow scaffold to a repository. |
47
47
  | `/log-session` | Append a structured session entry to `docs/LOGS.md`. |
48
- | `/loop-review-fold` | Review a unit, then fold what it found. |
49
48
  | `/plan-feature` | Route designed work into planning and the roadmap. |
50
49
  | `/plan-fix` | Draft a phased fix SPEC from one or more issues. |
51
50
  | `/product-audit` | Audit the product surface, not just the diff. |
@@ -140,8 +139,9 @@ touch the project file while the project is untrusted.
140
139
 
141
140
  ## Notes
142
141
 
143
- - Verified against Pi 0.84.3 (`pi install`, package skills, `sendUserMessage` with
144
- prompt template expansion).
142
+ - Verified against Pi 0.85.0 (2026-09-04) (`pi install`, package skills, friendly
143
+ command registration, routed set/clear, settings console round-trip, `sendUserMessage`
144
+ with prompt template expansion).
145
145
  - The package declares Pi as a peer dependency; it bundles no copy of Pi.
146
146
  - Skills can instruct the model to run commands. Review them as you would any
147
147
  third-party package.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtrabanco/pi-agentic-workflow",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Pi package: canonical agentic-workflow skills, friendly slash commands, and per-command model routing.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -53,6 +53,7 @@
53
53
  "@earendil-works/pi-coding-agent": "*"
54
54
  },
55
55
  "devDependencies": {
56
+ "@earendil-works/pi-server": "0.85.0",
56
57
  "@types/node": "^24",
57
58
  "typescript": "6"
58
59
  }
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: design-feature
3
3
  user-invocable: true
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  argument-hint: <idea | NN-slug> [<instruction>]
6
6
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
@@ -53,6 +53,34 @@ evidence → draft → cut → readiness. Its outcomes (`READY-FOR-REVIEW |
53
53
  NEEDS-EVIDENCE | NEEDS-DESIGN | NEEDS-REPLAN`) are an authoring gate, never an
54
54
  approval: only `review-spec` can approve a Product half.
55
55
 
56
+ ## Research gate (mandatory, fail-closed)
57
+
58
+ Before the Product half is emitted, run the research gate in the evidence pass
59
+ (step 2 of the ordered passes):
60
+
61
+ - **Fetch the domain** — acquire **at least two externally fetched sources** on
62
+ the capability's domain (fetch/WebFetch/browser): how the domain defines and
63
+ solves this capability. Repo evidence alone cannot ground a design; the bias
64
+ this gate closes is designing from what the repository already believes.
65
+ Each fetched source becomes an evidence row (URL and access date).
66
+ - **Cover the full definition** — the rows must state what the capability **is
67
+ and what it is not**, and the **user's expectation of it** — accepted and
68
+ rejected inputs, boundaries, semantics — not just the project's current
69
+ framing of it.
70
+ - **Decompose every enunciated expectation** — expand each expectation the
71
+ user enunciates into the implicit case decomposition it implies **before**
72
+ the Product half is cut: valid and invalid values and limits, interaction
73
+ states, degraded mode, backend validation/filtering/parsing, alternate user
74
+ paths. The canonical case: a "phone number input" is not a field — it is the
75
+ whole case vector (prefixes/suffixes, lengths, non-text rejection, focus,
76
+ no-JS/JS behavior, backend filtering/validation/parsing) that the product
77
+ owner's one-liner hides.
78
+ - **Fail closed** — offline, or a material question the fetches do not answer,
79
+ returns `NEEDS-EVIDENCE` with the named owner and next fetch: never a guess,
80
+ never an invented citation.
81
+ - **Research before encode** — platform semantics a test will encode are
82
+ verified against authoritative documentation before the test exists (the
83
+ prevention half of `verification-contract`'s test-immutability contract).
56
84
 
57
85
  ## Progressive loading — resolve status before product detail
58
86
 
@@ -102,7 +130,8 @@ required resource or unresolved mandatory slot returns NEEDS_INPUT; never guess.
102
130
  - The Expectation sweep enumerates **domain conventions**, not new scope: it
103
131
  may only route each expectation to in-scope / out-of-scope / deferred — it
104
132
  never silently grows the feature beyond what the user confirms.
105
- - No systematic per-feature market research; no global skill/MCP discovery
133
+ - No market or competitive research — the mandatory research gate above is
134
+ this skill's only external research; no global skill/MCP discovery
106
135
  sweep (`product-audit`'s job); no `--update` flag — upsert is always the
107
136
  default behavior, not an opt-in.
108
137
  - Don't build a separate `DESIGN.md` — one SPEC, two halves, always.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: evidence-grounding
3
3
  user-invocable: false
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
6
6
  license: MIT
7
7
  description: >
@@ -75,7 +75,12 @@ Authoring is progressive. Never jump from discovery to a polished artifact.
75
75
  NEEDS-DESIGN`. Follow references and topology as far as the claim requires —
76
76
  the cap is the claim, not a file count. Wide reading that is not this turn's
77
77
  own goes out to the delegate-only role: [references/DELEGATION.md](references/DELEGATION.md)
78
- is its contract and the only shape its findings may arrive in. **If you are
78
+ is its contract and the only shape its findings may arrive in. **Web pass** —
79
+ when repository evidence cannot answer a bounded question, and always at
80
+ design stage where `design-feature`'s research gate makes it mandatory, fetch
81
+ external sources and freeze each as an evidence row (URL and access date);
82
+ offline or unanswered material questions return `NEEDS-EVIDENCE`, never an
83
+ invented citation. **If you are
79
84
  that reader** — you did not write the artifact and are not writing it — the
80
85
  contract governs you: skip steps 1, 3 and 4, and produce the artifact under
81
86
  whatever name the invitation used; the position decides, not the label.
@@ -28,7 +28,7 @@ id | claim-or-obligation | authority-kind | source-and-location | observed-revis
28
28
  | Value | Means | Acceptable `source-and-location` |
29
29
  |---|---|---|
30
30
  | `repository` | observed in tracked source, config, or a generated artifact | `path:line` or `path` + symbol/test name |
31
- | `document` | a project doc, template, SPEC, roadmap or fix-index row | `path:section` |
31
+ | `document` | a project doc, template, SPEC, roadmap or fix-index row, or fetched external documentation | `path:section`, or the URL plus access date for a fetched source (`https://… (fetched YYYY-MM-DD)`) |
32
32
  | `ledger` | a frozen Normalized Repository State fact/decision, or an accepted architectural decision | `REPOSITORY_STATE.md` row ID (`F0nn`/`AD-nnn`) |
33
33
  | `forge` | an issue, PR, review, or CI record | absolute issue/PR URL |
34
34
  | `user` | an explicit user decision recorded this unit or in `decisions.md` | dated `decisions.md` / SPEC `## Amendments` row |
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: execute-phase
3
3
  user-invocable: true
4
- version: 4.0.2
4
+ version: 4.2.0
5
5
  argument-hint: <NN> [P<k>] | --fix <n> [P<k>] | [--max-attempts N] [--force]
6
6
  allowed-tools: [Bash, Read, Edit, Write, MultiEdit]
7
7
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
@@ -105,8 +105,9 @@ use its fallback; never skip the workflow step.
105
105
 
106
106
  Planned by `plan-feature`/`plan-fix`; executes their SPEC. Explicit phases may
107
107
  hand off to `review-change` at layer/accumulation/sensitivity checkpoints and must
108
- at unit end. Unit-loop skips intermediate checkpoints and recommends
109
- `loop-review-fold` after opening the PR; direct `review-change` remains manual.
108
+ at unit end. Unit-loop skips intermediate checkpoints and recommends the manual
109
+ `/fold-findings` → re-run `/review-change` path after opening the PR; direct
110
+ `review-change` remains the manual entry.
110
111
  Independent work stays a proposal. A finished unit always opens its PR and flips
111
112
  to `done`; `audit-pr` gates merge. Every invocation prints the next step.
112
113
 
@@ -117,4 +118,5 @@ to `done`; `audit-pr` gates merge. Every invocation prints the next step.
117
118
  committed on the correct branch with nothing bundled beyond scope.
118
119
  - `git status --porcelain` is empty and an open-PR branch has nothing unpushed.
119
120
  - A finished unit is `done`, has an opened PR (URL printed), and recommends the
120
- mandatory `/loop-review-fold` hand-off with direct `/review-change` as manual alternative.
121
+ mandatory `/fold-findings` → re-run `/review-change` hand-off, with `/audit-pr`
122
+ as the merge gate.
@@ -8,8 +8,9 @@ The normal omitted-phase command is already the batch:
8
8
  ```
9
9
 
10
10
  It selects every unfinished phase, gates and commits each one, skips
11
- intermediate review stops, opens the PR, then recommends
12
- `/loop-review-fold`. An explicit `P<n>` keeps the atomic/manual path.
11
+ intermediate review stops, opens the PR, then recommends the manual
12
+ `/fold-findings` → re-run `/review-change` path. An explicit `P<n>` keeps the
13
+ atomic/manual path.
13
14
 
14
15
  ### Fresh-context driver (recommended for cheap models)
15
16
 
@@ -19,8 +20,8 @@ slice, and compact receipts. An external driver may implement the same contract:
19
20
 
20
21
  1. Call `workflow-status` and choose the next unfinished phase.
21
22
  2. Invoke `/execute-phase <unit> P<n>` on the cheap tool-capable tier.
22
- 3. Repeat `CONTINUE`; route `READY_FOR_REVIEW` to `/loop-review-fold` on the
23
- required review/fold tiers.
23
+ 3. Repeat `CONTINUE`; route `READY_FOR_REVIEW` to `/fold-findings`, then re-run
24
+ `/review-change`, on the required review/fold tiers.
24
25
  4. Stop on `NEEDS_INPUT`, `HALT`, repeated unchanged evidence, or the declared
25
26
  attempt budget.
26
27
 
@@ -22,8 +22,9 @@ Write `docs/features/<NN>-<slug>/CHECKLIST.md`: schema migration applied (if any
22
22
  ## Review checkpoint & finishing a unit
23
23
 
24
24
  **Independent final review is mandatory — every unit gets one before merge.**
25
- Recommend `loop-review-fold` because it preserves fresh review contexts while
26
- handling bounded corrections; direct `review-change` is the manual path. Review
25
+ Recommend the manual `/fold-findings` → re-run `/review-change` path because it
26
+ preserves fresh review contexts while handling bounded corrections; direct
27
+ `review-change` remains the manual entry. Review
27
28
  runs in its own turn (hand-off, not composed): a skill's model and
28
29
  effort are fixed at turn start, so invoking `review-change` from here would run it at
29
30
  execute-phase's `sonnet`/`medium` rather than its own `opus`/`high` — under-powering
@@ -45,8 +46,8 @@ one).
45
46
  **Finishing a unit (single-pass, `--fix`, or a feature's final phase): the last step
46
47
  is always an open PR.** Mark the unit `done`, commit the flip, push, and `gh pr create`
47
48
  (see the mode steps above) — regardless of the review/audit still to come. Then hand
48
- off to `/loop-review-fold` (recommended) or direct `/review-change`, which feeds
49
- `audit-pr` (the merge gate).
49
+ off to `/fold-findings`, then re-run `/review-change`, which feeds `audit-pr`
50
+ (the merge gate).
50
51
 
51
52
  **Adversarial pass at that mandatory end review.** `review-change` evaluates its
52
53
  own recommendation checklist there (`L`/sensitive change, reviewer not the
@@ -17,6 +17,8 @@ end up "solved" locally but absent from the merged PR:
17
17
  ```
18
18
  ✓ Fixes implemented (scope: only the routed findings — nothing extra)
19
19
  ✓ Gate RUN and green (exit codes pasted)
20
+ ✓ Never edit an existing test's expectation to match behaviour — a setup
21
+ repair keeps assertions at least as strong and never touches expectations
20
22
  ✓ Per-phase / unit docs updated where the finding touched them
21
23
  (known-issues.md entry resolved? progress.md notes the fold)
22
24
  ✓ Each folded finding's row in the unit's `review-findings.md` ledger (if one
@@ -39,8 +41,7 @@ Final-phase / single-pass / fix hand-off:
39
41
  <unit> implemented, gate green, marked done.
40
42
  PR opened: <FULL PR URL — always printed here; not every agent shows open PRs>
41
43
  Roadmap/fix-index row: done · #<n> (linked and pushed)
42
- → Next: /loop-review-fold <unit> (recommended review/fold router; unresolved findings go to triage/replan)
43
- · manual path → /review-change
44
+ → Next: /fold-findings, then re-run /review-change (unresolved findings go to triage/replan)
44
45
  · clean → /audit-pr (merge gate) → human merges
45
46
  · findings → fold fix-now into this PR; independent work remains a proposal until user triage; re-review
46
47
  · docs site declared (documentation map has a `Docs site` block) →
@@ -82,7 +82,6 @@ UNIT LOOP — <unit> COMPLETE
82
82
  Phases: <n> · Commits: <sha list> · Acceptance: <blob> · Gate: PASS
83
83
  PR: <url>
84
84
 
85
- → Next: /loop-review-fold <unit> — select the persisted review/fold route, then triage or replan unresolved findings
86
- · manual path → /review-change, then /fold-findings and re-review as required
85
+ → Next: /fold-findings, then re-run /review-change on the changed HEAD — triage or replan unresolved findings
87
86
  · merge gate after REVIEW-PASS → /audit-pr
88
87
  ```
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: fold-findings
3
3
  user-invocable: true
4
- version: 1.2.2
4
+ version: 1.3.0
5
5
  argument-hint: [finding-id …]
6
6
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
@@ -31,6 +31,8 @@ A finding is `FOLDED` only when **all** of these hold:
31
31
  ✗ Adding a known-issues.md / backlog entry instead of fixing the code
32
32
  ✗ A decisions.md tradeoff note that accepts the defect as-is
33
33
  ✗ Deleting, skipping (.skip, .only elsewhere), or loosening a test to make it pass
34
+ ✗ Editing an existing test's expectation to match behaviour — a setup repair
35
+ may only keep assertions at least as strong and never touch expectations
34
36
  ✗ eslint-disable / @ts-ignore / equivalent suppression AS the fix
35
37
  ✗ A TODO/FIXME stub left in place of the actual fix
36
38
  ✗ Ticking `folded: yes` without a reviewer-mappable diff behind it
@@ -41,3 +43,8 @@ A finding is `FOLDED` only when **all** of these hold:
41
43
 
42
44
  Something forbidden looks like the only option → stop, do not apply it, and
43
45
  mark the finding `DISPUTED` or `BLOCKED` with the reason instead.
46
+
47
+ Never edit an existing test's expectation to match behaviour: a setup repair may
48
+ only keep assertions at least as strong and never touch expectations; the
49
+ test-immutability contract (`verification-contract`) owns the sole amendment
50
+ path.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: plan-feature-scaffold
3
3
  user-invocable: false
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
6
6
  license: MIT
7
7
  description: >
@@ -56,6 +56,18 @@ The [verification contract](<../verification-contract/SKILL.md>) owns the
56
56
  `ACCEPTANCE.md` schema, validation ladder, and anti-weakening rules. Consume it
57
57
  after the engineering plan is complete and before registering `planned`.
58
58
 
59
+ ## Research and reference trace (plan stage)
60
+
61
+ - **Conditional web research.** Plan-stage research runs only when a bounded
62
+ question (ROWS.md Q1–Q5) cannot be answered from repository evidence: run
63
+ exactly one web pass before the phases are emitted and freeze what it
64
+ returns as evidence rows (URL and access date). A question the repository
65
+ answers is never re-fetched.
66
+ - **Mandatory reference trace.** Affected code is located by symbol/reference
67
+ search — LSP/serena when the environment offers it, grep otherwise — and the
68
+ blast radius is derived from that search, never from model memory: added or
69
+ changed code can break callers the plan must name.
70
+
59
71
  ## Guardrails
60
72
 
61
73
  - Docs only. No source edits, migrations, or dependencies.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: plan-fix
3
3
  user-invocable: true
4
- version: 3.0.1
4
+ version: 3.1.0
5
5
  argument-hint: <issue-number> [<issue-number> …]
6
6
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
@@ -68,6 +68,18 @@ One or more GitHub issue numbers from this repo, space-separated.
68
68
  - One local commit with SPEC and `docs/fix/README.md` (`pending`, all merged issues).
69
69
  - **Stop: do not push/open PR.** Hand off to `review-plan`, then `execute-phase --fix`.
70
70
 
71
+ ## Research and reference trace (plan stage)
72
+
73
+ - **Conditional web research.** Plan-stage research runs only when a bounded
74
+ question (ROWS.md Q1–Q5) cannot be answered from repository evidence: run
75
+ exactly one web pass before the phases are emitted and freeze what it
76
+ returns as evidence rows (URL and access date). A question the repository
77
+ answers is never re-fetched.
78
+ - **Mandatory reference trace.** Affected code is located by symbol/reference
79
+ search — LSP/serena when the environment offers it, grep otherwise — and the
80
+ blast radius is derived from that search, never from model memory: added or
81
+ changed code can break callers the plan must name.
82
+
71
83
  ## Hard rules
72
84
 
73
85
  - Honor Workflow conventions: create `fix/<n>-<topic>` first, never `main`; gate,
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: pre-execution-review
3
3
  user-invocable: false
4
- version: 1.5.0
4
+ version: 1.7.0
5
5
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
6
6
  license: MIT
7
7
  description: >
@@ -135,7 +135,7 @@ and is out of scope; a copy or shell rewrite stays the reviewer's job.
135
135
  ```text
136
136
  ledger-ownership@1
137
137
  truth-class | ledger | owner | annotator | annotator-token | validator
138
- review-findings | docs/features/<NN>-<slug>/review-findings.md · docs/fix/<issue>-<topic>/review-findings.md | review-change:finding-rows + review-change:review-mark + audit-pr:audit-rows + triage-issue:triage-rows + fold-findings:folded-flag | scripts/ledger-provenance.mjs | · fold <sha> + · ticked <sha> + · REOPENED | node --test scripts/ledger-provenance.test.mjs
138
+ review-findings | docs/features/<NN>-<slug>/review-findings.md · docs/fix/<issue>-<topic>/review-findings.md | review-change:finding-rows + review-change:finding-mark + review-change:review-mark + audit-pr:audit-rows + triage-issue:triage-rows + fold-findings:folded-flag | scripts/ledger-provenance.mjs | · fold <sha> + · ticked <sha> + · REOPENED | node --test scripts/ledger-provenance.test.mjs
139
139
  planning-findings | docs/features/<NN>-<slug>/planning-findings.md · docs/fix/<issue>-<topic>/planning-findings.md | review-spec:spec-stage-rows + review-plan:plan-stage-rows + design-feature:product-class-resolutions + plan-feature:plan-class-resolutions + plan-fix:fix-plan-class-resolutions + fold-findings:source-class-resolutions | none | none | node --test scripts/pre-execution-quality.test.mjs
140
140
  progress | docs/features/<NN>-<slug>/progress.md · docs/fix/<issue>-<topic>/progress.md | plan-feature-scaffold:create + execute-phase:phase-entries + execute-phase:gate-rejection-traces + review-spec:product-receipt + review-plan:plan-receipt | none | none | node --test scripts/pre-execution-sensor.test.mjs
141
141
  known-issues | docs/features/<NN>-<slug>/known-issues.md · docs/fix/<issue>-<topic>/known-issues.md | plan-feature-scaffold:create + execute-phase:blocker-entries-and-status | none | none | node --test scripts/ledger-ownership.test.mjs
@@ -172,3 +172,25 @@ REVIEW-RAN | HEAD <40-hex sha> | n/a | n/a | review-mark | n/a | n/a
172
172
  other cells carry `n/a` because the row reports no finding — which keeps it out of
173
173
  the fix-now projection, `fold-findings`, and the annotator (its pattern matches
174
174
  `F<n>` ids only). A mark says a review ran, never that the candidate passed.
175
+
176
+ ### The durable finding mark
177
+
178
+ A candidate finding that verifies — or refutes — before persistence gets a
179
+ per-finding durable signature of its own, under `review-change:finding-mark`.
180
+ This is the fix/161 extension of the feature-28 treatment: a verdict has a
181
+ signature, so must the individual finding. The single writer of every finding mark is `review-change`; nothing else appends one.
182
+
183
+ ```text
184
+ finding-mark@1
185
+ id | file:line | axis | severity | class | route | folded
186
+ VF-<n> | <file:line> · reviewer review-change · HEAD <40-hex sha> · recheck <method + reproducer> | <axis> | confirmed | finding-mark | n/a | n/a
187
+ ```
188
+
189
+ `VF-` ids are deliberately outside the `F<n>` range the provenance annotator's
190
+ row pattern matches, so a finding mark is invisible to the recount, to
191
+ `--check`, to `--annotate`, and to the fix-now projection. A `confirmed`
192
+ finding's row carries the mark; a `refuted` candidate carries its
193
+ counter-evidence in the same report and **never becomes a row**, a fold task,
194
+ or a re-review trigger. The mark's `confirmed | refuted` value and the
195
+ `recheck` cell (the method the finding's axis demands) are what let a driver
196
+ outside the repo consume the verification the review performed.
@@ -86,7 +86,7 @@ outside this policy and can never be translated into a PASS.
86
86
  - An automatic forge issue. No route in the pre-execution set — `evidence-grounding`
87
87
  readiness, `review-spec`, `review-plan`, `plan-feature-scaffold`, `plan-fix`,
88
88
  `execute-phase`, `workflow-status`, `ship-roadmap`, `review-change`,
89
- `loop-review-fold`, `audit-pr` — creates one for a planning gap, and none defers
89
+ `audit-pr` — creates one for a planning gap, and none defers
90
90
  an obligation to a future issue: the row stays in the unit's ledger, open, until
91
91
  the **user** amends the governing SPEC. A blocker that says "file an issue" is a
92
92
  contract violation, not a workaround, and a `deferred` row without an amendment is
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: review-change
3
3
  user-invocable: true
4
- version: 3.0.0
4
+ version: 3.2.1
5
5
  argument-hint: <path-or-glob> [--adversarial N] [--synthesize]
6
6
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
@@ -81,19 +81,19 @@ Every axis maps to a skill of the workflow's **own internal review pack**
81
81
  | API ergonomics / usage docs (inline pass) | if API | if API | flags/help | ✓✓ | ✓ |
82
82
 
83
83
  > `review-implementation` (the single classifier over the synthesized table —
84
- > process step 7) and `review-debt` (the debt transform over the classified
85
- > table — process step 8) are not axis finders: they run once per review, not
84
+ > process step 8) and `review-debt` (the debt transform over the classified
85
+ > table — process step 9) are not axis finders: they run once per review, not
86
86
  > per axis.
87
87
 
88
88
  ## Isolation rule (default — every pass, not only adversarial)
89
89
 
90
- Each applicable pass, the classifier (step 7), and debt transform (step 8) runs
90
+ Each applicable pass, the verification pass (step 6), the classifier (step 8), and debt transform (step 9) runs
91
91
  **isolated/context-clean** and returns only its fixed findings table plus
92
92
  `PASS | FAIL`—never diff or prose. Spawn one fresh subagent/headless run per
93
93
  pass; without those, use a fresh conversation. Pass only scope, its checklist,
94
94
  and Step 0 docs; cap full non-diff reads at 10 (targeted ≤50-line reads/greps
95
95
  excluded). The orchestrator retains tables, not sources, and fuses them in step
96
- 6. Inline fallback is sequential table reduction. A pass runs at its own tier or
96
+ 7. Inline fallback is sequential table reduction. A pass runs at its own tier or
97
97
  stronger, never weaker.
98
98
 
99
99
 
@@ -143,8 +143,11 @@ only for independent proposals (D3). It is Stage 4: checkpoint reviews are
143
143
  optional, the end review is mandatory and fresh. `fix-now` folds in-unit,
144
144
  `replan-in-unit` adds user-confirmed phases, and independent work becomes
145
145
  proposals. `audit-pr` consumes only the verified PR-comment receipt, never the
146
- chat report; `product-audit` is the periodic sweep;
147
- `loop-review-fold` may run this skill fresh and route FAIL to `fold-findings`.
146
+ chat report; `product-audit` is the periodic sweep. On `REVIEW-FAIL` the manual
147
+ correction path is `/fold-findings`, then re-run `/review-change` on the changed
148
+ HEAD (bounded at two cycles — a third cycle never starts without an explicit
149
+ user instruction, per `REVIEW_PROCESS.md`); a programmatic outer driver may run
150
+ the same review→fold sequence.
148
151
 
149
152
  ## Done when
150
153
 
@@ -16,7 +16,11 @@
16
16
  or `med` (only ledger severities; finder scale
17
17
  `critical`→`high`, `major`→`med`, `minor`→`low`): append a row
18
18
  (create the file with the header row when missing), carrying the
19
- verbatim `Sev` value into `severity`; `folded` always starts `no` —
19
+ verbatim `Sev` value into `severity`; `folded` always starts `no` — that
20
+ row comes from a **confirmed** candidate only and carries its
21
+ `finding-mark@1` signature on a **separate `VF-` row** (reviewer, head SHA,
22
+ recheck + reproducer), as modeled in `LEDGERS.md` (§finding-mark@1) and the
23
+ fixture.
20
24
  `execute-phase`'s fold cycle is the only step that ever flips it to `yes`.
21
25
  A `low` finding is **never persisted to the fold ledger** — report-only
22
26
  note (step 13), never blocking (finders' materiality floor). Re-runs
@@ -25,7 +29,7 @@
25
29
  a re-report at a folded row's location is legitimate only as `regression of <id>`
26
30
  (fix provably failed) or `DISPUTED`; else `Fn+1`.
27
31
  **Non-fix-now findings are never written here** — they keep
28
- their destinations from step 10 (outcome routing): independent future
32
+ their destinations from step 11 (outcome routing): independent future
29
33
  capabilities batch as proposals; only the user routes them to `triage-issue`
30
34
  (D3).
31
35
  **Commit the ledger append** — rows + `REVIEW-RAN` mark, one commit
@@ -34,7 +38,7 @@
34
38
  `REVIEW-PASS` with an open PR no ledger write happens (the SHA-bound
35
39
  receipt is the durable record): head and posted receipt stay identical.
36
40
  12. **Close out the final-review receipt before reporting.** First derive the
37
- `Decision` from step 6 and persist step 11. Then, before printing any line of
41
+ `Decision` from step 7 and persist step 11. Then, before printing any line of
38
42
  the fixed report block or the `→ Next:` block, complete the receipt action
39
43
  below. The receipt is a precondition of the report, not a follow-up.
40
44
 
@@ -85,7 +89,7 @@
85
89
  Architectural invariants: pass | finding (<ID>) | n/a: no project invariants declared
86
90
  Receipt: current at <head SHA> | n/a: no PR | none: REVIEW-FAIL/NEEDS-DECISION
87
91
 
88
- <the synthesized decision table (step 6)>
92
+ <the synthesized decision table (step 7)>
89
93
 
90
94
  Manual verification (a human must check):
91
95
  - <item> …
@@ -93,14 +97,17 @@
93
97
  Notes (low · report-only, never persisted):
94
98
  - <finding + evidence, or none>
95
99
 
96
- Proposals (step 10): <n> — batched for the user, no issues created (D3)
100
+ Refuted (verified false — reported with counter-evidence, never persisted):
101
+ - <candidate + counter-evidence, or none>
102
+
103
+ Proposals (step 11): <n> — batched for the user, no issues created (D3)
97
104
 
98
105
  Summary: <1-2 sentences>
99
106
  Decision: REVIEW-PASS | REVIEW-FAIL | NEEDS-DECISION (D10: review says these three; only audit-pr says MERGE-READY)
100
107
  ```
101
108
 
102
109
  14. **Next step.** The `→ Next:` block is **never one static template** — branch
103
- on the `Decision` value from step 6 and emit the matching block **verbatim,
110
+ on the `Decision` value from step 7 and emit the matching block **verbatim,
104
111
  as multiple literal lines**. Never join the `·` sub-bullets into one prose
105
112
  line — each sub-bullet is its own line, exactly as quoted below.
106
113
  For `REVIEW-FAIL` or `NEEDS-DECISION`, list every open finding ID in the
@@ -111,9 +118,9 @@
111
118
  passing receipt was posted** (step 12):
112
119
 
113
120
  ```
114
- → Next: /loop-review-fold <unit> — repair all open fix-now findings: <F1> + <F2> + <F3>,
115
- then re-review changed HEADs within the bounded correction budget
116
- · manual path → /fold-findings, then re-run /review-change
121
+ → Next: /fold-findings — repair all open fix-now findings: <F1> + <F2> + <F3>,
122
+ then re-run /review-change on the changed HEAD (bounded at two cycles; a
123
+ third cycle never starts without an explicit user instruction)
117
124
  · /audit-pr → only after the table is clean (not yet — findings open)
118
125
  · any finding routed replan-in-unit? → confirm the proposed SPEC phase(s),
119
126
  then /execute-phase on this same branch (yes: list the finding ids; no:
@@ -78,14 +78,30 @@
78
78
  (stack-specific linters, framework skills) and they are installed, run them
79
79
  **in addition** — their findings merge into the same table. Never treat an
80
80
  absent extra as a gap; the pack already covered the axis.
81
- 6. **Synthesize.** Fuse all findings into **one** findings table, deduped by
81
+ 6. **Verify, then synthesize.** Before fusing anything, every candidate finding
82
+ is **verified in an isolated context against the reviewed head's bytes** (the
83
+ SHA frozen in step 1) and marked `confirmed` or `refuted`. The recheck method
84
+ follows the finding's axis:
85
+ - a **code / behavioral** claim confirms only with a **failing reproducer** —
86
+ a red test written first and run against **unchanged code**, or
87
+ **reproducible command output**;
88
+ - a **documentation / wording** claim confirms by **direct read** of the
89
+ cited text (typos and wording are corrected without ceremony, no test);
90
+ - a **missing-documentation** claim confirms the named user path is
91
+ undocumented.
92
+ Only **confirmed** candidates flow to synthesis; a **refuted** candidate is
93
+ reported with its counter-evidence in the same report and never becomes a
94
+ row, a fold task, or a re-review trigger. The per-finding durable mark is
95
+ `finding-mark@1` (contract in `pre-execution-review/references/LEDGERS.md`).
96
+
97
+ 7. **Synthesize.** Fuse all findings into **one** findings table, deduped by
82
98
  `file:line` + axis, per the synthesis contract (the same fusion rules apply
83
99
  in the default single-reviewer case). Columns: `# | Finding | Axis | Sev |
84
100
  Evidence | Suggested fix` — **unclassified**. Overlapping signals on the same
85
101
  defect collapse into one row. Add a **`Reviewers n/N`** column when running
86
102
  in `--adversarial N` mode (omitted entirely in the default single-reviewer
87
103
  case).
88
- 7. **Classify (once).** Run `review-implementation` over the synthesized table
104
+ 8. **Classify (once).** Run `review-implementation` over the synthesized table
89
105
  (isolated, per the *Isolation rule*) — the single classification engine
90
106
  (D5). It verifies axis coverage (every applicable axis represented; a
91
107
  missing axis is a `coverage` finding) and applies the current-unit contract:
@@ -94,17 +110,37 @@
94
110
  → the **classified decision table** (Sev, Class, WHY, impl risk, long-term
95
111
  impact, premature-opt?, Route). No per-pass or per-reviewer classification,
96
112
  no re-litigation.
97
- 8. **Debt transform.** Run `review-debt` over the classified table — it
113
+ 9. **Debt transform.** Run `review-debt` over the classified table — it
98
114
  transforms debt-shaped findings into explicit TRIGGER-carrying debt items;
99
115
  it does not rescan the diff (SPEC contract).
100
- 9. **Manual-verification checklist.** List what automated review **cannot** confirm
116
+ 10. **Manual-verification checklist.** List what automated review **cannot** confirm
101
117
  and a human must check — visual correctness, real-device/locale behavior, UX
102
118
  feel, perf under load, anything marked *verify*. Be explicit so the dev has zero
103
119
  doubt about what to eyeball.
104
- 10. **Route the outcomes.** fix-now findings fold into the current unit (or gain
120
+ 11. **Route the outcomes.** fix-now findings fold into the current unit (or gain
105
121
  user-confirmed phases via replan-in-unit); decision-required stops for the
106
122
  user's decision; genuinely independent future capabilities become
107
123
  **non-blocking proposals** — batched in the report with a trigger, and
108
124
  **never** sent to `triage-issue` automatically (D3). `review-change` creates
109
125
  no backlog work. No non-fix-now finding may end without a destination — none
110
126
  silently lost.
127
+
128
+ ## Two-cycle cap
129
+
130
+ The review→fold loop runs at most **two** review→fold cycles per unit, counted
131
+ unit-level and family-agnostic from the ledger's `REVIEW-RAN` marks and forge
132
+ receipts — new finding families do not reset the count. After two cycles without
133
+ convergence, the review prints
134
+
135
+ ```text
136
+ LOOP CAP REACHED — <unit>
137
+ - Finding ids: <every open id>
138
+ - Cycles: 2 (REVIEW-RAN marks + forge receipts)
139
+ - Route: /triage-issue --prioritize-now <unit> F<k> … (or the programmatic outer driver)
140
+ ```
141
+
142
+ A **third cycle never starts** unless the user explicitly instructs it — it is
143
+ the user's escape, never a reviewer election. The residue routes to
144
+ `triage-issue --prioritize-now` (or the programmatic outer driver), and a unit
145
+ that needs a third cycle has a planning or root-cause defect, not a review
146
+ deficit.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: review-code
3
3
  user-invocable: false
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
6
6
  license: MIT
7
7
  description: >
@@ -41,6 +41,8 @@ default branch. State the scope at the top of the returned table.
41
41
  ✓ No new dependency not justified in the SPEC
42
42
  ✓ Simplification: any changed block that can lose lines without losing
43
43
  behavior (cite before/after)
44
+ ✓ Reference trace: every changed symbol/API got a reference search —
45
+ un-updated callers are findings
44
46
  ✓ Edge cases the SPEC's dev scenarios name are actually handled in code, not
45
47
  just in tests
46
48
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: review-implementation
3
3
  user-invocable: false
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  argument-hint: <path-or-glob>
6
6
  allowed-tools: Read, Grep, Glob, Bash, WebFetch
7
7
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
@@ -113,7 +113,7 @@ finding in its `Route` cell.
113
113
 
114
114
  | Owning stage | Hand-off | Never |
115
115
  |---|---|---|
116
- | `source` | fold locally: `/loop-review-fold` → `/fold-findings` → re-review the changed HEAD | — |
116
+ | `source` | fold locally: `/fold-findings`, then re-run `/review-change` on the changed HEAD | — |
117
117
  | `plan` | 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 a **fresh `/review-plan <unit>`** precedes `execute-phase` | fold it in code and leave the plan describing the old build |
118
118
  | `product` | `/design-feature <unit>` repairs the half, then `/review-spec <unit>` re-judges it | patch the product claim into agreement in code |
119
119
  | `environment` / `runtime` | the existing retry/`BLOCKED` paths | translate into a PASS, or an issue |
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: review-plan
3
3
  user-invocable: true
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  argument-hint: <NN-slug | fix-N | path/to/SPEC.md> [--adversarial N]
6
6
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
@@ -93,8 +93,8 @@ stage.
93
93
  resolver:** class `plan` → `plan-feature` / `plan-fix` (the author re-cuts, then
94
94
  `/review-plan` re-judges) · class `product` → `design-feature` repairs the
95
95
  Product half (then `/review-spec`, then the plan re-derives) · class `source` |
96
- `environment` | `runtime` → the executor's fold path (`/loop-review-fold` →
97
- `/fold-findings`), never by editing the plan to hide the row.
96
+ `environment` | `runtime` → the executor's fold path (`/fold-findings`, then re-run
97
+ `/review-change`), never by editing the plan to hide the row.
98
98
  **`fold-findings` never repairs a planning artifact** — folding repairs source,
99
99
  not authority.
100
100
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: review-spec
3
3
  user-invocable: true
4
- version: 1.4.0
4
+ version: 1.5.0
5
5
  argument-hint: <NN-slug | path/to/SPEC.md>
6
6
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
@@ -80,7 +80,7 @@ fourth verdict.
80
80
  resolver:** class `product` → `design-feature` (then `/review-spec` re-judges the
81
81
  new revision) · class `plan` → `plan-feature` / `plan-fix` re-cuts the plan (then
82
82
  `/review-plan` re-judges) · class `source` | `environment` | `runtime` → the
83
- executor's fold path (`/loop-review-fold` → `/fold-findings`).
83
+ executor's fold path (`/fold-findings`, then re-run `/review-change`).
84
84
  **`fold-findings` never repairs a planning artifact**, and a planning finding is
85
85
  never resolved by patching the artifact during review — folding repairs source,
86
86
  not authority.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: ship-roadmap
3
3
  user-invocable: true
4
- version: 5.0.0
4
+ version: 5.1.0
5
5
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
6
6
  license: MIT
7
7
  argument-hint: "[--fullauto] | --continue [--fullauto]"
@@ -102,7 +102,7 @@ fallback only when a primitive is unavailable; keep stage order and safety floor
102
102
 
103
103
  | Relation | Skills/policy |
104
104
  |---|---|
105
- | Compose (same/lower tier) | `init-workspace`; JIT `design-feature` + `plan-feature-scaffold`; `plan-feature`; `loop-review-fold`; verdict-only `audit-pr`; `audit-docs`. |
105
+ | Compose (same/lower tier) | `init-workspace`; JIT `design-feature` + `plan-feature-scaffold`; `plan-feature`; the review→fold manual path (`/fold-findings` → re-run `/review-change`); verdict-only `audit-pr`; `audit-docs`. |
106
106
  | Cheap workers | `execute-phase` (fresh context/phase), mechanical folds, audit-blocker fixes; use the validated worker model. |
107
107
  | Human hand-off | Default merges, `product-audit` (higher effort), and report issue batches via `triage-issue`. |
108
108
  | Sibling | `workflow-status` supplies the strict sensor result; worker skills use the package-owned output profiles, while the conductor keeps its native `SHIP:` turn contract. |
@@ -70,11 +70,12 @@
70
70
  when the PR opens; any flips left at run end ride the report commit).
71
71
  Stop before the literal final `Hardening & PR` phase: PR owns that explicit
72
72
  phase so close-out has one owner. Never bundle phases into one worker.
73
- - **REVIEW** — compose `loop-review-fold` in-turn (equal tier) once, over
74
- the complete PR candidate. It reuses a current exact-SHA receipt or runs
75
- `review-change` context-clean, batches compatible fixes through
76
- `fold-findings`, and re-reviews only changed HEADs. Default correction
77
- budget is two; unchanged evidence stops NO-PROGRESS. L/sensitive features
73
+ - **REVIEW** — compose the manual review→fold path in-turn (equal tier) once,
74
+ `/fold-findings`, then re-run `/review-change`, over the complete PR
75
+ candidate. It reuses a current exact-SHA receipt or runs `review-change`
76
+ context-clean, batches compatible fixes through `fold-findings`, and
77
+ re-reviews only changed HEADs. Default correction budget is two; unchanged
78
+ evidence stops NO-PROGRESS. L/sensitive features
78
79
  forward `--adversarial 2` (security/auth: `3`) as the unattended floor;
79
80
  other units use one final reviewer. There are no intermediate phase
80
81
  reviews in autopilot: phase gates + frozen acceptance guard execution,
@@ -9,7 +9,7 @@
9
9
  | Product review (REVIEW-SPEC) | opus/high | `review-spec` in a **clean context** (fresh subagent or outside headless call) — never the turn that wrote the product half; tier equals or exceeds the author's, so the ≥ rule holds |
10
10
  | Plan review (REVIEW-PLAN) | opus/high | `review-plan` in a **clean context**, same rule; it judges the plan the previous stage froze |
11
11
  | Phase execution, single-pass, fixes | **cheap worker** | fresh context per phase following `execute-phase`; Claude branch maps this role to `sonnet`, portable drivers use their validated worker tier |
12
- | Final review/correction loop | opus/high | compose `loop-review-fold`; it selects review or fold from persisted evidence and routes unresolved findings to `triage-issue --prioritize-now` |
12
+ | Final review/correction loop | opus/high | compose the manual path `/fold-findings`, then re-run `/review-change`; it reuses a current exact-SHA receipt or reviews context-clean, and routes unresolved findings to `triage-issue --prioritize-now` |
13
13
  | Merge gate | opus/high | compose `audit-pr` in-turn (the highest-stakes automated verdict; must share one turn with the floor checks) |
14
14
  | Forge/git mechanics | — | Bash tool calls; no model judgment involved |
15
15
  | Final-report evidence gathering | haiku (optional) | fan-out subagents for grep-shaped per-feature log collection when ultracode is on; synthesis stays opus |
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: triage-issue
3
3
  user-invocable: true
4
- version: 2.6.0
4
+ version: 2.7.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 <gtrabanco@users.noreply.github.com>"
7
7
  license: MIT
@@ -25,7 +25,7 @@ after `/fold-findings` leaves rows unresolved.
25
25
 
26
26
  4. Never implement the new phases in this triage turn. After a replan, ask the
27
27
  user to continue manually with `/execute-phase <unit> P<n>` (or the fix
28
- equivalent), then re-run `/loop-review-fold` on the resulting HEAD.
28
+ equivalent), then re-run `/review-change` on the resulting HEAD (the manual path).
29
29
 
30
30
  Return exactly one block per finding:
31
31
 
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: verification-contract
3
3
  user-invocable: false
4
- version: 1.1.0
4
+ version: 1.2.1
5
5
  author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
6
6
  license: MIT
7
7
  description: >
8
8
  Internal contract: one compact frozen ACCEPTANCE.md per delivery unit, its
9
9
  validation ladder, anti-weakening rules, and blob-bound execution receipt.
10
- Consumed by planners, execute-phase, review-change, and loop-review-fold.
10
+ Consumed by planners, execute-phase, and review-change.
11
11
  ---
12
12
 
13
13
  # Verification Contract (internal)
@@ -80,6 +80,17 @@ stub, hard-coded answer, or no-op fix used to manufacture green. A command canno
80
80
  prove an untested read/manual row. Stronger regression tests are allowed. Repair
81
81
  test setup only when assertions stay at least as strong and the reason is logged.
82
82
 
83
+ ## Test immutability
84
+
85
+ A test, once written, is **immutable**. The executor fixes code until green,
86
+ never the test — editing an expectation to match behaviour is not a fix, it is
87
+ a cover-up. The sole legitimate amendment is a **proven mis-encoding of external semantics**: the test's expectation contradicts the actual
88
+ documented semantics of the platform/library/language, cited from authoritative documentation — not a product decision change. Even that surfaces as a
89
+ **finding plus a SPEC amendment**, never a silent edit to go green.
90
+
91
+ Prevention rides the research gate (**research-before-encode**): platform
92
+ semantics are verified against authoritative documentation **before a test encodes them**, so **adding stronger tests stays allowed**; **editing expectations never** (except the proven-mis-encoding path above).
93
+
83
94
  ## Done when
84
95
 
85
96
  Frozen manifest + current blob receipt + named validators + literal quality
@@ -1,200 +0,0 @@
1
- ---
2
- name: loop-review-fold
3
- user-invocable: true
4
- version: 4.0.0
5
- argument-hint: <NN> | --fix <issue-number>
6
- author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
7
- license: MIT
8
- description: >
9
- Run the simple review-change/fold-findings loop for an open feature or fix
10
- unit. Inspect persisted review evidence first so a previous review resumes
11
- with fold-findings instead of reviewing the same candidate again. Unresolved
12
- findings go to triage-issue with an immediate-fix instruction; oversized
13
- findings become a user-confirmed plan-feature or plan-fix replan with new
14
- phases. Triggers: "loop-review-fold", "review and fold this PR", "run the
15
- review fold loop".
16
- ---
17
-
18
- # Review / Fold Loop
19
-
20
- Run one small state loop over the current feature or fix unit:
21
-
22
- ```text
23
- review-change ── findings ──▶ fold-findings ── changed HEAD ──▶ review-change
24
- ▲ │
25
- └──────── current PASS ◀───────┘
26
- └─ unresolved ─▶ triage-issue
27
- ```
28
-
29
- This skill is a router, not a third review or repair implementation. It reads
30
- the durable evidence left by `review-change` and `fold-findings`, chooses the
31
- next action, and stops when a user decision or manual phase execution is
32
- required. Never merge, create an unrelated issue, or silently discard a
33
- finding.
34
-
35
- ## Turn contract
36
-
37
- ```text
38
- ✓ The feature/fix unit, branch, PR, current HEAD, acceptance, and finding ledger were checked
39
- ✓ The first action was selected from persisted evidence: PASS, review-change, or fold-findings
40
- ✓ review-change ran only when no current review result required fold-findings first
41
- ✓ A successful fold was followed by review-change on the new HEAD
42
- ✓ Every unresolved finding is named and routed to triage-issue --prioritize-now
43
- ✓ An oversized finding routes to plan-feature or plan-fix, new P<n> phases, and manual user execution
44
- ✓ No merge, unrelated issue, acceptance weakening, or silent finding drop occurred
45
- ✓ The fixed result and the closing → Next: block are the final output
46
- ```
47
-
48
- Any unchecked box means the turn is not done.
49
-
50
- ## When to use
51
-
52
- Use after `execute-phase` opens the unit PR, or when the user asks to review and
53
- fold an open feature or fix. The argument identifies the unit:
54
-
55
- - `/loop-review-fold <NN>` for a feature unit.
56
- - `/loop-review-fold --fix <issue-number>` for a fix unit.
57
-
58
- Do not use this entrypoint to edit this skill, inspect its implementation as the
59
- requested deliverable, or invent a target when the unit argument is missing.
60
-
61
- ## Step 0 — Discover the project (always first)
62
-
63
- Read the target project's agent guide and documentation map. Then verify the
64
- target unit, current branch, open PR, remote HEAD, frozen acceptance artifact,
65
- the latest `review-change` result/receipt, and the unit's `review-findings.md`.
66
- Use repository and forge commands required by the project's own conventions.
67
- Narration, an old chat result, or a clean worktree alone is not evidence.
68
-
69
- If the target, PR, acceptance, or ledger cannot be verified, stop with
70
- `BLOCKED` and name the exact missing input and recovery command. Do not create
71
- replacement artifacts in this router.
72
-
73
- ## Process
74
-
75
- Apply this first-match table exactly:
76
-
77
- | Persisted state on the current HEAD | First action |
78
- |---|---|
79
- | Exact current `REVIEW-PASS`, matching acceptance, and no open finding rows | `PASS`; do not run either skill |
80
- | A review result exists for this HEAD and it leaves any `folded: no` row | `fold-findings` on the complete open queue |
81
- | No usable current review result and no open queue | `review-change` on the current HEAD |
82
-
83
- Then continue as follows:
84
-
85
- 1. Run the selected skill in its own fresh context and follow that skill's
86
- contract literally. This loop does not copy its internal checklist.
87
- 2. If `review-change` returns `REVIEW-PASS`, verify its exact-HEAD receipt and
88
- zero open rows, then return `PASS`.
89
- 3. If `review-change` returns findings, run `fold-findings` for every open
90
- `fix-now` row. Do not start another review before that queue is processed.
91
- 4. If `fold-findings` changes and pushes the candidate, run `review-change` on
92
- that new HEAD. Never review an unchanged HEAD a second time.
93
- 4a. Before step 5, split the open queue by **owning stage** (the `route` cell each
94
- `review-change` finding carries: `product | plan | source | environment |
95
- runtime`). Only `source`, `environment` and `runtime` rows may be folded or
96
- triaged here. A `plan`-owned row stops the loop with `BLOCKED` and hands off to
97
- `/plan-feature <unit>` (fix: `/plan-fix <n>`) for one root-caused re-cut, then
98
- `/review-plan <unit>`; a `product`-owned row goes to `/design-feature <unit>`
99
- then `/review-spec <unit>`. Folding repairs the candidate; it cannot repair the
100
- authority that describes it, so never fold a row whose artifact of record is a
101
- planning document, and never send one to `triage-issue` to make it disappear.
102
- 4b. On entering a **second** local review→fold cycle for the same finding family,
103
- diagnose before editing again: emit the `CONVERGENCE-ANOMALY` report defined by
104
- `pre-execution-review` (repeated vs new ids, snapshot digest and
105
- `artifactRevisionId` move, what was missed, owning stage, why the prior
106
- repair failed, route to owner) and continue from the owner it names. A third
107
- blind edit is not a repair attempt, and no cycle count here is ever hidden.
108
- 4c. **Cycle bound (unit-level, family-agnostic).** This loop runs at most **two**
109
- review→fold cycles for a unit, counted from the unit's ledger marks and
110
- receipts — new finding families do not reset the count. A third cycle never
111
- starts here: stop with `TRIAGE-REQUIRED`, name every open finding ID, and
112
- hand the convergence diagnosis to `/triage-issue --prioritize-now` (which
113
- routes replans) or to the user. A unit that needs a third cycle has a
114
- planning or root-cause defect, not a review deficit — more blind rounds
115
- only manufacture findings.
116
-
117
- 5. If any finding remains unresolved (`DISPUTED`, `BLOCKED`, `REPLAN`, or an
118
- open row left after folding), stop the loop and hand every such ID to:
119
-
120
- ```text
121
- /triage-issue --prioritize-now <unit-or-fix> F1 F2 ...
122
- ```
123
-
124
- Tell `triage-issue` to try to resolve every named finding immediately. It
125
- may route a small correction back to the current unit, but it must not hide,
126
- downgrade, or postpone a review finding merely to finish the loop.
127
- 6. When the smallest correct correction is too large for the current fold,
128
- `triage-issue` must choose a replan route: re-run `/plan-feature <slug>` for
129
- a feature or `/plan-fix <issue-number>` for a fix, append explicit new
130
- `P<n>` phases to the unit's SPEC, and stop. The loop then asks the user to
131
- execute those phases manually with `/execute-phase <unit> P<n>` (or the
132
- fix equivalent) before invoking this loop again.
133
-
134
- Do not use a hidden retry count. The loop ends at the first `PASS`, blocked
135
- prerequisite, unresolved finding, or required manual replan. A later user
136
- invocation starts from the newly persisted state. The loop files nothing: an
137
- unresolved finding never becomes a forge issue from here, and deferring one out of
138
- the unit requires the user to amend the governing SPEC first.
139
-
140
- ## Fixed output contract
141
-
142
- Return exactly:
143
-
144
- ```text
145
- REVIEW-FOLD LOOP — PASS | TRIAGE-REQUIRED | BLOCKED
146
- Unit: <unit> · PR: <url> · HEAD: <sha>
147
- First action: PASS | review-change | fold-findings
148
- Review: <PASS | FAIL | not-run> · Fold: <changed | unchanged | not-run>
149
- Owned elsewhere: <plan → /plan-feature + /review-plan | product → /design-feature
150
- + /review-spec | none>
151
- Unresolved: <F1 + F2 + … | none>
152
- Evidence: <one concise line explaining the selected action and result>
153
-
154
- → Next: <one concrete command or user action> — <why>
155
- · <alternative when applicable>
156
- ```
157
-
158
- Use `TRIAGE-REQUIRED` whenever a finding needs `triage-issue`, a replan, or a
159
- user decision. Replace every placeholder, list each actual finding ID exactly
160
- once joined with ` + `, and never emit a literal ellipsis.
161
-
162
- ## Guardrails
163
-
164
- Allowed: read target evidence, invoke `review-change`, invoke `fold-findings`,
165
- and route unresolved findings to `triage-issue`.
166
-
167
- Forbidden: implementing a fix in this router, editing review classifications,
168
- marking findings folded, creating unrelated issues, weakening acceptance or
169
- checks, merging, or claiming that a user has implemented newly planned phases.
170
- Also forbidden: folding a `plan`- or `product`-owned finding, re-editing on a
171
- second local cycle before the convergence diagnosis is reported, entering a
172
- third review→fold cycle for the same unit, and treating an
173
- absent pre-execution PASS as foldable debt.
174
-
175
- ## Relationship to other skills
176
-
177
- `execute-phase` hands off here after a unit PR opens. `review-change` owns
178
- read-only classification and the SHA-bound pass receipt. `fold-findings` owns
179
- the actual correction and ledger tick. `triage-issue --prioritize-now` owns the
180
- decision for unresolved findings and routes oversized work to `plan-feature` or
181
- `plan-fix`; the user then executes the appended phases manually.
182
-
183
- ## Portability (agents other than Claude Code)
184
-
185
- If fresh contexts or subagents are unavailable, invoke each delegated skill in
186
- a new conversation and re-read the persisted HEAD, receipt, and ledger before
187
- continuing. If the host has no slash-command menu, open each named `SKILL.md`
188
- and follow it literally. Never claim a clean review after the same context
189
- implemented the correction.
190
-
191
- ## Done when
192
-
193
- The current HEAD has a verified `REVIEW-PASS` and no open findings, or every
194
- remaining finding has a concrete triage/replan hand-off and the user has been
195
- told to implement the new phases manually.
196
-
197
- → Next: print the matching terminal route from the fixed output contract — never send a non-PASS result to audit-pr
198
- · PASS → /audit-pr — consume the current exact-HEAD REVIEW-PASS
199
- · TRIAGE-REQUIRED → /triage-issue --prioritize-now <unit> F<k> — resolve every actual unresolved finding, then plan/execute new phases manually
200
- · BLOCKED → the exact recovery command — supply the missing target, PR, acceptance, or ledger input before re-running the loop