Problem
A new Claude Code session opens on whichever model was selected last, not on a fixed default. Josh wants new sessions to always start on Opus, regardless of what the previous session ended on.
This matters because several skills are hard-gated to a cheap tier — handle-gmails and fix-labels both refuse to run unless the session is on Haiku. Running one means typing /model haiku, and that choice then persists into the next session, so the next session silently starts on the wrong tier for Opus judgment work.
Observed behavior (2026-07-29, cwd /home/joshua)
Running /model printed a note naming .claude/settings.json and the model it pins, and the reported value changed across two consecutive invocations:
/model haiku → "Set model to Haiku 4.5 and saved as your default for new sessions. .claude/settings.json pins Opus 5 — that applies on restart"
/model opus → "Set model to Opus 5 and saved as your default for new sessions. .claude/settings.json pins Haiku 4.5 — that applies on restart"
~/.claude/settings.json afterwards contained "model": "opus".
This is consistent with /model writing the model into that settings file, with the printed note showing the value as it was before the change. Not confirmed — that is an inference from two data points, and confirming it is part of this task.
What to investigate
- Which file does
/model actually write to — ~/.claude/settings.json, ~/.claude/settings.local.json, or ~/.claude.json? Confirm empirically.
- What is Claude Code's real settings precedence order across: enterprise/managed policy settings, CLI args,
.claude/settings.local.json, .claude/settings.json, ~/.claude/settings.json?
- Is there a higher-precedence layer that
/model does not overwrite, where "model": "opus" could live and win on every new session — while still allowing /model haiku to take effect within a session? (The in-session switch must keep working, or the gated skills become unrunnable.)
- Does a SessionEnd hook exist, and can it reset the persisted model back to
opus on exit? If so, does it fire reliably on all exit paths (/quit, Ctrl-C, terminal close, crash)?
- Would managed policy settings (
/etc/claude-code/managed-settings.json) force Opus at the cost of blocking /model entirely? If so, rule it out and say why.
Acceptance criteria
- A verified answer to "can a new session always default to Opus regardless of the last-selected model?" — yes with a working recipe, or no with the reason.
- If yes: the exact file + key + precedence rationale, plus confirmation that
/model haiku still works mid-session afterwards.
- If it requires a hook: the hook config, which event, and a note on which exit paths it does not cover.
- Do not apply the change — report the recipe and let Josh decide. Config edits to
~/.claude/ are his call.
Notes
~/.claude/settings.json currently pins opus.
- Do not
cat whole settings files while investigating — they contain live credentials. Extract single keys only (e.g. python3 -c "import json;print(json.load(open(p)).get('model'))"). See rule never-print-files-that-hold-secrets / web-jam-tools#272.
Problem
A new Claude Code session opens on whichever model was selected last, not on a fixed default. Josh wants new sessions to always start on Opus, regardless of what the previous session ended on.
This matters because several skills are hard-gated to a cheap tier —
handle-gmailsandfix-labelsboth refuse to run unless the session is on Haiku. Running one means typing/model haiku, and that choice then persists into the next session, so the next session silently starts on the wrong tier for Opus judgment work.Observed behavior (2026-07-29, cwd
/home/joshua)Running
/modelprinted a note naming.claude/settings.jsonand the model it pins, and the reported value changed across two consecutive invocations:/model haiku→ "Set model to Haiku 4.5 and saved as your default for new sessions..claude/settings.jsonpins Opus 5 — that applies on restart"/model opus→ "Set model to Opus 5 and saved as your default for new sessions..claude/settings.jsonpins Haiku 4.5 — that applies on restart"~/.claude/settings.jsonafterwards contained"model": "opus".This is consistent with
/modelwriting the model into that settings file, with the printed note showing the value as it was before the change. Not confirmed — that is an inference from two data points, and confirming it is part of this task.What to investigate
/modelactually write to —~/.claude/settings.json,~/.claude/settings.local.json, or~/.claude.json? Confirm empirically..claude/settings.local.json,.claude/settings.json,~/.claude/settings.json?/modeldoes not overwrite, where"model": "opus"could live and win on every new session — while still allowing/model haikuto take effect within a session? (The in-session switch must keep working, or the gated skills become unrunnable.)opuson exit? If so, does it fire reliably on all exit paths (/quit, Ctrl-C, terminal close, crash)?/etc/claude-code/managed-settings.json) force Opus at the cost of blocking/modelentirely? If so, rule it out and say why.Acceptance criteria
/model haikustill works mid-session afterwards.~/.claude/are his call.Notes
~/.claude/settings.jsoncurrently pinsopus.catwhole settings files while investigating — they contain live credentials. Extract single keys only (e.g.python3 -c "import json;print(json.load(open(p)).get('model'))"). See rulenever-print-files-that-hold-secrets/ web-jam-tools#272.