Nick Webb from London, United Kingdom · CC BY 2.0 · Wikimedia Commons
cull-audit · public demo study
A local-first verification harness for records from AI photo-culling pipelines: bring JSON/JSONL judgments and it writes a flip table, repeat-stability classes, and cost evidence to audit.json and report.md. The study below audits one 67-call reference run on an openly licensed photo set — an example produced with the optional runner.
01 / premise
AI culling pipelines often expose scores and rankings that invite more confidence than a single read warrants. cull-audit asks a narrower, answerable question: what do the records actually say — and what happens when the same question is asked again, alone and at higher resolution?
It audits what a culler's records say about stage disagreement, repeat stability, and cost. It never claims human ground truth.
Follow the receipts ↓Scroll horizontally to see the full diagram ↗
02 / protocol
What this run found
77 openly licensed photos (Wikimedia Commons, CC BY 2.0) → nine contact sheets, up to nine photos each (triage reads, relative context) → 21 dedicated reads (1536 px, one photo each) → 21 face crops (enrichment) → 16 repeat reads (8 groups × 2, identical settings).
Scroll horizontally to see the full diagram ↗
The set, and why it is this one
The demo runs on one coherent, openly licensed event set — fixed and licensed before any model touched a frame.
Every number on this page reproduces from the frozen artifacts in the repository: examples/open-demo/run-2026-10-03 (audit.json, report.md, RUN-NOTES.md).
03 / disagreement
The triage pass judges a photo inside a contact sheet; the dedicated pass reads each finalist alone, at higher resolution. Of the 21 paired finalists (all triage accepts), 6 flipped — every one downward: 2 accept→reject, 4 accept→maybe; 15 stayed accept. The other 56 photos had no dedicated comparison. This run shows the disagreement; it does not isolate whether sheet context, resolution, or other stage differences caused any single change.
These six cards are every flip among the 21 paired photos — the complete set of verdict changes, nothing curated out.
What the triage pass saw
Relative reads happen inside sheets like this one: nine frames judged together in a single call — sheet 7 of 9. Two of this sheet's frames flipped downward when read alone, marked below; whether the neighbours caused the change is not something this run isolates.
Tiles are hotlinked Wikimedia Commons thumbnails; each links to its source page. Photographs: Nick Webb, CC BY 2.0.
The six flips, with the actual photographs — scores are composites (0–100):
Nick Webb from London, United Kingdom · CC BY 2.0 · Wikimedia Commons
Nick Webb from London, United Kingdom · CC BY 2.0 · Wikimedia Commons
Nick Webb from London, United Kingdom · CC BY 2.0 · Wikimedia Commons
Nick Webb from London, United Kingdom · CC BY 2.0 · Wikimedia Commons
Nick Webb from London, United Kingdom · CC BY 2.0 · Wikimedia Commons
Nick Webb from London, United Kingdom · CC BY 2.0 · Wikimedia Commons
04 / repeatability
The top eight finalists were read twice under identical settings. All eight came back robust: identical verdicts, composite spread within the v1 threshold (mostly 0; one spread of 3). A verdict that survives a re-read is evidence; a rank position is not.
two reads per selected photo · identical verdicts · composite spread ≤ 5 under v1
This tests only these two configured repeats for these eight photos — not ranking stability, and not general model reliability.
05 / accounting
Estimated across 67 calls: $0.273687 from a pinned price table (documented in the repository). 67 records carry usage for 67 calls; the other 68 records — triage siblings sharing one billed call per sheet — have no separate bill. "Known $0" means no known-price records, not free provider usage.
80,928 in · 18,559 out · 59,182 thinking
thinking-token counts may overlap output-token counts (per the frozen report's warnings)
Known / estimated / unknown stay separate. No guessed bills.
06 / method
Try the audit mechanics — keyless and image-free, on invented records:
git clone https://github.com/rmax-ai/cull-audit
cd cull-audit
uv venv && uv pip install -e .
python -m cull_audit demo --output tmp/demo This synthetic demo exercises the mechanics; it does not reproduce the 77-photo study.
Check the study — rerun the audit on the frozen judgments:
python -m cull_audit audit \
--judgments examples/open-demo/run-2026-10-03/judgments.json \
--baseline-stage triage --decisive-stage dedicated \
--prices examples/open-demo/price-table-gemini-3-flash-preview-2026-10.json \
--output tmp/audit-check --source-date-epoch 1791029022 Produces the same aggregates as the committed audit (6/21 flips, 8/8 robust, $0.273687). Byte-identical output means rerunning the audit on identical frozen inputs — not rerunning the live provider; the staged-workspace procedure is in RUN-NOTES. The optional reference runner (your own key, dry-run gate first) is how the study itself was produced.
07 / boundary
One licensed set, one model snapshot, one prompt configuration: these are demonstration receipts, not a benchmark. No claim of human ground truth; provider outputs drift; aesthetic judgment stays with people.
The audit is the point, and it is open to challenge: inspect the frozen audit.json and report.md, run the synthetic smoke test, or bring your own records and pressure-test the pairing rules, stability thresholds, and cost attribution.
Back to the protocol ↑