@gtrabanco/pi-agentic-workflow 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/audit-pr/SKILL.md +1 -1
- package/skills/audit-pr/references/02_CLOSURE_AND_SCOPE_GATES.md +1 -1
- package/skills/design-feature/SKILL.md +1 -1
- package/skills/design-feature/references/REPAIR.md +5 -0
- package/skills/execute-phase/SKILL.md +1 -1
- package/skills/execute-phase/references/PRE_EXECUTION_GATE.md +1 -1
- package/skills/fold-findings/SKILL.md +59 -1
- package/skills/fold-findings/references/FOLD_POLICY.md +13 -0
- package/skills/fold-findings/references/FOLD_PROCESS.md +40 -3
- package/skills/plan-feature/SKILL.md +1 -1
- package/skills/plan-feature/references/ROUTING.md +7 -2
- package/skills/pre-execution-review/SKILL.md +1 -1
- package/skills/pre-execution-review/references/LEDGERS.md +6 -0
- package/skills/pre-execution-review/references/POLICY.md +28 -0
- package/skills/pre-execution-review/references/SNAPSHOT.md +6 -0
- package/skills/review-change/SKILL.md +1 -1
- package/skills/review-change/references/PERSIST_AND_DECIDE.md +6 -0
- package/skills/review-change/references/REVIEW_PROCESS.md +35 -2
- package/skills/review-plan/SKILL.md +10 -8
- package/skills/review-plan/references/OUTPUT.md +31 -17
- package/skills/review-spec/SKILL.md +1 -1
- package/skills/review-spec/references/OUTPUT.md +20 -1
- package/skills/ship-roadmap/SKILL.md +1 -1
- package/skills/ship-roadmap/references/ADVANCE.md +3 -3
- package/skills/workflow-status/SKILL.md +1 -1
- package/skills/workflow-status/references/PRE_EXECUTION.md +1 -0
- package/skills/workflow-status/references/SENSOR_CORE.md +7 -3
package/package.json
CHANGED
package/skills/audit-pr/SKILL.md
CHANGED
|
@@ -95,7 +95,7 @@ verdict:
|
|
|
95
95
|
`structural.reasonCode`/`changedPaths` name the drifted dimension), and — for a
|
|
96
96
|
feature unit — its named `— spec` parent re-derives the same way. Bound artifacts
|
|
97
97
|
are frozen: new implementation-phase files are allowed, edits to a bound artifact
|
|
98
|
-
are not. Stale, missing
|
|
98
|
+
are not. Stale, missing, wrong-stage **or impossible-timeline** lineage → **BLOCKED**,
|
|
99
99
|
`→ Next: /review-plan <unit>` (or `/review-spec <unit>` when the parent is the
|
|
100
100
|
broken link). A `SPEC-REVIEW-PASS` never satisfies the plan hop, and vice versa.
|
|
101
101
|
2. **Obligations are closed.** Every row of the unit's obligation ledger is
|
|
@@ -65,6 +65,11 @@ further edit, then routes to that owner. More cycles stay allowed when
|
|
|
65
65
|
correctness needs them; they never earn a PASS, and an exhausted cycle budget
|
|
66
66
|
does not downgrade an open finding.
|
|
67
67
|
|
|
68
|
+
A repair responding to a persisted verdict is **never** a loop defect (POLICY §4
|
|
69
|
+
scopes every guard to blind re-reviews): a unit whose `progress.md` carries an open
|
|
70
|
+
FAIL/NEEDS-DESIGN receipt is being repaired by definition, so no "already complete"
|
|
71
|
+
answer exists for it and no cycle cap converts its verdict into a dead end.
|
|
72
|
+
|
|
68
73
|
The spec-stage detail this skill adds: the owning stage of a Product-half miss is
|
|
69
74
|
`product` unless the evidence proves the plan asked for something the SPEC never
|
|
70
75
|
said — then it is `plan`, and it leaves this skill for `plan-feature`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: execute-phase
|
|
3
3
|
user-invocable: true
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.4.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>"
|
|
@@ -21,7 +21,7 @@ Actual: <receipt state — what was read, and `structural.changedPaths` +
|
|
|
21
21
|
`structural.reasonCode` from the verify run naming which bound file moved>
|
|
22
22
|
|
|
23
23
|
→ Next: /review-plan <NN>-<slug> — the plan needs a current independent review
|
|
24
|
-
· the review returned
|
|
24
|
+
· the review returned a Product-rooted finding → /design-feature <NN>-<slug>
|
|
25
25
|
· a bound artifact is genuinely wrong → /plan-feature <NN>-<slug> (re-cut), then re-review
|
|
26
26
|
· no bypass flag exists for this gate: --force has never covered it and does not now
|
|
27
27
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: fold-findings
|
|
3
3
|
user-invocable: true
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
argument-hint: [finding-id …]
|
|
6
6
|
author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
|
|
7
7
|
license: MIT
|
|
@@ -92,6 +92,37 @@ Folded: n/m · Disputed: k · Blocked: j · Replan: r
|
|
|
92
92
|
|
|
93
93
|
Omit `· Replan: r` when `r = 0` (preserves the existing three-field format).
|
|
94
94
|
|
|
95
|
+
Then print the REPAIR-RECEIPT as the ABSOLUTE-last output, together with the
|
|
96
|
+
branching `→ Next:` block below. The receipt is immutable once printed; a
|
|
97
|
+
later fold prints a new receipt (append-only output history — no ledger row,
|
|
98
|
+
no schema field). Six fields, always present:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
## REPAIR-RECEIPT
|
|
102
|
+
- Repaired: <F-ids with (VF-<n>) refs, joined ` + `, or `none`>
|
|
103
|
+
- Refuted/open: <F-ids joined ` + `, or `none`>
|
|
104
|
+
- Gate: <command> → exit <n> at head <40-hex sha> · n/a when nothing was folded
|
|
105
|
+
- Batch class: <all-repair-in-place | frozen (replan present) | none>
|
|
106
|
+
- Fold diff: <shortstat from a real `git diff` run> · none when nothing was folded
|
|
107
|
+
- Branch: <RE-REVIEW-REQUIRED (delta) | RE-REVIEW-OPTIONAL | RE-REVIEW-SKIPPED | REPLAN-ROUTE>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- The `Gate` line carries the actual exit codes observed at the head the gate
|
|
111
|
+
ran on — green or red. A **failed gate never silences the receipt**: the
|
|
112
|
+
batch is reported with the observed exit codes and nothing folded (a red gate
|
|
113
|
+
is not a silent gap).
|
|
114
|
+
- The `Fold diff` shortstat comes from a real `git diff` run over the batch's
|
|
115
|
+
commits.
|
|
116
|
+
- The `Batch class` derives from the taken queue's frozen rows only — the fold
|
|
117
|
+
never reclassifies (`all-repair-in-place`, `frozen (replan present)`, or
|
|
118
|
+
`none` for an empty queue); the vocabulary comes from
|
|
119
|
+
`review-implementation`'s closed class set.
|
|
120
|
+
|
|
121
|
+
**Freeze-batch (replan present).** When the taken queue contains any row whose
|
|
122
|
+
frozen class is `replan-in-unit` or `decision-required`, nothing folds: no
|
|
123
|
+
`folded: yes` flips, no commits. The receipt records the `REPLAN-ROUTE` branch
|
|
124
|
+
and every retained (unfolded) row id, and the loop stops to route to planning.
|
|
125
|
+
|
|
95
126
|
## Guardrails
|
|
96
127
|
|
|
97
128
|
Scope is the ledger (or explicit ID subset); unlisted discoveries are proposals
|
|
@@ -139,3 +170,30 @@ or touched outside the queue.
|
|
|
139
170
|
|
|
140
171
|
Replace placeholders with every actual affected finding ID before printing; never
|
|
141
172
|
print `<F2>`, `…`, or a single representative ID in a live hand-off.
|
|
173
|
+
|
|
174
|
+
## Closing-block decision branch (choose one, at emission)
|
|
175
|
+
|
|
176
|
+
The closing block picks exactly one of four outcomes. The **no-decision →
|
|
177
|
+
re-review default** holds whenever the turn carries no recorded prior consumer
|
|
178
|
+
decision to skip.
|
|
179
|
+
|
|
180
|
+
| Batch state | Branch | `→ Next:` (consumer) |
|
|
181
|
+
|---|---|---|
|
|
182
|
+
| freeze-batch (≥ 1 replan-class row) | `REPLAN-ROUTE` | plan-fix/execute-phase on this unit after the user confirms the replan |
|
|
183
|
+
| `all-repair-in-place` + docs-only + no folded row severity `high` + prior consumer skip decision | `RE-REVIEW-SKIPPED` | skip — consumer has explicitly decided to skip the re-review |
|
|
184
|
+
| `all-repair-in-place` + docs-only + no folded row severity `high` | `RE-REVIEW-OPTIONAL` | `/review-change` (default, delta mode) — or the consumer's recorded skip decision |
|
|
185
|
+
| empty batch (class `none`) | `RE-REVIEW-OPTIONAL` | `/review-change` by default — safe: the head is unchanged |
|
|
186
|
+
| anything else (behavioral surface or any folded row `high`) | `RE-REVIEW-REQUIRED (delta)` | `/review-change` — delta mode mandatory default |
|
|
187
|
+
|
|
188
|
+
**Branch-selection decision inputs.**
|
|
189
|
+
|
|
190
|
+
- **Docs-only test (E-D3).** ``RE-REVIEW-OPTIONAL`` requires every fold-diff
|
|
191
|
+
file to be a Markdown/documentation file; otherwise the batch is behavioral
|
|
192
|
+
(→ `RE-REVIEW-REQUIRED (delta)`).
|
|
193
|
+
- **Frozen-severity-`high` override.** A folded row whose frozen severity is
|
|
194
|
+
`high` forces `RE-REVIEW-REQUIRED (delta)` even on a docs-only diff. Frozen
|
|
195
|
+
fields are never edited to reach a branch.
|
|
196
|
+
- **SKIPPED requires prior consumer decision (E-D2).** `RE-REVIEW-SKIPPED`
|
|
197
|
+
is printed only by a turn carrying an explicit prior consumer decision to
|
|
198
|
+
skip. A turn with no recorded prior consumer decision prints
|
|
199
|
+
`RE-REVIEW-OPTIONAL` + the re-review default, **never** `RE-REVIEW-SKIPPED`.
|
|
@@ -48,3 +48,16 @@ Never edit an existing test's expectation to match behaviour: a setup repair may
|
|
|
48
48
|
only keep assertions at least as strong and never touch expectations; the
|
|
49
49
|
test-immutability contract (`verification-contract`) owns the sole amendment
|
|
50
50
|
path.
|
|
51
|
+
|
|
52
|
+
## Reproducer handoff (materialize, never re-derive)
|
|
53
|
+
|
|
54
|
+
Before repairing a **behavioral** finding, read the row's `finding-mark@1`
|
|
55
|
+
`recheck` cell (method + reproducer, written by `review-change` at verification
|
|
56
|
+
time) and materialize it as the regression check — the method as written (red
|
|
57
|
+
test first, reproducible command output, or direct read). The fold runner
|
|
58
|
+
**never invents or re-derives** the reproducer; it consumes the cell as the
|
|
59
|
+
allowed materialization.
|
|
60
|
+
|
|
61
|
+
- A `recheck` cell that cannot be materialized as a runnable check yields
|
|
62
|
+
`BLOCKED <missing input>` and names the missing input.
|
|
63
|
+
- Never substitute a weaker re-derived check for the recorded reproducer.
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
1. **Build the queue.** Take every `folded: no` fix-now row, or the explicit ID
|
|
4
4
|
subset, in severity/id order. `replan-in-unit` rows emit `REPLAN`; they stay
|
|
5
|
-
on the same SPEC/branch/PR and never become issues.
|
|
5
|
+
on the same SPEC/branch/PR and never become issues. **Empty batch:** an
|
|
6
|
+
empty queue (zero findings taken) prints a REPAIR-RECEIPT with batch class `none`
|
|
7
|
+
and nothing folded — a receipt only, no flips, no commits.
|
|
6
8
|
2. **Form the fewest atomic correction groups.** Findings may share one group
|
|
7
9
|
only when all boxes pass:
|
|
8
10
|
|
|
@@ -33,9 +35,44 @@
|
|
|
33
35
|
member so no finding disappears inside the batch.
|
|
34
36
|
6. **Continue groups.** A blocked/disputed group does not prevent independent
|
|
35
37
|
groups from folding. Leave its rows `no` and emit individual outcomes.
|
|
36
|
-
|
|
38
|
+
**Failed gate:** if the group's gate is red, do not fold the group — the
|
|
39
|
+
receipt records the observed gate exit codes and nothing is folded for it;
|
|
40
|
+
never silence the receipt and never commit red.
|
|
41
|
+
7. **Batch classification.** The batch class derives from the taken queue's
|
|
42
|
+
frozen rows only, and the fold never reclassifies:
|
|
43
|
+
|
|
44
|
+
| Condition over the taken batch | Batch class | Fold behavior |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| ≥ 1 row with frozen class `replan-in-unit` or `decision-required` | `frozen (replan present)` | **freeze-batch** — nothing folds, no `folded: yes` flips, no commits; the receipt records the REPLAN-ROUTE and every retained (unfolded) row id; the loop stops and routes to planning |
|
|
47
|
+
| all taken rows foldable, none replan-class | `all-repair-in-place` | fold as today (group → fix → gate → commit → flip) |
|
|
48
|
+
| empty queue (zero findings taken) | `none` | receipt only |
|
|
49
|
+
|
|
50
|
+
The batch-class vocabulary references only `review-implementation`'s closed
|
|
51
|
+
class set (`CLASSIFY.md`); the receipt invents no parallel vocabulary.
|
|
52
|
+
|
|
53
|
+
The emitted branch follows the closing-block decision inputs in the skill:
|
|
54
|
+
a freeze-batch always selects `REPLAN-ROUTE`; otherwise the docs-only
|
|
55
|
+
file-set test (E-D3) and the frozen-severity-`high` override (E-D2) select
|
|
56
|
+
`RE-REVIEW-OPTIONAL` vs `RE-REVIEW-REQUIRED (delta)`.
|
|
57
|
+
8. **Disputes.** Non-reproducible/already-fixed/wrong findings become
|
|
37
58
|
`DISPUTED <evidence → user decision>`; never edit classification or create an
|
|
38
59
|
issue.
|
|
39
|
-
|
|
60
|
+
9. **Replan.** If the smallest correct group exceeds a reviewable correction,
|
|
40
61
|
emit `REPLAN` with proposed phases appended to the same unit. After user
|
|
41
62
|
confirmation, `/execute-phase <unit>` completes them and ticks the rows.
|
|
63
|
+
|
|
64
|
+
## REPAIR-RECEIPT — fixed printed block (verbatim copy)
|
|
65
|
+
|
|
66
|
+
Printed after the per-finding table and tally, as part of the ABSOLUTE-last
|
|
67
|
+
output together with the branching `→ Next:` block. Six fields, always
|
|
68
|
+
present:
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
## REPAIR-RECEIPT
|
|
72
|
+
- Repaired: <F-ids with (VF-<n>) refs, joined ` + `, or `none`>
|
|
73
|
+
- Refuted/open: <F-ids joined ` + `, or `none`>
|
|
74
|
+
- Gate: <command> → exit <n> at head <40-hex sha> · n/a when nothing was folded
|
|
75
|
+
- Batch class: <all-repair-in-place | frozen (replan present) | none>
|
|
76
|
+
- Fold diff: <shortstat from a real `git diff` run> · none when nothing was folded
|
|
77
|
+
- Branch: <RE-REVIEW-REQUIRED (delta) | RE-REVIEW-OPTIONAL | RE-REVIEW-SKIPPED | REPLAN-ROUTE>
|
|
78
|
+
```
|
|
@@ -29,10 +29,15 @@ SPEC's `## Design status` marker is the SPEC-local record and the
|
|
|
29
29
|
→ Next: /execute-phase <NN> <next-phase> — this feature is already being
|
|
30
30
|
implemented; resume the current phase, don't re-plan it.
|
|
31
31
|
```
|
|
32
|
-
4. **Roadmap row status `done`** → **STOP
|
|
32
|
+
4. **Roadmap row status `done`** → **STOP** (replanning stays forbidden — the
|
|
33
|
+
feature is fully built), and: `done` means built + PR open with the human merge
|
|
34
|
+
pending (a lifecycle label, never a gate verdict), so this is **not** "nothing
|
|
35
|
+
pending". Route to the merge gate instead. Print exactly:
|
|
33
36
|
|
|
34
37
|
```
|
|
35
|
-
→ Next:
|
|
38
|
+
→ Next: /audit-pr <PR> — done means built + PR open, merge pending (a lifecycle label, never a gate verdict)
|
|
39
|
+
· the row's PR is merged → nothing pending, pick the next unit → /plan-feature --next
|
|
40
|
+
· no PR is open → the row is mislabeled or execution stopped → /execute-phase <NN> (never a replan)
|
|
36
41
|
```
|
|
37
42
|
5. **Roadmap row status `idea`, or no row at all** → **STOP**. Print exactly:
|
|
38
43
|
|
|
@@ -194,3 +194,9 @@ counter-evidence in the same report and **never becomes a row**, a fold task,
|
|
|
194
194
|
or a re-review trigger. The mark's `confirmed | refuted` value and the
|
|
195
195
|
`recheck` cell (the method the finding's axis demands) are what let a driver
|
|
196
196
|
outside the repo consume the verification the review performed.
|
|
197
|
+
|
|
198
|
+
`fold-findings` reads the `recheck` cell to **materialize** the finding's
|
|
199
|
+
reproducer as its regression check — it never re-derives it; a `recheck` cell
|
|
200
|
+
that cannot be materialized yields `BLOCKED <missing input>`. This consumption
|
|
201
|
+
leaves the row shape, the `VF-` exclusions, and the `review-change`
|
|
202
|
+
single-writer rule untouched.
|
|
@@ -76,6 +76,13 @@ on a Product- or Plan-rooted finding is invalid even when the candidate changed:
|
|
|
76
76
|
the loop repairs source, not authority. Runtime retry and budget mechanics stay
|
|
77
77
|
outside this policy and can never be translated into a PASS.
|
|
78
78
|
|
|
79
|
+
The guards above gate **blind re-reviews** — an identical snapshot with the
|
|
80
|
+
identical question — and never a repair performed in response to a persisted
|
|
81
|
+
verdict: a repair turn whose input is a FAIL/NEEDS-DESIGN receipt produces a new
|
|
82
|
+
snapshot by design, so no cycle cap or anomaly rule may block or end it. The
|
|
83
|
+
anomaly is printed and routed, never a stop, and no cap converts a verdict into a
|
|
84
|
+
dead end.
|
|
85
|
+
|
|
79
86
|
### 5. What a cycle can never produce
|
|
80
87
|
|
|
81
88
|
- A verdict from an author turn, a readiness preflight, a roadmap status, or a
|
|
@@ -93,6 +100,14 @@ outside this policy and can never be translated into a PASS.
|
|
|
93
100
|
an open row with a new name.
|
|
94
101
|
- Execution authority from a neighbouring stage: a `SPEC-REVIEW-PASS` never unlocks
|
|
95
102
|
`execute-phase`, and a `PLAN-REVIEW-PASS` never certifies the Product half.
|
|
103
|
+
- A gate answer from a roadmap row's status. Gates read receipts only;
|
|
104
|
+
roadmap rows are labels and never answer a gate. `done` means built + PR open
|
|
105
|
+
with the human merge pending (`docs/features/ROADMAP.md` § Status legend;
|
|
106
|
+
`docs/fix/README.md` § Status legend), so it never satisfies or suppresses a
|
|
107
|
+
pre-execution/verification gate, never retires the obligation to re-derive a
|
|
108
|
+
receipt, and never lets a reviewer or consumer report a unit closed while its
|
|
109
|
+
PR is unmerged. The complement of §5's "no verdict *from* a status" — and the
|
|
110
|
+
same rule read the other way: a status never **suppresses** a gate either.
|
|
96
111
|
|
|
97
112
|
### 6. Legacy adoption (units planned before this gate existed)
|
|
98
113
|
|
|
@@ -142,6 +157,19 @@ reports; a printed verdict whose mark is still "for next turn" is not finished.
|
|
|
142
157
|
a gate rejection. The mark is what the ownership map designates for that truth
|
|
143
158
|
class — receipt block, folded row, rejection trace — at the home and column set
|
|
144
159
|
[`LEDGERS.md`](LEDGERS.md) names. This section opens no second home.
|
|
160
|
+
- **The reviewer is consumer zero.** Write-then-report is mechanical, not prose: in
|
|
161
|
+
the same act as persisting the receipt, the reviewer runs the sensor's own
|
|
162
|
+
`verify --stage <spec|plan> --unit <id> [--dir …]` (the fix unit's recipe; a
|
|
163
|
+
feature plan adds `--parent`) and pastes the sensor's JSON answer beside the
|
|
164
|
+
verdict block *before* the report is printed. A digest-bound receipt requires
|
|
165
|
+
`structural.fresh: true` (and, for a PASS verdict, `current: true`); exit 3
|
|
166
|
+
(`missing-receipt-snapshot`) or a digest-bound `structural.fresh: false` means
|
|
167
|
+
the mark did not land — the reviewer fixes the write and re-runs, and the verdict
|
|
168
|
+
is not emit-able in that turn. A `Snapshot: refused` receipt's
|
|
169
|
+
`missing-receipt-snapshot` answer is its sanctioned form. A verdict block
|
|
170
|
+
printed without the pasted self-check output is a contract defect, and every
|
|
171
|
+
consumer reads a chat-only verdict as `missing-receipt-snapshot` — it does not
|
|
172
|
+
exist to the sensor.
|
|
145
173
|
- **A gate rejection is typed**, from a closed set of four: `dependency`, `status`,
|
|
146
174
|
`phase-lint`, `stale-or-missing-receipt`. Each fixed gate block carries its type
|
|
147
175
|
and names what it read and where the turn goes:
|
|
@@ -105,6 +105,12 @@ sensor exists to catch: they carry no bound digest, so they fail as
|
|
|
105
105
|
`missing-receipt-snapshot` rather than being interpreted charitably. Nothing here
|
|
106
106
|
grants a verdict — only a reviewer turn writes the block.
|
|
107
107
|
|
|
108
|
+
**The reviewer is consumer zero.** This re-verify recipe, run by the reviewer itself
|
|
109
|
+
in the same act as persisting the receipt (POLICY §8), is the self-check that makes
|
|
110
|
+
write-then-report mechanical: the reviewer runs `verify --stage …` for its own stage
|
|
111
|
+
before it prints the verdict and pastes the sensor's answer beside the block. The
|
|
112
|
+
recipe owner stays this file; §8 owns the rule the recipe serves.
|
|
113
|
+
|
|
108
114
|
### Authoring side: rotating the revision
|
|
109
115
|
|
|
110
116
|
The author's `artifactRevisionId` is the field that lets a reviewer prove its own
|
|
@@ -135,6 +135,12 @@
|
|
|
135
135
|
· adversarial recommendation checklist fired AND this run was
|
|
136
136
|
single-reviewer? → re-run the fold review as /review-change
|
|
137
137
|
--adversarial N (N per the ladder below) instead of single-reviewer
|
|
138
|
+
|
|
139
|
+
The two-cycle cap scopes the **review→fold loop on source findings** only (a
|
|
140
|
+
finding already on the branch, repaired here). A planning repair routed by a
|
|
141
|
+
`class: plan`/`product` finding is a **verdict response** under
|
|
142
|
+
`pre-execution-review` POLICY §4 — it re-derives plan/Product authority, not
|
|
143
|
+
source — so it is never a loop-defect stop and never counts against this cap.
|
|
138
144
|
(yes: <which box fired>; no: omit this line)
|
|
139
145
|
· SPEC drift flagged here AND on a prior unit? → /product-audit (yes: the
|
|
140
146
|
founding assumptions are probably stale — don't keep patching a
|
|
@@ -21,6 +21,37 @@
|
|
|
21
21
|
same location. A cycle ≥ 2 that produces any new fix-now row appends the
|
|
22
22
|
`CONVERGENCE-ANOMALY` block (`pre-execution-review/references/POLICY.md` §4)
|
|
23
23
|
to the report.
|
|
24
|
+
|
|
25
|
+
**Delta mode (default on a post-fold re-review).** When the preceding fold
|
|
26
|
+
receipt's branch is `RE-REVIEW-REQUIRED (delta)` — or `RE-REVIEW-OPTIONAL`
|
|
27
|
+
acted on with the re-review decision — the review runs **delta mode**:
|
|
28
|
+
|
|
29
|
+
1. Re-verify every `folded: yes` row at the `file:line` cited in its
|
|
30
|
+
`review-findings.md` row (the existing cycle-≥2 rule above);
|
|
31
|
+
2. Review the **fold diff only** (`git diff <pre-batch HEAD>..<batch HEAD>`
|
|
32
|
+
over the commits this turn's batch produced);
|
|
33
|
+
3. Require the **gate green at the reviewed head** and the sibling
|
|
34
|
+
`ACCEPTANCE.md` blob recomputed to an **exact match** — the step-2
|
|
35
|
+
structural precondition, unchanged and still mandatory;
|
|
36
|
+
4. Append the normal `review-mark@1` `REVIEW-RAN` mark — delta cycles count
|
|
37
|
+
toward the two-cycle cap from the unchanged source (marks + forge
|
|
38
|
+
receipts), never a fresh reset;
|
|
39
|
+
5. Admit a candidate only when **genuinely new**: a same-`file:line`+axis
|
|
40
|
+
re-report inside the delta scope is admitted only as
|
|
41
|
+
`regression of <id>` or `DISPUTED`, never a plain new row (extending the
|
|
42
|
+
cycle-2 rule to the whole delta scope);
|
|
43
|
+
6. A clean delta pass posts the normal SHA-bound `REVIEW-PASS`.
|
|
44
|
+
|
|
45
|
+
**Escalation to a full pass.** Either trigger escalates a delta review to a
|
|
46
|
+
full pass, and the escalation **states which trigger fired and the observed
|
|
47
|
+
numbers**:
|
|
48
|
+
|
|
49
|
+
- **Width** — any changed file outside the union of the batch's cited files
|
|
50
|
+
(the folded rows' `file:line`), or any changed line in a cited file more
|
|
51
|
+
than **50 lines** from every cited line in that file (changed-line starts
|
|
52
|
+
read from `git diff --unified=0` hunk headers);
|
|
53
|
+
- **Size** — added+deleted changed lines **> 200**, or changed files
|
|
54
|
+
**> 15** (`git diff --numstat`).
|
|
24
55
|
2. **Frozen acceptance + SPEC drift check (structural).** Locate sibling
|
|
25
56
|
`ACCEPTANCE.md`, recompute its blob, and require an exact match with the
|
|
26
57
|
execution receipt before assessing the candidate. Missing/mismatch is a
|
|
@@ -129,8 +160,10 @@
|
|
|
129
160
|
|
|
130
161
|
The review→fold loop runs at most **two** review→fold cycles per unit, counted
|
|
131
162
|
unit-level and family-agnostic from the ledger's `REVIEW-RAN` marks and forge
|
|
132
|
-
receipts — new finding families do not reset the count.
|
|
133
|
-
|
|
163
|
+
receipts — new finding families do not reset the count. **Delta cycles count
|
|
164
|
+
from the same unchanged source** (the `review-mark@1` marks + forge receipts), so
|
|
165
|
+
a delta-scoped re-review does not escape or reset the two-cycle bound. After two
|
|
166
|
+
cycles without convergence, the review prints
|
|
134
167
|
|
|
135
168
|
```text
|
|
136
169
|
LOOP CAP REACHED — <unit>
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review-plan
|
|
3
3
|
user-invocable: true
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.6.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
|
|
8
8
|
description: >
|
|
9
9
|
Independent read-only review of a frozen Engineering plan before execution, in a
|
|
10
10
|
context that did not cut it: feature or fix snapshot, obligation ledger sweep,
|
|
11
|
-
phase and validator checks. Returns only PLAN-REVIEW-PASS
|
|
12
|
-
|
|
11
|
+
phase and validator checks. Returns only PLAN-REVIEW-PASS or PLAN-REVIEW-FAIL
|
|
12
|
+
with a snapshot-bound receipt (a product-intent gap is PLAN-REVIEW-FAIL with
|
|
13
|
+
`class: product`). Never edits a plan artifact.
|
|
13
14
|
Triggers: "review-plan", "review the plan", "review the phases".
|
|
14
15
|
---
|
|
15
16
|
|
|
@@ -81,7 +82,7 @@ another `references/` path.
|
|
|
81
82
|
|---|---|---|
|
|
82
83
|
| Roadmap row read, unit kind known (feature or fix) | [checks](references/CHECKS.md) — snapshot construction, falsification, the L1–L6 ledger sweep | [eng-checks](references/ENG-CHECKS.md) and [output](references/OUTPUT.md) |
|
|
83
84
|
| Snapshot bound and the ledgers swept clean enough to judge the plan | [eng-checks](references/ENG-CHECKS.md) — P1–P12, plus F1–F4 for a fix unit | [output](references/OUTPUT.md) until every check has a result |
|
|
84
|
-
| Any check failed, the parent receipt is missing/stale, or a product choice is open | [output](references/OUTPUT.md) for the FAIL
|
|
85
|
+
| Any check failed, the parent receipt is missing/stale, or a product choice is open | [output](references/OUTPUT.md) for the FAIL block (product-intent gaps get `class: product`) and route | — |
|
|
85
86
|
| A prior Plan receipt exists for this unit | [output](references/OUTPUT.md) §Repeats for the no-progress / convergence gate before re-running anything | never blend rows from two snapshots |
|
|
86
87
|
|
|
87
88
|
## Guardrails
|
|
@@ -98,12 +99,13 @@ another `references/` path.
|
|
|
98
99
|
candidate `ReviewReceipt` or a staged `VerificationReceipt` answers different
|
|
99
100
|
questions and never stands in for a Plan review. A missing parent receipt is
|
|
100
101
|
reported, not repaired by assumption.
|
|
101
|
-
- **
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
- **Two verdicts only.** Exactly `PLAN-REVIEW-PASS | PLAN-REVIEW-FAIL`.
|
|
103
|
+
No partial pass, no "approve with caveats", no SPEC verdict, no generic
|
|
104
|
+
"approved" verb (PD1). The design-verdict token is not a verdict at this stage — a gap
|
|
105
|
+
requiring invented product intent is `PLAN-REVIEW-FAIL` with `class: product`.
|
|
104
106
|
- **No engineering decisions invented.** Where the right phase cut, validator, or
|
|
105
107
|
migration depends on a product choice this review cannot make, return
|
|
106
|
-
`
|
|
108
|
+
`class: product` and route it to the human through `design-feature` — invalidating
|
|
107
109
|
downstream Plan evidence is the point.
|
|
108
110
|
- **No source fixes.** A plan defect that this turn could "just patch" is still a
|
|
109
111
|
defect: report it and route it. Implementing while reviewing collapses the gate.
|
|
@@ -13,7 +13,7 @@ One `PreExecutionReviewReceipt v1`
|
|
|
13
13
|
|
|
14
14
|
```text
|
|
15
15
|
## Pre-execution review receipt v1 — plan
|
|
16
|
-
- Review: <receipt-id> · Snapshot: <64-hex|refused> · Verdict: <plan-review-pass|plan-review-fail
|
|
16
|
+
- Review: <receipt-id> · Snapshot: <64-hex|refused> · Verdict: <plan-review-pass|plan-review-fail>
|
|
17
17
|
- Unit: <unitId> · Stage: plan · Unit kind: <feature|fix>
|
|
18
18
|
- Parent SPEC snapshot: <64-hex> · Parent Product receipt: <receipt-id of the current SPEC-REVIEW-PASS>
|
|
19
19
|
- Source revision: <40-hex> · Artifact revision: <artifactRevisionId>
|
|
@@ -52,6 +52,26 @@ verdict, and file one finding row per refused artifact carrying its code verbati
|
|
|
52
52
|
checks bind to a snapshot, so with no snapshot none of them ran. `SNAPSHOT.md` owns why
|
|
53
53
|
a refusal prints no digest and what a consumer then reads this receipt as.
|
|
54
54
|
|
|
55
|
+
**Self-check (`verify --stage plan …`, POLICY §8).** In the same act as appending the
|
|
56
|
+
receipt, run the recipe owner's re-verify for this stage and paste the sensor's JSON
|
|
57
|
+
answer beside the verdict block before reporting. A feature plan run names `--parent`
|
|
58
|
+
(the Product digest this plan descended from); a fix unit omits it (it binds none):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# feature plan — binds the Product snapshot it descends from
|
|
62
|
+
node scripts/pre-execution-snapshot.mjs verify --stage plan --unit <NN-slug> --dir docs/features/<NN>-<slug> --unit-kind feature --parent <64-hex>
|
|
63
|
+
# fix unit — no Product half exists (D6)
|
|
64
|
+
node scripts/pre-execution-snapshot.mjs verify --stage plan --unit fix-<N> --dir docs/fix/<N> --unit-kind fix
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
A digest-bound receipt requires `structural.fresh: true` (and, for a PASS verdict,
|
|
68
|
+
`current: true`); `exit 3` (`missing-receipt-snapshot`) or a digest-bound
|
|
69
|
+
`structural.fresh: false` means the mark did not land — fix the write and re-run, the
|
|
70
|
+
verdict is not emit-able in this turn. A `Snapshot: refused` receipt's
|
|
71
|
+
`missing-receipt-snapshot` answer is its sanctioned form. A verdict block printed
|
|
72
|
+
without the pasted self-check output is a contract defect — chat-only is
|
|
73
|
+
`missing-receipt-snapshot` to every consumer.
|
|
74
|
+
|
|
55
75
|
### Verdict blocks — return exactly one
|
|
56
76
|
|
|
57
77
|
```text
|
|
@@ -72,20 +92,11 @@ PLAN-REVIEW-FAIL — <NN-slug|fix-N> BLOCKED
|
|
|
72
92
|
- Parent state: <current | stale-parent → review-spec first | missing → review-spec first>
|
|
73
93
|
```
|
|
74
94
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
-
|
|
78
|
-
-
|
|
79
|
-
|
|
80
|
-
- Downstream: this Plan receipt and every execution decision bound to the parent
|
|
81
|
-
Product half are invalid until the answer lands and the Product half is re-reviewed
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
`NEEDS-DESIGN` when the answer requires inventing product intent, scope, role,
|
|
85
|
-
authority, or user outcome; `PLAN-REVIEW-FAIL` when the plan is decidable but
|
|
86
|
-
incomplete, contradictory, unowned, or unsupported. Never blend them; never emit
|
|
87
|
-
a fourth verdict, a generic "approved", or a `SPEC-REVIEW-*` verdict from this
|
|
88
|
-
stage.
|
|
95
|
+
`PLAN-REVIEW-FAIL` when the plan is decidable but incomplete, contradictory,
|
|
96
|
+
unowned, or unsupported. A gap that requires **inventing product intent is
|
|
97
|
+
`PLAN-REVIEW-FAIL` with `class: product`** — the design-verdict token is not a
|
|
98
|
+
verdict at this stage: only `review-spec` may emit it. Never emit a generic
|
|
99
|
+
"approved" or a `SPEC-REVIEW-*` verdict from this stage.
|
|
89
100
|
|
|
90
101
|
### Routes
|
|
91
102
|
|
|
@@ -104,7 +115,6 @@ not authority.
|
|
|
104
115
|
| `PLAN-REVIEW-FAIL`, `class: plan` | `plan-feature` / `plan-fix` (the author) | one root-caused repair batch → new `artifactRevisionId` → re-review of the new snapshot |
|
|
105
116
|
| `PLAN-REVIEW-FAIL`, `class: product` | `design-feature` | repair the Product half → `review-spec` → the Plan receipt is re-derived (`stale-parent`) |
|
|
106
117
|
| `PLAN-REVIEW-FAIL`, `class: source\|environment\|runtime` | its owner, later | record the row, keep it `open`, route it. Do not edit the plan to hide it and do not start `execute-phase` on a plan carrying an open material row |
|
|
107
|
-
| `NEEDS-DESIGN` | the human, through `design-feature` | dated amendment → new Product revision → `review-spec` → `plan-feature` replan → `/review-plan` again |
|
|
108
118
|
|
|
109
119
|
Repeating this review follows the no-progress and convergence rules in
|
|
110
120
|
`pre-execution-review/references/POLICY.md` §4 — a repeat needs
|
|
@@ -121,6 +131,10 @@ into `review-change → fold-findings`, which repairs source, not plan authority
|
|
|
121
131
|
✓ L1–L6 resolved, and every applicable P/F check resolved to pass / finding / n/a
|
|
122
132
|
✓ Obligation ledger swept row by row: none blank, deferred, duplicated, unvalidated
|
|
123
133
|
✓ One verdict block returned verbatim from the closed set
|
|
134
|
+
✓ RUN `verify --stage plan` for this stage in-turn (feature plan names `--parent`;
|
|
135
|
+
fix omits it), JSON pasted beside the block; `structural.fresh: true` (+ `current: true` on PASS) —
|
|
136
|
+
`exit 3`/`structural.fresh: false` means the mark did not land, fix and re-run;
|
|
137
|
+
`exit 4`/`current: false` means a verdict persisted but not a PASS — the verdict itself is the emit result, route per verdict
|
|
124
138
|
✓ Receipt appended to progress.md and findings appended to planning-findings.md
|
|
125
139
|
✓ `git status --porcelain` shows no change to any reviewed plan artifact
|
|
126
140
|
✓ Closing `→ Next:` printed as the absolute last output
|
|
@@ -136,7 +150,7 @@ On PASS:
|
|
|
136
150
|
· Product half moved after this receipt → the parent went stale: /review-spec <NN>
|
|
137
151
|
```
|
|
138
152
|
|
|
139
|
-
On FAIL
|
|
153
|
+
On FAIL, name every finding id once, in order, joined with ` + `:
|
|
140
154
|
|
|
141
155
|
```
|
|
142
156
|
→ Next: /plan-feature <NN-slug> "<instruction>" (or /plan-fix <N> "<instruction>") —
|
|
@@ -42,6 +42,22 @@ verdict, and file one finding row per refused artifact carrying its code verbati
|
|
|
42
42
|
checks bind to a snapshot, so with no snapshot none of them ran. `SNAPSHOT.md` owns why
|
|
43
43
|
a refusal prints no digest and what a consumer then reads this receipt as.
|
|
44
44
|
|
|
45
|
+
**Self-check (`verify --stage spec …`, POLICY §8).** In the same act as appending the
|
|
46
|
+
receipt, run the recipe owner's re-verify for this stage and paste the sensor's JSON
|
|
47
|
+
answer beside the verdict block before reporting:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
node scripts/pre-execution-snapshot.mjs verify --stage spec --unit <NN-slug> --dir docs/features/<NN>-<slug> --unit-kind <feature|fix>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
A digest-bound receipt requires `structural.fresh: true` (and, for a PASS verdict,
|
|
54
|
+
`current: true`); `exit 3` (`missing-receipt-snapshot`) or a digest-bound
|
|
55
|
+
`structural.fresh: false` means the mark did not land — fix the write and re-run, the
|
|
56
|
+
verdict is not emit-able in this turn. A `Snapshot: refused` receipt's
|
|
57
|
+
`missing-receipt-snapshot` answer is its sanctioned form. A verdict block printed
|
|
58
|
+
without the pasted self-check output is a contract defect — chat-only is
|
|
59
|
+
`missing-receipt-snapshot` to every consumer.
|
|
60
|
+
|
|
45
61
|
### Verdict blocks — return exactly one
|
|
46
62
|
|
|
47
63
|
```text
|
|
@@ -110,7 +126,10 @@ is ever lost between cycles.
|
|
|
110
126
|
✓ Snapshot digest computed from one revision and pasted; no mixed-revision bytes
|
|
111
127
|
✓ All 14 Product checks resolved to pass / finding / n/a with a reason
|
|
112
128
|
✓ One verdict block returned verbatim from the closed set
|
|
113
|
-
✓
|
|
129
|
+
✓ RUN `verify --stage spec` for this stage in-turn, JSON pasted beside the block;
|
|
130
|
+
`structural.fresh: true` (+ `current: true` on PASS) — `exit 3`/`structural.fresh: false` means
|
|
131
|
+
the mark did not land, fix and re-run, verdict not emit-able; `exit 4`/`current: false` means
|
|
132
|
+
a verdict persisted but not a PASS — the verdict itself is the emit result, route per verdict
|
|
114
133
|
✓ `git status --porcelain` shows no change to any reviewed artifact
|
|
115
134
|
✓ Closing `→ Next:` printed as the absolute last output
|
|
116
135
|
```
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
- **REVIEW-PLAN** (only between PLAN and EXECUTE) — compose `review-plan` in a
|
|
43
43
|
clean context at the routed tier over the plan the previous stage just froze.
|
|
44
44
|
`PLAN-REVIEW-PASS` releases EXECUTE. A FAIL routes by root cause: plan-local
|
|
45
|
-
(bad phase cut, blank validator, ledger drift) →
|
|
46
|
-
planning author and a
|
|
47
|
-
cannot settle →
|
|
45
|
+
(bad phase cut, blank validator, ledger drift) → root-caused re-cut by the
|
|
46
|
+
planning author and a review; product-rooted or an assumption this record
|
|
47
|
+
cannot settle → PLAN-REVIEW-FAIL with class: product → design-feature. A second local cycle
|
|
48
48
|
that changes nothing stops editing and reports `CONVERGENCE-ANOMALY` instead of
|
|
49
49
|
burning a third budget. **No stage between PLAN and EXECUTE may create a forge
|
|
50
50
|
issue or defer an obligation to one** — an unmet obligation fails this stage, it
|
|
@@ -47,6 +47,7 @@ sensor reports a missing gate, never a verdict that no review ever happened.
|
|
|
47
47
|
| `self-approved` | the author of the artifact recorded the PASS | that stage's review in a clean context |
|
|
48
48
|
| `author-readiness` | an authoring readiness result sits where a verdict should be | that stage's review — readiness never licenses execution |
|
|
49
49
|
| `legacy` | `planned`/`in-progress` unit with no ledgers and no receipt (predates feature 28) | the adoption route below |
|
|
50
|
+
| `impossible-timeline` | `structural.fresh: false`, `structural.reasonCode: impossible-timeline` — digest and revision match by construction; a receipt's own recorded timeline is physically impossible (finish predating source revision's commit date beyond the published skew); a legacy receipt with no parsable Started/finished: line, or a source revision git cannot resolve, stays unflagged (fail-open) | that stage's review — the timeline is self-refuting, not a stale source |
|
|
50
51
|
|
|
51
52
|
A stale receipt re-runs the **review**, not the authoring skill: the artifacts may be
|
|
52
53
|
exactly right and simply need re-judging in a clean context. A missing verdict block,
|
|
@@ -64,14 +64,18 @@ live evidence against a frozen ledger remains a contradiction candidate.
|
|
|
64
64
|
command matched to the exact status: `defined` → `/plan-feature <slug>`,
|
|
65
65
|
`planned` → `/execute-phase <NN>`.
|
|
66
66
|
- deps unmet (any status ≥ `defined`) → `blocked_units` (unchanged).
|
|
67
|
-
6a. **Sense the pre-execution receipts** for every unit at `defined`, `planned
|
|
68
|
-
`in-progress`
|
|
67
|
+
6a. **Sense the pre-execution receipts** for every unit at `defined`, `planned`,
|
|
68
|
+
`in-progress`, **or `done` with a linked PR that is still open (unmerged — merge
|
|
69
|
+
state lives in the forge)** ([pre-execution evidence](PRE_EXECUTION.md)). A
|
|
70
|
+
done-but-unmerged row is a lifecycle label, never merge-ready, so a stale or
|
|
71
|
+
missing receipt there surfaces as a gate blocker; merged units stay excluded
|
|
72
|
+
(the merge itself closes their gates). Read the stage's
|
|
69
73
|
newest receipt block, re-derive the bound digest with the recipe owner's
|
|
70
74
|
verify mode (`node scripts/pre-execution-snapshot.mjs verify --stage
|
|
71
75
|
<spec|plan> --unit <id> [--parent <64-hex>]` — a snapshot digest is a canonical SHA-256, never a
|
|
72
76
|
git blob id; `structural.reasonCode` names the dimension that drifted), and
|
|
73
77
|
label the stage `current`/`missing`/`stale`/`wrong-stage`/`substitute`/
|
|
74
|
-
`self-approved`/`author-readiness`/`legacy
|
|
78
|
+
`self-approved`/`author-readiness`/`legacy`/`impossible-timeline` (unresolvable revision or unparsable timeline: fail-open → unflagged). The label **overrides step 6's
|
|
75
79
|
status-only command**: a unit without a current PASS for the stage it is about to
|
|
76
80
|
enter is demoted out of `startable_now` into a `gate` blocker naming the missing
|
|
77
81
|
review, and `detail.pre_execution[]` records the row. A roadmap row is never
|