Field SOP
Field SOP

Migration SOP for Model Sunsets and Repricing: Four Steps to Inventory, Migrate, Recalculate, and Contain Cost

Three things happened at once on 2026-08-31: Sonnet 5 API rates moved from $2 and $10 to $3 and $15, GPT-5.4 and GPT-5.4 mini stopped being offered to Codex users signed in with ChatGPT, and kimi-k2.5 and moonshot-v1 sunset the same day. The three change types need completely different responses, yet most teams apply one uniform reaction and end up either overreacting or underreacting. This SOP runs four steps. Step zero classifies using keywords in the vendor announcement: sunset or deprecated means the ID stops responding, handle it today; replace or a default change means the entry point still works but the model behind it changed, so run a regression this week; pricing only means no interruption but a recalculation this month. Step one inventories every model ID in the codebase with a single grep, collapses them into one central config, and wires the check into CI. Step two executes the per-type migration. Step three recalculates monthly cost from three factors: tokenizer inflation, peak versus off-peak share, and cache hit rate. Also included: an eleven-item checklist, step four on limits, alerts and a fallback path, and seven ways this goes wrong, the most common being model IDs scattered through code where one fix misses three call sites.

Published August 31, 202612 min read
<!-- model-sunset-migration-cost-sop | sop | Migration SOP for Model Sunsets and Repricing: Four Steps to Inventory, Migrate, Recalculate, and Contain Cost -->

Three things landed on the same day, 2026-08-31. Claude Sonnet 5's API rate returned from $2 and $10 to the standard $3 and $15. GPT-5.4 and GPT-5.4 mini stopped being served in Codex to users signed in with a ChatGPT account. Moonshot AI sunset kimi-k2.5 and moonshot-v1. These three changes need completely different responses, and most teams apply one generic response to all of them, ending up either over-reacting or under-reacting. This piece gives a four-step procedure: classify, inventory, migrate, then recalculate metering and add monitoring.

Scope note: facts here come from aitoolsrecap's 2026-08-31 summary, the Tencent AI daily brief for 2026-08-31, TheRouter.ai's provider pricing and deprecation notices retrieved 2026-08-24, and a pricing table compiled by checking each vendor's official pricing page individually (checked 2026-08-24, re-checked 2026-08-28). Prices are a 2026-08-31 snapshot and move frequently; verify against the official pricing page and announcements for your own account region. Commands and configuration samples are generic illustrations and need adapting to your stack. For migration targets, follow vendor announcements; no unverified substitution is recommended here.

Step 0: classify which kind of change you are dealing with

This step gets skipped most often, and it sets the priority for everything after it. The three kinds differ entirely in urgency.

TypeSymptomUrgencyConsequence of inaction
SunsetOld model ID stops respondingImmediate, same dayCalls fail outright; outage
ReplacementRoute still works, model behind it changedThis weekBehaviour and output shift; regression needed
RepricingID unchanged, unit price changedThis monthCost rises; no outage

Today's three events map cleanly onto the three types. kimi-k2.5 and moonshot-v1 are sunsets and must be handled today. GPT-5.4 leaving Codex is a replacement: nothing errors, but the model answering you has changed, so regression testing is required. Sonnet 5 returning to standard pricing is a repricing: no interruption, but costs need recalculating.

Treating them alike wastes effort in both directions. Reading a repricing as a sunset triggers an unnecessary emergency migration; reading a sunset as a repricing means you find out when production starts erroring. The test is simple: look for two words in the vendor announcement. Sunset or deprecated means retirement. Replace or a default change means replacement. Pricing alone means repricing.

Step 1: inventory, and pull model IDs out of the codebase

Most teams only discover at the first sunset that they cannot say how many model IDs they use or which services hold them. Fix that first.

Scan the whole repository. Run one recursive search matching the common model-name prefixes, excluding dependency directories:

bash
grep -rnE "(gpt-|claude-|kimi-|moonshot|qwen|deepseek|glm-|doubao|gemini|grok|mimo)" \
  --include="*.ts" --include="*.tsx" --include="*.py" --include="*.js" \
  --include="*.json" --include="*.yaml" --include="*.yml" --include="*.env*" . \
  | grep -v node_modules | grep -v ".next" > model-inventory.txt

Do not stop at source. Model IDs routinely hide in three places that get missed: default model values in environment files, fallback chains in configuration, and historical session records stored in databases or caches. The last category is the worst, because it is runtime data: changing code does not fix it, and you need a migration script.

Then build a registry with an expiry-date field. Collapse scattered strings into one configuration, shaped roughly like this:

ts
export const MODELS = {
  chat: {
    id: 'kimi-k3',
    provider: 'moonshot',
    sunset: null,
    migratedFrom: 'kimi-k2.5',
    note: 'Migrated from k2.5 on 2026-08-31; verify pricing for your account region',
  },
  reason: {
    id: 'deepseek-v4-pro',
    provider: 'deepseek',
    sunset: '2026-10-24',
    migratedFrom: 'deepseek-reasoner',
    note: 'Peak/off-peak: weekdays 09-12 and 14-18 are peak, off-peak is half',
  },
  cheap: {
    id: 'gpt-5.6-luna',
    provider: 'openai',
    sunset: null,
    migratedFrom: null,
    note: 'High-throughput simple tasks; permanent price 0.20 / 1.20 USD',
  },
} as const

The value here is not elegance. It is that expiry becomes an explicit field. With it, the next announcement means editing one line rather than hunting strings across the codebase. Wire it into CI while you are there: a check that fails the build when a model ID past its sunset date is referenced beats any documentation reminder.

Step 2: migrate, one procedure per change type

Sunsets: switch now, and verify. kimi-k2.5 and moonshot-v1 sunset today with kimi-k3 as the target. The switch itself is one ID, but two things come first. Confirm the new ID's price in your own account region, since reported kimi-k3 figures vary considerably (some sources quote $3 and $15, others RMB 20 and 100), and do not budget off someone else's invoice. Then run a regression pass, because a new model means a new output distribution, and anything downstream that parses responses needs retesting.

Replacements: pick one of two paths. GPT-5.4 leaving Codex affects users signed in with a ChatGPT account, with GPT-5.6 Terra ($2 and $12) and Luna ($0.20 and $1.20) taking over. You can either accept the new model and re-test, or switch to API key authentication to keep using the original. The first costs less effort but carries behavioural change; the second is stable but pulls key management into your secrets infrastructure. Decide by measuring how far apart the two models are on your core tasks. Test, do not guess.

Schedule the already-announced dates in one pass. The published calendar: 2026-09-14 Claude Code permanent weekly limits take effect; 2026-10-10 DashScope retires 30-plus legacy IDs including qwen-turbo, qwen-vl-plus, qwen-audio-turbo, and several early Qwen3 snapshots; 2026-10-24 deepseek-chat and deepseek-reasoner are deprecated; 2026-11-12 OpenAI models leave Cursor; around 2026-11-21 GPT-5.6 Sol's promotion ends and $4 and $20 revert to $5 and $30. Put all of them in the schedule now rather than during announcement week.

Step 3: recalculate metering, three factors drive the real invoice

After migration, the new bill is not comparable to the old one, because the unit of measurement may have shifted. Three factors need recomputing.

Factor one: tokenizer inflation. Sonnet 5 changed tokenizers, mapping identical input to 1.0x to 1.35x as many tokens depending on content type. No official breakdown by content type exists, so the reliable approach is to take your own corpus and count it under both tokenizers to get your real factor. It costs almost nothing and beats every estimate.

Factor two: peak and off-peak windows. DeepSeek has billed peak and off-peak since 2026-08-17: weekdays 09:00-12:00 and 14:00-18:00 are peak, off-peak is half, weekends are off-peak all day. Schedule anything asynchronous into off-peak windows. That is a 2x spread requiring no engineering change. Do not budget against stale figures either: the 2026-08-13 GA note recorded uncached input at 3 and output at 6 RMB, but after the peak/off-peak reform, peak moved to 9 and 27.

Factor three: cache hit rate. Platforms charge far less for input tokens that hit a prefix cache, in some models a small fraction of the standard input rate. This variable is yours to move. Putting stable system instructions at the very front and reusing history prefixes across turns raises hit rates directly. Log cache-hit token counts separately, or you will never know how much discount you are collecting.

Combine the three into a reusable monthly estimate:

text
monthly cost ~= input_tokens * tokenizer_factor * input_price * (1 - cache_hit_rate)
              + input_tokens * tokenizer_factor * cache_price * cache_hit_rate
              + output_tokens * output_price

One caution: the input-to-output ratio moves the result substantially, because output is typically priced three to five times input. Any budget built on a rough "half and half" assumption needs redoing against your real ratio. Worked examples and how the ranking shifts are in this batch's comparison piece: /en/posts/post-aug31-token-cost-comparison-review.

Step 4: monitor and contain, limits, alerts, and a fallback path

Know the limit changes in advance. Anthropic has announced a permanent 25 percent increase to Claude Code weekly limits effective 2026-09-14, with the current 50 percent temporary boost holding until 09-13. Indexed across three points: the pre-May baseline is 100, today is 150, and from September 14 it is 125. That is plus 25 percent against the old standard and minus 17 percent against what you have now. If you rely on Claude Code weekly capacity for heavy work, the boost still applies until September 13, and capacity will be lower than today afterwards, so plan throughput accordingly.

Alert per model, not in aggregate. Set at least three: daily cost per model against a budget threshold, week-over-week token spikes per model, and cache hit rate falling below expectations. The third is the one everyone skips, and a falling hit rate usually means someone restructured a prompt, quietly doubling cost without a single error.

Build the fallback path before you need it. The cheapest model is not found by shopping; it is found by splitting traffic. GPT-5.6 Luna at $0.20 input and $1.20 output has a blended cost of $0.70, roughly one thirteenth of Sonnet 5. Moving high-throughput simple work such as classification, extraction, formatting, and routing off a flagship usually saves more than switching vendors, and it does not touch quality where it matters.

A checklist you can copy

In execution order:

  1. Scan the repository for model IDs, including env files, config, and runtime data; produce an inventory
  2. Tag each ID with status (in use / deprecated / pending migration) and an expiry date
  3. Consolidate IDs into one configuration and wire an expiry check into CI
  4. Sunsets: switch today; confirm regional pricing first, run regression after
  5. Replacements: choose one path, accept and re-test, or move to API key auth
  6. Schedule the known dates: 09-14, 10-10, 10-24, 11-12, 11-21
  7. Measure your tokenizer factor against real corpus
  8. Move asynchronous work into off-peak windows
  9. Log cache-hit token counts and alert on hit rate
  10. Split cost per model; alert on daily cost and spikes
  11. Stand up a fallback route to a cheap model for simple tasks

Seven ways this goes wrong

Reading the rate card and ignoring tokenization. The easiest trap in this cycle. Sonnet 5's rate rose 50 percent, but code workloads land 65 to 100 percent higher once the tokenizer change is compounded. What you feed it determines what you pay.

Modelling promotions as permanent. GPT-5.6 Sol's $4 and $20 reverts to roughly $5 and $30 around 2026-11-21, moving the blended cost from $12 to $17.5. Any migration with engineering cost should be justified at the post-expiry rate; three months of savings rarely pays for the work.

Model IDs scattered through the code. Fixing one call site and missing three is the most common direct cause of migration incidents. Centralised configuration plus a CI check solves it once.

Ignoring the input-to-output ratio. Output costs three to five times input, so any 1:1 estimate can be far off the real bill.

Not monitoring cache hit rate. It is a silent variable. It does not error when it drops; it shows up on the month-end invoice.

Mixing subscription quotas with API costs. This Sonnet 5 change affects API pricing only; consumer subscriptions are unaffected. The two cost bases are not comparable on one sheet.

No fallback path. Discovering there is no cheap model to fail over to when you need to cut spend leaves only two options: degrade everything or absorb the cost. Build the fallback while costs are healthy.

One closing note on cadence. This round looks dense, but taken apart, every item came with lead time: Sonnet 5's standard price was stated in the launch pricing documentation two months ago, Claude Code's limit change was announced half a month ahead, and the DashScope October retirement leaves a six-week window. What catches teams out is never the announcement itself; it is treating model IDs as permanent rather than as dependencies that expire. Build the registry from step one, wire it into CI, and every future announcement becomes a one-line change.

FAQ

Q1: Model IDs are scattered across dozens of files. How do I find them all at once? A1: Sweep for candidates with one grep, then confirm by hand: grep -rnE "(gpt-|claude-|kimi-|moonshot|qwen|deepseek|glm-|doubao|gemini|grok|mimo)" --include="*.ts" --include="*.py" --include="*.json" --include="*.yaml" . Do not edit each hit. Collapse them into one central config (see the MODELS example in step one) and have application code reference constants only. Then wire that same grep into CI as a failing check, so the next hardcoded ID gets caught before it merges.

Q2: After migrating, do prompts need re-tuning? A2: Yes, but calibrate the effort. Same-vendor, same-family upgrades (kimi-k2.5 to kimi-k3, for example) usually need no prompt rewrite, only a regression pass. Cross-vendor moves (DeepSeek to GLM, say) require a full regression over prompts and tool-call schemas. The part most often missed is tokenization: the same prompt costs a different number of tokens under a different tokenizer, which moves both cost and context budget. Measure it once before and once after and the difference is quantified.

Q3: How do I estimate the post-migration bill before I ship? A3: Use the three factors from step three. Tokenizer inflation: run the same sample through both tokenizers and take the ratio. Peak versus off-peak share: what proportion of your load can actually be scheduled off-peak. Cache hit rate: measured on production traffic, not assumed. Monthly cost is roughly input tokens times the inflation factor times the input rate times (1 minus hit rate), plus the cached portion, plus output tokens times the output rate. Substitute a default for any one of the three and the estimate drifts.

Q4: How do I notice a cache hit rate regression? A4: It never throws an error; it shows up on the invoice at the end of the month, so it has to be monitored deliberately. Log cached read and written token counts per call, aggregate hourly into a hit rate, and alert on a threshold, for example twenty points below baseline. The most common cause is not on the model side at all: someone put a timestamp, a request ID, or retrieval fragments in random order into the prompt prefix, which destroys prefix matching.

Q5: What counts as an acceptable fallback path? A5: Three conditions. First, the cheaper alternative is integrated and passes regression while costs are healthy, not on the day you need to cut spend. Second, switching is a one-line config change, not a code change and a release. Third, degraded output has an acceptable floor: if falling back makes the feature unusable, that is not a fallback, it is an outage. Note also that this Sonnet 5 change affects the API only and leaves Consumer subscriptions untouched, which is a reminder that the two quota types need separate fallback designs.

This article is AI-assisted and human-edited. Last updated: 2026-08-31

FAQ

Model IDs are scattered across dozens of files. How do I find them all at once?
Sweep for candidates with one grep, then confirm by hand: grep -rnE "(gpt-|claude-|kimi-|moonshot|qwen|deepseek|glm-|doubao|gemini|grok|mimo)" scoped with --include for your file types. Do not edit each hit. Collapse them into one central config and have application code reference constants only. Then wire that same grep into CI as a failing check, so the next hardcoded ID gets caught before it merges.
After migrating, do prompts need re-tuning?
Yes, but calibrate the effort. Same-vendor, same-family upgrades (kimi-k2.5 to kimi-k3, for example) usually need no prompt rewrite, only a regression pass. Cross-vendor moves (DeepSeek to GLM, say) require a full regression over prompts and tool-call schemas. The part most often missed is tokenization: the same prompt costs a different number of tokens under a different tokenizer, which moves both cost and context budget. Measure it once before and once after and the difference is quantified.
How do I estimate the post-migration bill before I ship?
Use three factors. Tokenizer inflation: run the same sample through both tokenizers and take the ratio. Peak versus off-peak share: what proportion of your load can actually be scheduled off-peak. Cache hit rate: measured on production traffic, not assumed. Monthly cost is roughly input tokens times the inflation factor times the input rate times (1 minus hit rate), plus the cached portion, plus output tokens times the output rate. Substitute a default for any one of the three and the estimate drifts.
How do I notice a cache hit rate regression?
It never throws an error; it shows up on the invoice at the end of the month, so it has to be monitored deliberately. Log cached read and written token counts per call, aggregate hourly into a hit rate, and alert on a threshold, for example twenty points below baseline. The most common cause is not on the model side at all: someone put a timestamp, a request ID, or retrieval fragments in random order into the prompt prefix, which destroys prefix matching.
What counts as an acceptable fallback path?
Three conditions. First, the cheaper alternative is integrated and passes regression while costs are healthy, not on the day you need to cut spend. Second, switching is a one-line config change, not a code change and a release. Third, degraded output has an acceptable floor: if falling back makes the feature unusable, that is not a fallback, it is an outage. Note also that this Sonnet 5 change affects the API only and leaves Consumer subscriptions untouched, which is a reminder that the two quota types need separate fallback designs.

Related

Field SOP

Build Long-Running Agent Workflows with GPT-6 Astra

A hands-on SOP for building long-running agent workflows on GPT-6 Astra's real capabilities (1.05M context, 128K output, 0% alignment overreach): start with three prerequisites (OpenAI Python SDK 1.50+, the OPENAI_API_KEY environment variable, and API allowlist), then proceed in order through long-context planning, tool definition (function calling plus computer use), async invocation, mid-flight correction, and acceptance with cost control. Key points: on the first call place only the goal, acceptance criteria, tool list, and key background so the model emits a plan first; tools must specify name, description, and parameters; use streaming events plus a background queue and task-id polling for async; correct course by injecting new instructions without restart; and accept only via independent assertion scripts while keeping max_output_tokens small and setting a daily spend cap.

Sep 4, 202611 min read
Field SOP

Claude Fable 5.1 API Migration SOP

Fable 5.1's 2026-09-01 launch lists three breaking API changes, each able to 400 or silently degrade at cutover. ① tool_choice any/tool now returns 400 — switch to auto with strict tool use or structured outputs. ② Thinking blocks are bound to the model: Fable 5.1 can read older models' thinking but not vice versa, so fallback loses the reasoning chain. ③ Editing history turns invalidates thinking blocks and errors on accounts created on or after 2026-08-31. This piece gives a three-step pre-upgrade audit, per-change code fixes, post-migration regression checks (parallel-call distribution, thinking continuity, 20+ round stress test, watermark/C2PA downstream compatibility), canary rollback, and eight pitfalls (whole-file rewrite tendency, low-effort memory answers, history edits breaking the cache). The turn-scoped system messages and context-editing betas are the fixes; exact header names are per official docs.

Sep 1, 202610 min read
Field SOP

Back up the state directory before you upgrade: OpenClaw 2.0 migration, rollback and credential-hardening SOP

For engineers already running OpenClaw: how to get up to 2.0 safely, how to roll back if it fails, and how to tighten credentials afterward. First principle — before upgrading, back up the Gateway's entire configuration and state (not a single client) and verify it is recoverable. Four upgrade steps: check → openclaw doctor --fix → restart the Gateway → verify health (model-access verification must pass for the upgrade to count). Two breaking changes: the OpenProse plugin and /prose command removed (.prose source files are preserved), and codex/* plus openai-codex/* routes move to openai/* (conflicts fixed manually). The 2026-09-01 plugin SDK deprecation (plugin-sdk-config-runtime-subpath → api.pluginConfig) is due today. Rollback is bounded: sessions created after the move to SQLite are invisible to the old version, and a full rollback also takes approvals and dedup records back. After upgrade, actively enable five things: masked credential requests, the proxy allowlist, precise authorization, role narrowing, and correcting the Incognito misconception.

Sep 1, 202614 min read