paseo-room 0.1.0-alpha.6 → 0.2.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.
Files changed (42) hide show
  1. package/README.md +178 -53
  2. package/dist/index.js +966 -428
  3. package/dist/index.js.map +1 -1
  4. package/dist/plugin-assets/index.server.ts +50 -0
  5. package/dist/plugin-assets/package.json +5 -0
  6. package/dist/plugin-assets/paseo-plugin.json +5 -0
  7. package/dist/plugin-assets/server/carrier.ts +41 -0
  8. package/dist/plugin-assets/server/contract.ts +3 -0
  9. package/dist/plugin-assets/tsconfig.json +10 -0
  10. package/dist/prompts/contract/lead/complete-peer-brief.md +10 -0
  11. package/dist/prompts/contract/lead/independent-review.md +9 -0
  12. package/dist/prompts/contract/lead/moving-write-ownership.md +13 -0
  13. package/dist/prompts/contract/lead/peer-seat-lifecycle.md +30 -0
  14. package/dist/prompts/contract/lead/project-technical-ownership.md +12 -0
  15. package/dist/prompts/contract/lead/technical-acceptance.md +6 -0
  16. package/dist/prompts/contract/peer/bounded-outcome.md +5 -0
  17. package/dist/prompts/contract/peer/independent-judgment.md +11 -0
  18. package/dist/prompts/contract/peer/no-orchestration.md +5 -0
  19. package/dist/prompts/contract/peer/no-self-acceptance.md +5 -0
  20. package/dist/prompts/contract/peer/reproducible-handoff.md +5 -0
  21. package/dist/prompts/contract/peer/writing-and-review-scope.md +5 -0
  22. package/dist/prompts/contract/shared/evidence-and-event-waiting.md +7 -0
  23. package/dist/prompts/contract/shared/human-authority.md +8 -0
  24. package/dist/prompts/contract/shared/scope-and-unrelated-work.md +4 -0
  25. package/dist/prompts/contract/shared/workspace-protocol-precedence.md +15 -0
  26. package/dist/prompts/contract/shared-lead-peer/challenge-signals.md +9 -0
  27. package/dist/prompts/contract/supervisor/directive-integrity.md +5 -0
  28. package/dist/prompts/contract/supervisor/escalation-boundaries.md +5 -0
  29. package/dist/prompts/contract/supervisor/lead-discovery-and-recovery.md +52 -0
  30. package/dist/prompts/contract/supervisor/observation-and-advice.md +13 -0
  31. package/dist/prompts/contract/supervisor/technical-non-interference.md +8 -0
  32. package/dist/prompts/documents/lead.md +3 -0
  33. package/dist/prompts/documents/peer.md +3 -0
  34. package/dist/prompts/documents/supervisor.md +3 -0
  35. package/dist/prompts/documents/workspace.md +5 -0
  36. package/dist/prompts/pi/communication-style.md +5 -0
  37. package/dist/prompts/pi/runtime.md +7 -0
  38. package/dist/prompts/workspace/repository-conventions.md +7 -0
  39. package/dist/prompts/workspace/review.md +4 -0
  40. package/dist/prompts/workspace/topology.md +13 -0
  41. package/dist/prompts/workspace/verification.md +8 -0
  42. package/package.json +4 -3
package/README.md CHANGED
@@ -7,7 +7,8 @@ It does three things:
7
7
 
8
8
  1. Reads your existing Codex / Claude Code / Pi configuration.
9
9
  2. Writes one isolated role home per seat under `~/.paseo-room`. Each role owns its mutable
10
- credentials; read-only skills, plugins and other supported resources may be symlinked.
10
+ credentials; read-only skills and other supported resources may be symlinked, and Peer
11
+ receives a narrower set than Supervisor and Lead.
11
12
  3. Registers those role homes with your running Paseo daemon as providers — room tools on for Supervisor and Lead, off for Peer — and adds one agent profile per seat so opening one is a single pick.
12
13
 
13
14
  Everything it manages lives in `$HOME`, under `~/.paseo-room`. Agent runtimes may later
@@ -63,10 +64,15 @@ starts, its exit code is preserved; a signal is returned using the conventional
63
64
  ## Requirements
64
65
 
65
66
  - Node 22 or newer, macOS or Linux.
66
- - A running Paseo daemon with CLI and daemon on the same version. Codex and Claude require
67
- **0.8.0-beta.1 or newer**; any selection containing Pi requires **0.8.0 or newer**.
68
- `paseo-room` checks this before touching anything, and never installs or upgrades Paseo.
67
+ - A running Paseo daemon with CLI and daemon on the same version. Codex requires
68
+ **0.8.0-beta.1 or newer**; any selection containing Claude or Pi requires **0.8.0 or newer**.
69
+ Claude also requires Paseo plugins to be enabled explicitly: the generated trusted server plugin
70
+ is the strong contract carrier, and `paseo-room` never enables plugins for you. The plugin is
71
+ version-bounded to `>=0.8.0 <0.9.0`. `paseo-room` checks compatibility before touching anything,
72
+ and never installs or upgrades Paseo.
69
73
  - An initialised Codex home (`~/.codex/config.toml`) and/or Claude Code home (`~/.claude`).
74
+ Codex must be new enough for `codex debug models` to print its JSON model catalog: the room
75
+ seats Codex only if it can generate the scrubbed catalog copy.
70
76
  Setup never copies mutable credential stores or runs login. Use supported environment/static
71
77
  auth, or log in once in each role after setup. For current Claude runtimes, paseo-room
72
78
  pins both `CLAUDE_CONFIG_DIR` and `CLAUDE_SECURESTORAGE_CONFIG_DIR` per role. It does not
@@ -83,25 +89,28 @@ starts, its exit code is preserved; a signal is returned using the conventional
83
89
  room.json # what this CLI created; verify and remove read it
84
90
  AUTHENTICATION.md # exact per-role login commands; contains no secrets
85
91
  room/WORKSPACE_PROTOCOL.md # the default protocol every seat carries, as one readable file
92
+ plugin/ # Claude only: trusted creation-time system-prompt append carrier
93
+ paseo-plugin.json # accepts Paseo >=0.8.0 <0.9.0
94
+ index.server.ts, server/ # exact provider map + generated role contracts
86
95
  roles/codex/<role>/
87
96
  config.toml # your config.toml + the room's overrides
88
97
  role-instructions.md # readable copy of what this seat was told
89
- model-catalog.json # your catalog with native multi-agent metadata removed
98
+ model-catalog.json # generated copy of your catalog, native multi-agent metadata removed
90
99
  auth.json # created and owned by Codex after role login, if file-backed
91
- AGENTS.md, skills, plugins, hooks.json → symlinks into ~/.codex when present
100
+ AGENTS.md, skills, plugins, hooks.json → symlinks into ~/.codex when present (Peer: see below)
92
101
  roles/claude/<role>/
93
102
  CLAUDE.md # your global memory + role instructions
94
103
  settings.json # your settings.json + PASEO_ROOM_ROLE
95
104
  .claude.json # seeded once from yours, then owned by Claude
96
105
  .credentials.json # created and owned by Claude after role login, if file-backed
97
106
  skills, plugins, commands, hooks, rules, output-styles,
98
- keybindings.json, themes → symlinks into ~/.claude when present
107
+ keybindings.json, themes → symlinks into ~/.claude when present (Peer: see below)
99
108
  roles/pi/<role>/
100
109
  settings.json # your settings minus package/extension declarations
101
110
  APPEND_SYSTEM.md # your append + style/runtime capsules + role instructions
102
111
  auth.json # created and owned by Pi after role login, if used
103
112
  models.json, AGENTS.md, skills, prompts, themes,
104
- keybindings.json, mcp.json → symlinks into ~/.pi/agent when present
113
+ keybindings.json, mcp.json → symlinks into ~/.pi/agent when present (Peer: see below)
105
114
  ```
106
115
 
107
116
  Each seat gets its own file-backed credential path, sessions, history and projects inside its
@@ -109,6 +118,42 @@ role home. Current supported runtimes therefore do not share mutable file-backed
109
118
  or conversation state; older-runtime Claude Keychain isolation remains unverifiable. Credential
110
119
  paths are never managed-entry symlinks: setup and update preserve whatever is already there.
111
120
 
121
+ A managed file or symlink only ever replaces an absent path or the same shape, and it is
122
+ written to a temporary sibling and renamed into place, so a seat never reads a half-written
123
+ file. Anything else at a managed path — a directory where a file belongs, an unexpected
124
+ symlink — makes setup stop and name the path for you to move aside. Nothing is deleted
125
+ recursively on your behalf.
126
+
127
+ ### What Peer does not receive
128
+
129
+ Peer has no room tools, so the room also stops handing it orchestration surfaces:
130
+
131
+ - Resources whose contents execute are not shared with Peer at all — Codex `plugins` and
132
+ `hooks.json`, Claude `plugins`, `commands` and `hooks`, Pi `prompts`. Supervisor and Lead
133
+ still get them.
134
+ - Peer's `skills` is not one symlink to your skills directory. It is a room-owned directory
135
+ of links to each of your skills whose name does not start with `paseo` (any capitalization),
136
+ so orchestration skills are not advertised to the seat that cannot orchestrate. Adding or
137
+ removing one of your skills is drift `verify` reports and `setup --apply` reconciles.
138
+
139
+ Your own skills directory is never modified: `paseo*` skills stay exactly where they are.
140
+ An existing room upgrades its one legacy Peer `skills` symlink to that projection on the next
141
+ `setup --apply`; setup only unlinks the alias, never your skills, and stops with an actionable
142
+ message if that path has become something it does not recognize.
143
+
144
+ This is capability hygiene, not a sandbox. Peer still has shell access.
145
+
146
+ ### Paseo MCP servers are refused, never rewritten
147
+
148
+ Paseo is the room's only control plane, so setup and verify read the MCP declarations in your
149
+ Codex `config.toml`, your Claude state, Pi's `mcp.json`, and any already-seeded role
150
+ `.claude.json`, and **fail before applying anything** if a declaration looks Paseo-related.
151
+ Recognition is one bounded rule — `paseo` as a whole identifier or path token, in the server
152
+ name, `command`, `args` or a URL field — and the message quotes the file and the field that
153
+ matched. It is a heuristic, not a scanner: a renamed or obfuscated endpoint passes it. Remove
154
+ or rename the server yourself; `paseo-room` never edits, filters or deletes your MCP
155
+ configuration.
156
+
112
157
  Pi role homes deliberately do not link `extensions`, `npm`, `git`, `trust.json`, runtime
113
158
  caches or session state. Their copied `settings.json` removes `packages` and `extensions`,
114
159
  so startup cannot install configured packages or discover unrelated configured extensions.
@@ -176,21 +221,42 @@ For Codex, the generated `config.toml` is a copy of yours with only these keys o
176
221
  | `sandbox_mode` | `danger-full-access` | A seat that stops to ask for permission cannot be driven headless. |
177
222
  | `approval_policy` | `never` | Same. |
178
223
  | `developer_instructions` | the role contract | This is the room's whole instruction payload. |
179
- | `model_catalog_json` | generated catalog | Strips `multi_agent_version` so the seat is not offered native collaboration. Skipped, with a warning, if your Codex cannot produce a catalog. |
180
- | `[agents].enabled` | `false` | Paseo owns agent lifecycle. |
224
+ | `model_catalog_json` | generated catalog | Strips `multi_agent_version` so the seat is not offered native collaboration. Setup **fails** if your Codex cannot produce a catalog. |
225
+ | `[agents].enabled` | `false` | Paseo owns agent lifecycle. Top-level only: Codex profiles have no such key. |
181
226
  | `features.multi_agent`, `features.multi_agent_v2` | `false` | Same, at the feature-flag level. |
182
227
 
183
- If your config has an active `profile`, the same sandbox and approval overrides are written
184
- into that profile too, because a profile outranks the top-level keys. Your model, reasoning
185
- effort, MCP servers, trusted projects and every other key are copied through untouched.
228
+ If your config has an active `profile`, every one of those keys a profile can also carry —
229
+ sandbox, approval, the catalog path and both multi-agent features — is written into that
230
+ profile too, because a profile outranks the top-level keys. Your model, reasoning effort, MCP
231
+ servers, trusted projects and every other key are copied through untouched.
232
+
233
+ The catalog is a closure, not a nicety, so it fails closed: if `codex debug models` cannot
234
+ run, does not print JSON, or prints JSON that is not a catalog object, no Codex seat is
235
+ planned and the message quotes the exact command it tried. A Codex too old to print that JSON
236
+ catalog cannot be seated.
237
+
238
+ What lands in each role home is a **generated copy** captured at that setup, and it replaces
239
+ Codex's built-in catalog for that seat. New models from a later Codex release therefore do not
240
+ reach a seat until you run `setup --apply` again. `verify` says so explicitly when a drifted
241
+ file is a `model-catalog.json`, because that seat is missing the closure rather than only
242
+ holding older contract text.
186
243
 
187
244
  **The room never replaces an agent's base prompt.** Codex's `model_instructions_file`,
188
245
  Claude's `--system-prompt` and Pi's `SYSTEM.md` / `--system-prompt` all *replace* the vendor
189
- system prompt; using them would mean
190
- vendoring a full copy of that prompt and re-vendoring it on every agent release. The role
191
- contract is additive instead: `developer_instructions` for Codex, `CLAUDE.md` for Claude,
192
- and the generated Pi `APPEND_SYSTEM.md` passed with `--append-system-prompt` for Pi. Pi keeps
193
- normal project `AGENTS.md` / `CLAUDE.md` context loading.
246
+ system prompt; using them would mean vendoring a full copy of that prompt and re-vendoring it
247
+ on every agent release. The role contract is additive instead: `developer_instructions` for
248
+ Codex, a room-owned Paseo creation hook that writes `config.systemPrompt` for Claude, and the
249
+ generated Pi `APPEND_SYSTEM.md` passed with `--append-system-prompt` for Pi. Pi keeps normal
250
+ project `AGENTS.md` / `CLAUDE.md` context loading.
251
+
252
+ For Claude, Paseo maps `config.systemPrompt` to the Claude Code preset's SDK `append` field,
253
+ so the native prompt remains intact while the generated role contract enters the instruction
254
+ layer. The trusted plugin targets only exact `claude-supervisor`, `claude-lead`, and
255
+ `claude-peer` room providers and skips internal agents; existing caller prompt text is
256
+ preserved. `CLAUDE.md` remains unchanged as a degraded and resume fallback. `verify` fails if
257
+ the plugin is absent, disabled, failed, registered from another path, or drifted, because a
258
+ silently missing carrier is not a guarantee. The hook runs for newly created sessions;
259
+ recreate an existing Claude session after setup or an update.
194
260
 
195
261
  Pi providers use a strict command tail:
196
262
 
@@ -224,6 +290,11 @@ agent's own configuration:
224
290
  | strict argv + `PI_MCP_CONFIG_MODE=exclusive` + additive runtime capsule | Pi | Disables extension discovery and project trust, and restricts adapter config to the role-home `mcp.json`; forbids a second agent control plane without claiming sandboxing. |
225
291
  | `paseoTools: {enabled}` | all | Room tools for Supervisor and Lead, never for Peer. |
226
292
 
293
+ `verify` compares each provider's `command`, `env`, `paseoTools` and pins against what the
294
+ room would write, and fails if one has been dropped — a pin that can be silently removed is
295
+ not a guarantee. The `env` map is compared whole rather than as a subset, because an added key
296
+ can re-enable exactly what a pin closes. Unrelated top-level provider fields stay yours.
297
+
227
298
  It also saves one **agent profile** per seat, which is what the Paseo picker lists under
228
299
  Profiles. A profile is a preset, not a constraint: it decides where a seat *starts*.
229
300
 
@@ -242,7 +313,10 @@ Supervisor starts low because it routes rather than reasons. No seat starts on t
242
313
  option — Codex's `ultra` and Claude's `ultracode` advertise automatic task delegation, which
243
314
  is a second control plane. `setup` restores room-owned identity, appearance and mode fields,
244
315
  but leaves your model and reasoning choice alone; profiles you created yourself are never
245
- touched.
316
+ touched. If you do put a room seat on `ultra` or `ultracode`, setup and verify warn and name
317
+ the seats: the room has not verified whether its closed multi-agent paths actually prevent
318
+ that option from delegating, so it reports the selection rather than rejecting or changing it.
319
+ The warning does not fail the command.
246
320
 
247
321
  Pi exposes no selectable Paseo mode, so its profiles omit `modeId`; setup also removes a
248
322
  stale room-owned value from an existing Pi profile. Pi has no sandbox or approval boundary:
@@ -264,24 +338,20 @@ the operator.
264
338
  ### Recognizing a live room seat
265
339
 
266
340
  Names are not identity. A matching cwd, title, or provider label does not make an existing
267
- agent a room Lead or Peer. Before Supervisor reuses a Lead, it reads `list_profiles` and
268
- selects the exact current `room-<agent>-lead` profile for the intended agent implementation.
269
- Because agent creation has no profile parameter, it materializes every field that profile
270
- defines: provider/model, `modeId`, `thinkingOptionId`, and `featureValues`, omitting absent
271
- fields. It uses `list_agents(cwd)` only to discover candidates because that filter also returns
272
- descendant working directories, then rejects anything whose cwd is not the exact project
273
- root, is archived, or runs a bare, wrong-role, or other provider. For every remaining
274
- candidate it reads `get_agent_status`: the provider must equal the selected profile's current
275
- provider, `workspaceId` must equal the intended workspace when that id is available, and
276
- `currentModeId` must equal the profile's `modeId` when the profile defines one. Parentage or
277
- known Human-opened ownership history must corroborate the established owner. An unparented
278
- or ambiguous candidate is not adopted silently; it enters the duplicate-recovery and Human
279
- escalation path in the role contract.
280
-
281
- Lead applies the same rule when creating a Peer: read the exact current
282
- `room-<agent>-peer` profile, materialize every present launch field in the intended workspace,
283
- then require the live seat's daemon-added `paseo.parent-agent-id` to name the current Lead.
284
- A Peer is one fresh brief and receives no room tools or orchestration authority.
341
+ agent a room Lead or Peer. The exact eligibility procedure is model-facing wording and lives
342
+ in the contract itself —
343
+ [Lead Discovery and Recovery](src/room/prompts/contract/supervisor/lead-discovery-and-recovery.md)
344
+ for Supervisor and
345
+ [Peer Seat Lifecycle](src/room/prompts/contract/lead/peer-seat-lifecycle.md) for Lead — rather
346
+ than being restated here. In outline: the seat's evidence is the current live configuration.
347
+ Supervisor reads the exact current `room-<agent>-lead` profile from `list_profiles` and
348
+ materializes every field it defines (agent creation takes no profile id), uses `list_agents(cwd)`
349
+ only to find candidates, then inspects each one's full status for the profile's provider, the
350
+ intended workspace and its mode. For `room-<agent>-peer`, Lead copies provider, mode and
351
+ features exactly, treats model and thinking as protocol-governed defaults, and additionally
352
+ requires the live seat's daemon-added `paseo.parent-agent-id` to name itself. Ownership must be
353
+ corroborated by parentage or known Human-opened history; an ambiguous candidate goes to
354
+ duplicate recovery and Human escalation instead of being adopted.
285
355
 
286
356
  Current Paseo agent sessions do not retain `profileId`. A direct launch with the exact
287
357
  profile provider, mode and workspace is therefore **profile-equivalent**, but literal picker
@@ -291,11 +361,51 @@ provider ids or claim that the daemon enforces this procedural eligibility check
291
361
  ## Keeping the room current
292
362
 
293
363
  Role homes are generated once, at `setup` time. After you edit `~/.codex/config.toml`,
294
- `~/.claude/settings.json`, or Pi's `settings.json` / `APPEND_SYSTEM.md`, run `setup --apply`
295
- again to fold the change into every seat.
296
- The same update regenerates `AUTHENTICATION.md` from the newly resolved binaries. `verify`
297
- reports drift in the meantime, and re-running `setup` is safe: it rewrites only
298
- managed configuration that differs and never replaces role credential paths.
364
+ `~/.claude/settings.json`, or Pi's `settings.json` / `APPEND_SYSTEM.md`, run setup again to
365
+ fold the change into every seat. The same applies after upgrading `paseo-room`; a release
366
+ that changes generated headings or prompt assets produces expected one-time managed-file
367
+ drift.
368
+
369
+ Use the upgraded version with the same repeated `--agent` selection as the installed room:
370
+
371
+ ```bash
372
+ npx paseo-room@<new-version> setup --agent codex --agent claude --agent pi
373
+ npx paseo-room@<new-version> setup --agent codex --agent claude --agent pi --apply
374
+ npx paseo-room@<new-version> verify
375
+ ```
376
+
377
+ First inspect the dry run, then apply it. The apply regenerates managed prompt carriers,
378
+ the Codex model catalogs and `AUTHENTICATION.md` from the newly resolved binaries, but
379
+ preserves role credential paths and the operator agent homes. Stop and restart every affected
380
+ seat after the apply; sending another turn to an already-running seat is not a restart.
381
+ `setup` and `verify` prove the files and live Paseo configuration, not that an existing model
382
+ context reloaded them. Only a newly launched seat context is expected to ingest the
383
+ regenerated instructions.
384
+
385
+ `room.json` records a short `contract` digest of the role documents and workspace protocol
386
+ this room was installed from. When it differs from what the installed package renders — or is
387
+ absent, because the room predates the field — setup and verify warn that the seats are holding
388
+ older text and ask for `setup --apply` plus a restart. It is provenance you compare by eye, not
389
+ a security claim. Rooms written before the field still parse.
390
+
391
+ One migration happens on the first upgraded apply: an existing Peer `skills` symlink becomes
392
+ the room-owned projection described above. Only the alias is unlinked, never your skills, and
393
+ setup stops with an actionable message rather than guessing if that path has become something
394
+ it does not recognize.
395
+
396
+ To roll back, run the prior package version with the same agent selection and `setup --apply`,
397
+ then restart the affected seats again:
398
+
399
+ ```bash
400
+ npx paseo-room@<prior-version> setup --agent codex --agent claude --agent pi --apply
401
+ npx paseo-room@<prior-version> verify
402
+ ```
403
+
404
+ No reverse data migration is needed; a prior package regenerates its own marker, including
405
+ dropping or restoring the contract digest as its own schema requires. Do not use `remove` for a
406
+ version rollback: it deletes the room home, including role-owned credential files. Re-running
407
+ setup is safe because it rewrites only managed configuration that differs and never replaces
408
+ role credential paths.
299
409
 
300
410
  There are three separate evidence boundaries:
301
411
 
@@ -325,17 +435,22 @@ command again.
325
435
 
326
436
  ## The role contract
327
437
 
328
- The exact wording every seat reads lives in [`src/room/clauses.ts`](src/room/clauses.ts).
329
- In short:
438
+ The exact model-facing wording every seat reads lives in the canonical Markdown under
439
+ [`src/room/prompts/`](src/room/prompts/). TypeScript selects those semantic sections with
440
+ `instructionKeys()` and `protocolKeys()`; it does not duplicate their prose. In short:
330
441
 
331
442
  - **Supervisor** routes Human directives to Lead and observes. Before opening a seat it checks
332
- for and reuses the project's existing Lead, including an idle or resumable Lead. It does
333
- not edit project work, run validation, direct Peer, or decide technical acceptance. Room
334
- tools: on.
443
+ for and reuses the project's existing Lead, including an idle or resumable Lead. It observes
444
+ the Lead–Peer process for named failures and advises with evidence, but advice carries no
445
+ technical authority: it does not edit project work, run validation, direct Peer, or decide
446
+ technical acceptance. Room tools: on.
335
447
  - **Lead** is the durable owner of one project across turns. It owns framing, decomposition,
336
- routing, integration and technical acceptance. One moving write scope has exactly one
337
- owner, and at most one Peer is writable at a time. Room tools: on.
338
- - **Peer** owns one bounded outcome, may challenge a failed premise with
448
+ routing, integration and technical acceptance. A brief states the outcome and the evidence
449
+ that settles it rather than pre-solving the work; any plan or file list in it is provisional.
450
+ One moving write scope has exactly one owner, and at most one Peer is writable at a time.
451
+ Room tools: on.
452
+ - **Peer** owns one bounded outcome, forms its own technical position from the code and its own
453
+ verification, may challenge a failed premise with
339
454
  `REOPEN_REQUEST` / `DEPENDENCY_REQUEST` / `BLOCKED`, hands back a reproducible candidate,
340
455
  and never accepts its own difficult change. Room tools: off.
341
456
 
@@ -343,8 +458,9 @@ Human keeps product goals, priority, material cost, external effects and irrever
343
458
 
344
459
  One rule has no runtime enforcement behind it and so is procedural and regression-tested in
345
460
  the contract instead: **one Lead owns one project; Supervisor discovers, verifies and reuses
346
- it, while Lead alone opens verified Peer seats.** The exact eligibility procedure is described
347
- above. A completed turn, idle state, pending permission, or resumable closed session is not an
461
+ it, while Lead alone opens verified Peer seats.** The eligibility evidence is summarized
462
+ above and stated exactly in the contract sections linked there. A completed turn, idle state,
463
+ pending permission, or resumable closed session is not an
348
464
  absent Lead. Fresh independent review means that existing Lead opens a fresh read-only Peer;
349
465
  it never means Supervisor opens another Lead.
350
466
 
@@ -353,6 +469,15 @@ Supervisor stops parallel routing, preserves both histories, keeps the previousl
353
469
  healthy owner, and closes the duplicate only after a stable handoff. Ambiguous ownership,
354
470
  health, or concurrent writes go back to Human rather than being guessed or merged.
355
471
 
472
+ Two further limits are deliberately conservative. **One writable Peer per project**, not one
473
+ per moving scope: the room gives you no writer isolation, so separate scopes are not evidence
474
+ of separate working trees, and no workspace protocol relaxes the limit. Concurrent writable
475
+ Peers in isolated worktrees are a deferred decision, not an oversight. And a seat's **model and
476
+ reasoning effort are defaults**: Lead varies them for a brief only where the repository's
477
+ workspace protocol supplies an explicit task-risk policy, and never up to a tier advertising
478
+ automatic delegation. Provider, mode, workspace, parent and feature values are eligibility
479
+ evidence and copied exactly.
480
+
356
481
  Every seat also carries a **default workspace protocol** — topology by difficulty,
357
482
  verification, review, repository conventions — so a project has that layer without doing
358
483
  anything. Each seat gets the sections that bear on its own work; topology goes to Lead and
@@ -410,7 +535,7 @@ that review; Supervisor must route the request to Lead rather than opening a fre
410
535
  ## Development
411
536
 
412
537
  ```bash
413
- npm run verify # typecheck, lint, test, build — the gate order
538
+ npm run verify # typecheck, lint, test, build, packed-package test — the gate order
414
539
  ```
415
540
 
416
541
  Releases are published to npm from a GitHub Release; see