20 May 2026 · 5 min read
Post #1Six commits on one Saturday
Not a line of code typed myself, all in production. Here's how.
Saturday May 16, 2026. Between 09:00 and 17:00 NL I pushed six production commits to my algo trading repo. All tested, all passed CI, all auto-deployed to Render. Not a single line of code typed myself.
That sounds like a marketing claim. It wasn't marketing. It was Saturday.
The six commits
For transparency, here's what the day was about:
Commit 1 (5e49fce3): factory pattern for IBKR account ID. Three scripts fixed, one new file ibkr_client_factory.py. Plus tests.
Commit 2 (b1da1112): fill sync lookback window. Removed 24h filter, replaced with 30-day maximum. Tests + constant definition.
Commit 3 (29471a0f): migration from ib.fills() to reqExecutions(ExecutionFilter). Plus SMART/AEB ticker mapping fix.
Commit 4 (ad2d92fe): diagnostic probe script probe_reqexecutions.py to test three time format variants.
Commit 5 (9d609b77): standalone sync_positions.py with IBKRClient method and 4× daily Render cron config.
Commit 6 (handover docs): two research documents committed, SYNC_FILLS_INVESTIGATION.md and SYNC_FILLS_INVESTIGATION_PART2.md.
Three code-changes, two infra-changes, one pure documentation commit. 506 tests green at end of day.
What I did do
I thought. Specifically: I formulated what the problem was. Before each commit there was a diagnosis phase where I tried to understand why something wasn't working. For commit 1 that was: "why does dashboard show zero while IBKR shows fourteen." Three hypotheses written down, one validated via Render Shell probe.
Then I wrote a prompt for Cursor. Not a one-line "fix the bug". A spec of one and a half pages with:
- What the problem is in my own words
- Which path I want followed (factory pattern instead of direct hardcode)
- Which files may be touched and which not
- Which tests minimally need to be added
- What I don't want to see (no defensive code that silently masked the IBKR account)
- Commit message format
Cursor implemented. I reviewed the diff. Sometimes accepted directly, sometimes had comments. On one point Cursor wanted to build in some overcomplex defensive code that would produce masking behavior. I rejected that and asked for a more specific implementation. Second iteration nailed it.
What my AI assistant did
Between Cursor and me sits another layer: Harry de hulp, my Claude-based sparring partner. Not to generate code, that's what Cursor is for. Harry helps me with:
Strategic decisions: for commit 5 (sync_positions) the question was whether we should run it as evening cron or 4× per day. Harry's analysis of possible race conditions with fill_sync helped me choose 4× per day, with clientId 12 preventing overlap with clientId 11.
Diagnostic-driven approach: at commit 4 (probe script) the choice was to first fetch raw data before building a fix. Harry pushed me toward that instead of trying yet another fix directly. Good he did, because otherwise I might have just rewritten commit 3 again without really understanding why it didn't work.
Pushback on risk-related actions: I'd been at my laptop 26 hours by Friday. Harry at one point specifically said: "Erik, this fix touches live trading state. Don't do it under fatigue. Wait until tomorrow." That helped me push commit 5 to Saturday instead of Friday evening.
The cognitive division
Three roles, three kinds of work:
Erik thinks: what's the problem, which path to follow, when to or not to implement, when to accept or reject.
Harry spars: builds no code, helps with strategic choices, forces me to write hypotheses before fixing, pushes back on risk-related actions under fatigue.
Cursor builds: reads my prompt, writes code, runs tests, commits, pushes. No strategic choices, only execution of a specific spec.
It works because none of the three takes too many tasks. Cursor isn't asked "what should I do", that question is already resolved as the prompt is written. Harry isn't asked to write code, that role is with Cursor. I'm not asked to type every line of code myself, because that's exactly what the whole setup is designed to prevent.
What's hard about this workflow
Honest check: this sounds clean, but in practice it's messy.
Cursor implements faster than I can review. For commit 1 I had a diff of 200 lines. Cursor had it done in two minutes. I needed fifteen minutes to understand each part and check whether it did what I meant. That asymmetry is structural. The faster AI builds, the more disciplined I need to review.
Sometimes Cursor wants to go too far. At commit 3 (reqExecutions migration) Cursor wanted to add a retry mechanism with exponential backoff alongside the migration. Not asked, possibly useful, but broadens the scope of the commit. I rejected that and kept it to what was in the spec.
Sometimes I'm too quick to approve. At commit 5 I should have reviewed the IBKR sync_positions_from_ibkr method earlier, before the cron config was added. By accepting both in one commit the reviewable unit became too big. Not broken, but a tactical lesson for next time.
The take-away
Typing no code sounds like marketing until you see what it actually requires. A spec specific enough that Cursor can't wander. A review discipline that doesn't collapse under speed. A sparring partner asking you to think before asking you to build. A set of rules and handover docs that make every session consistent.
Six commits on one Saturday isn't fast. It's the result of two years of built-up workflow. The system is faster than I could have been alone, not because AI is magic, but because the three roles reinforce each other without getting in each other's way.
Friday had blocked six commits on one bug because of the marathon. Saturday six commits got pushed. Not because I was better. Because the right person did the right work at the right time.