Every Monday: what moved in each business unit's pipeline last week — what advanced, what stalled, what was won and lost, and the five biggest moves narrated in plain language.
Monday morning: a short message per BU lead, plus (as the company feed rolls out) one card per business unit with a stacked pipeline chart.
Odoo keeps no history of aggregates — nobody can answer “is our pipeline growing?” The loop builds that memory itself, one weekly snapshot at a time. Baseline captured: AED 382M open pipeline across 635 deals — junk-inflated today, which is exactly why CRM-1 runs first.
Before the week's pipeline reviews
Every open deal, per team and stage
Appends this week's counts/values to its own history table
New, advanced, won, lost — per team
Numbers + the five biggest moves in plain words
For implementers and the technically curious. The full build sheet — verified queries, thresholds, and build notes — lives on the specs page.
| System | Role in this loop |
|---|---|
| Odoo 19 CRMread-only connection | The live CRM. The loop reads deals, activities and teams through a read-only connection — writes are technically impossible on this credential. |
| Postgres “loops” schemareporting database | A small dedicated schema where loops keep snapshots and history that need SQL (week-over-week diffs, mirrors for drill-down links). Scoped role; Metabase can read it for the clickable aggregate links. |
| Company feedfeed.huxapps.com | Target surface for the four sales-* cards (headline: open pipeline; tiles: WoW delta, won-this-week; stacked bar by stage). |
| Hermesagent runtime on our server | The scheduler that wakes the loop up. Each loop is a cron job under a Hermes profile; the planned bizops profile will host the business digests (IT loops run under vpsops). |
| Healthcheckshealthchecks.huxapps.com | The dead-man's switch. The loop pings it only after a clean run — if the loop dies or errors, the ping stops and Healthchecks raises the alarm independently. This is how 'never silent' is enforced by machinery, not promises. |
| Email renderer + gwsrender_email.py | All 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.py | Shared plumbing every loop reuses instead of reinventing: state files, run-over-run diffing, Metabase drill-down link building, quiet-on-green notify logic. |
| Model / brain | What it does here |
|---|---|
| None at run timedeterministic script | A normal cycle is a plain Python script — no AI tokens are spent unless a diagnosis or judgment step is actually needed. AI wrote the script; the script does the rounds. |
| GPT-5.5 via Codexthe bulk-work model | Wrote and maintains the mechanical parts — SQL, diffing, digest assembly. Effectively free on our existing subscription, so routine cycles cost almost nothing. |
| Claude Opusthe judgment model | Reviews alert wording, thresholds, and anything a human will read and act on. Post-Fable, Opus owns everything that ships. |
A weekly snapshot table (run date × team × stage × count × value) in the loops schema. Two snapshots minimum before the first WoW digest.
Monday email per BU lead; later one feed card per BU. Same numbers, same plain language on both surfaces.
Read-only. Reports team aggregates, not individuals. Won't publish its first digest until the underlying data has been cleaned enough to mean something.