pi-session-mcp 0.8.1 → 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/CHANGELOG.md +68 -0
- package/CONTRIBUTING.md +5 -3
- package/README.md +5 -3
- package/dist/setup-skills.d.ts +8 -2
- package/dist/setup-skills.js +56 -18
- package/dist/setup.js +21 -4
- package/docs/acceptance.md +393 -22
- package/docs/client-setup-design.md +60 -13
- package/docs/client-setup.md +19 -0
- package/docs/releasing.md +7 -1
- package/docs/reviews/2026-10-13-post-0.8.1-audit.md +393 -0
- package/docs/roadmap.md +127 -0
- package/docs/skills.md +39 -11
- 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 +1 -1
- package/docs/tool-contracts.md +19 -1
- package/package.json +1 -1
- package/skills/pi-session-orchestration/SKILL.md +5 -2
package/docs/acceptance.md
CHANGED
|
@@ -16,6 +16,16 @@ Provider-free tests exercise the real Pi SDK and real stdio child processes with
|
|
|
16
16
|
a scripted model. They do not establish live client or model acceptance. State
|
|
17
17
|
only what was run.
|
|
18
18
|
|
|
19
|
+
Targeted live checks are not a level. The [Pi extension live
|
|
20
|
+
check](#pi-extension-live-check) and the [multi-session skill
|
|
21
|
+
acceptance](#multi-session-skill-acceptance) use a real provider and model on one
|
|
22
|
+
path with one or two sessions: the first drives the server with a scripted
|
|
23
|
+
client, the second with one real controller. They are not a Level 3 cycle,
|
|
24
|
+
do not count towards its [gate](#gate) and do not replace it. A record of one
|
|
25
|
+
of them never says that Level 3 passed. What a package version, the MCP tool
|
|
26
|
+
contract and a setup report `schemaVersion` identify is defined in [tool
|
|
27
|
+
contracts](tool-contracts.md#versions).
|
|
28
|
+
|
|
19
29
|
## Level 1: repository checks
|
|
20
30
|
|
|
21
31
|
Run on a clean checkout of the exact source under test:
|
|
@@ -24,7 +34,7 @@ Run on a clean checkout of the exact source under test:
|
|
|
24
34
|
npm ci
|
|
25
35
|
npm run typecheck
|
|
26
36
|
npm run build:cli
|
|
27
|
-
npm test
|
|
37
|
+
NODE_OPTIONS=--unhandled-rejections=strict npm test
|
|
28
38
|
npm run build
|
|
29
39
|
npm audit
|
|
30
40
|
git diff --check
|
|
@@ -316,6 +326,11 @@ external MCP grants, and client restart or resume.
|
|
|
316
326
|
A narrower live check can cover a single path. It must state its scope and does
|
|
317
327
|
not count as a ten-task cycle.
|
|
318
328
|
|
|
329
|
+
This applies to the two-session records below: the extension live check
|
|
330
|
+
started two sessions and the multi-session acceptance drives two concurrent
|
|
331
|
+
sessions from one controller. Both are targeted evidence, not a Level 3 cycle,
|
|
332
|
+
and no number of such runs adds up to the gate.
|
|
333
|
+
|
|
319
334
|
## Pi extension live check
|
|
320
335
|
|
|
321
336
|
Manual, on a machine with Pi, `pi-cursor-sdk@0.5.3` and a stored Cursor key. Run it from a working tree (`npm run build`, then `node dist/main.js`) with a temporary configuration, passed through `PI_SESSION_MCP_CONFIG`, whose profile names `"extensions": ["npm:pi-cursor-sdk@0.5.3"]` and a Cursor model from Pi's catalog.
|
|
@@ -328,6 +343,9 @@ Manual, on a machine with Pi, `pi-cursor-sdk@0.5.3` and a stored Cursor key. Run
|
|
|
328
343
|
|
|
329
344
|
Record date, source commit, versions and outcome under Status. No secret, path or prompt content goes into the record.
|
|
330
345
|
|
|
346
|
+
This check is targeted. Its two parallel sessions show that the extension path
|
|
347
|
+
works for the recorded build, provider and model. They are not a Level 3 cycle.
|
|
348
|
+
|
|
331
349
|
## Multi-session skill acceptance
|
|
332
350
|
|
|
333
351
|
A targeted live check for profile skill selection ([skills](skills.md)) and for
|
|
@@ -347,8 +365,12 @@ Pi Session MCP tools; the script never does.
|
|
|
347
365
|
`dist/`; `run` refuses a changed build.
|
|
348
366
|
- Configuration: `prepare --base-config <operator config> --from-profile
|
|
349
367
|
<alias>` copies only provider, model and thinking level of the one explicitly
|
|
350
|
-
selected profile into a run configuration with
|
|
351
|
-
`accept-code` (`coding
|
|
368
|
+
selected profile into a run configuration with the profiles `accept-read` (default, `read-only`, skill `review`) and
|
|
369
|
+
`accept-code` (`coding`). From the Sprint 2 harness (#68) on, `accept-code`
|
|
370
|
+
selects exactly `implementation` and is used for every task except `slug`,
|
|
371
|
+
and a second coding profile `accept-code-handshake` selects `implementation`
|
|
372
|
+
and `handshake` and is used only for the `slug` session; before, `accept-code`
|
|
373
|
+
carried both skills for every task. From the
|
|
352
374
|
harness of `3f98104` on, all three are `builtin:` references: the two worker
|
|
353
375
|
skills ship with the candidate, and the `handshake` skill sits in the
|
|
354
376
|
override directory `skills/` next to the run configuration, so the run also
|
|
@@ -357,16 +379,18 @@ Pi Session MCP tools; the script never does.
|
|
|
357
379
|
`mcpServers` is always rejected. A profile with `extensions` is rejected
|
|
358
380
|
unless `--with-extensions` is given; with it, `prepare` also copies exactly
|
|
359
381
|
that profile's extension allowlist (1 to 8 distinct exact
|
|
360
|
-
`npm:<name>@<version>` pins) into
|
|
382
|
+
`npm:<name>@<version>` pins) into every run profile and installs nothing.
|
|
361
383
|
`--with-extensions` on a profile without extensions is rejected. Nothing else
|
|
362
384
|
is copied: the run has its own workspaces and skills.
|
|
363
385
|
- Working directory: `--work-dir` (default `~/.cache/pi-session-mcp-acceptance`)
|
|
364
386
|
must not be inside a temporary directory (the system temporary directory,
|
|
365
387
|
`/tmp`, `/var/tmp` or `/dev/shm`), because Codex refuses helper binaries
|
|
366
388
|
there.
|
|
367
|
-
- Fixtures:
|
|
368
|
-
`wait`, `range`
|
|
369
|
-
`cx-*` for Codex).
|
|
389
|
+
- Fixtures: five small synthetic git repositories per client (`slug`, `stats`,
|
|
390
|
+
`wait`, `range` and, from the Sprint 3 harness (#71) on, `review`), each a
|
|
391
|
+
separate workspace alias (`cc-*` for Claude Code, `cx-*` for Codex). `review`
|
|
392
|
+
holds a finished, frozen implementation that only the read-only reviewer of
|
|
393
|
+
`trio` uses. Both clients use the same configuration and build.
|
|
370
394
|
- Fixture baselines: when it creates a fixture, `prepare` stores its initial
|
|
371
395
|
commit and a manifest of its files (path, type, mode, SHA-256; without
|
|
372
396
|
`.git/`) under the run's private directory, never inside the worker's
|
|
@@ -381,7 +405,31 @@ Pi Session MCP tools; the script never does.
|
|
|
381
405
|
home (`~/.claude/skills` and `~/.agents/skills`, recorded as missing when
|
|
382
406
|
absent). `run` rechecks all of them before the launch and again after the
|
|
383
407
|
run. A change before the launch refuses the run; a change after it fails the
|
|
384
|
-
result with `resourcesChanged`.
|
|
408
|
+
result with `resourcesChanged`. From the Sprint 2 harness (#66, #67) on it
|
|
409
|
+
also binds, under path-free names: per allowlisted extension the tree of its
|
|
410
|
+
real package root (`extension:<name>`) and the whole npm installation of
|
|
411
|
+
Pi's agent directory, with dependencies, `package.json` and lockfile
|
|
412
|
+
(`extensionNpmInstallation`, `none` without extensions); and every Codex
|
|
413
|
+
skill source besides the run's own link: `$CODEX_HOME/skills` with the
|
|
414
|
+
bundled `.system` skills (`codexHomeSkills`), all of `~/.agents/skills`
|
|
415
|
+
(`homeAgentsSkills`), `/etc/codex/skills` (`etcCodexSkills`) and the
|
|
416
|
+
`.agents/skills` of every ancestor of the Codex controller's directory
|
|
417
|
+
(`codexAncestorSkills`, up to `/`). These extension, Codex source and
|
|
418
|
+
candidate skill digests (the controller skill and both worker skills) walk a
|
|
419
|
+
tree without following links, record every link's text, and for a link
|
|
420
|
+
whose real path lies outside the bound root also bind what it leads to (the
|
|
421
|
+
file's bytes, or the same digest of the target directory, recursively); a
|
|
422
|
+
link that stays inside the root needs only its text. Each real directory is
|
|
423
|
+
digested once, so link cycles end, and at most 200,000 entries are read. A
|
|
424
|
+
value of `unreadable` or `tooLarge` means that a resource cannot be bound
|
|
425
|
+
completely. For every key, composed ones included, `prepare` then refuses and
|
|
426
|
+
names the key, and `run` refuses before the launch with `resourcesUnbound`.
|
|
427
|
+
`missing`, `none`, `notDirectory`, `unset` and a dangling top-level link are
|
|
428
|
+
determinate values and stay allowed. The other resources keep the plain tree
|
|
429
|
+
digest. `prepare` resolves Pi's
|
|
430
|
+
agent directory (`PI_CODING_AGENT_DIR`, else `~/.pi/agent`) and `CODEX_HOME`
|
|
431
|
+
(else `~/.codex`) once and records both only in the run's private data; they
|
|
432
|
+
never appear in a result or the evidence.
|
|
385
433
|
- Home controller skills: Claude Code prefers a personal skill over a project
|
|
386
434
|
skill of the same name. With `--setting-sources project,local`, as the
|
|
387
435
|
harness starts it, Claude Code `2.1.296` listed only the project copy when a
|
|
@@ -389,8 +437,25 @@ Pi Session MCP tools; the script never does.
|
|
|
389
437
|
without that flag the personal copy shadowed the project copy. Re-check this
|
|
390
438
|
when the client version changes. Codex's precedence between its home skills
|
|
391
439
|
and the run's repository skill is not established, so a Codex run is refused
|
|
392
|
-
while
|
|
393
|
-
|
|
440
|
+
while any bound Codex skill source (`$CODEX_HOME/skills`,
|
|
441
|
+
`~/.agents/skills`, `/etc/codex/skills` or an ancestor's `.agents/skills`)
|
|
442
|
+
holds a controller skill whose resolved content differs from the
|
|
443
|
+
candidate's. A controller skill is a directory named
|
|
444
|
+
`pi-session-orchestration` or one whose `SKILL.md` frontmatter declares that
|
|
445
|
+
`name:`. The frontmatter is read as a YAML block mapping whose top-level keys
|
|
446
|
+
are those at the indentation of its first content line; `name` may be a plain
|
|
447
|
+
or quoted scalar, and a ` #` comment outside quotes is ignored. Any other
|
|
448
|
+
form (a flow mapping or sequence, a bare scalar, a dedent or tab
|
|
449
|
+
indentation, a block or multi-line scalar, malformed quoting, a duplicate
|
|
450
|
+
`name`, unclosed frontmatter), and a `SKILL.md` that is not a regular file,
|
|
451
|
+
make the skill indeterminate, so its source counts as differing. Only the
|
|
452
|
+
first 16 KiB of a `SKILL.md` are read, after its type was checked. The
|
|
453
|
+
bounded search includes hidden directories such as `.system` and
|
|
454
|
+
follows links. An equal copy, also behind a link, or none is allowed; a
|
|
455
|
+
source that cannot be searched completely refuses the run. Skills that Codex
|
|
456
|
+
might load by other means, such as other file names or plugin caches, are
|
|
457
|
+
not covered. Before the Sprint 2 harness only
|
|
458
|
+
`~/.agents/skills/pi-session-orchestration` was checked.
|
|
394
459
|
- Launch record and failed analysis: `run` records the launch once before the
|
|
395
460
|
controller starts, so an attempt that ends without a result is never repeated
|
|
396
461
|
silently. If the analysis after the controller fails, the result is recorded
|
|
@@ -410,7 +475,10 @@ Pi Session MCP tools; the script never does.
|
|
|
410
475
|
the shipped skill. Codex installs skills only in the user's home, which the
|
|
411
476
|
run must not change, so the Codex controller gets one run-scoped symbolic link
|
|
412
477
|
in `.agents/skills` of its directory. Earlier runs linked both. No global
|
|
413
|
-
skill directory changes.
|
|
478
|
+
skill directory changes. From the Sprint 2 harness (#67) on, the evidence
|
|
479
|
+
records per client the kind of controller skill, `installed` for Claude Code
|
|
480
|
+
and `linked` for Codex, with its tree digest and without paths
|
|
481
|
+
(`controllerSkills`).
|
|
414
482
|
- Clients: Claude Code runs as `claude -p` with `--mcp-config`,
|
|
415
483
|
`--strict-mcp-config`, `--setting-sources project,local`,
|
|
416
484
|
`--permission-mode dontAsk` and an `--allowedTools` list of the eight tools
|
|
@@ -418,8 +486,19 @@ Pi Session MCP tools; the script never does.
|
|
|
418
486
|
`codex exec --ignore-user-config --sandbox read-only` with the server
|
|
419
487
|
defined through `-c mcp_servers.pi-candidate.*` and the three per-tool
|
|
420
488
|
approvals from [client setup](client-setup.md#run-codex-without-prompts).
|
|
421
|
-
|
|
422
|
-
both use the existing authentication.
|
|
489
|
+
The harness changes neither a persistent registration, `HOME` nor the
|
|
490
|
+
contents of `CODEX_HOME`, and both runs use the existing authentication.
|
|
491
|
+
Codex itself can install its bundled `.system` skills into
|
|
492
|
+
`$CODEX_HOME/skills` on its first start after an upgrade, or create that
|
|
493
|
+
directory in a fresh `CODEX_HOME`. Because those skills are bound, such a
|
|
494
|
+
change invalidates the prepared run for both clients; it fails safe and never
|
|
495
|
+
passes. After a Codex upgrade, start Codex once with the same `CODEX_HOME`
|
|
496
|
+
before `prepare`. From the Sprint 2
|
|
497
|
+
harness (#66, #67) on, the Codex controller runs with exactly the
|
|
498
|
+
`CODEX_HOME` that `prepare` recorded, whatever the launching environment
|
|
499
|
+
holds, and the server of both clients receives the recorded Pi agent
|
|
500
|
+
directory as `PI_CODING_AGENT_DIR`, so the bound extension directory is the
|
|
501
|
+
one the server loads from.
|
|
423
502
|
- Time limit: `run --timeout-min` takes a number above 0 and at most 180
|
|
424
503
|
(default 25). After the limit the harness sends `SIGTERM` to the client's
|
|
425
504
|
process group and waits up to 10 seconds. It then sends `SIGKILL` to that
|
|
@@ -435,12 +514,14 @@ Pi Session MCP tools; the script never does.
|
|
|
435
514
|
|
|
436
515
|
### Scenarios
|
|
437
516
|
|
|
438
|
-
Each client runs
|
|
517
|
+
Each client runs one invocation per scenario: `parallel` and `abort`, and from
|
|
518
|
+
the Sprint 3 harness (#71) on also `trio`:
|
|
439
519
|
|
|
440
520
|
| Scenario | What the controller does | What is checked |
|
|
441
521
|
| --- | --- | --- |
|
|
442
|
-
| `parallel` | Capabilities first;
|
|
443
|
-
| `abort` | Two sessions on `wait` (a bounded `sleep 120` command) and `range` (a bounded `sleep 45`, then the change); abort `wait` about 15 seconds after both turns started, while `range` runs; verify and close both | Every
|
|
522
|
+
| `parallel` | Capabilities first; a session of `accept-code-handshake` on `slug` and one of `accept-code` on `stats` (before the Sprint 2 harness: `accept-code` for both); both first turns started before waiting; one follow-up in the `slug` session that adds a test and completes the handshake from the worker's skills; own verification; close both | Candidate version and configuration fingerprint seen through capabilities; `skills` of both coding profiles and the profile of each session; first turns overlap by the server's `startedAt` and `completedAt`; follow-up completed; tests pass and only allowed files changed; handshake file holds the token although no prompt contained it |
|
|
523
|
+
| `abort` | Two sessions of `accept-code` on `wait` (a bounded `sleep 120` command) and `range` (a bounded `sleep 45`, then the change); abort `wait` about 15 seconds after both turns started, while `range` runs; verify and close both | Every `pi_session_abort` call of the transcript is `ok` and targets the `wait` session (an `abort_timeout`, an unknown session id or an abort on `range` stays on record and fails, also after a retry); the first successful abort comes before `pi_turn_get` shows the `wait` turn `aborted`, and both before its session is closed; its abort time lies inside the running interval of `range`; `range` completed and verified; at the end of the run no late file exists and no worker `sleep` remains |
|
|
524
|
+
| `trio` | Capabilities first; three sessions whose first turns start in the order `review`, `slug`, `wait`, all before waiting for any: `accept-read` on `review` (an enumerated read-only review of the frozen `review` fixture, one finding per exported function with a line reference), `accept-code` on `slug` (a bounded `sleep 45`, then the change, only in `src/slug.js`) and on `wait` (a bounded `sleep 120`); abort `wait` about 5 seconds after its turn was accepted, while `slug` and `review` run; own verification of `slug`; confirm `review` changed nothing; close all three; no handshake | Candidate version and configuration fingerprint seen through capabilities; three sessions, each on its expected alias and profile; `accept-read` offers exactly `review` and only the `review` session used it; all three first turns overlap; every `pi_session_abort` call is `ok` and on `wait`, the first successful abort comes before `wait` is seen `aborted`, both before close; the abort lies inside the running intervals of both `slug` and `review`; `slug` and `review` completed; `slug` tests pass; the `review` fixture is byte-identical in working tree, index and `HEAD`, with no empty directory; `wait` leaves no late file; no worker `sleep` remains |
|
|
444
525
|
|
|
445
526
|
### Independent checks
|
|
446
527
|
|
|
@@ -482,6 +563,8 @@ Each client runs two invocations, one per scenario:
|
|
|
482
563
|
- the controller exit code is 0 (`controllerExit`), neither `timedOut`,
|
|
483
564
|
`spawnFailed` nor `harnessAborted` is set, and the analysis finished
|
|
484
565
|
(`analysisFailed`);
|
|
566
|
+
- every bound resource was completely readable when recorded and after the
|
|
567
|
+
run (`resourcesUnbound`);
|
|
485
568
|
- no bound resource changed after the run (`resourcesChanged`), and for a
|
|
486
569
|
reanalysis no resource or fixture differs from the state recorded at the
|
|
487
570
|
end of the run (`stateChangedSinceRun`);
|
|
@@ -489,8 +572,15 @@ Each client runs two invocations, one per scenario:
|
|
|
489
572
|
process of the run remains (`residualProcesses`);
|
|
490
573
|
- the controller called `pi_capabilities_get` first (`capabilitiesNotFirst`),
|
|
491
574
|
saw the candidate version and configuration fingerprint
|
|
492
|
-
(`candidateNotConfirmed`)
|
|
493
|
-
`
|
|
575
|
+
(`candidateNotConfirmed`), saw exactly the skill `implementation` on
|
|
576
|
+
`accept-code` and exactly `implementation` and `handshake` on
|
|
577
|
+
`accept-code-handshake`, and only the `slug` session used
|
|
578
|
+
`accept-code-handshake` while every other session used `accept-code`
|
|
579
|
+
(`workerSkills`; before the Sprint 2 harness: exactly `implementation` and
|
|
580
|
+
`handshake` on `accept-code`). In `trio` there is no handshake: `slug` and
|
|
581
|
+
`wait` use `accept-code`, `accept-read` offers exactly `review`, and only the
|
|
582
|
+
`review` session may use `accept-read`; in `parallel` and `abort` no session
|
|
583
|
+
uses `accept-read`;
|
|
494
584
|
- the structural leak scan found nothing (`structuralLeaks`), the token
|
|
495
585
|
appears nowhere it must not (`tokenExposed`), and no worker prompt or
|
|
496
586
|
controller action touched a private marker (`privateAccess`);
|
|
@@ -499,13 +589,31 @@ Each client runs two invocations, one per scenario:
|
|
|
499
589
|
overlapped (`noOverlap`) and the follow-up completed
|
|
500
590
|
(`followUpNotCompleted`);
|
|
501
591
|
- `abort`: the `wait` turn ended `aborted` after only successful aborts
|
|
502
|
-
(`abortFailed`),
|
|
592
|
+
(`abortFailed`), every abort call on the `wait` session
|
|
593
|
+
(`offTargetAbort`), in the required order and before its session closed
|
|
503
594
|
(`abortOrder`), and `range` completed with the abort inside its running
|
|
504
595
|
interval (`neighborNotRunningDuringAbort`);
|
|
596
|
+
- `trio`: exactly three sessions started (`sessionsNotStarted`), each on its
|
|
597
|
+
expected workspace alias and profile (`sessionAssociation`); the `slug` and
|
|
598
|
+
`review` first turns completed (`firstTurnsNotCompleted`) and all three
|
|
599
|
+
first turns overlapped (`noOverlap`); the `wait` turn ended `aborted` after
|
|
600
|
+
only successful aborts (`abortFailed`) and only on `wait`
|
|
601
|
+
(`offTargetAbort`), in the required order and before
|
|
602
|
+
close (`abortOrder`), with the abort inside the running intervals of both
|
|
603
|
+
`slug` and `review` (`neighborsNotRunningDuringAbort`); the `review` fixture
|
|
604
|
+
is unchanged in working tree, index and `HEAD`, `HEAD` is still its base
|
|
605
|
+
commit, and no empty directory appeared (`review:readOnly`); the `slug`
|
|
606
|
+
task of `trio` may change only `src/slug.js`, while `test/slug.test.js`
|
|
607
|
+
and `HANDSHAKE.txt` stay allowed in `parallel` only. The read-only check
|
|
608
|
+
compares the end state with the baseline, so a write reverted before the
|
|
609
|
+
end, a `git stash`, new refs or branches and directory-mode changes are not
|
|
610
|
+
seen; the read-only profile is the actual guard;
|
|
505
611
|
- per fixture: only allowed changes (`<task>:changes`), every change written
|
|
506
612
|
during a worker turn (`<task>:attribution`), fixture tests and business
|
|
507
|
-
checks passing (`<task>:tests`), for `slug` the added test
|
|
508
|
-
handshake (`slug:followUp`), for `
|
|
613
|
+
checks passing (`<task>:tests`), for `slug` in `parallel` the added test
|
|
614
|
+
and the handshake (`slug:followUp`), for `review` the read-only invariance
|
|
615
|
+
(`review:readOnly`) instead of tests, for `wait` no late file
|
|
616
|
+
(`wait:lateFile`),
|
|
509
617
|
and an oracle for every task of the scenario (`oracleMissing`).
|
|
510
618
|
- Liveness observation: for each turn of a session, `turnLiveness` records the
|
|
511
619
|
number of `pi_turn_get` polls that saw the turn `running` and whether
|
|
@@ -530,7 +638,8 @@ Each client runs two invocations, one per scenario:
|
|
|
530
638
|
- `evidence` writes one sanitized JSON record and refuses to write a local path
|
|
531
639
|
or the token. It lists the original results and the reanalyses separately,
|
|
532
640
|
lists every launch with whether it left a result, and includes the extension
|
|
533
|
-
names and versions and the
|
|
641
|
+
names and versions, the resource digests, the profiles and, from the Sprint 2
|
|
642
|
+
harness on, the controller skill kinds and digests.
|
|
534
643
|
Transcripts and the configuration stay in the run's private directory and
|
|
535
644
|
are never published.
|
|
536
645
|
|
|
@@ -555,6 +664,19 @@ limits, which that change removed:
|
|
|
555
664
|
client to close without a bound. A hang would have shown as a hang, not as a
|
|
556
665
|
pass.
|
|
557
666
|
|
|
667
|
+
Records made with the harness before Sprint 2 (#66, #67, #68) have these
|
|
668
|
+
further method limits:
|
|
669
|
+
|
|
670
|
+
- Pi extensions were bound by name and version only, not by the package
|
|
671
|
+
contents the server loaded, and the run's server did not receive the agent
|
|
672
|
+
directory explicitly.
|
|
673
|
+
- For Codex, only `~/.agents/skills/pi-session-orchestration` was checked;
|
|
674
|
+
`$CODEX_HOME/skills`, `/etc/codex/skills`, other home skills and ancestor
|
|
675
|
+
`.agents/skills` were neither bound nor excluded, and the controller
|
|
676
|
+
inherited `CODEX_HOME` from the launching environment.
|
|
677
|
+
- The `handshake` skill was offered to every task's worker; this is how the
|
|
678
|
+
v0.8.1 Codex `abort` run's worker could apply it to an unrequested file.
|
|
679
|
+
|
|
558
680
|
These limits do not show that any recorded result was wrong. The records stay
|
|
559
681
|
as recorded; a new run gets a new record.
|
|
560
682
|
|
|
@@ -573,6 +695,13 @@ as recorded; a new run gets a new record.
|
|
|
573
695
|
|
|
574
696
|
## Status
|
|
575
697
|
|
|
698
|
+
Targeted records below, the Pi extension live check and the multi-session
|
|
699
|
+
skill acceptance with one or two concurrent sessions, are not Level 3 cycles
|
|
700
|
+
even where they used a real controller or a real model. The wording "passed all
|
|
701
|
+
three levels" refers to earlier private cycles only; the full ten-task Level 3
|
|
702
|
+
cycle has not been repeated on Pi SDK `1.x`. This note adds no result and
|
|
703
|
+
changes none.
|
|
704
|
+
|
|
576
705
|
Release notes state which levels were run for a release and what was not
|
|
577
706
|
covered. Pi Session MCP has passed all three levels in earlier private cycles. The
|
|
578
707
|
live two-client acceptance has not yet been repeated on a build with Pi SDK
|
|
@@ -1204,3 +1333,245 @@ release candidate `baa6406` on Linux (`x64`), with Node.js `26.11.1`, Codex CLI
|
|
|
1204
1333
|
`0c7bad3`. Its built modules have the same dist tree SHA-256
|
|
1205
1334
|
(`7b16757f9a1a0318247914f56debe79119a3845e1a1debcf1ad371db3a958fce`) as the
|
|
1206
1335
|
final candidate `1e904be` of the multi-session acceptance recorded above.
|
|
1336
|
+
|
|
1337
|
+
### v0.8.1 post-release evidence carried over from the release notes
|
|
1338
|
+
|
|
1339
|
+
The post-release results of `v0.8.1` were recorded in the [v0.8.1 release
|
|
1340
|
+
notes](https://github.com/plagor44-ux/pi-session-mcp/releases/tag/v0.8.1),
|
|
1341
|
+
published on 2026-10-12 (22:06 UTC), and were carried over into this document
|
|
1342
|
+
on 2026-10-13 as roadmap item R19. This is a historical record taken from
|
|
1343
|
+
those notes: the checks were not rerun for it, and every item below keeps the
|
|
1344
|
+
scope, result and limitation that the notes state. The pre-release results of
|
|
1345
|
+
the same release candidate are recorded above.
|
|
1346
|
+
|
|
1347
|
+
Source and CI, as stated in the notes:
|
|
1348
|
+
- Release source and annotated tag target: `e462054a37505ef00e1e0c549ebab27e4db7ef55`,
|
|
1349
|
+
the merge of #55 (head `440f2e4ccb4f7cebd88825abd8515218f4bbbdee`). The
|
|
1350
|
+
annotated tag object is `02f0b30588115058fbb30148cb0934f18cf05aa3`.
|
|
1351
|
+
- #55 passed CI on Linux, macOS 15 and macOS 26. The merged-main CI run
|
|
1352
|
+
`38309519719` and the tag CI run `38309738675` are named in the notes. CI is
|
|
1353
|
+
neither Level 2 nor Level 3 acceptance.
|
|
1354
|
+
|
|
1355
|
+
Provider-free (Level 1), on a fresh clone of the tag, with Node.js `26.11.1`
|
|
1356
|
+
and npm `12.2.0`. Every command exited with `0`:
|
|
1357
|
+
- Typecheck, server build and CLI build.
|
|
1358
|
+
- 50 test files: 1035 passed and 6 skipped.
|
|
1359
|
+
- `npm audit` and `npm audit --omit=dev`: 0 vulnerabilities.
|
|
1360
|
+
- Offline Doctor: package version `0.8.1`. With the example configuration, the
|
|
1361
|
+
only finding was its placeholder workspace.
|
|
1362
|
+
|
|
1363
|
+
Package publication, a release fact and not an acceptance level: the npm
|
|
1364
|
+
package `pi-session-mcp@0.8.1` was published from a fresh clone of the tag
|
|
1365
|
+
through staged publishing, approved by the maintainer. It has 129 files and
|
|
1366
|
+
215.6 kB, with shasum `b39fe48aff6ade4bf52c427960593951e150191b`. The tarball
|
|
1367
|
+
downloaded from the registry has the same SHA-1 and SHA-512 integrity. The
|
|
1368
|
+
package has no provenance attestation, because it was published from the
|
|
1369
|
+
maintainer's machine.
|
|
1370
|
+
|
|
1371
|
+
Real clients without a model (Level 2), with `scripts/setup-acceptance.mjs`:
|
|
1372
|
+
160 of 160 checks passed in each of three variants:
|
|
1373
|
+
- the release candidate's working tree (`baa6406`);
|
|
1374
|
+
- a fresh clone of the tag;
|
|
1375
|
+
- the npm package installed into a temporary prefix.
|
|
1376
|
+
|
|
1377
|
+
The clients were Codex CLI `0.162.1` (`user`) and Claude Code `2.1.296`
|
|
1378
|
+
(`user`, `project`, `local`), in disposable homes. The real client
|
|
1379
|
+
registrations were unchanged, no process remained, and the build stayed
|
|
1380
|
+
byte-identical. The notes do not state the platform of these variants; the
|
|
1381
|
+
pre-release run of the candidate above states Linux (`x64`).
|
|
1382
|
+
|
|
1383
|
+
Real model, targeted multi-session skill acceptance (not a Level 3 cycle), on
|
|
1384
|
+
the final code candidate `1e904be`, whose built modules equal this release's
|
|
1385
|
+
(dist tree SHA-256 `7b16757f…`, abbreviated in the notes; the full value is
|
|
1386
|
+
recorded above). The detailed record is in the multi-session section above.
|
|
1387
|
+
- Controllers: Claude Code `2.1.296` and Codex CLI `0.162.1`. Workers: Cursor
|
|
1388
|
+
(`pi-cursor-sdk@0.5.3`, `composer-2.5`) on Pi SDK `1.1.0`.
|
|
1389
|
+
- Both required Claude Code scenarios passed every check: two overlapping
|
|
1390
|
+
sessions with a same-session follow-up, and a targeted abort while the
|
|
1391
|
+
neighbor kept running.
|
|
1392
|
+
- `updatedAt` had moved past `startedAt` in every Cursor turn polled while
|
|
1393
|
+
running: 31 of 31 across four runs.
|
|
1394
|
+
|
|
1395
|
+
Limitations and failures stated in the notes:
|
|
1396
|
+
- No full ten-task Level 3 cycle. The multi-session check is targeted.
|
|
1397
|
+
- Live acceptance ran on Linux only, with Cursor (`pi-cursor-sdk@0.5.3`,
|
|
1398
|
+
`composer-2.5`) workers. macOS is covered by CI.
|
|
1399
|
+
- Not live-proven: a Codex controller reading the skill from a copy installed
|
|
1400
|
+
in `~/.agents/skills`; a third concurrent or `read-only` worker; a real crash
|
|
1401
|
+
in the middle of a setup skill update (provider-free tests cover it).
|
|
1402
|
+
- In the final run, the supplementary Codex `abort` invocation failed its scope
|
|
1403
|
+
check: the Cursor worker applied the `handshake` test skill on its own. The
|
|
1404
|
+
required Claude Code invocations and Codex `parallel` passed, and Codex
|
|
1405
|
+
`abort` had passed on earlier runs of the same build.
|
|
1406
|
+
|
|
1407
|
+
### v0.8.2 pre-release acceptance
|
|
1408
|
+
|
|
1409
|
+
Before its release, `v0.8.2` passed Level 1 and the working-tree Level 2 on its
|
|
1410
|
+
release candidate `bdbdf00` on Linux (`x64`), with Node.js `26.11.1`, Codex CLI
|
|
1411
|
+
`0.162.1` and Claude Code `2.1.296`, on 2026-10-13:
|
|
1412
|
+
- Level 1 on the release branch: every command exited with `0`.
|
|
1413
|
+
- The test run, with `NODE_OPTIONS=--unhandled-rejections=strict`, reported
|
|
1414
|
+
54 files, 1409 passed and 6 skipped, and no unhandled error.
|
|
1415
|
+
- `npm audit` and `npm audit --omit=dev` reported 0 vulnerabilities.
|
|
1416
|
+
- `npm pack --dry-run` listed 135 files, including the three skills, and
|
|
1417
|
+
no acceptance harness, sources, tests, lockfile or implementation plan.
|
|
1418
|
+
- Doctor reported `packageVersion` `0.8.2`. With the example configuration
|
|
1419
|
+
its only finding was the placeholder workspace.
|
|
1420
|
+
- Level 2 through `scripts/setup-acceptance.mjs` on the candidate's working
|
|
1421
|
+
tree: 160 of 160 checks passed. All nine steps passed on all four targets.
|
|
1422
|
+
The real client registrations were unchanged, no process remained, and the
|
|
1423
|
+
built files were unchanged.
|
|
1424
|
+
- Apart from the version and documentation, the candidate's sources equal
|
|
1425
|
+
`166ffef`, current main; its runtime sources (`src/`, `skills/`) equal
|
|
1426
|
+
those of `0aae639`, on which Sprint 3 ran. Its built modules have the same
|
|
1427
|
+
`dist/main.js` SHA-256 (`47875d38886528ace6b242df2c6ad79d624c51e330e63c2f401576eadc449ed7`)
|
|
1428
|
+
and `dist` tree as the build on which the
|
|
1429
|
+
[Sprint 3 live acceptance](#sprint-3-live-acceptance-2026-10-13) ran, including
|
|
1430
|
+
the accepted ten-task Level 3 cycle.
|
|
1431
|
+
|
|
1432
|
+
## Sprint 1 correctness checks (2026-10-13)
|
|
1433
|
+
|
|
1434
|
+
These checks belong to [#59](https://github.com/plagor44-ux/pi-session-mcp/issues/59)
|
|
1435
|
+
(recovery keeps unprovable trash) and
|
|
1436
|
+
[#56](https://github.com/plagor44-ux/pi-session-mcp/issues/56) (verify
|
|
1437
|
+
diagnostics). They were run on 2026-10-13 against the Sprint 1 branch
|
|
1438
|
+
`fix/59-56-s1-correctness`, before merge and without a release. The
|
|
1439
|
+
[Sprint 1 file](sprints/2026-10-13-s1-correctness.md) holds the commands,
|
|
1440
|
+
source binding, before-fix evidence and review findings in full.
|
|
1441
|
+
|
|
1442
|
+
Source: base main `3e360dd`; runtime candidate
|
|
1443
|
+
`fa32c22b573ff0bb0b920813bd9520bb79b025f4`, the last commit that changes `src/`
|
|
1444
|
+
or `test/`. Native Linux (x64), Node.js `26.11.1`, npm `12.2.0`, Codex CLI
|
|
1445
|
+
`0.162.1`, Claude Code `2.1.296`. No provider, model or credential was used.
|
|
1446
|
+
|
|
1447
|
+
Provider-free (Level 1), on `fa32c22`:
|
|
1448
|
+
|
|
1449
|
+
| Check | Exit | Result |
|
|
1450
|
+
| --- | --- | --- |
|
|
1451
|
+
| `npm ci`, `npm run typecheck`, `npm run build:cli`, `npm run build` | 0 each | |
|
|
1452
|
+
| `NODE_OPTIONS=--unhandled-rejections=strict npm test` | 0 | 52 files passed; 1121 tests passed, 6 skipped, 0 failed; no unhandled error |
|
|
1453
|
+
| `npm audit`, `npm audit --omit=dev` | 0 each | 0 vulnerabilities |
|
|
1454
|
+
| `git diff --check`, `git status --short` | 0 each | clean |
|
|
1455
|
+
| #59 counterexamples for `apply`, `remove` and `rollback` (`test/setup-skills-trash-preservation.test.ts`) and the adapted SIGKILL recovery tests | 0 | All pass. On the unfixed base 24 of the 30 counterexamples failed on the defect itself (`skill_recovered` or `skill_removed` where `skill_recovery_retained` was required). |
|
|
1456
|
+
| #56 counterexamples (`test/setup-verify-diagnostics.test.ts`) | 0 | All 53 pass. On the unfixed base 19 failed on the defect itself (`registration_not_equivalent` for unsupported and throwing inspections, and inspection or handshake after a failed Doctor). |
|
|
1457
|
+
|
|
1458
|
+
On the documentation head that followed, `npm pack --dry-run` listed 132 files
|
|
1459
|
+
without `src/`, `test/`, lockfile or implementation plans, and a relative link
|
|
1460
|
+
and anchor check of the changed documentation found no problem.
|
|
1461
|
+
|
|
1462
|
+
Real clients without a model (Level 2), on the build of the same runtime
|
|
1463
|
+
sources (`dist/main.js` SHA-256 `47875d38886528ace6b242df2c6ad79d624c51e330e63c2f401576eadc449ed7`):
|
|
1464
|
+
|
|
1465
|
+
- `scripts/setup-acceptance.mjs`: 160 of 160 checks passed, exit `0`, for
|
|
1466
|
+
`codex:user` and `claude-code:user`, `project` and `local` in disposable
|
|
1467
|
+
homes. Real registrations unchanged, no remaining process, no path leak,
|
|
1468
|
+
build unchanged.
|
|
1469
|
+
- New #56 negative case, outside the harness: with the client CLI not on
|
|
1470
|
+
`PATH`, `--verify` reported `unsupported (unsupported)` in human and JSON
|
|
1471
|
+
form and `--dry-run` reported `unsupported (unsupported)`, each with exit
|
|
1472
|
+
`1`, for Codex `user` and Claude Code `user`. The registration was unchanged
|
|
1473
|
+
during these steps, and no output contained a path. The same steps on the
|
|
1474
|
+
built base reproduced #56 (`registration_not_equivalent`).
|
|
1475
|
+
|
|
1476
|
+
Not established by these checks: the result on macOS (only CI covers it
|
|
1477
|
+
there), the final pull-request head's CI matrix, a real operating-system crash
|
|
1478
|
+
during a skill update (the interruption tests use a checkpoint and SIGKILL,
|
|
1479
|
+
the counterexamples a scripted checkpoint), and any model behavior. A dry-run
|
|
1480
|
+
of a pending recovery can still announce a recovery that apply retains; that
|
|
1481
|
+
is tracked as [#60](https://github.com/plagor44-ux/pi-session-mcp/issues/60).
|
|
1482
|
+
Note added in Sprint 2: #60 changes this dry-run behavior; see the
|
|
1483
|
+
[Sprint 2 checks](#sprint-2-evidence-checks-2026-10-13). The Sprint 1 record
|
|
1484
|
+
above is unchanged.
|
|
1485
|
+
|
|
1486
|
+
Open gates that Sprint 1 does not close:
|
|
1487
|
+
- Level 3: no full ten-task cycle on Pi SDK `1.x`, and none for the profile
|
|
1488
|
+
intended for use.
|
|
1489
|
+
- Current macOS Level 2 on real hardware with both clients. CI covers macOS;
|
|
1490
|
+
it does not replace that.
|
|
1491
|
+
- Live discovery of the Codex home skill that setup installs.
|
|
1492
|
+
- Multi-session operation beyond two sessions, including a third concurrent
|
|
1493
|
+
worker and a `read-only` worker.
|
|
1494
|
+
|
|
1495
|
+
## Sprint 2 evidence checks (2026-10-13)
|
|
1496
|
+
|
|
1497
|
+
These checks belong to [#60](https://github.com/plagor44-ux/pi-session-mcp/issues/60),
|
|
1498
|
+
[#62](https://github.com/plagor44-ux/pi-session-mcp/issues/62),
|
|
1499
|
+
[#63](https://github.com/plagor44-ux/pi-session-mcp/issues/63) and the harness
|
|
1500
|
+
issues [#66](https://github.com/plagor44-ux/pi-session-mcp/issues/66),
|
|
1501
|
+
[#67](https://github.com/plagor44-ux/pi-session-mcp/issues/67) and
|
|
1502
|
+
[#68](https://github.com/plagor44-ux/pi-session-mcp/issues/68). They ran on
|
|
1503
|
+
2026-10-13 on branch `fix/s2-evidence`, before merge and without a release.
|
|
1504
|
+
The [Sprint 2 file](sprints/2026-10-13-s2-evidence.md) holds the commands,
|
|
1505
|
+
before-fix evidence, every gate run and the review rounds.
|
|
1506
|
+
|
|
1507
|
+
Source: base main `b145f8c`; final runtime candidate `923a393`, the last commit
|
|
1508
|
+
that changes `src/`, `scripts/`, `test/`, `skills/` or CI; native Linux
|
|
1509
|
+
(x64), Node.js `26.11.1`, npm `12.2.0`, Codex CLI `0.162.1`, Claude Code
|
|
1510
|
+
`2.1.296`. No provider, model or credential was used.
|
|
1511
|
+
|
|
1512
|
+
Provider-free (Level 1), on the documentation head `07f56b6` of that runtime:
|
|
1513
|
+
`npm ci`, typecheck, `build:cli`,
|
|
1514
|
+
`NODE_OPTIONS=--unhandled-rejections=strict npm test` (54 files; 1300 passed,
|
|
1515
|
+
6 skipped, 0 failed; no unhandled error), build, `npm audit` and
|
|
1516
|
+
`npm audit --omit=dev` (0 vulnerabilities), `git diff --check` and a clean
|
|
1517
|
+
status all exited with `0`. On the unfixed base, the new #60 counterexamples
|
|
1518
|
+
failed 14 of 23 on the defect itself (`skill_recovery_planned` where
|
|
1519
|
+
`skill_recovery_retained` was required).
|
|
1520
|
+
|
|
1521
|
+
Pi SDK canary: the published `1.2.0` is compatible with the candidate's
|
|
1522
|
+
sources (typecheck and the 12 SDK-facing test files passed); the pin stays
|
|
1523
|
+
`1.1.0`. This is not an SDK update.
|
|
1524
|
+
|
|
1525
|
+
Real clients without a model (Level 2): `scripts/setup-acceptance.mjs` passed
|
|
1526
|
+
160 of 160 checks, exit `0`, on the build that the final head also produces
|
|
1527
|
+
(`dist` JS tree SHA-256 `f85bf73ee8c0ddb2270d8d6040feffbc49f018d2e6ab6253fffb828654a389df`),
|
|
1528
|
+
for `codex:user` and `claude-code:user`, `project` and `local`; real
|
|
1529
|
+
registrations unchanged, no remaining process, no path leak.
|
|
1530
|
+
|
|
1531
|
+
The multi-session harness changes (#66, #67, #68) were verified with
|
|
1532
|
+
provider-free tests only: no live multi-session run used them yet. A live run
|
|
1533
|
+
belongs to Sprint 3.
|
|
1534
|
+
|
|
1535
|
+
Open gates that Sprint 2 does not close: the final-head CI of the pull request,
|
|
1536
|
+
a live run with the new harness bindings, and every Sprint 1 open gate above.
|
|
1537
|
+
|
|
1538
|
+
## Sprint 3 live acceptance (2026-10-13)
|
|
1539
|
+
|
|
1540
|
+
Recorded on 2026-10-13 against main `0aae639` (package `0.8.1` plus the
|
|
1541
|
+
unreleased Sprint 1 and 2 changes; `dist/main.js` SHA-256 `47875d38…`), on
|
|
1542
|
+
native Linux x64 with Node.js `26.11.1`, Claude Code `2.1.296` and Codex CLI
|
|
1543
|
+
`0.162.1`. The [Sprint 3 file](sprints/2026-10-13-s3-live-usage.md) holds the
|
|
1544
|
+
pre-registration, every command and the review rounds. Worker profiles are
|
|
1545
|
+
the maintainer's intended pair, copied without its read-only external MCP
|
|
1546
|
+
grant: read-only OpenAI `gpt-6-luna` (`low`) and coding DeepSeek
|
|
1547
|
+
`deepseek-flash` (`high`).
|
|
1548
|
+
|
|
1549
|
+
Level 3 (R05, R09): one ten-task cycle with both controllers, pre-registered,
|
|
1550
|
+
strictly sequential. Accepted: 10 of 10 tasks reached their intended outcome
|
|
1551
|
+
and every gate condition held, including the coding barrier for both clients
|
|
1552
|
+
(in Codex's read-only sandbox too), read-only invariance, no change outside the
|
|
1553
|
+
approved diff, no public leak, no session or process left after a verified
|
|
1554
|
+
close, and Level 1 green for the release source. Every running turn was seen
|
|
1555
|
+
in at most one `pi_turn_get` poll. This is the first full cycle on Pi SDK `1.x`;
|
|
1556
|
+
it covers this provider pair on Linux only.
|
|
1557
|
+
|
|
1558
|
+
Targeted multi-session evidence (not Level 3), with
|
|
1559
|
+
`scripts/multi-session-acceptance.mjs`:
|
|
1560
|
+
|
|
1561
|
+
- R06, Codex `abort` (DeepSeek workers): passed, including the strict scope
|
|
1562
|
+
oracle that failed the v0.8.1 Codex abort run.
|
|
1563
|
+
- R08, `trio` (three concurrent sessions, a read-only reviewer of a frozen
|
|
1564
|
+
fixture, a neighbor abort): Codex passed; Claude Code failed only
|
|
1565
|
+
`neighborsNotRunningDuringAbort`, because the read-only review finished 6.7 s
|
|
1566
|
+
before the abort. The failed run stays on record
|
|
1567
|
+
([#74](https://github.com/plagor44-ux/pi-session-mcp/issues/74)).
|
|
1568
|
+
|
|
1569
|
+
Real client discovery (R07): a real Codex run in an isolated home found the
|
|
1570
|
+
controller skill that setup had installed as a regular copy, named that copy's
|
|
1571
|
+
path and quoted a line that exists only in the revision under test; no manual
|
|
1572
|
+
link was needed.
|
|
1573
|
+
|
|
1574
|
+
Not established: macOS (R10, R11; runbook in the Sprint 3 file), other
|
|
1575
|
+
providers and models, the operator profiles' external MCP grant, larger tasks,
|
|
1576
|
+
more than three concurrent sessions, and the `trio` timing with Claude Code as
|
|
1577
|
+
controller.
|