pi-session-mcp 0.8.1 → 0.8.3

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.
@@ -0,0 +1,355 @@
1
+ # Sprint 1: correctness
2
+
3
+ Base: main `3e360dd672cbffcce2913a5cf9f6333a0262f077` (after docs PR #58).
4
+ Date: 2026-10-13. Tracking: [#59](https://github.com/plagor44-ux/pi-session-mcp/issues/59)
5
+ (R01) and [#56](https://github.com/plagor44-ux/pi-session-mcp/issues/56) (R02).
6
+ Integration branch: `fix/59-56-s1-correctness`. Runtime candidate (the last
7
+ commit that changes `src/` or `test/`):
8
+ `fa32c22b573ff0bb0b920813bd9520bb79b025f4`. Later commits on the branch change
9
+ documentation only.
10
+ Planning sources: the [roadmap](../roadmap.md) and the
11
+ [post-0.8.1 audit](../reviews/2026-10-13-post-0.8.1-audit.md), which defines
12
+ R01–R23 and the Sprint 1 exit gate.
13
+
14
+ This file tracks the state of Sprint 1. It records what is planned, what code
15
+ exists and what is proven. A status of `implemented` or `verified` is set only
16
+ together with evidence in the sections below; nothing here is a claim that a
17
+ check has already passed.
18
+
19
+ ## Scope
20
+
21
+ In scope:
22
+
23
+ - R01: skill recovery must not delete operator content in the transaction's
24
+ trash ([#59](https://github.com/plagor44-ux/pi-session-mcp/issues/59)).
25
+ - R02: `--verify` must report the client and inspection failures it currently
26
+ reduces to `registration_not_equivalent`
27
+ ([#56](https://github.com/plagor44-ux/pi-session-mcp/issues/56)).
28
+ - R03: the native Linux quality gate for the integrated candidate.
29
+ - R19: carry the v0.8.1 post-release evidence from the release notes into
30
+ [acceptance](../acceptance.md).
31
+ - The documentation that these changes directly affect.
32
+
33
+ Out of scope: Sprint 2–4 items, the R13/R14 harness extensions, a full Level 3
34
+ cycle, a third concurrent worker session, new features, dependency or Pi SDK
35
+ updates, a version bump and any change to the MCP contract.
36
+
37
+ R-identifiers are planning identifiers, not GitHub issue numbers. R01 and R02
38
+ have issues (#59, #56). R03 and R19 have no separate issues; they are delivered
39
+ in this sprint's pull request. R21 (the consolidated roadmap) was delivered as
40
+ documentation by #58; that did not fix R01 or R02.
41
+
42
+ ## Delivery
43
+
44
+ One branch and one pull request against main, with separate commits per issue.
45
+ The work runs in separate worktrees, each with its own file ownership, and an
46
+ integrator combines them. No merge, tag or publication is part of this sprint.
47
+
48
+ ## Status legend
49
+
50
+ | Status | Meaning |
51
+ | --- | --- |
52
+ | planned | Not started |
53
+ | in_progress | Work has started; no result may be claimed yet |
54
+ | implemented | The code or text exists; the acceptance criteria are not yet met with evidence |
55
+ | verified | The named acceptance criteria are met and the evidence is recorded below |
56
+ | blocked | A named blocker prevents progress |
57
+
58
+ ## Tasks
59
+
60
+ | Task | Issue | Owners | Branch / worktree | Depends on | Status |
61
+ | --- | --- | --- | --- | --- | --- |
62
+ | R01 recovery retains unprovable trash | [#59](https://github.com/plagor44-ux/pi-session-mcp/issues/59) | Strand A implements `src/setup-skills.ts` and the existing recovery tests; strand C writes the counterexamples in `test/setup-skills-trash-preservation.test.ts` | `s1/a-recovery` (worktree a-recovery); `s1/c-trash-tests` | None | verified (native Linux; final-head CI pending) |
63
+ | R02 verify diagnostics | [#56](https://github.com/plagor44-ux/pi-session-mcp/issues/56) | Strand B implements `src/setup.ts`; strand D writes the counterexamples in `test/setup-verify-diagnostics.test.ts` | `s1/b-verify` (worktree b-verify); `s1/d-verify-tests` | None | verified (native Linux and real clients; final-head CI pending) |
64
+ | R03 native QA gate | None | Strand E prepares native QA readiness and later reviews read-only; the integrator runs the gate | Runs on the integrated candidate (branch `fix/59-56-s1-correctness`) | Integrated candidate of R01 and R02 | verified (native Linux) |
65
+ | R19 v0.8.1 evidence carry-over | None | Strand F (documentation) | `s1/f-docs` (worktree f-docs) | None | verified |
66
+
67
+ Status as of 2026-10-13, after integration, the native gate, Level 2 and two
68
+ independent reviews. "verified" refers to the acceptance criteria of each task
69
+ below. It does not include the final-head CI matrix on Linux, macOS 15 and
70
+ macOS 26, which runs on the pull request, or the maintainer's merge decision;
71
+ the Sprint 1 exit gate stays open until both exist. Issue #56 was closed once
72
+ by an unrelated documentation merge although the code was unchanged; it is
73
+ fixed only by the commits listed below.
74
+
75
+ Strand F also owns the sprint file, the roadmap status, the changelog entry and
76
+ the corrected recovery and verify documentation. The integrator owns the
77
+ version and release fields, which stay unchanged in this sprint.
78
+
79
+ ## Acceptance criteria
80
+
81
+ ### R01 / #59: recovery retains unprovable trash
82
+
83
+ The contract of the fix. None of it is verified until the evidence section
84
+ says so.
85
+
86
+ - Recovery deletes the transaction's `.trash` intermediate only when its
87
+ current contents are the complete, unchanged replaced copy: its version 2
88
+ tree fingerprint equals the replaced fingerprint in the pending record.
89
+ - A partial trash tree (for example after an interruption during the
90
+ entry-by-entry deletion, including an empty one), a modified, added-to,
91
+ foreign or otherwise unprovable tree, and any trash when the record names no
92
+ usable replaced fingerprint are retained and reported as
93
+ `skill_recovery_retained` (status `divergent`). The pending record, the slot
94
+ and the other intermediates stay unchanged. This deliberately replaces the
95
+ earlier automatic deletion of partial trash trees.
96
+ - An added regular operator file and modified content of an existing regular
97
+ file survive `apply`, `remove` and `rollback` byte for byte.
98
+ - A complete, unchanged own trash tree is still deleted and the transaction
99
+ settles normally (`skill_recovered` or `skill_removed`).
100
+ - Intermediates of other transactions and 0.8.0 names stay untouched.
101
+ - Reports contain no paths or file content.
102
+ - The existing interruption recovery tests are kept, and their partial-trash
103
+ expectations follow the corrected contract.
104
+ - A dry-run still announces `skill_recovery_planned` without inspecting
105
+ intermediates, so a later apply can still retain.
106
+ - Lock, guardian, healthy checks, directory fsync and release binding are not
107
+ weakened.
108
+ - [Skills](../skills.md#interrupted-updates) and the
109
+ [setup design](../client-setup-design.md) describe the retention guarantee and
110
+ the operator settlement steps.
111
+
112
+ ### R02 / #56: verify diagnostics
113
+
114
+ The contract of the fix. None of it is verified until the evidence section
115
+ says so.
116
+
117
+ - Precedence stays: unknown client (`client_unsupported`), ownership
118
+ (`ownership_unavailable`), release binding (`release_binding_mismatch`),
119
+ then Doctor under its own code. A failed Doctor now ends that target's verify
120
+ before inspection and handshake.
121
+ - Inspection that reports the client unsupported or not discoverable (for
122
+ example its CLI is not on `PATH`) gives status `unsupported`, code
123
+ `unsupported`.
124
+ - Inspection that throws gives `inspect_failed`.
125
+ - An absent registration, a divergent one, or an equivalent one with another
126
+ fingerprint gives `registration_not_equivalent`.
127
+ - Only a truly equivalent registration runs the bounded MCP handshake
128
+ (`mcp_verified` or `mcp_<status>`).
129
+ - No failure case mutates a registration or starts the handshake, and all exit
130
+ with `1`.
131
+ - No new code such as `client_unavailable` is introduced.
132
+ - Human and JSON output, exit status and the documented codes agree.
133
+ - [Client setup](../client-setup.md#verify-diagnostics) and the
134
+ [setup design](../client-setup-design.md#verification-boundary) document the
135
+ codes.
136
+
137
+ ### R03: native QA gate
138
+
139
+ Runs once, on the integrated candidate, on native Linux (not a container whose
140
+ process, `/proc` or kernel-lock prerequisites are unproven):
141
+
142
+ - `npm ci`
143
+ - `npm run typecheck`
144
+ - `npm run build:cli`
145
+ - `NODE_OPTIONS=--unhandled-rejections=strict npm test`
146
+ - `npm run build`
147
+ - `npm audit` and `npm audit --omit=dev`
148
+ - `git diff --check` and a clean `git status --short`
149
+ - `npm pack --dry-run`, and a check that the relative links of the changed
150
+ documents resolve
151
+
152
+ Every command exits with `0`, with no unhandled rejection. Where a check
153
+ fails, record whether it is a regression of the candidate or an unmet platform
154
+ prerequisite (for example unreadable `/proc`, a missing trusted `flock`, or an
155
+ unsupported filesystem). Do not retry until green, and do not weaken a process
156
+ proof to make a run pass. Original failures stay on record. The earlier
157
+ container failures of the audit are not attributed to a cause here.
158
+
159
+ ### R19: v0.8.1 evidence carry-over
160
+
161
+ - The post-release evidence that exists only in the v0.8.1 release notes is
162
+ carried into [acceptance](../acceptance.md#v081-post-release-evidence-carried-over-from-the-release-notes)
163
+ with its source, what was checked, on what, with which result, its
164
+ classification (provider-free, real client without a model, real model) and
165
+ the stated limitations and failures.
166
+ - No item is upgraded or reinterpreted, and nothing is added that the release
167
+ notes do not state.
168
+
169
+ ## Evidence
170
+
171
+ Recorded by the integrator on 2026-10-13 on native Linux (x64, kernel 7.2,
172
+ Btrfs checkout, tmpfs temporary root), Node.js `26.11.1`, npm `12.2.0`. No
173
+ provider, model or credential was used. A result for one commit is not
174
+ evidence for another; the binding to the final pull-request head is described
175
+ under [Source binding](#source-binding).
176
+
177
+ ### Commits
178
+
179
+ | Commit | Content |
180
+ | --- | --- |
181
+ | `73fd804` | fix(setup): report `unsupported` and `inspect_failed` in verify (#56) |
182
+ | `7736322` | test(setup): verify diagnostics counterexamples (#56) |
183
+ | `02a6a7f` | fix(skills): retain unprovable trash during recovery (#59), including the adapted interruption tests |
184
+ | `fa32c22` | test(skills): trash preservation counterexamples for recovery (#59) — runtime candidate |
185
+ | later | documentation only |
186
+
187
+ ### Before the fix (base `3e360dd`)
188
+
189
+ The counterexamples were written against the contract, independently of the
190
+ fixes, and run on the unfixed base first. Every failure is an assertion about
191
+ the defect; none is an import, type or fixture error.
192
+
193
+ | Check | Exit | Result |
194
+ | --- | --- | --- |
195
+ | `NODE_OPTIONS=--unhandled-rejections=strict npx vitest run test/setup-skills-trash-preservation.test.ts` | 1 | 24 of 30 failed: `apply` reported `skill_recovered`, `remove` and `rollback` reported `skill_removed` where `skill_recovery_retained` was required (added file, modified files, partial, empty, and a record without a replaced fingerprint). The complete own trash and the other-transaction cases passed. |
196
+ | `NODE_OPTIONS=--unhandled-rejections=strict npx vitest run test/setup-verify-diagnostics.test.ts` | 1 | 19 of 53 failed: unsupported and throwing inspections reported `registration_not_equivalent`, including at the `main()` and formatter boundary; after a failed Doctor, inspection (and for an equivalent registration the handshake) still ran. |
197
+ | Real clients, built base, isolated homes: verify with the client CLI not on `PATH` | 1 | Codex `user` and Claude Code `user` both reported `failed (registration_not_equivalent)`; `--dry-run` reported `unsupported (unsupported)`. This reproduces #56. |
198
+
199
+ The adapted interruption tests in `test/setup-skills-recovery.test.ts` were
200
+ not executed against the base. The independent review confirmed by reading
201
+ that the base deletes the one-entry partial trash and would fail them.
202
+
203
+ ### Native gate (R03) on the runtime candidate `fa32c22`
204
+
205
+ | Check | Command | Exit | Result |
206
+ | --- | --- | --- | --- |
207
+ | Install | `npm ci` | 0 | |
208
+ | Typecheck | `npm run typecheck` | 0 | |
209
+ | CLI build | `npm run build:cli` | 0 | |
210
+ | Tests, strict rejections | `NODE_OPTIONS=--unhandled-rejections=strict npm test` | 0 | 52 files passed; 1121 tests passed, 6 skipped, 0 failed; no unhandled error |
211
+ | Build | `npm run build` | 0 | |
212
+ | Audit | `npm audit` | 0 | 0 vulnerabilities |
213
+ | Audit, production | `npm audit --omit=dev` | 0 | 0 vulnerabilities |
214
+ | Whitespace | `git diff --check 3e360dd HEAD` | 0 | |
215
+ | Clean tree | `git status --short` | 0 | empty |
216
+
217
+ The test count reconciles with the v0.8.1 record (50 files, 1035 passed, 6
218
+ skipped): two new files and 86 new cases. By their skip conditions, the six
219
+ skipped cases are the four macOS-only kernel-lock cases, one isolated-probe
220
+ case and one red-before case that needs an unmodified base build. A readiness
221
+ check before the run found every Linux setup prerequisite present: supported
222
+ filesystems for the temporary root and the checkout, a trusted root-owned
223
+ `flock`, a readable `/proc` without `hidepid`, a determinate process table and
224
+ no nested PID namespace. The process, `/proc` and kernel-lock failures of the
225
+ audit's container run did not occur here. That does not establish their cause
226
+ in the container.
227
+
228
+ On the documentation head that followed, without a change to `src/`, `test/`,
229
+ `scripts/` or the package manifests:
230
+
231
+ | Check | Command | Exit | Result |
232
+ | --- | --- | --- | --- |
233
+ | Package contents | `npm pack --dry-run --json` | 0 | 132 files, 234,493 bytes; this sprint file included; no `src/`, `test/`, lockfile or implementation plan |
234
+ | Relative links | link and heading-anchor check of every changed Markdown file, README, roadmap and audit | 0 | 114 links, 0 problems |
235
+
236
+ ### Targeted results on the integrated candidate
237
+
238
+ | Check | Exit | Result |
239
+ | --- | --- | --- |
240
+ | #59: `test/setup-skills-trash-preservation.test.ts`, `test/setup-skills-recovery.test.ts`, `test/setup-skills.test.ts`, `test/setup-skills-legacy.test.ts`, `test/setup-skills-collision.test.ts` | 0 | 123 passed, 0 skipped; the Linux SIGKILL recovery cases ran |
241
+ | #56: `test/setup-verify-diagnostics.test.ts`, `test/setup-lifecycle.test.ts` | 0 | 75 passed |
242
+
243
+ ### Source binding
244
+
245
+ The native gate ran on `fa32c22`. Level 2 ran on the build of the same
246
+ runtime sources at the documentation head `73967f7`: its built `dist/main.js`
247
+ has SHA-256 `47875d38886528ace6b242df2c6ad79d624c51e330e63c2f401576eadc449ed7`,
248
+ which the harness recorded as well. The final pull-request head changes only
249
+ documentation relative to `fa32c22`; that is checked with
250
+ `git diff --stat fa32c22 <head> -- src test scripts package.json package-lock.json tsconfig*.json`,
251
+ which must be empty. A later runtime change requires the native gate and
252
+ Level 2 again.
253
+
254
+ ## Level 2
255
+
256
+ One run of `scripts/setup-acceptance.mjs` on the final runtime build, with the
257
+ real Codex CLI `0.162.1` and Claude Code `2.1.296`, disposable homes and the
258
+ harness's synthetic configuration. No model, no global installation.
259
+
260
+ | Check | Exit | Result |
261
+ | --- | --- | --- |
262
+ | `node scripts/setup-acceptance.mjs --setup "node <checkout>/dist/setup-main.js" --build-dir <checkout> --work-dir <private cache directory> --label <label> --out <private file>` | 0 | 160 of 160 checks passed: `codex:user`, `claude-code:user`, `claude-code:project` and `claude-code:local`, 9 of 9 steps each. Real registrations unchanged, no remaining process, no path leak, build unchanged, disposable directory removed. |
263
+
264
+ New negative case for #56, recorded separately because the harness has no
265
+ negative steps: with the same real clients in isolated homes, apply and verify
266
+ ran with the client on `PATH`; then verify (human and `--json`) and dry-run
267
+ ran with `PATH` reduced to the system directories, so that neither client was
268
+ found; then remove ran with the client on `PATH` again.
269
+
270
+ | Client | Verify without client on `PATH` | JSON | Dry-run | Registration during these steps | Exit |
271
+ | --- | --- | --- | --- | --- | --- |
272
+ | Codex `user` | `unsupported (unsupported)` | `unsupported`/`unsupported` | `unsupported (unsupported)` | unchanged | 1 each |
273
+ | Claude Code `user` | `unsupported (unsupported)` | `unsupported`/`unsupported` | `unsupported (unsupported)` | unchanged | 1 each |
274
+
275
+ Apply, verify (`mcp_verified`) and remove with the client on `PATH` exited 0
276
+ for both. No output contained a path. The real client registrations were
277
+ unchanged before and after. This check script is not part of the repository.
278
+
279
+ ## Independent review
280
+
281
+ Two read-only reviewers who did not write the change reviewed the frozen
282
+ runtime diff `3e360dd..fa32c22`:
283
+
284
+ - Strand E (Claude family): approve with nits; 135 targeted tests rerun.
285
+ - A Pi worker with the `review` profile (OpenAI family): approve with nits; no
286
+ material runtime finding.
287
+
288
+ | Finding | Severity | Resolution |
289
+ | --- | --- | --- |
290
+ | A dry-run still announces `skill_recovery_planned` where apply retains an intermediate; more reachable now that a partial trash is retained | minor | Pre-existing and documented. Not fixed in this sprint: a fix needs one read-only classification shared by dry-run and recovery. Tracked as [#60](https://github.com/plagor44-ux/pi-session-mcp/issues/60) and linked from the documentation. |
291
+ | An empty trash directory is retained and must be deleted by hand | nit | Kept deliberately: it is a partial tree under this sprint's contract, and the documentation names the case. |
292
+ | The documentation described the old structural trash deletion | minor | The reviewer saw the base documentation; the documentation commit replaces it. |
293
+ | The v2 fingerprint covers regular files, not empty directories or file modes | observation | Documented: such a difference inside an otherwise complete trash does not prevent deletion, and no file content is lost. |
294
+ | A retained backup or staging directory can follow the deletion of a proven own trash | observation | Pre-existing order, correct because the trash was proven. The documentation now says so instead of claiming that all other intermediates stay unchanged. |
295
+ | A same-user process can change the trash between its check and its deletion | observation | Pre-existing for every intermediate and outside the documented trust model; not widened. |
296
+
297
+ No finding required a runtime change, so the native gate and Level 2 were not
298
+ repeated.
299
+
300
+ ## Open gates and remaining findings
301
+
302
+ Sprint 1 does not close these. They stay open:
303
+
304
+ - Final-head CI on Linux, macOS 15 and macOS 26 for the pull request. Its
305
+ result belongs to the pull request; recording it here would need another
306
+ push and another CI run.
307
+ - The maintainer's merge decision.
308
+ - [#60](https://github.com/plagor44-ux/pi-session-mcp/issues/60): dry-run
309
+ prediction of a retained intermediate.
310
+ - Current macOS Level 2 on real hardware with both clients (R10). The new
311
+ #59 and #56 behavior is covered on macOS only by CI.
312
+ - Level 3: the full ten-task cycle on Pi SDK 1.x (R05) and the profile
313
+ actually intended for use (R09).
314
+ - Live discovery of the setup-installed Codex home skill (R07).
315
+ - Multi-session acceptance beyond two sessions, including a third worker and a
316
+ read-only reviewer (R08).
317
+ - Explicit strict unhandled rejections in CI (R16, Sprint 2). The local gate
318
+ above used them.
319
+
320
+ Release 0.8.2 is only a recommendation. It would need its own scope: an
321
+ unchanged MCP contract, the version and pre-release acceptance in a change
322
+ pull request, and a separate maintainer decision to merge, tag and publish.
323
+ This sprint authorizes none of them.
324
+
325
+ ## Next step
326
+
327
+ When final-head CI passes, the maintainer decides on merging the one pull
328
+ request; merging it closes #59 and #56. Then Sprint 2 begins under the entry
329
+ conditions in the [roadmap](../roadmap.md): R04, R13/R14 resource binding,
330
+ R16 strict CI and the R19–R23 documentation, with #60 as a candidate bounded
331
+ fix. Its proposed window shifts with the Sprint 1 gate.
332
+
333
+ ## Closure
334
+
335
+ Added on 2026-10-13 after the merge. The sections above are the record as of
336
+ the exit gate and are not rewritten; where they say that final-head CI and the
337
+ merge are pending, this section supersedes them.
338
+
339
+ - Merge: pull request [#61](https://github.com/plagor44-ux/pi-session-mcp/pull/61)
340
+ was merged on 2026-10-13 as `b145f8c32cca76d23628ac8830069cee5ccbaece`.
341
+ - Final-head CI on the pull request head `186186d`: run `38389636823`
342
+ (`pull_request`) and run `38389630496` (`push`) both succeeded on
343
+ `ubuntu-latest`, `macos-15`, `macos-26` and the `verify` job.
344
+ - CI on main: run `38402514112` on `b145f8c` succeeded on the same matrix.
345
+ - Issues: [#59](https://github.com/plagor44-ux/pi-session-mcp/issues/59) (R01)
346
+ and [#56](https://github.com/plagor44-ux/pi-session-mcp/issues/56) (R02) were
347
+ closed as completed by the merge.
348
+ - Carried into Sprint 2: [#60](https://github.com/plagor44-ux/pi-session-mcp/issues/60),
349
+ the dry-run prediction of a retained intermediate, is still open. The other
350
+ open gates above (R05 to R11 and, from Sprint 2, R16, R20, R22 and R23)
351
+ are not closed by this merge; they belong to the later sprints in the
352
+ [roadmap](../roadmap.md). Sprint 2 is tracked in the
353
+ [Sprint 2 file](2026-10-13-s2-evidence.md).
354
+ - A green final-head CI matrix does not add platform evidence beyond what CI
355
+ runs. Current macOS Level 2 on real hardware and Level 3 remain open.