pi-session-mcp 0.13.1 → 0.14.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.
- package/.pi-session-mcp-cli/config.js +21 -3
- package/.pi-session-mcp-cli/doctor.js +6 -2
- package/.pi-session-mcp-cli/skill-library.js +1 -1
- package/.pi-session-mcp-cli/writer-boundary.js +2 -1
- package/.pi-session-mcp-cli/writer-lifecycle.js +18 -4
- package/CHANGELOG.md +87 -0
- package/README.md +1 -1
- package/dist/capabilities.d.ts +13 -0
- package/dist/capabilities.js +17 -13
- package/dist/config.d.ts +3 -1
- package/dist/config.js +21 -3
- package/dist/doctor.d.ts +1 -1
- package/dist/doctor.js +6 -2
- package/dist/model-catalog.d.ts +40 -0
- package/dist/model-catalog.js +38 -0
- package/dist/profile-probe.d.ts +28 -0
- package/dist/profile-probe.js +164 -0
- package/dist/sdk-pi-adapter.d.ts +1 -1
- package/dist/sdk-pi-adapter.js +25 -6
- package/dist/setup-cli.d.ts +7 -0
- package/dist/setup-cli.js +36 -0
- package/dist/setup-main.js +10 -3
- package/dist/setup-probe-main.d.ts +14 -0
- package/dist/setup-probe-main.js +76 -0
- package/dist/setup-probe-result.d.ts +39 -0
- package/dist/setup-probe-result.js +62 -0
- package/dist/setup-writers-common.js +1 -1
- package/dist/skill-library.js +1 -1
- package/dist/writer-boundary.d.ts +1 -1
- package/dist/writer-boundary.js +2 -1
- package/dist/writer-guard.js +1 -1
- package/dist/writer-lifecycle.d.ts +1 -0
- package/dist/writer-lifecycle.js +18 -4
- package/dist/writer-relay.js +12 -1
- package/docs/acceptance.md +313 -1
- package/docs/adr/0012-leased-writer-pool.md +10 -6
- package/docs/adr/0013-hardened-read-only-profiles.md +30 -0
- package/docs/adr/0014-profile-probe-and-model-catalog.md +89 -0
- package/docs/client-setup.md +18 -12
- package/docs/doctor-design.md +1 -0
- package/docs/execution-modes.md +25 -3
- package/docs/installation.md +87 -0
- package/docs/isolation-setup.md +8 -2
- package/docs/roadmap.md +20 -1
- package/docs/skills.md +42 -25
- package/docs/sprints/2026-10-24-s8-writer-migration.md +5 -3
- package/docs/sprints/2026-10-29-s12-audit-fixes.md +172 -0
- package/docs/threat-model.md +10 -1
- package/docs/tool-contracts.md +1 -1
- package/package.json +1 -1
- package/skills/pi-session-orchestration/SKILL.md +1 -1
- package/skills/pi-session-profiles/SKILL.md +124 -0
package/docs/execution-modes.md
CHANGED
|
@@ -182,10 +182,24 @@ pi-session-mcp-setup --writer my-project-w1 --finish --apply
|
|
|
182
182
|
|
|
183
183
|
Collection exports changed branches via a bundle into the operator's checkout as
|
|
184
184
|
`refs/remotes/writer-<name>/<branch>`. Uncommitted/untracked work is captured as a
|
|
185
|
-
synthetic `<branch>-wip` commit.
|
|
185
|
+
synthetic `<branch>-wip` commit. A clean detached HEAD whose commit no branch in
|
|
186
|
+
the clone reaches is exported as `<base>-detached` (for example `main-detached`,
|
|
187
|
+
imported as `refs/remotes/writer-<name>/main-detached`); a dirty detached HEAD
|
|
188
|
+
keeps the `<base>-wip` export. A `<base>-detached` or `<branch>-wip` name that
|
|
189
|
+
an exported branch already takes, or that conflicts with an exported branch's
|
|
190
|
+
path (such as a branch `main-detached/topic`), is refused and makes collection
|
|
191
|
+
incomplete (`writer_collect_incomplete`); the other branches are still
|
|
192
|
+
exported. Clone-side Git ignores replace refs. These refs are **untrusted until reviewed**;
|
|
186
193
|
setup does not merge or cherry-pick them. Collection does not change the clone.
|
|
187
|
-
Only a complete export records a digest authorizing later destructive cleanup
|
|
188
|
-
|
|
194
|
+
Only a complete export records a digest authorizing later destructive cleanup,
|
|
195
|
+
and the digest is recorded only when the clone's HEAD commit and every branch
|
|
196
|
+
commit exist in the operator checkout; otherwise collection is incomplete
|
|
197
|
+
(`writer_collect_incomplete`) and no digest is recorded. This includes the base
|
|
198
|
+
commit: if the operator checkout no longer has it (for example after a deleted
|
|
199
|
+
base branch and garbage collection), collect and finish fail this way even on a
|
|
200
|
+
pristine writer, without refused names; fetch the base again or resolve with
|
|
201
|
+
`--reset --discard --apply`. New work invalidates
|
|
202
|
+
that authorization. Stashes are not exported as branches:
|
|
189
203
|
resolve any needed stash inside the boundary before collection.
|
|
190
204
|
|
|
191
205
|
`--finish` collects, then resets a persistent writer or recreates an ephemeral
|
|
@@ -234,6 +248,14 @@ reset updates admission without a server restart. A missing/unusable runtime or
|
|
|
234
248
|
stale/unready writer launches a refusal MCP server: all eight tools return the
|
|
235
249
|
sanitized refusal, with no host fallback. See [Tool contracts](tool-contracts.md).
|
|
236
250
|
|
|
251
|
+
Before the relay starts an inner session it compares every public capability
|
|
252
|
+
field of the writer's profile with the host profile: `permissionProfile`,
|
|
253
|
+
`provider`, `model`, `thinkingLevel` and `shell` exactly, and `skills`,
|
|
254
|
+
`extensions` and `grantedExtensionTools` as sets. A mismatch or a missing
|
|
255
|
+
entry counts as `settingsChanged`, starts no inner session and moves on to the
|
|
256
|
+
next writer; if no writer is admitted, the start fails with
|
|
257
|
+
`writer_unavailable` and reason `none_admitted`.
|
|
258
|
+
|
|
237
259
|
## Reports and finding codes
|
|
238
260
|
|
|
239
261
|
Reports use sanitized targets `modes/workspace/<alias>` or `writer/<alias>/<name>`
|
package/docs/installation.md
CHANGED
|
@@ -89,6 +89,89 @@ local user's existing Pi authentication and never prints it. Automated writers
|
|
|
89
89
|
keep selected provider credentials in their private boundary agent copy; see
|
|
90
90
|
[Execution modes](execution-modes.md#writer-storage-launch-and-readiness).
|
|
91
91
|
|
|
92
|
+
## Check profiles: model catalog and probe
|
|
93
|
+
|
|
94
|
+
List the providers and model ids Pi knows locally, with authentication presence
|
|
95
|
+
only (never credential values):
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
pi-session-mcp-setup --list-models
|
|
99
|
+
pi-session-mcp-setup --list-models --json
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
This is offline and read-only: no provider request, credential refresh, model
|
|
103
|
+
network access or setup lock. It requires no `PI_SESSION_MCP_CONFIG`.
|
|
104
|
+
Providers registered only by Pi extensions are not listed; the report includes
|
|
105
|
+
that note. Invalid catalog ids are omitted and counted in `omittedIds`.
|
|
106
|
+
Catalog creation failures report `catalog_unavailable`.
|
|
107
|
+
|
|
108
|
+
With `PI_SESSION_MCP_CONFIG` already set to the configuration to check:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pi-session-mcp-setup --probe-profile review,code --json
|
|
112
|
+
pi-session-mcp-setup --probe-profile review,code --apply --json
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The first command is a dry run: Doctor runs offline, followed by profile,
|
|
116
|
+
provider, model and authentication-presence checks. Only `--apply` sends a
|
|
117
|
+
provider turn: one fixed PONG request per profile that passes the offline
|
|
118
|
+
checks, sequentially. Duplicate aliases are checked once in request order.
|
|
119
|
+
Point the variable at a candidate configuration to check it before going live;
|
|
120
|
+
the commands do not write configuration or registrations. The running MCP
|
|
121
|
+
server still needs a restart or reconnect to read changes.
|
|
122
|
+
|
|
123
|
+
The Doctor gate blocks global configuration/build/version errors and errors
|
|
124
|
+
whose subject is a requested profile. Unrelated errors and all warnings are
|
|
125
|
+
listed by check id in `doctor.other`, without blocking. A blocked request
|
|
126
|
+
reports `doctor_failed`; missing or unusable configuration reports
|
|
127
|
+
`config_required` or `config_unusable`. Unexpected operational failures report
|
|
128
|
+
`operation_failed`, and catalog creation failures report `catalog_unavailable`.
|
|
129
|
+
No raw exception text is printed.
|
|
130
|
+
|
|
131
|
+
Each applied probe starts the normal adapter with the resolved profile in a
|
|
132
|
+
private empty temporary directory (mode 0700), not a real repository. This
|
|
133
|
+
directory is created internally, never supplied as an argument or workspace
|
|
134
|
+
alias, and removed after cleanup. Start and turn deadlines are 60 and 120
|
|
135
|
+
seconds; session cleanup is bounded to 10 seconds. Interrupts abort and dispose
|
|
136
|
+
the current session and skip the remaining profiles. Reports never include
|
|
137
|
+
paths, credential values, environment values, the prompt or reply text.
|
|
138
|
+
Foreign stdout from profiles/extensions is suppressed so JSON remains intact;
|
|
139
|
+
sanitized structured diagnostics go to stderr. No turn event spool is used.
|
|
140
|
+
|
|
141
|
+
| Code | Status | Meaning |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| `probe_planned` | planned | Dry run: offline checks passed |
|
|
144
|
+
| `probe_profile_unknown` | failed | Alias not in the configuration |
|
|
145
|
+
| `probe_provider_unknown` | failed | Provider not in the catalog (offline) |
|
|
146
|
+
| `probe_model_unknown` | failed | Model not in the provider's catalog (offline) |
|
|
147
|
+
| `probe_auth_missing` | failed | Provider has no configured authentication (offline) |
|
|
148
|
+
| `probe_passed` | ok | Session started, reply was `PONG` |
|
|
149
|
+
| `probe_unexpected_reply` | failed | Turn completed with another reply |
|
|
150
|
+
| `probe_turn_failed` | failed | Turn failed or was aborted |
|
|
151
|
+
| `probe_start_failed` | failed | Session creation refused; carries the existing sanitized `PiSessionCreationErrorCode` |
|
|
152
|
+
| `probe_timeout` | failed | Start or turn deadline passed; the session was aborted and disposed |
|
|
153
|
+
|
|
154
|
+
A profile that fails an offline check is not started; the other profiles are
|
|
155
|
+
still checked. Apply findings include `durationMs`. `providerTurn` records
|
|
156
|
+
whether a provider turn was accepted, including turns that failed or timed out;
|
|
157
|
+
a `false` finding did not spend a provider turn. Provider usage and monetary
|
|
158
|
+
cost remain `unknown`.
|
|
159
|
+
|
|
160
|
+
Exit codes: `0` for a successful catalog, a clean dry run (`planned`) or an
|
|
161
|
+
apply where every profile passed; `1` for a failed check or refusal; `64` for
|
|
162
|
+
invalid usage; `130` for SIGINT and `143` for SIGTERM during a probe (both
|
|
163
|
+
report `operation_interrupted`). Both operations run on Linux and macOS and
|
|
164
|
+
need no setup lock. Probe requests cannot be combined with `--target`,
|
|
165
|
+
`--repo`, `--writer`, `--customize-skill`, `--list-models`, `--verify`,
|
|
166
|
+
`--rollback` or `--remove`. `--list-models` is standalone apart from `--json` and the default `--dry-run`.
|
|
167
|
+
Doctor and `--verify` remain provider-free.
|
|
168
|
+
|
|
169
|
+
**Container repositories:** the probe proves the profile on the host, with
|
|
170
|
+
the host's Pi agent directory. Writer acceptance stays with Doctor's
|
|
171
|
+
`container_profile_refused` check and writer provisioning; a host probe does
|
|
172
|
+
not prove a container writer. See [Execution modes](execution-modes.md) and
|
|
173
|
+
[ADR 0014](adr/0014-profile-probe-and-model-catalog.md).
|
|
174
|
+
|
|
92
175
|
## 1. Install
|
|
93
176
|
|
|
94
177
|
### From npm
|
|
@@ -701,6 +784,10 @@ choose skills.
|
|
|
701
784
|
directory, so concurrent runs cannot lose a recorded base.
|
|
702
785
|
- A `builtin:` name with no override and no shipped skill makes Doctor report
|
|
703
786
|
`skill_missing` and the session start fail with `skill_load_failed`.
|
|
787
|
+
- The controller skills `pi-session-orchestration` and `pi-session-profiles`
|
|
788
|
+
are not worker skills: a `builtin:` catalog entry for either makes the
|
|
789
|
+
configuration invalid, and Doctor reports `skill_controller_selected` for
|
|
790
|
+
`configuration:skillCatalog.<alias>`.
|
|
704
791
|
- An extension allowlist alone makes none of a package's skills available. If a
|
|
705
792
|
profile relied on them, add a catalog entry with the absolute path of the
|
|
706
793
|
package's `SKILL.md` and select it; see the migration section of [Pi
|
package/docs/isolation-setup.md
CHANGED
|
@@ -225,12 +225,18 @@ Git metadata can redirect reads to worker-controlled configuration. Setup checks
|
|
|
225
225
|
clone layout and runs clone-side Git only in throwaway no-network containers.
|
|
226
226
|
Collect with `--writer <name> --collect --apply`, then review
|
|
227
227
|
`refs/remotes/writer-<name>/<branch>` in your own checkout, with dirty work at
|
|
228
|
-
`<branch>-wip
|
|
228
|
+
`<branch>-wip` and a clean detached HEAD at `<base>-detached` (for example
|
|
229
|
+
`main-detached`). Imported refs are untrusted until reviewed.
|
|
229
230
|
|
|
230
231
|
After taking over the result and closing its coding session, run
|
|
231
232
|
`pi-session-mcp-setup --writer <name> --finish --apply` before another task.
|
|
232
233
|
It collects then resets (persistent) or recreates (ephemeral). If any branch name
|
|
233
|
-
was refused, collection is incomplete and finish stops
|
|
234
|
+
was refused, collection is incomplete and finish stops; a `<base>-detached` or
|
|
235
|
+
`<branch>-wip` name that an exported branch takes or whose path it conflicts
|
|
236
|
+
with is refused the same way. The release digest is
|
|
237
|
+
recorded only when the clone's HEAD commit and every branch commit exist in the
|
|
238
|
+
operator checkout, otherwise collection is `writer_collect_incomplete` and no
|
|
239
|
+
digest is recorded. Rename inside the writer
|
|
234
240
|
or have the operator explicitly resolve loss with `--reset --discard --apply`.
|
|
235
241
|
Finish returns persistent and ephemeral writers to the workspace default base.
|
|
236
242
|
No reconnect is needed after finish, reset or recreate: each session starts a
|
package/docs/roadmap.md
CHANGED
|
@@ -23,7 +23,8 @@ mean they are implemented or that their gates passed.
|
|
|
23
23
|
workspace-confined read tools for every read-only profile and the opt-in
|
|
24
24
|
bubblewrap shell (`shell: "sandboxed"`), released in minor release 0.13.0
|
|
25
25
|
together with #162, #163, #165 and #166.
|
|
26
|
-
- 2026-10-29: the post-0.13.0 review findings in one pull request,
|
|
26
|
+
- 2026-10-29: the post-0.13.0 review findings in one pull request, released in
|
|
27
|
+
patch release 0.13.1:
|
|
27
28
|
stale waiter-lock reclamation in the wake hook
|
|
28
29
|
([#179](https://github.com/plagor44-ux/pi-session-mcp/issues/179)), per-writer
|
|
29
30
|
reconcile failures ([#180](https://github.com/plagor44-ux/pi-session-mcp/issues/180))
|
|
@@ -31,6 +32,24 @@ mean they are implemented or that their gates passed.
|
|
|
31
32
|
([#181](https://github.com/plagor44-ux/pi-session-mcp/issues/181)). #120 still
|
|
32
33
|
waits for a Pi SDK release: 1.4.0 is the newest and still pins `undici` 8.10.2,
|
|
33
34
|
which `npm audit` now reports with eight advisories.
|
|
35
|
+
- 2026-10-29: agent-driven execution-profile setup
|
|
36
|
+
([#139](https://github.com/plagor44-ux/pi-session-mcp/issues/139)), released in
|
|
37
|
+
minor release 0.14.0 together with the refusal of controller skills as worker
|
|
38
|
+
skills ([#188](https://github.com/plagor44-ux/pi-session-mcp/issues/188)):
|
|
39
|
+
the offline model catalog `pi-session-mcp-setup --list-models`, the opt-in
|
|
40
|
+
provider probe `--probe-profile <alias> --apply` (one fixed PONG turn per
|
|
41
|
+
profile), and the shipped controller skill `pi-session-profiles`, with which a
|
|
42
|
+
controlling agent creates, changes or retires profiles without a guided
|
|
43
|
+
dialog. Recorded in [ADR 0014](adr/0014-profile-probe-and-model-catalog.md).
|
|
44
|
+
- 2026-10-30: [Sprint 12](sprints/2026-10-29-s12-audit-fixes.md) fixes three
|
|
45
|
+
audit findings on `9d9cf8c` in one pull request, released in patch release
|
|
46
|
+
0.14.1: read-only context files confined to the workspace
|
|
47
|
+
([#192](https://github.com/plagor44-ux/pi-session-mcp/issues/192)), detached
|
|
48
|
+
`HEAD` collection and the release-digest gate
|
|
49
|
+
([#193](https://github.com/plagor44-ux/pi-session-mcp/issues/193)) and the
|
|
50
|
+
full writer profile comparison in the relay
|
|
51
|
+
([#194](https://github.com/plagor44-ux/pi-session-mcp/issues/194)). Levels 1
|
|
52
|
+
to 3 passed for the candidate. #120 still waits for a Pi SDK release.
|
|
34
53
|
|
|
35
54
|
The explicit 2026-10-17 user request adds a bounded development-only
|
|
36
55
|
[token-footprint measurement](sprints/2026-10-17-token-footprint.md), following
|
package/docs/skills.md
CHANGED
|
@@ -8,12 +8,12 @@ its system prompt. The model may read the file when a task matches the skill's
|
|
|
8
8
|
description. Pi Session MCP lets the operator register skill files in a catalog
|
|
9
9
|
and select them per execution profile. MCP callers never choose skills.
|
|
10
10
|
|
|
11
|
-
The package ships
|
|
12
|
-
the operator's own overrides. `pi-session-mcp-setup --apply` also installs
|
|
13
|
-
controller
|
|
11
|
+
The package ships four skills and keeps them in a skill library together with
|
|
12
|
+
the operator's own overrides. `pi-session-mcp-setup --apply` also installs both
|
|
13
|
+
controller skills into Claude Code and Codex. Nothing needs to be linked by hand.
|
|
14
14
|
Sections: [Configuration](#configuration), [The skill library](#the-skill-library),
|
|
15
15
|
[Customize and add skills](#customize-and-add-skills), [Install the
|
|
16
|
-
|
|
16
|
+
controller skills into Codex and Claude Code](#install-the-controller-skills-into-codex-and-claude-code)
|
|
17
17
|
and [Upgrade from 0.8.0](#upgrade-from-080).
|
|
18
18
|
|
|
19
19
|
## Configuration
|
|
@@ -96,6 +96,11 @@ Doctor reports `config_invalid`. Stderr shows the stable startup code
|
|
|
96
96
|
for example two aliases for `builtin:pi-session-review`;
|
|
97
97
|
- a catalog value that violates the rules above (including a malformed
|
|
98
98
|
`builtin:` name), or more than 64 entries;
|
|
99
|
+
- a catalog value `builtin:pi-session-orchestration` or
|
|
100
|
+
`builtin:pi-session-profiles`, selected or not: the catalog serves Pi
|
|
101
|
+
workers, and the controller skills are for the controlling agent only. Doctor
|
|
102
|
+
reports `skill_controller_selected` for `configuration:skillCatalog.<alias>`
|
|
103
|
+
instead of `config_invalid`;
|
|
99
104
|
- more than 16 selected aliases.
|
|
100
105
|
|
|
101
106
|
## The skill library
|
|
@@ -143,7 +148,7 @@ The shipped example configuration registers the two worker skills with
|
|
|
143
148
|
|
|
144
149
|
### Shipped skills
|
|
145
150
|
|
|
146
|
-
The package ships
|
|
151
|
+
The package ships four skills under `skills/`. Each has one canonical copy and
|
|
147
152
|
frontmatter with only `name` and `description`.
|
|
148
153
|
|
|
149
154
|
| Skill | For | Use |
|
|
@@ -151,6 +156,7 @@ frontmatter with only `name` and `description`.
|
|
|
151
156
|
| `pi-session-implementation` | A Pi worker | One bounded implementation task and a fixed final report. Register it as `builtin:pi-session-implementation` and select it on coding profiles. |
|
|
152
157
|
| `pi-session-review` | A Pi worker | A review of a fixed target with findings and evidence. Register it as `builtin:pi-session-review` and select it on read-only profiles. |
|
|
153
158
|
| `pi-session-orchestration` | The controlling Claude Code or Codex agent | How to run Pi worker sessions through this server. `setup --apply` installs it into the clients. It is not a Pi worker skill: do not select it in a profile. |
|
|
159
|
+
| `pi-session-profiles` | The controlling agent | Create, change, tune, rename or retire execution profiles and change container repository profile selections. Uses the offline model catalog and a bounded profile probe, preserves writer work, and reports evidence. `setup --apply` installs it into clients; do not select it in a Pi worker profile. |
|
|
154
160
|
|
|
155
161
|
The worker skills ask for concise final reports: status, actual changed paths,
|
|
156
162
|
checks with exit codes, failures, blockers, risks and repository-relative
|
|
@@ -287,18 +293,19 @@ equals a shipped skill replaces that skill instead of adding one.
|
|
|
287
293
|
Where `setup` is unsupported, create an override by copying a shipped skill
|
|
288
294
|
directory by hand. Doctor does not track a copy that has no recorded base.
|
|
289
295
|
|
|
290
|
-
## Install the
|
|
296
|
+
## Install the controller skills into Codex and Claude Code
|
|
291
297
|
|
|
292
|
-
|
|
293
|
-
`pi-session-mcp-setup --apply --target <target>`
|
|
294
|
-
registration, as
|
|
295
|
-
|
|
298
|
+
`pi-session-orchestration` and `pi-session-profiles` are for the controlling
|
|
299
|
+
agent, not for a Pi worker. `pi-session-mcp-setup --apply --target <target>`
|
|
300
|
+
installs both after the registration, as real copies of the effective skills:
|
|
301
|
+
your per-skill override if present, else the shipped skill. Clients discover
|
|
302
|
+
them without further steps.
|
|
296
303
|
|
|
297
|
-
| Target | Skill
|
|
304
|
+
| Target | Skill directories |
|
|
298
305
|
| --- | --- |
|
|
299
|
-
| `codex:user:pi-session-mcp` | `~/.agents/skills/pi-session-orchestration` |
|
|
300
|
-
| `claude-code:user:pi-session-mcp` and `claude-code:local:pi-session-mcp` | `~/.claude/skills/pi-session-orchestration` (
|
|
301
|
-
| `claude-code:project:pi-session-mcp` | `<project>/.claude/skills/pi-session-orchestration`, where `<project>` is the directory in which `setup` runs |
|
|
306
|
+
| `codex:user:pi-session-mcp` | `~/.agents/skills/pi-session-orchestration` and `~/.agents/skills/pi-session-profiles` |
|
|
307
|
+
| `claude-code:user:pi-session-mcp` and `claude-code:local:pi-session-mcp` | `~/.claude/skills/pi-session-orchestration` and `~/.claude/skills/pi-session-profiles` (shared by both scopes) |
|
|
308
|
+
| `claude-code:project:pi-session-mcp` | `<project>/.claude/skills/pi-session-orchestration` and `<project>/.claude/skills/pi-session-profiles`, where `<project>` is the directory in which `setup` runs |
|
|
302
309
|
|
|
303
310
|
Claude Code reads personal skills in `~/.claude/skills/<name>/SKILL.md` and
|
|
304
311
|
project skills in `.claude/skills/<name>/SKILL.md`
|
|
@@ -306,8 +313,9 @@ project skills in `.claude/skills/<name>/SKILL.md`
|
|
|
306
313
|
skills in `~/.agents/skills`
|
|
307
314
|
([Codex skills](https://learn.chatgpt.com/docs/build-skills)).
|
|
308
315
|
|
|
309
|
-
Every
|
|
310
|
-
scope and
|
|
316
|
+
Every eligible target has two skill findings in addition to its registration
|
|
317
|
+
finding, with the same client and scope and aliases `pi-session-orchestration`
|
|
318
|
+
and `pi-session-profiles`. A skill problem never blocks
|
|
311
319
|
the registration, but a `divergent` or `failed` skill finding makes the overall
|
|
312
320
|
status `failed` (exit 1), so it is not overlooked.
|
|
313
321
|
|
|
@@ -432,7 +440,7 @@ The directories of updates by 0.8.0 had random names. Setup never searches for
|
|
|
432
440
|
or deletes them; you may delete them by hand. `--dry-run` and `--verify` do not
|
|
433
441
|
report leftover intermediates.
|
|
434
442
|
|
|
435
|
-
### Customize the controller
|
|
443
|
+
### Customize the controller skills
|
|
436
444
|
|
|
437
445
|
Never edit the installed copy: it becomes divergent. Instead:
|
|
438
446
|
|
|
@@ -441,13 +449,18 @@ Never edit the installed copy: it becomes divergent. Instead:
|
|
|
441
449
|
3. `pi-session-mcp-setup --apply --target <target>` again. The unmodified
|
|
442
450
|
installed copy is replaced (`skill_updated`).
|
|
443
451
|
|
|
452
|
+
The same steps work for `pi-session-profiles`: use
|
|
453
|
+
`pi-session-mcp-setup --customize-skill pi-session-profiles` to plan the copy,
|
|
454
|
+
then add `--apply`, edit its override and reapply your client targets. Each
|
|
455
|
+
skill has independent ownership, update, verification and removal behavior.
|
|
456
|
+
|
|
444
457
|
To recover after editing the installed copy, move your edits into the override,
|
|
445
458
|
delete the installed copy, and run `--apply` again.
|
|
446
459
|
|
|
447
460
|
### Scope of what setup installs
|
|
448
461
|
|
|
449
|
-
Setup installs only `pi-session-orchestration`
|
|
450
|
-
are for Pi profiles and are used through `builtin:`. Controller skills of your
|
|
462
|
+
Setup installs only `pi-session-orchestration` and `pi-session-profiles` into
|
|
463
|
+
clients. The worker skills are for Pi profiles and are used through `builtin:`. Controller skills of your
|
|
451
464
|
own belong in the clients' native skill directories; setup does not manage
|
|
452
465
|
them.
|
|
453
466
|
|
|
@@ -457,8 +470,9 @@ Where `setup` does not run, copy the directory; do not link it. Copy
|
|
|
457
470
|
`skills/pi-session-orchestration` from the installed package (in an npm
|
|
458
471
|
installation `"$(npm root -g)/pi-session-mcp/skills/pi-session-orchestration"`)
|
|
459
472
|
to `~/.claude/skills/` or `.claude/skills/` of a project for Claude Code, or to
|
|
460
|
-
`~/.agents/skills/` for Codex.
|
|
461
|
-
|
|
473
|
+
`~/.agents/skills/` for Codex. Also copy `skills/pi-session-profiles` from the
|
|
474
|
+
same package root into the same client skill directory. Repeat both copies
|
|
475
|
+
after a package update; nothing keeps a manual copy current. Do not replace an existing skill of the same name
|
|
462
476
|
without checking it first.
|
|
463
477
|
|
|
464
478
|
Neither client needs a skill to call the Pi Session MCP tools; the skill only
|
|
@@ -471,8 +485,11 @@ setup](client-setup.md#run-codex-without-prompts) describes.
|
|
|
471
485
|
|
|
472
486
|
Pi workers never discover skills on their own in Pi Session MCP. Register the
|
|
473
487
|
worker skills with `builtin:` and select them on profiles, as described above.
|
|
474
|
-
|
|
475
|
-
tools of its profile and is not
|
|
488
|
+
Neither controller skill can be selected for a Pi worker: a worker has only the
|
|
489
|
+
tools of its profile and is not the controlling agent, so the configuration
|
|
490
|
+
rejects `builtin:pi-session-orchestration` and `builtin:pi-session-profiles` as
|
|
491
|
+
catalog values. A catalog entry with a plain path to a copy of a controller
|
|
492
|
+
skill is not detected; do not add one.
|
|
476
493
|
|
|
477
494
|
## What happens at session start
|
|
478
495
|
|
|
@@ -583,8 +600,8 @@ to.
|
|
|
583
600
|
Skills are operator-managed prompt content. The override directory and its
|
|
584
601
|
bases file are operator-trusted configuration next to the configuration file,
|
|
585
602
|
never a workspace; keep them out of every workspace and writable only by you.
|
|
586
|
-
Setup copies the effective
|
|
587
|
-
directories, where
|
|
603
|
+
Setup copies the effective controller skills into the clients' skill
|
|
604
|
+
directories, where they become instructions for the controlling agent, so review
|
|
588
605
|
an override like code. In a `coding` profile a skill's
|
|
589
606
|
instructions are executed with that profile's tools, so review a skill like
|
|
590
607
|
code. A skill grants no rights: the tools of the permission profile stay the
|
|
@@ -4,9 +4,11 @@ Planning basis: main `47b8d26` (Sprint 7 merged), installed release 0.11.2.
|
|
|
4
4
|
Tracking: [#79](https://github.com/plagor44-ux/pi-session-mcp/issues/79),
|
|
5
5
|
prerequisite [#121](https://github.com/plagor44-ux/pi-session-mcp/issues/121).
|
|
6
6
|
|
|
7
|
-
Status: **
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
Status: **in progress** — steps 1–4 are done (pilot `pi-session-mcp`,
|
|
8
|
+
`node-app`, the operator images, go-app) and steps 5–7 are open; see
|
|
9
|
+
[Progress (2026-10-27)](#progress-2026-10-27) and the v0.11.6 and v0.11.8
|
|
10
|
+
post-release evidence in [Acceptance](../acceptance.md). The maintainer made
|
|
11
|
+
the choices on 2026-10-25; see [Decisions](#decisions-2026-10-25).
|
|
10
12
|
|
|
11
13
|
## Mandate
|
|
12
14
|
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Sprint 12: audit findings F1–F3
|
|
2
|
+
|
|
3
|
+
Planning basis: main `9d9cf8ca49e6e34dc16be6846b9324ad26ad92b9` (merge of PR
|
|
4
|
+
#191), published 0.14.0, 2026-10-29. Entry: an external audit of that commit
|
|
5
|
+
reported three defects with reproductions. This file plans the work and records
|
|
6
|
+
it as it lands; it claims nothing that its progress log does not state with
|
|
7
|
+
evidence.
|
|
8
|
+
|
|
9
|
+
Branch: `fix/s12-audit-findings`, one pull request, no release.
|
|
10
|
+
|
|
11
|
+
## Preflight (2026-10-29)
|
|
12
|
+
|
|
13
|
+
- main and `origin/main` at `9d9cf8c`; open issues #79, #120, #144; no open
|
|
14
|
+
pull requests; clean operator checkout; no other worktree in use.
|
|
15
|
+
- Doctor: no errors; only the known `workspace_gitfile` and
|
|
16
|
+
`workspace_mode_unset` warnings of the host worktree aliases.
|
|
17
|
+
- Level 1 on `9d9cf8c` in a clean detached worktree on the workstation:
|
|
18
|
+
`npm ci`, `npm run typecheck`, `npm run build:cli`,
|
|
19
|
+
`NODE_OPTIONS=--unhandled-rejections=strict npm test` (527 files, 4005
|
|
20
|
+
passed, 14 skipped, 0 failed, no unhandled error) and `npm run build` all exit
|
|
21
|
+
0. The audit's cloud run of the same commit reported 70 failed tests and four
|
|
22
|
+
unhandled errors; they do not reproduce here, so they are not attributed to
|
|
23
|
+
the product. The audit environment is not available to separate them further.
|
|
24
|
+
- Both `pi-session-mcp` writers were at `baseline` on an older main and were
|
|
25
|
+
reset without `--discard` to `9d9cf8c` (`writer_reset`).
|
|
26
|
+
|
|
27
|
+
## Findings, re-checked on `9d9cf8c`
|
|
28
|
+
|
|
29
|
+
| Id | Issue | Reproduction by the controller | Result |
|
|
30
|
+
| --- | --- | --- | --- |
|
|
31
|
+
| F1 | [#192](https://github.com/plagor44-ux/pi-session-mcp/issues/192) | Synthetic workspace whose `AGENTS.md` links to an outside marker file; `PI_CODING_AGENT_DIR` isolated; faux provider | Confined `read` refuses; `getAgentsFiles()` contains the marker; the real `SdkPiSessionAdapter` sends it as `project_instructions` to the faux provider. Confirmed. |
|
|
32
|
+
| F2 | [#193](https://github.com/plagor44-ux/pi-session-mcp/issues/193) | Real Git; boundary scripts run by an injected runner | Detached `HEAD` commit, clean tree: remove before collect `writer_uncollected`; collect `nothing_to_collect`, 0 refs, digest stored; commit absent from the operator checkout; finish `writer_reset`; remove `writer_removed`. Feature-branch counterproof exports the commit. Confirmed; not yet a Podman result. |
|
|
33
|
+
| F3 | [#194](https://github.com/plagor44-ux/pi-session-mcp/issues/194) | Real relay over stdio, fake writer server fixture | Identical profiles admitted; model drift refused with `settingsChanged`; host `skills: ["pi-session-implementation"]` against inner `skills: []` admitted. Confirmed. |
|
|
34
|
+
|
|
35
|
+
## Decisions taken at planning
|
|
36
|
+
|
|
37
|
+
- F1: for read-only profiles every resource loader keeps only context files
|
|
38
|
+
whose real path lies inside the workspace's real path. Context files of
|
|
39
|
+
ancestor directories above the workspace, including a main repository above a
|
|
40
|
+
linked worktree, are no longer loaded for read-only profiles: they are outside
|
|
41
|
+
the read roots of ADR 0013. Coding profiles keep the SDK's behaviour.
|
|
42
|
+
- F2: smallest fix inside the existing collection contract; the export name for
|
|
43
|
+
a detached `HEAD` is a documented behaviour addition, no new public code.
|
|
44
|
+
- F3: the relay compares every public capability field a writer reports, with
|
|
45
|
+
set semantics for skills, extensions and granted extension tools.
|
|
46
|
+
- #120: still waiting for an SDK release (see below); no override, no
|
|
47
|
+
`npm audit fix --force`.
|
|
48
|
+
- No release on this branch.
|
|
49
|
+
|
|
50
|
+
## Roles and routing
|
|
51
|
+
|
|
52
|
+
`pi_capabilities_get` and `--list-models` on 2026-10-29 settle which requested
|
|
53
|
+
models exist as authenticated profiles:
|
|
54
|
+
|
|
55
|
+
| Requested | Profile used | Status |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| GPT 6.1 Sol | `code` (openai `gpt-6.1-sol`) | available |
|
|
58
|
+
| GPT 6.1 Terra | none | unavailable: the catalog lists no `gpt-6.1-terra`; not substituted with another version |
|
|
59
|
+
| DeepSeek | `code-deepseek` (`deepseek-flash`) | available |
|
|
60
|
+
| GLM 5.3 | `review-glm`, `code-glm` (`zai-glm-5-3`) | available |
|
|
61
|
+
| Mistral Large 4 | `code-mistral` (`mistral-large-4`) | available |
|
|
62
|
+
| Sonnet 5.5 | no profile; provider `anthropic` authenticated | added only in an expendable test configuration (acceptance item D) |
|
|
63
|
+
| Grok 4.7 | `review-grok` (xai `grok-4.7`) | available: the R2 turn completed |
|
|
64
|
+
|
|
65
|
+
agy (Antigravity CLI, Gemini) plans the work packages, dependencies and review
|
|
66
|
+
routing; Pi workers implement and review; the controller integrates, verifies
|
|
67
|
+
and is the only editor of this file, the roadmap, `docs/acceptance.md` and the
|
|
68
|
+
CHANGELOG.
|
|
69
|
+
|
|
70
|
+
## Tasks
|
|
71
|
+
|
|
72
|
+
| Id | Task | Route | Change area |
|
|
73
|
+
| --- | --- | --- | --- |
|
|
74
|
+
| P1 | Work packages, dependencies, review routing | agy | none |
|
|
75
|
+
| P2 | Independent regression test plan | `review-glm` | none |
|
|
76
|
+
| T1 | F1, #192 | `pi-session-mcp` writer, `code` | `src/sdk-pi-adapter.ts`, `src/confined-tools.ts`, tests |
|
|
77
|
+
| T2 | F2, #193 | `pi-session-mcp` writer, `code-mistral` (agy's fallback for the unavailable Terra) | `src/writer-lifecycle.ts`, tests |
|
|
78
|
+
| T3 | F3, #194 | `pi-session-mcp` writer, `code-deepseek` | `src/writer-relay.ts`, `src/capabilities.ts`, tests, relay fixture |
|
|
79
|
+
| R1 | Security review of T1 and T3 | Sonnet 5.5, read-only | none |
|
|
80
|
+
| R2 | Adversarial review of T2 and the Git lifecycle checks | `review-grok` | none |
|
|
81
|
+
| D1 | Documentation and issue reconciliation (#120, ADR 0014 status, Sprint 8 status, #79, #144) | `pi-session-mcp` writer, `code-mistral`; controller as editor | `docs/`, `skills/pi-session-orchestration/SKILL.md` |
|
|
82
|
+
| A | Live acceptance A–E | controller | evaluation record |
|
|
83
|
+
|
|
84
|
+
## Progress log
|
|
85
|
+
|
|
86
|
+
Recorded as work lands on the branch.
|
|
87
|
+
|
|
88
|
+
- 2026-10-29: issues #192, #193 and #194 filed; this plan written before any
|
|
89
|
+
implementation.
|
|
90
|
+
- P1: agy (`gemini-3.8-flash-high`, plan mode) proposed the packages,
|
|
91
|
+
`code-mistral` as the F2 author in place of Terra, Sonnet for R1 and Grok
|
|
92
|
+
with a fallback for R2, and at most three review rounds. Adopted.
|
|
93
|
+
- P2: `review-glm` wrote the regression test plan; its edge cases (absent
|
|
94
|
+
against empty set fields, real-Git collection, a Podman case) went into the
|
|
95
|
+
task prompts.
|
|
96
|
+
- T3 (`code-deepseek`, writer w2): collected as
|
|
97
|
+
`writer-pi-session-mcp-w2/fix/f3-relay-profile-drift`; the controller ran the
|
|
98
|
+
new tests against the old source (7 fail) and the fix (all pass); integrated
|
|
99
|
+
as `230e60e`, writer finished (`writer_reset`).
|
|
100
|
+
- T1 (`code`, writer w1): collected as
|
|
101
|
+
`writer-pi-session-mcp-w1/fix/f1-context-files`; new tests against the old
|
|
102
|
+
source 9 of 12 fail, with the fix 148 of 148 pass; integrated as `a0a7d87`,
|
|
103
|
+
writer finished. The container-writer suite showed only the eight known
|
|
104
|
+
lock and hook timeouts (`override-lock`, `skill-customize-concurrency`,
|
|
105
|
+
`wake-hook`).
|
|
106
|
+
- R1 (Sonnet 5.5, read-only, through the test configuration of item D):
|
|
107
|
+
`NON_BLOCKING_ONLY`. Fixed by the controller: kept context files are read
|
|
108
|
+
again from their verified real path (`79e8a7a`), the set comparison is
|
|
109
|
+
symmetric with a duplicated-entry test (`3e14279`); the shadowing case is
|
|
110
|
+
covered by a test and documented. Not changed: synchronous `realpathSync` in
|
|
111
|
+
the loader override (the SDK hook is synchronous) and the trust in the
|
|
112
|
+
writer's own capability report, which is the boundary the relay already
|
|
113
|
+
assumes.
|
|
114
|
+
- T2 (`code-mistral`, writer w2): collected as
|
|
115
|
+
`writer-pi-session-mcp-w2/fix/f2-detached-collect`; the new real-Git tests
|
|
116
|
+
against the old source 3 of 8 fail, with the fix 8 of 8 pass, and the F2
|
|
117
|
+
reproduction now gets `writer_collected`; integrated as `236ca28`, writer
|
|
118
|
+
finished. The controller added the Podman case (`6ee7add`): with real
|
|
119
|
+
rootless Podman and the pinned Node image it passes, against the old source
|
|
120
|
+
it fails.
|
|
121
|
+
- D1 (`code-mistral`, writer w1): collected as
|
|
122
|
+
`writer-pi-session-mcp-w1/docs/s12-reconcile`; split by issue into
|
|
123
|
+
`f5a9712`, `58e0e7b`, `17845ff` and `ebe3c52`. Controller edits: the
|
|
124
|
+
shadowing and re-read rule in the ADR 0013 amendment, and the relay wording
|
|
125
|
+
(a mismatch counts as `settingsChanged`; `writer_unavailable` with
|
|
126
|
+
`none_admitted` only when no writer is admitted). Writer finished.
|
|
127
|
+
- R2 (`review-grok`, Grok 4.7, read-only): `NON_BLOCKING_ONLY`. Verified by
|
|
128
|
+
the controller and fixed in `1dfe4da`: a derived `-wip` or `-detached` name
|
|
129
|
+
that conflicts with an exported branch path aborted the export under
|
|
130
|
+
`set -eu` (reproduced with a branch `main-detached/topic`); a worker-made
|
|
131
|
+
`git replace --graft` made an unexported detached commit look reachable
|
|
132
|
+
(Grok's variant with a plain replacement did not reproduce, the graft did);
|
|
133
|
+
the reachability gate now also runs on `nothing_to_collect`. Recorded as
|
|
134
|
+
limits, not changed: an index-only staged change that the worktree reverted
|
|
135
|
+
(pre-existing), a base name of 192 to 200 characters (fails closed), and a
|
|
136
|
+
runner that reports a fetch it did not do (outside the threat model).
|
|
137
|
+
- Final integration review (Sonnet 5.5, read-only, on `896e29d`):
|
|
138
|
+
`NON_BLOCKING_ONLY`. Fixed: the in-boundary guard probe now ignores replace
|
|
139
|
+
refs too (`9426682`, with a test that fails without it), the BOM pattern is an
|
|
140
|
+
escape (`5d9f15b`), and execution modes names the pruned-base case of the
|
|
141
|
+
digest gate. Not changed: `inspectWork.head` stays optional because required
|
|
142
|
+
would break type-checked mocks outside this change.
|
|
143
|
+
- Acceptance: see
|
|
144
|
+
[Sprint 12 candidate acceptance](../acceptance.md#sprint-12-candidate-acceptance-2026-10-30).
|
|
145
|
+
Level 1 green on `9426682`; Level 2 green on the packed `896e29d`; live items
|
|
146
|
+
B, C and D passed on expendable configurations and were rolled back; the
|
|
147
|
+
Level 3 ten-task cycle 2 passed (10 of 10) after cycle 1 failed on fixture and
|
|
148
|
+
harness design (5 of 10, kept unchanged).
|
|
149
|
+
|
|
150
|
+
## Results
|
|
151
|
+
|
|
152
|
+
| Finding | Status | Commits | Evidence |
|
|
153
|
+
| --- | --- | --- | --- |
|
|
154
|
+
| F1 #192 | fixed | `a0a7d87`, `79e8a7a`, `5d9f15b`; docs `f5a9712` | `test/read-only-context-files.test.ts` (fails on `9d9cf8c`), faux-provider context check, R1 and final review |
|
|
155
|
+
| F2 #193 | fixed | `236ca28`, `6ee7add`, `1dfe4da`, `9426682`; docs `58e0e7b`, `896e29d` | real-Git collect tests, Podman test, guard test (each fails on the source before), R2 and final review |
|
|
156
|
+
| F3 #194 | fixed | `230e60e`, `3e14279`; docs `17845ff` | `test/writer-relay.test.ts` drift tests (fail on `9d9cf8c`), live refusal with `settingsChanged`, R1 and final review |
|
|
157
|
+
|
|
158
|
+
Remaining risk: #120 is unchanged. `npm audit --omit=dev` on 2026-10-29 still
|
|
159
|
+
reports `undici` 8.10.2 (high) through `@earendil-works/pi-coding-agent` 1.4.0
|
|
160
|
+
(moderate), eight advisories fixed in `undici` >= 8.12.2; the only offered fix
|
|
161
|
+
is a semver-major downgrade. No override and no `npm audit fix --force`.
|
|
162
|
+
|
|
163
|
+
Kept open: #79 (Sprint 8 steps 5 to 7 are not done), #120 and #144 (no macOS
|
|
164
|
+
claim). The sandbox resource limits of ADR 0013 are the follow-up issue
|
|
165
|
+
[#195](https://github.com/plagor44-ux/pi-session-mcp/issues/195), not part of
|
|
166
|
+
this sprint.
|
|
167
|
+
|
|
168
|
+
Cleanup: all controller Pi sessions closed; both `pi-session-mcp` writers
|
|
169
|
+
finished (`writer_reset`); the test writer `s12-probe-w1` removed; expendable
|
|
170
|
+
configurations, the synthetic repository, the pack prefix and the
|
|
171
|
+
controller's worktrees removed.
|
|
172
|
+
|
package/docs/threat-model.md
CHANGED
|
@@ -16,7 +16,16 @@ Pi Session MCP trusts the local process that launches and speaks MCP over inheri
|
|
|
16
16
|
(arguments the SDK would rewrite, such as a leading `@` or `~`, a `file:`
|
|
17
17
|
URL, Unicode spaces or NUL, are refused so both resolve the same path), and
|
|
18
18
|
the `*Operations` hooks of `read`, `grep` and `ls` check the absolute path
|
|
19
|
-
again. `rg` and `fd` do not follow symlinks during traversal.
|
|
19
|
+
again. `rg` and `fd` do not follow symlinks during traversal. For read-only
|
|
20
|
+
profiles the resource loader likewise keeps only Pi context files
|
|
21
|
+
(`AGENTS.override.md`, `AGENTS.md`, `AGENTS.MD`, `CLAUDE.md`, `CLAUDE.MD`)
|
|
22
|
+
whose real path lies inside the workspace's real path, on every reload and
|
|
23
|
+
before the first provider request: a symlinked context file that resolves
|
|
24
|
+
outside the workspace, a dangling one and the context files of ancestor
|
|
25
|
+
directories above the workspace (including a main repository above a linked
|
|
26
|
+
worktree) are not loaded, while the linked worktree's own file inside the
|
|
27
|
+
workspace is. Coding profiles keep the SDK behaviour (the working directory
|
|
28
|
+
and its ancestors). A profile with
|
|
20
29
|
`shell: "sandboxed"` also gets `bash`, run as `/usr/bin/bwrap` (fixed path,
|
|
21
30
|
root-owned and not group- or world-writable, no `PATH` lookup) with
|
|
22
31
|
`--unshare-all`, `--disable-userns`, a cleared environment, no network, `/usr`
|
package/docs/tool-contracts.md
CHANGED
|
@@ -40,7 +40,7 @@ records name the package version and the build they ran on, see
|
|
|
40
40
|
```json
|
|
41
41
|
{
|
|
42
42
|
"ok": true,
|
|
43
|
-
"server": { "name": "pi-session-mcp", "version": "0.
|
|
43
|
+
"server": { "name": "pi-session-mcp", "version": "0.14.1" },
|
|
44
44
|
"configuration": {
|
|
45
45
|
"fingerprint": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
|
46
46
|
"reloadPolicy": "restart-required"
|
package/package.json
CHANGED
|
@@ -122,7 +122,7 @@ You integrate. Workers never integrate each other's changes. Resolve conflicts b
|
|
|
122
122
|
|
|
123
123
|
After taking over the result and closing its coding session, before the next task:
|
|
124
124
|
|
|
125
|
-
1. Run `pi-session-mcp-setup --writer <name> --collect --apply` from the operator environment. Review the collected refs in the operator's checkout: `refs/remotes/writer-<name>/<branch>`, with uncommitted work as `<branch>-wip`. They are untrusted until reviewed. Integrate only verified work yourself.
|
|
125
|
+
1. Run `pi-session-mcp-setup --writer <name> --collect --apply` from the operator environment. Review the collected refs in the operator's checkout: `refs/remotes/writer-<name>/<branch>`, with uncommitted work as `<branch>-wip` and a clean detached HEAD as `<base>-detached`. They are untrusted until reviewed. Integrate only verified work yourself.
|
|
126
126
|
2. Run `pi-session-mcp-setup --writer <name> --finish --apply`. It collects again, then resets a persistent writer or recreates an ephemeral writer. Do not reuse it until this succeeds. A refused branch name makes collection incomplete and finish stops: ask the operator to resolve it by renaming inside the boundary or explicitly discarding with `--reset --discard --apply`. Finish returns it to the workspace default base. No reconnect is needed after reset, finish or recreate. A setup operation on a writer held by a session fails with `writer_busy` after a short wait; close the session and allow launcher cleanup to finish.
|
|
127
127
|
3. A coding start needs the writer's clone at its baseline, even after a complete collection; otherwise it fails with the controller-action code for uncollected work in [references/start-errors.md](references/start-errors.md). To let a fresh session continue from collected work, for example after a failed turn or for a review fix round, create a local branch at the collected ref and run `pi-session-mcp-setup --writer <name> --reset --base <branch> --apply`, then call `pi_session_start` on `pi-session-mcp` with the coding profile and `base: "<branch>"`. Read `writer` from that result for collection. Default starts cannot use a writer moved to the fix branch.
|
|
128
128
|
4. Never run Git inside the writer's clone as the host user, including direct fetch from that clone. Use setup's bundle collection and inspect the imported refs in your own checkout. Never discard unreviewed work just to admit the next task.
|