extraction · note · in motion
ExtractLab — a shot logbook and the recommender it has to earn
Espresso is a repeatability problem wearing a hobby costume. ExtractLab is the data system I built for it — a logbook first, and a recommender that only speaks when the numbers back it.
The loop
Every shot gets logged: bean, grind setting, dose in, yield out, shot time, first drip, how it tasted. The log lives in a D1 database behind a Cloudflare Worker, with my own records archived as plain YAML in a git repository — append-only, corrections as new records, the same habit an engineering logbook has. Several hundred shots in, the dataset is the asset: not any single pull, but the history a recommendation can be checked against.
A recommender that has to show its work
The grind recommender is rules and statistics, deliberately — no machine learning, nothing it can't explain. Its core is a weighted least-squares fit of shot time against grind setting, inverted to propose the setting that should hit the target time. The fit is only trusted when it earns trust: the slope has to have the physically correct sign, there have to be enough shots behind it, and the fit quality has to clear a threshold checked by backtesting. Below that bar it falls back to explainable priors — same bean, same roaster, similar roast — and says which one it used.
The guardrails are the interesting part. Confidence only ever moves down, never up. A good shot holds its setting — one bad pull doesn't send the grinder chasing noise. Channeling is treated as a puck-prep fault, not a grind signal. And every recommendation is written to a ledger and reconciled against the shot that actually follows, so the system's advice has a track record instead of a vibe.
Where it sits
Running in production for one user: me. That's the honest ceiling — it's a personal instrument in single-user alpha, not a product with validated multi-user behaviour. The operational side is where the aerospace habits show: numbered database migrations, a gated deploy that runs its test battery before anything ships and a smoke check after, and written post-mortems when something slips through. The recommender itself is in data-collection mode — calibration waits until the reconciliation ledger has earned it.