Skip to main content
Case study

Jarvis

YEAR
2026
ROLE
Solo — architecture, build, operations
STACK
Python · MCP · Postgres (Supabase) · Streamlit · GitHub Actions · Claude + OpenAI
LINKS
—
▸ Results

The cockpit, as it runs today.

Captured from the live tool on October 5, 2026. Revenue, spend, profit and customer counts are blurred — the structure is the point. Tap any panel to read it full-size.

Jarvis is the marketing operating system I build and run for Sartoro, a custom-made menswear brand on Shopify — named, yes, after the assistant in Iron Man. When I first wrote it up in June it was a handful of adapters, a first dashboard and some markdown reports. Since then it has become the thing I open every morning: one warehouse, one dashboard, a memory, and a standing habit of checking its own numbers.

The problem

A brand's marketing data is scattered across channels — Meta Ads, Google Ads, Search Console, GA4, Shopify, and now ChatGPT Ads — and nobody, least of all the person paying for it, sees the whole picture at once. The simple questions are the hard ones: what did we spend across everything this week, which campaigns are working, which are bleeding, what should change — and are the numbers we're looking at even right?

That last question turned out to be the important one.

What it is now

Six sources land in one Postgres warehouse twice a day, through a cloud cron that needs no machine switched on: Meta Ads, Google Ads, GA4, Search Console, Shopify, and a read-only ChatGPT Ads channel. Shopify is the source of truth for orders. Everything else is read against it. The dashboard reads only from the warehouse, so a page never waits on a live ad-platform API.

The interface is eight workspaces, each built around a question rather than a data source:

  • Dashboard — business performance first, then goal pacing, then up to three signals that need a decision, then channels. Every KPI card opens to its formula, its delta, and 7/30/90-day views.
  • Data — platform → dimension tables (age, placement, country, keyword quality, ad copy) with export, a column picker and saved views.
  • P&L — monthly contribution with cost of goods taken from Shopify's per-item cost, not a flat percentage, and a what-if card for "what happens if I scale Meta 50% for 90 days?"
  • Growth — organic search, an SEO workspace, and content distribution.
  • Customers — the customer base rebuilt live from Shopify segments, an email view, and the support inbox that drafts its own replies.
  • Brain — what Jarvis knows and what it has learned (more below).
  • Reports — a Monday digest, a monthly pack, and a 13-week quarterly view, all sent without anyone asking.
  • Settings — connected apps, last load per source, and a daily data-quality gate.

Chat sits across all of it. Ask a question in plain English and it answers from the warehouse, with a schema card generated from the database itself so a new table can't silently go missing from what it knows.

Alerts that earn attention

Most dashboards fail the same way: too many alerts, so nobody reads any of them. Jarvis keeps a persistent alert ledger instead of firing and forgetting. Repeats are merged, an alert closes itself when the condition stops, and each one carries an estimated weekly impact. Seven anomaly checks (spend spikes and drops, CPM spikes, a campaign that stopped, a zero-conversion day, stale data) sit beside seven optimizer rules (zero conversions on real spend, low ROAS, high CPA, scale candidates, negative search terms, stuck learning, creative fatigue).

Each alert is scored for confidence. Muting one makes its rule less sensitive next time; low-confidence alerts are recorded but never pushed; the weekly digest is capped at five items. In a 45-day backtest, only three ratio anomalies fired, all at 0.91 confidence or higher. I can also set my own rules in plain words — "alert me if CAC goes above X" — and they're evaluated on every refresh.

The staging is still describe → recommend → act, and Jarvis stops at recommend. It never changes a budget. Every scaling recommendation shows the platform-reported figure next to what Shopify attributes by last click, because the truth is usually somewhere between the two, and a person should make that call.

A memory, not just a database

The Jarvis Brain page: counters for 43 knowledge notes, 99 experience notes, 0 of 0 lessons graded, 15 of 59 open alerts in memory, and 0 standing notes; tabs for Graph, Health, Ask the brain and Teach JARVIS; and a dark Obsidian-style graph of 143 notes and 442 links, coloured by kind — hubs, rules, channels, sources, metrics, decisions, playbooks, alerts and campaigns
The Brain: 143 notes and 442 links, the same vault I edit in Obsidian. Hand-written knowledge on one side, experience synced nightly from the warehouse on the other.

Numbers without context make every week look new. So Jarvis has a brain: a vault of linked notes. Some are written by hand — how the business works, what a rule is for, why a decision was made. The rest are generated every night from the warehouse, as read-only queries: signals, lessons, and a note for each campaign and channel. Chat recalls the relevant notes on every turn without an extra model call, and anything I tell it to remember becomes a standing note.

The "Lessons graded" counter still reads 0 / 0, and I've left it on the page on purpose. Grading what happened after a recommendation is the next loop to close.

The numbers were wrong — that was the point

Building a second source of truth is how you find out the first one was lying. Reconciling Jarvis against the reference dashboard the business already used surfaced bugs that no feature list would have:

  • The blended view was Google-only. Meta was never written at campaign grain, so every blended number — headline CAC, digests, alerts, chat — silently left out the bigger spender. CAC was understated by about 2×.
  • Thirty-seven days of Meta data had gone missing from an intermediate sheet. One page claimed Google was 100% of spend; Meta was actually 53%. The loader now reconciles every day against the warehouse and re-fetches only the days that disagree.
  • Google conversions were 17% low, because a one-day fetch missed conversions that report late. A rolling 14-day re-fetch made them exact.
  • Two days of Meta numbers were doubled by a primary-key mismatch, and a 10,000-row read cap had quietly produced 9,974 duplicate rows.

After the fixes, Jarvis matches the reference within 0.3% on total spend and 0.8% on ad revenue, with purchases exact. That reconciliation is the feature I'd defend first. A dashboard that is fast and wrong is worse than no dashboard.

How it's built

MCP-first: every source is wrapped as its own adapter, so the system stays composable and testable, and the ad platforms stay read-only. The ChatGPT Ads adapter refuses any HTTP verb but GET — which is why its conversions aren't in Jarvis yet: the only endpoint that reports them is a POST. Python, because the work is data analysis. Supabase Postgres for the warehouse, Streamlit for the interface, GitHub Actions for the twice-daily refresh — a seven-step run that migrates the schema, loads every source, gates on data quality, syncs alerts and sends a morning briefing.

It ships in small slices, each proven by a side-by-side demo case rather than a feature list — a 22-step build plan, every step done. The first steps weren't features at all. They were speed:

Before → after
Channels page, 30-day window41.8 s → 10.8 s
Database queries per Daily-page rerun26 → 0
Chat answering "hi"6.6 s → instant, no lookup
A dead network, surfaced to the user600 s+ → 10.8 s
Data lagonce a day → under 12 hours

By the numbers

Since the June write-up, measured from the repository:

June 2026October 2026
Commits74146 (36 merged pull requests)
Lines of Python~26k~50k
Test functions29683 (762 passing in CI)
Warehouse tables + views1 + 921 + 14
Dashboard pages1627, in 8 workspaces

Where it's going

Klaviyo is wired and waiting on a key; TikTok is still a scaffold. The bigger work is the loop the Brain page admits is open: grading each recommendation against what actually happened, so Jarvis learns which of its own advice to trust. The throughline hasn't changed — one place for everything an ecommerce brand's marketing touches, paid, organic, customers, replies, with a human still in the chair for the calls that carry risk.

It's an internal tool, written up here as craft. The full thinking lives in the marketing-engineering essays.


Related writing: A room of agents — on running multiple agents as a coordinated team with shared memory and handoff protocols.