@gtrabanco/pi-agentic-workflow 0.1.0 → 0.2.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/README.es.md +2 -0
- package/README.md +2 -0
- package/package.json +1 -1
- package/skills/audit-pr/SKILL.md +4 -1
- package/skills/audit-pr/references/02_CLOSURE_AND_SCOPE_GATES.md +35 -0
- package/skills/design-feature/SKILL.md +58 -21
- package/skills/design-feature/references/INTERVIEW.md +17 -0
- package/skills/design-feature/references/REPAIR.md +81 -0
- package/skills/design-feature/references/WRITE_AND_UPSERT.md +25 -2
- package/skills/discover-repository-state/SKILL.md +2 -1
- package/skills/evidence-grounding/SKILL.md +163 -0
- package/skills/evidence-grounding/references/DELEGATION.md +131 -0
- package/skills/evidence-grounding/references/READINESS.md +130 -0
- package/skills/evidence-grounding/references/ROWS.md +93 -0
- package/skills/execute-phase/SKILL.md +6 -1
- package/skills/execute-phase/references/DESCOPE.md +11 -5
- package/skills/execute-phase/references/PREFLIGHT.md +38 -1
- package/skills/execute-phase/references/PRE_EXECUTION_GATE.md +78 -0
- package/skills/loop-review-fold/SKILL.md +25 -2
- package/skills/orchestration-envelope/references/TURN_CONTRACT.md +34 -0
- package/skills/plan-feature/SKILL.md +37 -10
- package/skills/plan-feature/references/ROUTING.md +61 -2
- package/skills/plan-feature-from-issue/SKILL.md +30 -8
- package/skills/plan-feature-scaffold/SKILL.md +1 -1
- package/skills/plan-feature-scaffold/references/SCAFFOLD_PROCESS.md +35 -2
- package/skills/plan-fix/SKILL.md +31 -8
- package/skills/plan-fix/references/PLANNING_PROCESS.md +15 -0
- package/skills/pre-execution-review/SKILL.md +73 -0
- package/skills/pre-execution-review/references/LEDGERS.md +174 -0
- package/skills/pre-execution-review/references/POLICY.md +182 -0
- package/skills/pre-execution-review/references/SNAPSHOT.md +112 -0
- package/skills/resolve-repository-state/SKILL.md +2 -1
- package/skills/review-change/SKILL.md +1 -1
- package/skills/review-change/references/PERSIST_AND_DECIDE.md +5 -0
- package/skills/review-implementation/SKILL.md +1 -1
- package/skills/review-implementation/references/CLASSIFY.md +24 -0
- package/skills/review-plan/SKILL.md +152 -0
- package/skills/review-plan/references/CHECKS.md +108 -0
- package/skills/review-plan/references/ENG-CHECKS.md +30 -0
- package/skills/review-plan/references/OUTPUT.md +140 -0
- package/skills/review-spec/SKILL.md +145 -0
- package/skills/review-spec/references/CHECKS.md +105 -0
- package/skills/review-spec/references/OUTPUT.md +126 -0
- package/skills/ship-roadmap/SKILL.md +1 -1
- package/skills/ship-roadmap/references/ADVANCE.md +34 -6
- package/skills/ship-roadmap/references/CLOSEOUT_AND_LOG.md +2 -1
- package/skills/ship-roadmap/references/MODEL_ROUTING.md +2 -0
- package/skills/ship-roadmap/references/RECOVERY_AND_SELECTION.md +3 -2
- package/skills/workflow-status/SKILL.md +11 -5
- package/skills/workflow-status/references/ENVELOPE_FIELDS.md +6 -2
- package/skills/workflow-status/references/PRE_EXECUTION.md +78 -0
- package/skills/workflow-status/references/SENSOR_CORE.md +46 -6
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
## Snapshot, prompt, and Product checks
|
|
2
|
+
|
|
3
|
+
Run in this order: build the snapshot, then falsify, then check. Nothing below
|
|
4
|
+
writes to the reviewed artifact.
|
|
5
|
+
|
|
6
|
+
### 1. Build the snapshot (exact bytes, one revision)
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
git rev-parse HEAD # sourceRevision — one value for the whole review
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Construct `PreExecutionArtifactSnapshot v1` (`agentic-workflow/
|
|
13
|
+
pre-execution-artifact-snapshot@1`) over the bytes just read. The authoritative
|
|
14
|
+
validator is `@gtrabanco/agentic-workflow-schema`'s
|
|
15
|
+
`validatePreExecutionArtifactSnapshotV1`; the generated JSON Schema is a
|
|
16
|
+
structural projection, never the authority. Where that package is unavailable,
|
|
17
|
+
record the same fields by hand and state `validated: manual` in the receipt note.
|
|
18
|
+
|
|
19
|
+
A SPEC-stage snapshot is deliberately narrow:
|
|
20
|
+
|
|
21
|
+
| Field | Value for this stage |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `stage` | `spec` |
|
|
24
|
+
| `unitKind` | `feature` (a `fix` unit is refused here — no Product half) |
|
|
25
|
+
| `unitId` | the roadmap unit id, e.g. `28-evidence-grounded-spec-plan-review` |
|
|
26
|
+
| `sourceRevision` | the exact revision read above |
|
|
27
|
+
| `artifactRevisionId` | the author's current revision id from the handoff |
|
|
28
|
+
| `artifacts` | **exactly one row**: `kind: spec`, `path` normalized repo-relative, `selector: spec-product-v1`, `byteLength`, lowercase SHA-256 `digest` |
|
|
29
|
+
| `parentSpecSnapshotDigest` | `null` — a SPEC snapshot roots its own lineage |
|
|
30
|
+
| `contexts` | each authoritative source actually consulted: `roadmap-row`, `governing-issue`, `normalized-repository-state`, `architectural-invariants`, `dependency-unit`, `project-guide` — `present` with its exact digest, or `absent` with `null` |
|
|
31
|
+
|
|
32
|
+
`spec-product-v1` selects the title, `## Goal`, `## Branch`, `## Size`,
|
|
33
|
+
`## Dependencies`, the whole Product half, and `## Design status` — never the
|
|
34
|
+
empty or future Engineering half, so planning writes cannot invalidate this
|
|
35
|
+
review by themselves. Contexts are all-or-nothing on purpose: "I did not look"
|
|
36
|
+
is not representable, so an unread authority must appear as `absent` and is then
|
|
37
|
+
visible to whoever reads the receipt.
|
|
38
|
+
|
|
39
|
+
Ordering is normative, not cosmetic: artifact rows sort by UTF-8 path bytes,
|
|
40
|
+
context rows by `kind` then `identifier`, and each `(kind, identifier)` context
|
|
41
|
+
appears once. Duplicate kinds, out-of-order rows, or extra artifact rows are
|
|
42
|
+
contract failures, not style.
|
|
43
|
+
|
|
44
|
+
Then build the snapshot with the recipe owner —
|
|
45
|
+
`pre-execution-review`'s [`SKILL.md`](<../../pre-execution-review/SKILL.md>) →
|
|
46
|
+
SNAPSHOT reference: `node scripts/pre-execution-snapshot.mjs build --stage spec
|
|
47
|
+
--unit <unitId>` (canonical serializer: sorted keys, context rows ordered by kind
|
|
48
|
+
then identifier, UTF-8, lowercase SHA-256). The digest is stdout's first line, so
|
|
49
|
+
this recipe writes no file; `--json` is in-repository only. Paste the digest it
|
|
50
|
+
prints. Every verdict below is bound to that digest, and a refused build
|
|
51
|
+
(partial binding) ends this turn in the refusal form [`OUTPUT.md`](OUTPUT.md) fixes —
|
|
52
|
+
`Snapshot: refused` beside the builder's own code, never a hand-computed substitute.
|
|
53
|
+
|
|
54
|
+
### 2. Clean-context falsification prompt
|
|
55
|
+
|
|
56
|
+
Read the snapshot's Product bytes as if the document were adversarial, then
|
|
57
|
+
answer, in writing, before checking anything:
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
FALSIFICATION — <unitId> @ <sourceRevision short>
|
|
61
|
+
- Name 3 specific product decisions in this half that a hostile reader could
|
|
62
|
+
call invented rather than recorded: <section/row pointers or "none found">
|
|
63
|
+
- Name the user outcome the SPEC promises that has no observable check: <row>
|
|
64
|
+
- Name one role the matrix leaves unspecified for a capability it does list:
|
|
65
|
+
<row or "none">
|
|
66
|
+
- What would have to be true in the repository for this half to be wrong, and is
|
|
67
|
+
it true? <evidence pointer>
|
|
68
|
+
- Verdict stance before checking: <CONFIRMED-GAPS | NO-CONFIRMED-GAPS>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The point is to try to break the document, not to summarize it. A gap this pass
|
|
72
|
+
confirms is a finding; a suspicion it cannot evidence is not.
|
|
73
|
+
|
|
74
|
+
### 3. Product checks (fixed list — one row each, in order)
|
|
75
|
+
|
|
76
|
+
| # | Check | PASS only if |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| C1 | Outcome ownership | the user outcome each in-scope item produces is stated and observable, not "improve X" |
|
|
79
|
+
| C2 | Actors and roles | every actor that can trigger or be affected is named, and the role matrix covers every inventory role per capability with no unlisted role |
|
|
80
|
+
| C3 | Entity closure | every entity introduced or touched resolves CRUD + state transitions to UI/API/test or an explicit `n/a: <reason>`; zero blank rows |
|
|
81
|
+
| C4 | Limits and failure states | size/failure/empty/concurrency limits are stated or explicitly out of scope; each named failure state has a resolution |
|
|
82
|
+
| C5 | Scope and non-goals | every out-of-scope bullet names an owner or a non-goal; nothing is excluded by silence |
|
|
83
|
+
| C6 | Integration closure | one resolved row per subsystem of the derived capability inventory; none skipped; the inventory is recorded when `docs/CAPABILITIES.md` is absent |
|
|
84
|
+
| C7 | Expectation sweep | ≥ 10 rows (M/L) / ≥ 5 (XS/S), each forced to in-scope/out-of-scope/deferred with a pointer |
|
|
85
|
+
| C8 | Acceptance objectivity | every criterion is objective and labelled command-verified or read-verified, and every in-scope bullet maps to ≥ 1 criterion |
|
|
86
|
+
| C9 | Internal contradiction | no two sections of the half assert incompatible behaviour, counts, or ownership |
|
|
87
|
+
| C10 | Repository contradiction | the half's claims about existing surfaces match what is in the repository now (cited `path:line`, roadmap row, or frozen ledger fact) |
|
|
88
|
+
| C11 | Evidence integrity | material claims resolve to `proven`/`decision` rows that are `current`; every `unknown` names an owner and next evidence; no `drifted`/`stale` row survives |
|
|
89
|
+
| C12 | Open product choices | `Deferred decisions` is `none`, or each open item is genuinely product-owned and flagged for the human |
|
|
90
|
+
| C13 | Engineering leakage | the Product half pre-fills no architecture, phases, tasks, or validators (that is the Plan stage's authority) |
|
|
91
|
+
| C14 | Obligation containment | no current-unit obligation is exported to a future issue or "later" — the unit's own scope carries it |
|
|
92
|
+
|
|
93
|
+
Every row gets exactly one result: `pass`, `finding`, or `n/a: <reason>`. `n/a`
|
|
94
|
+
requires a reason that does not contradict scope (an accessibility row is `n/a`
|
|
95
|
+
when no UI exists; "skipped because large" is not `n/a`).
|
|
96
|
+
|
|
97
|
+
### 4. Assemble findings
|
|
98
|
+
|
|
99
|
+
Each finding is one row of the receipt's `findings` array: stable `id`,
|
|
100
|
+
`severity` (`info | low | medium | high | critical`), `class` (`product | plan |
|
|
101
|
+
source | environment | runtime`), `claim` (what is wrong, with the section
|
|
102
|
+
pointer), `evidenceRefs` (≥ 1 — a finding without evidence is a hunch and gets
|
|
103
|
+
dropped), `verification` (`verified | unverified`), `resolution` (`open` on
|
|
104
|
+
emission). Material = anything above `info`; a `PASS` may not carry an open or
|
|
105
|
+
unverified material row.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
## Verdicts, receipt, and routes
|
|
2
|
+
|
|
3
|
+
### Persist the receipt first, then report
|
|
4
|
+
|
|
5
|
+
Append the receipt to the unit's `docs/features/<NN>-<slug>/progress.md` **and
|
|
6
|
+
each finding row to the unit's `planning-findings.md`** with
|
|
7
|
+
`stage: spec` (ledger contract: `pre-execution-review/references/LEDGERS.md`);
|
|
8
|
+
create the file from that contract when the unit has none. A findings ledger the
|
|
9
|
+
reviewer cannot write is not a ledger. Any later write to a reviewed artifact
|
|
10
|
+
rotates `artifactRevisionId` and makes this receipt stale — that is the contract
|
|
11
|
+
working, not a mistake.
|
|
12
|
+
|
|
13
|
+
One `PreExecutionReviewReceipt v1`
|
|
14
|
+
(`agentic-workflow/pre-execution-review-receipt@1`) per review, in a fenced block:
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
## Pre-execution review receipt v1 — spec
|
|
18
|
+
- Review: <receipt-id> · Snapshot: <64-hex|refused> · Verdict: <spec-review-pass|spec-review-fail|needs-design>
|
|
19
|
+
- Unit: <unitId> · Stage: spec · Unit kind: <feature|fix> · Parent: null
|
|
20
|
+
- Source revision: <40-hex> · Artifact revision: <artifactRevisionId>
|
|
21
|
+
- Reviewer: <id> · Session: <id> · Role: reviewer · Author: <id>
|
|
22
|
+
- Author exclusion: <enforced|not-enforceable> · Context clean: <true|false>
|
|
23
|
+
- Model diversity: <same-model|cross-model|not-applicable> · Policy: <policyVersion>
|
|
24
|
+
- Started/finished: <UTC>/<UTC> · Findings: <n> (material open: <n>)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Fields the runtime can enforce but a manual review must still state:
|
|
28
|
+
`contextClean`, `authorExclusion`, `modelDiversity`. If context cleanliness is
|
|
29
|
+
false or the reviewer identity equals the author's under an enforced exclusion,
|
|
30
|
+
a PASS is not emit-able — return `SPEC-REVIEW-FAIL` and name the reason.
|
|
31
|
+
|
|
32
|
+
A `Snapshot:` line carries the digest the builder printed, or the one form a refused
|
|
33
|
+
build may take — `refused`, with the builder's own code beside it, never a value
|
|
34
|
+
computed here instead:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
- Snapshot: refused · Build: refused (<the reason code the builder printed>)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Write that pair in place of the `Snapshot:` line, end the turn with this stage's FAIL
|
|
41
|
+
verdict, and file one finding row per refused artifact carrying its code verbatim: the
|
|
42
|
+
checks bind to a snapshot, so with no snapshot none of them ran. `SNAPSHOT.md` owns why
|
|
43
|
+
a refusal prints no digest and what a consumer then reads this receipt as.
|
|
44
|
+
|
|
45
|
+
### Verdict blocks — return exactly one
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
SPEC-REVIEW-PASS — <NN-slug>
|
|
49
|
+
- Snapshot: <digest> · Artifact revision: <artifactRevisionId> · Checks: 14/14
|
|
50
|
+
- Material findings open: 0 · Read-only: no reviewed artifact modified
|
|
51
|
+
- Authority: planning may bind this receipt as its Product parent
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
SPEC-REVIEW-FAIL — <NN-slug> BLOCKED
|
|
56
|
+
- Snapshot: <digest> · Artifact revision: <artifactRevisionId>
|
|
57
|
+
- Failed checks: <Cnn, …>
|
|
58
|
+
- Findings (unioned, one row each):
|
|
59
|
+
| id | severity | class | check | claim | evidence | verification |
|
|
60
|
+
- Repair owner: `design-feature <NN-slug>` — one batch over this whole set
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
NEEDS-DESIGN — <NN-slug>
|
|
65
|
+
- Snapshot: <digest> · Blocking rows: <Cnn / decision id>
|
|
66
|
+
- Missing product choice (product authority only): <one bounded question>
|
|
67
|
+
- Recommended default: <the smallest coherent answer>
|
|
68
|
+
- Downstream: any Plan evidence bound to this unit is now invalid and must be
|
|
69
|
+
re-reviewed after the answer lands
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`NEEDS-DESIGN` when the answer requires inventing product intent, scope, role,
|
|
73
|
+
authority, or user outcome; `SPEC-REVIEW-FAIL` when the half is decidable but
|
|
74
|
+
incomplete, contradictory, or unsupported. Never blend them, and never emit a
|
|
75
|
+
fourth verdict.
|
|
76
|
+
|
|
77
|
+
### Routes
|
|
78
|
+
|
|
79
|
+
| Verdict | Who repairs | What happens next |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| `SPEC-REVIEW-PASS` | nobody | `/plan-feature <NN-slug>` binds this receipt + exact snapshot digest |
|
|
82
|
+
| `SPEC-REVIEW-FAIL` | `design-feature` (the author) | one root-caused repair batch → new revision → re-review of the new snapshot |
|
|
83
|
+
| `NEEDS-DESIGN` | the human, through `design-feature` | dated `## Amendments`/`Product decisions` entry → new revision → re-review |
|
|
84
|
+
|
|
85
|
+
A finding whose `class` is `plan`, `source`, `environment`, or `runtime` does not
|
|
86
|
+
become work here: record it, keep it open, and route it to its owner (`review-plan`
|
|
87
|
+
for plan defects, the executor for source defects). This skill repairs nothing and
|
|
88
|
+
schedules nothing.
|
|
89
|
+
|
|
90
|
+
Repeating this review follows the no-progress and convergence rules in
|
|
91
|
+
`pre-execution-review/references/POLICY.md` §4: a repeat needs a
|
|
92
|
+
changed snapshot or a named falsifiable question plus a new evidence route, and
|
|
93
|
+
entering a second repair/re-review cycle prints `CONVERGENCE-ANOMALY` before any
|
|
94
|
+
further edit. A `design-feature` repair turn re-reads the union of open findings
|
|
95
|
+
from `planning-findings.md`, not just the newest receipt, so nothing recorded here
|
|
96
|
+
is ever lost between cycles.
|
|
97
|
+
|
|
98
|
+
### Skill-specific turn-contract boxes
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
✓ Snapshot digest computed from one revision and pasted; no mixed-revision bytes
|
|
102
|
+
✓ All 14 Product checks resolved to pass / finding / n/a with a reason
|
|
103
|
+
✓ One verdict block returned verbatim from the closed set
|
|
104
|
+
✓ Receipt appended to the unit's progress.md before the report was printed
|
|
105
|
+
✓ `git status --porcelain` shows no change to any reviewed artifact
|
|
106
|
+
✓ Closing `→ Next:` printed as the absolute last output
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Closing recommendation
|
|
110
|
+
|
|
111
|
+
On PASS:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
→ Next: /plan-feature <NN-slug> — Product half reviewed; the plan binds this receipt
|
|
115
|
+
· design changed underneath → re-run /review-spec <NN-slug> first
|
|
116
|
+
· recurring closure gaps across units → /product-audit (a systemic pattern, not one SPEC)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
On FAIL or NEEDS-DESIGN, name every finding id once, in order, joined with ` + `:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
→ Next: /design-feature <NN-slug> "<instruction>" — one repair batch for F1 + F2 + F4,
|
|
123
|
+
then /review-spec <NN-slug> re-reviews the new artifact revision
|
|
124
|
+
· a product choice is missing → answer it in the instruction; nothing here chooses for you
|
|
125
|
+
· finding class is plan/source/environment/runtime → route to its owner, do not edit the SPEC
|
|
126
|
+
```
|
|
@@ -21,14 +21,34 @@
|
|
|
21
21
|
undesignable unit is picked back up only by a human answering the
|
|
22
22
|
recorded question and re-running `/design-feature <slug> "<answer>"`
|
|
23
23
|
directly — the autopilot never re-asks it.
|
|
24
|
+
- **REVIEW-SPEC** (only between DESIGN and PLAN) — compose `review-spec` in a
|
|
25
|
+
clean context at the routed tier (opus/high), never in the turn that wrote the
|
|
26
|
+
product half. `SPEC-REVIEW-PASS` releases the unit into PLAN. A FAIL whose
|
|
27
|
+
findings are common-root-cause or wording-only returns to the same unit's
|
|
28
|
+
author for one root-caused repair batch, then a fresh review. `NEEDS-DESIGN`
|
|
29
|
+
means a product choice is open that this run's locked record cannot answer:
|
|
30
|
+
**park the unit** with the exact question (`NEEDS_INPUT`, same shape as the
|
|
31
|
+
undesignable park above) — the autopilot never answers a product question
|
|
32
|
+
itself, and `SELECT` continues with the next startable unit.
|
|
24
33
|
- **PLAN** — compose `plan-feature` in-turn via its scoped path (equal
|
|
25
|
-
tier). Every unit reaching PLAN
|
|
26
|
-
first
|
|
27
|
-
|
|
34
|
+
tier). Every unit reaching PLAN holds a current `SPEC-REVIEW-PASS` (REVIEW-SPEC
|
|
35
|
+
ran first, or the unit was already planned before this gate existed and its
|
|
36
|
+
own Product receipt is current), so `plan-feature`'s PRODUCT-REVIEW gate passes
|
|
37
|
+
here. The interview path is **forbidden** mid-run:
|
|
28
38
|
SPEC gaps are resolved silently from the decision record and logged. JIT
|
|
29
39
|
planning that reveals the feature's premise is wrong (obsolete, absorbed,
|
|
30
40
|
impossible on this stack) → mark it blocked with the contradiction
|
|
31
41
|
recorded; never re-ask.
|
|
42
|
+
- **REVIEW-PLAN** (only between PLAN and EXECUTE) — compose `review-plan` in a
|
|
43
|
+
clean context at the routed tier over the plan the previous stage just froze.
|
|
44
|
+
`PLAN-REVIEW-PASS` releases EXECUTE. A FAIL routes by root cause: plan-local
|
|
45
|
+
(bad phase cut, blank validator, ledger drift) → one root-caused re-cut by the
|
|
46
|
+
planning author and a fresh review; product-rooted or an assumption this record
|
|
47
|
+
cannot settle → `NEEDS-DESIGN` → park as in REVIEW-SPEC. A second local cycle
|
|
48
|
+
that changes nothing stops editing and reports `CONVERGENCE-ANOMALY` instead of
|
|
49
|
+
burning a third budget. **No stage between PLAN and EXECUTE may create a forge
|
|
50
|
+
issue or defer an obligation to one** — an unmet obligation fails this stage, it
|
|
51
|
+
is never exported.
|
|
32
52
|
- **EXECUTE** — run each unfinished **implementation phase** in a **fresh cheap-tier context**: on Claude
|
|
33
53
|
Code, spawn one subagent per phase with `model: sonnet` (the override is
|
|
34
54
|
the only mechanism that runs *below* the conductor's turn tier); on an
|
|
@@ -81,10 +101,18 @@
|
|
|
81
101
|
parked and the loop moves on); the fixer's cycle ends committed AND
|
|
82
102
|
pushed (step 5), so the re-audit judges the real branch.
|
|
83
103
|
|
|
84
|
-
|
|
104
|
+
Fix units take the same pair in miniature: **plan-fix → REVIEW-PLAN → EXECUTE
|
|
105
|
+
(`--fix`)** — a fix has no Product hop to wait on (D6), so its plan review is the
|
|
106
|
+
only pre-execution gate it can have. The stage sequence is per-feature and size-dependent — always **one stage
|
|
85
107
|
per iteration**: a feature starting at `idea`/`defined` gets a DESIGN stage
|
|
86
108
|
first; one already `planned` (including the founding-scaffolded feature 01)
|
|
87
|
-
|
|
109
|
+
goes to its missing review stage, and skips to EXECUTE only when a current
|
|
110
|
+
`PLAN-REVIEW-PASS` is bound to its bytes. Every size follows
|
|
111
|
+
**[DESIGN → REVIEW-SPEC] → PLAN → REVIEW-PLAN → EXECUTE**
|
|
88
112
|
(implementation phases, fresh cheap worker per phase) → PR (explicit
|
|
89
113
|
`Hardening & PR`) → REVIEW (bounded final loop) → AUDIT. Risk changes final
|
|
90
|
-
review strength, not phase cadence.
|
|
114
|
+
review strength, not phase cadence. The two review stages are the pre-execution
|
|
115
|
+
pair: they judge documents in a clean context and are **not** the post-code
|
|
116
|
+
REVIEW loop, which stays exactly as described below. Merge policy is unchanged —
|
|
117
|
+
the human (or the `--fullauto` wrapper behind its recorded floors) still owns the
|
|
118
|
+
merge, and neither review stage may merge, close, or file anything.
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
A subagent that "finished" but left the tree dirty or the branch unpushed
|
|
11
11
|
did NOT finish: the conductor commits/pushes the remainder itself (same
|
|
12
12
|
stage, same iteration) or marks the stage partial. This check is
|
|
13
|
-
unconditional for
|
|
13
|
+
unconditional for REVIEW-SPEC/REVIEW-PLAN repairs, EXECUTE, REVIEW fix cycles,
|
|
14
|
+
PR, and AUDIT fix cycles.
|
|
14
15
|
6. **LOG** one line to `.ship-run.log`; print `→ Next: <unit> (CONTINUE)` (the
|
|
15
16
|
canonical next-step shape; `CONTINUE` stays the loop's keep-going signal).
|
|
16
17
|
**Say WHY the turn is ending** — one explicit
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
| Recovery, routing, logging | opus/high | in-turn (tiny token volume; a subagent would add cost, not save it) |
|
|
7
7
|
| JIT feature design (mid-run `idea`/`defined` unit) | opus/high | compose `design-feature` + `plan-feature-scaffold` in-turn (equal tier, deriving only from `SHIP_DECISIONS.md` — no new questions) |
|
|
8
8
|
| JIT feature planning | opus/high | compose `plan-feature` in-turn (its internals are opus/high–medium: ≥ holds) |
|
|
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
|
+
| Plan review (REVIEW-PLAN) | opus/high | `review-plan` in a **clean context**, same rule; it judges the plan the previous stage froze |
|
|
9
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 |
|
|
10
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` |
|
|
11
13
|
| Merge gate | opus/high | compose `audit-pr` in-turn (the highest-stakes automated verdict; must share one turn with the floor checks) |
|
|
@@ -61,7 +61,8 @@ turns:
|
|
|
61
61
|
**Verify the closure transitively:** a dep row marked merged whose own
|
|
62
62
|
dependencies aren't merged means the roadmap's statuses are inconsistent
|
|
63
63
|
→ `SHIP: STOPPED` (substrate invariant broken), never build on top of it.
|
|
64
|
-
→ `idea`/`defined`: DESIGN first (see ADVANCE). `planned`: →
|
|
64
|
+
→ `idea`/`defined`: DESIGN first (see ADVANCE). `planned`: → REVIEW-SPEC/
|
|
65
|
+
REVIEW-PLAN if its receipt for that stage is missing or stale, else PLAN/EXECUTE
|
|
65
66
|
directly.
|
|
66
67
|
5. **Issue sweep — features exhausted, run NOT over.** Every roadmap feature
|
|
67
68
|
is `done` **and merged** but the sweep hasn't completed → the run
|
|
@@ -81,7 +82,7 @@ turns:
|
|
|
81
82
|
report (promotions and untracked residue become report proposals,
|
|
82
83
|
never in-run scope or automatically-created issues).
|
|
83
84
|
3. **SHIP the fix-now issues** one unit at a time through the normal
|
|
84
|
-
stages (`plan-fix` → EXECUTE (`--fix`) → PR → REVIEW → AUDIT), same
|
|
85
|
+
stages (`plan-fix` → REVIEW-PLAN → EXECUTE (`--fix`) → PR → REVIEW → AUDIT), same
|
|
85
86
|
budget caps, floors, and merge policy as features.
|
|
86
87
|
6. Nothing startable → `SHIP: BLOCKED` with the **unblock map** ("merging
|
|
87
88
|
#12 unblocks 05 and 07") and the resume command.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: workflow-status
|
|
3
3
|
user-invocable: true
|
|
4
|
-
version:
|
|
4
|
+
version: 3.1.0
|
|
5
5
|
author: "Gabriel Trabanco <gtrabanco@users.noreply.github.com>"
|
|
6
6
|
license: MIT
|
|
7
7
|
argument-hint: "[--json-only] [--last-envelope <json|path>]"
|
|
@@ -27,9 +27,11 @@ and what the recommended next command is.** Built for external orchestrators
|
|
|
27
27
|
fix index, feature folders) — nothing inferred from memory
|
|
28
28
|
✓ Nothing was edited, committed, pushed, or created — read-only, always
|
|
29
29
|
✓ `next.recommended` is non-bare (carries the unit's slug/NN, never a bare
|
|
30
|
-
`/plan-feature`) AND staged by the target unit's resolved status
|
|
31
|
-
`idea`/undesigned → `/design-feature <slug>`;
|
|
32
|
-
|
|
30
|
+
`/plan-feature`) AND staged by the target unit's resolved status **and** its
|
|
31
|
+
current pre-execution evidence: `idea`/undesigned → `/design-feature <slug>`;
|
|
32
|
+
`defined` → `/plan-feature <slug>` only on a current `SPEC-REVIEW-PASS`, else
|
|
33
|
+
`/review-spec <slug>`; `planned`/`in-progress` → `/execute-phase <NN>` only on a
|
|
34
|
+
current `PLAN-REVIEW-PASS`, else `/review-plan <NN>` (step 6a)
|
|
33
35
|
✓ A missing or non-frozen repository-state ledger emits a machine-readable
|
|
34
36
|
substrate blocker and routes to discovery or resolution before any unit is
|
|
35
37
|
listed as startable
|
|
@@ -86,8 +88,12 @@ invocation loads this baseline in order:
|
|
|
86
88
|
2. [crash recovery](references/CRASH_RECOVERY.md)
|
|
87
89
|
3. [envelope core](references/ENVELOPE_CORE.md)
|
|
88
90
|
4. [envelope fields](references/ENVELOPE_FIELDS.md)
|
|
89
|
-
5. [
|
|
91
|
+
5. [pre-execution evidence](references/PRE_EXECUTION.md)
|
|
92
|
+
6. [guardrails](references/GUARDRAILS.md)
|
|
90
93
|
|
|
94
|
+
Add [pre-execution evidence](references/PRE_EXECUTION.md) whenever a unit is
|
|
95
|
+
`defined`, `planned` or `in-progress` — it defines step 6a (receipt sensing, the
|
|
96
|
+
one-label-per-stage table, and the legacy-adoption route).
|
|
91
97
|
Add [sensor signals](references/SENSOR_SIGNALS.md) only when a unit, issue,
|
|
92
98
|
finding, or recommendation exists; an empty project skips that file but still
|
|
93
99
|
emits the empty shapes defined by envelope fields. Add
|
|
@@ -27,6 +27,7 @@ side). The recommendation itself is unaffected — this only adds visibility.
|
|
|
27
27
|
"suggested": [{"command": "/review-change", "trigger": "accumulation: 420 changed lines since last-reviewed sha", "source_skill": "execute-phase"}]},
|
|
28
28
|
"detail": {
|
|
29
29
|
"design_candidates": [{"id": "08-billing-webhooks", "status": "idea", "next": "/design-feature 08-billing-webhooks"}],
|
|
30
|
+
"pre_execution": [{"unit": "12-export-api", "stage": "plan", "label": "stale", "verdict": "PLAN-REVIEW-PASS", "boundDigest": "sha256:9f2c…", "observedDigest": "sha256:41ab…", "recommended": "/review-plan 12-export-api", "reason": "docs/features/12-export-api/ACCEPTANCE.md changed after the review"}],
|
|
30
31
|
"features": [
|
|
31
32
|
{"id": "07-csv-export", "status": "in-progress", "deps": ["01"], "deps_unmet": [],
|
|
32
33
|
"phase": {"current": "P2", "total": 4}, "pr": null,
|
|
@@ -68,8 +69,11 @@ side). The recommendation itself is unaffected — this only adds visibility.
|
|
|
68
69
|
```
|
|
69
70
|
|
|
70
71
|
`detail.startable_now`, `detail.blocked_units` (with build orders),
|
|
71
|
-
`detail.design_candidates`,
|
|
72
|
-
|
|
72
|
+
`detail.design_candidates`, `detail.pre_execution` (one row per sensed unit from step
|
|
73
|
+
6a, `{unit, stage, label, verdict, boundDigest, observedDigest, recommended, reason}`,
|
|
74
|
+
`verdict`/`reason` null when absent) and `detail.pending_triage` are the keys an
|
|
75
|
+
orchestrator routes on; a unit appears in `startable_now` only when its
|
|
76
|
+
`pre_execution[].label` is `current` for the stage it is about to enter; every id in `startable_now`/`blocked_units` must appear
|
|
73
77
|
fully in `features`/`fixes` — an `idea` unit appears ONLY in
|
|
74
78
|
`design_candidates` (and `detail.features`), never in `startable_now`, since
|
|
75
79
|
it has no deps-met check to pass (design precedes dependency startability).
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
## Pre-execution receipt sensing (step 6a)
|
|
2
|
+
|
|
3
|
+
Roadmap status says what exists; only a receipt bound to the current bytes says
|
|
4
|
+
whether the unit may be executed. Sense it like every other signal — read the file,
|
|
5
|
+
recompute the digest, never trust the prose sitting around the block.
|
|
6
|
+
|
|
7
|
+
### What is read
|
|
8
|
+
|
|
9
|
+
For every unit whose resolved status is `defined`, `planned` or `in-progress`:
|
|
10
|
+
|
|
11
|
+
1. The newest `## Pre-execution review receipt v1 — spec` and `… — plan` block in the
|
|
12
|
+
unit's `progress.md` (no `progress.md`, or no block for that stage → `missing`).
|
|
13
|
+
2. The `snapshot` line — the `sha256:` digest the receipt binds — and each bound
|
|
14
|
+
artifact's current bytes: re-derive the digest with the recipe owner's verify
|
|
15
|
+
mode — `node scripts/pre-execution-snapshot.mjs verify --stage <spec|plan> --unit
|
|
16
|
+
<id> [--parent <64-hex>]` (`pre-execution-review` owns the recipe; a feature plan
|
|
17
|
+
check needs the Product digest it descended from, a fix check binds no parent).
|
|
18
|
+
Read `structural.reasonCode` and `structural.changedPaths` out of the JSON — they
|
|
19
|
+
name the dimension that stopped being true, which is what the sensor labels
|
|
20
|
+
`stale`. A snapshot digest is a canonical
|
|
21
|
+
SHA-256 over the snapshot object, so `git hash-object` is never a substitute: it
|
|
22
|
+
stays correct only for the frozen `ACCEPTANCE.md` manifest blob.
|
|
23
|
+
3. The verdict, the reviewed `unit`, the stage, and the author fields
|
|
24
|
+
(`reviewer` and `authorId` — the receipt's `Reviewer:` / `Author:` lines — and
|
|
25
|
+
`authorExclusion`).
|
|
26
|
+
|
|
27
|
+
### What proves a review ran (step 8)
|
|
28
|
+
|
|
29
|
+
One artifact later, the same discipline: step 8's `review_pending` keys on the
|
|
30
|
+
unit's **durable review mark** — the `REVIEW-RAN` row of its `review-findings.md`
|
|
31
|
+
ledger, whose shape and writer `pre-execution-review`'s `LEDGERS.md` owns — and
|
|
32
|
+
judges it by step 8's currency rule in `SENSOR_CORE.md`, never by a keying
|
|
33
|
+
invented here. A findings ledger with rows and no mark leaves the unit
|
|
34
|
+
review-pending: its rows prove findings were folded against
|
|
35
|
+
some state, which is a different fact from *this* state being reviewed, so the
|
|
36
|
+
sensor reports a missing gate, never a verdict that no review ever happened.
|
|
37
|
+
|
|
38
|
+
### One label per stage, and the command it recommends
|
|
39
|
+
|
|
40
|
+
| Label | Evidence | Recommended |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `current` | stage PASS verdict **and** recomputed digest = bound digest | spec: `/plan-feature <slug>` · plan: `/execute-phase <NN>` |
|
|
43
|
+
| `missing` | no receipt block for the stage | `defined` → `/review-spec <slug>` · planned/in-progress → `/review-plan <NN>` |
|
|
44
|
+
| `stale` | bound digest differs, or a bound context row moved | re-run **that stage's** review |
|
|
45
|
+
| `wrong-stage` | the only PASS belongs to the other stage | the stage that is missing — never the stage that passed |
|
|
46
|
+
| `substitute` | prose verdict, legacy block, or internal attestation stands where a receipt should be | that stage's review, and report the substitute as a blocker detail |
|
|
47
|
+
| `self-approved` | the author of the artifact recorded the PASS | that stage's review in a clean context |
|
|
48
|
+
| `author-readiness` | an authoring readiness result sits where a verdict should be | that stage's review — readiness never licenses execution |
|
|
49
|
+
| `legacy` | `planned`/`in-progress` unit with no ledgers and no receipt (predates feature 28) | the adoption route below |
|
|
50
|
+
|
|
51
|
+
A stale receipt re-runs the **review**, not the authoring skill: the artifacts may be
|
|
52
|
+
exactly right and simply need re-judging in a clean context. A missing verdict block,
|
|
53
|
+
or a verdict outside the stage's fixed set, is `missing` with the reason recorded —
|
|
54
|
+
never a guess in the recommended direction.
|
|
55
|
+
|
|
56
|
+
### Envelope projection
|
|
57
|
+
|
|
58
|
+
- A unit that is otherwise startable but lacks a current PASS for the stage it is
|
|
59
|
+
about to enter becomes a `gate` blocker (`scope: unit`, detail names stage +
|
|
60
|
+
label). `startable_now` keeps only units whose next command is genuinely runnable,
|
|
61
|
+
so `next.recommended` never points a human at `execute-phase` on an unreviewed plan.
|
|
62
|
+
- `detail.pre_execution[]` gains one row per sensed unit: `{unit, stage, label,
|
|
63
|
+
verdict, boundDigest, observedDigest, recommended, reason}` — `verdict`/`reason`
|
|
64
|
+
are `null` when absent, `observedDigest` is always the digest computed **now**.
|
|
65
|
+
`detail` is opaque to the envelope schema, so no field outside it changes.
|
|
66
|
+
- Nothing is inferred from the *absence* of a block: an unreadable artifact is
|
|
67
|
+
`missing` with the failure in `reason`, never a carried-forward claim from the
|
|
68
|
+
receipt itself.
|
|
69
|
+
|
|
70
|
+
### Legacy units
|
|
71
|
+
|
|
72
|
+
A `planned`/`in-progress` unit with no ledgers and no receipt predates the gate; it
|
|
73
|
+
reports as `legacy`, which is a different fact from `missing` ("never reviewed") and
|
|
74
|
+
routes the human differently. `pre-execution-review` owns the adoption rule —
|
|
75
|
+
construct the ledgers, never coerce old evidence, keep frozen acceptance and every
|
|
76
|
+
past commit byte-identical, and resume only on a current `PLAN-REVIEW-PASS`. This
|
|
77
|
+
sensor only reports the label and the command; it never edits a unit to make the
|
|
78
|
+
label disappear, and it files nothing.
|
|
@@ -64,16 +64,36 @@ 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` or
|
|
68
|
+
`in-progress` ([pre-execution evidence](PRE_EXECUTION.md)): read the stage's
|
|
69
|
+
newest receipt block, re-derive the bound digest with the recipe owner's
|
|
70
|
+
verify mode (`node scripts/pre-execution-snapshot.mjs verify --stage
|
|
71
|
+
<spec|plan> --unit <id> [--parent <64-hex>]` — a snapshot digest is a canonical SHA-256, never a
|
|
72
|
+
git blob id; `structural.reasonCode` names the dimension that drifted), and
|
|
73
|
+
label the stage `current`/`missing`/`stale`/`wrong-stage`/`substitute`/
|
|
74
|
+
`self-approved`/`author-readiness`/`legacy`. The label **overrides step 6's
|
|
75
|
+
status-only command**: a unit without a current PASS for the stage it is about to
|
|
76
|
+
enter is demoted out of `startable_now` into a `gate` blocker naming the missing
|
|
77
|
+
review, and `detail.pre_execution[]` records the row. A roadmap row is never
|
|
78
|
+
edited here — sensing only reads.
|
|
67
79
|
7. **Phase progress.** For each in-progress feature, read `TASKS.md`: current
|
|
68
80
|
phase, total phases, per-phase checkbox completion.
|
|
69
81
|
8. **Pending quality gates.** For each unit with commits: has the mandatory
|
|
70
|
-
`review-change` for its current state run
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
`review-change` for its current state run? The artifact is the unit's
|
|
83
|
+
**durable review mark** — the `REVIEW-RAN` row of its `review-findings.md`
|
|
84
|
+
fold ledger, whose shape and writer `pre-execution-review`'s `LEDGERS.md`
|
|
85
|
+
owns — and it counts while the sha it names is an ancestor of the unit's head
|
|
86
|
+
and no commit after it touched a bound input of that review, over the paths
|
|
87
|
+
`pre-execution-review`'s `SNAPSHOT.md` binds:
|
|
88
|
+
`git log <mark-sha>..HEAD -- <bound paths>` prints nothing. Equality with the
|
|
89
|
+
head is not the test and cannot be: carrying the mark is a commit, and that
|
|
90
|
+
commit moves the head, so a rule keyed on equality calls every review that
|
|
91
|
+
finished its own turn unreviewed. The ledger's presence is never that proof: a
|
|
92
|
+
review that found nothing writes no finding row, so presence would call a
|
|
93
|
+
reviewed unit unreviewed and an unreviewed one reviewed. Has `audit-pr` a
|
|
74
94
|
MERGE-READY bound to the PR's current head SHA (look for the audit
|
|
75
|
-
comment marker on the PR)? Derive `review_pending`
|
|
76
|
-
`merge_ready` per unit.
|
|
95
|
+
comment marker on the PR)? Derive `review_pending` (no current mark) /
|
|
96
|
+
`audit_pending` / `merge_ready` per unit.
|
|
77
97
|
9. **Fix-now fold ledger → `findings.fix_now[]`.** For each in-flight unit
|
|
78
98
|
(feature or fix) that has a `review-findings.md` ledger, read only its
|
|
79
99
|
`folded: no` rows and emit each as a structured item:
|
|
@@ -93,3 +113,23 @@ live evidence against a frozen ledger remains a contradiction candidate.
|
|
|
93
113
|
error); no unit in the run has one → `findings.fix_now: []`, same as
|
|
94
114
|
today. **Read-only**: this step only projects the ledger's current
|
|
95
115
|
unfolded rows — never writes, ticks `folded`, or judges.
|
|
116
|
+
|
|
117
|
+
### Envelope fields the sensor projects (versioned grammar)
|
|
118
|
+
|
|
119
|
+
Steps 1-9 print these keys and no others; each row must be a field the schema
|
|
120
|
+
package's envelope validator declares for that object.
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
sensor-fields@1
|
|
124
|
+
# machine: envelope
|
|
125
|
+
object | field
|
|
126
|
+
unit | type
|
|
127
|
+
pr | merge_ready
|
|
128
|
+
gates | review_pending
|
|
129
|
+
gates | audit_pending
|
|
130
|
+
findings | fix_now
|
|
131
|
+
findings.fix_now | suggested_tier
|
|
132
|
+
dependencies | unmet
|
|
133
|
+
blockers | kind
|
|
134
|
+
recommendations | product_audit
|
|
135
|
+
```
|