The recall you handled informally: about $2,700 for a bad date stamp, forty half-barrels, and an afternoon of phone calls. Mac and Wren on why the informal version usually works, the three reasons it worked that week (the beer was fine, fourteen accounts, caught it Thursday), and why "we handled it" is not a record. First Runnings: a call from a bar — "this keg tastes wrong." Mac drives forty minutes each way to find the beer is fine and the date stamp says February. The stamp had been guilty since Tuesday morning, when the date coder started printing half-dates and nobody stopped the line. Hot Side: the arithmetic, assumptions throughout. Assume 40 half-barrels in the run and 25 replaced at an assumed $95 a keg to produce: $2,375 of beer. Assume two people, six hours, $28 an hour fully loaded: $336 of apology-driving. About $2,700 — and the number is not the wholesale revenue, and it assumes every affected keg was found, which is the assumption that breaks. Mac's defense of the informal version (it worked; he showed up; two accounts ordered more), Wren's full concession — then her win: could he name, in one afternoon, every account that got that lot? He could not. That is not a record. That is a memory. Ask BrewBuddy (real question, real account, whatever it says is what you hear): "Which customers received lot 260824-0914?" — landed 2026-09-25 on deploy 510eca62 (PR #810), attempt 1 of 3: lot 260824-0914 (Alma De La Tierra), 16 real customers. Per Jacob's explicit order, 15 customer names are anonymized with fictional stand-ins on air (Playground Brewery Taproom kept real); verbatim record in capture.json/answer.txt. Dry Hops: the code date is only useful if it's on the paperwork as well as the keg — put the lot on the delivery paperwork, every stop. And call the account that didn't complain: the loud ones cost you an afternoon, the quiet ones cost you a customer. Last Call: take your last packaging run and try to list every account that got it. Time yourself. If you can't do it in an afternoon, the list doesn't exist yet. Cold Side is from FermentIQ — built by a brewer, fifteen years on the floor, no engineering background, who directed AI coding agents to build the ERP he couldn't buy. It runs the whole operation, grain to glass. The first thirty days are free and you can cancel anytime at ferment-iq.com. --- 2026-09-25 diagnostic + fix (post-retry): - Jacob confirmed via pgAdmin: sales_invoice_item_lots has 807 rows for org 11 — migration 447's backfill worked. Data side is proven. - Root cause of the retry failure: PR #807 added the table to _QUERYABLE_TABLES and documented the join in docs, but BrewBuddy's SQL-generator prompt was never taught the join. The live schema path gives the model bare columns with no join semantics, and the prompt's RULES still described the pre-447 world. The canonical join only lived in the fallback schema-ref doc and the migration comment — neither reaches the model on the live path. - Second defect: the prompt told the model to JOIN product_variants for finished-goods product names, but product_variants wasn't in _QUERYABLE_TABLES, so the validator killed the query. This is exactly what broke the retry's "lots shipped in 90 days" attempt. - Fix: PR #809 (https://github.com/FermentIQ/FermentIQ/pull/809) — adds a LOT TRACEABILITY rule to the query prompt with the canonical join (junction → sales_invoices → crm_customers, lot via finished_goods_inventory.lot_code, org scoped on junction), and adds product_variants + products to _QUERYABLE_TABLES. Tests: 37/37 + 46/46 green; new assertions fail pre-fix. Awaiting Jacob's merge + deploy. - Note: lot 260807-EA shows 524 cans still on hand — it may genuinely have no junction rows (never shipped). After the fix, BrewBuddy will answer that definitively instead of deflecting; use "lots shipped in last 90 days" to pick the episode lot. - Process note: first publish attempt (PR #808) was polluted by a stale work copy (mass revert) — closed immediately, branch deleted, workdir synced to current main, republished clean as #809. Lesson recorded in ~/AGENTS.md. --- 2026-09-25 second diagnostic (post-#809 capture): - #809 deployed and live (deploy dep-dar89udg1s2s73e1ff30 on merge commit c6a1ac4c), but the capture still deflected on all 3 attempts. - Root cause: two steering layers, #809 only fixed the second. The query_org_data TOOL DESCRIPTION is what the BrewBuddy agent reads when framing the `question` parameter — it said nothing about lot traceability, so the agent framed every lot question around sales_invoice_items / packaging_runs, and the SQL generator inherited that framing. The agent's expanded question never mentioned sales_invoice_item_lots. - Fix: PR #810 (https://github.com/FermentIQ/FermentIQ/pull/810) — documents the junction-table framing in the tool description + question param (with tables_hint), and adds a worked SELECT example to the prompt rule (the failed attempt-3 join was malformed). Tests 44/44 + 48/48 green; org-scoping and standards checks pass. Awaiting Jacob's merge + deploy, then capture retry #2.