Slice 1 S6. packages/harness runs a role session under the pi or claude
adapter behind a tool gate, and packages/seat holds the session and its
process. The bus host gains a launch socket: `mosaic bus start
<business> --pm <harness>:<model>` runs the PM without a window, the PM
launches role sessions through the broker within the business file's
`launch.max`, and every launch, refusal and end is a launch-log line and
a broker event. `mosaic talk`, `mosaic launches off|on|list` and
`mosaic stop <run>` are new CLI verbs. packages/bus gains the IPC ops
identity, authorize, refuse, endLaunch and credentialStatus, plus
Broker.endLaunch (decision 77); no socket verb, event kind or schema
changed. The session environment is an allowlist, and the runner exits
before claiming if a founder credential reaches it.
Filbert built it (agents/filbert/work/s6). Darkwing reviewed on #1523:
round 1 changes (26991/26995), round 2 changes (27004/27010), round 3
changes (27012/27032), round 4 approve (27033/27034) on manifest
08a78972, 42 paths.
Sage's gate on 64b0f9f1 (12:32Z), sequential and teed: node suites
business 60, bus 74, cli 83, control-board 124, conversation 182,
discord 178, harness 56, ledger 78, mosaic 69, queue 149, runs 41,
seat 27, tasks 51, webui 39, every one 0 failed; test-auth 15,
test-conductor 17, test-config 24, test-discord 66,
test-extension-package 18, test-foundation 44, test-queue 27,
test-release 14, test-task 98 and 26 without Docker, all 0 failed.
64b0f9f1..ee7f909b touches none of the 42 paths. It landed after the
Q14 hold ended at 2026-10-11T17:19:23.857Z. The recorded PM-to-coder
run on a scratch data root is still owed before row 41 moves to done.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
82 lines
3.5 KiB
Markdown
82 lines
3.5 KiB
Markdown
# Mosaic runtime adapters
|
|
|
|
An adapter is the entire harness-specific surface of the system. Everything
|
|
upstream of an adapter — configuration, contracts, missions, tasks, run
|
|
records — is harness-agnostic; everything inside an adapter may assume one
|
|
specific agent runtime.
|
|
|
|
## Contract
|
|
|
|
An adapter lives at:
|
|
|
|
```text
|
|
/opt/mosaic/adapters/<name>/adapter.sh
|
|
```
|
|
|
|
and must be executable. The dispatcher (`/opt/mosaic/src/run-agent.sh`)
|
|
selects it via `MOSAIC_ADAPTER` (default: `pi`) and execs it after the
|
|
system prompt has been generated.
|
|
|
|
**Inputs (environment):**
|
|
|
|
| Variable | Meaning |
|
|
|---|---|
|
|
| `MOSAIC_SYSTEM_PROMPT_FILE` | Absolute path to the generated system prompt (contracts + optional mission section). Read it; do not modify it. |
|
|
| `MOSAIC_REQUEST` | The exact user request text (may contain newlines). |
|
|
| `MOSAIC_PROVIDER` | Configured provider name. |
|
|
| `MOSAIC_MODEL` | Configured model id. |
|
|
|
|
Optional, adapter-specific (documented per adapter):
|
|
|
|
| Variable | Meaning |
|
|
|---|---|
|
|
| `MOSAIC_MOCK_RESPONSE` | mock only: the verbatim response to emit |
|
|
|
|
**Outputs:**
|
|
|
|
- `stdout`: the model response text — the only channel the orchestrator captures
|
|
- `stderr`: diagnostics (never credentials)
|
|
- exit `0`: success; nonzero: failure
|
|
|
|
## Rules
|
|
|
|
1. Adapters print ONLY the response on stdout. Status lines go to stderr.
|
|
2. Adapters never read configuration files; the resolved settings arrive via environment.
|
|
3. Adapters never write outside `/var/lib/mosaic`.
|
|
4. Adding a worker adapter requires: a new directory, the contract
|
|
implementation, and adding the name to the allowlist in
|
|
`scripts/mosaic-config.mjs`. A managed-session adapter (below) is selected
|
|
by the launch bundle, not by `execution.adapter`, and is not on that
|
|
allowlist unless it also works as a worker adapter.
|
|
|
|
## Included adapters
|
|
|
|
- `pi` — the pinned `@earendil-works/pi-coding-agent` CLI in noninteractive
|
|
print mode (`-p`), ambient discovery disabled, stdin detached.
|
|
- `mock` — deterministic echo of `MOSAIC_MOCK_RESPONSE`. Test-only: never use
|
|
it where a real model response is required.
|
|
- `claude` — the host's `claude` CLI, for managed sessions only (below).
|
|
Not a worker adapter: the image has no `claude`, and the adapter refuses
|
|
without the bundle's hook and MCP files.
|
|
|
|
## Managed sessions (slice 1 S6)
|
|
|
|
The session runner (`packages/harness/src/runner.mjs`) runs one adapter
|
|
call per turn on the host, as `/bin/sh <adapters/<name>/adapter.sh>` (the
|
|
repository keeps adapters 0644; only the image sets the mode), in the
|
|
session's workspace and its own process group. Same contract, plus:
|
|
|
|
| Variable | Meaning |
|
|
|---|---|
|
|
| `MOSAIC_WORKSPACE` | The session's workspace; the adapter runs there. |
|
|
| `MOSAIC_SESSION_DIR` | The session's persistent directory; later turns resume the session kept there. |
|
|
| `MOSAIC_TOOLS` | The built-in tool limit (pi names for `pi`, Claude Code names for `claude`), comma-separated. |
|
|
| `MOSAIC_POLICY_FILE`, `MOSAIC_TOOLS_FILE` | The bundle's gate policy and typed tools. |
|
|
| `MOSAIC_TOOL_SOCKET` | The runner's tool socket, which the typed tools call. |
|
|
| `MOSAIC_TURN_MARKER` | `pi`: the extension writes it at `agent_end`; a pi turn that exits 0 without it failed. |
|
|
| `MOSAIC_EXTENSIONS` | `pi` only: extension files loaded with `-e`; a missing one exits 2. |
|
|
| `MOSAIC_CLAUDE_SETTINGS`, `MOSAIC_CLAUDE_MCP_CONFIG` | `claude` only: the bundle's gate hook and MCP server; required. |
|
|
|
|
The layers each adapter relies on, and what they don't cover, are in
|
|
`packages/harness/README.md`.
|