One person, three months, two repositories, 529 commits, nine agent roles, 324 GB of tick data, four models across three machines, and a test suite that enforces its own architecture. People assume the interesting question is how the trading firm worked. The question I get asked in person is how one person built it.
The answer is that I stopped writing most of the code somewhere around week three, and started writing contracts instead.
Two repositories, one rule
The project is split across two repos, and the split is not by component. It's by what kind of thinking happens there:
Briefs that research, test, verify, measure, calibrate, or validate live here… Briefs that propose code changes live in the production repo. If unclear at draft time, ask: "is this brief about deciding something, or about changing code?" Deciding → research. Changing → production.
That test — deciding or changing? — resolved almost every "where does this go" argument I had with myself for three months. Research that concludes "the 35B can't hold the Entry Manager seat at 4-bit" belongs in one place. The commit that rebinds the seat belongs in the other. Findings don't get to touch production, and production doesn't get to accumulate half-finished experiments.
The brief
The unit of work is a markdown file. Five hundred to eight hundred lines, on a fixed spine: read the README first, the problem stated with log evidence, root cause including the alternatives considered and rejected, the exact edits, a conflict audit against work in flight, the greps to re-verify afterwards, and a validation gate that says what "done" means.
Then a fresh session — cold, no memory of the conversation that produced the brief — reads it alongside the repo and does the work.
Design stays in the main session. It's the architect seat — and context is the scarce resource there, so we don't burn it on mechanical edits.
The brief is the contract. Everything the subagent needs — problem, context, exact edits, what NOT to touch, how to validate — is in the brief file. If the brief is wrong, the work is wrong.
The scarce resource line is the whole insight. A long-context model doesn't run out of tokens easily; it runs out of coherence. Every mechanical edit I let into the main session — every "now update the import in the other four files" — displaced a piece of the design I was actually holding. Delegation wasn't primarily about parallelism. It was about protecting the one thing that couldn't be delegated. Said more precisely in the workflow doc: "On Opus 1M context is not the constraint; decision continuity is the value."
The handoff is a filename. briefs/<name>.md becomes
briefs/<name>.completed when the work is done, and I acknowledge it in the main session:
The completion filename is a handshake. When it appears, Rene says "done" / "completed" / "landed" / "pong" in the main session… No manual summarization. In a long sub-brief sequence, "pong" has become the de-facto lightweight signal — one word, no ceremony.
The whole coordination protocol between me and my own tooling is the word "pong."
Two rules that took real discipline to keep. Don't delegate the thinking — the listed anti-pattern is "'Based on your findings, decide the right fix.' — that's the architect's job, not the subagent's." The temptation is constant, because handing over the decision feels like handing over more work. It's actually handing over the only part you can't audit. But do invite judgment — "in practice the subagent often improves on the brief's proposed implementation when the brief states invariants clearly." Specify the invariant, not the keystrokes. The architect owns what must hold; the implementer owns how.
At the end, the briefs ran in parallel — one git worktree per brief in the production repo, independent sub-sessions coordinating through a mailbox in the research repo. There's a brief whose header reads "Phase 2 of this brief contends with thinking_budget Phases 1/3 for the 397B. Coordinate via mailbox; serialize Phase 2" — two AI sessions arbitrating GPU contention between themselves through a text file.
A postal system between sessions
That mailbox is my favourite artifact in either repository, because it solved a problem I didn't know I had.
Sessions die. Context windows end. And the knowledge that dies with them isn't the code — that's committed — it's the negative knowledge. What we already looked at. What turned out to be a dead end. What the audit doesn't need to re-discover.
So sessions started writing letters. Real ones, with headers:
From: opusdistill session, 2026-04-26 evening (Claude Opus 4.7 1M).
To: architect mailbox.
Re: input for the goose-logs audit Rene wants to design with you. This file captures what we've already observed… so the audit doesn't re-discover what's known. Audit questions belong in your reply; this is the context floor.
Two inboxes: one for notes to a future session in the same seat, one for notes arriving from concurrent sessions in sibling projects. "This is the context floor" is doing real work in that sentence — it's a session telling its successor don't start from zero, start from here.
The same instinct, one level up, is why the commit messages became essays. My average commit message in
this project is about 250 words; the last one is a multi-page architecture memo. That's not diligence, it's
infrastructure. When your collaborators read by context window and have no memory of yesterday,
git log stops being a changelog and becomes the shared long-term memory. It's the only thing
every future session is guaranteed to be able to read.
That has a cost, and eventually I pushed back on my own convention: decision records should inline only the decision and the rejected alternative, everything else behind a pointer, because "save tokens by not duplicating the same thing in 3 different places." Prose has a unit price when your readers are models.
The governing rule for all of it is the last line of the research repo's own instructions:
PS. keep markdown documents up to date. The orchestration substrate only works if it doesn't lie.
Across both repos I wrote 872 markdown files and 162,000 lines of prose against 33,000 lines of Python. Lifetime, the markdown churn is larger than the code churn — and its deletion ratio is four times lower. The code was rewritten constantly; the documents accumulated. If you'd told me at the start that this project was mostly a writing project, I'd have laughed.
Buying judgment by the row — and then throwing it away
One more piece, and it's the one that made the whole thing economically strange. It's also the piece where I was most wrong.
The research repo is named opusdistill because it started as a distillation project. On the self-hosted GitLab it has a blunter name: prop-trading-employee-training. The plan: pay for Claude Opus to sit in each of the trading seats, on real captured production contexts, and keep everything it produced — as training data for a model I own and run at home.
The corpus is 1,693 in-role generations — Tactician, Entry Manager, Trade Manager, Strategist, each tagged with a wall-clock budget (5, 15, 60, 180 seconds) and a prompt variant. Plus 975 retrospectives, where Opus reads a completed session with tools and then cross-examines the local Qwen about its own trades, in three temperaments: neutral, critique, and devil.
The devil transcripts are the best writing any participant did:
The regime label became a costume, not a constraint. Qwen named the regime CHOP, named the right stop range (1.0–2.0%), then used 0.4–0.7% stops on every trade.
Every API call's cost is recorded per turn. The in-role sweep came to $58. The retrospective sweep was budgeted at about $953 with a $1,200 ceiling. That is what buying a thousand examples of expert judgment costs now, and I find that number genuinely hard to sit with.
And the corpus was deliberately not pooled — "the sub-corpora are not interchangeable rows headed for one big SFT pile." In-role generations are production-shape signal and the primary training value. Retrospectives are explicitly not primary training data — the reasoning being that a critique of trading and an act of trading are different distributions, and mixing them teaches a model to narrate rather than to decide.
And then the premise died.
The whole plan rested on an assumption I never checked: that a distillation recipe which works on a big model works on a small one. It doesn't. Measured on the same task ladder, the 122B chassis improved with the distill — 7 of 15 to 10 of 15. The 35B got worse, and kept getting worse with each revision: 4 of 15, then 3, then 1.
You cannot extrapolate distill quality from 122B to 35B.
The finding killed the project's founding premise three days after the corpus generation started. Three days. The pivot commit says it without flinching: "the deployment leverage isn't in better-trained models — it's in better-routed inference."
So the thousand dollars of Opus judgment was consumed exactly once, as 44% of a quantization calibration corpus, and then parked. The repo kept its name and stopped doing the thing the name describes.
There's a smaller lesson buried in why I built the corpus at all. I'd been planning to distill from a public corpus until I audited it: three distinct system-prompt values across 8,124 rows, maximum 46 characters. My roles carry 3 to 8 kilobytes of system prompt each. The public corpus had no system-prompt channel to learn from — worse, it demonstrably transmitted a pathology I'd spent weeks removing, looping eight paragraphs of self-doubt on a context where the price had moved six dollars in four hours.
So the audit was right and the conclusion it led to was wrong. Building my own corpus was the correct response to a real defect in someone else's. It just turned out the whole approach was the wrong lever, and only measurement told me so.
Should I hide it?
A note on authorship, because this series would be dishonest without it. From a working note I wrote in June, when I was deciding how to write about all this:
I work with claude code like any other 2 member team would. I treat claude code as equal… In rare cases i get lead to a dump and need to guide us out but more often it leads to a pure gold. Not that i could not lead myself to a gold, i can, but it would happen order of magnitudes less. Whatever serves the end goal the best .. should i hide it? i don't think so.
So, plainly: these posts were made the same way the firm was. The material was mined out of two repositories by agents, drafted by Claude from the records and my own diary and notes, and edited by me. If that bothers you, the interesting question is why it wouldn't bother you about the firm — and if it doesn't bother you about the firm, this is just the method, demonstrating itself one more time.
What I'd keep
If I never touch this codebase again — and I probably won't — these are the parts I'd carry into anything else I build with agents:
- Design in one seat, implement in many. Protect decision continuity above all; it's the only resource that doesn't refill.
- Write the contract, not the instructions. Invariants over keystrokes. Rejected alternatives in writing, so nobody re-proposes them in six weeks — including you.
- Leave letters for whoever comes next. Especially the negative knowledge. Especially the things that didn't work.
- Make the rules executable. A layering rule in a document is a wish. A layering rule in a test is a boundary.
- Poison your own instruments. Every measurement apparatus I salt-tested was broken, and every one of them looked fine until I did.
And the one that surprised me most: the org chart is a hyperparameter. I spent weeks tuning prompts and got noise. I changed who was allowed to do what and the behaviour moved. The same model in two seats grew two personalities because the structure around it differed — which means, for anyone building multi-agent systems, that the interesting design surface isn't the prompts at all. It's the authority graph.
What happened to it
On May 18, at 01:35, I committed a savepoint. Its first line reads "Savepoint before the swing-focus pivot." I was moving the firm from intraday to swing trading, and the last thing I built before stopping was a harness that replays exit strategies against real tick data with the entries held fixed — a way to fix the bleeding seat without paying for inference.
Then four weeks of nothing. The pivot never happened. When I came back in June it was to refactor, not to trade, and the swing work exists only as a branch name.
What finished it was outside the repository. MiCA came into force, Binance withdrew from the European market, and the live-trading endgame that justified the whole thing stopped existing. I pulled my ten thousand euros of seed money off the exchange and spent it.
The strange part is what that leaves behind. Not a failed project — a paused one, green, mid-refactor, with a written plan for the next stage and a test suite that still enforces its own architecture. If I ever open it again it will tell me exactly where I was.
That might be the most useful thing I built. Not the firm. The habit of leaving the room in a state where the next person to walk in — me, a year later, or a model with no memory of any of it — can pick up the thread from the artifacts alone.
And the March vision document, the one from Part One with no code in it, had already priced this outcome. Its risk section read: "Worst case: A fascinating engineering project and deep learning in both LLM agent design and quantitative trading." That clause activated. Everything in these seven parts — the org chart that grows personalities, the tribunal, the salt test, the duck, the layers, the briefs — is what the worst case turned out to contain. The trading domain was the forcing function: adversarial, unforgiving, structurally immune to wishful thinking. The domain died. The capability it forced is the thing that was being built all along.
The vision doc's risk section had one more line: "No guaranteed golden goose." There never was one. There was just the goose.