pi-session-mcp 0.8.0 → 0.8.2
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/.pi-session-mcp-cli/doctor.js +14 -7
- package/.pi-session-mcp-cli/override-lock.js +125 -0
- package/.pi-session-mcp-cli/setup-platform.js +195 -0
- package/.pi-session-mcp-cli/skill-customize.js +131 -46
- package/.pi-session-mcp-cli/skill-library.js +72 -4
- package/CHANGELOG.md +159 -0
- package/CONTRIBUTING.md +5 -3
- package/README.md +5 -3
- package/dist/doctor.d.ts +3 -0
- package/dist/doctor.js +14 -7
- package/dist/override-lock.d.ts +34 -0
- package/dist/override-lock.js +125 -0
- package/dist/pi-adapter.d.ts +6 -4
- package/dist/sdk-pi-adapter.js +28 -5
- package/dist/session-registry.d.ts +8 -6
- package/dist/session-registry.js +3 -2
- package/dist/setup-ownership.d.ts +4 -1
- package/dist/setup-ownership.js +6 -3
- package/dist/setup-skills.d.ts +46 -1
- package/dist/setup-skills.js +349 -78
- package/dist/setup.js +21 -4
- package/dist/skill-customize.d.ts +19 -1
- package/dist/skill-customize.js +131 -46
- package/dist/skill-library.d.ts +46 -1
- package/dist/skill-library.js +72 -4
- package/docs/acceptance.md +747 -26
- package/docs/adr/0007-profile-skill-selection.md +11 -0
- package/docs/architecture.md +1 -1
- package/docs/client-setup-design.md +157 -24
- package/docs/client-setup.md +38 -7
- package/docs/doctor-design.md +1 -1
- package/docs/installation.md +8 -2
- package/docs/pi-extensions-design.md +11 -0
- package/docs/releasing.md +25 -10
- package/docs/reviews/2026-10-13-post-0.8.1-audit.md +393 -0
- package/docs/roadmap.md +127 -0
- package/docs/skills.md +173 -16
- package/docs/sprints/2026-10-13-s1-correctness.md +355 -0
- package/docs/sprints/2026-10-13-s2-evidence.md +431 -0
- package/docs/sprints/2026-10-13-s3-live-usage.md +267 -0
- package/docs/sprints/2026-10-13-s4-decision-inputs.md +241 -0
- package/docs/threat-model.md +3 -3
- package/docs/tool-contracts.md +20 -2
- package/package.json +1 -1
- package/skills/pi-session-orchestration/SKILL.md +8 -4
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Sprint 3: live usage acceptance
|
|
2
|
+
|
|
3
|
+
Base: main `0aae6390c539e1d70138f1efaf297e6193a2b497` (the merge of Sprint 2,
|
|
4
|
+
[#69](https://github.com/plagor44-ux/pi-session-mcp/pull/69)). Date: 2026-10-13.
|
|
5
|
+
Planning sources: the [roadmap](../roadmap.md) and the
|
|
6
|
+
[post-0.8.1 audit](../reviews/2026-10-13-post-0.8.1-audit.md) (R05–R11 and the
|
|
7
|
+
Sprint 3 exit gate).
|
|
8
|
+
|
|
9
|
+
This file tracks Sprint 3. A status of `implemented` or `verified` is set only
|
|
10
|
+
together with evidence below.
|
|
11
|
+
|
|
12
|
+
## Scope and maintainer decisions
|
|
13
|
+
|
|
14
|
+
Decided by the maintainer on 2026-10-13:
|
|
15
|
+
|
|
16
|
+
- The Pi profiles actually intended for use (R09) are `explore-fast`
|
|
17
|
+
(read-only; OpenAI `gpt-6-luna`, thinking `low`) and `code-deepseek`
|
|
18
|
+
(coding; DeepSeek `deepseek-flash`, thinking `high`). Results cover this
|
|
19
|
+
pair only.
|
|
20
|
+
- All Linux items run now, each once: R05 (ten-task Level 3 cycle, both
|
|
21
|
+
controllers), R06 (a new Codex abort run), R07 (Codex home-skill discovery)
|
|
22
|
+
and R08 (three concurrent sessions with a read-only reviewer). Failures stay
|
|
23
|
+
on record.
|
|
24
|
+
- A 0.8.2 patch release follows the live runs in its own pull request. Merge,
|
|
25
|
+
tag and publication remain maintainer decisions.
|
|
26
|
+
- R10 and R11 need the work Mac, which is not reachable from the Linux
|
|
27
|
+
workstation; they are blocked, and the [runbook](#appendix-macos-runbook-r10-r11)
|
|
28
|
+
below describes the light check to run there.
|
|
29
|
+
|
|
30
|
+
Out of scope: new runtime features, dependency or Pi SDK updates, MCP contract
|
|
31
|
+
changes, Sprint 4 decisions.
|
|
32
|
+
|
|
33
|
+
The live runs use a separate detached, built checkout of the release under
|
|
34
|
+
test at the base commit: `dist/main.js` SHA-256
|
|
35
|
+
`47875d38886528ace6b242df2c6ad79d624c51e330e63c2f401576eadc449ed7`, `dist`
|
|
36
|
+
JavaScript tree SHA-256
|
|
37
|
+
`f85bf73ee8c0ddb2270d8d6040feffbc49f018d2e6ab6253fffb828654a389df`. Live runs
|
|
38
|
+
are strictly sequential: one controller invocation at a time.
|
|
39
|
+
|
|
40
|
+
## Status legend
|
|
41
|
+
|
|
42
|
+
planned, in_progress, implemented (code or tooling exists), verified (the named
|
|
43
|
+
criteria are met with evidence), blocked (a named blocker), failed (the run
|
|
44
|
+
happened and did not meet its criteria; it stays on record).
|
|
45
|
+
|
|
46
|
+
## Tasks
|
|
47
|
+
|
|
48
|
+
| Task | Issue | How | Status |
|
|
49
|
+
| --- | --- | --- | --- |
|
|
50
|
+
| Harness tests time out on macOS (main CI after #69) | [#70](https://github.com/plagor44-ux/pi-session-mcp/issues/70) | One fixture build per case | implemented; the pull request CI on macOS decides |
|
|
51
|
+
| R08 three sessions with a read-only reviewer | [#71](https://github.com/plagor44-ux/pi-session-mcp/issues/71) | `trio` scenario of the multi-session harness, then one live run per controller | partially verified: Codex passed; Claude Code failed on timing only ([#74](https://github.com/plagor44-ux/pi-session-mcp/issues/74)) |
|
|
52
|
+
| R05 / R09 ten-task Level 3 cycle | None (acceptance) | Private per-cycle driver, as [acceptance](../acceptance.md#level-3-live-two-client-acceptance) prescribes; pre-registered | verified (10/10, all gate conditions) |
|
|
53
|
+
| R06 new Codex abort run | None (acceptance) | Multi-session harness at the base commit, `abort` scenario, Codex | verified |
|
|
54
|
+
| R07 Codex discovery of the setup-installed skill | None (acceptance) | One real Codex run in an isolated home | verified |
|
|
55
|
+
| R10 / R11 current macOS Level 2 and smoke | None | Runbook below | blocked (work Mac not reachable) |
|
|
56
|
+
|
|
57
|
+
## Main CI on the Sprint 2 merge
|
|
58
|
+
|
|
59
|
+
The main CI run [38442206975](https://github.com/plagor44-ux/pi-session-mcp/actions/runs/38442206975)
|
|
60
|
+
on `0aae639` failed on `macos-15` only: one harness test timed out after
|
|
61
|
+
5684 ms against the default 5000 ms. The merge tree equals the pull-request
|
|
62
|
+
head `fb40f99`, whose CI passed on all platforms, and the test needs under
|
|
63
|
+
0.6 s on Linux. The cause is a test design defect (four fixture builds inside
|
|
64
|
+
one test), tracked as #70 and fixed in this sprint without raising a timeout.
|
|
65
|
+
The failed run stays on record; no manual re-run was started.
|
|
66
|
+
|
|
67
|
+
## Evidence
|
|
68
|
+
|
|
69
|
+
### R07: Codex home-skill discovery
|
|
70
|
+
|
|
71
|
+
Private check script, pre-registered by its SHA-256
|
|
72
|
+
`018fddbd28f699998cba23ec902f98d68951851052aa62209236fea5d5a9e7d2` before the
|
|
73
|
+
run. Codex CLI `0.162.1`, Linux.
|
|
74
|
+
|
|
75
|
+
- The candidate's `pi-session-mcp-setup --apply --target codex:user:pi-session-mcp`
|
|
76
|
+
ran with a disposable `HOME` and `CODEX_HOME`: exit 0, `skill_installed`; the
|
|
77
|
+
installed copy is a regular directory, equal to the candidate's skill; no
|
|
78
|
+
link exists in the project.
|
|
79
|
+
- One real `codex exec` (`--ignore-user-config`, `--sandbox read-only`, the
|
|
80
|
+
disposable `HOME`, the operator's `CODEX_HOME` only for authentication) in a
|
|
81
|
+
project that is its own git root reported the skill as available, named the
|
|
82
|
+
installed copy's `SKILL.md` as its path, and quoted verbatim a line that
|
|
83
|
+
exists only in the revision under test (#62), not in the 0.8.1 copy.
|
|
84
|
+
- The operator's own `~/.agents/skills` was unchanged; the disposable
|
|
85
|
+
directory was removed.
|
|
86
|
+
|
|
87
|
+
Limit: the path is the model's report. It matches the installed copy, and the
|
|
88
|
+
quoted line proves that the current revision was read; it is no proof of
|
|
89
|
+
Codex's internal precedence between several skill sources.
|
|
90
|
+
|
|
91
|
+
### Level 3 pre-registration
|
|
92
|
+
|
|
93
|
+
Recorded before the first Level 3 task. Both prepared runs (Claude Code with the
|
|
94
|
+
operator home, Codex with a disposable home on a non-temporary disk outside the
|
|
95
|
+
operator home) share one pre-registration content digest over the prompts,
|
|
96
|
+
tasks, tools, oracles, allowed files, the coding barrier, the profiles
|
|
97
|
+
(permission, provider, model, thinking) and the fixture digests:
|
|
98
|
+
`8645f3a4d4f700180473bbe9b4280c565bebf4e49e185685e2c0f712dd856cf5`. The private
|
|
99
|
+
per-cycle driver has SHA-256 `c160a9e54885dc6d706b7e922b2d117fb98fc3ae2fe1a81ae56f68f87adccdaf`.
|
|
100
|
+
|
|
101
|
+
The worker profiles copy provider, model, thinking level and permission of the
|
|
102
|
+
intended `explore-fast` and `code-deepseek`. Both operator profiles also grant a
|
|
103
|
+
read-only external MCP tool (`codegraph_explore`); the acceptance tooling never
|
|
104
|
+
copies MCP servers, and Level 3 does not cover external MCP grants, so the runs
|
|
105
|
+
use the profiles without it. The disposable Codex home is a conservative
|
|
106
|
+
isolation choice: the operator home holds no `pi-session-orchestration` copy in
|
|
107
|
+
`~/.agents/skills`.
|
|
108
|
+
|
|
109
|
+
### R06: new Codex abort run
|
|
110
|
+
|
|
111
|
+
`scripts/multi-session-acceptance.mjs` at the base commit (harness SHA-256
|
|
112
|
+
prefix `7c43cc8a`), `prepare --from-profile code-deepseek` (DeepSeek
|
|
113
|
+
`deepseek-flash`, thinking `high`), then one `run --client codex --scenario
|
|
114
|
+
abort`, with a disposable home and the operator's `CODEX_HOME` and Pi agent
|
|
115
|
+
directory passed explicitly. Codex CLI `0.162.1`, Node.js `26.11.1`, Linux
|
|
116
|
+
x64. Started 2026-10-13 19:30 UTC, 100 s.
|
|
117
|
+
|
|
118
|
+
- `acceptance.passed: true`, no failure code. The `wait` turn ended `aborted`,
|
|
119
|
+
the `range` turn `completed` with its tests passing, and both fixtures
|
|
120
|
+
changed only allowed files: the strict scope oracle (`range:changes`) that
|
|
121
|
+
failed the v0.8.1 Codex abort run passed unchanged.
|
|
122
|
+
- Both sessions closed, no residual process, no bound resource changed or
|
|
123
|
+
unbound, no structural leak, the handshake token appeared nowhere.
|
|
124
|
+
- The sanitized evidence record contains no path.
|
|
125
|
+
|
|
126
|
+
### R05 / R09: ten-task Level 3 cycle
|
|
127
|
+
|
|
128
|
+
Private per-cycle driver (SHA-256 prefix `c160a9e5`), pre-registered as
|
|
129
|
+
recorded above. Candidate: detached checkout of `0aae639`, clean, package
|
|
130
|
+
`0.8.1`, `dist/main.js` SHA-256 `47875d38…`. Clients Claude Code `2.1.296`
|
|
131
|
+
and Codex CLI `0.162.1`; Node.js `26.11.1`; Linux x64. Worker profiles
|
|
132
|
+
`l3-read` (OpenAI `gpt-6-luna`, `low`, read-only) and `l3-code` (DeepSeek
|
|
133
|
+
`deepseek-flash`, `high`, coding). Claude Code ran with the operator home,
|
|
134
|
+
Codex with a disposable home; both runs share the pre-registration digest
|
|
135
|
+
`8645f3a4…`.
|
|
136
|
+
|
|
137
|
+
- Preflight: both profiles answered PONG through the candidate server and
|
|
138
|
+
closed; the server exited with empty stderr.
|
|
139
|
+
- Six invocations, strictly sequential, 19:33–19:40 UTC (56–94 s each):
|
|
140
|
+
|
|
141
|
+
| Client | Read-only analysis | Read-only follow-up | Coding change | Coding follow-up | Abort and recovery |
|
|
142
|
+
| --- | --- | --- | --- | --- | --- |
|
|
143
|
+
| Claude Code | intended | intended | intended | intended | intended |
|
|
144
|
+
| Codex | intended | intended | intended | intended | intended |
|
|
145
|
+
|
|
146
|
+
- Verdict: accepted, 10 of 10 tasks, and all 16 gate conditions true: both
|
|
147
|
+
clients complete discovery, start, prompt, result and close; a useful
|
|
148
|
+
second turn; a bounded, independently verified coding workflow (barrier
|
|
149
|
+
snapshots taken after each coding turn and before the next prompt, fixture
|
|
150
|
+
tests and hidden business checks on the snapshots, only the allowed files
|
|
151
|
+
changed); no change outside the approved diff; no public leak; no session or
|
|
152
|
+
process left after a verified close; stable, sanitized lifecycle errors;
|
|
153
|
+
bound resources unchanged and complete; Level 1 green for the release source
|
|
154
|
+
(native Linux on `0aae639`: typecheck, strict `npm test` with 54 files, 1300
|
|
155
|
+
passed and 6 skipped, `npm audit` 0).
|
|
156
|
+
- The coding barrier worked for both clients, including inside Codex's
|
|
157
|
+
read-only sandbox.
|
|
158
|
+
- Liveness and polling: every turn was seen `running` in at most one
|
|
159
|
+
`pi_turn_get` poll, and whenever it was, `updatedAt` had advanced past
|
|
160
|
+
`startedAt`. Both clients waited between polls with `sleep`. This is no
|
|
161
|
+
evidence for the bounded-wait revisit trigger of ADR 0003.
|
|
162
|
+
|
|
163
|
+
Limits: one cycle, one provider pair, Linux only. The worker profiles do not
|
|
164
|
+
include the operator profiles' read-only `codegraph_explore` MCP grant. The
|
|
165
|
+
ten tasks are deliberately small and qualify the control path, not model
|
|
166
|
+
capability on larger work. No live run failed with `noServerObserved`, so this
|
|
167
|
+
sprint adds no input for R15.
|
|
168
|
+
|
|
169
|
+
### R08: three concurrent sessions with a read-only reviewer
|
|
170
|
+
|
|
171
|
+
`scripts/multi-session-acceptance.mjs` of this sprint's branch at `63d5ff7`
|
|
172
|
+
(harness SHA-256 prefix `bb1620ad`), reviewed before the runs (see
|
|
173
|
+
[Independent review](#independent-review)); candidate `0aae639`; `prepare
|
|
174
|
+
--from-profile code-deepseek` (DeepSeek `deepseek-flash`, `high`, for both
|
|
175
|
+
`accept-code` and `accept-read`); one `trio` run per controller, Claude Code
|
|
176
|
+
with the operator home, Codex with a disposable home. 2026-10-13, 20:13–20:17
|
|
177
|
+
UTC.
|
|
178
|
+
|
|
179
|
+
| Controller | Result | Duration | Notes |
|
|
180
|
+
| --- | --- | --- | --- |
|
|
181
|
+
| Codex `0.162.1` | passed, no failure code | 102 s | Three sessions on their expected aliases and profiles; all first turns overlapped; `wait` aborted by one successful, on-target abort while `slug` and `review` were running; `slug` tests passed within `src/slug.js`; the `review` fixture unchanged in working tree, index and `HEAD`; all closed; no residual process, leak or resource change |
|
|
182
|
+
| Claude Code `2.1.296` | failed: `neighborsNotRunningDuringAbort` only | 118 s | Every other criterion passed as for Codex. The `review` turn completed after 10.7 s, 6.7 s before the abort of `wait`, which came about 10 s after the `wait` turn started instead of the requested about 5 s; `slug` was still running |
|
|
183
|
+
|
|
184
|
+
The failure is a timing outcome of the scenario design, not a session-control
|
|
185
|
+
defect; it stays on record and was not repeated, as decided for this sprint.
|
|
186
|
+
Follow-up: [#74](https://github.com/plagor44-ux/pi-session-mcp/issues/74).
|
|
187
|
+
Three concurrent sessions, a read-only reviewer of a frozen result and a
|
|
188
|
+
neighbor abort are therefore accepted for Codex; for Claude Code everything
|
|
189
|
+
except the reviewer still running at the abort is shown.
|
|
190
|
+
|
|
191
|
+
### Native gate
|
|
192
|
+
|
|
193
|
+
On `0e90589` (this branch before this record), native Linux: `npm ci`,
|
|
194
|
+
typecheck, `build:cli`, `NODE_OPTIONS=--unhandled-rejections=strict npm test`
|
|
195
|
+
(54 files; 1409 passed, 6 skipped, 0 failed; no unhandled error), build,
|
|
196
|
+
`npm audit` and `npm audit --omit=dev` (0 vulnerabilities), `git diff --check`
|
|
197
|
+
and a clean status all exited with `0`; `npm pack --dry-run` listed 134 files
|
|
198
|
+
without sources, tests, lockfile, plans or the harness. The test count adds the
|
|
199
|
+
109 new harness cases to the 1306 of Sprint 2. The built `dist` tree equals the
|
|
200
|
+
one of the base commit, so the package runtime is unchanged and the live
|
|
201
|
+
evidence above binds to this branch. No client session in a test root and no
|
|
202
|
+
client process appeared during the run.
|
|
203
|
+
|
|
204
|
+
## Independent review
|
|
205
|
+
|
|
206
|
+
The harness changes for #70 and #71 were reviewed before the R08 runs by two
|
|
207
|
+
read-only reviewers who did not write them:
|
|
208
|
+
|
|
209
|
+
| Reviewer | Round | Verdict | Outcome |
|
|
210
|
+
| --- | --- | --- | --- |
|
|
211
|
+
| Claude family | 1 | approve with nits | An abort on a neighbor with `abort_timeout` was not judged; the reviewer started last and could finish before the abort; a looser `slug` scope in `trio`; an end-state-only read-only oracle; missing `analyze`-to-verdict tests; one test with two fixture builds. All addressed: `c80383f` to `63d5ff7`; the end-state limit is documented. |
|
|
212
|
+
| OpenAI family (Pi `review` profile) | 1 | changes requested | A failed abort with an unknown session id disappeared from the verdict (concrete false pass), also in the existing `abort` scenario; lost aggregate coverage in the #70 split. Fixed: every `pi_session_abort` call is judged in `abort` and `trio` (new code `offTargetAbort`); an aggregate test. |
|
|
213
|
+
| OpenAI family | 2 | approve | No new finding. |
|
|
214
|
+
|
|
215
|
+
The stricter abort rule also applies to `abort`. The recorded R06 run was
|
|
216
|
+
checked by hand against it: its transcript holds one abort call, on its own
|
|
217
|
+
started session, with an ok result.
|
|
218
|
+
|
|
219
|
+
## Open gates
|
|
220
|
+
|
|
221
|
+
- This sprint's pull request CI (Linux, macOS 15, macOS 26), which also shows
|
|
222
|
+
whether #70 removed the `macos-15` timeout, and the maintainer's merge.
|
|
223
|
+
- [#74](https://github.com/plagor44-ux/pi-session-mcp/issues/74): the `trio`
|
|
224
|
+
timing with Claude Code as controller (entry condition in the issue).
|
|
225
|
+
- R10 and R11 on the work Mac ([runbook](#appendix-macos-runbook-r10-r11)).
|
|
226
|
+
- R22 (external ChatGPT project instructions) stays blocked on an operator
|
|
227
|
+
action.
|
|
228
|
+
|
|
229
|
+
## Next step
|
|
230
|
+
|
|
231
|
+
After the merge, the 0.8.2 release pull request follows, as the maintainer
|
|
232
|
+
decided: version, changelog heading and pre-release acceptance on the release
|
|
233
|
+
candidate. It carries #59, #56 and #60, which the published 0.8.1 does not
|
|
234
|
+
have (0.8.1 still deletes a partial trash), and the #62 skill change; the MCP
|
|
235
|
+
contract is unchanged. Merge, tag and publication stay maintainer decisions.
|
|
236
|
+
Then Sprint 4 decides from the evidence of Sprints 1–3 and the
|
|
237
|
+
[Sprint 4 decision inputs](https://github.com/plagor44-ux/pi-session-mcp/pull/73)
|
|
238
|
+
prepared in parallel.
|
|
239
|
+
|
|
240
|
+
## Closure
|
|
241
|
+
|
|
242
|
+
Sprint 3 closed on 2026-10-13. Pull request
|
|
243
|
+
[#75](https://github.com/plagor44-ux/pi-session-mcp/pull/75) was merged as
|
|
244
|
+
`f636e6e` after its final-head CI passed on Linux, macOS 15 and macOS 26 (run
|
|
245
|
+
`38462141219`); the CI run on main (`38465781209`) passed on the same
|
|
246
|
+
matrix, so #70 holds on main too. The merge closed #70 and #71 as completed.
|
|
247
|
+
The Sprint 4 decision inputs
|
|
248
|
+
([#73](https://github.com/plagor44-ux/pi-session-mcp/pull/73), #72) followed
|
|
249
|
+
as `166ffef`, also with green CI on main. Open from this sprint: #74, R10 and
|
|
250
|
+
R11 on the work Mac, and R22. The 0.8.2 release is prepared in its own pull
|
|
251
|
+
request.
|
|
252
|
+
|
|
253
|
+
## Appendix: macOS runbook (R10, R11)
|
|
254
|
+
|
|
255
|
+
Light checks only; no full test suite and no parallel model work on the work
|
|
256
|
+
Mac. Run them from a checkout of the release under test.
|
|
257
|
+
|
|
258
|
+
1. `npm ci`, `npm run build`, `npm run build:cli`.
|
|
259
|
+
2. Level 2 with both clients in disposable homes:
|
|
260
|
+
`node scripts/setup-acceptance.mjs --setup "node <checkout>/dist/setup-main.js" --build-dir <checkout> --work-dir ~/.cache/pi-session-mcp-acceptance --label "macOS <version> <commit>" --out <private file>`.
|
|
261
|
+
Record the exit status, the check count, the client versions and the
|
|
262
|
+
result's `realRegistrationsUnchanged`, `processCheck` and `buildUnchanged`.
|
|
263
|
+
3. Read-only smoke (R11): one `pi_session_start` with a read-only profile, one
|
|
264
|
+
short prompt, `pi_turn_get` until completed, `pi_session_close`, through the
|
|
265
|
+
installed client registration.
|
|
266
|
+
4. Record date, macOS version, commit, `dist/main.js` SHA-256 and the outcomes
|
|
267
|
+
in [acceptance](../acceptance.md), without paths or prompt content.
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Sprint 4 decision inputs: R12, R15, R17 and R18
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-13. Base: main `0aae6390c539e1d70138f1efaf297e6193a2b497` (the
|
|
4
|
+
merge of Sprint 2). Tracking:
|
|
5
|
+
[#72](https://github.com/plagor44-ux/pi-session-mcp/issues/72).
|
|
6
|
+
Planning sources: the [roadmap](../roadmap.md) and the
|
|
7
|
+
[post-0.8.1 audit](../reviews/2026-10-13-post-0.8.1-audit.md), whose
|
|
8
|
+
[Sprint 4 section](../reviews/2026-10-13-post-0.8.1-audit.md#sprint-4-decide-the-next-investment-from-usage)
|
|
9
|
+
routes R12, R15, R17 and R18 "into one concrete follow-up or the deferred list
|
|
10
|
+
according to need".
|
|
11
|
+
|
|
12
|
+
This record is decision input, not the Sprint 4 decision. It checks the entry
|
|
13
|
+
condition of each of these four conditional items against facts gathered on
|
|
14
|
+
2026-10-13, while Sprint 3 (live usage acceptance) is still running. It
|
|
15
|
+
implements nothing: no workflow, `package.json`, release tooling or runtime
|
|
16
|
+
change. The usage evaluation that Sprint 4 needs from Sprint 3 (failures and
|
|
17
|
+
their causes, scope violations, polls per turn, task duration, cleanup,
|
|
18
|
+
restart cost and planned non-disposable workspaces) is outside this record.
|
|
19
|
+
Sprint 3 results can change the assessments of R12 and R15 below; Sprint 4
|
|
20
|
+
re-checks them.
|
|
21
|
+
|
|
22
|
+
R-identifiers are planning identifiers from the audit, not GitHub issue
|
|
23
|
+
numbers.
|
|
24
|
+
|
|
25
|
+
## Summary
|
|
26
|
+
|
|
27
|
+
| Item | Entry condition | Assessment on 2026-10-13 | Re-check in Sprint 4 |
|
|
28
|
+
| --- | --- | --- | --- |
|
|
29
|
+
| R17 scheduled advisory check | Further demonstrated `npm audit` drift | Not met | Any advisory found between releases or at a release gate; any Dependabot alert |
|
|
30
|
+
| R18 npm provenance / Trusted Publishing | External use makes it relevant | Not determinable; no evidence of external consumers | Distinguishable external use, or a maintainer decision to harden publication anyway |
|
|
31
|
+
| R12 real crash, contention and signal runs | Operating experience warrants targeted evidence | Not met | Sprint 3 records and operator reports of interrupted updates, customization conflicts or signal-ended analyses |
|
|
32
|
+
| R15 explicit unverified evidence for an unreadable start time | A run passes while the start time was unreadable, or a demonstrated need | Not met | Sprint 3 `noServerObserved` failures whose investigated cause is an unreadable start time |
|
|
33
|
+
|
|
34
|
+
Assessment values: **met** (the facts satisfy the entry condition), **not
|
|
35
|
+
met** (the facts were checked and do not satisfy it), **not determinable**
|
|
36
|
+
(the available facts cannot decide it).
|
|
37
|
+
|
|
38
|
+
## R17: scheduled advisory check
|
|
39
|
+
|
|
40
|
+
Definition
|
|
41
|
+
([audit, cluster C](../reviews/2026-10-13-post-0.8.1-audit.md#c-acceptance-and-release-evidence-quality)):
|
|
42
|
+
`npm audit` is manual only. Deliverable: keep the manual release gate;
|
|
43
|
+
consider one small scheduled advisory check only after further demonstrated
|
|
44
|
+
drift, in its own issue.
|
|
45
|
+
|
|
46
|
+
Facts:
|
|
47
|
+
- `npm audit` and `npm audit --omit=dev` against the lockfile of `0aae639`
|
|
48
|
+
reported 0 vulnerabilities each (331 dependencies), exit 0.
|
|
49
|
+
- The release notes of v0.6.4, v0.7.0, v0.7.1, v0.8.0 and v0.8.1 each record
|
|
50
|
+
`npm audit` and `npm audit --omit=dev` with 0 vulnerabilities. The native
|
|
51
|
+
gates of [Sprint 1](2026-10-13-s1-correctness.md) and
|
|
52
|
+
[Sprint 2](2026-10-13-s2-evidence.md) recorded 0 vulnerabilities on every
|
|
53
|
+
run.
|
|
54
|
+
- No changelog entry and no commit after the initial public release patches
|
|
55
|
+
an audit advisory. The 0.6.2 changelog records that the earlier lockfile
|
|
56
|
+
patches for `proxy-addr`, `shell-quote` and `concurrently`, present since
|
|
57
|
+
the initial public release (2026-10-06), left the tree with the Inspector
|
|
58
|
+
update `5015143` of 2026-10-09, before v0.6.2 was tagged the same day.
|
|
59
|
+
[Releasing](../releasing.md#patch-audit-advisories) describes the
|
|
60
|
+
`concurrently` case.
|
|
61
|
+
- GitHub vulnerability alerts (Dependabot alerts) are enabled for the
|
|
62
|
+
repository and list no alerts. There is no `.github/dependabot.yml`, so no
|
|
63
|
+
version-update pull requests are configured. Dependabot alerts already give
|
|
64
|
+
a passive advisory signal for the default branch between releases.
|
|
65
|
+
- `npm audit signatures` on the installed tree of the workstation checkout
|
|
66
|
+
(consistent with the lockfile: `npm ls --all` exit 0) reported 251 packages
|
|
67
|
+
with verified registry signatures and 79 with verified attestations, exit 0.
|
|
68
|
+
CI does not run it.
|
|
69
|
+
- A scheduled-workflow precedent exists:
|
|
70
|
+
[`pi-sdk-canary.yml`](../../.github/workflows/pi-sdk-canary.yml) runs nightly
|
|
71
|
+
and reports an incompatible SDK into one labeled tracker issue.
|
|
72
|
+
|
|
73
|
+
Assessment: **not met**. No drift is demonstrated after the initial release.
|
|
74
|
+
|
|
75
|
+
If the condition is met later, the smallest follow-up is its own issue for a
|
|
76
|
+
nightly job that runs both audit commands against the lockfile and reports
|
|
77
|
+
into one labeled tracker issue, following the canary's pattern. The manual
|
|
78
|
+
release gate stays. Whether Dependabot alerts already cover the need is part
|
|
79
|
+
of that decision.
|
|
80
|
+
|
|
81
|
+
## R18: npm provenance and Trusted Publishing
|
|
82
|
+
|
|
83
|
+
Definition
|
|
84
|
+
([audit, cluster C](../reviews/2026-10-13-post-0.8.1-audit.md#c-acceptance-and-release-evidence-quality)):
|
|
85
|
+
npm publication has no provenance attestation. Deliverable: consider Trusted
|
|
86
|
+
Publishing or provenance as a separate supply-chain decision if external use
|
|
87
|
+
makes it relevant; not a blocker for bounded local dogfooding.
|
|
88
|
+
[#3](https://github.com/plagor44-ux/pi-session-mcp/issues/3) deferred
|
|
89
|
+
"provenance and trusted publishing from GitHub Actions" when the package was
|
|
90
|
+
first published.
|
|
91
|
+
|
|
92
|
+
Facts about publication:
|
|
93
|
+
- The registry lists 0.6.1, 0.6.2, 0.6.3, 0.6.4, 0.7.0, 0.7.1, 0.8.0 and 0.8.1,
|
|
94
|
+
published between 2026-10-06 and 2026-10-12 (UTC), plus the staging placeholder
|
|
95
|
+
`0.0.0-stage`. None of them carries a provenance attestation in its registry
|
|
96
|
+
metadata.
|
|
97
|
+
- [Releasing](../releasing.md#publish-a-release) publishes from a fresh local
|
|
98
|
+
clone of the tag with `npm stage publish`; the maintainer approves the staged
|
|
99
|
+
version with the account's second factor and compares the shasum.
|
|
100
|
+
|
|
101
|
+
Facts about use:
|
|
102
|
+
- The npm download API, whose data ended on 2026-10-11 at the time of the
|
|
103
|
+
query, reports 915 downloads from 2026-10-07 to 2026-10-11 (59, 15, 150, 349
|
|
104
|
+
and 342 per day) and none earlier in the 30-day window, all within days of
|
|
105
|
+
the six publications from 0.6.1 to 0.7.1; 0.8.0 and 0.8.1 fall after the
|
|
106
|
+
data. The counts do not distinguish
|
|
107
|
+
people from registry mirrors and automated fetchers, nor external users from
|
|
108
|
+
the maintainer's own installations.
|
|
109
|
+
- GitHub reports one star, no forks and no watchers. Its 14-day traffic shows
|
|
110
|
+
770 clones (229 unique) and 45 views (3 unique); every CI run checks the
|
|
111
|
+
repository out, so clones do not indicate external users either.
|
|
112
|
+
- All 26 pull requests are from the maintainer account. Before #72, 43 of 45
|
|
113
|
+
issues were from the maintainer account and two (#28, #29) from one other
|
|
114
|
+
account. #28 reports use from a clone of a release tag, not from the npm
|
|
115
|
+
package. No issue or pull request identifies an external consumer of the
|
|
116
|
+
npm package.
|
|
117
|
+
|
|
118
|
+
Facts about the mechanism (npm documentation, read on 2026-10-13:
|
|
119
|
+
[Trusted publishing for npm packages](https://docs.npmjs.com/trusted-publishers),
|
|
120
|
+
[Staged publishing for npm packages](https://docs.npmjs.com/staged-publishing),
|
|
121
|
+
[Generating provenance statements](https://docs.npmjs.com/generating-provenance-statements)):
|
|
122
|
+
- Trusted publishing authenticates a CI workflow through OIDC instead of a
|
|
123
|
+
long-lived token. It needs npm CLI 11.5.1 or later and Node.js 22.14.0 or
|
|
124
|
+
later, a GitHub Actions workflow with `id-token: write`, and a trusted
|
|
125
|
+
publisher configured on npmjs.com for the owner, repository and workflow
|
|
126
|
+
file name.
|
|
127
|
+
- A trusted publisher always allows `npm stage publish`; a direct
|
|
128
|
+
`npm publish` and dist-tag management are separate options. A staged
|
|
129
|
+
version still needs a maintainer's approval with the second factor, so the
|
|
130
|
+
current approval step can stay. Staging needs npm 11.15 or later (see
|
|
131
|
+
[Releasing](../releasing.md#publish-a-release)), above the trusted-publishing
|
|
132
|
+
minimum.
|
|
133
|
+
- Trusted publishing from GitHub Actions generates provenance attestations
|
|
134
|
+
automatically when the repository and the package are public. Both are
|
|
135
|
+
public. A local publish, as today, cannot produce provenance.
|
|
136
|
+
|
|
137
|
+
Assessment: **not determinable**. The available counts cannot separate
|
|
138
|
+
external consumers from mirrors, automation and the maintainer's own
|
|
139
|
+
installations, and no external consumer has made itself known.
|
|
140
|
+
|
|
141
|
+
If the condition is met later, or the maintainer decides to harden
|
|
142
|
+
publication without it, the smallest follow-up is its own issue and a release
|
|
143
|
+
procedure decision:
|
|
144
|
+
- a tag-triggered workflow with `id-token: write` that runs `npm ci`, builds
|
|
145
|
+
and stages the package with `npm stage publish`;
|
|
146
|
+
- a trusted publisher on npmjs.com limited to staging, so every version still
|
|
147
|
+
needs the second-factor approval;
|
|
148
|
+
- [Releasing](../releasing.md) updated, including a check of the attestation
|
|
149
|
+
after approval;
|
|
150
|
+
- the published-release Level 2 acceptance unchanged.
|
|
151
|
+
|
|
152
|
+
Trade-offs to weigh: the release bytes are built on a GitHub-hosted runner
|
|
153
|
+
instead of a fresh local clone; the repository gains a workflow with an
|
|
154
|
+
OIDC token permission and depends on the actions it uses; the first release
|
|
155
|
+
under the new procedure needs the same pre-release acceptance as any other.
|
|
156
|
+
The change touches release tooling; if a 0.8.2 patch release happens, keeping
|
|
157
|
+
this change out of it would keep that patch's scope unchanged.
|
|
158
|
+
|
|
159
|
+
## R12: real crash, contention and signal runs
|
|
160
|
+
|
|
161
|
+
Definition
|
|
162
|
+
([audit, cluster B](../reviews/2026-10-13-post-0.8.1-audit.md#b-evidence-and-orchestration)):
|
|
163
|
+
a real skill-update crash, a real customization contention and a
|
|
164
|
+
harness-analysis signal run are absent from live evidence. Deliverable: add
|
|
165
|
+
only targeted evidence when operating experience warrants it; existing
|
|
166
|
+
provider-free tests are not renamed as live evidence.
|
|
167
|
+
|
|
168
|
+
Facts:
|
|
169
|
+
- The [acceptance status](../acceptance.md#status) states that its records do
|
|
170
|
+
not cover a real crash in the middle of a setup skill update, a real
|
|
171
|
+
contention of two customization processes outside the tests, or an
|
|
172
|
+
operating-system signal to the harness during a live analysis, and that the
|
|
173
|
+
provider-free tests cover these.
|
|
174
|
+
- Those provider-free tests exist: SIGKILL recovery at six of the seven update
|
|
175
|
+
checkpoints in [`setup-skills-recovery.test.ts`](../../test/setup-skills-recovery.test.ts),
|
|
176
|
+
concurrent customization in
|
|
177
|
+
[`skill-customize-concurrency.test.ts`](../../test/skill-customize-concurrency.test.ts)
|
|
178
|
+
and signal handling of the harness in
|
|
179
|
+
[`multi-session-acceptance.test.ts`](../../test/multi-session-acceptance.test.ts).
|
|
180
|
+
- No issue and no acceptance record reports an interrupted real skill update,
|
|
181
|
+
a customization conflict between two processes, or a live analysis ended by
|
|
182
|
+
a signal.
|
|
183
|
+
- On `main` since Sprints 1 and 2, not yet in a published release, recovery
|
|
184
|
+
retains an unprovable intermediate
|
|
185
|
+
([#59](https://github.com/plagor44-ux/pi-session-mcp/issues/59)) and the
|
|
186
|
+
dry-run predicts it ([#60](https://github.com/plagor44-ux/pi-session-mcp/issues/60)).
|
|
187
|
+
A real interruption that leaves an unprovable intermediate on a build that
|
|
188
|
+
contains these changes would surface as `skill_recovery_retained`; the
|
|
189
|
+
published 0.8.1 still deletes a partial trash.
|
|
190
|
+
|
|
191
|
+
Assessment: **not met**.
|
|
192
|
+
|
|
193
|
+
If the condition is met later, the smallest follow-up records that occurrence
|
|
194
|
+
as evidence, with its sanitized setup report, and adds a targeted test only
|
|
195
|
+
when the occurrence shows behavior the provider-free tests miss.
|
|
196
|
+
|
|
197
|
+
## R15: explicit unverified evidence for an unreadable start time
|
|
198
|
+
|
|
199
|
+
Definition
|
|
200
|
+
([audit, cluster C](../reviews/2026-10-13-post-0.8.1-audit.md#c-acceptance-and-release-evidence-quality)):
|
|
201
|
+
a client start time that is unreadable immediately after spawn leaves no
|
|
202
|
+
sighting. Deliverable: explicit failed or unverified evidence; never infer
|
|
203
|
+
cleanup from an absent observation. [Sprint 2](2026-10-13-s2-evidence.md#tasks)
|
|
204
|
+
did not include it and set the entry condition: a run that passes while the
|
|
205
|
+
start time was unreadable, or a demonstrated need for an explicit unverified
|
|
206
|
+
code.
|
|
207
|
+
|
|
208
|
+
Facts:
|
|
209
|
+
- The [multi-session harness](../../scripts/multi-session-acceptance.mjs)
|
|
210
|
+
records a process only together with its start time; without the client's
|
|
211
|
+
start time nothing is recorded. Its pass criteria include at least one
|
|
212
|
+
observed server (`noServerObserved`) and no residual process.
|
|
213
|
+
- The acceptance records contain one run with `noServerObserved` failures:
|
|
214
|
+
run 2 on `06471b5`, where three invocations failed only with
|
|
215
|
+
`noServerObserved`. Their cause was a harness defect that replaced earlier
|
|
216
|
+
sightings; `cb6e949` fixed it. The code was misleading there, but the runs
|
|
217
|
+
failed. The cause was not an unreadable start time.
|
|
218
|
+
- No record shows a run that passed while a start time was unreadable.
|
|
219
|
+
|
|
220
|
+
Assessment: **not met**.
|
|
221
|
+
|
|
222
|
+
If the condition is met later, the smallest follow-up is its own issue for an
|
|
223
|
+
explicit failure code when the client's start time cannot be read, so the
|
|
224
|
+
result names the cause instead of `noServerObserved`; such a run still fails.
|
|
225
|
+
|
|
226
|
+
## Sources and checks
|
|
227
|
+
|
|
228
|
+
All checks ran on 2026-10-13 on the Linux workstation, read-only, without a
|
|
229
|
+
client, Pi session, provider or model:
|
|
230
|
+
- `npm audit` and `npm audit --omit=dev` against the lockfile of `0aae639`;
|
|
231
|
+
`npm audit signatures` on the installed tree of the workstation checkout.
|
|
232
|
+
- npm registry metadata of `pi-session-mcp` (publication times, attestations)
|
|
233
|
+
and the npm download API (point and daily range).
|
|
234
|
+
- GitHub API: repository statistics, 14-day traffic, Dependabot alerts and
|
|
235
|
+
the vulnerability-alert setting, issue and pull request authors.
|
|
236
|
+
- Release notes of v0.6.4 to v0.8.1, `CHANGELOG.md`, the Git history,
|
|
237
|
+
[Releasing](../releasing.md), [Acceptance](../acceptance.md), the Sprint 1
|
|
238
|
+
and Sprint 2 files, the audit and
|
|
239
|
+
[#3](https://github.com/plagor44-ux/pi-session-mcp/issues/3).
|
|
240
|
+
- npm documentation on trusted publishing, staged publishing and provenance,
|
|
241
|
+
read through a documentation index on 2026-10-13.
|
package/docs/threat-model.md
CHANGED
|
@@ -29,10 +29,10 @@ Pi Session MCP trusts the local process that launches and speaks MCP over inheri
|
|
|
29
29
|
- **Skill installation into clients:** `setup --apply` writes the controller skill `pi-session-orchestration` into the clients' skill directories, in the home directory (`~/.agents/skills`, `~/.claude/skills`) and, for Claude Code `project`, in the project that setup runs in (`<project>/.claude/skills`). What is written there becomes instructions for the controlling agent, so the copy is as trusted as the package or the override it comes from. Mitigations:
|
|
30
30
|
- Copies come only from the package's `skills/` directory or from the operator's override directory next to the configuration file. No tool argument, client prompt or workspace names a source.
|
|
31
31
|
- The override directory and its `.pi-session-mcp-bases.json` are operator-trusted configuration next to the configuration file, never a workspace. Keep them out of every workspace and writable only by the operator; a `coding` session that can write there could change what setup installs next.
|
|
32
|
-
- Setup reads a bounded tree of regular files (at most 32 files and 1 MiB, no links or special files) and installs it as a real copy, never as a link. The copy is staged and renamed into place
|
|
33
|
-
- Setup never replaces or deletes a modified installed copy, hidden operator entries inside it, a foreign skill of the same name or a linked or non-directory entry; it reports `skill_divergent`. A link to exactly the effective skill is accepted as the operator's own (`skill_linked`) and never written through or deleted. Ownership records hold a content fingerprint (and, during an update, the replaced fingerprint), no path; a project record carries an unsalted, truncated SHA-256 of the project's real path as an opaque identity, which someone who can read the state file could test against guessed paths.
|
|
32
|
+
- Setup reads a bounded tree of regular files (at most 32 files and 1 MiB, no links or special files) and installs it as a real copy, never as a link. The copy is staged and renamed into place. An update renames the old tree to a backup named after the pending record's transaction id and deletes it only after verifying that it is the exact old tree; leftover intermediates are deleted only by their exact names and only after verification (a leftover trash directory only while it still is the complete, unchanged replaced copy), and anything modified, foreign, partial or otherwise unprovable stays (`skill_recovery_retained`).
|
|
33
|
+
- Setup never replaces or deletes a modified installed copy, hidden operator entries inside it, a foreign skill of the same name or a linked or non-directory entry; it reports `skill_divergent`. A link to exactly the effective skill is accepted as the operator's own (`skill_linked`) and never written through or deleted. Ownership records hold a version 2 content fingerprint (and, during an update, the replaced fingerprint), no path. A bare version 1 value from 0.8.0 names a copy only when a trusted reference (a released 0.8.0 shipped tree or the current library tree) has that value and the copy's exact bytes; otherwise setup reports `skill_legacy_unverified` and changes nothing; a project record carries an unsalted, truncated SHA-256 of the project's real path as an opaque identity, which someone who can read the state file could test against guessed paths.
|
|
34
34
|
- A project may be untrusted. Inside a project setup never follows a link: any link below the project root makes the slot divergent, so a repository cannot redirect the write outside itself. In the home directory the client's skills directory may be the operator's own link (for example into a dotfiles checkout) and is followed; the skill entry itself is never followed.
|
|
35
|
-
- `--customize-skill` writes only below the override directory, never overwrites an existing override and never edits an operator's file. It moves the recorded base only on an explicit `--apply`, which acknowledges a reviewed change to the shipped skill.
|
|
35
|
+
- `--customize-skill` writes only below the override directory, never overwrites an existing override and never edits an operator's file. It moves the recorded base only on an explicit `--apply`, which acknowledges a reviewed change to the shipped skill. `--apply` runs under an exclusive kernel lock on `<override dir>/.pi-session-mcp-bases.lock` and replaces the bases file atomically, so concurrent runs cannot lose a base; the dry-run takes no lock and writes nothing.
|
|
36
36
|
- Worker skills are not installed into clients. Reports name the skill and a stable code, never a path or content.
|
|
37
37
|
- **False verification:** Verify combines Doctor and exact registration
|
|
38
38
|
equality with a bounded direct MCP initialize, `tools/list`, and
|
package/docs/tool-contracts.md
CHANGED
|
@@ -15,6 +15,24 @@ Every response includes text JSON for broad client compatibility and the same ob
|
|
|
15
15
|
|
|
16
16
|
There are exactly eight tools. No `pi_turn_wait` tool or live provider/model inventory exists.
|
|
17
17
|
|
|
18
|
+
## Versions
|
|
19
|
+
|
|
20
|
+
Three different versions exist. They identify different things and change for
|
|
21
|
+
different reasons; none of them stands in for another.
|
|
22
|
+
|
|
23
|
+
| Version | What it identifies | Where it appears | When it changes |
|
|
24
|
+
| --- | --- | --- | --- |
|
|
25
|
+
| Package version | One build and release of Pi Session MCP: the npm package, the GitHub release and the server. | `package.json`; `server.version` of `pi_capabilities_get`; `packageVersion` of the Doctor result | With every release. A release that keeps the MCP tool contract is a patch release. |
|
|
26
|
+
| MCP tool contract | The eight tools of this document: their inputs, response fields, states and error codes. | Only this document. It carries no version number of its own and no tool, field or code names one. | A change to a tool, field, state or error code needs a new minor release and its own decision, so within a `0.x` minor line the contract is stable. A client identifies its compatibility by the package version, as `pi_capabilities_get` reports it, and by this document at that release. |
|
|
27
|
+
| Setup report `schemaVersion` | The shape of the result of `pi-session-mcp-setup`, currently `1`; the human output derives from the same result. | The `schemaVersion` field of the `--json` report | Independent of the package version and no part of the MCP tool contract; a release does not change it by itself. It has been `1` since the first public release, and no document defines a further rule for changing it. |
|
|
28
|
+
|
|
29
|
+
The setup report is not an MCP response. The Doctor result has its own
|
|
30
|
+
`schemaVersion` (currently `1`), and the skill customization bases file has a
|
|
31
|
+
`schemaVersion` (currently `2`) that is separate again; neither is the setup
|
|
32
|
+
report's. Release rules are in [Releasing](releasing.md#versioning); acceptance
|
|
33
|
+
records name the package version and the build they ran on, see
|
|
34
|
+
[Acceptance](acceptance.md#evidence-rules).
|
|
35
|
+
|
|
18
36
|
## Capability discovery
|
|
19
37
|
|
|
20
38
|
`pi_capabilities_get` accepts only `{}`. Unknown fields fail MCP schema validation. Success has this strict shape:
|
|
@@ -22,7 +40,7 @@ There are exactly eight tools. No `pi_turn_wait` tool or live provider/model inv
|
|
|
22
40
|
```json
|
|
23
41
|
{
|
|
24
42
|
"ok": true,
|
|
25
|
-
"server": { "name": "pi-session-mcp", "version": "0.8.
|
|
43
|
+
"server": { "name": "pi-session-mcp", "version": "0.8.2" },
|
|
26
44
|
"configuration": {
|
|
27
45
|
"fingerprint": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
|
28
46
|
"reloadPolicy": "restart-required"
|
|
@@ -90,7 +108,7 @@ Invalid execution-profile configuration prevents startup, so it cannot be an MCP
|
|
|
90
108
|
|
|
91
109
|
`pi_session_prompt` returns `{session,turn}` only after successful Pi preflight. Preflight is bounded at 5,000 ms; a missing callback, hanging prompt acceptance, or timeout returns `prompt_timeout` / `Pi prompt preflight timed out` and creates no public turn. Late settlement may only release the unpublished operation's quarantine; it cannot publish a turn. `pi_session_abort` waits at most 5,000 ms per caller for one shared SDK abort attempt and returns `abort_timeout` / `Pi abort timed out` without claiming the turn was aborted. Rejection/failure remain `prompt_rejected`/`abort_failed`. Close allows at most 5,000 ms for abort cleanup, then performs best-effort disposal and removes the public registry entry; it remains idempotent through the retained tombstone. Registry shutdown rejects new starts, allows 12,000 ms, and disposes a handle from a late-resolving start instead of admitting it. Process shutdown, started by `SIGINT`, `SIGTERM`, or stdin EOF, allows 15,000 ms, attempts transport cleanup even after registry failure/timeout, then explicitly exits the process. These boundaries do not guarantee graceful cancellation of a provider request. `pi_turn_get` returns a `TurnView` with `turnId`, `sessionId`, state, timestamps, and `completedAt` for terminal turns. Completed views add normalized final `assistantText` and `truncated`; failed views contain only `{code:"turn_failed",message:"Pi turn failed"}`. Final assistant text is capped at 64 KiB UTF-8 bytes, each active session retains at most 20 turns, and close removes its turn data.
|
|
92
110
|
|
|
93
|
-
While a turn runs, `updatedAt` is the
|
|
111
|
+
While a turn runs, `updatedAt` is the time of the last observed public SDK activity of that turn: assistant message start, streaming updates and end, and tool execution start, update and end. It freezes at the terminal transition. The `updatedAt` of the session does not follow this activity: it moves when a turn starts and at its terminal transition. It is a liveness lower bound only. Streaming is activity, not evidence of finished or useful work. Work without a public event, such as the internal steps of an extension's own agent loop or a long tool call without updates, stays invisible, so a stamp that has not moved can still be a working turn (a long model response, thinking, a first token, or a long tool call) and never justifies a claim that a turn is hung. The stamp is a wall-clock ISO-8601 millisecond value for ordering, not a progress count, duration, or step total, and activity within one millisecond simply reuses the stamp. Only the type of an event and the role of its message are inspected: no delta, thinking block, tool argument, or partial result is stored or projected, and the answer still comes only from the final assistant message.
|
|
94
112
|
|
|
95
113
|
Context usage stays out of the boundary: no token, usage, context-window, or cost figure is projected for a running or terminal turn, so approaching context exhaustion remains invisible in the turn view and in `pi_session_get`. This change adds no progress counters, tool names, arguments, results, or transcripts; see *Failure causes* below for failure-cause classification, which is not part of the turn view and is decided in *Failure causes* below.
|
|
96
114
|
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@ You control Pi worker sessions through the pi-session-mcp tools. You choose only
|
|
|
11
11
|
|
|
12
12
|
- Call `pi_capabilities_get` before anything else in a run. Use only the workspace and profile aliases it lists. Never invent an alias or pass a path.
|
|
13
13
|
- Each profile lists `permissionProfile` (`read-only` or `coding`), `extensions` and `skills`. `skills` names the configured skill aliases. That is configuration intent only. It does not prove that a session loaded the skill or that the model will read it.
|
|
14
|
-
- Capabilities do not prove that a provider or model is reachable.
|
|
14
|
+
- Capabilities do not prove that a provider or model is reachable. A successful `pi_session_start` shows that the session was created with the selected provider, model and thinking level, and that local authentication, the extensions, external MCP servers and selected skills passed their start checks. It does not prove that the provider accepts requests: credentials, quota and network show only when a turn runs.
|
|
15
15
|
|
|
16
16
|
## 2. Scope each task
|
|
17
17
|
|
|
@@ -56,7 +56,7 @@ Keep an internal ledger with one row per task: task, workspace alias, profile al
|
|
|
56
56
|
|
|
57
57
|
## 7. Interpret progress and results
|
|
58
58
|
|
|
59
|
-
- `updatedAt` on a running turn is
|
|
59
|
+
- `updatedAt` on a running turn is the time of the last observed public SDK activity: assistant message start, streaming updates and end, and tool execution start, update and end. Streaming is activity, not evidence of finished or useful work. Work without a public event stays invisible, for example inside an extension's own agent loop or in a long tool call without updates. A stamp that has not moved is therefore no proof of a hang. Judge by your time budget and by the workspace.
|
|
60
60
|
- `completed` is a technical state: the turn ended and returned text. It does not mean the task succeeded. Read `assistantText` and check `truncated`.
|
|
61
61
|
- Never accept a worker report as proof. A worker saying the tests pass is a claim, not evidence.
|
|
62
62
|
|
|
@@ -77,8 +77,12 @@ You integrate. Workers never integrate each other's changes. Resolve conflicts b
|
|
|
77
77
|
- `failed` means `turn_failed`. The error carries no cause. Check the result in the workspace, then retry once in a fresh session with a narrower prompt, or take the task over yourself.
|
|
78
78
|
- `aborted` means the turn stopped. Look at what the workspace contains before reusing it.
|
|
79
79
|
- `pi_session_abort` returns `abort_failed` if the abort was rejected. The turn may still be running. Poll it.
|
|
80
|
-
- `abort_timeout` is not a successful abort. The turn may still be running or may finish normally. Poll `pi_turn_get` until
|
|
81
|
-
-
|
|
80
|
+
- `abort_timeout` is not a successful abort. The turn may still be running or may finish normally. Decide an observation and cleanup budget before you abort, for example a fixed number of polling rounds within a few minutes. Poll `pi_turn_get` until the turn is terminal or the budget is spent, then close the session with `pi_session_close`. If the close fails or does not finish, stop using that workspace, treat it as unverified and report it. Never wait without a bound.
|
|
81
|
+
- Classify every `pi_session_start` error by its `code` alone. Never decide by the message, provider text or any other free text, and never infer a cause. Each code below is in exactly one class:
|
|
82
|
+
- Operator needed (do not retry and do not switch to another profile; report the code and stop that task): `unknown_execution_profile`, `unknown_workspace`, `unknown_provider`, `unknown_model`, `model_unavailable`, `thinking_level_unavailable`, `local_authentication_missing`, `execution_selection_mismatch`, `skill_load_failed`, `extension_not_installed`, `extension_version_mismatch`, `extension_tool_conflict`, `external_mcp_no_tools`, `external_mcp_grant_tool_missing`, `external_mcp_activation_mismatch`, `server_stopping`. The last code means the server is shutting down: a new server process is needed, not a retry.
|
|
83
|
+
- Transient (retry at most once after a pause, then report): `external_mcp_unavailable` (an external MCP server that cannot connect, times out or breaks the protocol), `extension_load_failed` (an invalid package, but also a start timeout), `local_authentication_unavailable` (local authentication could not be resolved within its deadline).
|
|
84
|
+
- Unknown (report the code; at most one retry in a fresh session): `pi_session_creation_failed`. Any code not listed above is also unknown.
|
|
85
|
+
- If the pi-session-mcp tools are missing entirely, the server did not start. Its stderr names a `startup_failed` diagnostic (`invalid_execution_profile_config` or `invalid_thinking_level`). No MCP server is available; the operator must fix the configuration.
|
|
82
86
|
|
|
83
87
|
## 10. Close every session
|
|
84
88
|
|