refactor(native-chat): stop threading the owner kind through a reservation

A reservation only ever names a native owner now, so the request no longer
carries a kind and the reserved lease records `native` directly. The attach
params keep `runtimeKind`: agentSession.ensure and create accept it, and the
operation fingerprint stored in the ledger covers it.
This commit is contained in:
Brennan Benson
2026-09-25 01:58:00 -07:00
parent 35742fd3c0
commit 54ce5fca0d
20 changed files with 2 additions and 25 deletions
@@ -324,7 +324,6 @@ export function reserveRequestFor(input: {
: {}),
...(authority.launchArgs ? { launchArgs: authority.launchArgs } : {}),
...(authority.launchEnv ? { launchEnv: authority.launchEnv } : {}),
runtimeKind: params.runtimeKind,
...(params.adopt
? {
// Fence 1 is a new record's first, and the owner probe requires the head link to carry
@@ -43,7 +43,6 @@ describe('Claude root-exit eviction', () => {
},
provider: 'claude',
accountHome: { variable: 'CLAUDE_CONFIG_DIR', path: root },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-1',
claimKeyId: 'key-1',
@@ -26,7 +26,6 @@ async function liveStore(): Promise<AgentSessionRecordStore> {
},
provider: 'codex',
accountHome: { variable: 'CODEX_HOME', path: root },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-renewal',
claimKeyId: 'key-1',
@@ -48,7 +48,6 @@ async function reserve(store: AgentSessionRecordStore) {
},
provider: 'codex',
accountHome: { variable: 'CODEX_HOME', path: '/tmp/codex' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-recovery',
claimKeyId: 'key-1',
@@ -27,7 +27,6 @@ async function seedLiveSession(sessionId: string): Promise<number> {
},
provider: 'codex',
accountHome: { variable: 'CODEX_HOME', path: join(root, 'codex-home') },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'seed-live',
claimKeyId: 'key-1',
@@ -101,7 +100,6 @@ async function seedSession(sessionId: string): Promise<number> {
},
provider: 'codex',
accountHome: { variable: 'CODEX_HOME', path: join(root, 'codex-home') },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'seed',
claimKeyId: 'key-1',
@@ -30,7 +30,6 @@ const reserveRequest = (): AgentSessionReserveRequest => ({
location: NATIVE,
provider: 'claude',
accountHome: { variable: 'CLAUDE_CONFIG_DIR', path: '/home/dev/.claude-work' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-a',
claimKeyId: 'key-1',
@@ -20,7 +20,6 @@ function request(overrides: Partial<AgentSessionReserveRequest> = {}): AgentSess
},
provider: 'codex',
accountHome: { variable: 'CODEX_HOME', path: '/home/dev/.codex' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-a',
claimKeyId: 'key-1',
@@ -20,7 +20,6 @@ function request(overrides: Partial<AgentSessionReserveRequest> = {}): AgentSess
},
provider: 'claude',
accountHome: { variable: 'CLAUDE_CONFIG_DIR', path: '/home/dev/.claude' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-a',
claimKeyId: 'key-1',
@@ -27,7 +27,6 @@ async function establishOwner(
},
provider: 'codex',
accountHome: { variable: 'CODEX_HOME', path: directory },
runtimeKind: 'native',
expectedFence: null,
spawnToken,
claimKeyId: 'key-1',
@@ -19,13 +19,11 @@ import {
import type {
AgentSessionJournalCheckpoint,
AgentSessionLease,
AgentSessionOwnerRuntimeKind,
AgentSessionProcessIdentity,
AgentSessionRecord
} from '../../shared/agent-session-record'
export type AgentSessionReservation = {
runtimeKind: AgentSessionOwnerRuntimeKind
spawnToken: string
claimKeyId: string
handoffOperationId: string | null
@@ -76,7 +74,7 @@ export function reserveAgentSessionOwner(args: {
disposition: 'reserved',
record: withLease(record, {
...record.lease,
runtimeKind: reservation.runtimeKind,
runtimeKind: 'native',
runtimeFence: decision.nextFence,
// Why: a reserved owner is not yet a writer; it may only talk to the provider to prove resume.
handoffStage: 'new-owner-proving',
@@ -57,7 +57,6 @@ it('persists resumed provider options atomically with owner proof', async () =>
},
provider: 'codex',
accountHome: { variable: 'CODEX_HOME', path: '/accounts/codex' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-options',
claimKeyId: 'key-1',
@@ -44,7 +44,6 @@ async function persistLiveOwner(): Promise<void> {
},
provider: 'claude',
accountHome: { variable: 'CLAUDE_CONFIG_DIR', path: '/home/dev/.claude-work' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-a',
claimKeyId: 'key-1',
@@ -20,7 +20,6 @@ function reserveRequest(): AgentSessionReserveRequest {
},
provider: 'codex',
accountHome: { variable: 'CODEX_HOME', path: '/accounts/created' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-created',
claimKeyId: 'key-1',
@@ -48,7 +48,6 @@ function reserveRequest(
location: NATIVE,
provider: 'claude',
accountHome: { variable: 'CLAUDE_CONFIG_DIR', path: '/home/dev/.claude-work' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-a',
claimKeyId: 'key-1',
@@ -57,7 +57,6 @@ function reserveRequest(
location: NATIVE,
provider: 'claude',
accountHome: { variable: 'CLAUDE_CONFIG_DIR', path: '/home/dev/.claude-work' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-a',
claimKeyId: 'key-1',
@@ -25,7 +25,6 @@ function reserveRequest(): AgentSessionReserveRequest {
},
provider: 'codex',
accountHome: { variable: 'CODEX_HOME', path: '/home/user/.codex' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-new',
claimKeyId: 'key-1',
@@ -50,7 +50,6 @@ function reserveRequest(
location: LOCATION,
provider: 'claude',
accountHome: { variable: 'CLAUDE_CONFIG_DIR', path: '/home/dev/.claude' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-a',
claimKeyId: 'key-1',
@@ -62,7 +62,6 @@ export type AgentSessionReserveRequest = {
/** Set only when this create adopts an existing provider conversation. Seeds the handle chain so
* the adapter resumes; without it a new record has never proved a thread and starts a fresh one. */
adoptedHandleLink?: AgentSessionProviderHandleLink
runtimeKind: AgentSessionReservation['runtimeKind']
/** Null when the session does not exist yet; otherwise the fence the caller last observed. */
expectedFence: number | null
/** A supplier is invoked only when this operation wins a new reservation. */
@@ -154,7 +153,6 @@ export function applyAgentSessionReservation(
throw new Error('agent_session_options_invalid')
}
const reservation: AgentSessionReservation = {
runtimeKind: request.runtimeKind,
spawnToken:
typeof request.spawnToken === 'function' ? request.spawnToken() : request.spawnToken,
claimKeyId: request.claimKeyId,
@@ -283,7 +281,7 @@ function createAgentSessionRecord(
updatedAt: request.now,
lease: {
sessionId: request.sessionId,
runtimeKind: reservation.runtimeKind,
runtimeKind: 'native',
// Why: fence 1 is the first reservation; 0 is reserved for "no owner has ever existed".
runtimeFence: 1,
handoffStage: 'new-owner-proving',
@@ -34,7 +34,6 @@ function reserveRequest(
},
provider: 'claude',
accountHome: { variable: 'CLAUDE_CONFIG_DIR', path: '/home/dev/.claude-work' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: 'spawn-a',
claimKeyId: 'key-1',
@@ -26,7 +26,6 @@ function reserveRequest(
},
provider: 'codex',
accountHome: { variable: 'CODEX_HOME', path: '/home/dev/.codex' },
runtimeKind: 'native',
expectedFence: null,
spawnToken: `spawn-${operations}`,
claimKeyId: 'key-1',