Problem
src/lib/pricing/curated-overrides.json pins deepseek-v4-pro at promotional prices that expired on 2026-05-31. The file documents the expiry itself, in _meta:
deepseek_v4_pro_discount_expiry: "2026-05-31T15:59:00Z — DeepSeek v4-pro is currently at a 75% promotional discount. After expiry the prices revert to 4x: input $1.74/M, output $3.48/M, cache_read $0.0145/M, cache_write $1.74/M. Update this file before the cutover."
Nothing checks that note, so the cutover never happened. As of today the file still carries the discounted values:
| field |
in file now |
correct (post-promo) |
input |
0.435 |
1.74 |
output |
0.87 |
3.48 |
cache_read |
0.003625 |
0.0145 |
cache_write |
0.435 |
1.74 |
Any deepseek-v4-pro usage since 2026-06-01 has been displayed at 25% of its true cost.
Why this is worse than the claude-opus-5 $0 bug
A model with no price at all shows $0.00, which looks broken and gets noticed. A model with a stale price shows a plausible number and never looks wrong. Same root cause — a price that depends on a human remembering a date — but silent in the direction that is harder to catch.
There is a second one already scheduled: _meta.sonnet5_intro_price_expiry says Sonnet 5 intro pricing (2/10) reverts to 3/15 on 2026-08-31, with the note "the src pricing path auto-tracks LiteLLM (no edit needed); re-vendor the seed after the cutover." Re-vendoring the seed is a manual step with the same failure mode.
Fix
- Correct the
deepseek-v4-pro prices to the post-promo values above.
- Replace the free-text
_meta.*_expiry string keys with a machine-readable _meta.expiries array (id, expires_at, what, action).
- Add
scripts/validate-curated-expiry.cjs and wire it into ci:local so any PR opened on or after an expires_at date fails until a human updates the price and advances or removes the entry.
This converts "remember to edit a JSON file in May" into "the next PR yells at you." Extra keys on curated entries are already tolerated by the lookup path (note lives there today), so the schema change is non-breaking.
Acceptance
Found during a Fable-model QA review of 0.39.40.
Problem
src/lib/pricing/curated-overrides.jsonpinsdeepseek-v4-proat promotional prices that expired on 2026-05-31. The file documents the expiry itself, in_meta:Nothing checks that note, so the cutover never happened. As of today the file still carries the discounted values:
inputoutputcache_readcache_writeAny
deepseek-v4-prousage since 2026-06-01 has been displayed at 25% of its true cost.Why this is worse than the
claude-opus-5$0 bugA model with no price at all shows
$0.00, which looks broken and gets noticed. A model with a stale price shows a plausible number and never looks wrong. Same root cause — a price that depends on a human remembering a date — but silent in the direction that is harder to catch.There is a second one already scheduled:
_meta.sonnet5_intro_price_expirysays Sonnet 5 intro pricing (2/10) reverts to 3/15 on 2026-08-31, with the note "the src pricing path auto-tracks LiteLLM (no edit needed); re-vendor the seed after the cutover." Re-vendoring the seed is a manual step with the same failure mode.Fix
deepseek-v4-proprices to the post-promo values above._meta.*_expirystring keys with a machine-readable_meta.expiriesarray (id,expires_at,what,action).scripts/validate-curated-expiry.cjsand wire it intoci:localso any PR opened on or after anexpires_atdate fails until a human updates the price and advances or removes the entry.This converts "remember to edit a JSON file in May" into "the next PR yells at you." Extra keys on curated entries are already tolerated by the lookup path (
notelives there today), so the schema change is non-breaking.Acceptance
deepseek-v4-propriced at post-promo rates_meta.expiriesarray replaces the free-text expiry keys, carrying the Sonnet 5 2026-08-31 cutovernpm run validate:curated-expiryfails when anyexpires_athas passed, passes todayci:localFound during a Fable-model QA review of 0.39.40.