fix(server): Claude follow-ups no longer fail in Auto on models without Auto#15687
Claude can accept an Auto request as Manual when the selected model does not support Auto. The first turn works, but follow-ups used to retry the rejected Auto mode and fail. The adapter now restores the mode reported by the first init frame. Later init/status frames still track current mode, so restoration after Plan continues to work. A different API model after fallback uses the existing resumed-process replacement path to negotiate permissions again.
Continues @Gigioxx's work in #15687, addressing the follow-up failure described in #15650. Main was merged while preserving the contributor's commits. Independent implementation inspection retained the small process-local fix; test setup was simplified. Hiding Auto for unsupported models remains separate work.
Verification:
- 287 → 288 passing runnable adapter cases in the existing ClaudeAdapterV2 test file. The baseline count comes from the earlier full run. One regression is parameterized over same-model reuse and changed-model renegotiation; the existing Plan lifecycle case remains. No new test file or fixture.
- Exact main production with the current tests: fallback regression fails (
expected ['auto'] to deeply equal []); Plan restoration passes. Restored original fix: both pass. The additional model-switch case fails before the review fix and passes afterward; all 288 cases pass on this head. Before/after test proof. - Server typecheck and targeted formatting/lint passed. Lint reports the existing unused
layerwarning also present on main. - Two parallel adversarial review rounds: round one identified the model-switch permission regression, now fixed. Round two found no code blockers.
The proof executes the real adapter with an injected SDK stream/session. No fresh live Claude request or delegated parent/child flow was run; historical live claims from the contributor were not repeated. No UI/layout change makes a screenshot useful here. macOS, Windows, iOS, Android, Electron desktop and remote/relay connections were not exercised live.
A model change requiring renewed permission negotiation follows the existing background-work guard: wait for background work to finish or press Stop before replacing that process. An accepted-Auto process switching live to an unsupported model remains the pre-existing behavior, outside this fallback-follow-up fix.
Implementation and coordination: GPT-6.1 Sol through Codex in T3 Code. Tests: GPT-6 Astra through Codex. Adversarial reviews: Claude Opus 5.5 through Claude Code and GPT-6 Sol through Codex.
Checks
Added 1 commit
- fix(server): Claude follow-ups no longer fail in Auto on models without Autofcd3ad6
Approvability
Verdict: Approved at aa92c5d
Macroscope's review found this PR approvable — This is a focused Claude adapter bug fix that records the CLI’s effective permission mode and safely renegotiates when the API model changes. The production change is localized, with targeted regression coverage and no schema, deployment, product-default, or static-analysis configuration changes.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
- Configuration used: Path: .coderabbit.config.ts
- Review profile: CHILL
- Plan: Advanced
- Run ID:
a83a52f0-b84e-4182-9ed8-399624515617
📥 Commits
Reviewing files that changed from the base of the PR and between fcd3ad6986056af2293bb13b186c70e4d20fadd2 and aa92c5d6aeb44a9e89dd393ec46fdb1e49c68b05.
📒 Files selected for processing: 2
apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.tsapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.
📝 Walkthrough
The Claude adapter records the permission mode reported by its first SDK init frame, or retains the query option when the frame omits a mode. For a changed API model, live selection updates now require the opened mode to match the requested policy mode. Tests cover auto-mode query reuse and init-frame processing.
Changes: Claude permission-mode initialization
Layer / File(s) Summary Track the initial permission mode
apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts,apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.tsThe adapter records the first init frame’s permission mode and checks the opened mode before applying a live update for a changed API model. Tests cover same-model query reuse and changed-model reopening in auto mode, and await init-frame processing in plan-lifecycle tests. Priority: ➖ Normal
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix · Severity of issue fixed: Medium
Suggested reviewers:
juliusmarminge
Merge Risk: ⚪ Minimal · up to aa92c
Follow-ups restore the mode reported when the Claude process opened. No merge-blocking issue is established; merge after normal checks.
Security architecture risk: 🔵 Low · up to aa92c
The change preserves the initially accepted permission mode between turns and restricts process reuse. No new authorization bypass was established, but exceptional initialization and recovery behavior remains unverified.
Retained concerns No architecture-level concerns identified.
Security review details
Security Blast Radius
- inferred — The directly evidenced exposure is permission restoration for a live query within its provider session and native thread. The inspected change does not establish expanded cross-tenant or cross-service reachability.
Trust Boundaries and Controls
- observed — The first SDK initialization mode becomes authoritative for later restoration, including same-model reuse. The code does not compare that reported mode's permissiveness with the requested policy. This establishes a trust dependency, not an exploit: no attacker-controlled producer of a more-permissive first mode was demonstrated, and SDK enforcement under that condition remains unverified.
Resilience and Maintainability Implications
- observed — An initialization frame without permissionMode still marks initialization received and retains the requested opening mode. Later reports cannot correct that target. Mode-less fixtures exist, but their helper only checks the frame type before asserting SDKMessage, so they do not prove production schema behavior. Whether this sequence occurs in production remains unresolved.
Hardening Proposals
- proposed — Define and verify the accepted initialization contract, including missing and unexpectedly more-permissive modes. Cover those cases alongside interruption before initialization and repeated recovery, so permission restoration cannot silently drift from the intended authority contract.
Pre-merge checks: Passed 4
Check name Status Explanation Title check Passed The title clearly and concisely describes the main fix: Claude follow-ups no longer fail when Auto is unsupported by the selected model. It uses a valid conventional commit format. Description check Passed The description explains the problem, implementation, scope, linked issue, verification results, limitations, and test evidence. It does not use the template's explicit Problem, Change, and Scope and … Linked Issues check Passed Issue #15650requires a Claude follow-up to start and answer after the first init frame falls back from requestedautotodefault.ClaudeAdapterV2.tsnow records the permission mode from the fir…Out of Scope Changes check Passed The production changes limit process reuse and mode restoration to the Claude adapter behavior described in issue #15650. The added tests cover fallback reuse, model switching, session resume, and exi…Full details: Description check
Explanation
The description explains the problem, implementation, scope, linked issue, verification results, limitations, and test evidence. It does not use the template's explicit Problem, Change, and Scope and approval headings, but it provides the required information in clear paragraphs and passes the completeness requirement.
Full details: Linked Issues check
Explanation
Issue
#15650requires a Claude follow-up to start and answer after the first init frame falls back from requestedautotodefault.ClaudeAdapterV2.tsnow records the permission mode from the first init frame and restores that mode for later turns. The regression test covers same-model reuse and changed-model renegotiation, including native-session resume and absence of an invalid live permission update. The existing plan-mode test now supplies init frames, so later mode tracking remains covered. The issue's model-aware mode selection and clearer error text are suggested fixes, not required outcomes for this adapter fix.
Full details: Out of Scope Changes check
Explanation
The production changes limit process reuse and mode restoration to the Claude adapter behavior described in issue
#15650. The added tests cover fallback reuse, model switching, session resume, and existing plan-mode restoration. These changes support the linked objective, and no unrelated change appears in the reviewed diff.
✨ Finishing Touches
🧪 Generate unit tests (beta)
- Create a new PR
- Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.
Added 1 commit
- fix(server): preserve Claude permission fallback on current mainf929b71
Taking over this one as maintainer for batch claude-03. I will preserve your commits, merge current main, and run separate minimal-test, implementation, and adversarial-review passes before pushing. No merge planned.
Added 3 commits