feat(host-service): host sessions sync v1 — canonical sessions over tRPC snapshots + /sessions/sync
What
The simplified v1 of the host sessions surface — the agent-agnostic session/thread/event model that mobile and web sync against. One squashed commit, rebased on main.
Read this first: plans/host-sessions-sync.md — the single design doc, structured as three review layers (1: principles + budgets, 2: state ownership + surface + recovery, 3: one realistic scenario with exact payloads), plus rollout and the E2E gym story.
Shape
- Budgets (hard): 9 tRPC procedures · 12 socket packet types · 2 opaque incarnation-tagged cursor kinds · 1 automatic recovery path + the existing "restart host" hammer.
- Snapshots ride tRPC (
sessions.list/getcarry theheadcursor); the/sessions/syncsocket carries only small frames;subscribe.afteris required. - Claimless client tool calls: cards render on every device, first resolve wins.
- Recovery = the cold path re-run per stream, guarded by a client circuit breaker (3 resets / 30 s →
error). - camelCase everywhere on the wire; inputs AND outputs schema-validated at the router.
Evidence
- 602 host-service src tests, 46 protocol/client tests, 11-test realistic-scenario suite (mid-stream disconnect, scrollback parity vs the full journal, session switching under load, host reboot with exactly one reset).
- Gym user story 10/10 with a real Opus instance on this exact surface (
ACP_E2E=1 bun test test/integration/sessions-user-story.integration.test.ts). - Known gap (pinned by a test, fixed by the durable store next): a host-reboot journal rebuild loses
causationIdattribution.
Also in here
Doc consolidation: the old protocol/rollout pair and the stale Mastra/ACP-era chat docs are deleted (−5.7k lines); direction recorded — ACP gets replaced by a direct SDK adapter behind this unchanged surface (deferred, prototype in claude-sdk-session-harness), Mastra chat stays frozen for existing desktop users and is never used by mobile.
Out of scope (deferred)
Direct SDK adapter / ACP removal, host control-plane extension (workspace lifecycle etc. — see the "Trajectory" section in the doc). Next up after this: durable history store, React bindings + mobile rewire, Maestro phone replay.
https://claude.ai/code/session_01N98A6Rs53rLfRb8Qf5pM3Y
Summary by cubic
Ships v1 of Host Sessions sync: a canonical session/thread/event model with tRPC snapshots and a lightweight WebSocket for live updates. Adds sessions.*, /sessions/sync, a shared protocol package, and a small client store; cleans up old Mastra/ACP docs.
-
New Features
- New
@superset/host-service-syncpackage with zod-validated protocol, a shared projection reducer, and a framework-freezustandclient (createSessionsSyncClient). - Host
sessions.*tRPC (snapshots vialist/get, idempotent receipts, camelCase wire) and/sessions/synchub (hello/ack,subscribe.afterfromhead, replay/reset with invalid/expired cursor handling). - Canonical runtime that translates ACP into canonical events and serves both tRPC and the hub; claimless client tool-call resolves; host and client fold the same reducer.
- Documentation consolidated into
plans/host-sessions-sync.md; removed stale Mastra/ACP-era docs.
- New
-
Migration
- No breaking changes; legacy Mastra chat remains for existing users. This surface is gated.
- To adopt: fetch
sessions.list/sessions.getto seed, then open/sessions/syncand sendsubscribe.afterusing the returnedheadcursor; onreset, refetch the snapshot and resubscribe. - The reference client lives in
@superset/host-service-sync(createSessionsSyncClient).