Skip to content

[BENCH-766] Model pricing in Postgres: admin-recorded rates with history - #594

Open
cooperr1 wants to merge 1 commit into
mainfrom
cooper/bench-766-pricing-db
Open

[BENCH-766] Model pricing in Postgres: admin-recorded rates with history#594
cooperr1 wants to merge 1 commit into
mainfrom
cooper/bench-766-pricing-db

Conversation

@cooperr1

@cooperr1 cooperr1 commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Linear: BENCH-766

What

  • benchmarks_v2.pricing_rates (migration 20260903_0027): append-only log, seeded with the 61 rates verified against providers' public pricing pages. Nothing updates or deletes a row; a correction appends and marks the earlier row superseded, a future date schedules a change, null unit + price records "no known public rate".
  • GET /v1/pricing?as_of=: the rate in force on a day (default today) with earlier spans as history. Same roster and embargo filters as every other data endpoint.
  • GET / POST /v1/admin/pricing: coval-org only via the existing require_coval_admin. Each recording is stamped with the caller's Clerk user id and email. Writes pass the ratesheet PricingEntry rules.
  • Downgrade refuses to drop the table once admin recordings exist.

Deploy

  1. Merge. After the release deploys, run the migration the usual way:
    gcloud run jobs execute benchmarks-runner --region=us-east1 --project=coval-benchmarks-prod --args="db,migrate"
  2. Grant: coval-ai/benchmark-infra#169 gives the api role SELECT + INSERT on pricing_rates, applied via Atlantis after the table exists.
  3. Then the web PR: coval-ai/benchmarks-web#76.

Until the grant lands, GET /v1/pricing returns 503 and admin writes fail closed. Nothing else is affected.

Verification

cd runner && uv run ruff check . && uv run ruff format --check . && uv run mypy --strict src tests && uv run pytest -q --disable-socket --allow-unix-socket --allow-hosts=127.0.0.1,::1 — 2010 passed. Live on the local stack with a mock Clerk issuer: 401 no token, 403 other org, 422 bad unit / float price / bad URL / two years out, 201 stamped recording, repeat 200, public read serves the new rate with the old one in history, ?as_of=yesterday serves the old one.

Adds benchmarks_v2.pricing_rates (migration 20260903_0027), an append-only
log seeded with the 61 rates verified against providers' public pricing
pages. A price changes through POST /v1/admin/pricing instead of a deploy,
and every rate ever served stays on record: recording again for the same
effective date corrects it (the latest wins, the earlier row is kept and
marked superseded), a future effective date schedules a change, and null
unit + price records that no public rate is known from that day.

GET /v1/pricing reads the log live and serves the rate in force on ?as_of
(default today, never later) with the earlier spans as history, behind the
same roster and embargo filters as every other data endpoint. GET and POST
/v1/admin/pricing require the coval org (require_coval_admin) and stamp
each recording with the caller's Clerk user id and email. Every write
passes the same PricingEntry rules as a ratesheet entry: the unit bills
that benchmark, the price is a decimal string, the source is a real URL,
the effective date is at most a year ahead.

The downgrade refuses to drop the table once it holds a recording made
after the seed. GRANTs are Terraform-managed: the api role needs SELECT
and INSERT on pricing_rates.
@cooperr1
cooperr1 requested a review from a team as a code owner September 3, 2026 22:01

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 5df0cf16-5c66-4e6c-80b8-ecb179c167d9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cooperr1
cooperr1 removed the request for review from a team September 3, 2026 22:05

@coval-cale coval-cale left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving overall. I left two follow-up correctness comments around model identity across renames and unsupported benchmark validation.

roster = {(m.benchmark, m.provider, m.model) for m in models}
rates: list[PricingRateOut] = []
for key, timeline in sorted(timelines(recordings).items()):
if key not in roster or (key[1], key[2]) in hidden:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Keep pricing attached to an immutable model identity. This joins the pricing log to the current roster using the mutable (benchmark, provider, model) key. After a model is renamed, its old key becomes available to POST /admin/models; a different model later created under that key will silently inherit the original model's entire pricing timeline, potentially including embargoed rates. Please store an immutable model ID, migrate rates during rename, or reserve historical keys so they cannot be reused.

"""
CREATE TABLE benchmarks_v2.pricing_rates (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
benchmark TEXT NOT NULL CHECK (benchmark IN ('STT', 'TTS', 'S2S')),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Reject unsupported modalities before inserting. AdminRateCreate accepts the full Benchmark enum, and an unpriced LLM entry skips PricingEntry's unit validation. For a registered LLM model, model_exists() therefore succeeds and this CHECK rejects the insert, surfacing an uncaught database error as a 500. Please restrict the admin schema to supported pricing modalities or make the database and validation rules agree.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants