Phase 4: Local Daemon and Bubble Tea TUI
Objective and prerequisites
Expose the deterministic engine through authenticated user-local IPC and a separate generated terminal application. This phase starts only after snapshots, interaction lifecycles, replay cursors, and provider/tool vertical behavior are stable enough to encode in a versioned protocol.
Engine protocol contracts
common/v1 and engine/v1 are Protobuf APIs governed by Buf lint and breaking
checks. They provide initialization and version/capability negotiation,
server-owned definitions, stable-owner reconnect CAS, health, run creation,
atomic paged event replay/tailing, complete pending-interaction snapshots with
revisioned deltas, cancellation, interaction responses, suspend/resume, safe
snapshot import, and bounded replay diagnostics. Authentication is transport
metadata, never an application payload.
Protocol minor 1 makes snapshot transfer authenticated and atomic with the
snapshot-authority-v1 capability. Signed construction and keyed import
verification are mandatory. Minor-0 connections receive neither snapshot
capability; unkeyed SHA-256 validation is payload integrity, not authority.
Every request has count, byte, and deadline limits. Unknown fields follow the documented additive-compatibility rule. Protocol errors distinguish invalid argument, unauthenticated, incompatible version, out-of-range cursor, resource exhaustion, unavailable, cancellation, and uncertain operation state.
Local transport and managed startup
- Linux/macOS use a current-user Unix socket; Windows uses a current-user named pipe. Remote TCP listening is absent, not merely disabled by default.
- Endpoint metadata and random authentication tokens use user-only permissions and are validated against the current user before connection.
spice-agentattaches to a compatible user daemon or starts one, with a bounded startup lock and health handshake.spice-agentd serveexplicitly hosts the daemon.spice-agent attachconnects to an explicitly selected local endpoint.- An incompatible daemon is rejected with its observed/required versions and a safe remediation command. It is never silently killed or reused.
- Last acknowledged event sequence drives reconnect. Cursor gaps require an explicit snapshot recovery path; no event is silently omitted.
TUI contracts
The spice-agent-tui repository owns only Bubble Tea presentation, UI-neutral
render values, editor/input translation, commands, key bindings, accessibility,
status, and theme. It consumes a high-level client/session port and may not
import kernel internals, generated gRPC packages, daemon hosting, or OS IPC.
Shell, renderers, command set, prompt editor, key bindings, workspace view, status bar, and theme are generated Spice beans. Runtime plugins may emit portable semantic views and namespaced data; they never load executable UI code.
Implementation slices
- Freeze common/engine schemas and generate deterministic Go code.
- Implement the transport-independent host primitives, then authenticated local listeners, client/session translation, negotiation, replay, cancellation, interaction, snapshot, and health.
- Add user-scoped endpoint discovery and managed start coordination.
- Implement the Bubble Tea shell with injected presentation components and terminal-size-independent semantic models.
- Generate separate daemon and terminal
@Applicationtargets in the distribution; preserve args, environment, working directory, and cleanup. - Add reconnect, resize, interruption, and clean-shutdown acceptance on Windows and Linux.
Exclusions
Remote access, TLS, multi-user hosting, browser UI, persistence policy, plugin executable views, and automatic daemon upgrades are excluded. macOS receives compile/protocol coverage until a stable terminal-interaction runner is available.
Verification
- Buf lint/breaking checks and deterministic generation run offline.
- Protocol tests cover old/new peers, unknown fields, authentication, overload, cursor replay/gap, stale clients, half-close, cancellation, and malformed data.
- OS tests prove socket/pipe ownership, token permissions, stale endpoint cleanup, concurrent managed startup, version rejection, and process cleanup.
- TUI golden tests cover multiple dimensions, wrapping, Unicode width, light/dark themes, accessibility text, resize, reconnect, and bounded history.
- Real terminal tests exercise one-command start, explicit serve/attach, interactions, cancellation, reconnect, and Ctrl-C shutdown.
Performance and completion evidence
Daemon startup targets 250 ms, warm connection 75 ms, and local event delivery p95 10 ms. Evidence records OS/build, endpoint type, handshake timing, replay cursor, terminal transcript, and generated target source map.
Status is in progress. Slice 1 is implemented: provisional schemas,
generated Go, handwritten boundary validation, compatibility/freshness gate,
protocol tests, and fuzz smoke are green. This is intentionally not a daemon.
The transport-independent foundation of slice 2 is also implemented: immutable
server definitions, root-owned reconnect CAS sessions, bounded per-client
idempotency, and a stable-client-partitioned pending-interaction hub with
explicit run-binding leases, independent complete-first revisions, reconnect
fencing, global/per-client retention budgets, and joined observer shutdown. It
adds no listener or RPC adapter. Session ownership now has a bounded commit and
stream gate: reconnect takes priority over queued old-epoch mutations, drains
the active commit, cancels and joins every old stream, then alone advances the
epoch. Mutation, reconnect, and stream-acquisition queues are bounded and
participate in shutdown drain accounting. The OS-backed run authority now
persists a distinct current-user scope and HMAC key, holds a stable per-run OS
lock, and
drives signed ACTIVE, SUSPENDED, IMPORTING, and terminal records through
an explicit prepare/consume/activate transaction. Authority-key generation and
local run-transition generation are deliberately separate. A consumed import
cannot be retried after an uncertain failure. Its retained OS directory
identity makes lock and state operations immune to pathname substitution, and
full-ancestry trust validation prevents cross-lifetime rollback by another
unprivileged principal. Suspended export retains ownership; authority resume
durably invalidates the old snapshot before kernel execution resumes. Its
explicit close/drain lifecycle is ready for generated singleton cleanup.
The kernel now also exposes
transactional prepared start/resume handles: preparation yields a stable run ID
and exact leased plan without registration or execution, then commit accepts
the separately owned run root. This is the authority-acquisition seam, not an
authority implementation.
Locally suspended runs additionally expose an inert prepared-resume boundary.
The host can reserve the exact next event sequence, durably invalidate the old
snapshot through RunAuthority, and only then release kernel execution.
Cancellation and shutdown latch behind that decision; abort restores the exact
suspended snapshot.
The TUI composition half of slice 4 is implemented independently at
spice-agent-tui commit 82adb45: public APIs contain no Bubble Tea or daemon
types, Spice generates the renderer/theme/binding/I/O/shell graph, cancellation
has an independent control lane, and external acceptance executes the actual
injected terminal shell through explicit application start and stop. Its full
gate passed in 158.4 seconds at 90.1% product coverage. The high-level daemon
client adapter and real terminal process workflow remain pending.
The remainder of slices 2 through 6 stays pending,
including OS transport, authentication, run hosting/translation, managed
startup, the daemon-to-TUI bridge, and real Windows/Linux reconnect acceptance. See
evidence/phase4-protocol.md.
Foundation-specific evidence is in
evidence/phase4-host-foundation.md.
Run-authority evidence is in
evidence/phase4-run-authority.md.
Kernel preparation evidence is in
evidence/phase4-kernel-preparation.md.
Local-resume evidence is in
evidence/phase4-kernel-local-resume.md.
The standard-library-only public client contract is recorded in
evidence/phase4-client-contract.md.
Session gate evidence is in
evidence/phase4-session-gates.md.
The baseline remains intentionally provisional. The pre-host repair closes the schema and kernel seams for interaction discovery/run identity, reconnect CAS, suspend/resume/import identity, authenticated snapshot envelopes, and atomic replay bounds. Before the final Phase 4 freeze, the daemon host must prove them over real RPCs, enforce run tombstones and OS-backed authority-key lifecycle, and separate RPC contexts from run lifetime. Buf protects changes against the committed baseline; it does not imply those host semantics are already implemented.