magi-code 0.77.1

Repository-aware CLI coding agent for terminal work
Documentation
# Persistent service core

The library exports `PersistentService`, an in-process adapter boundary for [RFC-0002](../rfc/0002-persistent-service-protocol.md). It loads the normal runtime and runs one coordinator thread. Turns use the existing service turn manager and agent runner—not another execution loop.

`PersistentService::start()` is transport-independent and reports no available transports. The separate [Unix daemon adapter](unix-daemon.md) provides socket framing, authenticated endpoints, lifetime locking, launch commands, and write deadlines. `magi-code --app service` still uses version 1 and cancels/drains on EOF.

## Adapter lifecycle

1. `PersistentService::start()` loads startup resources.
2. `connect()` allocates a bounded pending connection; initialize within five seconds.
3. `submit(connection, record)` submits one complete JSON record. Read replies/events with `next_record(connection)`.
4. Call `response_written(connection, request_id)` after a successful response write. On write failure, call `disconnect(connection)` instead. Dequeue alone does not release request correlation.
5. Disconnect revokes that connection's grants and requests cancellation of only its login. Accepted turns, logout, settings writes, and catalog refreshes continue.
6. Dropping the service owner cancels and drains workers before returning. Ordinary zero-client operation does not drop the owner. Idle shutdown requires no connections, admitted work, or lease-held sessions.

A submission timeout is uncertain, not permission to resend. Use `operation.lookup` with the original instance and operation ID, then reconcile snapshots, durable replay, settings, or auth status. Never automatically replay a prompt or callback.

## Ownership and bounds

The coordinator serializes admission, claim, disconnect, cancellation, and snapshot attachment. Each connection has its own request reservations. Each lease-held session has at most one controller and one active turn. Claim responses precede subsequent live events.

Worker output is consumed even with no clients. A full client queue drops only activity; reliable-output overflow disconnects that client without stopping its turn. Queues are bounded to 64 records and 262144 encoded bytes per connection. There are at most 16 connections, 16 lease-held sessions, and 16 turns including cleanup.

Terminal publication follows persistence and worker cleanup, including title-writing workers on cancellation. Unowned cleaned-up sessions release their writer leases automatically; controlled idle sessions retain them. Failed persistence retains accepted text with `persistence: failed`, a matching lookup error, and `replay_required: true`. It never claims saved success.

Mutation evidence is limited to 256 entries. Intent comparison uses a daemon-local keyed digest, not retained prompt or callback text. Settled outcomes and terminal snapshots expire after 600 seconds; identity-only tombstones remain another 600 seconds. Unsettled work never expires. Unknown/expired evidence never starts work.

Per-turn settings are captured under the existing global/project settings locks by one preparation worker, not the command loop. While preparation is pending, further turn preparations and settings writes return `configuration_busy`; a running configuration operation likewise prevents preparation. Before starting a prepared turn, the coordinator rechecks the submission deadline, connection, grant, session, and operation. Disconnect before acceptance prevents execution. Running turns retain their snapshot. Provider definitions, instructions, skills, and other startup resources stay fixed.

Credential status, readiness checks, and logout share one bounded worker slot; overlapping requests return `auth_busy`. Login generation reads run on the login worker. Each login has one cancellation worker that waits for the protected credential commit lock, so disconnect and cancellation requests never wait for that lock on the coordinator. Cancellation requested before generation capture prevents the login exchange; a protected commit already in progress may win. Logout waits for login cancellation before removing Codex credentials. Login terminal events follow cancellation-worker cleanup. Initialize does not read credentials.

## Verification and remaining integration

`cargo test --quiet --lib service::` exercises synthetic tool execution across disconnect, zero-client cleanup, late claim, explicit Stop after reclaim, independent sessions, lost acceptance, outcome retention/capacity, queue overflow, persistence failure, scoped login cancellation, settings completion, and unchanged stdio behavior. Tests use temporary stores and synthetic workers/providers.

Core tests alone do not establish socket permissions, singleton launch races, physical-terminal behavior, OS survival, signed-helper packaging, or consumer preflight compatibility. See the [Unix adapter verification limits](unix-daemon.md#verification-limits) for process tests and remaining platform gates.

The [backend release evidence matrix](persistent-backend-readiness.md) maps CI
partitions to lifecycle races and records the remaining platform/consumer gates.