Back to projects & research

TTB Label Checker: the model reads, code judges

Built a label compliance checker where GPT-4o vision only transcribes the label and a tested TypeScript rules engine makes every pass, fail, or needs-review decision.

Year

2026

My role

Sole designer and developer.

Tools & technologies

Next.js · TypeScript · GPT-4o vision · Vitest · Tailwind CSS

Outcome

Deployed on Vercel with sample labels for every failure mode. The rules engine has 44 unit tests (69 across the project), and batch results stream into the table as each label completes, at roughly $0.01 per label.

The problem

Alcohol labels have to carry every mandatory TTB field and the government warning word for word. Reviewers check batches of 200 to 300 labels, need a verdict in about five seconds each, and are not necessarily technical.

What I built and owned

The model reads; code judges

GPT-4o vision transcribes brand name, class and type, ABV, net contents, and the government warning with its capitalization preserved, under a strict JSON schema. Every decision is made by pure TypeScript rule functions with no I/O and no network calls, so a given set of extracted fields always produces the same verdict.

No form to fill out

The warning text is fixed by 27 CFR 16.21, and the presence and format of the other fields can be checked from the label alone. The default flow is to drop an image and get a verdict. Expected values are optional: a short form for one label, or a CSV keyed on filename for a batch.

A false fail costs more than a review

A check either fails reliably or does not hard-fail at all. Bold type cannot be judged reliably from a photograph, so a warning header that appears not to be bold goes to needs review rather than failing. Brand names are normalized for case, punctuation, and possessives, and near misses also go to a person.

Batches handled in the browser

Each label is its own request. The browser downscales images to 1,500 pixels on the longest edge, runs a pool of five concurrent uploads, and fills the results table as each verdict returns, which keeps every request under the hosting body limit.

Built to move inside an agency boundary

Extraction sits behind an ExtractionProvider interface, so running GPT-4o inside an existing Azure tenant is a one-file change that leaves the rules engine untouched. The README lists what production adds (authentication, durable rate limiting, audit logging, and a retention review) and records the prototype trade-offs accepted after a security review.

Screenshots

TTB Label Checker: drop zone, built-in sample buttons, and streaming batch results
Drop zone, sample labels, and batch results streaming in.
Batch results with an expanded failure: label image beside the per-check verdict
An expanded failure with the label beside each check's verdict.

Explore the work

Try the TTB Label Checker (opens in a new tab)TTB Label Checker source (opens in a new tab)
Back to profileNext: Widedoor: Section 508 and WCAG 2.1 AA checker