@@ -15,12 +15,12 @@ Claude integration must plug into this path instead of reintroducing legacy prov
1515
1616---
1717
18- ## Current constraints to design around
18+ ## Current constraints to design around (post-Stage 1)
1919
20201 . Provider runtime ingestion expects canonical ` ProviderRuntimeEvent ` shapes, not provider-native payloads.
21- 2 . ` ProviderService.startSession ` currently defaults to ` provider: "codex" ` unless explicitly provided .
22- 3 . ` thread.turn.start ` has no provider field today, so first-turn provider selection cannot be explicitly requested .
23- 4 . ` ProviderService ` requires adapter ` startSession() ` to return a ` ProviderSession ` with ` threadId ` .
21+ 2 . Start input now uses typed ` providerOptions ` and generic ` resumeCursor ` ; top-level provider-specific fields were removed .
22+ 3 . ` resumeCursor ` is intentionally opaque outside adapters and must never be synthesized from ` providerThreadId ` .
23+ 4 . ` ProviderService ` still requires adapter ` startSession() ` to return a ` ProviderSession ` with ` threadId ` .
24245 . Checkpoint revert currently calls ` providerService.rollbackConversation() ` , so Claude adapter needs a rollback strategy compatible with current reactor behavior.
25256 . Web currently marks Claude as unavailable (` "Claude Code (soon)" ` ) and model picker is Codex-only.
2626
@@ -61,21 +61,24 @@ Update `packages/contracts/src/orchestration.ts`:
6161
6262This removes the implicit “Codex unless session already exists” behavior as the only path.
6363
64- ### 1.3 Provider session start input for Claude runtime knobs
64+ ### 1.3 Provider session start input for Claude runtime knobs (completed)
6565
6666Update ` packages/contracts/src/provider.ts ` :
6767
68- 1 . Extend ` ProviderSessionStartInput ` with optional Claude-specific fields (for example ` claudeBinaryPath ` , ` permissionMode ` , ` maxThinkingTokens ` ).
69- 2 . Keep fields optional so current call sites remain valid.
70- 3 . Continue using generic ` resumeThreadId ` + ` resumeCursor ` as the cross-provider recovery mechanism.
68+ 1 . Move provider-specific start fields into typed ` providerOptions ` :
69+ - ` providerOptions.codex `
70+ - ` providerOptions.claudeCode `
71+ 2 . Keep ` resumeCursor ` as the single cross-provider resume input in ` ProviderSessionStartInput ` .
72+ 3 . Deprecate/remove ` resumeThreadId ` from the generic start contract.
73+ 4 . Treat ` resumeCursor ` as adapter-owned opaque state.
7174
72- ### 1.4 Contract tests
75+ ### 1.4 Contract tests (completed)
7376
7477Update/add tests in ` packages/contracts/src/*.test.ts ` for:
7578
76791 . New command payload shape.
77802 . Provider-aware model resolution behavior.
78- 3 . Backward compatibility of existing command/schema decoding .
81+ 3 . Breaking-change expectations for removed top-level provider fields .
7982
8083---
8184
@@ -100,9 +103,9 @@ Baseline adapter options to support from day one:
100103
1011041 . ` cwd `
1021052 . ` model `
103- 3 . ` pathToClaudeCodeExecutable ` (from ` claudeBinaryPath ` )
104- 4 . ` permissionMode `
105- 5 . ` maxThinkingTokens `
106+ 3 . ` pathToClaudeCodeExecutable ` (from ` providerOptions.claudeCode.binaryPath ` )
107+ 4 . ` permissionMode ` (from ` providerOptions.claudeCode.permissionMode ` )
108+ 5 . ` maxThinkingTokens ` (from ` providerOptions.claudeCode.maxThinkingTokens ` )
1061096 . ` resume `
1071107 . ` resumeSessionAt `
1081118 . ` includePartialMessages `
@@ -120,7 +123,7 @@ Required capabilities:
1201232 . Multi-turn input queue.
1211243 . Interrupt support.
1221254 . Approval request/response bridge.
123- 5 . Resume support via ` resumeThreadId ` / ` resumeCursor ` .
126+ 5 . Resume support via opaque ` resumeCursor ` (parsed inside Claude adapter only) .
124127
125128#### 2.2.a Agent SDK details to preserve
126129
@@ -129,7 +132,7 @@ The adapter should explicitly rely on these SDK capabilities:
1291321 . ` query() ` returns an async iterable message stream and control methods (` interrupt ` , ` setModel ` , ` setPermissionMode ` , ` setMaxThinkingTokens ` , account/status helpers).
1301332 . Multi-turn input is supported via async-iterable prompt input.
1311343 . Tool approval decisions are provided via ` canUseTool ` .
132- 4 . Resume support uses ` resume ` and optional ` resumeSessionAt ` .
135+ 4 . Resume support uses ` resume ` and optional ` resumeSessionAt ` , both derived by parsing adapter-owned ` resumeCursor ` .
1331365 . Hooks can be used for lifecycle signals (` Stop ` , ` PostToolUse ` , etc.) when we need adapter-originated checkpoint/runtime events.
134137
135138#### 2.2.b Effect-native session lifecycle skeleton
@@ -142,21 +145,23 @@ const acquireSession = (input: ProviderSessionStartInput) =>
142145 Effect .acquireRelease (
143146 Effect .tryPromise ({
144147 try : async () => {
148+ const claudeOptions = input .providerOptions ?.claudeCode ;
149+ const resumeState = readClaudeResumeState (input .resumeCursor );
145150 const abortController = new AbortController ();
146151 const result = query ({
147- prompt: makePromptAsyncIterable (input . sessionId ),
152+ prompt: makePromptAsyncIterable (),
148153 options: {
149154 cwd: input .cwd ,
150155 model: input .model ,
151- permissionMode: input .permissionMode ,
152- maxThinkingTokens: input .maxThinkingTokens ,
153- pathToClaudeCodeExecutable: input . claudeBinaryPath ,
154- resume: input . resumeThreadId ,
155- resumeSessionAt: readResumeCursor ( input . resumeCursor ) ,
156+ permissionMode: claudeOptions ? .permissionMode ,
157+ maxThinkingTokens: claudeOptions ? .maxThinkingTokens ,
158+ pathToClaudeCodeExecutable: claudeOptions ?. binaryPath ,
159+ resume: resumeState ?. threadId ,
160+ resumeSessionAt: resumeState ?. sessionAt ,
156161 signal: abortController .signal ,
157162 includePartialMessages: true ,
158- canUseTool: makeCanUseTool (input . sessionId ),
159- hooks: makeClaudeHooks (input . sessionId ),
163+ canUseTool: makeCanUseTool (),
164+ hooks: makeClaudeHooks (),
160165 },
161166 });
162167 return { abortController , result };
@@ -345,7 +350,8 @@ Define explicit adapter semantics:
345350
3463511 . ` sessionId ` : adapter-owned stable session id.
3473522 . ` threadId ` : Claude conversation/session identifier returned as ` ProviderThreadId ` .
348- 3 . ` resumeCursor ` : provider-specific cursor (for example message id) needed for precise recovery/rollback.
353+ 3 . ` resumeCursor ` : provider-specific cursor (for example thread id + message cursor) needed for precise recovery/rollback.
354+ 4 . Orchestration/shared services persist and forward ` resumeCursor ` unchanged without provider-specific parsing.
349355
350356### 2.5 Rollback/read strategy
351357
@@ -402,11 +408,12 @@ Update integration tests to ensure:
402408
403409## Phase 4: Orchestration command/reactor updates
404410
405- ### 4.1 Decider propagation
411+ ### 4.1 Decider propagation (completed)
406412
407413Update ` apps/server/src/orchestration/decider.ts ` :
408414
4094151 . Carry optional ` provider ` from ` thread.turn.start ` command into ` thread.turn-start-requested ` event payload.
416+ 2 . Keep this behavior provider-agnostic (no provider-specific runtime fields in the event payload).
410417
411418### 4.2 ProviderCommandReactor provider selection
412419
@@ -415,6 +422,7 @@ Update `apps/server/src/orchestration/Layers/ProviderCommandReactor.ts`:
4154221 . Prefer provider from turn-start event payload when starting a new session.
4164232 . Fallback to existing thread session provider when payload omitted.
4174243 . Fallback to default provider only when neither is present.
425+ 4 . On restart/rebind, forward the runtime session's persisted ` resumeCursor ` as-is (no reconstruction from ` providerThreadId ` ).
418426
419427Switch behavior policy (explicit in implementation):
420428
@@ -516,31 +524,26 @@ Confirm both native and canonical provider logs remain useful with multi-adapter
516524
517525## File checklist
518526
519- Likely files to touch:
520-
521- 1 . ` packages/contracts/src/model.ts `
522- 2 . ` packages/contracts/src/orchestration.ts `
523- 3 . ` packages/contracts/src/provider.ts `
524- 4 . ` apps/server/src/provider/Services/ClaudeCodeAdapter.ts ` (new)
525- 5 . ` apps/server/src/provider/Layers/ClaudeCodeAdapter.ts ` (new)
526- 6 . ` apps/server/src/provider/Layers/ProviderAdapterRegistry.ts `
527- 7 . ` apps/server/src/serverLayers.ts `
528- 8 . ` apps/server/src/orchestration/decider.ts `
529- 9 . ` apps/server/src/orchestration/Layers/ProviderCommandReactor.ts `
530- 10 . ` apps/web/src/session-logic.ts `
531- 11 . ` apps/web/src/components/ChatView.tsx `
532- 12 . Related tests under ` packages/contracts/src ` , ` apps/server/src/provider/Layers ` , ` apps/server/src/orchestration/Layers ` , ` apps/server/integration ` , and ` apps/web/src ` .
527+ Likely remaining files to touch:
528+
529+ 1 . ` apps/server/src/provider/Services/ClaudeCodeAdapter.ts ` (new)
530+ 2 . ` apps/server/src/provider/Layers/ClaudeCodeAdapter.ts ` (new)
531+ 3 . ` apps/server/src/provider/Layers/ProviderAdapterRegistry.ts `
532+ 4 . ` apps/server/src/serverLayers.ts `
533+ 5 . ` apps/server/src/orchestration/Layers/ProviderCommandReactor.ts `
534+ 6 . ` apps/web/src/session-logic.ts `
535+ 7 . ` apps/web/src/components/ChatView.tsx `
536+ 8 . Related tests under ` apps/server/src/provider/Layers ` , ` apps/server/src/orchestration/Layers ` , ` apps/server/integration ` , and ` apps/web/src ` .
533537
534538---
535539
536540## Delivery order
537541
538- 1 . Contracts for provider selection + models.
539- 2 . Claude adapter + unit tests.
540- 3 . Registry/layer wiring.
541- 4 . Reactor updates for provider-aware session start.
542- 5 . Web provider picker + provider-aware models.
543- 6 . Checkpoint/revert compatibility.
544- 7 . End-to-end integration tests and stabilization.
542+ 1 . Claude adapter + unit tests on top of the new ` providerOptions ` /opaque-cursor contracts.
543+ 2 . Registry/layer wiring.
544+ 3 . Remaining reactor updates for provider-aware session selection/switching invariants.
545+ 4 . Web provider picker + provider-aware models.
546+ 5 . Checkpoint/revert compatibility.
547+ 6 . End-to-end integration tests and stabilization.
545548
546549This order keeps risk isolated and maintains a working orchestrated path at each stage.
0 commit comments