CLAUDE LABJP
MODEL — Claude Sonnet 5 becomes the default across all plans, with stronger planning, tool use, and autonomyPRICE — Sonnet 5 launches at $2 input / $10 output per million tokens through August 31MODEL — Sonnet 5 nears Opus 4.8 performance at a lower price for always-on agentsCODE — Claude Code adopts Sonnet 5 as default with a native 1M-token context windowCODE — Claude Code adds sandbox credential blocking and org-level model restrictionsCLOUD — Claude is generally available in Microsoft Foundry on Azure with Azure-native accessMODEL — Claude Sonnet 5 becomes the default across all plans, with stronger planning, tool use, and autonomyPRICE — Sonnet 5 launches at $2 input / $10 output per million tokens through August 31MODEL — Sonnet 5 nears Opus 4.8 performance at a lower price for always-on agentsCODE — Claude Code adopts Sonnet 5 as default with a native 1M-token context windowCODE — Claude Code adds sandbox credential blocking and org-level model restrictionsCLOUD — Claude is generally available in Microsoft Foundry on Azure with Azure-native access
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 Code176Sonnet 52unattended automation2headless12model 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-01
Don't Accept an Agent's Numbers and Citations As-Is — A Verification Gate Built on a Dedicated Auditor Subagent
A design that verifies every number and citation in an agent-generated summary using a separate subagent before accepting it — with working TypeScript for deterministic recomputation and fail-closed source matching.
Claude Code2026-06-19
Noticing From the Outside When a Scheduled Job Quietly Did Nothing
exit 0, but zero output. How to catch a silent no-op not from the job's own log but from an external heartbeat ledger and ground truth, written from running several sites on a nightly schedule as an indie developer.
Claude Code2026-06-17
The Day a Billing Change Got Reversed at the Last Minute — Designing a Reversible Pipeline So You Don't Rewrite in a Panic
A billing change due to take effect on June 15 was retracted at the eleventh hour. From the position of someone who had literally logged 'effective today' the night before, here is why I didn't have to scramble to rewrite my headless stages, and how to build a pipeline that survives reversals and delays — with working code.
📚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 →