@gtrabanco/pi-agentic-workflow 0.30.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/dist/config/defaults.js +3 -0
- package/dist/config/merge.js +5 -0
- package/dist/config/schema.d.ts +0 -5
- package/dist/config/schema.js +31 -1
- package/dist/config/types.d.ts +15 -0
- package/dist/extension/engram.d.ts +119 -0
- package/dist/extension/engram.js +187 -0
- package/dist/extension/index.js +70 -3
- package/dist/settings/console.js +68 -22
- package/package.json +1 -1
- package/skills/audit-pr/SKILL.md +1 -1
- package/skills/audit-pr/references/03_AUDIT_PROCESS.md +3 -2
- package/skills/execute-phase/SKILL.md +22 -8
- package/skills/execute-phase/references/EXECUTION_CONTRACT.md +15 -9
- package/skills/execute-phase/references/FOLDING.md +11 -8
- package/skills/execute-phase/references/PREFLIGHT.md +7 -3
- package/skills/fold-findings/SKILL.md +28 -17
- package/skills/fold-findings/references/FOLD_PROCESS.md +5 -3
- package/skills/init-workspace/SKILL.md +13 -2
- package/skills/init-workspace/references/BOOTSTRAP_WRITE.md +11 -5
- package/skills/init-workspace/references/ENGRAM.md +107 -0
- package/skills/log-session/SKILL.md +17 -1
- package/skills/orchestration-envelope/references/TURN_CONTRACT.md +2 -1
- package/skills/pre-execution-review/SKILL.md +1 -1
- package/skills/pre-execution-review/references/LEDGERS.md +30 -2
- package/skills/review-change/SKILL.md +1 -1
- package/skills/review-change/references/OUTPUT_AND_GUARDRAILS.md +2 -1
- package/skills/review-change/references/PERSIST_AND_DECIDE.md +30 -9
- package/skills/review-change/references/REVIEW_PROCESS.md +14 -6
- package/skills/review-implementation/SKILL.md +10 -2
- package/skills/review-implementation/references/CLASSIFY.md +21 -4
- package/skills/triage-issue/SKILL.md +18 -12
- package/skills/triage-issue/references/FOLD_LEDGER.md +11 -3
- package/skills/triage-issue/references/ISSUE_PROCESS.md +3 -2
- package/skills/triage-issue/references/REVIEW_FINDING_PROCESS.md +17 -8
- package/skills/unit-lane/SKILL.md +23 -5
- package/skills/unit-lane/references/DESIGN.md +1 -1
- package/skills/unit-lane/references/EVIDENCE.md +7 -3
- package/skills/unit-lane/references/MEMORY.md +179 -0
- package/skills/unit-lane/references/PLAN.md +11 -1
- package/skills/unit-lane/references/RESEARCH.md +3 -3
- package/skills/verification-contract/SKILL.md +9 -7
- package/skills/workflow-status/SKILL.md +4 -2
- package/skills/workflow-status/references/ENVELOPE_FIELDS.md +3 -1
package/dist/settings/console.js
CHANGED
|
@@ -650,38 +650,84 @@ function describeRouting(file) {
|
|
|
650
650
|
];
|
|
651
651
|
return routes.join(" · ");
|
|
652
652
|
}
|
|
653
|
+
/**
|
|
654
|
+
* The canonical write order for a config file. `dirty()` compares the cleaned
|
|
655
|
+
* draft against the cleaned file as JSON text, so the order is part of the
|
|
656
|
+
* contract: the same keys written in a different order would read as an edit.
|
|
657
|
+
* Keys outside this list are appended in the draft's own order, so a key the
|
|
658
|
+
* console never prompts for still survives the save (F4).
|
|
659
|
+
*/
|
|
660
|
+
const KEY_ORDER = [
|
|
661
|
+
"default",
|
|
662
|
+
"commands",
|
|
663
|
+
"onUnavailableRoute",
|
|
664
|
+
"onSettle",
|
|
665
|
+
"pathProtection",
|
|
666
|
+
"advance",
|
|
667
|
+
"recommendedModels",
|
|
668
|
+
"memory",
|
|
669
|
+
"profiles",
|
|
670
|
+
"profileOrder",
|
|
671
|
+
"profileFallback",
|
|
672
|
+
];
|
|
653
673
|
/**
|
|
654
674
|
* Keep everything the file held or the operator set; drop only what says nothing
|
|
655
675
|
* (an empty route). Eliding by VALUE — treating an explicit `inherit` or `stop` as
|
|
656
676
|
* absent because a shipped default happens to agree — silently discards the only
|
|
657
677
|
* two moves that matter at project scope: switching a command off under a global
|
|
658
678
|
* route, and re-arming fail-closed over a global `inherit` (F4).
|
|
679
|
+
*
|
|
680
|
+
* The copy is driven by the draft's OWN keys, not by a list of the keys this
|
|
681
|
+
* console edits. Enumerating them silently deleted every valid key the console
|
|
682
|
+
* never prompts for — `memory` (the Engram consent switch, feature 66 AC3),
|
|
683
|
+
* `pathProtection` and `advance` — so an opt-in written by hand vanished on the
|
|
684
|
+
* next save with no message and no error (F4/VF-4). A key the parser accepted is
|
|
685
|
+
* never a key this function may drop.
|
|
659
686
|
*/
|
|
660
687
|
function clean(draft) {
|
|
661
|
-
const
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
688
|
+
const kept = {};
|
|
689
|
+
for (const [key, value] of Object.entries(draft)) {
|
|
690
|
+
if (value === undefined)
|
|
691
|
+
continue;
|
|
692
|
+
if (key === "commands") {
|
|
693
|
+
const commands = {};
|
|
694
|
+
for (const [name, route] of Object.entries((value ?? {}))) {
|
|
695
|
+
if (route && Object.keys(route).length > 0)
|
|
696
|
+
commands[name] = { ...route };
|
|
697
|
+
}
|
|
698
|
+
if (Object.keys(commands).length > 0)
|
|
699
|
+
kept.commands = commands;
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
702
|
+
if (key === "profiles") {
|
|
703
|
+
const profiles = {};
|
|
704
|
+
for (const [name, profile] of Object.entries((value ?? {}))) {
|
|
705
|
+
if (profile && Object.keys(profile).length > 0)
|
|
706
|
+
profiles[name] = structuredClone(profile);
|
|
707
|
+
}
|
|
708
|
+
if (Object.keys(profiles).length > 0)
|
|
709
|
+
kept.profiles = profiles;
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
712
|
+
if (Array.isArray(value)) {
|
|
713
|
+
// `profileOrder` is the only list at this level: an empty order says
|
|
714
|
+
// nothing, so it is elided exactly as the empty route was.
|
|
715
|
+
if (value.length > 0)
|
|
716
|
+
kept[key] = [...value];
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
if (typeof value === "object" && value !== null && Object.keys(value).length === 0)
|
|
720
|
+
continue;
|
|
721
|
+
kept[key] = typeof value === "object" && value !== null ? structuredClone(value) : value;
|
|
679
722
|
}
|
|
680
|
-
|
|
681
|
-
|
|
723
|
+
const file = {};
|
|
724
|
+
for (const key of KEY_ORDER) {
|
|
725
|
+
if (key in kept)
|
|
726
|
+
file[key] = kept[key];
|
|
682
727
|
}
|
|
683
|
-
|
|
684
|
-
|
|
728
|
+
for (const key of Object.keys(kept)) {
|
|
729
|
+
if (!(key in file))
|
|
730
|
+
file[key] = kept[key];
|
|
685
731
|
}
|
|
686
732
|
return file;
|
|
687
733
|
}
|
package/package.json
CHANGED
package/skills/audit-pr/SKILL.md
CHANGED
|
@@ -29,8 +29,9 @@
|
|
|
29
29
|
- **BLOCKED** — one or more gates fail; output the ranked blocker list.
|
|
30
30
|
6. **Persist blockers to the fold ledger (BLOCKED verdict only).** Every blocker
|
|
31
31
|
on a **BLOCKED** verdict is, by definition, fix-now — merge is gated on it.
|
|
32
|
-
Append each to the unit's fix-now fold ledger `
|
|
33
|
-
|
|
32
|
+
Append each to the unit's fix-now fold ledger — its `## Findings` section for
|
|
33
|
+
a migrated unit (issue #308), `review-findings.md` for a legacy one; probe the
|
|
34
|
+
doc first and write to exactly one carrier (same fixed schema
|
|
34
35
|
`| id | file:line | axis | severity | class | route | folded |` as
|
|
35
36
|
`review-change`'s persist step) — the **same ledger**, not a separate one
|
|
36
37
|
(D4: the fold cycle consumes one list). **Merged unit → no write** — check
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: execute-phase
|
|
3
3
|
user-invocable: true
|
|
4
|
-
version: 6.
|
|
4
|
+
version: 6.2.2
|
|
5
5
|
argument-hint: <NN-slug> [P<k>|step] [--max-attempts N] [--force]
|
|
6
6
|
allowed-tools: [Bash, Read, Edit, Write, MultiEdit]
|
|
7
7
|
author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
|
|
@@ -35,7 +35,8 @@ done:
|
|
|
35
35
|
|
|
36
36
|
```
|
|
37
37
|
✓ Required user inputs were answered concretely (not defaulted). Nothing here
|
|
38
|
-
is inferred: a gap runs `
|
|
38
|
+
is inferred: a gap runs `bun scripts/needs-input.mjs <unit-dir>` (node fallback
|
|
39
|
+
if bun is not installed) and the
|
|
39
40
|
`open-questions@1` block is pasted, then the run stops.
|
|
40
41
|
✓ Triage verified — unit doc Evidence section header matches
|
|
41
42
|
`bun scripts/unit-route.mjs --triage <slug>` output block (PREFLIGHT.md)
|
|
@@ -44,6 +45,8 @@ done:
|
|
|
44
45
|
✓ Evidence rows updated (command → exit/digest → output → verified-by)
|
|
45
46
|
✓ Progress log updated with a dated `YYYY-MM-DD HH:MM` entry that names the
|
|
46
47
|
phase id (what, commit, next)
|
|
48
|
+
✓ Memory boundary ran — the phase's outcome saved under `unit/<NN-slug>/doc`,
|
|
49
|
+
or the mirror marked pending when the layer is degraded
|
|
47
50
|
✓ Diff guard passed (on implement steps) — see `diff-guard` in PREFLIGHT.md
|
|
48
51
|
✓ → Next: block printed as the absolute last output
|
|
49
52
|
```
|
|
@@ -64,8 +67,8 @@ This skill **never interviews**. It reads its inputs — the unit doc's `Tasks`,
|
|
|
64
67
|
one is a **gap**, resolved in one fixed order and never by inference:
|
|
65
68
|
**(0) provenance** (search the repo's own docs and record where) →
|
|
66
69
|
**(1) research** (2–3 concrete options with trade-offs; asking for more research
|
|
67
|
-
is a legitimate answer) → **(2) halt**: run `
|
|
68
|
-
<unit-dir
|
|
70
|
+
is a legitimate answer) → **(2) halt**: run `bun scripts/needs-input.mjs
|
|
71
|
+
<unit-dir>` (node fallback if bun is not installed), paste the `open-questions@1` block verbatim, stop. Interactive the
|
|
69
72
|
block is the pause point, unattended it is a hard fail. Grammar and exit codes:
|
|
70
73
|
`orchestration-envelope`'s `references/TURN_CONTRACT.md` §Open questions.
|
|
71
74
|
|
|
@@ -79,9 +82,13 @@ path-protection checkpoint.
|
|
|
79
82
|
## Step 0 — Discover the project
|
|
80
83
|
|
|
81
84
|
Per the agent guide's **Workflow conventions** + **documentation map**, read the
|
|
82
|
-
unit doc at `docs/features/<NN-slug>/SPEC.md`. Verify it carries `## Tasks` (P1…Pn)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
unit doc at `docs/features/<NN-slug>/SPEC.md`. Verify it carries `## Tasks` (P1…Pn)
|
|
86
|
+
**and the receipt sections of the shape it is written in** (#308 accepts both):
|
|
87
|
+
the legacy shape carries `## Evidence` + `## Progress log`, a re-cut unit doc carries
|
|
88
|
+
`## Specs`, `## Findings` + `## Log` (its evidence and gate runs are `E`/`G` log
|
|
89
|
+
lines, its progress is `P` lines). If neither pair is present, the unit is not ready —
|
|
90
|
+
stop and suggest `unit-lane` triage first. `scripts/unit-route.mjs` resolves the
|
|
91
|
+
shape; never judge a re-cut unit by the legacy headings and stop it.
|
|
85
92
|
|
|
86
93
|
## Process
|
|
87
94
|
|
|
@@ -136,7 +143,14 @@ names before implementation), then green. UI/adapter glue may test after.
|
|
|
136
143
|
output (≤2 lines) | verified-by |`. Append to the Evidence section.
|
|
137
144
|
3. **Progress log**: append a dated entry —
|
|
138
145
|
`YYYY-MM-DD HH:MM — <what was done> → <commit sha> — next: <what is next>`.
|
|
139
|
-
4. **
|
|
146
|
+
4. **Memory boundary** — this step is a phase transition. Follow
|
|
147
|
+
[the memory protocol](../unit-lane/references/MEMORY.md): before the first
|
|
148
|
+
memory read run `agentic-workflow memory probe` once and record its verdict
|
|
149
|
+
in Evidence; after the step, save the phase id, what it changed, its Evidence
|
|
150
|
+
outcome and any discovery under `topic_key: "unit/<NN-slug>/doc"`, an explicit
|
|
151
|
+
`project` and explicit session attribution (§5). A `degraded` verdict is
|
|
152
|
+
recorded and the mirror marked pending — it never blocks the step.
|
|
153
|
+
5. **Commit**: `git add <changed files>` then `git commit -m "<type>(<scope>):
|
|
140
154
|
<step-summary>"` — run it, paste the SHA.
|
|
141
155
|
|
|
142
156
|
### 6. Red gate (repair loop)
|
|
@@ -52,8 +52,10 @@ Something forbidden looks necessary → stop, record it in `decisions.md` or
|
|
|
52
52
|
|
|
53
53
|
## Step completion gate
|
|
54
54
|
|
|
55
|
-
The step completion gate verifies that
|
|
56
|
-
|
|
55
|
+
The step completion gate verifies that the step's acceptance criteria have
|
|
56
|
+
complete evidence in the unit's own carrier — the `## Evidence` table rows for a
|
|
57
|
+
legacy-shape unit, `## Log` `E` lines (command, exit, ≤2 lines of output) for a
|
|
58
|
+
re-cut one (#308) — that the unit doc is committed clean, and that the diff guard
|
|
57
59
|
(if applicable) passed. The mark's shape, ownership, and reuse rule are
|
|
58
60
|
declared in `LEDGERS.md` (§gate-ran@1).
|
|
59
61
|
|
|
@@ -76,7 +78,8 @@ GATE-RAN | HEAD <40-hex sha> | <cmds> | exit <code>
|
|
|
76
78
|
✓ Verification gate green — type-check + tests + build actually RUN (paste exit
|
|
77
79
|
status), never assumed
|
|
78
80
|
✓ Every task of this step checked off in the unit doc's `Tasks` section, each
|
|
79
|
-
mapped to an Evidence row (
|
|
81
|
+
mapped to an Evidence row (legacy shape) or an `E` log line (re-cut shape) —
|
|
82
|
+
code path or test name
|
|
80
83
|
✓ Tests updated/added for every behavior this step changed
|
|
81
84
|
✓ Tests-first red run recorded (core/domain + orchestration steps, n/a for
|
|
82
85
|
test-after UI/adapter steps) — the failing first run's command, exit status,
|
|
@@ -88,10 +91,12 @@ GATE-RAN | HEAD <40-hex sha> | <cmds> | exit <code>
|
|
|
88
91
|
consumers)
|
|
89
92
|
✓ Architecture doc respected (dependency directions, layer boundaries)
|
|
90
93
|
✓ Architectural invariants preserved or backed by an explicit recorded decision
|
|
91
|
-
✓
|
|
92
|
-
(one dated `YYYY-MM-DD HH:MM` Progress entry, all
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
✓ The step's ACs have complete evidence in the unit's carrier — unit doc committed
|
|
95
|
+
clean (one dated `YYYY-MM-DD HH:MM` Progress entry or `P` log line, all evidence
|
|
96
|
+
current)
|
|
97
|
+
✓ Docs COMMITTED with the step — the unit doc carries all required sections of its
|
|
98
|
+
own shape (Tasks + Evidence + Progress + References for legacy; Specs + Tasks +
|
|
99
|
+
Findings + Log + References for re-cut); no orphan files remain
|
|
95
100
|
```
|
|
96
101
|
|
|
97
102
|
A step that cannot tick every box is **not done**: fix within the step's
|
|
@@ -123,8 +128,9 @@ planned work, and inference never prove implementation. A present ledger whose
|
|
|
123
128
|
status is `draft`, `contradicted`, or `resolved` stops implementation and routes
|
|
124
129
|
to discovery or resolution first. If no ledger exists, inspect the repository
|
|
125
130
|
directly and record `n/a: no normalized repository state`; NRS is optional.
|
|
126
|
-
Unit doc evidence
|
|
127
|
-
|
|
131
|
+
Unit doc evidence is the single source of truth for step completion — the
|
|
132
|
+
`## Evidence`/`## Progress log` sections of a legacy-shape doc, the `## Log` lines of
|
|
133
|
+
a re-cut one (#308) — never a separate ACCEPTANCE.md, progress.md, or TASKS.md.
|
|
128
134
|
|
|
129
135
|
## Architectural invariants
|
|
130
136
|
|
|
@@ -24,10 +24,12 @@ findings end up "solved" locally but absent from the merged PR:
|
|
|
24
24
|
✓ Gate RUN and green (exit codes pasted)
|
|
25
25
|
✓ Never edit an existing test's expectation to match behaviour — a setup
|
|
26
26
|
repair keeps assertions at least as strong and never touches expectations
|
|
27
|
-
✓ Evidence rows updated where the finding touched them
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
is the
|
|
27
|
+
✓ Evidence rows updated where the finding touched them, in the unit's own findings
|
|
28
|
+
carrier: a legacy row flipped `folded: no → yes`; a migrated unit's row leaves
|
|
29
|
+
`## Findings` and its fold is a `## Log` `F` line naming the fold commit — that
|
|
30
|
+
carrier has no `folded` column to flip (#308). Either close is the one and only
|
|
31
|
+
state transition, and `ledger-ownership@1` / `fold-findings:folded-flag` is the
|
|
32
|
+
sole writer of it
|
|
31
33
|
✓ Progress log advanced with a dated entry noting the fold
|
|
32
34
|
✓ `git add` + `git commit` RUN (sha pasted) — e.g.
|
|
33
35
|
`fix(<scope>): fold review findings — <summary>`
|
|
@@ -56,8 +58,9 @@ No auto-merge. Explicit `P<k>` stops after one step; omitted-step mode gates
|
|
|
56
58
|
and commits every remaining step before the same final review.
|
|
57
59
|
## Gate-run marks (gate-ran@1)
|
|
58
60
|
|
|
59
|
-
Every verification gate this cycle runs records a `GATE-RAN` mark
|
|
60
|
-
|
|
61
|
+
Every verification gate this cycle runs records a `GATE-RAN` mark at the head it
|
|
62
|
+
actually ran — a row in the legacy `review-findings.md`, a `## Log` `G` line for a
|
|
63
|
+
re-cut unit (#308):
|
|
61
64
|
`GATE-RAN | HEAD <40-hex sha> | <cmds> | exit <code>`. A green run is recorded;
|
|
62
65
|
a red run is also recorded (exit code ≠ 0 is evidence, not silence). Any skill
|
|
63
66
|
may consume a green mark only at the identical HEAD — a changed head re-runs
|
|
@@ -70,5 +73,5 @@ the gate. The recorders are `execute-phase:gate-ran-marks` and
|
|
|
70
73
|
When the final triaged step closes: mark the unit done, push the branch, and
|
|
71
74
|
open the PR with `gh pr create` (per the project's Workflow conventions) —
|
|
72
75
|
regardless of the review still to come. The PR body carries the unit doc's
|
|
73
|
-
|
|
74
|
-
issues via `Closes #N`.
|
|
76
|
+
verification record (its `## Evidence` rows, or a re-cut unit's `## Log` `E`/`G`
|
|
77
|
+
lines) and closes the unit's tracked issues via `Closes #N`.
|
|
@@ -125,7 +125,10 @@ block text, no-forgery and legacy detail:
|
|
|
125
125
|
Consume `skills/verification-contract/SKILL.md`. For a current-format unit,
|
|
126
126
|
the Evidence section in the unit doc **is** the acceptance manifest — each
|
|
127
127
|
acceptance criterion has a corresponding Evidence row with command, exit/digest,
|
|
128
|
-
and output.
|
|
128
|
+
and output. A re-cut unit (#308) has no Evidence section by design: its acceptance
|
|
129
|
+
manifest is `## Specs`, and each criterion's receipt is a `## Log` `E` line; the
|
|
130
|
+
gate below reads that carrier instead, and never stops a migrated unit for lacking
|
|
131
|
+
a section its own template retired. No sibling file; the unit doc's Evidence section header carries the
|
|
129
132
|
last-reviewed sha. The unit doc's triage block (pasted verbatim from
|
|
130
133
|
`scripts/unit-route.mjs --triage`) is the step authority: `execute-phase` runs
|
|
131
134
|
only what the triage block demands.
|
|
@@ -136,8 +139,9 @@ only what the triage block demands.
|
|
|
136
139
|
- Missing/mismatched Evidence (unit doc has been edited since last execution)
|
|
137
140
|
→ print the verification contract's fixed `EVIDENCE GATE` block and stop.
|
|
138
141
|
`--force` never bypasses a changed acceptance state.
|
|
139
|
-
- Unit with no Evidence section → the unit doc template was
|
|
140
|
-
create the section before proceeding.
|
|
142
|
+
- Unit with no Evidence section and no `## Log` → the unit doc template was
|
|
143
|
+
incomplete; create the section its shape requires before proceeding. A doc with
|
|
144
|
+
`## Log` is the re-cut shape: its `E`/`G` lines are the rows, never a gap.
|
|
141
145
|
|
|
142
146
|
Run this check before each step in whole-unit mode. The executor may add tests
|
|
143
147
|
but may not narrow acceptance criteria, weaken assertions, or edit the Acceptance
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: fold-findings
|
|
3
3
|
user-invocable: true
|
|
4
|
-
version: 1.9.
|
|
4
|
+
version: 1.9.2
|
|
5
5
|
argument-hint: [finding-id …]
|
|
6
6
|
author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
|
|
7
7
|
license: MIT
|
|
@@ -49,19 +49,30 @@ postpone/wontfix/promote/documented-tradeoff rows; those belong to `/triage-issu
|
|
|
49
49
|
|
|
50
50
|
Per Workflow conventions, read:
|
|
51
51
|
|
|
52
|
-
1. The unit's
|
|
53
|
-
`
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
1. The unit's findings carrier: a migrated unit (issue #308) keeps its OPEN rows
|
|
53
|
+
in its own `SPEC.md` under `## Findings`, with folded history and marks as
|
|
54
|
+
`## Log` lines; a legacy unit keeps `review-findings.md` under
|
|
55
|
+
`docs/features/<NN>-<slug>/` or `docs/fix/<n>-<topic>/`. Probe the doc first and
|
|
56
|
+
fall back to the file — a unit with the section never reads both. Each carrier
|
|
57
|
+
has **its own** schema, owned by `review-change`/`audit-pr` and stated for both
|
|
58
|
+
shapes in `pre-execution-review/references/LEDGERS.md`:
|
|
59
|
+
|
|
60
|
+
- legacy (7 cols): `\| id \| file:line \| axis \| severity \| class \| route \| folded \|`
|
|
61
|
+
— closing a row flips `folded: no → yes`, and this skill is that flip's sole writer
|
|
62
|
+
- migrated (6 cols, `findings-table@1`): `\| id \| S# / file:line \| axis \| severity \|
|
|
63
|
+
class \| route \|` — every row it holds is OPEN; closing one **deletes the row** and
|
|
64
|
+
appends a `## Log` `F` line naming the fold commit. There is no `folded` column to
|
|
65
|
+
flip, and `class` here is the repairing owner (`product`/`plan`/`source`/
|
|
66
|
+
`environment`/`runtime`), not a disposition.
|
|
67
|
+
|
|
68
|
+
Never write one carrier's row into the other's grammar. After `VERDICT: BLOCKED`,
|
|
69
|
+
append missing rows in the carrier's own schema (next free `Fn`, dedupe
|
|
70
|
+
`file:line`+axis; legacy `class: fix-now`, `folded: no`), commit as
|
|
71
|
+
`docs(<unit>): reconstruct fold ledger from audit-pr blockers`, then fold; never
|
|
72
|
+
report “no findings”.
|
|
73
|
+
2. Queue the carrier's open rows — a legacy `folded: no` row, a migrated row of
|
|
74
|
+
`## Findings` (all of them are open); explicit IDs restrict the queue and leave
|
|
75
|
+
other rows untouched. Group by root cause, verifier and rollback boundary.
|
|
65
76
|
3. The project's verification gate and forge CLI (use the declared forge).
|
|
66
77
|
4. Whether the branch has an open PR; this decides immediate push after commit.
|
|
67
78
|
|
|
@@ -126,7 +137,7 @@ conclusion the already-run router printed, never the invocation itself: on
|
|
|
126
137
|
`route: replan` the planner command it printed — `/unit-lane <slug>` for a
|
|
127
138
|
feature unit or `/unit-lane --fix <n>` for a fix unit; on `route: decision` stop
|
|
128
139
|
and surface the decision to the user, never a planner. `<unit>` is the bare folder number or the full slug (both resolve). The invocation
|
|
129
|
-
`
|
|
140
|
+
`bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed) is the discovery step the fold already
|
|
130
141
|
ran; it is never the recommendation.
|
|
131
142
|
|
|
132
143
|
**Freeze-batch (product owner present).** Any taken `fix-now` row whose `Route`
|
|
@@ -212,8 +223,8 @@ decision to skip.
|
|
|
212
223
|
|
|
213
224
|
| Batch state | Branch | `→ Next:` (consumer) |
|
|
214
225
|
|---|---|---|
|
|
215
|
-
| freeze-batch (≥ 1 product-owned row) | `PRODUCT-ROUTE` | `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) when the router concludes `product` — the lane repairs the half through its `design` step, its `review` step re-judges it; the conclusion printed by `
|
|
216
|
-
| freeze-batch (≥ 1 replan-class row) | `REPLAN-ROUTE` | `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) when the router concludes `replan` — user confirms, the lane's `plan` step appends the phases and its `review` step gates, then `/execute-phase` on this unit; on `route: decision` stop and surface the decision to the user — the conclusion printed by `
|
|
226
|
+
| freeze-batch (≥ 1 product-owned row) | `PRODUCT-ROUTE` | `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) when the router concludes `product` — the lane repairs the half through its `design` step, its `review` step re-judges it; the conclusion printed by `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed; discovery step the fold already ran) |
|
|
227
|
+
| freeze-batch (≥ 1 replan-class row) | `REPLAN-ROUTE` | `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) when the router concludes `replan` — user confirms, the lane's `plan` step appends the phases and its `review` step gates, then `/execute-phase` on this unit; on `route: decision` stop and surface the decision to the user — the conclusion printed by `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed; discovery step the fold already ran) |
|
|
217
228
|
| `all-repair-in-place` + docs-only + no folded row severity `high` + prior consumer skip decision | `RE-REVIEW-SKIPPED` | skip — consumer has explicitly decided to skip the re-review |
|
|
218
229
|
| `all-repair-in-place` + docs-only + no folded row severity `high` | `RE-REVIEW-OPTIONAL` | `/review-change` (default, delta mode) — or the consumer's recorded skip decision |
|
|
219
230
|
| empty batch (class `none`) | `RE-REVIEW-OPTIONAL` | `/review-change` by default — safe: the head is unchanged |
|
|
@@ -43,8 +43,10 @@
|
|
|
43
43
|
|
|
44
44
|
| Condition over the taken batch | Batch class | Fold behavior |
|
|
45
45
|
|---|---|---|
|
|
46
|
-
| ≥ 1 row with frozen class `replan-in-unit` or `decision-required` | `frozen (replan present)` | **freeze-batch** — nothing folds, no `folded: yes` flips, no commits; the receipt records the REPLAN-ROUTE and every retained (unfolded) row id; the loop stops; the consumer is the conclusion printed by `
|
|
47
|
-
|
|
46
|
+
| ≥ 1 row with frozen class `replan-in-unit` or `decision-required` | `frozen (replan present)` | **freeze-batch** — nothing folds, no `folded: yes` flips, no commits; the receipt records the REPLAN-ROUTE and every retained (unfolded) row id; the loop stops; the consumer is the conclusion printed by `bun scripts/unit-route.mjs <unit>` (node fallback
|
|
47
|
+
if bun is not installed) (discovery step the fold already ran), where `<unit>` is the bare folder number or the full slug (both resolve): on `route: replan` the planner command the router printed — `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) — the lane appends the phases and its `review` step gates, then `/execute-phase` on this unit; on `route: decision` stop and surface the decision to the user, never a planner |
|
|
48
|
+
| ≥ 1 row with frozen class `fix-now` whose `Route` cell begins `product owner`, `product-owned` or `owned by product` (head-anchored, identical to `scripts/unit-route.mjs`'s `PRODUCT_ROUTE` regex: `/^(?:product[- ]owner\|product[- ]owned\|owned by product)\b/i`, per `#293`) | `frozen (product owner present)` | **freeze-batch** — nothing folds, no `folded: yes` flips, no commits; the receipt records the PRODUCT-ROUTE and every retained (unfolded) row id; the loop stops; the consumer is the conclusion printed by `bun scripts/unit-route.mjs <unit>` (node fallback
|
|
49
|
+
if bun is not installed): `route: product` and the lane hand-off — `/unit-lane <slug>` (feature) or `/unit-lane --fix <n>` (fix) — the lane repairs the half, its `review` step re-judges it, then `/execute-phase` on this unit |
|
|
48
50
|
| all taken rows foldable, none replan-class | `all-repair-in-place` | fold as today (group → fix → gate → commit → flip) |
|
|
49
51
|
| empty queue (zero findings taken) | `none` | receipt only |
|
|
50
52
|
|
|
@@ -60,7 +62,7 @@
|
|
|
60
62
|
`DISPUTED <evidence → user decision>`; never edit classification or create an
|
|
61
63
|
issue.
|
|
62
64
|
9. **Replan.** If the smallest correct group exceeds a reviewable correction,
|
|
63
|
-
run `
|
|
65
|
+
run `bun scripts/unit-route.mjs <unit>` (node fallback if bun is not installed) — its `route: replan` line prints the
|
|
64
66
|
planner command (`/unit-lane <slug>` for a feature, `/unit-lane --fix <n>` for
|
|
65
67
|
a fix) that appends the proposed
|
|
66
68
|
phases to the unit's SPEC. The `<unit>` argument accepts the bare folder number
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: init-workspace
|
|
3
3
|
user-invocable: true
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.2.0
|
|
5
5
|
argument-hint: <target-dir>
|
|
6
6
|
author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
|
|
7
7
|
license: MIT
|
|
@@ -78,7 +78,7 @@ Inspect the target dir (`[target-dir]`, default cwd) before touching anything:
|
|
|
78
78
|
|
|
79
79
|
## Progressive loading — bootstrap or upgrade, never both
|
|
80
80
|
|
|
81
|
-
The reference allowlist is exactly the
|
|
81
|
+
The reference allowlist is exactly the six linked paths below. Never invent or
|
|
82
82
|
read another `references/` path. Step 0 selects exactly one route:
|
|
83
83
|
|
|
84
84
|
**Hard rule for an existing Claude Code, Cursor, Copilot, or OpenCode
|
|
@@ -95,6 +95,10 @@ or portability unless the runtime platform has no named adapter at all.
|
|
|
95
95
|
only. Its additive-only rule is absolute; do not replay bootstrap.
|
|
96
96
|
The upgrade route loads [SERENA language servers](references/SERENA.md)
|
|
97
97
|
for the additive provisioning step.
|
|
98
|
+
- Provisioning Engram on a host with no pi package: read
|
|
99
|
+
[Engram provisioning](references/ENGRAM.md) — detect, ask, register or
|
|
100
|
+
instruct, report. Loaded by the bootstrap write route only (the pi package
|
|
101
|
+
provisions itself, feature 66).
|
|
98
102
|
- No named adapter exists for the detected runtime platform: add
|
|
99
103
|
[portability](references/PORTABILITY.md) only for that fallback. Claude Code,
|
|
100
104
|
Cursor, Copilot, and OpenCode are named supported adapters; a missing adapter
|
|
@@ -133,6 +137,13 @@ loads exactly upgrade and skips bootstrap plus portability.
|
|
|
133
137
|
auto-detected), a listed server that fails to start must be removed (one
|
|
134
138
|
failure disables every server in the project), and LSP evidence stays
|
|
135
139
|
TypeScript/JavaScript-only. Document verification is a script's job.
|
|
140
|
+
- **Engram provisioning is ask-first, never assumed (feature 66).** Detect the
|
|
141
|
+
`engram` binary, ask before writing any host MCP config, write the absolute
|
|
142
|
+
path with the exact `mcp --tools=agent` argv, and report exactly what was
|
|
143
|
+
written. An existing `engram` declaration is never overwritten, and an absent
|
|
144
|
+
binary is a recorded residual — the documented install route is
|
|
145
|
+
`pi install npm:gentle-engram@latest`, never the CLI's own setup subcommand,
|
|
146
|
+
which keeps serving whatever version ran it until it is re-run.
|
|
136
147
|
- **Retrieval index scaffold and git hooks are consent-gated (AC22).** The
|
|
137
148
|
index surface — the committed `.agentic-workflow/index.json` config plus the
|
|
138
149
|
three freshness hooks (`post-merge`, `post-checkout`, `post-rewrite`, all
|
|
@@ -34,7 +34,13 @@
|
|
|
34
34
|
health check and render the fixed provisioning report. When no installer is
|
|
35
35
|
available, offer only what the machine can perform and record the residual
|
|
36
36
|
with its reason — the run completes either way.
|
|
37
|
-
9. **
|
|
37
|
+
9. **Offer Engram provisioning.** Load [ENGRAM](ENGRAM.md), detect the binary
|
|
38
|
+
and ask consent: register the `engram` MCP server (absolute path, exact
|
|
39
|
+
`mcp --tools=agent` argv) when the host has one, leave an existing
|
|
40
|
+
declaration untouched, and report exactly what was written. An absent binary
|
|
41
|
+
becomes a residual with the documented install route — never a failed run.
|
|
42
|
+
Skip this step when the pi package provisions the host itself.
|
|
43
|
+
10. **Install accepted agent safety hooks.** Keep the canonical policy and
|
|
38
44
|
fullauto wrapper at `.agentic-workflow/hooks/`. Seed the shipped
|
|
39
45
|
path-protection policy at `.agentic-workflow/path-policy.json` and its doc
|
|
40
46
|
page at `.agentic-workflow/path-protection.md`, beside the hooks — the
|
|
@@ -47,10 +53,10 @@
|
|
|
47
53
|
an unknown payload, or an existing customized hook file becomes a residual,
|
|
48
54
|
never a silent overwrite. Direct merges remain blocked; do not create a
|
|
49
55
|
`.automerge` exception.
|
|
50
|
-
|
|
56
|
+
11. **Offer the workflow skills.** Propose installing them:
|
|
51
57
|
`npx skills add gtrabanco/agentic-workflow` (note the SSH/local-path variant if
|
|
52
58
|
the source is private). Don't install without a yes.
|
|
53
|
-
|
|
59
|
+
12. **State that reviews are self-contained; offer optional extras.** The
|
|
54
60
|
workflow ships its **own internal review pack** (`review-code`,
|
|
55
61
|
`review-security`, `review-verify`, `review-debt`, `review-design`,
|
|
56
62
|
`review-a11y`, `review-brand`, `review-perf`, `review-seo`) — it installs
|
|
@@ -60,7 +66,7 @@
|
|
|
60
66
|
under a short "Optional review extras" note so `review-change` and
|
|
61
67
|
`product-audit` run them **in addition** — never as a dependency. Don't
|
|
62
68
|
install anything without a yes.
|
|
63
|
-
|
|
69
|
+
13. **Seed the urgency labels (feature 15, injection-safe urgency).** Create the
|
|
64
70
|
two capability-gated GitHub labels `triage-issue` owns and applies
|
|
65
71
|
(`skills/triage-issue/SKILL.md` is the sole owner of the name/color
|
|
66
72
|
vocabulary — this step only seeds it, never redefines it):
|
|
@@ -73,7 +79,7 @@
|
|
|
73
79
|
forge is unavailable or the user declines forge setup, skip this step and
|
|
74
80
|
list the two labels as a residual for the user to create manually later
|
|
75
81
|
(never fail the whole scaffold on it).
|
|
76
|
-
|
|
82
|
+
14. **Report.** List what was created, which placeholders still need human input,
|
|
77
83
|
the companion skills recorded/installed, the urgency labels seeded (or
|
|
78
84
|
skipped, with reason), and the next step:
|
|
79
85
|
`discover-repository-state` → `/unit-lane` (or `workflow-status`) → catalog
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
## Why this step exists
|
|
2
|
+
|
|
3
|
+
The workflow's units save what they learned into Engram, the cross-session
|
|
4
|
+
memory layer its memory protocol documents. On a host whose agent has no `pi`
|
|
5
|
+
package to provision it (the pi package registers the server itself, feature
|
|
6
|
+
66 P4), the target project has no memory layer at all unless this step offers
|
|
7
|
+
one — so Engram provisioning is a **parity obligation**, not an optional extra:
|
|
8
|
+
feature 66's approval is that the pi path registers it and every other host is
|
|
9
|
+
offered the same thing ask-first.
|
|
10
|
+
|
|
11
|
+
## What this file owns
|
|
12
|
+
|
|
13
|
+
The **non-pi** half of Engram provisioning. It owns exactly four moves —
|
|
14
|
+
detect, ask, provision-or-instruct, report — and nothing else. The workflow-side
|
|
15
|
+
protocol (when units save, the recall order, the degraded path) is **not** here;
|
|
16
|
+
it lives in `unit-lane`'s memory reference, which the skills that run units
|
|
17
|
+
already load.
|
|
18
|
+
|
|
19
|
+
## 1. Detect
|
|
20
|
+
|
|
21
|
+
Look for the `engram` binary on `PATH` (`command -v engram`) and read its
|
|
22
|
+
version (`engram --version`). Two outcomes matter:
|
|
23
|
+
|
|
24
|
+
- **Present** — record the resolved path and the version fingerprint.
|
|
25
|
+
- **Absent** — record it as a residual, and go to step 2 with the install
|
|
26
|
+
guidance below rather than silently skipping the step.
|
|
27
|
+
|
|
28
|
+
Never write an MCP registration file for a binary that does not resolve: a
|
|
29
|
+
registered-but-unstartable server fails every session after it, which is a worse
|
|
30
|
+
default than an honest gap.
|
|
31
|
+
|
|
32
|
+
## 2. Ask, then do exactly what was agreed
|
|
33
|
+
|
|
34
|
+
This is a **consent-gated install** like every other in this skill. Ask one
|
|
35
|
+
question — "register Engram as the project's memory layer?" — and act on the
|
|
36
|
+
answer:
|
|
37
|
+
|
|
38
|
+
| Answer | What you do |
|
|
39
|
+
|---|---|
|
|
40
|
+
| yes | write the MCP registration named in step 3 and report it verbatim |
|
|
41
|
+
| no | write nothing, record it as a residual, finish the run normally |
|
|
42
|
+
| not installed | offer the install route below, and provision **only** if the user then says yes |
|
|
43
|
+
|
|
44
|
+
**The install route is `pi install npm:gentle-engram@latest`.** The CLI's own
|
|
45
|
+
setup subcommand is **not** the documented route and must never be printed as an
|
|
46
|
+
instruction: it pins whatever version ran it and keeps serving that version
|
|
47
|
+
until it is re-run, so an updated binary can sit unused behind a stale
|
|
48
|
+
registration (decision D3, 2026-10-21).
|
|
49
|
+
|
|
50
|
+
## 3. What "register" means on a non-pi host
|
|
51
|
+
|
|
52
|
+
There is no `pi.registerMcpServer` here, so the registration is a **declared
|
|
53
|
+
file** the host agent reads. Write the server into that host's own MCP config
|
|
54
|
+
(the agent's documented MCP surface), never into a file the host does not read:
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"engram": { "command": "<absolute path to engram>", "args": ["mcp", "--tools=agent"] }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Rules:**
|
|
65
|
+
|
|
66
|
+
- **Absolute path, never a bare name** — the host's `PATH` at load time is not
|
|
67
|
+
the shell's.
|
|
68
|
+
- **Args are exactly** `mcp` `--tools=agent`. A different argv changes which
|
|
69
|
+
tools the server exposes.
|
|
70
|
+
- **Never overwrite a server the user already declared** under the name
|
|
71
|
+
`engram` — a declared server wins over anything this step would add. Report
|
|
72
|
+
that you found it and left it alone.
|
|
73
|
+
- **Additive and idempotent** — a second run with the same content writes
|
|
74
|
+
nothing and says so.
|
|
75
|
+
|
|
76
|
+
## 4. Report exactly what was written
|
|
77
|
+
|
|
78
|
+
Every outcome ends in a report the user can read back:
|
|
79
|
+
|
|
80
|
+
- **Registered** — the file path, the server name, and the exact `command` +
|
|
81
|
+
`args` written.
|
|
82
|
+
- **Declined** — that nothing was written, and that the run continued.
|
|
83
|
+
- **Binary missing** — that nothing was written, the install route verbatim, and
|
|
84
|
+
that it is recorded as a residual.
|
|
85
|
+
- **Already declared** — the file that already carries it, and that it was left
|
|
86
|
+
untouched.
|
|
87
|
+
|
|
88
|
+
"Report exactly what was written" is the same contract the Serena step follows;
|
|
89
|
+
a provisioning step the user cannot read back is one they cannot trust.
|
|
90
|
+
|
|
91
|
+
## Checklist (pass only if)
|
|
92
|
+
|
|
93
|
+
- [ ] `engram` presence **and** version were detected (or absence recorded)
|
|
94
|
+
- [ ] Consent was asked before any file was written — never assumed
|
|
95
|
+
- [ ] The written server uses the absolute binary path and the exact argv
|
|
96
|
+
- [ ] An existing `engram` declaration was left untouched and reported
|
|
97
|
+
- [ ] A second run is a no-op
|
|
98
|
+
- [ ] The closing report states what was written — or that nothing was
|
|
99
|
+
|
|
100
|
+
## Forbidden
|
|
101
|
+
|
|
102
|
+
- Never print the CLI's own setup subcommand as the install route
|
|
103
|
+
- Never write an MCP config for an unresolved binary
|
|
104
|
+
- Never overwrite an operator's existing `engram` declaration
|
|
105
|
+
- Never let a memory gap fail the run — record it as a residual and continue
|
|
106
|
+
- Never restate the unit-boundary save/recall protocol here; that is the lane's
|
|
107
|
+
memory reference
|