Skip to content

Expired DeepSeek v4-pro promo prices still active; curated expiries are not machine-checked #87

Description

@pitimon

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

  1. Correct the deepseek-v4-pro prices to the post-promo values above.
  2. Replace the free-text _meta.*_expiry string keys with a machine-readable _meta.expiries array (id, expires_at, what, action).
  3. 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

  • deepseek-v4-pro priced at post-promo rates
  • _meta.expiries array replaces the free-text expiry keys, carrying the Sonnet 5 2026-08-31 cutover
  • npm run validate:curated-expiry fails when any expires_at has passed, passes today
  • Validator runs as part of ci:local
  • Unit test covering expired / not-yet-expired / malformed-entry cases

Found during a Fable-model QA review of 0.39.40.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions