On October 10, 2026, an architecture audit of Jarvis v1 found a class called RunnerStore with 271 methods in a 10,818-line file, and 226 modules importing it. It had been born on September 24 with 15. In 16 days, 186 PRs touched it. I didn’t read any of them.
What I believed
On September 14 a conventions file went into every brief an agent received: “Prefer small modules with one responsibility and explicit dependencies.” I believed a rule every agent reads is a rule every agent follows. In v1 I ran the fleet that way. “I was really spending a lot of time allowing the LLMs to manage things before and not having a lot of deterministic capabilities.”
Three days later I asked whether the code being generated for Jarvis was actually good. The agent’s answer that night was that it had “no evidence either way,” and it proposed auditing recent merges. No architecture audit ran until October 10. RunnerStore didn’t exist yet when I asked. It was born a week later and grew under the same blind spot.
What broke
RunnerStore was the card engine’s store, and every card that needed one more thing from it added one more method. It had 49 methods when the babysitter, the agent session that ran shipping from outside, took over on September 26. 222 of the 271 came after that. On September 27 alone the file took 75 commits from 29 PRs and gained 68 methods.
No single diff was unreasonable. Size is a property of the sum, and nothing owned the sum. By the freeze,
108 of the 271 methods wrote to more than one kind of record, and the proposed split was 18 repositories.
The database driver had spread the same way. Files under the daemon that named sqlite3 went
from 0 on September 13 to 223, with 578 except sqlite3 clauses across 178 files and 20
separate database files.
The audit named the cause in one line: “There is no import-linter, no tach, no ruff
banned-api/TID rule, and no layer or boundary test in the gate.” The agent that
had been running the fleet described the mechanism: “A 271-method ‘repository’ isn’t a repository. It’s
what you get when every card adds ‘one more method’ to the nearest object and nobody steps back.” Then its
own part: “I optimized for merge count and never put architecture rules in the gate.” v1’s best day,
October 8, merged 320 PRs.
Mine is simpler. “The idea that there was a repository class that had 271 methods in it is just insane to me. And 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 do now
I reset the codebase that day, and the next chapter covers what survived. The audit “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.” v2 starts from the patterns instead of hoping to arrive at them. “It’s obviously a lot easier to fix it from when you’re trying to build from scratch than try to retroactively go fix everything.”
Two checks answer RunnerStore directly. One fails any port in the daemon with more than 10 methods. The other fails any database driver import outside an adapter. Both list their escape hatch as “none.” The port check counts methods on interfaces, and counted the same way, RunnerStore was over the limit the night it was born. Every outside call in v2 goes through a port with a fake and one contract suite that runs against both fake and real.
“Now I’ve got a lot of mechanical capabilities that are built in that are forcing things to work the way that I want them to, such as linting that don’t get overlooked by an LLM.” Where the rules live is that gate, and what it costs.
What’s still open
Lint catches the shapes I’ve already seen. It doesn’t catch the next one. “If there is something that gets a little off track, then I think adding more linting rules is the right way to do it for right now. … But you’re right, I should be doing more comprehensive audits on a interval basis.” The audit that found RunnerStore ran once, 16 days in, and no audit is on a schedule yet. The prose rules carried over from v1 are still being converted into checks.
The same commit that wrote “Prefer small modules” also gave the fleet a rule a script did check, and that one held. A check for every rule my agents follow tells it from that side.
I don’t put a structural rule in a brief anymore without the check that fails it. The brief says what I want. The gate decides what ships.
How this was counted
The method count is every def and async def directly in the class body, parsed
with Python’s ast module at the last
commit of each day the file changed. The PR count is merges on v1’s main that touched the file. The
sqlite3 count is files under the daemon’s source tree that name it; the audit itself counted
222 under a slightly different rule. The quotes are mine from an interview on October 29, 2026, except
where the text credits the agent or the audit.
This project
This project, in order
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.