Projects · Jarvis

  • My current system for running AI coding agents, the successor to Omnigent, rebuilt from scratch after an audit of its first version
  • operating
  • Builder and operator
  • eight weeks, two codebases
  • 2026
  • one operator, three Mac Studios
  • Claude Code, OpenAI Codex, Python, React, TypeScript, Temporal, Postgres
  • 9 min read

Jarvis

My AI agents ignored rules written into their instructions, so I rebuilt the system to enforce those rules with automated checks before code merges.

What was on fire

Jarvis is the third harness I’ve built to run a fleet of coding agents. Omnigent taught me to let code move a card when the proof is already stored, and I shut it off on October 1, 2026. Jarvis v1 started on September 5 as a voice control plane for my own desk, with native Mac, iPhone, and Watch apps. Within three weeks it had become the factory itself.

Omnigent Jul 23 to Oct 1 code moves a card on stored proof: orchestration from 54% of tokens to 3% of spend Jarvis v1 Sep 5 to Oct 10 rules in the prompt: one class reached 271 methods Jarvis v2 Oct 10 on rules in the gate: 5 checks to 126 The babysitter Sep 21 on one agent session supervising from outside Aug 1 Sep 1 Oct 1 2026
Fig. 01 — Three harnesses in fourteen weeks. Each one moved the rules somewhere new: into code that moves cards on stored proof, into prompts that one class outgrew, into a gate that refuses the change. The babysitter, one agent session supervising from outside, has outlived two of them.

Fig. 01 · pinch or scroll to zoom · drag to pan

On October 10 an architecture audit of v1 found one repository class with 271 methods and 226 modules importing it. Files naming sqlite3 under the daemon had gone from 0 to 223. Swift gates took 19 minutes at the median, against 130 seconds for Python-only changes. A rule against classes like that had been in every agent’s brief since September 14, and nothing checked it. I reset the codebase that day.

“That audit really kind of also opened my eyes to needing to be smarter on how I’m building this out and not expecting that the agents are going to build things with best practices in mind.” The first chapter is how one class got there.

Constraint set

One operator, and I don’t read the PRs. “I am honestly not looking at any PRs.” I run the fleet from dashboards and reports, on a phone or a laptop. That’s a choice, and the 271-method class is what it cost. “I definitely take ownership of not looking at all the PRs or quite frankly, any of the PRs that led up to that.”

What I watch instead is the flow. “What I feel like I am is kind of like a head chef at a Michelin Star restaurant that has like 20 sous chefs.” My version of tasting the plate is the dashboards: where work is piling up, and whether the machines, the model seats, and the queue are all busy. Since that audit, anything I’d have caught by reading a diff becomes a rule the gate checks. Across both codebases the fleet has merged 4,884 PRs since September 5.

Subscriptions, not metered API: about $2,400 a month in seats today, which I plan to cut once the build-out settles. Hardware so far is close to $8,000, most of it three Mac Studios. Claude Code on Opus 5.5 builds and Codex on gpt-6.1-sol reviews, by rule since October 27.

v2 also had to run for someone other than me. v1 was “something clean, polished that I would personally use on a day-to-day.” A thin web client over an API tier can be swapped out, and “not everybody’s got a Mac.”

System diagram

On October 29 the fleet runs on five machines and one supervising agent.

OWNER phone or laptop; reads dashboards and the board BABYSITTER one agent session and its sub-agents; runs the pipeline for now CONTROLLER a Mac mini: dispatch, QA control, the landing train; no tests, no builds BUILD POOL three Mac Studios: Claude builder lanes, Codex review lanes, QA gates, by load SHARED INFRA a Linux box: Temporal, Postgres for dev and CI GITHUB a product repo and a pipeline repo; one lander, one train gate onto main AWS CELL, PLANNED k3s on EC2, Aurora Postgres, Terraform; no Terraform on main yet
Fig. 02 — Jarvis v2 on October 29, 2026. The controller only coordinates. The three Studios are one pool, and work lands on main through one lander. The babysitter still runs the pipeline, and the AWS cell is a plan, not a deployment.

Fig. 02 · pinch or scroll to zoom · drag to pan

The web app is React over a Python API tier. Every screen from v1 runs in it on fake data while the back end arrives one domain at a time, and every port in the daemon ships a fake plus one contract suite that runs against both fake and real. The pipeline that builds Jarvis lives in its own repository. It’s being rebuilt as Jarvis’s own code, behind switches that default off.

Architecture decisions

Each decision below is a belief that broke. “Once you set a good pattern, like you should make it deterministic so that that part doesn’t shift anymore, and then you work on something else.” Four chapters take the turns one at a time: the audit, the reset, the gate, and the layout. Chapters on the native start, the babysitter, review, and throughput are still to come.

  1. Web only, thin client. I built v1 native because I’d never built a Mac or iPhone app and wanted a polished tool for my own desk. Xcode turned that into the fleet’s constraint. A clean build of the apps took 413 seconds, and 65 to 68% of Swift PRs touched one shared module, so most of them rebuilt every app. On October 12 I dropped the Apple apps for one React app over a heavy Python tier. “It’s very fast for me to be able to make changes now.”
  2. Rules in the gate, not the prompt. In v1, “Prefer small modules” sat in every brief while one class grew from 15 methods to 271. v2’s gate fails any port with more than 10 methods and any database driver import outside an adapter, and neither check has an escape hatch. A review finding that recurs and can be linted becomes a check. A check for every rule my agents follow has the scar in full.
  3. One unit per file, registered by discovery. v1’s merge conflicts lived in a few large shared files. In v2 every unit gets its own file with its test and story beside it, and adding one never means editing a shared list.
  4. QA is a mechanical service. Since October 13 tests run as their own service with their own queue. No model picks the suites. The planner reads its playbook from the PR’s base commit, “so a PR cannot change what runs on itself.”
  5. One path to main. Two PRs that each pass their gate can break main together. Work lands through one lander that checks the merged tree under a lock. Omnigent had that, v1’s scripts dropped it, and v2 launched without it. Landing only the tree the gate tested is that story.
  6. The system that saw the outcome writes the status. An agent’s report that it’s done is a claim. The merge script writes GitHub’s merge commit into the log, and the agent that asked for the merge doesn’t supply it. Status written by the system that saw the outcome has the cases.

Not again: don’t fill an empty queue with every cleanup card at once. On October 28 I did, and it jammed the line.

Recovery / operate path

When main goes red, all work stops, nothing builds on top of it, and the stop pauses work without throwing any away. That rule has held since October 17.

The jam is the operate path at its worst. On October 28 the ready queue ran dry, and I ordered the whole ratchet backlog at once: the cleanup cards that shrink the lists letting old code skip a new rule. “Ultimately, what that did was it created a giant bottleneck, and these ratchet rules were modifying the same types of files over and over and causing lots of conflicts.” Total merges stayed flat, but the merges that weren’t ratchet cleanup fell from 90 to 62 in a day, and open PRs peaked at 29. By the next afternoon two of the shared lists had been split into one file per card, 17 cards were on hold, and 12 PRs had been closed unmerged. The gate chapter has the numbers.

The constraint keeps moving, and I work it the way Goldratt says to. “You find the bottleneck and then you fix it and then you move to the next bottleneck.” First it was CPU for the tests and gates. “That’s why I bought all these Mac Studios to be able to resolve that problem.” Then “the bottlenecks moved” to merge conflicts, then to how cards come in. The controller and two more Studios arrived on October 26 and 27, and merges per hour went from 3.83 to 3.71 over matched 24-hour windows. The hardware didn’t move the number. The build capacity note has why I bought it anyway.

On October 29 two of the Studios sat idle on purpose. A work-in-progress limit held new lanes while more than 6 reviewed PRs waited to land. The agent running the pipeline put it in Goldratt’s terms: “the constraint has moved from card supply to landing, and the right step is to speed up landing, not to start more lanes.”

The babysitter is the piece I haven’t retired: one agent session that supervises the builders from outside the system. It took over shipping in v1 on September 26, and on October 29 it still runs the pipeline. I meant it as a stop gap. Every lesson it learns goes onto a bake list for Jarvis to absorb, and since October 17 a new entry that doesn’t name the check enforcing it fails the pipeline’s own gate.

Lanes and card linting are designed and filed, not running. In progress, as of October 29:

  • Area lanes, so UI, back end, pipeline, and ratchet work each move with their own cap. Today the single ratchet lane is a hold on 17 cards.
  • Card linting for categories, estimates, and the need a card traces to. A lint on dependencies and components has run since October 17.
  • The model routing table, logging what it would choose beside what ran.
  • Moving the pipeline into Jarvis, and retiring the babysitter with it.
  • Cheaper builders for routine work once the pipeline holds.
  • Hosting on AWS, which is a plan with no Terraform on main.

And I don’t use v2 every day yet. I “still don’t have … really anything that’s running in V2 that I can use on a day-to-day basis.” What runs every day is the fleet building it. This page will say when that changes.

What changed after

v1 froze on October 10 and v2 started the same afternoon, in the same repository. Here’s how they compare.

Measure v1 v2 When
Median source file 236 lines 70 lines Oct 9, then Oct 28
Files over 500 lines 765 of 3,560 96 of 4,019 Oct 9, then Oct 28
Tests beside their code 0.1% 67.4% Oct 9, then Oct 28
Review rounds per merged PR 2.5 1.53 v1 at its freeze; v2 to Oct 26
First review passes 45.4% 83.4% same
Conflicted syncs per 100 merges 33.1 25.5 each era’s last 7 days
Merges per hour, whole era 4.38 4.15 Sep 11 to Oct 10; Oct 10 to 28

The review rows aren’t measured the same way: v1’s come from its own scorecard, v2’s from the review files. The last row is the one that matters most to me, and v2 is behind on it.

By week, v2 merged 11.2 PRs an hour across its first 33 hours, mostly UI cards with no dependencies. Then 4.8, then 2.5, then 3.2 for the week to October 29. The last 24 hours ran at 3.7. I want “a consistent 10 PRs that are being merged per hour.” The checks went from 5 to 126 over the same 19 days. They made the fleet more reliable. They haven’t made it faster.

“It’s a painful process, but I think ultimately what’s being built is a robust solution that is the right way to do it.”

Anonymization notes

The repositories are private. Every number comes from git, GitHub’s PR data, or the pipeline’s own records, read on October 28 and 29, 2026, and the chapters say which. Merges per hour are GitHub PR merges by merge time, in UTC, and each one names its window. The quotes are mine, from an interview on October 29, 2026, except where the text credits an agent or a document. Withheld: account names and labels, host names, card titles, and session transcripts. Costs are what I pay, in subscriptions and hardware, never per account.

Who this is for

Every failure on this page needs more than one agent to happen: two green PRs breaking main together, sixteen ready cards waiting on one list, a class whose size no single change owned.

  • A team running more agents than anyone can watch.
  • A fleet that merges fast and breaks main.
  • Rules in the prompt that the agents keep skipping.
  • A rewrite that’s about to throw away what the last system learned.

Chapters, in order

More projects

Start

Tell me what’s stuck

I’ll tell you in about a day whether I’m the right person. The first conversation is fit, not a free architecture review.