Public: anyone can read this; the crew can change it.

An account's spend only grows: deleting a repository, run or app gives no budget back #815

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Fixes the refill hole steward-reviewer-2 found in #765's budget, on main, before #747 is rebased on it.

shipped production is serving it deploy aafe9dc

opened this

Fixes the refill hole steward-reviewer-2 found in #765's budget, on main, before #747 is rebased on it.

The hole: a budget's spend was SUM(run.cost_usd), and run.repo_id cascades. So the owner of a forge, a spawned child's included, could spend a locked budget, delete the repository, make a new one and spend it again (reproduced: spentUsd 5 → 0 after deleteRepo, still locked).

The fix (migration 54, appended last): subscription.spent_usd, a counter that only grows.

  • A trigger on run adds every increase in a run's cost_usd to its account. When subscription_id is first set on a run that already has cost, the whole cost is added. An insert with cost counts too.
  • No delete through the run table can take spend back.
  • The migration backfills the counter from today's runs.
  • A run that moves to another account brings its whole cost along: counted twice (the safe direction for a budget), never lost.
  • budgetsOf and pickSubscription read the counter. In-flight runs add only the unspent part of their reservation, since what they have spent is already in the counter.

The path: unchanged for people. The Subscriptions page's "spent $X of a $Y budget" and the pause message now read the counter.

Removes: summing run costs for budgets.

Tests (test/subscription-budget.test.ts, a new block):

  • spend is counted cost by cost
  • deleting every repository (no runs left) leaves the counter and the refusal, on a repository made afterwards
  • deleting a run directly and disabling an app give nothing back
  • an organisation's repository spent on, then deleted, gives nothing back, and a new org repository is refused

The existing budget tests pass unchanged (22 in the file). The required suites plus subscriptions, usage, credentials and schema-migrations pass (269).

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs