ReviewOS

stacks/uplink

fix(dashboard): a Codex run reports tokens and no cost, so the spend total is wrong by omission

#11
Open glennmichael123 opened this 9 days ago ·
9 days ago

Part of #4.

What is there today

EngineResult.costCents (app/Uplink/engine.ts#L33) is filled from Claude's total_cost_usd and turns from num_turns. Codex's turn.completed carries only usage: {input_tokens, cached_input_tokens, cache_write_input_tokens, output_tokens, reasoning_output_tokens} and no cost field at all.

Both fields are already nullable, so nothing crashes. The damage is in the reporting:

  • app/Uplink/dashboard.ts#L52 sums row.cost_cents ?? 0 into totals.spend and renders it as one dollar figure. A Mac running mostly Codex shows a total that is quietly short rather than absent, which is worse than showing nothing.
  • app/Commands/Uplink.ts#L151 prints , N¢ at API rates only when a cost exists, so a Codex run silently loses its line.
  • The README's claim that runs are recorded with "cost in integer cents, at API rates" becomes true of only some runs.

Proposal

Decide the shape before the engine column lands, because the column is what makes the mixed history visible.

  1. Record what each engine actually reports. Add token counts to the run record alongside cost_cents, so a Codex run stores something real instead of a null.
  2. Make the dashboard total say what it covers: "spend across N Claude runs" rather than one figure over a mixed history, and show Codex runs with their token counts.
  3. Do not price Codex tokens into cents from a hardcoded table. A price table in the app goes stale silently and the figure would be presented with the same confidence as Claude's reported cost, which is measured rather than estimated.

Requirements

  • A null cost must never read as zero cost in any total.
  • The dashboard and the buddy uplink:* output agree. Two different answers for the same history is worse than either.
  • Existing rows keep their meaning. No backfill invents numbers.

Acceptance

  • A mixed history of Claude and Codex runs shows a total that names what it covers.
  • A Codex run's row shows its tokens.
  • No total sums a null as zero.

Sign in to comment on this issue.