683 commits since April, and the project I am quietly building when nobody is watching.
What it is
JARVIS sits between me and macOS. I talk or type at it, and it does the thing: reads and writes files, runs commands, searches a codebase, manages tasks, drives a browser. 31 registered tools, all on my own hardware.
A chat window hands you a paragraph and leaves the work on your side of the screen. This closes that last inch: the thing that decides is also the thing that does it. The whole engineering problem is what you owe a system once it can act.
Why it is shaped like a brain
I started in neuroscience before I switched to business, and JARVIS is the question I never stopped asking: what does it take to run a day the way a mind runs one. Perception, memory, judgment, a decision, then a hand that moves.
That is not a metaphor bolted on afterward, it is the file tree. The tools live under
limbs. Recall is a semantic index rather than a lookup table. Naming the parts after
what they model keeps the design honest about what is missing, because a region with
nothing in it is obvious in a way an empty module is not.
Two decisions make it survivable.
Every tool call goes through one place. No route exists by which a model's output becomes an effect on my machine without passing the same permission check. It costs more work to add a tool, and it buys this: a thirty-second tool does not add a thirty-second way to get it wrong.
It can answer questions about itself. A semantic index of its own source in LanceDB with a filtered AST dependency graph beside it, so what breaks if I change this function is a lookup rather than a search. That stopped being optional around forty thousand lines, where the codebase outgrew what I could hold in my head.
111,000 lines, 683 commits, five months. 40,177 of those lines are tests against 53,566 lines of Python. That ratio was not a goal. It is what happens when requirements come first.
Where this is going
The desktop is the ground floor. What I am building toward owns the tedious half of operating a computer, reaching whatever application I already use instead of asking me to move into a new one, and following me onto the other machines in the house.
Phases 1 and 2 are built and green. Sandboxed execution, a Rust control plane that owns authority instead of borrowing it, more than one device, eventually a model tuned on my own logged interactions: all designed and not built. No tier of autonomy unlocks because it would be convenient. It unlocks when the tier below has earned it, which is why the capabilities that would demo best are the ones still on paper.
Alignment is not a feature you add. It is a character that develops.
The requirements database
Every behaviour has an id. REQ-001 through REQ-721, 627 unique, in a queryable database rather than a document.
That sounds like overhead until you have 111,000 lines and a model writing a meaningful fraction of them. Then it is the only thing between you and a codebase nobody can reason about. A requirement traces to the tests covering it and the code implementing it, a change that breaks one fails against the requirement rather than an assertion somebody wrote once, and is this built? has an answer that is not a guess.
The Cave Test
2,113 passed, 0 failed, against 2,122 collected, with one test hardware-gated and deselected. A number with a denominator and a failure count is a claim someone can check, which is why it is written that way. It also had to be rescued before it meant anything.
Before opening the next phase I audited the whole build. It came back no-go, not because features were missing, but because the instruments were broken.
pytest had never once finished on that machine: the suite armed the real hardware key
and the real lockdown routine, so it killed its own runner partway through and wrote to
the live vault on the way out. The build audit was scanning the wrong file. A security log
was being swallowed. Results depended on the order tests happened to run in.
None of the green numbers meant anything. A whole phase went on repairing the measuring equipment, and the first genuinely complete run in the project's history came out of it.
Then the certification, named after the obvious line:
I built the Mark I in a cave. If he bricks himself because the router blinks, the foundation is glass.
Pull the network mid-operation, while I watch. Say so out loud. Keep answering from the local model. Attempt zero cloud calls while severed. Notice when it comes back. Do not crash.
Run one. The spine passed with room to spare, and every clause a human would actually notice failed. A hung socket left a progress card cheerfully narrating a corpse for two minutes and thirty-eight seconds.
Run two. Three of four clauses passed. Both failures were in what it said rather than what it did, and one justified the whole exercise: the honest offline refusal, written in its own voice, was recorded to conversation history as an ordinary answer. Three minutes later, back online, the model read its own past refusal as a present fact and carried on insisting it was offline.
A refusal written in the agent's own voice becomes the agent's belief, unless something marks it as temporary.
Run three. Those closed, and a new one opened. With the network cut, three
conversations died in about a millisecond each. Local inference takes seconds, so that was
a short circuit rather than an answer: the fallback selector asked does the registry
contain any tools when it meant does this turn need one. The registry always holds one,
so the local lane was unreachable, offline and online both. Two further breakages sat
behind it, ready to turn the one-line fix into a crash, and git blame put the first two
months earlier, predating the entire repair campaign.
Three breakages stacked on one path is what a lane no live turn has ever taken looks like from the outside. A green unit suite proves nothing about a path whose first real traversal is the live test.
Certification is open. Across three runs the spine has never failed, and every run has turned something nobody could see into something with a fix. That is what the test is for.
The Docker decision
Phase 3 needed sandboxed execution for adversarial evaluation. Docker was the first approach, and it failed in a way you do not fix with a different container runtime.
The fix wasn't a different container engine; it was refusing to bet on any engine.
Betting the safety story on a runtime means inheriting that runtime's availability, platform quirks and failure modes on a machine I do not control. That is a dependency in exactly the place a security boundary cannot afford one, so Phase 3 is listed as designed, not done.
What does run is the adversarial evaluation: a local red-team model, DeepSeek-R1 under MLX, scoring outputs inside the reward matrix. No API call, no data leaving the machine. Sending outputs to a hosted model to be scored for safety makes the safety review itself a disclosure, which is the clearest case for local inference there is. Six of seven providers sit behind one interface, so no single one is load-bearing.
What makes the pace possible
111,000 lines in five months is not a typing speed. It is requirements before code, tests as the acceptance gate rather than a step after the fact, one model's output critiqued by another before it lands, and a dependency graph the system queries about itself.
This is the one project here you cannot read, because the repository is private and staying private. So every figure on this page is one I can re-run in front of you, and that practice is the part of this I would take to a team.