Loop INV-2 · Inventory & purchasing · reports to Lerris (+ migration team)

Teaching the ERP how long things take to arrive.

A goal-loop that studies our own purchase history and proposes supplier lead times and reorder points, 50 items at a time, as evidence-backed spreadsheets for Lerris to approve — the homework the Odoo migration needs done anyway.

Built & tested — pilotWave 3🕐 Goal-runs, batch of 50⚙️ Claude goal-loop + Codex
Part 1 — the plain-english view

From 9% lead-time coverage to full — one approved batch at a time.

What it watches
  • Items ranked by usage value, 50 per batch
  • For each: order-to-order intervals from our own purchase history, preferred vendor from recent POs, demand variability from work/sales orders
  • Coverage: % of active items with an approved lead time and reorder point
When & how it speaks

Each batch lands as a review spreadsheet — proposal + evidence per item, with approve/reject columns. Approved values go into Odoo during migration data-prep, not into the dying ERP.

Why it exists

Only 9% of items had a supplier lead time on record and 0% had reorder points — so the ERP cannot warn anyone before we run out. A key design ruling is encoded: demand counts outflow only (sales + work orders); incoming purchases don't inflate it.

57.7%
lead-time coverage of relevant items after deriving from PO history — 993 still missing
50
items per batch, cumulative burn-down — approved items never come back around
2
loops unlocked by this one's data: reorder-risk (INV-3) and honest MRP in Odoo
🎯

Goal set

“All 50 items have a proposal + evidence”

👀

Studies history

PO intervals, vendors, demand variability

🧮

Derives values

Lead time, reorder point, safety stock per item

📋

Builds the spreadsheet

Proposal + evidence + approve column

Lerris approves

Approved values go to Odoo via the migration team

What it will never doNever writes settings into the ERP itself — approved values enter Odoo through the migration data-prep, on human hands.
Where it stands today · July 2026Built and tested: first 50-item CSV produced with approve/reject columns; the planning fields now flow into the warehouse nightly after the data extension. Coverage math verified; the cumulative burn-down means each run proposes the next unapproved batch.
Part 2 — under the hood

How it's wired: systems, models, and the path a number takes.

For implementers and the technically curious. The full build sheet — verified queries, thresholds, and build notes — lives on the specs page.

ReadsNetSuite warehouse
PO history, item planning fields, demand lines
Stepinv2_mrp.py
Derivations: intervals → lead time; outflow-only demand rate
StateBurn-down state
Which items are proposed/approved — batches never repeat
DeliversReview spreadsheet
50 rows, evidence attached, approve/reject columns
Human gateLerris + consultant
Sanity-check and approve per batch
StepOdoo data-prep
Approved values loaded during migration — by people
System we read Automated step State / memory Human decision
SystemRole in this loop
NetSuite warehousePostgres on our serverOur nightly read-only copy of NetSuite (ERP) data — items, stock, transactions — refreshed by the ETL sync every morning. The loop queries this copy, never NetSuite itself.
ETL extensionraw planning fieldsThe data connection built for this loop: item planning fields and preferred vendors now sync nightly into the warehouse — the same extension that unlocked the receivables watchdog.
Metabasebi.huxapps.comThe BI layer over the warehouse. The loop runs its SQL through Metabase's API, and every number in the digest links to a live, clickable Metabase list so you can drill into the exact records.
Email renderer + gwsrender_email.pyAll digests pass through one shared renderer: Huxberry-branded HTML, tables for repeated rows, a coral 'needs your response' box when the loop has questions, and an arrow link on every record. Sent from the loops mailbox via the Google Workspace CLI.
Loop chassisloop_common.pyShared plumbing every loop reuses instead of reinventing: state files, run-over-run diffing, Metabase drill-down link building, quiet-on-green notify logic.
Model / brainWhat it does here
GPT-5.5 via Codexthe bulk-work modelWrote and maintains the mechanical parts — SQL, diffing, digest assembly. Effectively free on our existing subscription, so routine cycles cost almost nothing.
Claude Opusthe judgment modelReviews alert wording, thresholds, and anything a human will read and act on. Post-Fable, Opus owns everything that ships.
Claude Fablethe designer (retired)Designed this loop's spec and encoded the judgment as thresholds and checklists before its retirement on 8 July 2026 — so cheaper models can run it without Fable-level reasoning.
State & memory

A cumulative burn-down ledger: proposed and approved items are excluded from future batches. Note for operators: even a dry-run reads this state — use a scratch copy to reproduce batch 1.

Delivery

A spreadsheet per batch (emailed, attached), plus a coverage line: % of active items with proposed + approved values.

Safety rails

Proposals only — a wrong reorder point costs real money, so Opus sanity-judges every batch before it's sent, and a human approves every value.

Before it can run for real
  • Lerris's sign-off pattern on the first batches (the CSV sanity check is an open question with him)
Full build sheet →