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.
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.
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.
- 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.”
- 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.
- 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.
- 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.”
- 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.
- 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
One class, 16 days, 186 agent PRs, and the prompt rule against it that nothing enforced
Claude Code, OpenAI Codex, Python, SQLite
Scar · Oct 2026
1.53 million lines deleted, the old screens kept, and three lessons the rewrite had to learn again
Claude Code, OpenAI Codex, Python, React
Rewrite · Oct 2026
Rules moved from prompts into checks, exemption lists for old code, and a cleanup rush that cut other merges 31% for a day
Claude Code, OpenAI Codex, Python, TypeScript, ESLint, import-linter
Mechanism · Oct 2026
One file per piece of code with its test beside it, median file 236 lines to 70, and merge conflicts per merge down 23%
Python, React, TypeScript, Storybook, Git
Layout · Oct 2026
More projects
Start
I’ll tell you in about a day whether I’m the right person. The first conversation is fit, not a free architecture review.