pi-session-mcp 0.7.1 → 0.8.1

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.
Files changed (66) hide show
  1. package/.pi-session-mcp-cli/config.js +47 -7
  2. package/.pi-session-mcp-cli/doctor.js +75 -2
  3. package/.pi-session-mcp-cli/execution-profile.js +1 -0
  4. package/.pi-session-mcp-cli/override-lock.js +125 -0
  5. package/.pi-session-mcp-cli/setup-platform.js +195 -0
  6. package/.pi-session-mcp-cli/setup-result.js +8 -0
  7. package/.pi-session-mcp-cli/skill-catalog.js +35 -0
  8. package/.pi-session-mcp-cli/skill-customize.js +268 -0
  9. package/.pi-session-mcp-cli/skill-library.js +188 -0
  10. package/CHANGELOG.md +176 -0
  11. package/README.md +15 -3
  12. package/dist/capabilities.d.ts +1 -0
  13. package/dist/capabilities.js +2 -1
  14. package/dist/client-adapters/mcp-verifier.js +6 -2
  15. package/dist/config.d.ts +4 -0
  16. package/dist/config.js +47 -7
  17. package/dist/doctor.d.ts +7 -1
  18. package/dist/doctor.js +75 -2
  19. package/dist/execution-profile.d.ts +4 -0
  20. package/dist/execution-profile.js +1 -0
  21. package/dist/override-lock.d.ts +34 -0
  22. package/dist/override-lock.js +125 -0
  23. package/dist/pi-adapter.d.ts +7 -5
  24. package/dist/pi-adapter.js +1 -0
  25. package/dist/pi-skills.d.ts +17 -0
  26. package/dist/pi-skills.js +64 -0
  27. package/dist/sdk-pi-adapter.d.ts +7 -3
  28. package/dist/sdk-pi-adapter.js +82 -16
  29. package/dist/server.js +1 -0
  30. package/dist/session-registry.d.ts +8 -6
  31. package/dist/session-registry.js +3 -2
  32. package/dist/setup-cli.d.ts +2 -0
  33. package/dist/setup-cli.js +16 -0
  34. package/dist/setup-main.d.ts +1 -1
  35. package/dist/setup-main.js +18 -3
  36. package/dist/setup-ownership.d.ts +9 -0
  37. package/dist/setup-ownership.js +32 -5
  38. package/dist/setup-skills.d.ts +76 -0
  39. package/dist/setup-skills.js +586 -0
  40. package/dist/setup.d.ts +7 -0
  41. package/dist/setup.js +49 -6
  42. package/dist/skill-catalog.d.ts +26 -0
  43. package/dist/skill-catalog.js +35 -0
  44. package/dist/skill-customize.d.ts +41 -0
  45. package/dist/skill-customize.js +268 -0
  46. package/dist/skill-library.d.ts +106 -0
  47. package/dist/skill-library.js +188 -0
  48. package/docs/acceptance.md +593 -1
  49. package/docs/adr/0006-pi-extension-allowlist.md +3 -0
  50. package/docs/adr/0007-profile-skill-selection.md +228 -0
  51. package/docs/architecture.md +10 -6
  52. package/docs/client-setup-design.md +219 -1
  53. package/docs/client-setup.md +86 -3
  54. package/docs/doctor-design.md +9 -1
  55. package/docs/installation.md +128 -5
  56. package/docs/pi-extensions-design.md +28 -4
  57. package/docs/releasing.md +18 -9
  58. package/docs/session-mcp.md +7 -2
  59. package/docs/skills.md +616 -0
  60. package/docs/threat-model.md +19 -2
  61. package/docs/tool-contracts.md +9 -5
  62. package/package.json +2 -1
  63. package/pi-session-mcp.example.json +9 -3
  64. package/skills/pi-session-implementation/SKILL.md +42 -0
  65. package/skills/pi-session-orchestration/SKILL.md +94 -0
  66. package/skills/pi-session-review/SKILL.md +58 -0
@@ -10,7 +10,7 @@ directory: an npm executable can run from any directory.
10
10
  sanitized semver `packageVersion` when metadata is available, ordered `checks`,
11
11
  and `exitCode`). Human and JSON output are projections of that same model.
12
12
  Subjects are only fixed component names, validated workspace aliases, or
13
- validated `<profile>:<package>` pairs; paths, configuration values, errors,
13
+ validated `<profile>:<package>`, `<profile>:<skill-alias>` or `skill:<name>` pairs; paths, configuration values, errors,
14
14
  credentials, and provider data are never output.
15
15
 
16
16
  Each check is `{ id, severity, subject, remediation? }`. Severity is `ok`,
@@ -34,9 +34,17 @@ and owners are:
34
34
  | `workspace_not_writable` | A workspace is not writable while a coding profile can target it | validated workspace alias |
35
35
  | `extension_missing` | Pi has no user install of a package that a profile's `extensions` names | `<profile>:<package>` |
36
36
  | `extension_version_mismatch` | The installed manifest's version differs from the pinned version, or the manifest or its `pi.extensions` entries are invalid | `<profile>:<package>` |
37
+ | `skill_missing` | The `SKILL.md` file that a profile's selected skill alias names does not exist; a `builtin:<name>` value that matches no override and no shipped skill resolves to the shipped location and is reported here | `<profile>:<skill-alias>` |
38
+ | `skill_unreadable` | A selected skill path is not a regular file, is larger than 256 KiB, or cannot be read | `<profile>:<skill-alias>` |
39
+ | `skill_duplicate` | Two selected skill aliases of one profile resolve to the same canonical file | `<profile>:<skill-alias>` |
40
+ | `skill_override_outdated` | Warning. The current fingerprint of a shipped skill differs from the base recorded in the skill bases file next to the configuration file, or the bases file is corrupt | `skill:<name>`, or `skill:bases` for a corrupt file |
37
41
 
38
42
  Doctor reads extension manifests from Pi's user install location only; it never installs packages and never imports extension code.
39
43
 
44
+ The skill checks run after the extension checks. They look only at file availability: Doctor never reads a skill's frontmatter, never parses or executes it, and the subject carries the catalog alias, never a path. Frontmatter, skill-name rules, name collisions and explicit-only flags (`disable-model-invocation`) are checked only at session start by the Pi SDK contract, so a clean Doctor run does not promise that a skill loads. Unknown or duplicate aliases and two selected aliases with one path are configuration errors and surface as `config_invalid`. See [Pi skills](skills.md).
45
+
46
+ `skill_override_outdated` concerns the operator's skill overrides, not a profile. It is `ok` for a recorded base that still matches the shipped skill, and a warning (exit status 1, never blocking `setup`) when the shipped skill changed after the operator ran `pi-session-mcp-setup --customize-skill <name>`; its remediation names `pi-session-mcp-setup --apply --customize-skill <name>` to acknowledge a reviewed change. Only skills with a recorded base are compared, and a recorded name that is no longer shipped is skipped. A recorded base of 0.8.0 (a version 1 fingerprint) is compared through the version 2 value of the released 0.8.0 skill it names; a version 1 base that names no released skill cannot be confirmed and yields a warning that says so, with the same remediation. A corrupt bases file yields a warning with the subject `skill:bases`. Doctor reads the bases file and the shipped skill files only; nothing is executed and the subject is a validated skill name, never a path. The check sorts after `skill_duplicate`.
47
+
40
48
  The Doctor reuses `loadConfig`; it does not duplicate alias, profile, thinking
41
49
  level, or read-only-default rules. Workspace values are used only for local
42
50
  filesystem checks and are never copied into the result.
@@ -14,12 +14,14 @@ Pi Session MCP is a local, stdio-only MCP server. An MCP client starts
14
14
  Nothing listens on a network port, no daemon runs between client sessions, and
15
15
  session state exists only in the memory of that child process.
16
16
 
17
- An installation consists of three locations:
17
+ An installation consists of these locations:
18
18
 
19
19
  | What | Location | Notes |
20
20
  | --- | --- | --- |
21
21
  | Package | the npm global prefix, or a dedicated directory per release such as `~/.local/share/pi-session-mcp/releases/<tag>` | The built server, `setup` and Doctor. |
22
22
  | Configuration | a file outside the package, for example `~/.config/pi-session-mcp/pi-session-mcp.json` | Operator-owned, mode `0600`, never committed. |
23
+ | Skill overrides (optional) | the `skills/` directory next to the configuration file, for example `~/.config/pi-session-mcp/skills/` | Your own or customized skills, plus `.pi-session-mcp-bases.json` and its lock file `.pi-session-mcp-bases.lock`. Created by you or by `setup --customize-skill`. See [Pi skills](#pi-skills). |
24
+ | Controller skill | `~/.agents/skills/pi-session-orchestration` (Codex), `~/.claude/skills/pi-session-orchestration` or `<project>/.claude/skills/pi-session-orchestration` (Claude Code) | Written by `setup --apply`; see [Register a client](#4-register-a-client). |
23
25
  | Setup ownership state | `~/.local/state/pi-session-mcp/ownership.json` | Written by `setup` only. Path-free and secret-free. |
24
26
 
25
27
  Never register a development checkout. A registered client launches
@@ -156,6 +158,13 @@ Rules:
156
158
  `extensions`: a list of at most 8 entries of the form
157
159
  `npm:<name>@<exact version>`, each package once. Ranges, tags, `git:`
158
160
  sources, paths and build metadata (`+build`) are rejected. See [Pi extensions](#pi-extensions).
161
+ - A profile may select Pi skills through `skills`: a list of at most 16 aliases
162
+ from the top-level `skillCatalog`, which maps an alias to `builtin:<name>`
163
+ (a skill of the package or of your override directory) or to the path of one
164
+ `SKILL.md` file (at most 64 entries). A relative path resolves against the
165
+ configuration file's directory; `~` is not expanded. The example already uses
166
+ `builtin:` for the two worker skills, so you need not change its skill
167
+ entries. See [Pi skills](#pi-skills).
159
168
  - Never put keys, tokens, credential objects, headers, base URLs or
160
169
  authentication paths into this file.
161
170
 
@@ -217,6 +226,10 @@ pi-session-mcp-setup --apply --target claude-code:user:pi-session-mcp
217
226
  pi-session-mcp-setup --verify --target claude-code:user:pi-session-mcp
218
227
  ```
219
228
 
229
+ `--apply` also installs the controller skill `pi-session-orchestration` for the
230
+ target, after the registration, so the client knows how to drive Pi worker
231
+ sessions. See [Controller skill](#controller-skill).
232
+
220
233
  `setup` changes a Codex registration only through `codex mcp add` and
221
234
  `codex mcp remove`, and Codex rewrites `config.toml` on each of them. Codex CLI
222
235
  `0.162.0` groups all `[mcp_servers.*]` tables together and drops a comment
@@ -224,12 +237,14 @@ directly above such a table; settings are preserved. If your `config.toml`
224
237
  contains comments worth keeping, copy it before `--apply`, `--rollback` or
225
238
  `--remove` on `codex:user:pi-session-mcp`.
226
239
 
227
- Each report has one line for the operation with its overall status, and one line
228
- per target with a finding in the form `status (code)`:
240
+ Each report has one line for the operation with its overall status, and per
241
+ target two lines with a finding in the form `status (code)`: the registration
242
+ and the controller skill, whose alias is `pi-session-orchestration`:
229
243
 
230
244
  ```text
231
245
  dry-run: planned
232
246
  claude-code/user/pi-session-mcp: absent (absent)
247
+ claude-code/user/pi-session-orchestration: absent (skill_absent)
233
248
  ```
234
249
 
235
250
  Expected results:
@@ -237,8 +252,11 @@ Expected results:
237
252
  | Operation | Overall | Finding | Meaning |
238
253
  | --- | --- | --- | --- |
239
254
  | `--dry-run` | `planned` | `absent (absent)` | No registration exists. Apply will add one. |
255
+ | `--dry-run` | `planned` | `absent (skill_absent)` | The controller skill is not installed. Apply will install it. |
240
256
  | `--apply` | `ok` | `ok (applied)` | The registration was added and is now owned by `setup`. |
257
+ | `--apply` | `ok` | `ok (skill_installed)` | The controller skill was copied into the client's skill directory and is owned by `setup`. |
241
258
  | `--verify` | `ok` | `ok (mcp_verified)` | Doctor passed, the registration equals the intended one, and a direct MCP handshake listed the eight tools and answered `pi_capabilities_get`. |
259
+ | `--verify` | `ok` | `ok (skill_verified)` | The installed skill equals the effective skill. |
242
260
 
243
261
  Verify never starts a session and never contacts a provider. Add `--json` to
244
262
  any operation for the sanitized JSON report. Exit status `0` is success, `1` an
@@ -255,6 +273,39 @@ If a registration already exists, `setup` never replaces it:
255
273
  Start a new client session after registering. The client launches the server on
256
274
  demand; there is nothing to start by hand.
257
275
 
276
+ ### Controller skill
277
+
278
+ `--apply` copies the effective `pi-session-orchestration` skill (your override
279
+ if you have one, else the shipped skill) as a real copy to the client's skill
280
+ directory, where the client discovers it without further steps:
281
+
282
+ | Target | Skill directory |
283
+ | --- | --- |
284
+ | `codex:user:pi-session-mcp` | `~/.agents/skills/pi-session-orchestration` |
285
+ | `claude-code:user:pi-session-mcp`, `claude-code:local:pi-session-mcp` | `~/.claude/skills/pi-session-orchestration` (one shared directory) |
286
+ | `claude-code:project:pi-session-mcp` | `<project>/.claude/skills/pi-session-orchestration`, where `<project>` is the directory in which you run `setup` |
287
+
288
+ - `setup` never replaces or deletes a modified installed copy, hidden files
289
+ inside it (macOS Finder's `.DS_Store` counts too), a skill of the same name
290
+ that it did not install, or a link or non-directory entry. It reports
291
+ `skill_divergent`; the registration is still made, but the overall status is
292
+ `failed`. A link to exactly the effective skill is accepted as your own
293
+ (`skill_linked`). Inside a project, any link below the project root counts as
294
+ divergent.
295
+ - A package update or a changed override replaces setup's own unmodified copy on
296
+ the next `--apply` (`skill_updated`). `--remove` and `--rollback` delete it
297
+ again (`skill_removed`), except while the other Claude Code registration of
298
+ the shared directory still uses it (`skill_kept_shared`).
299
+ - To change the skill, do not edit the installed copy. Run
300
+ `pi-session-mcp-setup --apply --customize-skill pi-session-orchestration`,
301
+ edit the override it creates, and run `--apply` for the target again.
302
+ - Setup installs only this one skill into clients. Worker skills are for Pi
303
+ profiles; additional controller skills of your own belong in the clients'
304
+ native skill directories.
305
+
306
+ The codes and the rules are in [Pi skills](skills.md#install-the-orchestration-skill-into-codex-and-claude-code)
307
+ and the [setup lifecycle design](client-setup-design.md#skill-installation).
308
+
258
309
  ### Register without setup
259
310
 
260
311
  `setup` runs on Linux and macOS. On every other platform, Windows included, it
@@ -277,7 +328,11 @@ acceptance level covers this path.
277
328
  directory: in an npm installation `echo "$(npm root -g)/pi-session-mcp"`
278
329
  prints that directory, in a release checkout it is the checkout. Write the
279
330
  resulting absolute path into the command; a substitution inside the single
280
- quotes of the Codex example would not be expanded.
331
+ quotes of the Codex example would not be expanded. A manual registration
332
+ installs no skill. To use the controller skill, copy (do not link) the
333
+ directory `skills/pi-session-orchestration` of the package to the client's
334
+ skill directory listed under [Controller skill](#controller-skill), and
335
+ repeat the copy after an upgrade.
281
336
  3. Check the registration. These checks are not a replacement for
282
337
  `setup --verify`: it also performs a bounded direct MCP handshake, and
283
338
  outside `setup` nothing does that yet. The last check below depends on the
@@ -394,6 +449,58 @@ pin the installed version in the profile:
394
449
  reports a placeholder key. Session start succeeds and the first prompt fails
395
450
  with `turn_failed`. Store the key with Pi first.
396
451
 
452
+ ## Pi skills
453
+
454
+ An execution profile can give its sessions Pi skills. The package ships two
455
+ worker skills, `pi-session-implementation` and `pi-session-review`, and the
456
+ controller skill `pi-session-orchestration`, in its `skills/` directory. The
457
+ catalog maps an alias to a skill; the profile selects aliases. MCP callers never
458
+ choose skills.
459
+
460
+ ```json
461
+ "skillCatalog": {
462
+ "pi-session-review": "builtin:pi-session-review"
463
+ },
464
+ "executionProfiles": {
465
+ "safe-readonly": {
466
+ "default": true,
467
+ "permissionProfile": "read-only",
468
+ "provider": "your-configured-provider",
469
+ "model": "your-configured-model",
470
+ "thinkingLevel": "medium",
471
+ "skills": ["pi-session-review"]
472
+ }
473
+ }
474
+ ```
475
+
476
+ - `builtin:<name>` resolves to your override
477
+ `<directory of the configuration file>/skills/<name>/SKILL.md` if it exists,
478
+ else to the shipped skill. The shipped example configuration already uses
479
+ `builtin:pi-session-implementation` and `builtin:pi-session-review`, so the
480
+ copied example needs no path edits for skills. Adding or removing an override
481
+ needs a server restart, like any configuration change.
482
+ - To adjust a shipped skill, run `pi-session-mcp-setup --customize-skill <name>`
483
+ (a dry-run) and then `pi-session-mcp-setup --apply --customize-skill <name>`
484
+ with `PI_SESSION_MCP_CONFIG` set. It copies the shipped skill into the
485
+ override directory as a starting point and never overwrites an existing
486
+ override. Edit the copy, then restart the server. To add a skill of your own,
487
+ create `<override dir>/<new-name>/SKILL.md` and reference it as
488
+ `builtin:<new-name>`; no command is needed. After a package update, Doctor
489
+ warns with `skill_override_outdated` when a shipped skill changed since you
490
+ copied it. `--apply --customize-skill` takes a kernel lock on the override
491
+ directory, so concurrent runs cannot lose a recorded base.
492
+ - A `builtin:` name with no override and no shipped skill makes Doctor report
493
+ `skill_missing` and the session start fail with `skill_load_failed`.
494
+ - An extension allowlist alone makes none of a package's skills available. If a
495
+ profile relied on them, add a catalog entry with the absolute path of the
496
+ package's `SKILL.md` and select it; see the migration section of [Pi
497
+ skills](skills.md).
498
+ - A skill file is read by the SDK at session start and later by the model.
499
+ Do not change skill files while sessions that use them are active; close
500
+ those sessions first.
501
+
502
+ The complete rules, errors, Doctor checks and limits are in [Pi skills](skills.md).
503
+
397
504
  ## Upgrade
398
505
 
399
506
  `setup` binds each owned registration to the package manifests and to every
@@ -401,6 +508,17 @@ built runtime file, so the old version must remove its registration before the
401
508
  new one applies. Read the [changelog](../CHANGELOG.md) before upgrading; it
402
509
  records changes that affect operators, such as renamed provider keys.
403
510
 
511
+ Removing the registration also removes the controller skill that setup
512
+ installed, unless you modified it, and `--apply` for the new version installs
513
+ the new text. A package update that changes a shipped skill does not touch an
514
+ override of yours; Doctor warns with `skill_override_outdated` so that you can
515
+ review the change.
516
+
517
+ After an upgrade from 0.8.0, run `setup` as a dry-run and then with `--apply`
518
+ for your targets. Copies and records of 0.8.0 are proven before setup acts on
519
+ them; one that cannot be proven is reported as `skill_legacy_unverified` and
520
+ stays untouched. See [Upgrade from 0.8.0](skills.md#upgrade-from-080).
521
+
404
522
  ### npm installation
405
523
 
406
524
  An npm upgrade replaces the package in place. Close the client sessions that
@@ -465,7 +583,12 @@ npm uninstall -g pi-session-mcp
465
583
  same owned removal and reports `rolled_back`; use it to undo an apply. After
466
584
  every target reports `removed`, uninstall the package or delete the release
467
585
  directory, and delete the configuration file and
468
- `~/.local/state/pi-session-mcp/`.
586
+ `~/.local/state/pi-session-mcp/`. The same call removes the controller skill
587
+ that `setup` installed (`skill_removed`). It keeps a copy that you modified
588
+ (`skill_divergent`) and the shared Claude Code directory while the other
589
+ Claude Code registration is still owned (`skill_kept_shared`). Your override
590
+ directory `skills/` next to the configuration file is yours: delete it with the
591
+ configuration file if you no longer need it.
469
592
 
470
593
  ## When something fails
471
594
 
@@ -3,6 +3,14 @@
3
3
  Status: approved by the owner on 2026-10-11 for implementation. Tracking issue:
4
4
  [#34](https://github.com/plagor44-ux/pi-session-mcp/issues/34).
5
5
 
6
+ > **Amended by [ADR 0007](adr/0007-profile-skill-selection.md).** This design
7
+ > assumed that `noSkills` and the other `no*` options keep skills, prompt
8
+ > templates and themes out of every session. With Pi SDK 1.1.0 that did not hold
9
+ > for resources that an allowlisted extension package ships. An extension
10
+ > allowlist now makes none of them available; a skill reaches a session only
11
+ > through the operator's `skillCatalog` and the profile's `skills`. See
12
+ > [Pi skills](skills.md).
13
+
6
14
  ## Goal
7
15
 
8
16
  An operator can allowlist Pi extensions per execution profile. A profile that
@@ -53,8 +61,10 @@ Success means:
53
61
  `DefaultResourceLoader` with `noExtensions: true`, no skills, templates or
54
62
  themes, and a disabled system prompt. `SdkPiSessionAdapter.create` resolves
55
63
  provider, model, authentication and availability against one `ModelRuntime`
56
- shared by all sessions, and only then builds the resource loader and calls
57
- `createAgentSession`.
64
+ shared by the sessions of profiles without extensions (a profile with
65
+ `extensions` gets a runtime of its own, see *Session creation*), and only then
66
+ builds the resource loader and calls `createAgentSession`. This describes the
67
+ state before this feature; ADR 0007 later added the skill selection.
58
68
 
59
69
  Facts about Pi SDK 1.1.0 that shape this design, verified against the
60
70
  installed package:
@@ -85,8 +95,11 @@ installed package:
85
95
  mismatched npm packages, and `getInstalledPath(source, "user")` falls back
86
96
  to a synchronous `npm root -g` on a miss and accepts legacy global
87
97
  installs; neither is side-effect free.
88
- 9. `pi-cursor-sdk` and `@cursor/sdk` call `console.log`. In a stdio MCP server
89
- such output corrupts the protocol stream.
98
+ 9. Skills, prompt templates and themes that an allowlisted extension package
99
+ ships reached the session although `noSkills` was set (ADR 0007).
100
+ `loadSkills` removes duplicate skill names before `skillsOverride` runs.
101
+ 10. `pi-cursor-sdk` and `@cursor/sdk` call `console.log`. In a stdio MCP server
102
+ such output corrupts the protocol stream.
90
103
 
91
104
  The relevant SDK functions are root exports of
92
105
  `@earendil-works/pi-coding-agent`: `createAgentSessionServices`,
@@ -250,6 +263,17 @@ and step 6 leaves no session to dispose.
250
263
  - **UI and flags.** No UI context is bound; extension UI calls return the
251
264
  SDK's no-op results. `extensionFlagValues` is empty, so extension flags keep
252
265
  their defaults.
266
+ - **Turn liveness.** The `updatedAt` of a running turn follows the public SDK
267
+ events of the prompt: assistant message start, update and end, and tool
268
+ execution start, update and end. An extension provider with its own agent
269
+ loop, such as `pi-cursor-sdk`, therefore advances `updatedAt` whenever it
270
+ publishes streaming updates. Its internal steps that publish no public
271
+ event stay invisible, so an unchanged `updatedAt` is no proof of a hang, and
272
+ streaming is no evidence of finished or useful work. Only the event type and
273
+ the message role are inspected; no delta, thinking block, tool argument or
274
+ partial result is stored or projected, and the answer still comes only from
275
+ the final assistant message. See [Tool
276
+ contracts](tool-contracts.md).
253
277
 
254
278
  ### Lifecycle and close
255
279
 
package/docs/releasing.md CHANGED
@@ -131,9 +131,15 @@ Patch transitive advisories in the lockfile only:
131
131
 
132
132
  ## Prepare a release
133
133
 
134
+ A release travels in the pull request of the change it ships. That pull
135
+ request also carries the version, the changelog heading and the pre-release
136
+ acceptance record; there is no separate release pull request. Records that can
137
+ only be made after publishing go into the pull request of the next change.
138
+
134
139
  Preconditions:
135
140
 
136
- - `main` contains every change of the release, and Level 1 is green on `main`.
141
+ - The change pull request contains every change of the release, and Level 1
142
+ is green on its head.
137
143
  - `npm audit` reports 0 vulnerabilities.
138
144
  - The public contract is unchanged, or a minor release has been decided.
139
145
  - The acceptance that this release requires is recorded, or its absence is
@@ -141,8 +147,9 @@ Preconditions:
141
147
 
142
148
  Steps:
143
149
 
144
- 1. Create a release branch from the current `main`. Never reuse a release branch
145
- that predates later merges: its lockfile would undo later dependency patches.
150
+ 1. Bring the change branch up to date with `main` if `main` moved. Never reuse
151
+ a branch that predates later merges without that: its lockfile would undo
152
+ later dependency patches.
146
153
  2. Set the version:
147
154
 
148
155
  ```bash
@@ -159,11 +166,13 @@ Steps:
159
166
  5. Run the working-tree
160
167
  [Level 2 acceptance](acceptance.md#tooling) on the release candidate with
161
168
  `scripts/setup-acceptance.mjs`, unless the release notes state its absence.
162
- 6. Open one pull request named `chore: prepare v<x.y.z> release`.
169
+ 6. Record the pre-release acceptance in the status section of
170
+ [Acceptance](acceptance.md) and push it to the change pull request. Name the
171
+ release in the pull request's title and description.
163
172
 
164
173
  ## Publish a release
165
174
 
166
- After the release pull request is merged and CI is green on the merge commit:
175
+ After the change pull request is merged and CI is green on the merge commit:
167
176
 
168
177
  ```bash
169
178
  git switch main
@@ -217,9 +226,9 @@ After publishing:
217
226
 
218
227
  1. Run the published-release
219
228
  [Level 2 acceptance](acceptance.md#working-tree-and-published-release-variants)
220
- from a fresh clone of the tag and from the published npm package, and
221
- record it. `scripts/setup-acceptance.mjs` runs both
222
- ([Tooling](acceptance.md#tooling)).
229
+ from a fresh clone of the tag and from the published npm package.
230
+ `scripts/setup-acceptance.mjs` runs both ([Tooling](acceptance.md#tooling)).
223
231
  2. Upgrade the installation as described in
224
232
  [Installation](installation.md#upgrade).
225
- 3. Update the status section in [Acceptance](acceptance.md).
233
+ 3. Record both in the status section of [Acceptance](acceptance.md) with the
234
+ pull request of the next change, not in a pull request of their own.
@@ -7,8 +7,13 @@ the Pi session, supplies their definitions as `customTools`, and includes the
7
7
  names in Pi's explicit active `tools` list. The selected tools are verified again
8
8
  before the session is returned.
9
9
 
10
- Global/project extensions remain disabled (`noExtensions: true`). Installing
11
- `pi-mcp-adapter` globally is neither required nor sufficient for this integration.
10
+ Global and project extensions are never auto-discovered; only the extensions
11
+ that a profile allowlists load (see [Pi extensions](installation.md#pi-extensions)).
12
+ Installing `pi-mcp-adapter` globally is neither required nor sufficient for this
13
+ integration. Skills are likewise never auto-discovered; a profile gets only the
14
+ skills it selects from the operator's catalog (see [Pi skills](skills.md)).
15
+ Granting an external MCP tool through `mcpServers` and selecting a skill are
16
+ independent: a skill grants no tool.
12
17
  There is no automatic import of global MCP configuration or ambient credentials.
13
18
  Profiles without `mcpServers` keep their existing built-in tool sets and launch
14
19
  no MCP child process. The public `pi_session_start` input remains unchanged: callers