docs/refactor/claude-provider-vnext-locked.md
This is the implementation-locked vNext plan.
It preserves the original architecture direction, but removes ambiguity in behavior-critical areas before refactor work starts.
Current-state parity reference for present behavior:
Use the baseline doc for present behavior. This vNext plan defines what the refactor should preserve and how it should be staged; it is not the sole source of truth for current implementation details, and RAT-107 does not re-approve the rest of the future architecture below.
8.4/10..auto inconsistency handling, ClaudeUsageFetcher decomposition, stronger parity gates, TaskLocal-to-DI migration, and OAuth decomposition sub-phases.These behaviors are non-negotiable during refactor unless this doc is explicitly updated.
ClaudeSourcePlanner must reproduce this matrix exactly:
| Runtime | Selected mode | Ordered attempts | Fallback rules |
|---|---|---|---|
| app | auto | oauth -> cli -> web | oauth fallback allowed; cli fallback to web only when web available; web terminal |
| app | oauth | oauth | no fallback |
| app | cli | cli | no fallback |
| app | web | web | no fallback |
| cli | auto | web -> cli | web fallback allowed to cli; cli terminal |
| cli | oauth | oauth | no fallback |
| cli | cli | cli | no fallback |
| cli | web | web | no fallback |
Notes:
sourceLabel remains the final step label for successful fetch output.ProviderFetchPlan / ProviderFetchPipeline..auto inconsistency characterization contract (must-do before reconciliation)Current code has three .auto decision sites with inconsistent app ordering:
oauth -> cli -> web.resolveUsageStrategy helper order: oauth -> cli -> web -> cli fallback.ClaudeUsageFetcher.loadLatestUsage(.auto) order: oauth -> web -> cli -> oauth fallback.Phase 0 must characterize these paths with tests where they are reachable through stable seams, and otherwise defer to the baseline doc before deleting any path. Phase 2 must reconcile this into planner-only source selection.
The planner must use one explicit ClaudePromptDecision equivalent, but outcome parity with current behavior is required:
onlyOnUserActiononlyOnUserActionnever blocks delegated refresh attempts.Typed credentials must be introduced at the settings snapshot edge, with behavior parity:
ClaudeManualCredential.sessionKeyClaudeManualCredential.cookieHeaderClaudeManualCredential.oauthAccessTokenAccepted Claude token-account inputs must continue to work:
Bearer ... input)Routing parity requirements:
CodexBarCLI.Credential owner behavior must remain identical:
.claudeCLI expired credentials: delegated refresh path..codexbar expired credentials: direct refresh endpoint path..environment expired credentials: no auto-refresh.Refresh failure-gate semantics must remain unchanged.
Hard invariant:
.claude when persisted/displayed.Canonical plan inference can live behind the existing loginMethod compatibility surface, but outward
compatibility must be preserved:
Claude MaxClaude ProClaude TeamClaude EnterpriseUltra detection
semantics until that behavior is explicitly changed.docs/claude.md must be updated as part of Phase 0 after characterization lands so it no longer presents divergent
runtime ordering as settled behavior.auto: web -> cli.onlyOnUserActionauto ordering before this refactor.ClaudeSourcePlanner must be integrated into the existing provider descriptor / fetch pipeline rather
than added as a parallel orchestration layer.ProviderFetchContext / ProviderFetchPlan plumbing where possible.Deliverables:
docs/refactor/claude-current-baseline.md as the current-state behavior reference..auto decision paths where they are reachable through stable seams,
and defer remaining current-state details to the baseline doc until later reconciliation.docs/claude.md after tests land so documented ordering matches characterized behavior.Exit gate:
.auto characterization coverage plus the baseline doc record current divergence explicitly without forcing new
production seams in Phase 0.docs/claude.md no longer contradicts characterized runtime/source behavior.Deliverables:
ClaudePlan + one resolver used by OAuth/Web/CLI mapping and downstream UI consumers.Exit gate:
Deliverables:
Exit gate:
Deliverables:
ClaudeSourcePlanner + explicit ClaudeFetchPlan..auto policy branches from lower layers.ClaudeUsageFetcher internal .auto source selection.Exit gate:
.auto source-order logic outside planner.ClaudeUsageFetcher decompositionDeliverables:
ClaudeUsageFetcher into smaller executor-focused components.Exit gate:
Deliverables:
Exit gate:
Deliverables (sub-phases):
Exit gate:
claudeCLI, codexbar, environment).Deliverables:
ClaudeFetchDependencies and explicit protocol stubs.Exit gate:
Deliverables:
Exit gate:
Use this sequence to keep each PR reviewable without turning the rollout into unnecessary PR overhead.
| PR | Title | Scope | Primary risks | Must-pass gate before merge |
|---|---|---|---|---|
| PR-01 | Baseline characterization + doc correction | Lock current matrix behavior, characterize .auto paths through stable seams, defer remaining lower-level current-state details to the baseline doc, characterize prompt bootstrap/cooldown and token-account routing, then update docs to match reality. | R1, R2, R5, R6, R10 | No production behavior changes; characterization suites green; docs no longer contradict tests or the baseline. |
| PR-02 | Canonical plan resolver | Introduce ClaudePlan and central resolver; map OAuth/Web/CLI/UI compatibility through one model while preserving current loginMethod projections. | R8 | Plan compatibility tests green (Max/Pro/Team/Enterprise + current subscription compatibility). |
| PR-03 | Typed credentials at the edge | Parse manual credentials once (sessionKey, cookieHeader, oauthAccessToken) in app + CLI snapshot shaping. | R6 | Token-account routing parity tests green in app + CLI contexts. |
| PR-04 | Source planner introduction + cutover | Add ClaudeSourcePlanner, prove parity against old path, then remove duplicate .auto selection branches once parity is proven. | R1, R5, R10 | One .auto authority remains; attempt/source-label diagnostics remain parity-compatible. |
| PR-05 | ClaudeUsageFetcher decomposition | Split fetcher into execution/retry-focused units; remove embedded source-selection ownership. | R2, R10 | Delegated OAuth retry/recovery tests green with no behavior deltas. |
| PR-06 | OAuth decomposition | Extract repository, refresher, and delegated-controller seams from ClaudeOAuthCredentialsStore while preserving owner semantics. | R3, R4, R7, R9 | Cache/fingerprint/prompt/owner suites green (claudeCLI, codexbar, environment). |
| PR-07 (optional) | TaskLocal -> DI migration | Move remaining tests and seams to ClaudeFetchDependencies, keep temporary compat adapters, then remove. | R9 | Core planner/executor tests run without TaskLocal globals. |
| PR-08 (optional) | Web decomposition | Split cookie acquisition from web usage client and keep tooling isolated. | R8, R10 | Web parsing/account mapping suites remain green. |
Stacking rules:
Add these test groups before or during Phases 1-3, then extend for later phases:
(runtime x selected mode x interaction x refresh phase x availability) -> exact step order + fallback..auto divergence characterization tests:
resolveUsageStrategy helper vs fetcher-direct .auto..claude identity does not leak via snapshot scoping/merging.TokenAccountCLIContext and app settings snapshot behavior match for OAuth-vs-cookie routing.Use these risk IDs in refactor PR checklists/reviews.
| Risk ID | Severity | Risk | Detail |
|---|---|---|---|
| R1 | Critical | Auto-ordering reconciliation | Three .auto paths are inconsistent today. Characterize strategy pipeline vs resolveUsageStrategy helper vs fetcher-direct .auto before deleting any path. |
| R2 | High | Prompt policy consolidation | Prompt policy exists across strategy availability, fetcher flow, and credentials store gates. Preserve startup bootstrap constraints exactly to avoid prompt storms or silent OAuth suppression. |
| R3 | High | ClaudeOAuthCredentialsStore decomposition | Large lock-protected state + layered caches + fingerprint invalidation + security calls. Splits can break cache coherence, invalidation timing, or prompt gating order. |
| R4 | High | Owner semantics drift | Preserve exact owner-to-refresh mapping: .claudeCLI delegated, .codexbar direct refresh, .environment no refresh. |
| R5 | Medium | CLI runtime parity | Preserve runtime-specific policy: CLI auto remains web -> cli; OAuth is available only when explicitly selected as sourceMode=.oauth. Do not accidentally default CLI runtime to app ordering. |
| R6 | Medium | Token-account OAuth-vs-cookie misrouting | Keep routing parity for OAuth token vs session key vs full cookie header, including Bearer sk-ant-oat... normalization. |
| R7 | Medium | Cache invalidation regressions | Preserve credentials file/keychain fingerprint semantics and stale-cache guards during repository extraction. |
| R8 | Low-Medium | Plan inference heuristic drift | Preserve web-specific plan inference fallback (billing_type + rate_limit_tier) when unifying plan resolution. |
| R9 | Medium | Strict concurrency / @Sendable regressions | Maintain thread-safe behavior from current NSLock-based state while moving to DI/decomposed components under Swift 6 strict concurrency. |
| R10 | Low | Debug/diagnostic drift | Keep source labels, attempt sequences, and debug output aligned with real planner decisions after consolidation. |
Any refactor PR that intentionally changes one of the locked contracts above must: