@gtrabanco/pi-agentic-workflow 0.30.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +41 -0
  2. package/dist/config/defaults.js +3 -0
  3. package/dist/config/merge.js +5 -0
  4. package/dist/config/schema.d.ts +0 -5
  5. package/dist/config/schema.js +31 -1
  6. package/dist/config/types.d.ts +15 -0
  7. package/dist/extension/engram.d.ts +119 -0
  8. package/dist/extension/engram.js +187 -0
  9. package/dist/extension/index.js +70 -3
  10. package/dist/settings/console.js +68 -22
  11. package/package.json +1 -1
  12. package/skills/audit-pr/SKILL.md +1 -1
  13. package/skills/audit-pr/references/03_AUDIT_PROCESS.md +3 -2
  14. package/skills/execute-phase/SKILL.md +22 -8
  15. package/skills/execute-phase/references/EXECUTION_CONTRACT.md +15 -9
  16. package/skills/execute-phase/references/FOLDING.md +11 -8
  17. package/skills/execute-phase/references/PREFLIGHT.md +7 -3
  18. package/skills/fold-findings/SKILL.md +28 -17
  19. package/skills/fold-findings/references/FOLD_PROCESS.md +5 -3
  20. package/skills/init-workspace/SKILL.md +13 -2
  21. package/skills/init-workspace/references/BOOTSTRAP_WRITE.md +11 -5
  22. package/skills/init-workspace/references/ENGRAM.md +107 -0
  23. package/skills/log-session/SKILL.md +17 -1
  24. package/skills/orchestration-envelope/references/TURN_CONTRACT.md +2 -1
  25. package/skills/pre-execution-review/SKILL.md +1 -1
  26. package/skills/pre-execution-review/references/LEDGERS.md +30 -2
  27. package/skills/review-change/SKILL.md +1 -1
  28. package/skills/review-change/references/OUTPUT_AND_GUARDRAILS.md +2 -1
  29. package/skills/review-change/references/PERSIST_AND_DECIDE.md +30 -9
  30. package/skills/review-change/references/REVIEW_PROCESS.md +14 -6
  31. package/skills/review-implementation/SKILL.md +10 -2
  32. package/skills/review-implementation/references/CLASSIFY.md +21 -4
  33. package/skills/triage-issue/SKILL.md +18 -12
  34. package/skills/triage-issue/references/FOLD_LEDGER.md +11 -3
  35. package/skills/triage-issue/references/ISSUE_PROCESS.md +3 -2
  36. package/skills/triage-issue/references/REVIEW_FINDING_PROCESS.md +17 -8
  37. package/skills/unit-lane/SKILL.md +23 -5
  38. package/skills/unit-lane/references/DESIGN.md +1 -1
  39. package/skills/unit-lane/references/EVIDENCE.md +7 -3
  40. package/skills/unit-lane/references/MEMORY.md +179 -0
  41. package/skills/unit-lane/references/PLAN.md +11 -1
  42. package/skills/unit-lane/references/RESEARCH.md +3 -3
  43. package/skills/verification-contract/SKILL.md +9 -7
  44. package/skills/workflow-status/SKILL.md +4 -2
  45. package/skills/workflow-status/references/ENVELOPE_FIELDS.md +3 -1
@@ -0,0 +1,179 @@
1
+ # Memory protocol — save and recall at unit boundaries
2
+
3
+ Engram is this workflow's required cross-session memory substrate (owner
4
+ decision 2026-09-24, feature 66). **Required substrate is not a hard
5
+ dependency:** the committed docs stay authoritative, and a memory layer that is
6
+ down is reported once and recorded — it never blocks a unit.
7
+
8
+ This file is the protocol's single home. `execute-phase` and `log-session` carry
9
+ a thin instruction plus a pointer here; they never restate it.
10
+
11
+ ## 1. Probe before the first memory read
12
+
13
+ Run the bounded health probe once per session, before the first read:
14
+
15
+ ```sh
16
+ agentic-workflow memory probe # human block
17
+ agentic-workflow memory probe --json # memory-probe@1 verdict
18
+ ```
19
+
20
+ It is bounded (4 s / 10 s per check, 30 s ceiling), writes nothing, issues no
21
+ MCP tool call, and **always exits 0**. Paste its verdict into the unit doc's
22
+ Evidence section — one row, `verified-by` naming the session:
23
+
24
+ - `ok` → memory is trustworthy for this session.
25
+ - `degraded` → say **once** which checks failed, record the verdict, and keep
26
+ working. Never re-probe in a loop, never ask the user to fix it first.
27
+
28
+ A `degraded` verdict is an answer, not a blocker: the degraded path in §7 is the
29
+ documented response.
30
+
31
+ ## 2. Boundary saves — what, when, and under which key
32
+
33
+ Save at **three boundaries**, always under a stable per-unit topic key:
34
+
35
+ | Boundary | topic_key | Payload |
36
+ |---|---|---|
37
+ | unit start (after triage) | `unit/<NN-slug>/doc` | goal, the numbered acceptance criteria verbatim, the triaged step list |
38
+ | each phase transition | `unit/<NN-slug>/doc` | the phase id, what it changed, its Evidence outcome, new discoveries |
39
+ | unit close | `unit/<NN-slug>/doc` | final Evidence outcomes, decisions taken, the gotchas worth recalling |
40
+
41
+ One payload, four parts — the same four a later session needs to resume without
42
+ re-reading the docs:
43
+
44
+ ```text
45
+ memory-payload@1
46
+ goal: <one line — the unit's objective>
47
+ ac: 1. <numbered AC verbatim, one per line>
48
+ evidence: <phase> <command> → <exit/digest> → <outcome>
49
+ learned: <gotcha, edge case, or decision a fresh session would get wrong>
50
+ ```
51
+
52
+ Call `mem_save` with `topic_key: "unit/<NN-slug>/doc"` and an explicit
53
+ `project`; on a write surface that exposes `session_id`, pass it too (§5). Later
54
+ boundaries reuse the same `topic_key` so the record **upserts** instead of
55
+ fragmenting into one row per phase.
56
+
57
+ **What is saved is a summary for recall, never the artifact.** The unit doc, its
58
+ Evidence rows and `docs/LOGS.md` stay authoritative; a memory record that
59
+ disagrees with them is wrong by definition.
60
+
61
+ ## 3. Recall — the fixed order
62
+
63
+ Resume in this order, and stop as soon as the unit is reconstructable:
64
+
65
+ 1. **`mem_context`** — scoped explicitly (`project: "<name>"`, and `scope` when
66
+ you mean one).
67
+ 2. **`mem_search`** — a scoped search with an **explicit `project`**. Never rely
68
+ on an omitted selector for a global read; a default is not a decision.
69
+ 3. **One retry** — if the project-scoped search misses, retry **once** with
70
+ **`all_projects: true`** passed explicitly. A second miss is a miss.
71
+ 4. **`mem_get_observation`** — fetch the full untruncated body of the hit that
72
+ matters.
73
+ 5. **Read the unit doc** and reconcile: the file wins on every conflict, and the
74
+ difference is worth recording as a discovery (§2 `learned:`).
75
+
76
+ Only when `mem_context` and both searches miss does a fresh session fall back to
77
+ reading the docs cold — and that fallback is recorded, because it means the
78
+ recall path failed, not that nothing was ever saved.
79
+
80
+ When the cwd is ambiguous (several repos under it), call **`mem_current_project`**
81
+ and navigate by its `available_projects`: pick the matching project explicitly
82
+ rather than letting an ambiguous cwd decide. An ambiguous answer is never
83
+ resolved by guessing.
84
+
85
+ ## 4. Keyword-bound recall — the disclosed ceiling
86
+
87
+ Engram's recall is **keyword-bound** (FTS5 over stored text, no vectors). Two
88
+ consequences are obligations, not trivia:
89
+
90
+ - **A miss is not evidence that knowledge was never saved.** It means the query
91
+ did not hit the stored terms. Rephrase with the unit's own vocabulary (slug,
92
+ AC wording, file paths) before concluding anything is absent.
93
+ - **What you save must be searchable later.** Save the words a future session
94
+ will search for — the unit slug, the phase id, the failing command, the file
95
+ path — not a paraphrase.
96
+
97
+ Hybrid FTS5+vector recall is Engram's own direction (#192), never built here.
98
+
99
+ ## 5. Session attribution — explicit on every write, on the surface that carries it
100
+
101
+ Every write must be **attributed to one known session**, never to whichever
102
+ session a machine happens to resolve. On a box with several active runtime
103
+ sessions an unresolved attribution fails closed and the write is lost — the one
104
+ outcome this protocol exists to prevent (the health probe's
105
+ `session-ambiguity` check reads exactly this signal, §1).
106
+
107
+ Which parameter carries that attribution depends on the surface in front of you:
108
+
109
+ | Write surface | How the session is carried | What you do |
110
+ |---|---|---|
111
+ | Engram's own MCP server (`engram mcp --tools=agent`) | its `mem_save`, `mem_save_prompt`, `mem_session_summary` and `mem_capture_passive` take a `session_id` argument | open the session (`mem_session_start`) and pass that id on **every** write |
112
+ | a host whose memory tools expose no `session_id` (Pi's Engram provider binds the runtime session itself) | the provider stamps the session from the live runtime session and **refuses** when that identity is ambiguous or disagrees with the project | never write before the session is open, always pass an explicit `project` (and `cwd` when the directory could match more than one project), and treat an attribution refusal as a failed write — record it (§7), do not retry blind |
113
+
114
+ On both surfaces the obligation is the same and the check is the same: **a write
115
+ that cannot say which session it belongs to is a write that did not happen**.
116
+
117
+ - `mem_session_start` opens the id (or the runtime session the provider binds to)
118
+ at unit start; the boundaries in §2 reuse it, and nothing is written before it.
119
+ - **`mem_session_end` runs only on confirmed-stale ids** — ids you opened yourself
120
+ and know are finished. Never end an id a live session may still hold.
121
+ - When `mem_session_summary` cannot resolve the project, the explicit
122
+ **project fallback** is the documented escape hatch: pass `project` by name
123
+ and the summary lands instead of being refused. Record the fallback when you
124
+ use it.
125
+ - Passing a `session_id` to a tool that does not declare it is not "explicit
126
+ attribution", it is an invalid call. Read the tool's own parameter list when
127
+ the host offers more than one memory surface, and record which surface you used.
128
+
129
+ ## 6. The canonical split (D2)
130
+
131
+ Both writers exist on purpose; neither mirrors the other.
132
+
133
+ | Writer | Owns | Travels |
134
+ |---|---|---|
135
+ | `docs/LOGS.md` (`log-session`) | the human/team journal: what happened, for people | with git |
136
+ | `mem_session_summary` / `unit/<NN-slug>/doc` | local decision and gotcha recall keyed by unit id | local only |
137
+
138
+ Team memory travels with git; agent recall stays local. A double-write on
139
+ purpose, recorded here so it is never mistaken for an accident.
140
+
141
+ ## 7. Degradation — recorded, never silent
142
+
143
+ When the probe says `degraded` or a write fails:
144
+
145
+ - **Local progress is preserved.** The unit doc, Evidence rows and commit are
146
+ the record; they never depend on memory.
147
+ - **The mirror is marked pending explicitly** — one line in the Progress entry
148
+ or Evidence row saying the memory write is pending, so a later session knows
149
+ the gap exists and is not a "nothing was saved" conclusion.
150
+ - **Unrelated safe work continues.** Never stop a unit for a mirror failure.
151
+ - **Sync resumes when the layer answers** — retry the pending write at the next
152
+ boundary, not in a loop.
153
+ - **Read both sides back.** After a write, read the file and the mirror; when
154
+ the versions are irreconcilable, keep both and surface the difference rather
155
+ than silently picking one.
156
+
157
+ ## Checklist (pass only if)
158
+
159
+ - [ ] The probe ran once and its verdict is in Evidence (§1)
160
+ - [ ] A save happened at unit start, at each phase transition, and at close (§2)
161
+ - [ ] Every save was explicitly attributed: a `session_id` on a surface that
162
+ accepts one, otherwise an open session plus an explicit `project` — and it
163
+ named the unit's `topic_key` (§2, §5)
164
+ - [ ] Recall followed the fixed order, with an explicit `project` and at most
165
+ one explicit `all_projects: true` retry (§3)
166
+ - [ ] Any miss was treated as keyword-bound, not as absence (§4)
167
+ - [ ] Any degradation was recorded as pending — never silent (§7)
168
+
169
+ ## Forbidden
170
+
171
+ - Never let a memory verdict block a unit, or re-probe in a loop
172
+ - Never rely on an omitted selector for a global read
173
+ - Never write with unresolved session attribution — pass the `session_id` where
174
+ the surface takes one, and where it does not, never write before the session is
175
+ open (§5)
176
+ - Never call `mem_session_end` on an id you did not open or cannot confirm stale
177
+ - Never mirror `docs/LOGS.md` verbatim — the split is deliberate (§6)
178
+ - Never treat a recall miss as proof nothing was saved
179
+ - Never let a memory record override the committed artifact
@@ -166,7 +166,17 @@ name those files instead.
166
166
  - [ ] Each task names its validator (a backticked command plus its expected outcome)
167
167
  - [ ] Final task is verification (proves the whole unit works)
168
168
  - [ ] No task reaches into a future-phase concern (docs, release, migrations)
169
- - [ ] Phases labeled P1, P2, … (never S1, Step 1)
169
+ - [ ] Phases labeled P1, P2, … — `#308`: `S#` is the requirement id (a spec),
170
+ `P#` is the phase label (a task); the two vocabularies never swap roles
171
+ - [ ] Each requirement is cut from the request verbatim: numbered `S#` in
172
+ `## Specs`, one per distinct ask, with the requester's own words as its
173
+ quote and no requirement the request did not make
174
+ - [ ] A later correction is appended under its own id (`S1a`) and leaves the
175
+ requirement it corrects untouched
176
+ - [ ] Every task bullet names the `S#` it delivers on its `(Implements: …)` line
177
+ - [ ] The `## Log` is opened with `L1` = the request verbatim, and later entries
178
+ append (never rewrite) in the `log-kind@1` vocabulary
179
+ - [ ] `## Findings` is present and carries only OPEN rows (empty at plan time)
170
180
  - [ ] Both planning ledgers are cut (planning evidence + obligations), in the
171
181
  sizing rule's home, with stable ids
172
182
 
@@ -7,9 +7,9 @@ them, not the user. A blank or missing objective/scope is therefore a **document
7
7
  defect**: stop and repair the SPEC (`/unit-lane <unit>` — its §1 writes the
8
8
  objective/why/user-outcome) or re-triage. Never infer unit scope, and never
9
9
  turn a doc defect into a question the user cannot answer. A gap that survives
10
- the repair runs `node scripts/needs-input.mjs <unit-dir>`, pastes the
11
- `open-questions@1` block and stops, routed to `design` or `unit-lane` by the
12
- owning stage.
10
+ the repair runs `bun scripts/needs-input.mjs <unit-dir>` (node fallback if bun is
11
+ not installed), pastes the `open-questions@1` block and stops, routed to `design`
12
+ or `unit-lane` by the owning stage.
13
13
 
14
14
  ## Purpose
15
15
 
@@ -1,15 +1,16 @@
1
1
  ---
2
2
  name: verification-contract
3
3
  user-invocable: false
4
- version: 1.4.3
4
+ version: 1.5.0
5
5
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
6
6
  license: MIT
7
7
  description: >
8
8
  Internal contract: the acceptance artifact per delivery unit — legacy (pre-
9
9
  feature 61) units may carry a frozen `ACCEPTANCE.md` (binding if present);
10
10
  post-feature 61 units use the unit doc's `## Acceptance criteria` section as
11
- the canonical acceptance source; the unit doc's `## Evidence` table serves as
12
- the execution receipt. Consumed by planners, execute-phase, and review-change.
11
+ the canonical acceptance source; the unit doc's evidence carrier — `## Evidence`
12
+ table, or `## Log` `E` lines for a re-cut unit (#308) — serves as the execution
13
+ receipt. Consumed by planners, execute-phase, and review-change.
13
14
  ---
14
15
 
15
16
  # Verification Contract (internal)
@@ -63,9 +64,10 @@ v1` is needed: property/fuzz rides the existing `commands` class.
63
64
 
64
65
  ## Freeze and receipt
65
66
 
66
- The unit doc's `## Evidence` table is the execution receipt: each Evidence row
67
- records a validator command, its exit code or blob digest, output excerpt, and
68
- who verified it. A frozen criterion's receipt is the Evidence row for that
67
+ The unit doc's own evidence carrier is the execution receipt: the `## Evidence`
68
+ table for a legacy-shape unit, the `## Log` `E` lines for a re-cut one (#308). Each
69
+ row or line records a validator command, its exit code or blob digest, output
70
+ excerpt, and who verified it. A frozen criterion's receipt is the Evidence row for that
69
71
  criterion — exact match continues; missing/mismatched evidence stops before
70
72
  edits:
71
73
 
@@ -122,4 +124,4 @@ semantics are verified against authoritative documentation **before a test encod
122
124
 
123
125
  ## Done when
124
126
 
125
- Execution receipt (unit doc `## Evidence` table for post-feature 61 units; legacy `ACCEPTANCE.md` manifest binding-if-present) + named validators + literal quality floor; executor and reviewer evaluate identical evidence.
127
+ Execution receipt (unit doc `## Log` `E` lines for a re-cut unit, `## Evidence` table for a post-feature 61 one; legacy `ACCEPTANCE.md` manifest binding-if-present) + named validators + literal quality floor; executor and reviewer evaluate identical evidence.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: workflow-status
3
3
  user-invocable: true
4
- version: 3.9.2
4
+ version: 3.9.4
5
5
  author: "Gabriel Trabanco <1969593+gtrabanco@users.noreply.github.com>"
6
6
  license: MIT
7
7
  argument-hint: "[--json-only] [--last-envelope <json|path>] [--compact]"
@@ -69,7 +69,9 @@ bytes on a mature repo); the exact keep/drop set is in
69
69
  Per the agent guide's **Workflow conventions** + **documentation map**. The
70
70
  script reads what THIS skill needs (`docs/features/ROADMAP.md`, the fix index
71
71
  `docs/fix/README.md`, every in-flight feature folder's `TASKS.md` +
72
- `progress.md` + `review-findings.md`, and `docs/workflow/REPOSITORY_STATE.md`);
72
+ `progress.md` and its findings carrier — `SPEC.md` `## Findings` + `## Log` for a
73
+ migrated unit (issue #308), `review-findings.md` for a legacy one — and
74
+ `docs/workflow/REPOSITORY_STATE.md`);
73
75
  read them yourself only to interpret a field the script emitted.
74
76
 
75
77
  ## Progressive loading — fixed sensor route
@@ -104,7 +104,9 @@ Exactly two fields change:
104
104
  `in-progress` stays in both modes, so `detail.startable_now` and
105
105
  `detail.blocked_units` keep naming every unit either way.
106
106
  - `findings.fix_now[].route`: the reviewer's multi-paragraph evidence memo becomes
107
- `...(N char evidence, see the unit review-findings.md)`, keeping the original
107
+ `...(N char evidence, see the unit review-findings.md)` for a legacy carrier and
108
+ `...(N char evidence, see the unit SPEC.md ## Findings)` for a migrated one (#308),
109
+ keeping the original
108
110
  length visible. `id`, `file`, `axis`, `severity`, `class` and `suggested_tier`
109
111
  are untouched, and the memo is on disk in the unit's `review-findings.md`, which
110
112
  is where the fold reads it.