pi-session-mcp 0.8.2 → 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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,45 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.8.3 — 2026-10-15
6
+
7
+ - Fixed: a fresh `npm install -g pi-session-mcp@0.8.2` produced a server that
8
+ exited at startup. `@earendil-works/pi-coding-agent` 1.1.0 imports
9
+ `MCP_TYPESCRIPT_PREAMBLE` from `@earendil-works/pi-codemode` but declares it
10
+ as `^1.1.0`, and `pi-codemode` 1.2.0 removed that export. Consumers do not
11
+ receive our lockfile, so npm resolved the new version, while CI and the
12
+ acceptance runs used `npm ci` and never saw it. The SDK's internal
13
+ `@earendil-works` packages, including those declared by other family members
14
+ (`pi-telemetry` comes from `pi-ai`), are now direct, exactly pinned
15
+ dependencies. Issue #78.
16
+ - Changed: Pi SDK 1.2.0 (was 1.1.0) with `@earendil-works/pi-ai`, `pi-mcp`,
17
+ `pi-tui`, `pi-codemode`, `pi-agent-core` and `pi-telemetry` pinned to 1.2.0.
18
+ The SDK no longer depends on `@earendil-works/chord`, so `esbuild` leaves the install.
19
+ Upstream changes that matter to operators: print mode (`pi -p`) now exits 1
20
+ with a warning when the final response was cut off at the output token limit;
21
+ Mistral streams are no longer aborted mid-generation after the request
22
+ timeout; "The upstream provider returned an error" is retried as a transient
23
+ provider error; and an OpenRouter key now lists only the models it may use.
24
+ For extensions, `before_agent_start` now also fires for runs started by
25
+ `pi.sendMessage(..., { triggerTurn: true })`, and its event became a union on
26
+ `messageType`; the allowlisted `pi-cursor-sdk` 0.5.3 registers that event and
27
+ the provider-free checks do not test it against SDK 1.2.0.
28
+ The tools declared to the model, the stop-reason mapping and the reserved MCP
29
+ tool names are unchanged. The Pi SDK canary now tests a candidate SDK together
30
+ with the family versions that candidate declares, resolved transitively.
31
+ - Added: an install smoke (`scripts/install-smoke.mjs`) that starts an installed
32
+ server, checks its handshake, name, version and the eight tools, and requires
33
+ it to exit by itself with status 0 on stdin EOF. CI runs it on every change against the packed package
34
+ installed without a lockfile; a nightly workflow
35
+ (`.github/workflows/install-smoke.yml`) runs it against the published
36
+ `latest` and reports a failure in an issue labeled `install-smoke`.
37
+ - Added: documentation of the packed-tarball Level 2 check, the only
38
+ acceptance-level pre-release check that resolves dependencies like a consumer
39
+ install. The CI install smoke also resolves fresh, but it is an early warning,
40
+ not acceptance. See
41
+ [releasing](docs/releasing.md#prepare-a-release) and
42
+ [acceptance](docs/acceptance.md#tooling).
43
+
5
44
  ## 0.8.2 — 2026-10-13
6
45
 
7
46
  - Fixed: recovery of an interrupted skill update no longer deletes operator
package/README.md CHANGED
@@ -30,7 +30,7 @@ It is not the right tool when:
30
30
 
31
31
  ## Status
32
32
 
33
- The package version is **0.8.2**.
33
+ The package version is **0.8.3**.
34
34
 
35
35
  - **Pre-1.0.** The public tool contract is stable within a minor line: a change to tools, fields, states or error codes needs a new minor release.
36
36
  - **Linux and macOS**, Node.js 22.19.0 or newer. macOS is tested in CI on macOS 15 and 26 on Apple silicon; Intel Macs run the same code but are untested. Setup acceptance on a real Mac is recorded for Claude Code only; Codex is still pending. See [Acceptance](docs/acceptance.md#status). On other platforms `setup` refuses with `platform_unsupported`.
@@ -9,7 +9,7 @@ export const PROFILE_TOOLS = {
9
9
  */
10
10
  const EXTENSION_TOOL_NAME = /^[A-Za-z0-9_][A-Za-z0-9_-]{0,63}$/;
11
11
  /**
12
- * These mirror `isMcpToolName` of Pi SDK 1.1.0 (core/mcp-servers.js), which is not a root
12
+ * These mirror `isMcpToolName` of Pi SDK 1.2.0 (core/mcp-servers.js), which is not a root
13
13
  * export. When the allowlist names no `mcp__` entry, the SDK's `_isAllowedTool` keeps such
14
14
  * tools outside the allowlist for codemode and tool_search, so an extension tool with one
15
15
  * of these names could be active without being granted. This server's own MCP bridge
@@ -132,6 +132,17 @@ prefix (`npm install -g --prefix <dir> pi-session-mcp@<version>`) and runs the
132
132
  lifecycle through the installed `pi-session-mcp-setup`, which also proves the
133
133
  executables and the entry-point detection through npm's symlinks.
134
134
 
135
+ A packed-tarball run installs the tarball of the release candidate, before it is
136
+ published, into a fresh temporary prefix (`npm pack`, then
137
+ `npm install -g --prefix <dir> ./pi-session-mcp-<version>.tgz`, with `<dir>`
138
+ created by `mktemp -d` and removed afterwards) and runs the lifecycle through
139
+ the installed `pi-session-mcp-setup`. It is the only acceptance-level
140
+ pre-release check that resolves dependencies like a consumer install does,
141
+ without our lockfile, before publication. The working-tree run and the CI build
142
+ cannot prove that, because they install from the lockfile; the CI install smoke
143
+ also resolves fresh, but it is an early warning, not acceptance. The packed
144
+ tarball run is the pre-release counterpart of the published-package run.
145
+
135
146
  A published-release run uses a fresh clone of the published tag instead of an
136
147
  existing branch or local tag. It additionally records the tag object and the
137
148
  peeled commit, confirms `git describe --tags --exact-match`, passes Level 1 on
@@ -179,6 +190,35 @@ node scripts/setup-acceptance.mjs \
179
190
  --label npm-<version> --out level2-result.json
180
191
  ```
181
192
 
193
+ Packed tarball: pack the built candidate and install the tarball into a fresh
194
+ temporary prefix outside `/tmp`, then pass the installed executable and package
195
+ directory as for the published package. Create the prefix with `mktemp -d`,
196
+ never reuse a fixed one, and remove it and the tarball afterwards.
197
+
198
+ ```bash
199
+ npm pack
200
+ PREFIX="$(mktemp -d "$HOME/.cache/pi-session-mcp-pack.XXXXXX")"
201
+ npm install -g --prefix "$PREFIX" ./pi-session-mcp-<x.y.z>.tgz
202
+ node scripts/setup-acceptance.mjs \
203
+ --setup "$PREFIX/bin/pi-session-mcp-setup" \
204
+ --build-dir "$PREFIX/lib/node_modules/pi-session-mcp" \
205
+ --label packed-<x.y.z> --out level2-result.json
206
+ rm -rf "$PREFIX" ./pi-session-mcp-<x.y.z>.tgz
207
+ ```
208
+
209
+ The CI job and a nightly workflow (`.github/workflows/install-smoke.yml`) run
210
+ `scripts/install-smoke.mjs` against a lockfile-free install: CI against the
211
+ packed tarball of the commit, the nightly job against the published
212
+ `pi-session-mcp@latest`. The smoke starts the installed server, checks the
213
+ handshake, its name and version and the eight tools, and requires it to exit by
214
+ itself with status 0 after stdin EOF. It starts no session and uses no provider.
215
+ It reports one JSON line whose code is `smoke_passed` or one of
216
+ `package_invalid`, `server_exited`, `initialize_invalid`, `tools_invalid`,
217
+ `stdout_invalid`, `shutdown_timeout`, `shutdown_failed` or `timeout`. On any
218
+ failure it kills the server's whole process group. Both are early warnings for
219
+ a broken fresh install, not acceptance and not a replacement for the
220
+ packed-tarball run.
221
+
182
222
  Tag clone: build a fresh clone of the tag (`npm ci`, `npm run build`,
183
223
  `npm run build:cli`) and use it like the working tree, with `--setup` and
184
224
  `--build-dir` pointing at the clone.
@@ -1429,6 +1469,122 @@ release candidate `bdbdf00` on Linux (`x64`), with Node.js `26.11.1`, Codex CLI
1429
1469
  [Sprint 3 live acceptance](#sprint-3-live-acceptance-2026-10-13) ran, including
1430
1470
  the accepted ten-task Level 3 cycle.
1431
1471
 
1472
+ ### v0.8.2 post-release evidence
1473
+
1474
+ The published-release acceptance of `v0.8.2` ran on 2026-10-15 from 15:36 UTC
1475
+ on Linux (`x64`) with Node.js `26.11.1`, npm `12.2.0`, Codex CLI `0.162.1` and
1476
+ Claude Code `2.1.299`. It **failed** for the installed npm package; the tag
1477
+ passed. The failure is recorded as it happened and is tracked as
1478
+ [#78](https://github.com/plagor44-ux/pi-session-mcp/issues/78).
1479
+
1480
+ Tag binding: a fresh clone of the annotated tag `v0.8.2` (tag object
1481
+ `d068067539a5cf86917e0be08014c9535dce0cc2`) peels to
1482
+ `bdfb95de9a46defa64d2eb382d58d454f97fc8fb`, the merge of #76, and
1483
+ `git describe --tags --exact-match` reports `v0.8.2`.
1484
+
1485
+ Provider-free (Level 1), on that clone. Every command exited with `0`:
1486
+ - 54 test files: 1409 passed and 6 skipped, with strict unhandled rejections
1487
+ and no unhandled error.
1488
+ - `npm audit` and `npm audit --omit=dev`: 0 vulnerabilities.
1489
+ - `git diff --check` and `git status --short` printed nothing.
1490
+ - Offline Doctor with the example configuration: `packageVersion` `0.8.2`;
1491
+ its only finding was the placeholder workspace (`workspace_missing`).
1492
+
1493
+ `package.json`, `package-lock.json`, `dist/main.js` and the whole `dist` tree
1494
+ (84 files) were byte-identical before and after the client cycles.
1495
+ `dist/main.js` has the SHA-256 of the release build
1496
+ (`47875d38886528ace6b242df2c6ad79d624c51e330e63c2f401576eadc449ed7`).
1497
+
1498
+ Real clients without a model (Level 2), with `scripts/setup-acceptance.mjs`:
1499
+ - Tag clone: 160 of 160 checks passed; all nine steps passed on all four
1500
+ targets. The real client registrations were unchanged, no process
1501
+ remained, and the build stayed byte-identical.
1502
+ - npm package, installed with `npm install -g --prefix` into a temporary
1503
+ prefix: the installed version is `0.8.2`, the registry shasum is
1504
+ `1ab640909d8c513f3dbaad3c3691f7ce1f267945` and `dist/main.js` has the same
1505
+ SHA-256 as above. **151 of 160 checks passed.** `--verify` (steps 5 and 8)
1506
+ reported `mcp_unsupported` instead of `mcp_verified` on all four targets;
1507
+ every other step passed, no process remained and the package stayed
1508
+ byte-identical. `realRegistrationsUnchanged` was `false` (see below).
1509
+
1510
+ Cause of the verify failure (#78): the prefix resolved
1511
+ `@earendil-works/pi-codemode` `1.2.0`, while the lockfile pins `1.1.0`. The
1512
+ pinned Pi SDK `1.1.0` declares it as `^1.1.0`, and `1.2.0` no longer exports
1513
+ `MCP_TYPESCRIPT_PREAMBLE`, which the SDK imports. Started directly, the
1514
+ installed `dist/main.js` exits with `1` and a `SyntaxError` before its first
1515
+ MCP frame; the tag clone's server answers `initialize`. Verify reports a
1516
+ server that exits before `initialize` as `mcp_unsupported`. The published
1517
+ bytes are correct; a fresh install of them is not. Installations made before
1518
+ `pi-codemode` `1.2.0` was published (2026-10-12, 23:00 UTC) keep `1.1.0` and
1519
+ start.
1520
+
1521
+ `realRegistrationsUnchanged` `false`: the cause was not determined. Another
1522
+ process wrote the real Codex configuration file during the npm run (15:39:09
1523
+ UTC). Afterwards no real registration referenced the run's directories, the
1524
+ real setup ownership records were unchanged since 2026-10-13, and the real
1525
+ Claude Code registration still targeted the installed `0.8.1`. A live client
1526
+ that changes its registrations during a run is a known source of a false
1527
+ failure (see [Tooling](#tooling)); the check is not counted as passed.
1528
+
1529
+ A run against the published release on 2026-10-14 was reported with exit `0`,
1530
+ but neither its variant nor its check counts were saved; it is not evidence.
1531
+
1532
+ Result: `v0.8.2` is accepted as a release source (tag clone), not as an
1533
+ installed npm package. Fresh npm installs of `0.8.2`, and probably of every
1534
+ version that pins the Pi SDK `1.1.0`, crash at startup.
1535
+
1536
+ ### v0.8.3 pre-release acceptance
1537
+
1538
+ Before its release, `v0.8.3` passed Level 1, the working-tree Level 2 and the
1539
+ new packed-tarball Level 2 on its release candidate `35091eb` on Linux
1540
+ (`x64`), with Node.js `26.11.1`, npm `12.2.0`, Codex CLI `0.162.1` and Claude
1541
+ Code `2.1.299`, on 2026-10-15:
1542
+ - Level 1 on the release branch: every command exited with `0`.
1543
+ - The test run, with `NODE_OPTIONS=--unhandled-rejections=strict`, reported
1544
+ 55 files, 1425 passed and 6 skipped, and no unhandled error.
1545
+ - `npm audit` and `npm audit --omit=dev` reported 0 vulnerabilities.
1546
+ - `npm pack --dry-run` listed 136 files, including the three
1547
+ skills, and no acceptance harness, sources, tests, lockfile or
1548
+ implementation plan.
1549
+ - Doctor reported `packageVersion` `0.8.3`. With the example configuration
1550
+ its only finding was the placeholder workspace.
1551
+ - Level 2 through `scripts/setup-acceptance.mjs` on the candidate's working
1552
+ tree: 160 of 160 checks passed. All nine steps passed on all four targets.
1553
+ The real client registrations were unchanged, no process remained, and the
1554
+ built files were unchanged.
1555
+ - Packed-tarball Level 2 (#78): the candidate's tarball, installed with
1556
+ `npm install -g --prefix` into a fresh prefix without the lockfile, resolved
1557
+ every `@earendil-works` package to `1.2.0` with a single copy each. The install
1558
+ smoke reported `smoke_passed`, and Level 2 against the installed package
1559
+ passed 160 of 160 checks, with the same unchanged registrations, process
1560
+ and build results.
1561
+
1562
+ Targeted live multi-session acceptance on the new Pi SDK `1.2.0`, with
1563
+ `scripts/multi-session-acceptance.mjs` (harness SHA-256 prefix `bb1620ad`) on a
1564
+ clean detached checkout of `16b2374`, the candidate before the review fixes:
1565
+ `dist/main.js` SHA-256 `47875d38…`, build digest `c5e91f70…`. Between `16b2374`
1566
+ and `35091eb` no runtime source changed; the lockfile gained only the root
1567
+ entry that pins `@earendil-works/pi-telemetry` at the `1.2.0` it already
1568
+ resolved. Strictly sequential runs on 2026-10-15 from 18:19 UTC, with
1569
+ synthetic fixtures and the worker profiles copied from the operator profiles
1570
+ without their external MCP grant:
1571
+
1572
+ | Profile source | Extension | Controller | Scenario | Result | Duration |
1573
+ | --- | --- | --- | --- | --- | --- |
1574
+ | DeepSeek `deepseek-flash`, `high` | none | Codex `0.162.1` | `abort` | passed, no failure | 101 s |
1575
+ | DeepSeek `deepseek-flash`, `high` | none | Claude Code `2.1.299` | `parallel` | passed, no failure | 66 s |
1576
+ | Cursor `grok-4.7@256k:fast`, `high` | `pi-cursor-sdk` `0.5.3` | Claude Code `2.1.299` | `abort` | passed, no failure | 156 s |
1577
+ | Cursor `grok-4.7@256k:fast`, `high` | `pi-cursor-sdk` `0.5.3` | Codex `0.162.1` | `parallel` | passed, no failure | 146 s |
1578
+
1579
+ Every run kept its scope, closed its sessions and left no residual process.
1580
+ The Cursor runs load the allowlisted `pi-cursor-sdk` `0.5.3`, which registers
1581
+ `before_agent_start`, whose semantics changed in SDK `1.2.0`; both passed.
1582
+
1583
+ Not established for `0.8.3`: the ten-task Level 3 cycle on SDK `1.2.0`, the
1584
+ `trio` scenario, the operator profiles' external MCP grant, macOS on real
1585
+ hardware (R10, R11), and other providers and models. The published-release
1586
+ acceptance follows after publication.
1587
+
1432
1588
  ## Sprint 1 correctness checks (2026-10-13)
1433
1589
 
1434
1590
  These checks belong to [#59](https://github.com/plagor44-ux/pi-session-mcp/issues/59)
@@ -53,7 +53,7 @@ Changes that keep the public MCP contract (tools, fields, states, error codes) s
53
53
 
54
54
  ## Revisit triggers
55
55
 
56
- - **E (isolation research):** coding profiles are used on non-disposable repositories or with untrusted content, at the latest before a local writer runs on real repositories.
56
+ - **E (isolation research):** coding profiles are used on non-disposable repositories or with untrusted content, at the latest before a local writer runs on real repositories. This trigger fired on 2026-10-15: coding profiles had written on non-disposable repositories. Sprint 4 authorizes the isolation decision as the one next investment, an options comparison in ADR 0008, not an implementation; see [#79](https://github.com/plagor44-ux/pi-session-mcp/issues/79) and the [Sprint 4 decision](../sprints/2026-10-15-s4-decision.md).
57
57
  - **C (bounded wait):** clients routinely need more than about five polls per turn, or client tool-call limits or approval prompts make polling costly.
58
58
  - **D (persistence research):** a client or server restart loses useful work in practice.
59
59
  - **F (remote architecture):** a concrete remote or mobile use case that SSH or existing remote-development workflows cannot satisfy.
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Validated dependency baseline (2026-10-09)
4
4
 
5
- - [`@earendil-works/pi-coding-agent` 1.1.0](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) supplies the documented root exports used by this server, including `ModelRuntime` and `createAgentSession`. Since 0.99 the prompt preflight hook reports a dispatch disposition (`started`, `queued`, `handled`) and is not called on rejection; only `started` admits a public turn (`admitsTurn` in `src/sdk-pi-adapter.ts`). Model-visible tools are declared on transcript system messages rather than in the provider context. `test/sdk-contract.test.ts` pins both assumptions provider-free.
5
+ - [`@earendil-works/pi-coding-agent` 1.2.0](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) supplies the documented root exports used by this server, including `ModelRuntime` and `createAgentSession`. Since 0.99 the prompt preflight hook reports a dispatch disposition (`started`, `queued`, `handled`) and is not called on rejection; only `started` admits a public turn (`admitsTurn` in `src/sdk-pi-adapter.ts`). Model-visible tools are declared on transcript system messages rather than in the provider context. `test/sdk-contract.test.ts` pins both assumptions provider-free.
6
6
  - [`@modelcontextprotocol/server` 2.3.1](https://www.npmjs.com/package/@modelcontextprotocol/server) supplies `McpServer`, structured tool output, and the stdio entry point.
7
7
  - [Zod 4.6.5](https://zod.dev/) validates strict configuration, tool input, and structured output.
8
8
 
@@ -81,9 +81,13 @@ run.
81
81
 
82
82
  npm resolves the package's transitive dependencies at install time within the
83
83
  ranges that the Pi SDK and the MCP SDK declare, because npm does not ship a
84
- lockfile inside a package. Direct dependencies are pinned exactly. If you need
85
- the exact dependency tree that the maintainers tested, install from a release
86
- tag instead.
84
+ lockfile inside a package. Direct dependencies are pinned exactly, and so are
85
+ the SDK's internal `@earendil-works` packages (`pi-ai`, `pi-mcp`, `pi-tui`,
86
+ `pi-codemode`, `pi-agent-core` and `pi-telemetry`, the last one declared by
87
+ `pi-ai`), so that the SDK's caret ranges resolve to the tested versions.
88
+ CI smoke-tests an install of the packed package without a lockfile on every
89
+ change, and a nightly job does the same for the published `latest` version. If you need the exact dependency tree that the maintainers
90
+ tested, install from a release tag instead.
87
91
 
88
92
  ### From a release tag
89
93
 
package/docs/releasing.md CHANGED
@@ -28,13 +28,29 @@ A release is distributed twice: as the GitHub release with its source archive,
28
28
  and as the npm package `pi-session-mcp`. The npm package contains the built
29
29
  files, the executables, the operator documentation and the example
30
30
  configuration. It contains no implementation plans (`docs/superpowers/`), and
31
- no lockfile, because npm does not ship lockfiles inside packages.
31
+ no lockfile, because npm does not ship lockfiles inside packages. A consumer
32
+ install therefore resolves every transitive range afresh, which is why the Pi
33
+ SDK's own packages are pinned directly (see [Update the Pi SDK](#update-the-pi-sdk)).
32
34
 
33
35
  ## Update the Pi SDK
34
36
 
35
- The Pi SDK is pinned exactly. A nightly canary
36
- (`.github/workflows/pi-sdk-canary.yml`) checks the unchanged sources against the
37
- newest published `@earendil-works/pi-coding-agent`: typecheck plus every test
37
+ The Pi SDK is pinned exactly, together with the SDK's internal
38
+ `@earendil-works` packages: `pi-ai`, `pi-mcp`, `pi-tui`, `pi-codemode` and
39
+ `pi-agent-core`, which the SDK declares, and `pi-telemetry`, which `pi-ai`
40
+ declares. They are declared with caret ranges, and npm does not ship our
41
+ lockfile inside the package, so a consumer install resolves those ranges fresh.
42
+ A newer family member can then break the pinned SDK, as in
43
+ [#78](https://github.com/plagor44-ux/pi-session-mcp/issues/78), where
44
+ `pi-codemode` 1.2.0 removed an export that `pi-coding-agent` 1.1.0 imports. We
45
+ do not import the family members; they are direct, exactly pinned dependencies
46
+ only so that a fresh install resolves the SDK's ranges to the tested versions.
47
+ The SDK and the six packages therefore always move together, each to the
48
+ version the canary resolves from the declared ranges.
49
+
50
+ A nightly canary (`.github/workflows/pi-sdk-canary.yml`) checks the unchanged
51
+ sources against the newest published `@earendil-works/pi-coding-agent` together
52
+ with the family versions that candidate declares, transitively (a package that
53
+ another member declares, such as `pi-telemetry`, is followed too): typecheck plus every test
38
54
  that touches the SDK, provider-free. It reports each incompatible version once
39
55
  in an open issue labeled `pi-sdk-canary`. A green canary is a signal that an
40
56
  update is possible. It is not an update and not an acceptance.
@@ -48,7 +64,8 @@ update is possible. It is not an update and not an acceptance.
48
64
  ```
49
65
 
50
66
  Exit status `0` means compatible, `1` incompatible, and `2` invalid input or
51
- a changed manifest.
67
+ a changed manifest. The script prints the candidate and the family versions it
68
+ resolved from the declared ranges.
52
69
 
53
70
  2. Read the upstream changelog between the pinned and the target version. It
54
71
  ships in the package as
@@ -59,23 +76,32 @@ update is possible. It is not an update and not an acceptance.
59
76
  `src/session-tools.ts`. That function is not a root export, so no test
60
77
  notices when the SDK reserves another name.
61
78
 
62
- 3. Move the pin:
79
+ 3. Move the pins, the SDK and its six family packages in one command:
63
80
 
64
81
  ```bash
65
- npm install --save-exact @earendil-works/pi-coding-agent@<version>
82
+ npm install --save-exact \
83
+ @earendil-works/pi-coding-agent@<version> @earendil-works/pi-ai@<ai> \
84
+ @earendil-works/pi-mcp@<mcp> @earendil-works/pi-tui@<tui> \
85
+ @earendil-works/pi-codemode@<codemode> @earendil-works/pi-agent-core@<core> \
86
+ @earendil-works/pi-telemetry@<telemetry>
66
87
  ```
67
88
 
68
- `package.json` must change in exactly one line and keep an exact version
69
- without a range prefix. Review the lockfile diff: only the SDK's own packages
70
- and their dependencies should move, and earlier lockfile-only patches must
71
- survive.
89
+ Use the versions the canary reported. `package.json` must change in exactly
90
+ seven lines, one per package, and keep an exact version without a range
91
+ prefix. Check with `npm ls` that exactly one copy of each family package
92
+ exists.
93
+ Review the lockfile diff: only the SDK family and their dependencies should
94
+ move, and earlier lockfile-only patches must survive.
72
95
 
73
96
  4. Update the documents that name the pinned version,
74
97
  [architecture](architecture.md) and [tool contracts](tool-contracts.md), and
75
98
  add a changelog entry. Record upstream changes that affect operators, for
76
99
  example a renamed provider key.
77
100
 
78
- 5. Run the [Level 1 checks](acceptance.md#level-1-repository-checks).
101
+ 5. Run the [Level 1 checks](acceptance.md#level-1-repository-checks). Before
102
+ the release, the packed-tarball check under
103
+ [Prepare a release](#prepare-a-release) shows whether a consumer install of
104
+ the new pins works.
79
105
 
80
106
  Three guards protect the SDK boundary. `test/sdk-contract.test.ts` pins the prompt
81
107
  dispositions, the rejection path and the exact tools declared to the model for
@@ -172,7 +198,29 @@ Steps:
172
198
  5. Run the working-tree
173
199
  [Level 2 acceptance](acceptance.md#tooling) on the release candidate with
174
200
  `scripts/setup-acceptance.mjs`, unless the release notes state its absence.
175
- 6. Record the pre-release acceptance in the status section of
201
+ 6. Run the packed-tarball Level 2 acceptance on the same candidate. Pack the
202
+ built package, install the tarball into a fresh prefix and point the harness
203
+ at the installed package:
204
+
205
+ ```bash
206
+ npm pack
207
+ PREFIX="$(mktemp -d "$HOME/.cache/pi-session-mcp-pack.XXXXXX")"
208
+ npm install -g --prefix "$PREFIX" ./pi-session-mcp-<x.y.z>.tgz
209
+ node scripts/setup-acceptance.mjs \
210
+ --setup "$PREFIX/bin/pi-session-mcp-setup" \
211
+ --build-dir "$PREFIX/lib/node_modules/pi-session-mcp" \
212
+ --label packed-<x.y.z> --out level2-result.json
213
+ rm -rf "$PREFIX" ./pi-session-mcp-<x.y.z>.tgz
214
+ ```
215
+
216
+ This is the only acceptance-level pre-release check that resolves
217
+ dependencies like a consumer: the working tree and the CI build use our
218
+ lockfile, which a published package does not carry (#78). The CI install
219
+ smoke also resolves fresh, but it is an early warning, not acceptance. Always
220
+ use a fresh prefix from `mktemp -d`, never a fixed or reused one, and never
221
+ install without `--prefix`. Remove the prefix and the tarball afterwards; the
222
+ tarball is not committed.
223
+ 7. Record the pre-release acceptance in the status section of
176
224
  [Acceptance](acceptance.md) and push it to the change pull request. Name the
177
225
  release in the pull request's title and description.
178
226
 
package/docs/roadmap.md CHANGED
@@ -12,8 +12,8 @@ mean they are implemented or that their gates passed.
12
12
 
13
13
  ## Current state
14
14
 
15
- Updated 2026-10-13. Base main `0aae6390c539e1d70138f1efaf297e6193a2b497`
16
- (the merge of Sprint 2).
15
+ Updated 2026-10-15. Base main `bdfb95de9a46defa64d2eb382d58d454f97fc8fb`
16
+ (the merge of the 0.8.2 release).
17
17
 
18
18
  - R21 (this roadmap) was delivered as documentation by
19
19
  [#58](https://github.com/plagor44-ux/pi-session-mcp/pull/58), which closed
@@ -39,17 +39,30 @@ Updated 2026-10-13. Base main `0aae6390c539e1d70138f1efaf297e6193a2b497`
39
39
  ([#74](https://github.com/plagor44-ux/pi-session-mcp/issues/74)). R10 and R11
40
40
  are blocked on the work Mac, with a runbook. See the
41
41
  [Sprint 3 file](sprints/2026-10-13-s3-live-usage.md).
42
- - Release 0.8.2 is prepared in its own pull request: it carries #59, #56, #60
43
- and the #62 skill change to npm under an unchanged MCP contract. Merge, tag
44
- and publication are maintainer decisions.
42
+ - Release 0.8.2 was merged in [#76](https://github.com/plagor44-ux/pi-session-mcp/pull/76)
43
+ and published on 2026-10-14. It carries #59, #56, #60 and the #62 skill
44
+ change under an unchanged MCP contract. Its published-release acceptance on
45
+ 2026-10-15 found that a fresh npm install crashes at startup
46
+ ([#78](https://github.com/plagor44-ux/pi-session-mcp/issues/78)); the fix
47
+ ships as 0.8.3.
45
48
  - Sprint 4 decision inputs for the conditional items R12, R15, R17 and R18 are recorded in the [Sprint 4 decision inputs](sprints/2026-10-13-s4-decision-inputs.md) ([#72](https://github.com/plagor44-ux/pi-session-mcp/issues/72)): R12, R15 and R17 not met, R18 not determinable as of 2026-10-13; this is input, not the Sprint 4 decision.
49
+ - Sprint 4 is closed with its [decision](sprints/2026-10-15-s4-decision.md)
50
+ ([#77](https://github.com/plagor44-ux/pi-session-mcp/issues/77)), taken on
51
+ 2026-10-15 before the macOS gate by maintainer decision. ADR 0003's isolation
52
+ trigger fired, because coding profiles had written on non-disposable
53
+ repositories. The one next investment is the isolation decision
54
+ ([#79](https://github.com/plagor44-ux/pi-session-mcp/issues/79), ADR 0008
55
+ Proposed), with interim operating rules until it is accepted. R12, R15 and
56
+ R17 stay deferred (not met), R18 stays deferred (not determinable), and
57
+ [#74](https://github.com/plagor44-ux/pi-session-mcp/issues/74) is closed as
58
+ not planned. R10, R11 and R22 stay open.
46
59
 
47
60
  ### Sprint 3 task status
48
61
 
49
62
  | Task | Issue | Status |
50
63
  | --- | --- | --- |
51
64
  | Harness tests time out on macOS | [#70](https://github.com/plagor44-ux/pi-session-mcp/issues/70) | verified: CI green on macOS 15 and 26, also on main |
52
- | R08 three sessions with a read-only reviewer | [#71](https://github.com/plagor44-ux/pi-session-mcp/issues/71) | partially verified: Codex passed, Claude Code failed on timing only; follow-up [#74](https://github.com/plagor44-ux/pi-session-mcp/issues/74) |
65
+ | R08 three sessions with a read-only reviewer | [#71](https://github.com/plagor44-ux/pi-session-mcp/issues/71) | partially verified: Codex passed, Claude Code failed on timing only; follow-up [#74](https://github.com/plagor44-ux/pi-session-mcp/issues/74) closed as not planned in Sprint 4 |
53
66
  | R05 / R09 ten-task Level 3 cycle | None (acceptance) | verified: accepted, 10 of 10 tasks |
54
67
  | R06 new Codex abort run | None (acceptance) | verified |
55
68
  | R07 Codex discovery of the setup-installed skill | None (acceptance) | verified |
@@ -58,8 +71,8 @@ Updated 2026-10-13. Base main `0aae6390c539e1d70138f1efaf297e6193a2b497`
58
71
 
59
72
  Status words: planned, in progress, implemented (code exists), verified (named
60
73
  criteria met with evidence), blocked, failed (ran and missed its criteria; kept
61
- on record). Sprint 3 is closed; Sprint 4 decides the next investment
62
- from the evidence of Sprints 1 to 3 and the decision inputs.
74
+ on record). Sprints 1 to 4 are closed; the next investment is the isolation
75
+ decision in [#79](https://github.com/plagor44-ux/pi-session-mcp/issues/79).
63
76
 
64
77
  ## Sprints and exit gates
65
78
 
@@ -111,7 +124,7 @@ in-memory state and one trusted local peer.
111
124
 
112
125
  | Topic | Entry condition |
113
126
  | --- | --- |
114
- | OS isolation | Decide before coding on non-disposable repositories or with untrusted content; profiles/skills are not an OS sandbox |
127
+ | OS isolation | Trigger fired on 2026-10-15 (coding profiles wrote on non-disposable repositories); decision in [#79](https://github.com/plagor44-ux/pi-session-mcp/issues/79) and ADR 0008, interim rules in the [Sprint 4 decision](sprints/2026-10-15-s4-decision.md#interim-operating-rules); profiles/skills are not an OS sandbox |
115
128
  | pi_turn_wait | Measured high polling cost per turn with pauses or tool/approval cost; 5–7 polls per invocation is insufficient evidence |
116
129
  | Persistence/resume | Actual loss of useful work on restart |
117
130
  | HTTP/remote/mobile | Concrete need existing SSH/remote development cannot meet; separate ADR/security decision |
@@ -121,7 +134,7 @@ in-memory state and one trusted local peer.
121
134
  | Former pi-control #31/#32 | Closed as not_planned; no automatic migration/reopening |
122
135
  | Former release gates/#11–#14 | Historical; bind current acceptance to the current build |
123
136
 
124
- 0.8.2 is a possible patch candidate only if the MCP contract remains
125
- unchanged and its gates pass. Sprint 1 changed no version. Apply the current [release procedure](releasing.md):
126
- version and pre-release acceptance travel in the change PR. Merge, tagging and
137
+ 0.8.3 is a patch release only if the MCP contract remains unchanged and its
138
+ gates pass. Apply the current [release procedure](releasing.md): version and
139
+ pre-release acceptance travel in the change PR. Merge, tagging and
127
140
  publication remain maintainer decisions. No release is authorized by this plan.
@@ -0,0 +1,185 @@
1
+ # Sprint 4: next-investment decision
2
+
3
+ Date: 2026-10-15. Base: main `bdfb95de9a46defa64d2eb382d58d454f97fc8fb` (the
4
+ merge of the 0.8.2 release pull request). Tracking:
5
+ [#77](https://github.com/plagor44-ux/pi-session-mcp/issues/77). Planning
6
+ sources: the [roadmap](../roadmap.md), the
7
+ [post-0.8.1 audit](../reviews/2026-10-13-post-0.8.1-audit.md#sprint-4-decide-the-next-investment-from-usage)
8
+ and the [Sprint 4 decision inputs](2026-10-13-s4-decision-inputs.md).
9
+
10
+ Exit gate from the audit: a documented decision, at most one next investment,
11
+ a focused issue, and an appropriate ADR for scope or contract changes. No
12
+ feature implementation without a separate justified decision.
13
+
14
+ ## Decision
15
+
16
+ | Topic | Decision |
17
+ | --- | --- |
18
+ | Next investment | One: decide isolation for coding profiles on non-disposable repositories, as an options comparison in ADR 0008 (Proposed), tracked in [#79](https://github.com/plagor44-ux/pi-session-mcp/issues/79). No runtime change before ADR 0008 is accepted. |
19
+ | ADR 0003 | Trigger E fired on 2026-10-15; [ADR 0003](../adr/0003-post-mvp-maintenance.md#revisit-triggers) records it, as it already does for the B-type trigger. Candidates C, D and F stay rejected with their revisit triggers. |
20
+ | Interim operation | The maintainer keeps the operating rules below until ADR 0008 is accepted, with the residual risks stated there. |
21
+ | Maintenance | Continues. The fresh-install defect found during this sprint ([#78](https://github.com/plagor44-ux/pi-session-mcp/issues/78)) is maintenance, not the investment, and ships as patch 0.8.3. |
22
+ | R12, R15, R17 | Not met; stay deferred with their entry conditions. |
23
+ | R18 | Not determinable; stays deferred unless the maintainer decides to harden publication independently. |
24
+ | [#74](https://github.com/plagor44-ux/pi-session-mcp/issues/74) | Closed as not planned (maintainer decision). The strict neighbor criterion stays; the `trio` timing with Claude Code as controller remains "not established". Reopen when a usage claim needs it. |
25
+ | R10, R11, R22 | Open, blocked on operator actions (work Mac; ChatGPT project instructions). Nothing here claims macOS acceptance. |
26
+
27
+ The maintainer decided on 2026-10-15 to run this evaluation before the
28
+ current macOS acceptance (R10, R11), although the audit's dependency graph
29
+ places that acceptance before Sprint 4. The macOS gate affects platform
30
+ claims, not which investment comes next; it stays open.
31
+
32
+ ## Usage evidence from Sprint 3
33
+
34
+ Sources: [Sprint 3](2026-10-13-s3-live-usage.md) and
35
+ [Acceptance](../acceptance.md#sprint-3-live-acceptance-2026-10-13).
36
+
37
+ - The ten-task Level 3 cycle was accepted 10 of 10 with Claude Code `2.1.296`
38
+ and Codex CLI `0.162.1` on Linux `x64`, in six strictly sequential
39
+ invocations of 56–94 s each. The worker profiles were copies (`l3-read`,
40
+ `l3-code`) of `explore-fast` and `code-deepseek`, without the operator
41
+ profiles' external MCP grant. No change fell outside the approved diff, and
42
+ no session or process remained.
43
+ - R06 (Codex abort, 100 s) and R07 (Codex discovery of the setup-installed
44
+ skill) passed. R08 `trio` passed for Codex (102 s); Claude Code (118 s)
45
+ failed only `neighborsNotRunningDuringAbort`, a timing outcome of the
46
+ scenario design (#74).
47
+ - Polling: in Level 3, every turn was seen `running` in at most one
48
+ `pi_turn_get` poll, and both clients slept between polls. This counts polls
49
+ that saw a running turn, not `pi_turn_get` calls per turn; R06 and R08
50
+ record no poll counts. ADR 0003's baseline is 1–3 calls per turn.
51
+ - Restarts: Sprint 3 records no restart result, and Level 3 excludes restart
52
+ and resume. No record reports useful work lost to a restart.
53
+ - All recorded coding ran on synthetic fixtures; the `review` fixture of
54
+ `trio` is a frozen read-only fixture.
55
+ - Not established: macOS, other providers and models, the operator profiles'
56
+ external MCP grant, larger tasks, more than three concurrent sessions, and
57
+ the `trio` timing with Claude Code as controller.
58
+
59
+ ## New facts on 2026-10-15
60
+
61
+ - The maintainer confirmed that coding profiles have already written on
62
+ non-disposable repositories through configured workspace aliases (real
63
+ repositories and their worktrees). No incident is known: no unintended
64
+ change, push or write outside a workspace has been reported, but the use was
65
+ not audited systematically. Profiles, poll counts and restarts of that use
66
+ were not recorded, so it is not usage evidence in the sense of the
67
+ acceptance records.
68
+ - The published-release acceptance of v0.8.2 found that a fresh
69
+ `npm install -g pi-session-mcp@0.8.2` installs a server that exits at
70
+ startup ([#78](https://github.com/plagor44-ux/pi-session-mcp/issues/78);
71
+ evidence in [Acceptance](../acceptance.md#v082-post-release-evidence)). The
72
+ pinned Pi SDK `1.1.0` declares its sibling `@earendil-works/pi-codemode` with
73
+ a caret range, `pi-codemode` `1.2.0` removed an export the SDK imports, and
74
+ installed packages do not get this repository's lockfile. CI, the canary and
75
+ the pre-release acceptance all install from the lockfile, so none of them
76
+ saw it.
77
+
78
+ ## Revisit triggers of ADR 0003
79
+
80
+ | Candidate | ADR 0003 status | Trigger | Assessment |
81
+ | --- | --- | --- | --- |
82
+ | C: bounded turn waiting | Rejected | Routinely more than about five polls per turn, or costly client tool-call limits or approval prompts | Not evidenced in recorded use: Level 3 saw a running turn in at most one poll; the real-repository use was not measured |
83
+ | D: persistence and resume | Rejected | Useful work lost to a restart in practice | Not evidenced: no record and no report of lost work; restarts were not part of the recorded runs |
84
+ | E: isolation | Deferred | Coding profiles on non-disposable repositories or with untrusted content, at the latest before a local writer runs on real repositories | **Fired** on 2026-10-15 (maintainer confirmation above) |
85
+ | F: remote transport | Rejected | A concrete remote or mobile case that SSH or remote development cannot meet | Not fired: no such case |
86
+ | B-type work | Delivered | Repeated setup or diagnosis friction beyond version drift | Fired earlier for the client-version allowlist (ADR 0004); no new repeated friction recorded |
87
+
88
+ The audit's guidance applies: if real writing is next, isolation is the first
89
+ architecture question. Real writing is not next; it has already happened.
90
+
91
+ ## The next investment: decide isolation
92
+
93
+ [#79](https://github.com/plagor44-ux/pi-session-mcp/issues/79) authorizes a
94
+ decision, not an implementation. Sprint 4 decides that isolation is next, not
95
+ how. ADR 0008 (Proposed) must compare at least:
96
+
97
+ 1. operator-environment containment with no server change (separate OS user,
98
+ container or VM per writer, separate clone);
99
+ 2. whole-process self-restriction of the server on Linux, and the macOS
100
+ equivalent or gap;
101
+ 3. moving Pi out of process per session, which would amend ADR 0002.
102
+
103
+ Two facts constrain the options. `edit` and `write` run inside the server
104
+ process and only `bash` runs as a child process, so confining `bash` alone
105
+ would give false assurance. One server process serves every session of a
106
+ client, so whole-process confinement can only allow the union of all
107
+ workspaces plus Pi's agent directory and the provider network. The ADR also
108
+ names the threats each option addresses: model error, prompt injection from
109
+ repository content or `AGENTS.md`, and trusted extension code. Filesystem
110
+ confinement does nothing against extension code or exfiltration through the
111
+ provider. Its acceptance is a synthetic isolated-write test that covers
112
+ `edit` and `write` as well as `bash`.
113
+
114
+ The strongest argument against expansion remains the security and
115
+ maintenance surface it adds to a deliberately small local server; option 1
116
+ keeps that surface unchanged.
117
+
118
+ ## Interim operating rules
119
+
120
+ Maintainer decision on 2026-10-15: until ADR 0008 is accepted, coding
121
+ profiles keep running on non-disposable repositories under these rules. They
122
+ are operator practice; the server enforces none of them.
123
+
124
+ - Coding profiles only on dedicated worktrees of trusted repositories, one
125
+ writer per alias; never on untrusted content.
126
+ - Skill catalog and override directories outside every workspace.
127
+ - Every worker diff is reviewed before it leaves the worktree.
128
+ - Cursor-backed profiles only where a write would be uncritical.
129
+
130
+ These rules limit the damage of mistakes. They do not contain a misbehaving
131
+ worker. Accepted residual risks, as the two reviews of this decision named
132
+ them:
133
+
134
+ - A Git worktree is not a boundary: it shares configuration, hooks, refs and
135
+ objects with its main repository, so a change to `.git/hooks` or
136
+ `.git/config` can run code in the operator's later Git commands.
137
+ - `bash` runs with the server's OS identity, network access and inherited
138
+ credentials, so a worker can commit, push, or call `gh` and `ssh` before any
139
+ diff review.
140
+ - Files outside the workspace stay reachable, among them the Pi Session MCP
141
+ configuration file, client configurations, the installed controller skills,
142
+ shell start-up files, user cron and service units, `~/.ssh` and any other
143
+ credential readable by the OS identity; `read` is not path-confined in
144
+ `read-only` profiles either.
145
+ - The Cursor runtime starts processes of its own (`git`, `ssh`, `gh`, its MCP
146
+ servers), also in `read-only` profiles, and can write below `~/.pi/agent`,
147
+ `~/.cursor/projects/` and `<workspace>/.pi/`.
148
+ - External MCP grants of the operator profiles were not covered by acceptance.
149
+ - No decision date is set for ADR 0008, so the interim period is open-ended.
150
+
151
+ ## Conditional items, re-checked on 2026-10-15
152
+
153
+ | Item | Facts | Assessment |
154
+ | --- | --- | --- |
155
+ | R17 scheduled advisory check | `npm audit` and `npm audit --omit=dev` at `bdfb95d`: 0 vulnerabilities (331 dependencies). Dependabot alerts enabled, 0 open; no `.github/dependabot.yml` | Not met |
156
+ | R18 provenance | None of 0.6.1–0.8.2 carries an attestation. 1,284 downloads in the npm window 2026-09-13 to 2026-10-12 (daily from 2026-10-07: 59, 15, 150, 349, 342, 369). One star, no forks or watchers; 14-day traffic 1,116 clones (308 unique) and 54 views (4 unique). Of 47 issues only #28 and #29 come from another account; all 29 pull requests from the maintainer | Not determinable: the counts cannot separate external users from mirrors, automation and the maintainer's own installations |
157
+ | R12 real crash, contention, signal runs | No report of an interrupted real skill update, a customization conflict or a signal-ended analysis | Not met |
158
+ | R15 unreadable start time | No Sprint 3 live run failed with `noServerObserved` | Not met |
159
+
160
+ #78 is not drift in the sense of R17: `npm audit` reports advisories, not
161
+ broken resolutions. Its detection, a lockfile-free install smoke in CI and
162
+ nightly, belongs to #78.
163
+
164
+ ## Reviews of this decision
165
+
166
+ The draft was reviewed on 2026-10-15 by an independent advisor (Claude Opus
167
+ 5.5) and by a read-only Pi worker of another model family (`review-grok`,
168
+ xAI `grok-4.7`). Their corrections are applied above: C, D and F are rejected
169
+ in ADR 0003, not deferred; the B-type trigger fired before; Level 3 used
170
+ profile copies; the polling observation counts running sightings, not calls;
171
+ the investment is a decision with option 1 included, not a predetermined
172
+ OS-isolation build; ADR 0003 is annotated instead of a separate Sprint 4 ADR.
173
+ The reviewers also recommended stricter interim rules; the maintainer kept
174
+ the rules above and the residual risks are recorded instead.
175
+
176
+ ## Sources and checks
177
+
178
+ - Sprint 3 records, Acceptance, ADRs 0002–0004, the threat model and
179
+ `src/session-tools.ts`, read on 2026-10-15.
180
+ - `npm audit` and `npm audit --omit=dev` at `bdfb95d`; the npm registry
181
+ metadata of `pi-session-mcp`; the npm download API; the GitHub API for
182
+ repository statistics, traffic, Dependabot alerts and authorship; all
183
+ read-only, 2026-10-15 (15:36 UTC).
184
+ - The published-release acceptance of v0.8.2 and the reproduction of #78,
185
+ recorded in [Acceptance](../acceptance.md#v082-post-release-evidence).
@@ -40,7 +40,7 @@ records name the package version and the build they ran on, see
40
40
  ```json
41
41
  {
42
42
  "ok": true,
43
- "server": { "name": "pi-session-mcp", "version": "0.8.2" },
43
+ "server": { "name": "pi-session-mcp", "version": "0.8.3" },
44
44
  "configuration": {
45
45
  "fingerprint": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
46
46
  "reloadPolicy": "restart-required"
@@ -126,7 +126,7 @@ none of the eight public tools or their fields, states and error codes; see the
126
126
  bounded projection policy in [session-mcp.md](session-mcp.md). If the turn itself
127
127
  fails, the public result still contains only `turn_failed` / `Pi turn failed`.
128
128
 
129
- `turn_failed` remains the only terminal failure projection. The characterization was made against `@earendil-works/pi-coding-agent` 0.84.4, which exposes no closed, structured terminal cause discriminator; its provider-free tests keep their assertions on the pinned 1.0.4, whose public `AssistantMessage` type still carries only the stop reason plus free-form `errorMessage`, `rawStopReason`, and open-typed `diagnostics`, and Pi Session MCP uses no such discriminator: it normalizes the final assistant outcome by its stop reason (`src/sdk-pi-adapter.ts:106-130`, see *Final stop reasons* below) and the registry projects `turn_failed` for every outcome that is neither `completed` nor `aborted` (`src/session-registry.ts:242-243`). Retry and compaction events can describe an interim error that later recovers. Assistant `errorMessage`, `rawStopReason`, and `diagnostics` are free-form and may contain sensitive provider text; they cannot reliably identify the underlying terminal cause.
129
+ `turn_failed` remains the only terminal failure projection. The characterization was made against `@earendil-works/pi-coding-agent` 0.84.4, which exposes no closed, structured terminal cause discriminator; its provider-free tests keep their assertions on the pinned 1.2.0, whose public `AssistantMessage` type still carries only the stop reason plus free-form `errorMessage`, `rawStopReason`, and open-typed `diagnostics`, and Pi Session MCP uses no such discriminator: it normalizes the final assistant outcome by its stop reason (`src/sdk-pi-adapter.ts:106-130`, see *Final stop reasons* below) and the registry projects `turn_failed` for every outcome that is neither `completed` nor `aborted` (`src/session-registry.ts:242-243`). Retry and compaction events can describe an interim error that later recovers. Assistant `errorMessage`, `rawStopReason`, and `diagnostics` are free-form and may contain sensitive provider text; they cannot reliably identify the underlying terminal cause.
130
130
 
131
131
  This change therefore adds no runtime classification: no code is derived from `errorMessage`, `rawStopReason`, diagnostics, context size, or event order, and no provider text, diagnostics, or context figure is projected. In particular `turn_context_exceeded` is not added; an observed pattern (a long same-session turn fails, a fresh narrow session succeeds) stays a hypothesis that the public surface cannot confirm.
132
132
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-session-mcp",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "description": "Local stdio MCP server for controlled Pi coding-agent sessions",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -54,7 +54,13 @@
54
54
  "prepack": "npm run build && npm run build:cli"
55
55
  },
56
56
  "dependencies": {
57
- "@earendil-works/pi-coding-agent": "1.1.0",
57
+ "@earendil-works/pi-agent-core": "1.2.0",
58
+ "@earendil-works/pi-ai": "1.2.0",
59
+ "@earendil-works/pi-codemode": "1.2.0",
60
+ "@earendil-works/pi-coding-agent": "1.2.0",
61
+ "@earendil-works/pi-mcp": "1.2.0",
62
+ "@earendil-works/pi-telemetry": "1.2.0",
63
+ "@earendil-works/pi-tui": "1.2.0",
58
64
  "@modelcontextprotocol/client": "2.3.1",
59
65
  "@modelcontextprotocol/server": "2.3.1",
60
66
  "zod": "4.6.5"