Skip to content

feat(server): support recoverable Codex and Claude session handoff - #25476

Closed
mulyoved wants to merge 2 commits into
pingdotgg:mainfrom
mulyoved:feat/codex-shared-daemon-handoff
Closed

mulyoved wants to merge 2 commits into
pingdotgg:mainfrom
mulyoved:feat/codex-shared-daemon-handoff

Conversation

@mulyoved

Copy link
Copy Markdown

Problem

Moving one native conversation between a terminal controller and full T3 chat currently lacks an explicit ownership-transfer contract. Importing history alone does not coordinate writers, enforce the destination permission ceiling, or distinguish a queued launch from a confirmed release.

Change

Add API-driven native session handoff for Codex and manual handoff for already-stopped Claude sessions. Both variants expose adopt, refresh, status and release through typed RPC and MCP service methods; the environment descriptor advertises supported contracts.

Codex uses a shared native daemon and reconciles native history. Claude binds an exact saved UUID to explicit destination settings, resumes that UUID on the first T3 turn, and tracks managed writes and the exact owned child separately from SDK finalization. Controller epochs and transactional admission/release checks prevent stale controllers and independently scheduled work from crossing ownership changes. History reconciliation updates connected and reconnecting clients, including native removals.

These are two provider implementations of the same terminal-to-T3 conversation handoff. Migrations 070/071 retain ownership and recovery evidence. Other providers do not advertise these contracts. Claude v1 is Linux-local and manual-first; it does not stop an arbitrary running Claude source or infer its effective permissions.

Companion consumer: https://github.com/mulyoved/skills/pull/996.

Scope and approval

Maintainer direction/scope approval has not been obtained. This is a draft submitted at the developer's explicit request. It is a new workflow, and no small-fix or configuration exemption is claimed. Draft status does not satisfy CONTRIBUTING.md's prior-approval requirement. Review or merge should wait for agreement on the direction and scope.

No installation, deployment or live user-session stop/restart was performed. The tested head is a50f12d8ff4c7bfc593be4ef74d7985187aa5bc5, containing Codex commit e3259976c69ea460959b7ecea5c3896a6052d795 and the Claude increment. Tests were run on that committed source, not on a merge with the latest main.

Verification

On Linux, using private HOME/config/runtime/SQL stores and synthetic protocol peers:

vp run check:changed
  902 tests passed in 44 files
  31 affected/dependent package typechecks passed
  format, lint, both Knip checks and GraphQL checks passed
  exit 0; source drift []

# From apps/server, with a fresh private output directory:
vp pack --out-dir <private-output>/server-dist --no-clean
  exit 0; source drift []

Behavior checks include rejected/stale controller admission, exact UUID first-turn resume, existing binding protection, target settings and project races, native history removals, re-adoption identity mismatch, and a schedule arriving during final release. Counterexamples were reproduced before correction. Fresh final independent reviews found no remaining findings in their scopes.

A cross-repository synthetic round trip exercised the exact compiled CLI through the actual selected RPC definitions, authorization middleware, facade/domain services, history readers and SQLite, with private Unix socket/PTY/native peers: 66 assertions passed, zero source/binary drift and zero model queries. A separate actual Claude SDK 0.3.276/default managed-spawn proof passed 22 assertions, showing that close, EOF and SIGTERM are insufficient to prove child exit, followed by an observed exact-child exit.

An earlier private environment run failed because a 118-byte Unix socket path exceeded the platform limit. It remains recorded as failed. Shortening only the private environment paths produced the passing unchanged-source run above.

Not verified: real Claude callback delivery, persistence, ordinary prompt-complete-release, returned loaded-history identity, a live Herdr/browser round trip, complete production WebSocket composition or real credential issuance. The 22-assertion SDK proof uses a synthetic ELF peer with tools disabled and persistence disabled. Installed native source supports the expected Stop roster shape, but source inspection is not delivery evidence. Missing roster fields, unknown writes and unacknowledged elicitation block release.

Written with GPT-6.1 Sol and GPT-6 Astra through the Codex harness in T3 Code. Final backend review used independent Astra/medium and Sol/high seats.

Adopt an exact stopped Claude conversation with explicit destination settings, native history authority and controller epochs. Expose adoption, refresh, status and release through scoped RPC and MCP methods.

Fence managed writes, retain exact child-exit evidence and reserve one return launch. Reconcile native history and reject conflicting bindings, changed re-adoption requests and work admitted during release.

Verify 902 tests across 44 files, 31 package typechecks, required scoped checks, server bundle and the 66-check compiled CLI/RPC/SQL synthetic round trip. Real native persistence and normal-turn release remain unverified.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant