feat(coding-agent): direct session transport between TUI and worker (ENG-5817) - #1926
Merged
Merged
Conversation
xeophon
force-pushed
the
fix/daemon-client-reconnect-recoverable
branch
from
September 1, 2026 07:18
15c5075 to
aa2a4bf
Compare
snimu
force-pushed
the
fix/daemon-client-reconnect-recoverable
branch
from
September 1, 2026 08:34
aa2a4bf to
7c1c6d8
Compare
snimu
force-pushed
the
feat/direct-session-transport
branch
from
September 1, 2026 08:34
a586234 to
6cea3e9
Compare
snimu
force-pushed
the
fix/daemon-client-reconnect-recoverable
branch
from
September 1, 2026 08:48
7c1c6d8 to
ae22984
Compare
snimu
force-pushed
the
feat/direct-session-transport
branch
from
September 1, 2026 08:53
83358a5 to
959331e
Compare
Base automatically changed from
fix/daemon-client-reconnect-recoverable
to
main
September 1, 2026 09:59
Schema revision 25 adds the capability-gated get_direct_worker_transport command, the single-use DaemonPeerTransportTicket shape, and the peer grant, peer_auth, and worker_register_peer_transport wire types. DAEMON_COMMAND_PLANE classifies every daemon command as session- or control-plane at compile time so unclassified commands can never route to a direct transport, and the per-command hello compatibility predicate moves to daemon-protocol.ts so the routed client and DaemonClient share one check. Worker descriptors gain the per-incarnation workerInstanceId that peer grants bind to.
Workers accept supervisor-registered single-use peer grants (worker_register_peer_transport; bounded, TTL-capped, burned before their token is compared with sha256 + timingSafeEqual) and authenticate direct session clients via peer_auth on their own socket. A pre-auth socket may only authenticate; a failed peer_auth or any other command ends it. Authenticated peers are pinned to the session plane of their granted session, so worker control commands, other sessions, and unknown command types are rejected. Grants and live peers are fenced during update preparation, archive shutdown, and worker shutdown; compact assistant deltas stay a supervisor-only encoding. Session summaries report directAttachedClients so the supervisor roster, attachment counts, and idle eviction can stay honest.
get_direct_worker_transport asks the supervisor for a single-use ticket to a resident worker's own socket. The supervisor pre-registers a 10s grant in the worker over its authenticated channel, binds it to the fresh per-incarnation workerInstanceId (launched via env, echoed in worker_auth, persisted on the descriptor), verifies the worker process identity is current, and stamps the socket's dev/ino into the ticket so clients can detect a swapped socket. Workers advertise peer-transport support in their worker_auth capabilities; older workers never get grants and client-owned workers are refused at issue time. Public summaries and idle-eviction snapshots add worker-reported direct attachments to the supervisor-side count so eviction and the roster stay honest.
…port DaemonAgentConnection.attach upgrades its supervisor connection with a direct link to the session's worker when the supervisor advertises direct_peer_transport: it redeems a single-use ticket, verifies the socket's dev/ino, and wraps both sockets in a DaemonRoutedClient. Session-plane commands the worker's own hello serves go direct; control-plane commands, an old worker, or any direct-path failure fall back silently to supervisor routing, and a malformed direct frame closes the link instead of throwing into the client. An established direct link outlives supervisor-socket loss: the session keeps streaming while the control plane reconnects in the background. Watchers and owned sessions stay on the shared supervisor socket, and a successful reattach drops the now-stale direct link.
… not the live claim The fence check revokes a stale supervisor claim before ending its socket, so the disconnect cleanup can no longer consult supervisorClaims to decide whether to probe supervisor availability; the authentication role survives revocation and excludes direct session peers. Also drop the redundant shuttingDown clause from peer_auth (shutdown already fences admissions and clears grants) and teach the affected daemon fakes the fields the transport now touches.
…ransport Review fixes for the direct session transport: - Peer fencing now writes daemon_closing with the real reason before ending direct sockets, and the archive shutdown closes sessions first so direct peers read session_closed "killed" instead of a fake daemon shutdown; a clean daemon stop therefore stays terminal and never respawns the daemon. - The connection checks the authoritative shutdown/update close reason before the surviving-direct-link reroute, so reasoned closes stay terminal (stop) or take the update restoration path (restart) even while the direct link is healthy. - worker_auth enforces the instance binding only when the authenticating supervisor presents one, so a downgraded supervisor still adopts live workers; the peer-transport fencing between current builds is unchanged. - One helper owns the direct-plus-supervisor attachment sum; peer_auth drops the same-process re-check of the worker's own instance id (registration is the single enforcement point; the client-presented field stays checked) and the peer command gate drops the updateRestart clause that fencing makes unreachable.
Drop comments that narrate the adjacent code and squeeze multi-line docs to one line, keeping the load-bearing notes: grant burn-before-compare, the archive close-before-fence ordering, the reason-before-FIN contract, the fail-fast rule on dropped request options, the shutdown-window fence reachability, and the command-plane classification rule.
…n state Control-plane recovery with a healthy direct link completed a reconnect cycle per supervisor-socket flap (attach rides the direct link, so every cycle succeeded instantly) and each cycle emitted session_resynced, re-rendering an unchanged transcript up to 15 times during one supervisor replacement. The reconnect loop now emits session_resynced only when the session transport itself was re-established through a supervisor attach; a held direct link streamed state throughout, so recovery emits just the connected status.
…back A direct-transport loss is never itself a session loss: the connection now reconnects through a supervisor re-attach even without a recoverDaemon hook (the supervisor socket is still healthy; a worker that actually died keeps signalling through the authoritative session_closed path). The transport close handler is extracted into one method and the control-plane close saved during an initial direct attach replays through it, so a daemon shutdown during initial attach stays terminal instead of respawning the daemon.
A direct peer joining or leaving an idle session changes directAttachedClients without any session event to carry it, so the supervisor's roster (and roster-based idle eviction) held a stale count until unrelated activity. The attach handler and the shared detach path now schedule a roster flush for session_client sockets; supervisor-relayed viewers keep their existing event-driven cadence.
…irect link holds The resident-worker restart test predates the direct transport: its client now rides the worker's own socket through the supervisor swap, so the recovery emits connected without a session_resynced. The end-to-end pin now asserts the new semantics (no resync, no close, state queryable), matching the unit pins from the resync-emission fix.
…tial direct attach Replaying a saved supervisor-shutdown close through the close handler inside the static attach emitted the terminal event before any listener could subscribe, and terminalCloseEmitted then swallowed every later signal: a daemon stop during first attach produced a zombie connected TUI. No listener can exist during construction, so a terminal saved close now rejects the attach with the socket-close error — the pre-transport semantics every call site already handles; non-terminal saved closes keep replaying through the single close handler.
…ck; re-acquire direct after reattach A direct-socket drop while a session input pause was held hit the fail-closed pause branch before the recoverable-direct-loss ordering, terminalizing a session the supervisor could still serve and skipping update restoration. The fence stays fail-closed only for control-plane losses; a lost direct link clears it (holders still learn through the invalidation generation) and falls through to the normal close ordering. A successful in-window reattach dropped the stale direct link but never acquired one for the target, leaving the session supervisor-routed for good. The routed client can now upgrade itself with the same silent ticket dance as the initial attach (one shared acquisition helper), and reattachSession invokes it on success only — a rejected reattach still keeps the old link.
…the ticket request The post-reattach upgradeDirectTransport was half a mechanism: its own pin showed no attach ever crosses the new link, so events stayed on the supervisor relay while requests silently switched sockets, and supervisor attachment bookkeeping leaked. Post-reattach supervisor routing is the honest state until a designed-as-one-piece re-upgrade exists. With its only other caller gone, the ticket acquisition folds back into createDaemonSessionTransport, and the ticket request now opts out of reconnect parking (recoverable:false) so a supervisor drop mid-acquire fails into supervisor routing instead of pending the attach forever.
…ounded While the direct link is held, the reconnect loop's success is connect plus hello: no re-attach and no snapshot cross a socket that never stopped serving the session, which deletes the snapshot-restream-over-live-socket failure class and makes the resync skip structural. The bounded reconnect deadline arms only once the direct link is gone (re-armed at the transition), so a supervisor staying down never terminally closes a healthy direct stream; a mid-recovery direct death reruns the loop as a normal bounded session-plane reconnect.
…its type The session pin is scoped to the active-session slot and guards against routing accidents, not privilege escalation: ticket holders already hold supervisor access.
…recovery Control-plane-only recovery skips attach(), which was the roster store's only rebind seam, so a supervisor blip under a healthy direct link left the agents view subscribed to the dead hello. The subscription is a control-plane accessory: held-direct recovery now re-attaches the store non-fatally after connect + hello, and the session-plane path keeps its single rebind inside attach().
…sert Drop docs that restate their declarations (transport interface, role union), the close-handler narration the predicate name now carries, and squeeze three multi-line whys to one line each. The half-open handshake test loses its zero-resync assert: the deadline-policy pin and the supervisor-swap E2E both pin held-mode zero-resync across the whole recovery.
Contributor
|
Macroscope has since reviewed this pull request. An earlier review was skipped by a cost limit; a review has now completed, so that notice no longer applies. |
snimu
force-pushed
the
feat/direct-session-transport
branch
from
September 1, 2026 10:01
2360981 to
11c5f74
Compare
…er the held-recovery awaits The supervisor-side retry of a failed initial direct attach owns its bounded outcome, so it now opts out of reconnect parking and, on failure, rejects with the control-plane close saved during the window — a daemon stop racing the retry reaches the caller as the authoritative reason instead of a pend or a generic socket error. Held-direct recovery revalidates once after its last await (the roster re-attach): a terminal close inside the window stops the loop without emitting connected, and a direct loss inside it falls through to the bounded session-plane rerun instead of joining the finished recovery.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit bb47b4a. Configure here.
…restoration The post-await validation only re-derived two of the close handler's three outcomes, so an update close landing inside the held roster re-attach fell into the bounded session-plane rerun, whose deadline could close the client under the running restoration. The check now consults the handler's own dispatch outputs — terminalCloseEmitted, updateRestartPending, or the recoverable close that joined this loop — so a window close lands in exactly the branch the handler chose.
xeophon
approved these changes
Sep 1, 2026
This was referenced Sep 1, 2026
ketema
added a commit
to ketema/prime-agent
that referenced
this pull request
Sep 1, 2026
- Direct session transport between TUI and worker (ENG-5817, PrimeIntellect-ai#1926) - Event-driven supervisor agent roster with push subscriptions (PrimeIntellect-ai#1897, PrimeIntellect-ai#1900, PrimeIntellect-ai#1895) - Hardened daemon startup, recovery ownership, and worker launch diagnostics (PrimeIntellect-ai#1929, PrimeIntellect-ai#1918) - Python REPL runtime single-dump snapshots and bash preview tool (PrimeIntellect-ai#1945, PrimeIntellect-ai#1911) - Non-blocking RLM subagent deletion and snapshot update suppression (PrimeIntellect-ai#1954, PrimeIntellect-ai#1944) - Saved catalog loading on Agents View open (PrimeIntellect-ai#1960) - Advanced Anthropic prompt caching marker across tool results (PrimeIntellect-ai#1927) - TUI process replacement on update and empty draft eviction (PrimeIntellect-ai#1631, PrimeIntellect-ai#1946, PrimeIntellect-ai#1920)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Routes session-plane traffic (prompt/steer/attach/streaming deltas) directly between the TUI and the worker process over a ticketed unix-socket transport, so streaming volume no longer transits the supervisor event loop. The supervisor stays the authority: it issues single-use grants and keeps the whole control plane.
Linear: ENG-5817
Prior art: tkellogg's fork branch
feat/direct-worker-transport(discussion #1805) — the grant/ticket security design is ported largely as-is; the routing and integration layers are rebuilt for the agent-roster stack.Stacked on #1909 (→ #1900 → #1897 → #1895). Will be rebased onto main and retargeted once the stack merges; review the top 7 commits.
Design
get_direct_worker_transport); supervisor issues a single-use grant (32-byte token, TTL 10s, bound to a per-incarnationworkerInstanceId, checked with sha256 +timingSafeEqual, burned before compare) and pre-registers it in the worker; the TUI connects to the worker's own socket and authenticates viapeer_auth. Session-scoped: a direct peer can only issue commands for its granted session; pre-auth sockets accept nothing but auth and are ended on any violation.DAEMON_COMMAND_PLANE(as const satisfies Record<DaemonCommand["type"], "session" | "control">) colocated with the command union — adding a command without classifying it fails tsc. 33 control-plane commands stay on the supervisor; unknown types never route direct. One predicate shared by client routing and worker enforcement.direct_peer_transport; workers advertisepeer_transportinworker_auth; the routed client re-checks every command against the worker's owndaemon_hello. Downgraded (schema-24) supervisors still adopt live workers (instance match enforced only when presented). Both directions pinned.directAttachedClientsthrough the one summary builder into roster pushes, public list, and eviction snapshots — idle eviction stays honest with zero new bookkeeping.Invariant worth knowing (for future edits)
The archive-shutdown path closes sessions before fencing peer transports, so direct peers receive
session_closed "killed"through normal vocabulary rather than a reasonless FIN. The correctness of close-reason delivery on the archive leg lives in that ordering (pinned), not in types — an archive path that skipscloseSessionwould regress it.Review status
Implemented and reviewed by two independent agent passes (design-note veto round, fresh-eyes security review with a fix round, verification round → APPROVE): grant races, scope enforcement, double-execution, eviction honesty, and all 106 plane classifications audited. Benchmark of the supervisor choke point (motivation): at 20 concurrent streamers the supervisor burns ~2.5 cores forwarding deltas on all current builds.
Testing
test/daemon-peer-transport.test.ts(12): grant lifecycle matrix, pre-auth lockdown, scope enforcement, fencing, dev/ino ticket, eviction counting.recoverDaemonset), update restoration, reattach semantics.Note
Medium Risk
Large changes to daemon wire protocol, authentication, and reconnection semantics on the critical TUI↔session path; mitigated by capability gating, compile-time command plane classification, and broad tests, but regressions could affect session stability or routing during supervisor/worker failures.
Overview
Adds direct peer transport so interactive clients can run session-plane daemon traffic (prompt, attach, streaming) over a dedicated worker socket instead of relaying through the supervisor. The supervisor still owns control-plane work and mints single-use, short-lived tickets (
get_direct_worker_transport→ worker grant registration →peer_authon the worker socket), bound to worker instance id and socket dev/ino identity.Introduces
DaemonRoutedClientandDaemonTransportClient: session commands route to the worker when a direct link exists; failures degrade to supervisor routing without double-executing in-flight direct requests.DaemonAgentConnectionattach/reconnect behavior changes so a lost supervisor socket can recover in the background while a healthy direct link keeps the session live; shutdown/update closes stay authoritative. Workers gainsession_clientauth role, grant fencing on update/shutdown, andDAEMON_COMMAND_PLANE(schema 25,direct_peer_transport) so every command is explicitly control vs session plane.Roster/list summaries expose
directAttachedClientsso attachment counts and idle eviction stay accurate when viewers attach directly.Reviewed by Cursor Bugbot for commit 60efcec. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add direct session transport between TUI and worker in coding-agent daemon
worker_register_peer_transportand clients authenticate withpeer_authDaemonRoutedClientmultiplexes a supervisor control-plane socket with an optional direct worker socket, routing session-plane commands directly to the worker and falling back to the supervisor on direct-link lossDaemonAgentConnectionreconnect logic distinguishes control-plane vs session-plane recovery: a surviving direct link avoidssession_resynced, and direct-link loss triggers a bounded reattach instead of a terminal closeworkerInstanceId(randomUUID) passed viaDAEMON_WORKER_INSTANCE_ID_ENV; grants and auth bind to this id plus process and socket identitydirect_peer_transportcapability andget_direct_worker_transportcommand gated by schema 25 and protocol 7passivatedWorkerRosterEntrynow omitsdirectAttachedClientsfrom passivated summaries; direct session peers receive plain JSONL payloads instead of compact assistant deltas;watchSessionwatchers stay on the shared control-plane socket and never use direct transport;worker_archive_and_shutdownfences peers and emitssession_closedbefore socket end. Risk: fencing revokes outstanding grants and terminates live direct peers — any out-of-tree consumer expecting compact deltas on a direct peer socket or relying onsession_resyncedduring supervisor-only reconnect will see changed behaviorMacroscope summarized 60efcec.
Benchmark (same harness/workload as the roster-stack bench; 24 live sessions, 60s windows; sandbox 8c/16GB)
listRTT p50/p90/maxAt 20–24 streamers: delta p50 13→1 ms, supervisor RSS 1694→745 MiB (residual supervisor CPU is roster/state upkeep, not delta forwarding). Direct engagement verified per-connection (
hasDirectTransport30/30 across windows, zero silent fallbacks). Fallback probes: supervisor SIGKILL mid-stream → the stream never paused (~210 deltas/s through the outage), control plane recovered on its own; worker SIGKILL mid-stream → terminal close in 29 ms, no reconnect spin. Idle latency and hung-worker isolation identical to the stack baseline.