Skip to content

feat(framework): a price table for the tools that export no amount #654

Description

@blafourcade

Outcome

A cost figure exists for every supported tool, and a reader can always tell whether it was reported by the vendor or computed by us.

Scope

Measured: Claude Code exports cost in USD; Copilot exports a cost attribute with no documented currency; Codex and Cursor export none, and Cursor's cost metric carries no identifier so it cannot be attached to a session even though it exists.

  • Includes: a versioned price table keyed by model, with the date each rate took effect.
  • Includes: two clearly separated notions — reported cost and computed cost — never summed into one column.
  • Includes: a stated rate source and a stated refresh policy, since rates change and a stale table produces confident wrong figures.
  • Excludes: currency conversion. Figures print in their source currency.
  • Excludes: any inference of a rate the table does not carry; an unknown model yields "unknown", never an estimate.

Done When

  • Reported and computed cost are visually distinct in every output that shows both.
  • A model absent from the table yields an explicit unknown, and the total says how much of it is unpriced.
  • The table records the date each rate took effect, and reports its own staleness.
  • No output sums a reported cost with a computed one without saying so.

Relations

Field Value
depends_on the four-tools issue

Activity

  1. added this to the milestone on Aug 14, 2026
  2. added theissue type on Aug 14, 2026
  3. moved this from Ideation to Todo in AIDD Roadmapon Aug 20, 2026
  4. blafourcade commented on Aug 20, 2026

    @blafourcade
    ContributorAuthor

    Promoted from optional to load-bearing by #684.

    The decision there is that the reader takes its figures from the files the tools already write, and none of those files carries a dollar amount. Measured 2026-08-20:

    • Claude Code's transcript has message.usage with all four token counters, and no costUSD.
    • Codex's rollouts have token_count events, no amount.
    • OpenCode's SQLite has a cost field that is 0 in all 35 rows on disk, and its USD denomination is not established.
    • Copilot has a cost field denominated in premium requests, not dollars - it stays pinned at 0.33 while totalNanoAiu ranges from 0.99 to 2.95 billion across sessions, so it is requests × multiplier and invariant to consumption.

    So this table is now what turns tokens into money for every tool, not just for the ones that export no amount. Two consequences for its shape:

  5. blafourcade commented on Aug 20, 2026

    @blafourcade
    ContributorAuthor

    Moved to the SaaS. Closing here rather than leaving it to look pending.

    The rates belong in the governor, and once they do, this repository has no pricing code to write. Its job is upstream of pricing: emit metrics that are complete, identified and not double-counted, and let the service that holds the rates turn them into money.

    That also removes the objection #684 raised against a shipped table — a table inside a released binary goes stale the day a provider changes prices. Served, it does not. The argument survives; only the location changes.

    What was actually load-bearing in this ticket, and where it went:

    • A reader can tell whether a figure was reported by the vendor or computed by us. Already shipped, by a different mechanism: every stored record carries provenance (export or local-read), and cost_usd is present only when a vendor actually reported one. Nothing local computes an amount, so nothing can be mistaken for one.
    • No inferred rate, no stale table, no unpriced share silently dropped. All now the governor's constraints, not this repository's.

    What replaces it here is the gap that surfaced while planning this: a stored record does not say which tool produced it, and does not carry the skill. See the follow-up ticket, which is the real prerequisite for anything downstream pricing or aggregating these figures.

  6. blafourcade commented on Aug 28, 2026

    @blafourcade
    ContributorAuthor

    Reopening: this was closed as completed on 2026-08-20 with all four Done When boxes unticked, and nothing in the codebase implements it.

    Verified on claude/aidd-telemetry-layer-e403uf at 9f88c36d:

    • No price table exists. grep -rln "price\|rate_per\|per_million\|pricing" cli/src returns nothing.
    • The two notions this issue is built on are absent: grep -rn "computed\|reported" cli/src/domain/models/cost-report*.ts returns nothing, so nothing can be "visually distinct" from anything.
    • A real run prints the consequence. From the committed fixture, aidd telemetry report --from 2026-01-01 --to 2026-01-31:
      tokens                    16,625    85% cache
      cost                      amount unknown
    

    What does exist is the ingestion half, and only through the export route: cost_usd is on the sink record and in the OTLP attribute allowlist (cli/src/domain/models/telemetry-sink-record.ts:136). So a tool that reports an amount can have it stored. Nothing computes an amount for a tool that reports none, which is this issue's entire subject.

    The local read path — the one 01-cost uses, and the only one that needs no endpoint — has no route to a cost figure at all today.

    No blame attached: the closing looks like a batch tidy-up of the telemetry milestone rather than a claim of delivery. Flagging it because a closed issue reads as done, and this one's absence is the reason the cost line says amount unknown on every report.

  7. blafourcade commented on Aug 28, 2026

    @blafourcade
    ContributorAuthor

    Rescoped, and moved down

    A product decision taken 2026-08-28 narrows this and drops its priority. Recording it here rather than leaving the issue reading as it did.

    What the local layer can honestly produce is not "cost". Multiplying tokens by a public rate gives a value at list price — a measure of intensity. For anyone on a subscription (Claude Max, Copilot seats) that figure is not what they paid, and presenting it as cost produces a wrong number with the confidence of a right one. What someone actually paid depends on their plan, their seats and any negotiated rate: the organisation's contract, which a single machine does not hold and cannot infer.

    So the split is not "tokens free, money paid". It is which currency:

    • Local: tokens, plus a value at list price, named as such. Withholding the multiplication would be arbitrary — the counters are already there and the rates are public.
    • Elsewhere: real cost, where the contract is known.

    Two things this issue's scope gets wrong, both measured.

    Its outcome says "a cost figure exists for every supported tool". It cannot. Cursor writes no token counter in any file it produces — with no tokens, no table yields an amount. The honest scope is a figure for every tool that counts tokens, and a named "not covered" for the rest. Copilot is its own case: totalPremiumRequests is a denomination, not a currency, and converting it needs a plan this layer does not know.

    And the table must be keyed by (model, counter), not by model. The four counters price differently — cache write above input, cache read a fraction of it, output highest. On a real report from this repository's own fixture (16,625 tokens — 85% cache) a single blended rate would not be a rounding error; most of the figure would be wrong.

    What stays in scope, and it is small: a dated table for the two or three models that actually appear (claude-opus-5, gpt-5.4 are the only ones in a real sink today), overridable locally for a negotiated rate, unknown for any model absent, and the total saying how much of the period is unpriced. No currency conversion, no inferred rate, no summing a reported amount with a computed one.

    Why it moves down. It opens nothing. The figures that need a key nobody has yet — per person, per task, per epic — are gated on #661 and #649, and those are what a team view rests on. This is a lookup table; it can land any time.

    Reopened earlier today because it was closed as completed with all four Done When boxes unticked and nothing implemented: no price table exists in cli/src, and neither does the reported-versus-computed distinction it is built on.

  8. moved this from Done to Ideation in AIDD Roadmapon Aug 28, 2026
  9. moved this from Ideation to Todo in AIDD Roadmapon Sep 3, 2026
  10. moved this from Todo to Ideation in AIDD Roadmapon Sep 3, 2026
  11. removed this from the milestone on Sep 3, 2026
  12. blafourcade commented on Sep 12, 2026

    @blafourcade
    ContributorAuthor

    Closing as Not Planned for the framework.

    The subsequent decision record settles the conflict in this issue: a local price table would assert a price, not measure one; it would go stale in a released binary and cannot represent account-specific cost. The framework keeps token and model counters and reports amount unknown. A chosen destination may apply a dated rate or billing contract.

    No framework implementation remains.

  13. moved this from Ideation to Done in AIDD Roadmapon Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    Priority

    Low

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions