Model Selection Across the Plan/Execute Boundary in Claude Code
Plan mode in Claude Code is a permission mode, not a separate session type. It restricts
the agent to read-only tools, and ExitPlanMode transitions the session back into an
editing mode once you approve the plan. The transition changes the permission mode. It
does not change the model.
That matters because the two phases have different cost profiles. Planning is exploration and synthesis over a large working set — the phase where model capability translates most directly into output quality. Execution is applying an already-specified diff. Running both on the same model means either overpaying for the second phase or underspecifying the first.
Claude Code exposes one built-in mechanism for splitting the two, plus two manual workarounds. The differences are in resolution semantics, cache behaviour, and how they interact with enterprise policy.
opusplan: conditional alias resolution
opusplan is a model alias whose resolution depends on the session’s current permission
mode. While plan mode is active it resolves through the opus alias; otherwise it
resolves through sonnet. The switch happens at the mode transition, transparently.
/model opusplan
{
"model": "opusplan"
}
Because it resolves through the family aliases rather than to fixed model IDs, the family-level environment variables control both halves independently:
| Variable | Governs |
|---|---|
ANTHROPIC_DEFAULT_OPUS_MODEL |
opus, and opusplan while plan mode is active |
ANTHROPIC_DEFAULT_SONNET_MODEL |
sonnet, and opusplan while plan mode is not active |
export ANTHROPIC_DEFAULT_OPUS_MODEL='claude-opus-5'
export ANTHROPIC_DEFAULT_SONNET_MODEL='claude-sonnet-5'
Pin these on third-party deployments. Unpinned aliases resolve to a provider-specific
built-in default that lags the current Anthropic release: on the Anthropic API sonnet
is Sonnet 5, but on Amazon Bedrock and Google Cloud’s Agent Platform it is Sonnet 4.5,
and on Microsoft Foundry opus is Opus 4.6. Pinning is also what gives you control over
when users move to a new version.
Context window handling is worth noting. The plan-mode phase uses the same window as the
plain opus setting, so on subscription tiers where Opus is automatically upgraded to a
1M window, opusplan inherits that upgrade in plan mode only. To force 1M on both
phases without an auto-upgrade tier, set opusplan[1m].
Under an availableModels allowlist the behaviour degrades in a defined way. On the
Anthropic API, if the newest Opus is excluded but an older version is permitted, the
plan-mode upgrade targets the newest permitted Opus; only when every Opus is excluded
does planning stay on Sonnet. On providers that use provider-specific deployment IDs —
Bedrock, Agent Platform, Foundry, Mantle — Claude Code cannot perform that substitution,
so an excluded upgrade target means the upgrade is skipped entirely and planning
continues on the session model.
Manual switching at the approval prompt
opusplan hard-codes the Opus/Sonnet pairing. For any other pair, switch by hand, and
do it before approving.
At the approval dialog, select the option that sends further instructions rather than one of the approve options. The session stays in plan mode with the plan and all accumulated exploration context intact. Then:
/model haiku
Shift+Tab back out of plan mode and issue the implementation instruction.
Two mechanics govern the cost of this. First, a mid-session model switch invalidates the prompt cache: the next request re-reads the full conversation history uncached, which is why the picker asks for confirmation when there is prior output. On a long planning session the uncached re-read can outweigh the per-token saving on a short execution phase. Measure before assuming the switch is a win.
Second, persistence. /model <name> typed directly writes the model field to your user
settings, making the choice the default for new sessions. Opening the picker with a bare
/model gives you Enter (switch and save) versus s (switch for this session only).
In non-interactive mode under -p, /model is always session-scoped and never persists.
Note also that project and managed settings retain precedence and reapply at next launch,
as does an organization default configured to override user selection.
Session handoff via the plan document
The third option discards the session. Ctrl+G opens the proposed plan in $EDITOR,
where it can be written to disk; a fresh session on the cheaper model then executes
against that file.
This trades all exploration context for a cold, cheap execution run — and it doubles as a validation step. A plan that a context-free model cannot execute without asking clarifying questions is underspecified. The failure surfaces before any file is written rather than three steps into the implementation.
Selection criteria
| Approach | Model pair | Context retained | Cache cost | Manual step |
|---|---|---|---|---|
opusplan |
Fixed (Opus/Sonnet) | Full | None | None |
Manual /model |
Arbitrary | Full | Full uncached re-read | Per plan |
| Fresh session | Arbitrary | Plan document only | New session | Per plan |
For a genuinely mid-task second opinion rather than a switch at a phase boundary, the advisor tool is the relevant mechanism instead — it lets the model consult a second model during execution without changing the session model.
Current gap
There is no planModel settings key, and no model transition hook on ExitPlanMode. The
feature request exists in several near-duplicate forms on the issue tracker; until one
lands, opusplan is the only automatic path and arbitrary pairs cost one manual switch
per plan.
Reference: Claude Code model configuration