CLAUDE LABJP
SUNSET — The legacy Workbench and experimental prompt tool APIs retire tomorrow, August 17, one day outLATEST — Version 2.1.233, released August 15, is current: GitLab merge request URLs now work with --worktree and the claude agents view, where MRs appear as !NSECURITY — Windows paths written with the NT \??\ device prefix no longer bypass UNC validation, closing an NTLM credential-leak vectorTODO — Todo and task tracking tools are off by default on Opus 4.8, Sonnet 5, Fable 5, Mythos 5, and newer models; set CLAUDE_CODE_ENABLE_TODO_TOOLS=1 to bring them backFORK — Version 2.1.232, released August 14, makes subagent_type: 'fork' the default, so a forked subagent inherits the full conversation and prompt cacheMENTION — Typing @ in the prompt now mentions another Claude session by name, and SendMessage reaches that session directlySUNSET — The legacy Workbench and experimental prompt tool APIs retire tomorrow, August 17, one day outLATEST — Version 2.1.233, released August 15, is current: GitLab merge request URLs now work with --worktree and the claude agents view, where MRs appear as !NSECURITY — Windows paths written with the NT \??\ device prefix no longer bypass UNC validation, closing an NTLM credential-leak vectorTODO — Todo and task tracking tools are off by default on Opus 4.8, Sonnet 5, Fable 5, Mythos 5, and newer models; set CLAUDE_CODE_ENABLE_TODO_TOOLS=1 to bring them backFORK — Version 2.1.232, released August 14, makes subagent_type: 'fork' the default, so a forked subagent inherits the full conversation and prompt cacheMENTION — Typing @ in the prompt now mentions another Claude session by name, and SendMessage reaches that session directly
Articles/Claude Code
Claude Code/2026-07-02Advanced

Which Model Ran Last Night's Unattended Session? Building Model Attribution and Default-Drift Detection After the Sonnet 5 Switch

Claude Code's default model switched to Sonnet 5, and unpinned headless runs changed models silently. Here is a working design for extracting the actual model from run output, appending an atomic run record, and deciding per task lineage whether to pin or follow the default.

Claude Code221Sonnet 57unattended automation5headless14model managementscheduled tasks8

Premium Article

On July 2, Claude Code's default model switched to Claude Sonnet 5. In interactive use you notice immediately — the model name is right there on screen. The sessions that worry me are the unattended ones launched without --model. They raise no errors. The logs look completely normal. And yet a different model wrote last night's code than the night before.

As an indie developer who runs article pipelines for several sites on scheduled Claude Code sessions here at Dolice Labs, the first thing I checked that morning was which task lineages had been riding the default. Then came the uncomfortable discovery: my run logs had never recorded the model, so I couldn't strictly prove which model my July 1 runs had used. If output quality shifted, I had no evidence to attribute it to the model or to my own prompt changes. This article is the design I built out of that morning: per-run model attribution plus default-drift detection.

Why a Default-Model Change Is the Nastiest Failure Mode in Unattended Runs

Model retirements and permission errors fail loudly. You can catch them with retries and fallbacks, and there are established patterns for it — I covered mine in Designing a Three-Tier fallbackModel Setup for Claude Code.

A default-model change, by contrast, succeeds loudly. Exit code 0, artifacts generated, everything green. What changes are the slow-burn properties: tone, structure, latency, unit cost. To be clear, I welcome this particular switch — Sonnet 5 ships with intro pricing ($2 per million input tokens and $10 per million output tokens through August 31, 2026, then $3/$15) and stronger planning and tool use. The problem isn't the model. The problem is being unable to state, from your own records, when each task switched and to what. Without that, root-cause analysis is permanently broken.

Take Inventory of Every Place a Model Gets Decided

Before adding any tooling, map where the model is actually being chosen in your environment. Claude Code accepts the setting through several channels, and if you don't know which one wins for each task, even good records will mislead you.

ChannelExampleScopeUnattended-run caveat
CLI flagclaude -p --model claude-sonnet-5That invocation onlyEasiest to audit — it's visible in the launch command
model in settings.json"model": "claude-opus-4-8"All sessions in that projectScattered across repos, easy to miss during inventory
Environment variableANTHROPIC_MODELEvery run in that shell environmentHides inside cron or runner config; hardest to spot
Unspecified (default)Every session with none of the aboveWhen the default moves, all of these move together — as they did this week

I wrote one line per task lineage stating which channel decides its model. Of my nine lineages, six were already pinned via flag or settings.json; three were riding the default — and those three had been running on Sonnet 5 since the morning of July 2 without telling me.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
If you couldn't tell whether a batch job's output changed because of the model or because of your prompt, you'll be able to answer in minutes with a per-run model trail
You'll take home working TypeScript that defensively extracts model IDs from both the headless JSON result and the transcript, appends records atomically, and judges drift
You'll be able to decide pin-versus-follow for each task lineage using three concrete axes: the intro-pricing deadline, deprecation ownership, and behavioral stability requirements
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Claude Code2026-07-04
A 1M Context Window Is the New Default — So I Built an Admission Policy Instead of Filling It
Sonnet 5 is now the Claude Code default and native 1M context is standard. The hard errors disappeared, but a quieter kind of degradation took their place. Here is how I made it visible with a probe, plus an admission policy and an effective-token-cost view — with working code and my own measurements.
Claude Code2026-08-09
One Transient 401 Replaced My Long-Lived Token — Giving Credentials a Provenance Field
A shared credential file can lose its long-lived token to a single transient 401. I injected exactly one 401 into a 24-worker fleet, measured the blast radius, and compared a provenance guard against full isolation.
Claude Code2026-07-18
I Stopped the Headless Claude Code Job, but the Build Kept Running — Designing Teardown Around exit 143
In headless mode, a SIGTERM received while Claude Code was mid-Bash used to orphan the command's process tree. The 2.1.212 fix changes that to a clean exit 143. Here is how to redesign your supervisor and cleanup around that contract.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →