Ingot

What did the tokens buy?

Companies are spending heavily on AI coding agents. Dashboards show tokens per day and dollars per model, and nobody measures any of it against what actually shipped. Ingot builds the missing token:deliverable metric: it ingests agent-usage telemetry, reads your git history, joins the two by working directory and time window, and reports cost per commit, cache efficiency, and the spend that produced no commits at all.

Diagram of a token stream pouring from a spout and casting into an ingot stamped $11.01 per commit
$561.28
spend across 3,790 API responses
1.08B
total tokens, 45 sessions → 51 commits
$11.01
per commit, all spend over all commits
98%
cache hit rate, ~$3,200 net saved by caching
60%
of spend unattributed to any commit

this portfolio's own build, 2026-06-07 to 2026-07-07 - read HONESTY below before quoting any of it

How it works

A pipeline of four stages, from raw telemetry to a report you can put in front of whoever pays the bill:

  1. 01
    Usage adapters

    Parse agent telemetry into normalized usage events: timestamp, model, token counts, session id, working directory. Two adapters ship today (Claude Code transcripts and Langfuse exports); an adapter is one module with a single scan() function.

  2. 02
    Deliverable adapter

    Reads commit history via git log --numstat and classifies each commit: tests touched, docs touched, source touched, revert or not.

  3. 03
    The join

    Attributes usage to repos by longest working-directory prefix match and buckets both sides into time windows, days or ISO weeks.

  4. 04
    Metrics + report

    Prices tokens from a config-declared cost table and divides spend by what landed. Output as markdown, JSON, or a static HTML report. Scans are incremental and idempotent; prices apply at report time, so changing the cost table never requires a rescan.

Ingot is built to be pointed at real transcripts, so privacy is a hard guarantee, not a default: no conversation text is ever stored (adapters read from an explicit field allowlist and never touch message content), the directory allowlist is strict, and both guarantees are tested - fixture transcripts plant sentinel strings that the test suite asserts appear nowhere in the resulting database. 47 tests, fully offline.

A real report: this portfolio's own build

Ingot's worked example is the month that built the very projects these sites document. The scan allowlisted eleven Claude Code project directories of one inference-engineering workspace and joined them against five repos: four portfolio projects (anvil, sluice, assay, bellows) and the crucible eval harness.

ingot report · 2026-06-07 to 2026-07-07 · unedited
spend              $561.2785 across 3,790 api responses in 45 sessions
total tokens       1,083,985,397
  fresh input      408,377
  output           3,662,911
  cache read       1,058,462,021
  cache write      21,452,088

by model
  claude-fable-5     $198.2326    110,967,533 tok      665 responses
  claude-sonnet-4-6  $146.4594    367,017,236 tok    1,309 responses
  claude-sonnet-5    $131.4129    514,877,893 tok    1,236 responses
  claude-opus-4-8     $85.1737     91,122,735 tok      580 responses

cache efficiency
  hit rate           98.0% of prompt tokens served from cache
  saved by reads     $3,224.4751 vs paying fresh-input price
  net cache win      $3,200.9242 after the $23.5510 write premium

deliverables
  commits in period  51
  cost per commit    $11.0055 overall (all spend / all commits)
  crucible           $231.3977 attributed, 47 commits, $4.9234 per commit
                     (+24,097 / -1,274 lines, 18 test-touching commits at
                      $12.8554 per test-touching commit, 23 docs, 0 reverts)

unattributed spend
  no repo match      $304.2035
  repo, no commits   $32.5890
  total              $336.7925 (60.0% of spend)
  zero-commit        36 of 45 sessions ($309.2405)

Two things worth reading out of these numbers rather than past them. First, the cache is doing enormous work: 98% of prompt tokens were cache reads, and without caching this month would have cost roughly $3,200 more. Second, the 60% unattributed number is the honest one: most sessions ran in the workspace root repo, deliberately not one of the five configured deliverable repos, and much of that spend was research, planning, and writing rather than commits (the four portfolio repos also had exactly one commit each at scan time, being days old). That is exactly the conversation this tool exists to make concrete.

HONESTY

This section is lifted from the README, where it sits above the license. Read it before quoting any number from an Ingot report.

Correlation, not causation

Ingot joins spend and commits by directory and time window. It cannot see whether the tokens caused the commit, and it will happily attribute a hand-written commit to whatever agent session was open in that directory that day.

Commits are a proxy, not value

A one-line configuration fix can be worth more than a thousand-line refactor. Commit counts, insertions, and deletions measure motion, and motion is not the same thing as progress.

A zero-commit session is not a wasted session

Research, code review, debugging a production incident, and deciding not to build something are all legitimately commit-free. Ingot reports unattributed spend so that this conversation can be had with numbers instead of vibes, not so the number can be read as waste.

Token efficiency can be gamed

The moment cost-per-commit becomes a target, it stops being a good measure: commits get smaller, work gets split, and the metric improves while nothing else does. Goodhart's law applies in full.

What this tool is actually for

Making the spend conversation concrete: which projects the tokens flow to, how much of the prompt bill the cache absorbs, what a shipped change costs in tokens this month versus last. It is a lens for budgets and workflows. It is not a performance review, and using it to rank people is a misuse of the tool.

Quickstart

A Python project run with uv. Three decisions live in the config: which telemetry sources to allowlist, which repos count as deliverables, and the per-model price table.

shell
uv sync
cp ingot.example.yaml ingot.yaml   # edit sources, repos, prices
uv run ingot scan                  # ingest into ingot.db
uv run ingot report                # markdown to stdout
uv run ingot report --format json --out report.json
uv run ingot html --out report.html

ingot scan is incremental and idempotent: usage events are deduplicated by message id, and re-running only adds what is new.

Known limits

  • The join is a heuristic: longest working-directory prefix match plus a shared time window. It measures co-location in space and time, nothing stronger. Everything under HONESTY above follows from that.
  • Two usage adapters exist today: Claude Code transcripts and Langfuse exports. Any other agent's telemetry needs a new adapter (one module, one scan() function).
  • Prices come from a config-declared cost table you maintain by hand; Ingot does not fetch or verify provider pricing.
  • Deliverables are git commits only. Work that ships without a commit in a configured repo (docs elsewhere, reviews, incident response) lands in unattributed spend by design.
  • In the worked example above, 60% of spend is unattributed. That is the tool being honest about its own coverage, not a bug, and it is the number most worth interrogating before drawing conclusions.

stated up front because a metrics tool that oversells its own metric is the exact failure it exists to prevent.