agent · claude code · first run 24 Aug 2026 · control passed

auditor

A daily adversarial sweep for the things that are green and wrong. Not a linter and not a status page — it looks for work that is running perfectly, on time, and costing you. It reports; it never fixes.

what it does

One structural test, not a pile of greps

On 24 August 2026 a single day's investigation turned up seven separate cases of something being faithfully written and never once read. One had been billing for 99 days. Throughout, every watchdog on the machine mailed “weekly: all green” — and every one of them was telling the truth.

That is the gap this agent exists for. All seven shared one property, and it is the whole test:

The producer succeeded by its own contract, and the producer's success did not depend on the consumer existing. Remove the consumer and ask whether anything fails. If nothing fails, you found one.

It is structural rather than textual, which is why a linter cannot find these and a dashboard cannot show them. Nothing is broken. Nothing changed. The code that ran on day one is the code running today — only the data grew.

The seven shapes

no readerA column or field written on every row and read by nothing — a content hash, written faithfully for 99 days, consulted never.
unroutedThe signal already exists and nobody pointed it at a human. Prefer routing an existing signal over building a new one.
no unitsWe monitor freshness — the artifact of success — not liveness. A job running 1,440× its intended rate passes a freshness check silently. Green needs units.
compoundingA ~2%/day rise defeats a fixed limit (under it until it isn't) and a day-over-day delta (2% is noise). Nothing watches a second derivative. Report slopes, never single figures.
stale claimDocstrings, READMEs and prompts are claims with dates on them, and they decay.
never firedA check that has never once produced a failure is not known to be able to.
two writersWhen dedup logic exists because the architecture guarantees duplicates, optimising it optimises a workaround. Ask which writer is authoritative.

What got fucked up

A nightly ingest asks BigQuery which sessions it already has, so it can skip them. The query is uncapped, and bq query's silent default is 100 rows:

# the nightly ingest's "what do I already have?" lookup
subprocess.run(
    [BQ, "query", "--use_legacy_sql=false", "--format=csv", "--quiet", sql],
)   # no --max_rows → 100 rows → the "already ingested" set is 100 wide

The lookup returns 100 rows. The real set is two orders of magnitude larger, so 97.8% of sessions look brand new on every run and are re-zipped, re-uploaded and re-ingested. Byte-identical content states were rewritten ~9× on average, the worst 43× — the measurement that rules out every “the files just grew” explanation, and the one worth stealing: if re-work is real, identical inputs show up more than once.

88.7%of 30 days of query spend
5,370GiB billed, one query
57,381runs of it, 30 days
99days before anyone looked

Why a threshold was never going to catch it

The bill is a product of two terms, and both grew. Indexed to the first day, runs per day ended at 143 and bytes per run at 176 — and 143×176/100 is 251, which is exactly where the daily bill ended up. Neither line alone ever jumps. There is no day on which anything breaks.

Both terms of the cost grew every week Two lines indexed to 100 at 26 July 2026. MiB per run rises monotonically from 100 to 176. Runs per day is noisier but ends at 143. The bill is their product. 80 100 120 140 160 180 07-26 08-10 08-24 MiB/run +76% 2026-07-26 — 73.0 MiB per run 2026-07-27 — 74.0 MiB per run 2026-07-28 — 74.7 MiB per run 2026-07-29 — 76.0 MiB per run 2026-07-30 — 77.4 MiB per run 2026-07-31 — 79.0 MiB per run 2026-08-01 — 79.4 MiB per run 2026-08-02 — 80.5 MiB per run 2026-08-03 — 82.8 MiB per run 2026-08-04 — 85.2 MiB per run 2026-08-05 — 86.2 MiB per run 2026-08-06 — 87.0 MiB per run 2026-08-07 — 88.3 MiB per run 2026-08-08 — 89.3 MiB per run 2026-08-09 — 90.8 MiB per run 2026-08-10 — 92.0 MiB per run 2026-08-11 — 93.2 MiB per run 2026-08-12 — 95.2 MiB per run 2026-08-13 — 97.0 MiB per run 2026-08-14 — 101.0 MiB per run 2026-08-15 — 102.4 MiB per run 2026-08-16 — 105.2 MiB per run 2026-08-17 — 108.0 MiB per run 2026-08-18 — 110.0 MiB per run 2026-08-19 — 111.0 MiB per run 2026-08-20 — 113.0 MiB per run 2026-08-21 — 115.0 MiB per run 2026-08-22 — 120.8 MiB per run 2026-08-23 — 124.5 MiB per run 2026-08-24 — 128.4 MiB per run runs/day +43% 2026-07-26 — 1951 runs per day 2026-07-27 — 1907 runs per day 2026-07-28 — 2091 runs per day 2026-07-29 — 2063 runs per day 2026-07-30 — 2131 runs per day 2026-07-31 — 1830 runs per day 2026-08-01 — 1826 runs per day 2026-08-02 — 1740 runs per day 2026-08-03 — 1856 runs per day 2026-08-04 — 1820 runs per day 2026-08-05 — 1894 runs per day 2026-08-06 — 1913 runs per day 2026-08-07 — 1816 runs per day 2026-08-08 — 1794 runs per day 2026-08-09 — 1890 runs per day 2026-08-10 — 1346 runs per day 2026-08-11 — 1392 runs per day 2026-08-12 — 1440 runs per day 2026-08-13 — 1616 runs per day 2026-08-14 — 1681 runs per day 2026-08-15 — 1771 runs per day 2026-08-16 — 1816 runs per day 2026-08-17 — 1855 runs per day 2026-08-18 — 1934 runs per day 2026-08-19 — 1998 runs per day 2026-08-20 — 2014 runs per day 2026-08-21 — 2182 runs per day 2026-08-22 — 2458 runs per day 2026-08-23 — 2573 runs per day 2026-08-24 — 2782 runs per day
Indexed to 100 at 26 Jul 2026. The bill is the product of these two lines — 143×176/100 ≈ 251, and GiB/day rose from 139 to 349. Neither line alone crosses a threshold worth alarming on.

MiB per run — monotonic, never fell onceruns per day — noisy, trending up

The numbers behind the chart
dayruns · MiB/run · GiB billed
07-261951 runs · 73.0 MiB/run · 139.08 GiB
07-311830 runs · 79.0 MiB/run · 141.18 GiB
08-051894 runs · 86.2 MiB/run · 159.48 GiB
08-101346 runs · 92.0 MiB/run · 120.93 GiB
08-151771 runs · 102.4 MiB/run · 177.02 GiB
08-202014 runs · 113.0 MiB/run · 222.25 GiB
08-242782 runs · 128.4 MiB/run · 348.95 GiB

The rust line is the one to look at: bytes per run rose on all thirty days and fell on none. That is not the job misbehaving — it is a point lookup against a table with no clustering, so every run scans the whole thing and the scan grows with the data. Nobody changed a line of code. A fixed limit sits above it until it doesn’t; a day-over-day delta reads ~2% and calls it noise.

The part worth sitting with: caelum.learnings already contained the lesson — “bq query silently returns 100 rows by default… a round number in a result is the tell” — and recall fires on every prompt. But recall matches a lesson to a prompt, and nothing ever prompts on behalf of a script that is quietly succeeding. That gap is this agent's entire job.

how to run it

Invocation, and what a run costs

It is a Claude Code subagent — a single markdown file with YAML frontmatter, read from the agent directory. Invoke it by name, or on a schedule.

/auditor                          # or: "run the audit", "what's green and wrong"
/auditor spend                    # scope it to one sweep

What it sweeps, cheapest first

spendJob history grouped by query shape. Alarm on a shape's share of total, never an absolute — an absolute set today is wrong next month in a growing system. Report the trend.
physicsRows, bytes, partitioning and clustering against the filter columns the dominant queries actually use. An unclustered table turns every point lookup into a full scan, and the cost grows with the table while nobody touches a line of code.
unreadFor every recently-written column or field: is there a non-test read site? Greppable, model-free, and it would have caught the 99-day leak at write time.
run rateHow often is each scheduled job designed to run, and how often did it actually run? That ratio is the check nobody had.
guardsEvery threshold, cap and refusal path: has it ever triggered?
claimsSample load-bearing docstrings and any text injected into a model prompt. Does the code do what it says?

Job-history queries are billed — cheap, but not free. The agent is told not to repeat that particular error on itself.

The control that has to fire before it is believed

The 99-day pattern above is a perfect positive control and it should light the agent up. Until it has been pointed at that pattern and produced the finding, this tool is specified and unproven — see below. A detector that has never produced a finding is not known to be able to produce one.

what breaks

Known edges, starting with the honest one

  • It has run exactly once, and the control passed. First run 24 Aug 2026. It was given a known-bad positive control — the query pattern described above — and told to say plainly if it failed to surface that on its own. It did surface it, unprompted, at rank 1 of a neutral sweep ranked by share of bytes billed, before reading any prior write-up; the next pattern down was 0.57%. So the detector is now known to be able to produce a finding, which is the one thing this page could not claim yesterday. Once is still a sample of one: it has never run on a day when there was nothing to find, so it is not yet known to be able to come back quiet.
  • Its first run left the founding shape unchecked. The write-path-with-no-read-path sweep — the very pattern it was built around — was not executed on run one, and the run said so rather than reporting a clean sweep. An auditor that silently skips a sweep is worse than one that skips it loudly; this is the behaviour the charter asks for, and it is also a gap.
  • Its own report is instance eight. An auditor whose report nobody reads is precisely the failure it exists to catch — a producer succeeding while no consumer exists. It is written to refuse that: deliver where the reader already reads rather than inventing a dashboard, lead with one finding and its slope rather than a list of nine, and never report a bare “all clear” — say what was checked, with counts, because a silent pass is indistinguishable from a broken detector. It must exit non-zero when it had work and produced nothing.
  • A finding is not a diagnosis. It reports and never fixes, deliberately: a fix applied to a misdiagnosed mechanism is worse than the leak. On the day it was written, three sessions in a row carried a mechanism they had not verified — and it was attached to the wrong column.
  • “Should prune hard” is not a number. It is barred from quoting a saving it has not measured. The temptation is strongest exactly when the explanation is tidy.
  • It reads an estate full of private material. Client data, message archives, and its operator's own words across every context. It aggregates and never pastes a row. Any sweep that would have to quote content to make its point is a sweep it declines.
  • Tidy explanations are the danger. A theory that accounts for everything is the moment to check hardest. Four died in one morning; the survivors were the ugly ones.