Releases: anandgupta42/receipts
Release list
v0.8.2
Patch: the auto-attach hook now fires on bare-HEAD branch publishes —
git push -u origin HEAD (and --force-with-lease / HEAD:refs/heads/<x> forms), the
dominant idiom for coding agents, previously classified as not-a-branch-publish and the
SPEC-0073 hook silently wrote no receipt ref. Root-caused from the org dogfood pilots
producing zero receipts (issue #228, PR #230): the sibling hook on the same event fired
while ours declined classification. The receipt ref slug always derives from the
resolved checked-out branch; detached HEAD still attaches nothing (fail-safe), and
tag/sha/receipt-ref/delete publishes stay excluded.
Also: docs — terminal-statusline pages now say what happens without tmux (silent
fallback + alternatives, #226) and add a shell-wrapper recipe so the statusline appears
whenever the agent launches (#225).
v0.8.1
Patch: OpenAI gpt-5.6 family price rows — gpt-5.6-sol ($5.00 in / $0.50 cached /
$30.00 out per 1M), gpt-5.6-terra ($2.50 / $0.25 / $15.00), gpt-5.6-luna ($1.00 /
$0.10 / $6.00); Standard short-context tier, effective 2026-07-09, every row cited to
the official OpenAI pricing page (PR #223). Codex CLI sessions on these models — which
rendered tokens-only under I2's no-fabricated-dollars rule — now price in receipts and
the statusline. Additive data change only; no code touched.
Also: the README was restructured around a features-first flow with an agent-assisted
install section ("point your agent at this README and it installs + wires the
statusline"), contributed in PR #213. Docs-only; ships as the npm package README.
v0.8.0
Minor: the statusline now works at the terminal level — tmux, starship, zsh/bash,
PowerShell, terminal titles — so Codex and opencode sessions get a live cost line too,
not just Claude Code. Neither Codex nor opencode exposes a command-backed status hook
(openai/codex#17827 and anomalyco/opencode#8619 are open), so the surface moved to the
terminal itself (SPEC-0075, PRs #217/#221).
feat
aireceipts statusline --cwd <path>selects the newest session attributed to that
path instead of the machine's globally newest one, so a tmuxstatus-rightline
(--cwd "#{pane_current_path}") shows each pane its own session. Attribution is
guarded: Claude Code's lossy project-directory encoding is confirmed against the
transcript's own recordedcwdafter load, sessions launched from the home directory
(or/) never ancestor-match everything, dot-segments resolve lexically, full-parse
work is capped, and no match renders the neutral placeholder — never another
project's line. Cursor sessions carry no cwd and are excluded. Relative paths resolve
against the invocation directory; a usable Claude Code stdin payload still wins.
Recipes for tmux, starship, plain zsh/bash, PowerShell, and OSC terminal titles are
indocs/statusline.md— the Claude Code nativestatusLinehook remains the
recommended (richer, faster) surface where it exists (PRs #217, #221).~/.aireceipts/statusline.json({"items": ["brand", "cost", …]}) sets a persistent
default segment list for the statusline. Precedence: explicit--format> config
file > built-in default. An invalid file degrades to the default line with one stderr
note (exit 0); the--formatflag keeps its fail-fast contract (PR #221).- Telemetry:
--cwdinvocations are polling surfaces, so they count locally but never
network-flush (a 15-second tmux poll adds zero events). The
integration_surface_renderedevent gainsscopedandconfigFilebooleans — never
the path or the format string (docs/telemetry.md, PR #221).
fix
- The published CLI is ~3.5× faster wherever sqlite-backed sessions (opencode,
Cursor) are read (PR #214). tsup'sremoveNodeProtocoldefault rewrote
import("node:sqlite")toimport("sqlite")indist/, which fails at runtime, so
every published build silently fell back to spawning thesqlite3CLI per query —
measured 4.0s → 1.15s for one statusline render on a sqlite-heavy machine. On
Node ≥ 22.13 thesqlite3binary is no longer needed at all; older runtimes keep the
fallback. Built-artifact regression tests now pin the import specifier and the
in-process read path.
chore
- CI gains a
windows-latestjob (cwd matching, statusline suites, built-CLI e2e). Its
first runs surfaced and fixed three real Windows issues:.cmdspawns need a shell
under Node's CVE-2024-27980 hardening, goldens/fixtures gained-textline-ending
exemptions, and absolute POSIX paths are never drive-prefixed bypath.resolve
(PR #221). - OpenSSF Scorecard hardening: esbuild override for the open advisory, absolute
SECURITY.mdlink (PR #212); adopterpr-checkworkflow hardened with
continue-on-error+ concurrency groups (PR #207).
Rendered receipt output is byte-identical (receipt goldens unchanged; the help golden
gains the --cwd line); the default statusline
line renders through the exact same code path as 0.7.2 when neither --cwd nor a
config file is present.
v0.7.2
Patch: PR-receipt refs are now written under refs/aireceipts/* instead of the generic
refs/receipts/*. The old namespace collided with other tools that also publish to
refs/receipts/<slug> (e.g. an attestation producer storing an in-toto receipt.json at
the same path). In a repo running both, the namespace was occupied by the other tool's
payloads, so CI pr-check fetched a foreign ref, failed its schemaVersion check, and
silently posted nothing — the auto-attach hook fired and pushed refs, yet no receipt ever
appeared. aireceipts now owns refs/aireceipts/* and never reads or writes
refs/receipts/*, so the two coexist; the push classifier still recognizes both namespaces
so a foreign receipt-ref push is never mis-counted as a branch commit (PR #204). No
migration: aireceipts had never written a refs/receipts/* ref. Hooks and CI on @latest
adopt the new namespace together on this release. Rendered receipt output is byte-identical
(goldens unchanged); the only user-visible surface change is the ref name in pr --help.
v0.7.1
Patch: Claude Code receipts were over-reporting cost by ~2.5–3× and are now correct.
Claude Code writes one assistant transcript record per content block of a response, and
every record of that response repeats the same message.id and a byte-identical usage
snapshot. The adapter had counted each record as its own billed turn, multiplying a
response's tokens by its block count. Turns are now deduped by message.id — the first
record of a response books its usage once, later records only add their tool calls — so
turnCount and every $ reflect real billed responses (PR #196). After upgrading, every
Claude Code receipt you render shows lower dollars and fewer turns than 0.7.0 showed for
the same session: a real local session dropped from $102.97 to $36.69 (2.81×), and one PR
slice from $5.17 to $1.61. This was a silent over-report — the first known arithmetic
case of a receipt exceeding the true floor rather than under-reporting it. Codex, opencode,
and Cursor are unaffected (Codex reconciles against the rollout's own cumulative total and
was re-verified correct to the cent). Synthetic-fixture output is byte-identical (goldens
unchanged); the summary-cache version was bumped (2 → 3) so stale inflated totals recompute
on the next run. Receipts posted on this repo's own past PRs carry per-session correction
blocks with exact recomputed figures. Full audit and evidence: PR #196,
docs/cost-model.md, and the 2026-07-08 addendum in
docs/internal/cost-attribution-evidence.md.
v0.7.0
Minor: telemetry now defaults to enabled in CI, reversing the v0.6.x CI-default-off behavior.
Automated CI runs (e.g. the pr-check action) are now counted by default, so CI adoption shows up
in the data. CI is no longer special-cased — the isCI field still distinguishes CI from human
runs. Both kill switches still win everywhere: set AIRECEIPTS_TELEMETRY=off (or 0/false)
or DO_NOT_TRACK=1 to disable telemetry in CI or anywhere; an empty/malformed connection string
also disables. Telemetry payloads remain content-free (no transcript, prompts, file paths, repo
names, or dollar amounts — invariant I4). See SPEC-0002's 2026-07-08 amendment and docs/telemetry.md.
v0.6.1
Patch: the agent auto-attach hook (SPEC-0073) shipped with a 10s timeout — too tight for its
first npx -y aireceipts-cli@latest run on a cold npm cache (which downloads the package,
including the @resvg/resvg-js native dep, before it can write the ref). On a fresh clone the
first push could hit the timeout and silently skip its receipt. Bumped the pre-push hook timeout
to 60s (still bounded — the push is never gated on the receipt). The SessionEnd --mini hook
timeout is unchanged (10s). No other behavior change; rendered output is byte-identical.
v0.6.0
Minor: receipts can now be produced automatically on push, and PR attribution is more
robust. No change to rendered receipt output (goldens byte-identical); both additions are
opt-in / internal.
Added
- Agent auto-attach (SPEC-0073): a hidden
aireceipts hook pre-pushsubcommand, wired as a
Claude CodePreToolUsehook via a committed.claude/settings.json, writes and pushes the
receipt ref (refs/receipts/<slug>) when the coding agent runs a branch push — so a receipt
is produced with no manual command. It never blocks the push (exits 0 on every path, no
stdout, bounded by the hook timeout) and only acts on a realorigin/current-branch push
(tokenized detection; skips dry-run/delete/tags/non-origin/repo-retargeting/refs/receipts).
The adopter kit is now two files — thepr-checkworkflow (produces nothing on its own)
plus the.claude/settings.jsonhook (docs/adopt/,aireceipts integrations).
Fixed
- Robust PR-receipt attribution (SPEC-0072): a session whose commit SHA was orphaned by
git commit --amend(or rebase) is now correctly credited by matching its stable
git patch-idto the branch commit, instead of showing "no branch commit" while an unrelated
helper takes the credit. Strictly under-crediting — duplicated diffs, empty/merge commits, and
a diff already directly claimed by another session never produce a match (no fabricated or
stolen credit, I2). Adds anunanchored-git-writeconfidence signal that floors the total when
a real git-write can't be tied to the branch.
Minor: PR receipts gain a self-contained CI path (no external reusable workflow), the
default statusline gets richer, and the samosa tip link leaves the default PR-posted
surfaces (now opt-in). Two deliberate output changes — statusline default and the PR-posted
footer — both called out below.
Added
- Self-contained
pr-check(SPEC-0064 R2–R7): an adopter's own workflow can run
npx -y aireceipts-cli@latest pr-checkin a single job — no reusable-workflowuses:,
no org Actions-policy gate — to fetch the branch's receipt ref, render + sanitize it, and
upsert the marked PR comment viaGITHUB_TOKEN(no localgh). Hidden command; for trusted
same-repo/internal PRs (the two-job reusable workflow stays the hardened path for untrusted
fork PRs). Also fixes the reusable-caller template, which was missingpull-requests: write.
Changed (deliberate output changes)
- Richer default statusline (SPEC-0071): the default line now carries a burn rate (
$/hr),
context-window %, abbreviatedM/Btoken counts, and an inline 5h reset countdown — e.g.
[aireceipts] $423 · $80/hr · 501M · ctx 42% · 5h 26% ↺2h13m. Every segment renders from a
real payload field or a priced ledger value; nothing is estimated. - Samosa tip link off by default (SPEC-0070): the
buy me a samosalink no longer appears
on the surfaces aireceipts posts onto a PR (the comment's<details>and the artifact
footer). Opt back in with--samosa; the standalone tip page and the docs-site footer are
unchanged.
Internal / CI
- Incremental mutation testing (SPEC-0069): Stryker runs incrementally on PRs that touch
the money paths (src/pricing/**,src/pr/**), with a nightly full sweep — the same
anti-gaming moat at a fraction of the wall-clock. No product code change.
v0.5.0
Minor: PR receipts gain a self-contained CI path (no external reusable workflow), the
default statusline gets richer, and the samosa tip link leaves the default PR-posted
surfaces (now opt-in). Two deliberate output changes — statusline default and the PR-posted
footer — both called out below.
Added
- Self-contained
pr-check(SPEC-0064 R2–R7): an adopter's own workflow can run
npx -y aireceipts-cli@latest pr-checkin a single job — no reusable-workflowuses:,
no org Actions-policy gate — to fetch the branch's receipt ref, render + sanitize it, and
upsert the marked PR comment viaGITHUB_TOKEN(no localgh). Hidden command; for trusted
same-repo/internal PRs (the two-job reusable workflow stays the hardened path for untrusted
fork PRs). Also fixes the reusable-caller template, which was missingpull-requests: write.
Changed (deliberate output changes)
- Richer default statusline (SPEC-0071): the default line now carries a burn rate (
$/hr),
context-window %, abbreviatedM/Btoken counts, and an inline 5h reset countdown — e.g.
[aireceipts] $423 · $80/hr · 501M · ctx 42% · 5h 26% ↺2h13m. Every segment renders from a
real payload field or a priced ledger value; nothing is estimated. - Samosa tip link off by default (SPEC-0070): the
buy me a samosalink no longer appears
on the surfaces aireceipts posts onto a PR (the comment's<details>and the artifact
footer). Opt back in with--samosa; the standalone tip page and the docs-site footer are
unchanged.
Internal / CI
- Incremental mutation testing (SPEC-0069): Stryker runs incrementally on PRs that touch
the money paths (src/pricing/**,src/pr/**), with a nightly full sweep — the same
anti-gaming moat at a fraction of the wall-clock. No product code change.
v0.4.0
Minor: PR receipts can now attach and post themselves. A receipt travels with the
branch as a sibling git ref and CI renders + posts the comment, so a receipt lands even
when no one runs pr --post. Rendered receipt output is unchanged from v0.3.0 (goldens
byte-identical); the new surface is opt-in.
Added
- Seamless PR receipts —
store=ref+ pre-push hook (SPEC-0065):aireceipts pr --store ref(orAIRECEIPTS_STORE=ref) writes the receipt as a deterministic git
object onrefs/receipts/<slug>— invisible in the tree and PR diff, byte-identical
across machines (dated from the session's ownendedAt, never wall-clock). A committed
.githooks/pre-pushhook generates and pushes that ref ongit push(best-effort;
never blocks a push, no second push).npm run setup:hooksactivates the hook for a
clone of this repo; the default store stayscomment. - CI posts the receipt from the ref (SPEC-0066): a two-job
pr-receipt-check.yml
fetches the branch ref, validates and sanitizes the untrusted, fork-author-controlled
payload, renders it through the existing renderer, and upserts one marker comment via
GITHUB_TOKEN— no localghrequired. Opt-in enforcement
(AIRECEIPTS_REQUIRE_PR_RECEIPT=true) makes same-repo PRs require a receipt; fork
PRs always stay notice-only (their transcripts live on the contributor's machine, so CI
can't generate one). Enforcement is currently coarse — it does not yet distinguish
agent-built from hand-written PRs. @latestdistribution pin (SPEC-0064 R1): the PR-receipt-check caller installs the
reusable workflow at@latest; the movinglatestgit tag is advanced by the release
workflow on each publish. (SPEC-0064 R2–R4, the npm-nativepr-checkcommand, remain in
progress.)
Performance
- Faster feedback (SPEC-0063): in-process sqlite parsing, a goldens compile cache, and
parallel preflight reduce CLI and preflight wall-clock.
Security
- The receipt payload that rides on the branch ref is treated as untrusted input — anyone
who can push a branch, including a fork author, controls its bytes. The CI post path is a
hardened trust boundary: a field-aware sanitizer (bracket-escape +
autolink defang for live-markdown fields, fence-guard for fencedtext, an
https-allowlist that rejects markdown-breaking characters for artifact URLs), rendered in
a token-lessrenderjob whose data-only artifact is posted by a separatepost
job — golden-gated against an injection corpus.
Docs
- Adopter kit: a minimally-invasive default plus opt-in tiers for repos that want to turn
enforcement up (docs/pr-receipts.md,docs/adopt/).