pi-session-mcp 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.pi-session-mcp-cli/config.js +47 -7
- package/.pi-session-mcp-cli/doctor.js +68 -2
- package/.pi-session-mcp-cli/execution-profile.js +1 -0
- package/.pi-session-mcp-cli/extension-spec.js +7 -2
- package/.pi-session-mcp-cli/setup-result.js +8 -0
- package/.pi-session-mcp-cli/skill-catalog.js +35 -0
- package/.pi-session-mcp-cli/skill-customize.js +183 -0
- package/.pi-session-mcp-cli/skill-library.js +120 -0
- package/CHANGELOG.md +110 -0
- package/README.md +15 -3
- package/dist/capabilities.d.ts +1 -0
- package/dist/capabilities.js +2 -1
- package/dist/client-adapters/mcp-verifier.js +6 -2
- package/dist/config.d.ts +4 -0
- package/dist/config.js +47 -7
- package/dist/doctor.d.ts +4 -1
- package/dist/doctor.js +68 -2
- package/dist/execution-profile.d.ts +4 -0
- package/dist/execution-profile.js +1 -0
- package/dist/extension-spec.js +7 -2
- package/dist/pi-adapter.d.ts +1 -1
- package/dist/pi-adapter.js +1 -0
- package/dist/pi-skills.d.ts +17 -0
- package/dist/pi-skills.js +64 -0
- package/dist/sdk-pi-adapter.d.ts +7 -3
- package/dist/sdk-pi-adapter.js +57 -11
- package/dist/server.js +1 -0
- package/dist/session-tools.d.ts +1 -1
- package/dist/session-tools.js +20 -4
- package/dist/setup-cli.d.ts +2 -0
- package/dist/setup-cli.js +16 -0
- package/dist/setup-main.d.ts +1 -1
- package/dist/setup-main.js +18 -3
- package/dist/setup-ownership.d.ts +6 -0
- package/dist/setup-ownership.js +29 -5
- package/dist/setup-skills.d.ts +37 -0
- package/dist/setup-skills.js +353 -0
- package/dist/setup.d.ts +7 -0
- package/dist/setup.js +49 -6
- package/dist/skill-catalog.d.ts +26 -0
- package/dist/skill-catalog.js +35 -0
- package/dist/skill-customize.d.ts +23 -0
- package/dist/skill-customize.js +183 -0
- package/dist/skill-library.d.ts +61 -0
- package/dist/skill-library.js +120 -0
- package/docs/acceptance.md +372 -3
- package/docs/adr/0006-pi-extension-allowlist.md +5 -2
- package/docs/adr/0007-profile-skill-selection.md +217 -0
- package/docs/architecture.md +9 -5
- package/docs/client-setup-design.md +133 -1
- package/docs/client-setup.md +74 -3
- package/docs/doctor-design.md +9 -1
- package/docs/installation.md +129 -9
- package/docs/pi-extensions-design.md +41 -12
- package/docs/releasing.md +15 -6
- package/docs/session-mcp.md +7 -2
- package/docs/skills.md +487 -0
- package/docs/threat-model.md +21 -4
- package/docs/tool-contracts.md +9 -5
- package/package.json +3 -1
- package/pi-session-mcp.example.json +9 -3
- package/skills/pi-session-implementation/SKILL.md +42 -0
- package/skills/pi-session-orchestration/SKILL.md +93 -0
- package/skills/pi-session-review/SKILL.md +58 -0
- package/docs/superpowers/plans/2026-10-10-macos-setup.md +0 -1725
- package/docs/superpowers/plans/2026-10-11-pi-extensions.md +0 -2450
package/docs/acceptance.md
CHANGED
|
@@ -97,7 +97,12 @@ env -i HOME="$DISPOSABLE_HOME" PATH="$PATH" PI_SESSION_MCP_CONFIG="$ACCEPTANCE_C
|
|
|
97
97
|
### Pass criteria
|
|
98
98
|
|
|
99
99
|
- All nine operations report the expected overall status, finding and exit
|
|
100
|
-
status.
|
|
100
|
+
status. From the change that tracks #46 on, every operation also reports the
|
|
101
|
+
controller skill finding (`skill_absent` twice, `skill_installed`,
|
|
102
|
+
`skill_already_equivalent`, `skill_verified`, `skill_removed`,
|
|
103
|
+
`skill_installed`, `skill_verified`, `skill_removed`); the skill file exists
|
|
104
|
+
after steps 3 and 7 and is gone after steps 6 and 9; a foreign skill placed
|
|
105
|
+
in the same skill directory stays unchanged throughout.
|
|
101
106
|
- Steps 1 and 2 leave the client state unchanged.
|
|
102
107
|
- After step 9 the `pi-session-mcp` registration is absent, the sentinel is still
|
|
103
108
|
present, and the ownership record set is empty. The ownership directory has
|
|
@@ -124,6 +129,55 @@ that checkout with Doctor reporting the release version, and confirms that the
|
|
|
124
129
|
manifests and built runtime files are byte-identical before and after the
|
|
125
130
|
client cycles.
|
|
126
131
|
|
|
132
|
+
### Tooling
|
|
133
|
+
|
|
134
|
+
`scripts/setup-acceptance.mjs` runs the isolation, the sequence and the pass
|
|
135
|
+
criteria above with the real clients. It uses disposable homes below its work
|
|
136
|
+
directory (default `~/.cache/pi-session-mcp-acceptance`, never below `/tmp`,
|
|
137
|
+
`/var/tmp`, `/dev/shm` or `$TMPDIR`), removes them afterwards (also after Ctrl-C
|
|
138
|
+
or SIGTERM, with exit `130` or `143`) and writes a sanitized JSON result without
|
|
139
|
+
paths or environment values. It exits with `0` when every check passed, `1` when
|
|
140
|
+
a check failed and `2` on a usage, environment or harness error.
|
|
141
|
+
|
|
142
|
+
`--setup` is split on whitespace, so paths in it must not contain spaces. Its
|
|
143
|
+
first token must be an absolute path to an existing file or a command found on
|
|
144
|
+
`PATH`; otherwise the script exits with `2`.
|
|
145
|
+
|
|
146
|
+
The script only reads the real `~/.codex/config.toml` and `~/.claude.json` to
|
|
147
|
+
prove that the MCP registrations in them did not change. A file that does not
|
|
148
|
+
exist counts as the constant digest `absent`; one that exists but cannot be read
|
|
149
|
+
fails the check. A real client session that changes its own MCP registrations
|
|
150
|
+
during the run makes the digest check fail (a false fail), so close or idle real
|
|
151
|
+
clients first.
|
|
152
|
+
|
|
153
|
+
Working tree, after `npm run build` and `npm run build:cli`:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
node scripts/setup-acceptance.mjs \
|
|
157
|
+
--setup "node $PWD/dist/setup-main.js" --build-dir "$PWD" \
|
|
158
|
+
--label working-tree --out level2-result.json
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Published package: install it into a temporary prefix outside `/tmp`, then pass
|
|
162
|
+
the installed executable and package directory.
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
npm install -g --prefix "$PREFIX" pi-session-mcp@<version>
|
|
166
|
+
node scripts/setup-acceptance.mjs \
|
|
167
|
+
--setup "$PREFIX/bin/pi-session-mcp-setup" \
|
|
168
|
+
--build-dir "$PREFIX/lib/node_modules/pi-session-mcp" \
|
|
169
|
+
--label npm-<version> --out level2-result.json
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Tag clone: build a fresh clone of the tag (`npm ci`, `npm run build`,
|
|
173
|
+
`npm run build:cli`) and use it like the working tree, with `--setup` and
|
|
174
|
+
`--build-dir` pointing at the clone.
|
|
175
|
+
|
|
176
|
+
`--clients codex` or `--clients claude-code` limits a run to one client, for
|
|
177
|
+
example on a macOS machine without Codex. The script does not cover the macOS
|
|
178
|
+
lock-contention and interruption steps, Level 1, or the tag identity checks
|
|
179
|
+
(tag object, peeled commit, `git describe`). Run those by hand.
|
|
180
|
+
|
|
127
181
|
### macOS
|
|
128
182
|
|
|
129
183
|
macOS uses the same isolation, sequence and pass criteria, with the additions
|
|
@@ -154,7 +208,7 @@ CI-tested, and it has not passed Level 2 for Codex.
|
|
|
154
208
|
- **Interruption.** Start `--apply` for one target and press Ctrl-C while it
|
|
155
209
|
runs.
|
|
156
210
|
- The run exits with `130` and reports `operation_interrupted`.
|
|
157
|
-
- Afterwards `ps -A -o pid=,command=` lists no `claude mcp` or `codex mcp`
|
|
211
|
+
- Afterwards `ps -ww -A -o pid=,command=` lists no `claude mcp` or `codex mcp`
|
|
158
212
|
command and no `setup-main.js` or `setup-command-guardian.js` process of
|
|
159
213
|
the build under test.
|
|
160
214
|
- A following `--apply` reports one of three outcomes, depending on where
|
|
@@ -166,7 +220,8 @@ CI-tested, and it has not passed Level 2 for Codex.
|
|
|
166
220
|
- A following `--remove` reports `ok (removed)`.
|
|
167
221
|
- If the operation completes before the interrupt arrives, record that and
|
|
168
222
|
repeat. An interrupt that never lands is not a pass.
|
|
169
|
-
- **Processes.** Check that no process remains with `ps` instead of `/proc
|
|
223
|
+
- **Processes.** Check that no process remains with `ps -ww` instead of `/proc`;
|
|
224
|
+
without `-ww`, `ps` truncates long commands when it has no terminal.
|
|
170
225
|
|
|
171
226
|
The evidence record names the build (commit or tag), the environment above,
|
|
172
227
|
every command with its exit status, and the sanitized JSON results. It
|
|
@@ -273,6 +328,99 @@ Manual, on a machine with Pi, `pi-cursor-sdk@0.5.3` and a stored Cursor key. Run
|
|
|
273
328
|
|
|
274
329
|
Record date, source commit, versions and outcome under Status. No secret, path or prompt content goes into the record.
|
|
275
330
|
|
|
331
|
+
## Multi-session skill acceptance
|
|
332
|
+
|
|
333
|
+
A targeted live check for profile skill selection ([skills](skills.md)) and for
|
|
334
|
+
several Pi sessions that one real controller drives at the same time. It is not
|
|
335
|
+
the ten-task Level 3 cycle and does not replace it.
|
|
336
|
+
|
|
337
|
+
The maintainer script `scripts/multi-session-acceptance.mjs` prepares the run,
|
|
338
|
+
starts the controller and checks the outcome. The controller itself calls the
|
|
339
|
+
Pi Session MCP tools; the script never does.
|
|
340
|
+
|
|
341
|
+
### Preparation
|
|
342
|
+
|
|
343
|
+
- Candidate: a separate detached checkout of the commit under test, built with
|
|
344
|
+
`npm ci`, `npm run build` and `npm run build:cli`. `prepare` records the
|
|
345
|
+
commit, whether the checkout is clean, the SHA-256 of `dist/main.js` and,
|
|
346
|
+
from the harness of `cc810c9` on, a SHA-256 over every built module in
|
|
347
|
+
`dist/`; `run` refuses a changed build.
|
|
348
|
+
- Configuration: `prepare --base-config <operator config> --from-profile
|
|
349
|
+
<alias>` copies only provider, model and thinking level of one working profile
|
|
350
|
+
without extensions or MCP servers into a temporary configuration with two
|
|
351
|
+
profiles: `accept-read` (default, `read-only`, skill `review`) and
|
|
352
|
+
`accept-code` (`coding`, skills `implementation` and `handshake`). From the
|
|
353
|
+
harness of `3f98104` on, all three are `builtin:` references: the two worker
|
|
354
|
+
skills ship with the candidate, and the `handshake` skill sits in the
|
|
355
|
+
override directory `skills/` next to the run configuration, so the run also
|
|
356
|
+
exercises library resolution. The `handshake` skill is generated per run and
|
|
357
|
+
holds a random token that no controller prompt contains.
|
|
358
|
+
- Fixtures: four small synthetic git repositories per client (`slug`, `stats`,
|
|
359
|
+
`wait`, `range`), each a separate workspace alias (`cc-*` for Claude Code,
|
|
360
|
+
`cx-*` for Codex). Both clients use the same configuration and build.
|
|
361
|
+
- Controller skill: from the harness of `3f98104` on, `prepare` installs the
|
|
362
|
+
Claude Code controller skill the way an operator does, with the candidate's
|
|
363
|
+
`pi-session-mcp-setup --apply --target claude-code:project:pi-session-mcp` in
|
|
364
|
+
the controller's directory. The setup step runs with a disposable `HOME`, so
|
|
365
|
+
setup state and client files of that step never touch the real home; it must
|
|
366
|
+
report `applied` and `skill_installed` and leave a regular copy identical to
|
|
367
|
+
the shipped skill. Codex installs skills only in the user's home, which the
|
|
368
|
+
run must not change, so the Codex controller gets one run-scoped symbolic link
|
|
369
|
+
in `.agents/skills` of its directory. Earlier runs linked both. No global
|
|
370
|
+
skill directory changes.
|
|
371
|
+
- Clients: Claude Code runs as `claude -p` with `--mcp-config`,
|
|
372
|
+
`--strict-mcp-config`, `--setting-sources project,local`,
|
|
373
|
+
`--permission-mode dontAsk` and an `--allowedTools` list of the eight tools
|
|
374
|
+
plus read-only file tools, `sleep`, `node --test` and `git -C`. Codex runs as
|
|
375
|
+
`codex exec --ignore-user-config --sandbox read-only` with the server
|
|
376
|
+
defined through `-c mcp_servers.pi-candidate.*` and the three per-tool
|
|
377
|
+
approvals from [client setup](client-setup.md#run-codex-without-prompts).
|
|
378
|
+
Neither run changes a persistent registration, `HOME` or `CODEX_HOME`, and
|
|
379
|
+
both use the existing authentication.
|
|
380
|
+
|
|
381
|
+
### Scenarios
|
|
382
|
+
|
|
383
|
+
Each client runs two invocations, one per scenario:
|
|
384
|
+
|
|
385
|
+
| Scenario | What the controller does | What is checked |
|
|
386
|
+
| --- | --- | --- |
|
|
387
|
+
| `parallel` | Capabilities first; two sessions of `accept-code` on `slug` and `stats`; 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 `accept-code`; 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 |
|
|
388
|
+
| `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 abort result is `ok` (an `abort_timeout` stays on record even 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 |
|
|
389
|
+
|
|
390
|
+
### Independent checks
|
|
391
|
+
|
|
392
|
+
- The script watches `/proc` during the run and records every process of the
|
|
393
|
+
controller tree, every server of this run (entry point and configuration
|
|
394
|
+
path) and every process whose working directory lies inside the run, by PID
|
|
395
|
+
and start time. After the controller exits and the server's 15-second
|
|
396
|
+
shutdown bound has passed, none of them may remain.
|
|
397
|
+
- From the controller transcript it extracts only tool names, aliases, states,
|
|
398
|
+
timestamps and counts. It scans every Pi Session MCP result, with
|
|
399
|
+
`assistantText` removed, for local paths, the token and credential markers,
|
|
400
|
+
and counts mentions in `assistantText` separately.
|
|
401
|
+
- Fixture oracles run on the workspace after the controller exits: `node
|
|
402
|
+
--test` and `git status` per fixture. Every changed file must have been last
|
|
403
|
+
written during a worker turn of its task's session, and `HANDSHAKE.txt`
|
|
404
|
+
during the follow-up turn, by the server's turn timestamps. This catches a
|
|
405
|
+
write outside the worker turns, not one during them.
|
|
406
|
+
- Controller writes are limited by the client restrictions: the Codex
|
|
407
|
+
controller runs in a read-only sandbox, and the Claude Code controller has no
|
|
408
|
+
write or edit tool, although its allowed `git -C` could still change a
|
|
409
|
+
fixture.
|
|
410
|
+
- The handshake token must appear neither in a worker prompt nor anywhere in
|
|
411
|
+
the controller transcript, and no worker prompt may name a private path or a
|
|
412
|
+
skill file. The controller's own reads and commands must not name the run's
|
|
413
|
+
private directory or its files; this is a marker check, not a sandbox.
|
|
414
|
+
- The harness records its own SHA-256 at `prepare` and refuses to run or
|
|
415
|
+
re-evaluate a run with another version.
|
|
416
|
+
- `evidence` writes one sanitized JSON record and refuses to write a local path
|
|
417
|
+
or the token. Transcripts and the configuration stay in the run's private
|
|
418
|
+
directory and are never published.
|
|
419
|
+
|
|
420
|
+
A controller that reports success does not count; only the checks above do.
|
|
421
|
+
If a client or its authentication is not available, record that client's part
|
|
422
|
+
as blocked.
|
|
423
|
+
|
|
276
424
|
## Evidence rules
|
|
277
425
|
|
|
278
426
|
- Record only sanitized evidence: statuses, booleans, counts, durations,
|
|
@@ -485,3 +633,224 @@ Claude Code `2.1.296`, on 2026-10-11:
|
|
|
485
633
|
The Pi extension live check above ran on `eeaa597`, before the final fixes to
|
|
486
634
|
extension tool names and the `read-only` contract test. It has not been
|
|
487
635
|
repeated on the release candidate.
|
|
636
|
+
|
|
637
|
+
After its release, `v0.7.0` passed Level 1 and Level 2 on a fresh clone of its
|
|
638
|
+
tag, and Level 2 as published npm package, on 2026-10-11, on Linux with Node.js
|
|
639
|
+
`26.11.1`, Codex CLI `0.162.1` and Claude Code `2.1.296`:
|
|
640
|
+
- Tag clone: `git describe --tags --exact-match` reported `v0.7.0`. The tag
|
|
641
|
+
object is `a5516ce6e4e159ef1e20ee38aba06672379e9cb7` and the peeled commit
|
|
642
|
+
`6783631d2ae1813707cf798360a0a0f4c58ca66d`.
|
|
643
|
+
- Level 1 on the tag clone:
|
|
644
|
+
- every command exited with `0`;
|
|
645
|
+
- the test run reported 37 files, 660 passed and 5 skipped;
|
|
646
|
+
- `npm audit` and `npm audit --omit=dev` reported 0 vulnerabilities;
|
|
647
|
+
- Doctor reported `packageVersion` `0.7.0` and no finding;
|
|
648
|
+
- `dist/main.js` has the SHA-256
|
|
649
|
+
`47875d38886528ace6b242df2c6ad79d624c51e330e63c2f401576eadc449ed7`.
|
|
650
|
+
- Level 2 passed 96 of 96 checks on the tag clone, and 96 of 96 with the npm
|
|
651
|
+
package installed into a temporary prefix through
|
|
652
|
+
`pi-session-mcp-setup`. In both runs the real client registrations were
|
|
653
|
+
unchanged, no process remained, and the built files were byte-identical
|
|
654
|
+
before and after the client cycles.
|
|
655
|
+
- These runs, and the release candidate's runs above, used the harness that
|
|
656
|
+
#40 later checked in as `scripts/setup-acceptance.mjs`.
|
|
657
|
+
- The checked-in script, after its review fixes, also passed 96 of 96 on the
|
|
658
|
+
tag clone.
|
|
659
|
+
- The npm package has the shasum `c8d73311dbde1bdebd78e58b1f01c7cf3bebf374`.
|
|
660
|
+
The tarball downloaded from the registry had the same SHA-1 and SHA-512
|
|
661
|
+
integrity.
|
|
662
|
+
- Installed package:
|
|
663
|
+
- `pi-session-mcp-doctor` reported a healthy package `0.7.0` when run from an
|
|
664
|
+
unrelated working directory;
|
|
665
|
+
- with a configuration that pins `pi-cursor-sdk@0.5.3` on three profiles,
|
|
666
|
+
`setup --apply` and `--verify` for `claude-code:user:pi-session-mcp`
|
|
667
|
+
reported `applied` and `mcp_verified`.
|
|
668
|
+
|
|
669
|
+
On 2026-10-11 the installed `v0.7.0` package also passed the Pi extension live
|
|
670
|
+
check on Linux:
|
|
671
|
+
- Method: the same scripted JSON-RPC client as above drove the installed
|
|
672
|
+
server. It used the operator's configuration with three `pi-cursor-sdk@0.5.3`
|
|
673
|
+
profiles: one `read-only` and one `coding` profile with
|
|
674
|
+
`claude-opus-5-5@1m` and `claude-opus-5-5@300k` at thinking level `high`, and
|
|
675
|
+
one `coding` profile with `composer-2.5` at thinking level `off`.
|
|
676
|
+
- Each of the three profiles started, completed a prompt with the expected
|
|
677
|
+
one-word answer, and closed. One `coding` and one `read-only` Cursor session started in parallel
|
|
678
|
+
and both completed.
|
|
679
|
+
- Profiles without extensions on three other providers (xAI, Mistral and
|
|
680
|
+
DeepSeek) each completed a prompt.
|
|
681
|
+
- After close no descendant process of the server remained. No stdout line
|
|
682
|
+
failed to parse as an MCP frame; stderr carried four
|
|
683
|
+
`foreign_stdout_suppressed` reports for 12 suppressed writes and no other
|
|
684
|
+
event.
|
|
685
|
+
- The two OpenAI profiles ended `failed` with `turn_failed`. A direct Pi CLI
|
|
686
|
+
call outside the server showed that the account had reached its usage limit,
|
|
687
|
+
so they are not evidence for or against the release.
|
|
688
|
+
|
|
689
|
+
This check does not cover macOS, an MCP client in the loop, or a session that
|
|
690
|
+
uses Cursor's own tools.
|
|
691
|
+
|
|
692
|
+
Before its release, `v0.7.1` passed Level 1 and the working-tree Level 2 on its
|
|
693
|
+
release candidate `82dff20` on Linux, with Node.js `26.11.1`, Codex CLI
|
|
694
|
+
`0.162.1` and Claude Code `2.1.296`, on 2026-10-11:
|
|
695
|
+
- Level 1: every command exited with `0`.
|
|
696
|
+
- The test run reported 38 files, 684 passed and 5 skipped.
|
|
697
|
+
- `npm audit` and `npm audit --omit=dev` reported 0 vulnerabilities.
|
|
698
|
+
- Doctor reported `packageVersion` `0.7.1` and no finding.
|
|
699
|
+
- Level 2 ran through `scripts/setup-acceptance.mjs` on a fresh clone of the
|
|
700
|
+
candidate.
|
|
701
|
+
- All nine steps passed on all four targets, 96 of 96 checks.
|
|
702
|
+
- The real client registrations were unchanged, and no process remained.
|
|
703
|
+
- The built files were byte-identical before and after the client cycles.
|
|
704
|
+
- `dist/main.js` is byte-identical to that of `v0.7.0`. The changed modules are
|
|
705
|
+
the extension tool-name rule, the pin format and the prompt source.
|
|
706
|
+
|
|
707
|
+
The branch build of `8d5b069`, whose sources match this candidate, passed the
|
|
708
|
+
Pi extension live check with the operator's configuration on 2026-10-11:
|
|
709
|
+
- Three `pi-cursor-sdk@0.5.3` profiles and one xAI profile each completed a
|
|
710
|
+
prompt.
|
|
711
|
+
- Two Cursor sessions completed in parallel.
|
|
712
|
+
- No process remained, and no foreign line reached the MCP stdout.
|
|
713
|
+
|
|
714
|
+
Profile skill selection (#46) passed a multi-session skill acceptance with Claude
|
|
715
|
+
Code and Codex on 2026-10-12, on Linux (`x64`) with Node.js `26.11.1`, Claude
|
|
716
|
+
Code `2.1.296`, Codex CLI `0.162.1` and Pi SDK `1.1.0`:
|
|
717
|
+
- Candidate: detached checkouts of `bcef6ba` (runs 1 to 3), `a086339` (run 4)
|
|
718
|
+
and `b6cf624` (run 5), each clean and built with `npm ci`, `npm run build`
|
|
719
|
+
and `npm run build:cli`. `dist/main.js` has the same SHA-256 in all five
|
|
720
|
+
runs, `47875d38886528ace6b242df2c6ad79d624c51e330e63c2f401576eadc449ed7`:
|
|
721
|
+
the commits after `bcef6ba` change only the orchestration skill text, the
|
|
722
|
+
acceptance harness and documentation.
|
|
723
|
+
- Level 1 on `bcef6ba`, from the command output of the maintainer's gate run:
|
|
724
|
+
every command exited with `0`. The test run reported
|
|
725
|
+
40 files, 761 passed and 5 skipped; `npm audit` reported 0 vulnerabilities;
|
|
726
|
+
`npm pack --dry-run` listed the three skills and no harness. The test suite
|
|
727
|
+
passed again on `a086339` with the same counts.
|
|
728
|
+
- Configuration: the same bytes in every run, fingerprint
|
|
729
|
+
`sha256:b754f0f5e4702d81d99183817abb379eeed2fb5733f93373852eb827ec16d687`,
|
|
730
|
+
with the profiles `accept-read` and `accept-code` derived from an OpenAI
|
|
731
|
+
`gpt-6-luna` profile with thinking level `low`, and the fixture aliases
|
|
732
|
+
`cc-slug`, `cc-stats`, `cc-wait`, `cc-range`, `cx-slug`, `cx-stats`, `cx-wait`
|
|
733
|
+
and `cx-range`. Offline Doctor reported no finding for it.
|
|
734
|
+
- Every invocation confirmed the candidate's version and this fingerprint
|
|
735
|
+
through `pi_capabilities_get` as its first call, and saw the skills
|
|
736
|
+
`implementation` and `handshake` on `accept-code`. Exactly one server of the
|
|
737
|
+
run was observed per invocation, and no process of the controller tree, the
|
|
738
|
+
server or the fixtures remained afterwards. No Pi Session MCP result
|
|
739
|
+
contained a local path, the token or a credential marker, and no
|
|
740
|
+
`assistantText` mentioned one.
|
|
741
|
+
|
|
742
|
+
Run 5, on `b6cf624` with the harness of that commit (SHA-256
|
|
743
|
+
`ca851130bbade9f0b2700a43059b7ac3ce349dad40ad2b647133f950a408c719`), passed
|
|
744
|
+
every check of all four invocations:
|
|
745
|
+
|
|
746
|
+
| Client | Scenario | Result |
|
|
747
|
+
| --- | --- | --- |
|
|
748
|
+
| Claude Code | `parallel` | First turns overlapped by 25.1 s; follow-up in the same session completed; both fixtures pass their tests with only the allowed files changed, each last written during a worker turn; `HANDSHAKE.txt` holds the token and was written during the follow-up turn, although no worker prompt contained the token and the token never appeared in the controller transcript; no controller action named the private run directory; both sessions closed |
|
|
749
|
+
| Claude Code | `abort` | First turns overlapped by 23.7 s; one abort, result `ok`; `aborted` seen through `pi_turn_get` before close; the abort fell inside the running interval of the neighbor, which then completed and passes its tests; the worker's `sleep 120` was observed running, and at the end of the run it was gone and had written no file; both sessions closed |
|
|
750
|
+
| Codex | `parallel` | As for Claude Code, with an overlap of 24.8 s |
|
|
751
|
+
| Codex | `abort` | As for Claude Code, with an overlap of 22.4 s |
|
|
752
|
+
|
|
753
|
+
The controllers made 1 to 6 `pi_turn_get` calls per session and waited between
|
|
754
|
+
polls with `sleep`. Each invocation took 93 to 156 seconds. The run's
|
|
755
|
+
transcripts were also checked afterwards against the criteria the harness
|
|
756
|
+
gained after run 5: in both `abort` invocations the first successful abort came
|
|
757
|
+
before the first `aborted` observation, and no worker prompt named a private
|
|
758
|
+
path or a skill file. Run 5 used the harness of `b6cf624`; the head's harness
|
|
759
|
+
adds these two checks and the run-time checksum check, and changes nothing
|
|
760
|
+
else.
|
|
761
|
+
|
|
762
|
+
Earlier attempts on the same build, kept on record:
|
|
763
|
+
- Run 1 (Claude Code only, with the harness of `bcef6ba`, which did not record
|
|
764
|
+
its checksum yet): `parallel` passed
|
|
765
|
+
every check. In `abort` the abort itself passed (result `ok`, `aborted` seen
|
|
766
|
+
before close, the worker's `sleep` ended, no late file), but the neighbor
|
|
767
|
+
turn had completed about three seconds before the abort, so the run shows no
|
|
768
|
+
neighbor that keeps running. The neighbor task now starts with a bounded
|
|
769
|
+
`sleep 45` and the abort comes after about 15 seconds.
|
|
770
|
+
- Run 2: three invocations passed every check. In Codex `parallel` every
|
|
771
|
+
functional check passed, including the handshake written during the
|
|
772
|
+
follow-up turn with a token that no prompt contained, but the controller
|
|
773
|
+
then read the run's private handshake skill to confirm the token. The
|
|
774
|
+
controller prompt now confines reads and commands to the fixtures.
|
|
775
|
+
- Run 3: three invocations passed every check. In Codex `abort` the abort, the
|
|
776
|
+
running neighbor and cleanup passed, but the controller told both workers to
|
|
777
|
+
"follow configured handshake instructions" because capabilities listed a
|
|
778
|
+
`handshake` skill, so both fixtures got an extra `HANDSHAKE.txt`. The
|
|
779
|
+
orchestration skill now says that a listed skill is not a task.
|
|
780
|
+
- Run 4 (`a086339`): three invocations passed every check. The Codex
|
|
781
|
+
`parallel` controller read the fixtures-only rule as excluding its own skill
|
|
782
|
+
directory, worked from `./fixtures`, and stopped after
|
|
783
|
+
`pi_capabilities_get` without starting a session. The rule now allows the
|
|
784
|
+
controller's own skill directory.
|
|
785
|
+
|
|
786
|
+
No run showed a Pi Session MCP defect. The deviations were controller
|
|
787
|
+
behavior and harness wording.
|
|
788
|
+
|
|
789
|
+
This is a targeted check of skill selection and of two concurrent sessions
|
|
790
|
+
per client. It is not the ten-task Level 3 cycle. It covers neither the
|
|
791
|
+
extension profile path live (the automated SDK contract tests cover it), nor
|
|
792
|
+
`read-only` workers, nor more than two concurrent sessions, nor macOS.
|
|
793
|
+
|
|
794
|
+
After the owner asked on 2026-10-12 that skills install without manual linking
|
|
795
|
+
and can be adjusted and extended, the same change gained the skill library,
|
|
796
|
+
`builtin:` references, `--customize-skill` and the controller-skill
|
|
797
|
+
installation through `setup`. Its final candidate `0ebbaa0` passed on
|
|
798
|
+
2026-10-12, on Linux (`x64`) with Node.js `26.11.1`, Claude Code `2.1.296`,
|
|
799
|
+
Codex CLI `0.162.1` and Pi SDK `1.1.0`:
|
|
800
|
+
- Level 1 on a clean detached checkout: every command exited with `0`. The
|
|
801
|
+
test run reported 43 files, 884 passed and 5 skipped; `npm audit` reported 0
|
|
802
|
+
vulnerabilities; `npm pack --dry-run` listed 125 files with the three skills
|
|
803
|
+
and no acceptance harness. `git diff --check` from `0cb3c60` reported nothing.
|
|
804
|
+
- Level 2 through `scripts/setup-acceptance.mjs` with the setup of that
|
|
805
|
+
checkout: 160 of 160 checks passed. All nine steps passed on all four
|
|
806
|
+
targets, including the controller skill finding of every step, the skill file
|
|
807
|
+
after steps 3 and 7 and its absence after steps 6 and 9, and a foreign skill
|
|
808
|
+
that stayed unchanged. The real client registrations were unchanged, no
|
|
809
|
+
process remained, no report leaked a path, and the build was unchanged.
|
|
810
|
+
Earlier candidates `24ab13d` and `37034dd` of the same change had passed
|
|
811
|
+
Level 2 with 160 of 160 as well, before the review fixes that followed them.
|
|
812
|
+
- Multi-session skill acceptance, run 7, with the harness of that checkout
|
|
813
|
+
(SHA-256 `42d46f86ae617c229568437e6d96c93f965c27778c3e2fde51e1c449ef35fb12`)
|
|
814
|
+
and the dist tree SHA-256
|
|
815
|
+
`957dfac67bf0c3c179bff6584b3bda49bedad2fe1642790537f6790b31f5ef37`:
|
|
816
|
+
- `prepare` installed the Claude Code controller skill with the candidate's
|
|
817
|
+
`setup --apply` for the controller's project scope: `applied` and
|
|
818
|
+
`skill_installed`, a regular copy identical to the shipped skill.
|
|
819
|
+
- The configuration (fingerprint
|
|
820
|
+
`sha256:b8a341c9ff48ecd7c02f8959b8e4e696f305431945b659ea35d2d98485e948c3`)
|
|
821
|
+
referenced all three skills with `builtin:`: the two shipped worker skills
|
|
822
|
+
and the `handshake` skill from the override directory next to it.
|
|
823
|
+
- All four invocations passed every check: Claude Code `parallel` (first
|
|
824
|
+
turns overlapped by 21.5 s) and `abort` (22.1 s), Codex `parallel` (22.9 s)
|
|
825
|
+
and `abort` (18.9 s). In both `parallel` invocations the worker wrote the
|
|
826
|
+
handshake token, which existed only in the override-directory skill,
|
|
827
|
+
during the follow-up turn. In both `abort` invocations the one abort
|
|
828
|
+
returned `ok`, came before the `aborted` observation and fell inside the
|
|
829
|
+
running neighbor, which completed and passed its tests. No process
|
|
830
|
+
remained, and no result leaked a path, the token or a credential marker.
|
|
831
|
+
- Run 6 on `cc810c9`, before the last review fixes, had passed every check of
|
|
832
|
+
all four invocations with the same configuration fingerprint and the
|
|
833
|
+
setup-installed Claude Code skill.
|
|
834
|
+
|
|
835
|
+
These runs do not cover macOS, Codex skill discovery from the user's home
|
|
836
|
+
(setup installs it there, and Level 2 checks the file, but no live Codex
|
|
837
|
+
controller read it from there), the extension profile path live, or more than
|
|
838
|
+
two concurrent sessions.
|
|
839
|
+
|
|
840
|
+
Before its release, `v0.8.0` passed Level 1 and the working-tree Level 2 on
|
|
841
|
+
its release candidate `6d197a0` on Linux (`x64`), with Node.js `26.11.1`, Codex
|
|
842
|
+
CLI `0.162.1` and Claude Code `2.1.296`, on 2026-10-12:
|
|
843
|
+
- Level 1: every command exited with `0`.
|
|
844
|
+
- The test run reported 43 files, 884 passed and 5 skipped.
|
|
845
|
+
- `npm audit` and `npm audit --omit=dev` reported 0 vulnerabilities.
|
|
846
|
+
- `npm pack --dry-run` listed 125 files, including the three skills.
|
|
847
|
+
- Doctor reported `packageVersion` `0.8.0`. With the example
|
|
848
|
+
configuration its only finding was the missing placeholder workspace.
|
|
849
|
+
- Level 2 ran through `scripts/setup-acceptance.mjs` on the candidate's
|
|
850
|
+
working tree: 160 of 160 checks passed. All nine steps passed on all four
|
|
851
|
+
targets, including the controller skill finding of every step. The real
|
|
852
|
+
client registrations were unchanged, no process remained, and the built
|
|
853
|
+
files were unchanged.
|
|
854
|
+
- Apart from the version, the candidate's sources equal the merge of #48,
|
|
855
|
+
whose final candidate `0ebbaa0` passed the multi-session skill acceptance
|
|
856
|
+
recorded above.
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
**Status:** Accepted (2026-10-11). Issue #34. Design:
|
|
4
4
|
[Pi extensions design](../pi-extensions-design.md).
|
|
5
5
|
|
|
6
|
+
Amended by [ADR 0007](0007-profile-skill-selection.md) for skills that extension
|
|
7
|
+
packages ship.
|
|
8
|
+
|
|
6
9
|
## Context
|
|
7
10
|
|
|
8
11
|
Embedded sessions loaded no Pi extensions. Providers that exist only as Pi
|
|
@@ -40,8 +43,8 @@ model runtime per session:
|
|
|
40
43
|
|
|
41
44
|
Profiles without extensions keep the previous path. Client prompts are plain
|
|
42
45
|
text for every profile: they never dispatch extension commands, skills or
|
|
43
|
-
templates
|
|
44
|
-
stdout writer.
|
|
46
|
+
templates, and extension input hooks see them with `source: "rpc"`. An
|
|
47
|
+
always-on stdout guard gives the MCP transport the only real stdout writer.
|
|
45
48
|
|
|
46
49
|
## Consequences
|
|
47
50
|
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# ADR 0007: Execution profiles select Pi skills from an operator catalog
|
|
2
|
+
|
|
3
|
+
**Status:** Accepted (2026-10-12). Issue #46. Guide: [Pi skills in execution
|
|
4
|
+
profiles](../skills.md).
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Embedded sessions are meant to run without skills. A controlling agent that
|
|
9
|
+
delegates work to Pi workers needs a way to give a worker role-specific
|
|
10
|
+
instructions, such as an implementation or review procedure, under the same
|
|
11
|
+
rule as everything else: the operator decides, the MCP caller picks aliases.
|
|
12
|
+
|
|
13
|
+
Verified behavior of Pi SDK 1.1.0:
|
|
14
|
+
|
|
15
|
+
- `noSkills` does not stop skills that an allowlisted extension package
|
|
16
|
+
ships. Those skills reached the session although `noSkills` was set. The
|
|
17
|
+
same held for prompt templates and themes that packages ship. ADR 0006 did
|
|
18
|
+
not intend this and did not decide it.
|
|
19
|
+
- `loadSkills` removes duplicate skill names before the SDK's `skillsOverride`
|
|
20
|
+
runs. An override alone therefore cannot report a collision between two
|
|
21
|
+
selected files, so the server has to check names itself.
|
|
22
|
+
- Resources that extension hooks add later (`resources_discover`) pass through
|
|
23
|
+
the same override.
|
|
24
|
+
|
|
25
|
+
ADR 0003 chose maintenance without a new feature phase and reserves public
|
|
26
|
+
contract changes for a minor release with their own decision. ADR 0006 is the
|
|
27
|
+
precedent for an owner-approved scope expansion. This ADR is such a decision
|
|
28
|
+
for issue #46. It does not rewrite ADR 0006; that ADR records only a forward
|
|
29
|
+
link.
|
|
30
|
+
|
|
31
|
+
On 2026-10-12 the owner rejected installing the shipped skills by manual
|
|
32
|
+
symlinking and asked for skills that can be installed at install time and
|
|
33
|
+
adjusted and extended one by one. The decisions under "Skill library,
|
|
34
|
+
installation and customization" below record that, in the same change.
|
|
35
|
+
|
|
36
|
+
## Decision
|
|
37
|
+
|
|
38
|
+
The operator may register skills in a catalog and select them per execution
|
|
39
|
+
profile.
|
|
40
|
+
|
|
41
|
+
- **Catalog.** An optional top-level `skillCatalog` maps a skill alias
|
|
42
|
+
(`^[a-z][a-z0-9_-]{0,63}$`, at most 64 entries) to the path of exactly one
|
|
43
|
+
`SKILL.md` (at most 4096 characters). Directories, globs, URLs,
|
|
44
|
+
scheme-prefixed sources, `~` and backslashes are invalid. The one accepted
|
|
45
|
+
scheme is `builtin:<name>` (see below). Relative paths resolve against the
|
|
46
|
+
configuration file's directory. A missing catalog is empty. A skill folder
|
|
47
|
+
needs no `package.json` and no extension.
|
|
48
|
+
- **Selection.** An optional `executionProfiles.<alias>.skills` lists catalog
|
|
49
|
+
aliases (at most 16, no duplicates). Missing or empty means no skills. There
|
|
50
|
+
is no inheritance and no default skill. An unknown alias, a duplicate alias,
|
|
51
|
+
or two selected aliases that resolve to the same path is
|
|
52
|
+
`invalid_execution_profile_config`. All other profile fields are unchanged
|
|
53
|
+
and unknown fields are still rejected.
|
|
54
|
+
- **MCP surface.** Callers still choose only workspace and profile aliases.
|
|
55
|
+
`pi_session_start` and `pi_session_prompt` get no skill input. No tool is
|
|
56
|
+
added.
|
|
57
|
+
- **Loading.** At session start the server loads exactly the selected files
|
|
58
|
+
through the SDK's public `loadSkills`, with no default directories, and
|
|
59
|
+
validates them completely. `skillsOverride` returns exactly that set, also
|
|
60
|
+
after later resource additions by extension hooks.
|
|
61
|
+
- **Failure.** A missing, unreadable or oversized (over 256 KiB) file, an
|
|
62
|
+
invalid skill (SDK diagnostics such as a missing description or invalid
|
|
63
|
+
name), two selected files with the same Pi skill name, two aliases on the
|
|
64
|
+
same canonical file (for example through a symlink), or
|
|
65
|
+
`disable-model-invocation: true` fail the start with the new error
|
|
66
|
+
`skill_load_failed` and the fixed message `Configured Pi skill could not be
|
|
67
|
+
loaded`. The message never contains a path, a skill name or SDK text. The
|
|
68
|
+
same Pi skill name in different sessions is fine.
|
|
69
|
+
- **Explicit-only skills are incompatible in v1.** MCP prompts never run
|
|
70
|
+
`/skill:` commands, and Pi hides such skills from the model. The server does
|
|
71
|
+
not rewrite the flag.
|
|
72
|
+
- **Names.** The catalog alias may differ from the skill's declared `name`.
|
|
73
|
+
Nothing is renamed.
|
|
74
|
+
- **Capabilities.** Every execution profile in `pi_capabilities_get` gains
|
|
75
|
+
`skills: string[]`, the selected catalog aliases in configured order, `[]`
|
|
76
|
+
when none. No paths, file names, contents or SDK diagnostics. The setup
|
|
77
|
+
verifier accepts the field and still rejects unexpected fields.
|
|
78
|
+
- **Doctor.** Offline, it never parses or executes a skill. New check IDs after
|
|
79
|
+
the extension checks, with the subject `<profile>:<skill-alias>`:
|
|
80
|
+
`skill_missing`, `skill_unreadable` (not a regular file, over 256 KiB, or not
|
|
81
|
+
readable) and `skill_duplicate`. Frontmatter, name rules, collisions and
|
|
82
|
+
explicit-only flags are checked only at session start. A further warning
|
|
83
|
+
check, `skill_override_outdated`, is described below.
|
|
84
|
+
- **Diagnostics.** Stderr gets the new stage `skill_load` for a selected file
|
|
85
|
+
that fails validation, with an optional `skill` field holding the catalog
|
|
86
|
+
alias. A catalog that differs from the selection after construction reports
|
|
87
|
+
the existing stages `postcheck`, `extension_load` or `extension_bind`. No
|
|
88
|
+
diagnostic carries a path.
|
|
89
|
+
- **Snapshot semantics.** Profile and skill selection are fixed per session.
|
|
90
|
+
The content is not snapshotted: the SDK keeps file paths and later reads may
|
|
91
|
+
see changed files. Operators manage skill files and companion files, do not
|
|
92
|
+
change them during active sessions, and close affected sessions before an
|
|
93
|
+
update. The configuration fingerprint covers configuration bytes, not skill
|
|
94
|
+
contents. There is no hot reload, watcher, copy store for sessions or
|
|
95
|
+
versioning.
|
|
96
|
+
- **Shipped skills.** The package ships `pi-session-orchestration`,
|
|
97
|
+
`pi-session-implementation` and `pi-session-review` under `skills/`, one
|
|
98
|
+
canonical copy each. They are ordinary skill files. The two worker skills are
|
|
99
|
+
registered through the catalog like any operator skill, by `builtin:`. The
|
|
100
|
+
orchestration skill is for the controlling client agent and is not a Pi
|
|
101
|
+
worker skill.
|
|
102
|
+
|
|
103
|
+
## Skill library, installation and customization
|
|
104
|
+
|
|
105
|
+
Owner decision of 2026-10-12, same issue. The first design of this change had
|
|
106
|
+
the operator register shipped skills by absolute path and link the
|
|
107
|
+
orchestration skill into the clients by hand; the owner rejected that. Three
|
|
108
|
+
decisions were taken:
|
|
109
|
+
installation through `pi-session-mcp-setup --apply`, an override directory for
|
|
110
|
+
customization, and `builtin:` references in the Pi skill catalog.
|
|
111
|
+
|
|
112
|
+
- **Skill library.** Shipped skills live in the package's `skills/` directory.
|
|
113
|
+
The operator's override directory is `skills/` next to the configuration file
|
|
114
|
+
(for the default configuration `~/.config/pi-session-mcp/skills/<name>/SKILL.md`).
|
|
115
|
+
An override with the same name replaces the shipped skill; a new name adds a
|
|
116
|
+
skill. Names follow the Agent Skills rule: lowercase letters and digits in
|
|
117
|
+
hyphen-separated groups, 1 to 64 characters. Nothing else is searched.
|
|
118
|
+
- **`builtin:<name>`.** A `skillCatalog` value resolves to the override if
|
|
119
|
+
`<override dir>/<name>/SKILL.md` exists, else to the shipped skill. A missing
|
|
120
|
+
skill keeps the shipped location, so Doctor reports `skill_missing` and the
|
|
121
|
+
session start fails with `skill_load_failed`. Resolution happens when the
|
|
122
|
+
server loads the configuration: adding or removing an override needs a
|
|
123
|
+
restart, like any configuration change. Edits to an existing skill file reach
|
|
124
|
+
new sessions under the snapshot semantics above. The example configuration
|
|
125
|
+
uses `builtin:pi-session-implementation` and `builtin:pi-session-review`, so a
|
|
126
|
+
copied example needs no path edits.
|
|
127
|
+
- **Customization.** `pi-session-mcp-setup --customize-skill <name>` (a
|
|
128
|
+
dry-run) and `--apply --customize-skill <name>` copy a shipped skill into the
|
|
129
|
+
override directory as a starting point and record the shipped fingerprint in
|
|
130
|
+
`<override dir>/.pi-session-mcp-bases.json`. An existing override is never
|
|
131
|
+
overwritten. When the shipped skill changed after the copy, or no base is
|
|
132
|
+
recorded, the command reports `skill_override_outdated`; `--apply` then moves
|
|
133
|
+
only the recorded base (`skill_base_updated`) and never touches the
|
|
134
|
+
operator's files, which is how an operator acknowledges a reviewed change.
|
|
135
|
+
The finding target is `{ client: "skills", scope: "override", alias: <name> }`.
|
|
136
|
+
It works without `--target`, requires `PI_SESSION_MCP_CONFIG`, and follows
|
|
137
|
+
the platform rule of setup. A completely new skill needs no command: create
|
|
138
|
+
`<override dir>/<new-name>/SKILL.md` and reference it as `builtin:<new-name>`.
|
|
139
|
+
- **Installation of the controller skill.** `setup --apply` installs
|
|
140
|
+
`pi-session-orchestration` for each target, after the registration, as a real
|
|
141
|
+
copy of the effective skill (override, else shipped). Codex `codex:user` goes
|
|
142
|
+
to `~/.agents/skills/`, Claude Code `user` and `local` share
|
|
143
|
+
`~/.claude/skills/`, and Claude Code `project` goes to
|
|
144
|
+
`<project>/.claude/skills/`, the directory setup runs in. Ownership records
|
|
145
|
+
hold only a content fingerprint and, while an update is pending, the
|
|
146
|
+
fingerprint it replaces; a project record is bound to an opaque project
|
|
147
|
+
identity, never a path. Setup never replaces or deletes a modified installed
|
|
148
|
+
copy, hidden operator entries inside it, a foreign skill of the same name or a
|
|
149
|
+
linked or non-directory entry; it reports `skill_divergent`, which does not
|
|
150
|
+
block the registration. A link to exactly the effective skill is the
|
|
151
|
+
operator's own equivalent setup (`skill_linked`) and is never owned. In the home directory the client's skills
|
|
152
|
+
directory may be the operator's own link and is followed. Inside a project,
|
|
153
|
+
which may be untrusted, any link below the project root makes the slot
|
|
154
|
+
divergent, so setup never writes outside the project. Setup installs only
|
|
155
|
+
`pi-session-orchestration` into clients; the worker skills are for Pi
|
|
156
|
+
profiles through `builtin:`, and controller skills of the operator's own
|
|
157
|
+
belong in the clients' native skill directories. The operator customizes the
|
|
158
|
+
controller skill through the override and runs `--apply` again, and never
|
|
159
|
+
edits the installed copy.
|
|
160
|
+
- **Doctor.** The warning check `skill_override_outdated` has the subject
|
|
161
|
+
`skill:<name>` when a shipped skill's current fingerprint differs from the
|
|
162
|
+
recorded base, with a remediation that names the customize command. A
|
|
163
|
+
corrupt bases file reports the subject `skill:bases`. Doctor stays offline
|
|
164
|
+
and executes nothing.
|
|
165
|
+
- **Fallback.** Where setup does not run, the operator copies the controller
|
|
166
|
+
skill directory into the client's documented skill directory. There is no
|
|
167
|
+
symlink instruction.
|
|
168
|
+
|
|
169
|
+
## Compatibility change
|
|
170
|
+
|
|
171
|
+
Previously, with Pi SDK 1.1.0, an allowlisted extension package's bundled
|
|
172
|
+
skills, prompt templates and themes reached the session although `noSkills`
|
|
173
|
+
was set. Now an extension allowlist alone makes none of its skills available.
|
|
174
|
+
A skill is available only through the catalog plus the profile's explicit
|
|
175
|
+
selection.
|
|
176
|
+
|
|
177
|
+
Migration: add a catalog entry with the absolute path to the package's
|
|
178
|
+
`SKILL.md` inside Pi's install (normally under
|
|
179
|
+
`<Pi agent dir>/npm/node_modules/<package>/…`; `~` is not expanded) and select
|
|
180
|
+
it in the profile. Prompt templates and themes that packages ship are now also
|
|
181
|
+
closed through the SDK's public overrides. They were already never expanded
|
|
182
|
+
for MCP prompts. This does not mean every previous profile behaves unchanged:
|
|
183
|
+
a profile that used a package's skills needs the migration above.
|
|
184
|
+
|
|
185
|
+
## Consequences
|
|
186
|
+
|
|
187
|
+
- Skills are operator-managed prompt content. In `coding` profiles a skill's
|
|
188
|
+
instructions are executed with the profile's tools. A skill grants no rights.
|
|
189
|
+
- Skill selection limits the regular skill catalog only. An allowlisted
|
|
190
|
+
extension stays trusted executable code and can still read files or inject
|
|
191
|
+
prompt text. This is no sandbox.
|
|
192
|
+
- Three states stay distinct: configured (capabilities list the alias; intent
|
|
193
|
+
only), available in the SDK catalog (validated at session start and listed
|
|
194
|
+
to the model in its system prompt), and actually read by the model (the model
|
|
195
|
+
decides; not guaranteed). Task success is separate again.
|
|
196
|
+
- Skill files can change under a running session. Operators carry that
|
|
197
|
+
discipline; the server does not enforce it.
|
|
198
|
+
- Setup now writes into client skill directories, in the home directory and in
|
|
199
|
+
a project. It copies only from the package or the operator's override
|
|
200
|
+
directory, never follows a link inside a project, and never replaces what it
|
|
201
|
+
did not install or what the operator modified. The override directory and its
|
|
202
|
+
bases file are operator-trusted configuration, not a workspace. Installed
|
|
203
|
+
skill content becomes instructions for the controlling agent.
|
|
204
|
+
- The server needs a name check of its own for selected files, because
|
|
205
|
+
`loadSkills` dedupes by name before `skillsOverride`.
|
|
206
|
+
- Sessions of profiles with extensions each have their own model runtime
|
|
207
|
+
(ADR 0006). Skill loading does not change that.
|
|
208
|
+
|
|
209
|
+
## Versioning
|
|
210
|
+
|
|
211
|
+
ADR 0003 requires a minor release for a public contract change. The new
|
|
212
|
+
`skills` capability field and the new `skill_load_failed` error code are such a
|
|
213
|
+
change, and so are the new setup findings, the `--customize-skill` option and
|
|
214
|
+
the controller skill that `setup --apply` installs, so the next release after
|
|
215
|
+
0.7.1 is 0.8.0. The change is recorded under
|
|
216
|
+
`## Unreleased` in the changelog. Implementing it does not itself release or
|
|
217
|
+
bump the version.
|