paseo-room 0.4.1 → 0.6.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 (87) hide show
  1. package/README.md +178 -73
  2. package/dist/index.js +2069 -400
  3. package/dist/index.js.map +1 -1
  4. package/dist/plugin-assets/paseo-plugin.json +1 -1
  5. package/dist/prompts/contract/lead.md +152 -0
  6. package/dist/prompts/contract/peer.md +74 -0
  7. package/dist/prompts/contract/shared-authority.md +33 -0
  8. package/dist/prompts/contract/shared-seat-identity.md +18 -0
  9. package/dist/prompts/contract/supervisor.md +89 -0
  10. package/dist/runtime-plugin/client/data.ts +67 -0
  11. package/dist/runtime-plugin/client/views.tsx +176 -0
  12. package/dist/runtime-plugin/index.client.tsx +21 -0
  13. package/dist/runtime-plugin/index.server.ts +53 -0
  14. package/dist/runtime-plugin/package.json +5 -0
  15. package/dist/runtime-plugin/paseo-plugin.json +4 -0
  16. package/dist/runtime-plugin/server/bridge/bridge.mjs +146 -0
  17. package/dist/runtime-plugin/server/brief.ts +39 -0
  18. package/dist/runtime-plugin/server/capabilities.ts +45 -0
  19. package/dist/runtime-plugin/server/context.ts +80 -0
  20. package/dist/runtime-plugin/server/contracts/actions.ts +39 -0
  21. package/dist/runtime-plugin/server/contracts/assignment.ts +51 -0
  22. package/dist/runtime-plugin/server/contracts/envelope.ts +26 -0
  23. package/dist/runtime-plugin/server/contracts/peer.ts +112 -0
  24. package/dist/runtime-plugin/server/controller.ts +558 -0
  25. package/dist/runtime-plugin/server/correlations.ts +157 -0
  26. package/dist/runtime-plugin/server/domain/acceptance.ts +69 -0
  27. package/dist/runtime-plugin/server/domain/authorize.ts +37 -0
  28. package/dist/runtime-plugin/server/domain/receipts.ts +73 -0
  29. package/dist/runtime-plugin/server/domain/state.ts +413 -0
  30. package/dist/runtime-plugin/server/domain/validate.ts +69 -0
  31. package/dist/runtime-plugin/server/domain/views.ts +233 -0
  32. package/dist/runtime-plugin/server/events/schema.ts +214 -0
  33. package/dist/runtime-plugin/server/gate.ts +233 -0
  34. package/dist/runtime-plugin/server/generated/location.ts +11 -0
  35. package/dist/runtime-plugin/server/git.ts +158 -0
  36. package/dist/runtime-plugin/server/handlers/actions.ts +130 -0
  37. package/dist/runtime-plugin/server/handlers/peer.ts +183 -0
  38. package/dist/runtime-plugin/server/handlers/turns.ts +113 -0
  39. package/dist/runtime-plugin/server/hooks.ts +73 -0
  40. package/dist/runtime-plugin/server/lifecycle.ts +60 -0
  41. package/dist/runtime-plugin/server/notices.ts +103 -0
  42. package/dist/runtime-plugin/server/ownership.ts +63 -0
  43. package/dist/runtime-plugin/server/paseo-port.ts +194 -0
  44. package/dist/runtime-plugin/server/recognition.ts +80 -0
  45. package/dist/runtime-plugin/server/recovery.ts +166 -0
  46. package/dist/runtime-plugin/server/rpc.ts +169 -0
  47. package/dist/runtime-plugin/server/spool.ts +143 -0
  48. package/dist/runtime-plugin/server/store/project.ts +228 -0
  49. package/dist/runtime-plugin/server/store/publish.ts +142 -0
  50. package/dist/runtime-plugin/server/tools.ts +91 -0
  51. package/dist/runtime-plugin/shared/identity.ts +16 -0
  52. package/dist/runtime-plugin/shared/limits.ts +40 -0
  53. package/dist/runtime-plugin/shared/manifest.ts +51 -0
  54. package/dist/runtime-plugin/shared/policy.ts +61 -0
  55. package/dist/runtime-plugin/shared/rpc-contracts.ts +66 -0
  56. package/dist/runtime-plugin/shared/rpc.ts +34 -0
  57. package/dist/runtime-plugin/tsconfig.json +22 -0
  58. package/dist/skills/paseo-project-onboarding/SKILL.md +122 -0
  59. package/dist/skills/paseo-project-onboarding/references/workspace-protocol-template.md +56 -0
  60. package/package.json +9 -4
  61. package/dist/prompts/contract/lead/complete-peer-brief.md +0 -32
  62. package/dist/prompts/contract/lead/independent-review.md +0 -9
  63. package/dist/prompts/contract/lead/moving-write-ownership.md +0 -13
  64. package/dist/prompts/contract/lead/peer-seat-lifecycle.md +0 -39
  65. package/dist/prompts/contract/lead/project-technical-ownership.md +0 -12
  66. package/dist/prompts/contract/lead/technical-acceptance.md +0 -6
  67. package/dist/prompts/contract/peer/assignment-scope.md +0 -10
  68. package/dist/prompts/contract/peer/bounded-outcome.md +0 -13
  69. package/dist/prompts/contract/peer/independent-judgment.md +0 -11
  70. package/dist/prompts/contract/peer/no-orchestration.md +0 -5
  71. package/dist/prompts/contract/peer/no-self-acceptance.md +0 -5
  72. package/dist/prompts/contract/peer/reproducible-handoff.md +0 -17
  73. package/dist/prompts/contract/shared/evidence-and-event-waiting.md +0 -7
  74. package/dist/prompts/contract/shared/human-authority.md +0 -8
  75. package/dist/prompts/contract/shared/scope-and-unrelated-work.md +0 -4
  76. package/dist/prompts/contract/shared-supervisor-lead/workspace-protocol-precedence.md +0 -18
  77. package/dist/prompts/contract/supervisor/directive-integrity.md +0 -5
  78. package/dist/prompts/contract/supervisor/escalation-boundaries.md +0 -5
  79. package/dist/prompts/contract/supervisor/lead-discovery-and-recovery.md +0 -52
  80. package/dist/prompts/contract/supervisor/observation-and-advice.md +0 -13
  81. package/dist/prompts/contract/supervisor/technical-non-interference.md +0 -8
  82. package/dist/prompts/documents/workspace.md +0 -6
  83. package/dist/prompts/workspace/repository-conventions.md +0 -7
  84. package/dist/prompts/workspace/review.md +0 -4
  85. package/dist/prompts/workspace/topology.md +0 -13
  86. package/dist/prompts/workspace/verification.md +0 -10
  87. /package/dist/prompts/contract/{shared-lead-peer/challenge-signals.md → challenge-signals.md} +0 -0
package/README.md CHANGED
@@ -30,9 +30,11 @@ npx paseo-room auth login codex lead # interactive login for exact
30
30
  npx paseo-room auth login claude peer
31
31
  npx paseo-room auth login pi supervisor # minimal Pi login session; run /login, then exit
32
32
  npx paseo-room remove --apply # delete ~/.paseo-room (including role credentials) and providers
33
+ npx paseo-room setup --runtime --apply # opt in to runtime coordination (preview)
34
+ npx paseo-room export --apply # copy runtime state out for review; no daemon needed
33
35
  ```
34
36
 
35
- `setup` and `remove` are dry runs unless you pass `--apply`. Running with no arguments in a
37
+ `setup`, `remove` and `export` are dry runs unless you pass `--apply`. Running with no arguments in a
36
38
  terminal starts a short wizard: pick an action, pick the agents, review the plan, confirm.
37
39
  Setup and the wizard never start login. `auth login` is a separate explicit action, requires
38
40
  interactive stdin/stdout/stderr, and targets exactly one selected agent and role; it has no
@@ -46,6 +48,9 @@ interactive stdin/stdout/stderr, and targets exactly one selected agent and role
46
48
  | `--apply` | off | Actually write setup/remove changes; `auth login` does not use it. |
47
49
  | `--json` | off | One machine-readable document instead of text. |
48
50
  | `--no-claude-memory-contract` | off | Omit the role contract from Claude role `CLAUDE.md` files, leaving the room plugin as the only Claude carrier. Your global memory is still carried. `setup` only. |
51
+ | `--runtime` | off | Opt in to [runtime coordination](#runtime-coordination-preview) (preview). A per-run `setup` choice recorded in the room marker; running setup without it deselects runtime. |
52
+ | `--out <dir>` | a new directory under `~/.paseo-room/runtime/v1/exports` | `export` only: where to write the export. Must be new or empty. |
53
+ | `--include-gate-output` | off | `export` only: also copy the bounded, best-effort-masked gate output tails. |
49
54
  | `--room-home <path>` | `~/.paseo-room` | Where role homes are written. |
50
55
  | `--codex-home <path>` | `~/.codex` | Source Codex configuration. |
51
56
  | `--claude-home <path>` | `~/.claude` | Source Claude Code configuration. |
@@ -69,7 +74,7 @@ starts, its exit code is preserved; a signal is returned using the conventional
69
74
  **0.8.0-beta.1 or newer**; any selection containing Claude or Pi requires **0.8.0 or newer**.
70
75
  Claude also requires Paseo plugins to be enabled explicitly: the generated trusted server plugin
71
76
  is the strong contract carrier, and `paseo-room` never enables plugins for you. The plugin is
72
- version-bounded to `>=0.8.0 <0.9.0`. `paseo-room` checks compatibility before touching anything,
77
+ version-bounded to `>=0.8.0 <0.10.0`. `paseo-room` checks compatibility before touching anything,
73
78
  and never installs or upgrades Paseo.
74
79
  - An initialised Codex home (`~/.codex/config.toml`) and/or Claude Code home (`~/.claude`).
75
80
  Codex must be new enough for `codex debug models` to print its JSON model catalog: the room
@@ -89,29 +94,31 @@ starts, its exit code is preserved; a signal is returned using the conventional
89
94
  ~/.paseo-room/
90
95
  room.json # what this CLI created; verify and remove read it
91
96
  AUTHENTICATION.md # exact per-role login commands; contains no secrets
92
- room/WORKSPACE_PROTOCOL.md # the default protocol Lead and Supervisor carry, as one readable file
97
+ room/skills/paseo-project-onboarding/ # Lead-only Agent Skill: draft a repository protocol
98
+ SKILL.md, references/ # procedure plus a scaffold loaded only when the skill runs
99
+ room/skill-projections/<agent>/lead/ # exact Lead skill aggregate for each seated agent
93
100
  plugin/ # Claude only: trusted creation-time system-prompt append carrier
94
- paseo-plugin.json # accepts Paseo >=0.8.0 <0.9.0
101
+ paseo-plugin.json # accepts Paseo >=0.8.0 <0.10.0
95
102
  index.server.ts, server/ # exact provider map + generated role contracts
96
103
  roles/codex/<role>/
97
104
  config.toml # your config.toml + the room's overrides
98
105
  role-instructions.md # readable copy of what this seat was told
99
106
  model-catalog.json # generated copy of your catalog, native multi-agent metadata removed
100
107
  auth.json # created and owned by Codex after role login, if file-backed
101
- AGENTS.md, skills, plugins, hooks.json → symlinks into ~/.codex when present (Peer: see below)
108
+ AGENTS.md, skills, plugins, hooks.json → shared resources (Lead/Peer: see below)
102
109
  roles/claude/<role>/
103
110
  CLAUDE.md # your global memory + role instructions (contract omitted with --no-claude-memory-contract)
104
- settings.json # your settings.json + PASEO_ROOM_ROLE
111
+ settings.json # minimal room-owned env, deny and control-plane policy
105
112
  .claude.json # seeded once from yours, then owned by Claude
106
113
  .credentials.json # created and owned by Claude after role login, if file-backed
107
114
  skills, plugins, commands, hooks, rules, output-styles,
108
- keybindings.json, themes → symlinks into ~/.claude when present (Peer: see below)
115
+ keybindings.json, themes → shared resources (Lead/Peer: see below)
109
116
  roles/pi/<role>/
110
117
  settings.json # your settings minus package/extension declarations
111
118
  APPEND_SYSTEM.md # your append + style/runtime capsules + role instructions
112
119
  auth.json # created and owned by Pi after role login, if used
113
120
  models.json, AGENTS.md, skills, prompts, themes,
114
- keybindings.json, mcp.json → symlinks into ~/.pi/agent when present (Peer: see below)
121
+ keybindings.json, mcp.json → shared resources (Lead/Peer: see below)
115
122
  ```
116
123
 
117
124
  Each seat gets its own file-backed credential path, sessions, history and projects inside its
@@ -125,7 +132,14 @@ file. Anything else at a managed path — a directory where a file belongs, an u
125
132
  symlink — makes setup stop and name the path for you to move aside. Nothing is deleted
126
133
  recursively on your behalf.
127
134
 
128
- ### What Peer does not receive
135
+ ### How Lead and Peer receive skills
136
+
137
+ Lead's `skills` remains a symlink, but now points to a room-owned managed aggregate containing
138
+ links to every noncolliding operator skill plus the room-owned `paseo-project-onboarding` skill.
139
+ This adds the room skill without writing into your agent home, while keeping the role path
140
+ replaceable by an older package during rollback. An operator skill whose name collides
141
+ case-insensitively remains untouched but is shadowed in the aggregate by the room-owned copy,
142
+ avoiding duplicate names on case-insensitive filesystems.
129
143
 
130
144
  Peer has no room tools, so the room also stops handing it orchestration surfaces:
131
145
 
@@ -138,9 +152,9 @@ Peer has no room tools, so the room also stops handing it orchestration surfaces
138
152
  removing one of your skills is drift `verify` reports and `setup --apply` reconciles.
139
153
 
140
154
  Your own skills directory is never modified: `paseo*` skills stay exactly where they are.
141
- An existing room upgrades its one legacy Peer `skills` symlink to that projection on the next
142
- `setup --apply`; setup only unlinks the alias, never your skills, and stops with an actionable
143
- message if that path has become something it does not recognize.
155
+ On the next `setup --apply`, an existing Lead `skills` symlink is retargeted to its room aggregate,
156
+ while a legacy Peer symlink becomes its managed directory. Setup only replaces or unlinks those
157
+ aliases, never your skills, and stops with an actionable message for an unrecognized Peer shape.
144
158
 
145
159
  This is capability hygiene, not a sandbox. Peer still has shell access.
146
160
 
@@ -170,8 +184,8 @@ and environment-variable names. They never read credential contents, query a key
170
184
  a token over the network, or claim OAuth freshness. Authentication findings are warnings and
171
185
  do not turn an otherwise valid setup or verify into a failure:
172
186
 
173
- - **configured structurally** — a regular role credential file or supported auth configuration
174
- name exists; validity and freshness were not checked;
187
+ - **configured structurally** — a regular role credential file exists; validity and freshness
188
+ were not checked;
175
189
  - **login-required** — no role credential artifact or safely recognizable alternative exists;
176
190
  - **legacy-shared-risk** — an older room has a credential symlink, including one whose target
177
191
  may now be missing; only its stored link text is read, it is preserved, and the output gives
@@ -206,12 +220,12 @@ argv. No login path reads, copies, links, replaces, validates, or deletes a cred
206
220
 
207
221
  Codex diagnostics recognize an explicit `cli_auth_credentials_store` of `file`, `ephemeral`,
208
222
  `auto`, or `keyring`. An `OPENAI_API_KEY` name in the setup shell does not count as stored role
209
- auth; Codex's API-key login must create that role's native store. Claude recognizes the
210
- documented cloud selectors, `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_API_KEY`,
211
- `CLAUDE_CODE_OAUTH_TOKEN`, and `apiKeyHelper` by name. Pi recognizes a bounded list of built-in
212
- provider API-key environment names. Names found only in the setup process are ambient and
213
- unverifiable because their values are not copied into Paseo providers; other ambient provider
214
- authentication may exist but is not validated.
223
+ auth; Codex's API-key login must create that role's native store. Claude role settings do not
224
+ import operator auth helpers; diagnostics recognize only ambient documented cloud selectors,
225
+ `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_API_KEY`, and `CLAUDE_CODE_OAUTH_TOKEN` by name. Pi recognizes a
226
+ bounded list of built-in provider API-key environment names. Names found only in the setup process
227
+ are ambient and unverifiable because their values are not copied into Paseo providers; other
228
+ ambient provider authentication may exist but is not validated.
215
229
 
216
230
  ## What the room changes
217
231
 
@@ -286,13 +300,13 @@ attribute `/mcp` to `source: "extension"` at that same canonical path. Missing,
286
300
  path-escaped or wrongly attributed adapters fail closed. The probe and setup do not write the
287
301
  operator or planned role homes.
288
302
 
289
- Each seat is also pinned at the Paseo provider level, because a provider entry outranks the
290
- agent's own configuration:
303
+ Each seat combines generated agent configuration with Paseo provider pins. Provider fields are
304
+ still required where Paseo launch state outranks the agent's own configuration:
291
305
 
292
306
  | Pin | Applies to | Why |
293
307
  |---|---|---|
294
308
  | `params: {sandbox_mode, approval_policy}` | Codex | Without it Paseo sends its own mode preset (default `auto-review`) to the Codex app-server, and that outranks the generated `config.toml`. |
295
- | `disallowedTools` for `Task`, `Agent`, `Workflow`, coordination, task-list, cron and team tools | Claude | Blocks legacy/current subagents, dynamic workflows, cross-session coordination and agent teams. |
309
+ | provider `disallowedTools` + role `permissions.deny` for `Task`, `Agent`, `Workflow`, coordination, task-list, cron and team tools | Claude | Blocks legacy/current subagents, dynamic workflows, cross-session coordination and agent teams at both Paseo and Claude's role settings. |
296
310
  | `disableAgentView: true` + `CLAUDE_CODE_DISABLE_AGENT_VIEW=1` | Claude | Disables Claude's separate background-agent control plane across settings scopes and at launch. |
297
311
  | `disableWorkflows: true` + `CLAUDE_CODE_DISABLE_WORKFLOWS=1` | Claude | Disables dynamic workflows through every entry point, beyond denying the `Workflow` tool. |
298
312
  | `crossSessionInbound: "refuse"` | Claude | Prevents another Claude session from injecting a turn into a room seat. |
@@ -302,7 +316,8 @@ agent's own configuration:
302
316
  `verify` compares each provider's `command`, `env`, `paseoTools` and pins against what the
303
317
  room would write, and fails if one has been dropped — a pin that can be silently removed is
304
318
  not a guarantee. The `env` map is compared whole rather than as a subset, because an added key
305
- can re-enable exactly what a pin closes. Unrelated top-level provider fields stay yours.
319
+ can re-enable exactly what a pin closes. Unrelated top-level provider fields stay yours. Claude
320
+ role `settings.json` is compared separately as a managed file, including `permissions.deny`.
306
321
 
307
322
  It also saves one **agent profile** per seat, which is what the Paseo picker lists under
308
323
  Profiles. A profile is a preset, not a constraint: it decides where a seat *starts*.
@@ -332,10 +347,12 @@ stale room-owned value from an existing Pi profile. Pi has no sandbox or approva
332
347
  its permissive runtime is necessary for headless operation but grants no additional authority.
333
348
 
334
349
  Claude starts in Paseo's `bypassPermissions` mode, while Codex starts in its equivalent
335
- `full-access` mode. Claude deny rules still apply in bypass mode, so native orchestration
336
- stays unavailable. The room does not write `permissions.defaultMode` to `settings.json`:
337
- Paseo passes the profile's mode as a command-line session setting, which outranks that file.
338
- The two Claude disable environment keys are pinned in both the provider and generated
350
+ `full-access` mode. Claude deny rules still apply in bypass mode, so the canonical native-tool
351
+ list is written to both provider `disallowedTools` and every role's `settings.json` under
352
+ `permissions.deny`. The role file is minimal, deterministic room policy: it does not copy operator
353
+ env, hooks, permissions, or auth helpers. The room does not write `permissions.defaultMode`:
354
+ Paseo passes the profile's mode as a command-line session setting, which outranks that file. The two
355
+ Claude disable environment keys are likewise pinned in both the provider and generated
339
356
  `settings.json`, because Claude applies settings-file environment values after launch values.
340
357
  The generated top-level `disableAgentView` and `disableWorkflows` settings are also forced to
341
358
  `true`; their restrictive value cannot be weakened by another ordinary settings scope.
@@ -349,18 +366,18 @@ the operator.
349
366
  Names are not identity. A matching cwd, title, or provider label does not make an existing
350
367
  agent a room Lead or Peer. The exact eligibility procedure is model-facing wording and lives
351
368
  in the contract itself —
352
- [Lead Discovery and Recovery](src/room/prompts/contract/supervisor/lead-discovery-and-recovery.md)
353
- for Supervisor and
354
- [Peer Seat Lifecycle](src/room/prompts/contract/lead/peer-seat-lifecycle.md) for Lead — rather
355
- than being restated here. In outline: the seat's evidence is the current live configuration.
356
- Supervisor reads the exact current `room-<agent>-lead` profile from `list_profiles` and
357
- materializes every field it defines (agent creation takes no profile id), uses `list_agents(cwd)`
358
- only to find candidates, then inspects each one's full status for the profile's provider, the
359
- intended workspace and its mode. For `room-<agent>-peer`, Lead copies provider, mode and
360
- features exactly, keeps the profile's model unless the root workspace protocol routes models,
361
- chooses the thinking effort for the brief, and additionally
362
- requires the live seat's daemon-added `paseo.parent-agent-id` to name itself. Ownership must be
363
- corroborated by parentage or known Human-opened history; an ambiguous candidate goes to
369
+ the shared [Room Seat Identity](src/room/prompts/contract/shared-seat-identity.md) evidence,
370
+ with the role-specific procedures in
371
+ [the Supervisor contract](src/room/prompts/contract/supervisor.md) and
372
+ [the Lead contract](src/room/prompts/contract/lead.md) — rather than being restated here. In
373
+ outline: the seat's evidence is the current live configuration. Both seats read the exact current
374
+ `room-<agent>-<role>` profile from `list_profiles`, materialize every field it defines (agent
375
+ creation takes no profile id), then inspect the live seat's provider, workspace and mode.
376
+ Supervisor additionally uses `list_agents(cwd)` for discovery and corroborates Lead ownership by
377
+ parentage or known Human-opened history. For `room-<agent>-peer`, Lead copies provider, mode and
378
+ features exactly, keeps the profile's model unless a repository protocol routes models,
379
+ chooses the thinking effort under that repository protocol's policy, and requires the live seat's
380
+ daemon-added `paseo.parent-agent-id` to name itself. An ambiguous Lead candidate goes to
364
381
  duplicate recovery and Human escalation instead of being adopted.
365
382
 
366
383
  Current Paseo agent sessions do not retain `profileId`. A direct launch with the exact
@@ -370,9 +387,10 @@ provider ids or claim that the daemon enforces this procedural eligibility check
370
387
 
371
388
  ## Keeping the room current
372
389
 
373
- Role homes are generated once, at `setup` time. After you edit `~/.codex/config.toml`,
374
- `~/.claude/settings.json`, or Pi's `settings.json` / `APPEND_SYSTEM.md`, run setup again to
375
- fold the change into every seat. The same applies after upgrading `paseo-room`; a release
390
+ Role homes are generated once, at `setup` time. After you edit `~/.codex/config.toml` or Pi's
391
+ `settings.json` / `APPEND_SYSTEM.md`, run setup again to fold the change into every seat. Claude's
392
+ operator `settings.json` is not an input to its minimal room settings. The same applies after
393
+ upgrading `paseo-room`; a release
376
394
  that changes generated headings or prompt assets produces expected one-time managed-file
377
395
  drift.
378
396
 
@@ -392,16 +410,20 @@ seat after the apply; sending another turn to an already-running seat is not a r
392
410
  context reloaded them. Only a newly launched seat context is expected to ingest the
393
411
  regenerated instructions.
394
412
 
395
- `room.json` records a short `contract` digest of the role documents and workspace protocol
396
- this room was installed from. When it differs from what the installed package renders — or is
397
- absent, because the room predates the field — setup and verify warn that the seats are holding
398
- older text and ask for `setup --apply` plus a restart. It is provenance you compare by eye, not
399
- a security claim. Rooms written before the field still parse.
413
+ `room.json` records a short `contract` digest of the three rendered role documents this room
414
+ was installed from. When it differs from what the installed package renders — or is absent,
415
+ because the room predates the field — setup and verify warn that the seats are holding older
416
+ text and ask for `setup --apply` plus a restart. It is provenance you compare by eye, not a
417
+ security claim. Rooms written before the field still parse.
418
+
419
+ The room-owned skill files are live managed entries instead: `verify` compares their exact bytes,
420
+ so a skill update is not reported as stale seat instructions.
400
421
 
401
- One migration happens on the first upgraded apply: an existing Peer `skills` symlink becomes
402
- the room-owned projection described above. Only the alias is unlinked, never your skills, and
403
- setup stops with an actionable message rather than guessing if that path has become something
404
- it does not recognize.
422
+ On the first upgraded apply, each Lead `skills` symlink is retargeted to its room-owned aggregate
423
+ and an existing Peer `skills` symlink becomes the room-owned projection described above. Only
424
+ aliases are replaced or unlinked, never your skills. Lead retains the symlink shape the prior
425
+ package expects, so package-level rollback can retarget it without a reverse migration; setup
426
+ still stops rather than guessing if the Peer path has become something it does not recognize.
405
427
 
406
428
  To roll back, run the prior package version with the same agent selection and `setup --apply`,
407
429
  then restart the affected seats again:
@@ -422,8 +444,7 @@ There are three separate evidence boundaries:
422
444
  - `setup --apply` and `verify`, backed by regression tests, prove the generated/live
423
445
  configuration chain: each room profile points to its exact role provider and owned mode,
424
446
  each provider points to the exact role home, and each provider-selected role home carries
425
- the exact prompt input with the applicable role contract and default workspace-protocol
426
- sections.
447
+ the exact prompt input with the applicable role contract.
427
448
  - Delivery of those files and arguments into a newly launched model context relies on the
428
449
  documented Codex, Claude Code and Pi configuration contracts for
429
450
  `developer_instructions`, `CLAUDE.md`, and `--append-system-prompt`.
@@ -446,8 +467,10 @@ command again.
446
467
  ## The role contract
447
468
 
448
469
  The exact model-facing wording every seat reads lives in the canonical Markdown under
449
- [`src/room/prompts/`](src/room/prompts/). TypeScript selects those semantic sections with
450
- `instructionKeys()` and `protocolKeys()`; it does not duplicate their prose. In short:
470
+ [`src/room/prompts/`](src/room/prompts/), organised by who reads it: one shared authority body
471
+ for every role, shared room-seat identity evidence for Supervisor and Lead, the shared challenge
472
+ vocabulary for Lead and Peer, and exactly one body per role. TypeScript selects those layers with
473
+ `instructionKeys()`; it does not duplicate their prose. In short:
451
474
 
452
475
  - **Supervisor** routes Human directives to Lead and observes. Before opening a seat it checks
453
476
  for and reuses the project's existing Lead, including an idle or resumable Lead. It observes
@@ -457,8 +480,9 @@ The exact model-facing wording every seat reads lives in the canonical Markdown
457
480
  - **Lead** is the durable owner of one project across turns. It owns framing, decomposition,
458
481
  routing, integration and technical acceptance. A brief states the outcome and the evidence
459
482
  that settles it rather than pre-solving the work; any plan or file list in it is provisional.
460
- One moving write scope has exactly one owner, and at most one Peer is writable at a time.
461
- Room tools: on.
483
+ One moving write scope has exactly one owner, and at most one Peer is writable at a time. It
484
+ explicitly requests native Paseo completion/error/permission notification for Peer creation and
485
+ every background follow-up, then waits for events rather than polling. Room tools: on.
462
486
  - **Peer** owns one bounded assignment — writable inside an assigned scope, or read-only
463
487
  against a named candidate, question or area — under exactly one disposition Lead names in the
464
488
  brief (Engineer, Architect, Reviewer or Scout), forms its own technical position from the code
@@ -485,24 +509,57 @@ Two further limits are deliberately conservative. **One writable Peer per projec
485
509
  per moving scope: the room gives you no writer isolation, so separate scopes are not evidence
486
510
  of separate working trees, and no workspace protocol relaxes the limit. Concurrent writable
487
511
  Peers in isolated worktrees are a deferred decision, not an oversight. And a seat's **model and
488
- reasoning effort are not one knob**: the model stays the profile's default unless the root
489
- `WORKSPACE_PROTOCOL.md` explicitly supplies model routing, while the thinking effort is Lead's
512
+ reasoning effort are not one knob**: the model stays the profile's default unless a repository
513
+ protocol explicitly supplies model routing, while the thinking effort is Lead's
490
514
  per-brief choice on task risk, uncertainty, context size and verification burden — lowest that
491
515
  reliably answers the task, higher for architecture-sensitive or weakly observable work, only an
492
516
  option the live Paseo and provider context establishes as supported, and never up to a tier
493
517
  advertising automatic delegation. Provider, mode, workspace, parent and feature values are
494
518
  eligibility evidence and copied exactly.
495
519
 
496
- Every seat that owns workflow also carries a **default workspace protocol** — topology by
497
- difficulty, verification, review, repository conventions — so a project has that layer without
498
- doing anything. It goes to Lead and Supervisor, not to Peer: Lead reads the protocol and quotes
499
- what bears on an assignment into the brief, including the exact verification command, so a Peer
500
- spends its attention on one brief rather than on deciding which repository rules apply. A
501
- repository that needs different rules writes `WORKSPACE_PROTOCOL.md` at its root, which wins
502
- wherever it speaks while the default holds wherever it is silent — the root, because it is
503
- agent guidance rather than project documentation. `~/.paseo-room/room/WORKSPACE_PROTOCOL.md` is
504
- the whole default as one file, so you can read what is in force and start from it. The CLI
505
- never writes into a repository.
520
+ The room ships **no default workspace protocol**. A repository's root `WORKSPACE_PROTOCOL.md`
521
+ is optional, and when it exists it is that repository's complete workflow policy — there is no
522
+ hidden room document behind it to reconcile point by point, and no unstated rule survives where
523
+ it is silent. It stays subordinate to the authority floor: repository workflow directs how work
524
+ is done and can never enlarge or weaken role authority. The file lives at the repository root
525
+ because it is agent guidance rather than project documentation. The CLI never writes into a
526
+ repository.
527
+
528
+ Reading it goes to **Lead alone**, the only standing reader of workflow policy: Lead resolves
529
+ the repository root, reads the file in full when the repository ships one, and quotes what bears
530
+ on an assignment into the brief, including the exact verification command. Supervisor reads a
531
+ repository's protocol only under an explicit Human audit, update or maintenance mandate;
532
+ ordinary routing and observation need none of it, and it may propose a change with causal
533
+ evidence but never impose one. Peer is never told the filename at all, so it spends its attention
534
+ on one brief rather than on deciding which repository rules apply — what it needs unconditionally
535
+ is in its own contract, including the floor that no repository or workspace instruction can
536
+ enlarge or weaken its authority, with conflicts routed to Lead.
537
+
538
+ Lead's own contract carries a short, visible **operating baseline**, not another workspace
539
+ policy: compact Engineer/Architect/Reviewer/Scout assignment vocabulary; exact profile model and
540
+ thinking defaults absent explicit repository routing; the obligation to name and run the
541
+ repository's own verification gate; and fresh read-only review when Human or a repository
542
+ protocol requires it, or when Lead sees material technical risk. These stated contract rules
543
+ remain visible when a repository protocol is silent; no generic topology matrix, anti-pattern
544
+ catalog, or protocol-evolution policy survives in any prompt.
545
+
546
+ To write a protocol, Lead has one room-owned **Agent Skill**, `paseo-project-onboarding`,
547
+ delivered to Lead's `skills` directory from `~/.paseo-room/room/skills/` and to no other seat.
548
+ It inspects what the repository actually contains — agent instructions, README/CONTRIBUTING,
549
+ build manifests and scripts, CI, test configuration, architecture and operations docs — and
550
+ returns an evidence map, one standalone complete draft, and the decisions Human still owns,
551
+ separating observed facts from proposals rather than guessing. It is proposal-first: it writes
552
+ nothing by default, and writes the repository's root `WORKSPACE_PROTOCOL.md` only under an
553
+ explicit Human instruction to apply the draft, refusing any non-regular shape at that path and
554
+ leaving unrelated work alone. It cannot change authority, tool policy, the writer limit,
555
+ provider identity or credentials, and cannot make Peer a protocol reader. Its bundled template
556
+ is a scaffold loaded while the skill runs, never appended to a session.
557
+
558
+ Lead's visible skill inventory is therefore an exact room-owned aggregate behind the role-home
559
+ symlink: one link per skill in your own agent home, plus a link to the room's skill. Your own home
560
+ is never modified, and an operator skill whose name matches `paseo-project-onboarding` under a
561
+ case-insensitive comparison is left exactly where it is — the room-owned copy owns that name
562
+ inside the aggregate only.
506
563
 
507
564
  ## Working the room
508
565
 
@@ -539,14 +596,62 @@ reading a candidate is more independent than a fresh session of the family that
539
596
  one project on one family and keep the other for the review seat. Ask the existing Lead for
540
597
  that review; Supervisor must route the request to Lead rather than opening a fresh Lead.
541
598
 
599
+ ## Runtime coordination (preview)
600
+
601
+ An opt-in second plugin, `paseo-room-runtime`, gives the room a durable record of delegated work:
602
+ typed assignments, one writer at a time, Peer questions and handoffs, commit-bound candidates, an
603
+ optional independent gate rerun and Lead's acceptance — kept across daemon and plugin restarts.
604
+ It is separate from the Claude contract carrier; a runtime fault never touches that plugin.
605
+
606
+ ```bash
607
+ npx paseo-room setup --agent codex --agent claude --runtime # dry run first
608
+ npx paseo-room setup --agent codex --agent claude --runtime --apply
609
+ npx paseo-room verify
610
+ ```
611
+
612
+ - **Trust.** Like the carrier, the runtime is trusted, unsandboxed code running in your daemon.
613
+ Enable Paseo plugins yourself; `paseo-room` never does. It is not an operating-system sandbox and
614
+ cannot stop a process running as your user.
615
+ - **Range.** Runtime requires Paseo `>=0.8.0 <0.10.0`. `0.8.0` and `0.9.1` are both live-qualified
616
+ points, so a daemon outside that range is refused for runtime while the baseline room keeps
617
+ working.
618
+ - **Lead** gains room tools such as `assignment_create`, `assignment_dispatch`, `assignment_answer`,
619
+ `assignment_accept` and `gate_run`. **Supervisor** gains `room_status`, `runtime_findings` and
620
+ `message_lead`, and cannot change an assignment.
621
+ - **A runtime-dispatched Peer** gets exactly two tools, `ask` and `handoff`, for its own assignment,
622
+ and still no Paseo room tools. A report exists only once one of those calls is accepted; its
623
+ final message is never read as a report. Claude asks for permission before a Peer's first call
624
+ to `mcp__paseo_room__ask` or `mcp__paseo_room__handoff`: approve it in Paseo, since the runtime
625
+ never answers a permission for a seat. Codex and Pi Peers do not ask.
626
+ - **A Peer that Lead opens directly** with Paseo's own tools is not runtime-managed: it gets no
627
+ reporting tools and appears in no assignment. That is allowed; it is simply outside the record.
628
+ - **Writable work** starts from a clean workspace at an exact base commit and is handed back as an
629
+ immutable commit. The runtime reads the commit and changed paths itself, never merges, resets,
630
+ cleans or stashes, and releases a writer only after Paseo proves the Peer archived.
631
+ - **State** lives under `~/.paseo-room/runtime/v1` as append-only event files. Setup never edits it.
632
+ The **Room runtime** sidebar item and workspace panel show projects, assignments, writer
633
+ ownership and findings, each labelled with how it is known (enforced, detected, procedural,
634
+ unverifiable).
635
+
636
+ To stop using it, finish, close or abandon the recorded work, then run setup **without**
637
+ `--runtime`. Setup refuses while anything is still active or uncertain, and keeps the recorded
638
+ state once it proceeds. `npx paseo-room export --apply` copies that state out; the export omits gate
639
+ output unless you add `--include-gate-output`, and briefs or commands written by a seat cannot be
640
+ proven secret-free. `remove --apply` warns about runtime history and then deletes it with the rest
641
+ of the room.
642
+
542
643
  ## Documentation
543
644
 
544
- - [docs/orchestration-model.md](docs/orchestration-model.md) — the reference model this
545
- tool implements: roles, authority, instruction layers, invariants, anti-patterns and
546
- operating checklists. Tool-agnostic; useful on its own.
645
+ - [docs/demonthorn-agent-orchestration-deep-dive.md](docs/demonthorn-agent-orchestration-deep-dive.md)
646
+ — the reference model this tool implements: roles, authority, instruction layers, invariants,
647
+ anti-patterns and operating checklists. Tool-agnostic; useful on its own.
547
648
  - [docs/design.md](docs/design.md) — how and why this tool implements that model, and what
548
649
  it deliberately does not do. Read this before changing an override.
549
650
  - [AGENTS.md](AGENTS.md) — working rules for contributors and coding agents.
651
+ - [docs/product/runtime-coordination-prd.md](docs/product/runtime-coordination-prd.md),
652
+ [docs/design/runtime-coordination.md](docs/design/runtime-coordination.md) and
653
+ [docs/plans/runtime-coordination-phase1-implementation-plan.md](docs/plans/runtime-coordination-phase1-implementation-plan.md)
654
+ — the runtime coordination preview: requirements, technical design and Phase 1 plan.
550
655
  - [docs/product/paseo-room-prd.md](docs/product/paseo-room-prd.md) — the original PRD, kept
551
656
  for history; the transactional-installer requirements in it were deliberately dropped.
552
657