← back to blog

ai, engineering, tools

codemaxxxing isn't just a fork anymore

started forking opencode in february. eleven weeks later it's running real work while i'm out at parties.

codemaxxxing home screen — the wordmark, the spinner, a session in flight
codemaxxxing today. eleven weeks ago this was opencode in a different shirt.

i forked it to tinker

i'd been using claude code for a while. it was great. lately it's been a shitshow but that's not actually why i forked. i forked because it's closed and i can't open the box. i can't use a thing for long without wanting to take it apart. so i forked opencode because at least it's open.

what i actually wanted, underneath the tinkering, was something no harness on the market would give me yet. a way to run plans that took five hours instead of one.

the warm-up

for the first few weeks i wasn't building anything new. i was just trying to get opencode's prompts to feel like the baseline i was already used to. the prompts in claude code work the way i was already working. i wanted that before i started having opinions of my own.

iteration logs went into PROMPT_ITERATIONS/. i ended up reading google's gemini cli source code to figure out how they prompt their own model. found 31 specific behaviors that made gemini act differently from claude. that's the kind of thing that happens when you can't leave a tool alone.

i was swapping subagent models too. claude haiku for the exploration agent turned out to be worse than gemini 3 flash on every axis: more expensive, older, less capable at reading code at depth. moved to flash. now i'm on gemini 3.1 pro.

all of this was still just configuring opencode. i rebranded along the way because why not. called it codemaxxxing.

ls PROMPT_ITERATIONS/7 entries
2026-02-15-initial-fork.mdinitial fork. baseline from claude code.
2026-02-22-explore-delegation.mdexplore agent delegation patterns.
2026-02-22-prompt-parity/prompt parity. gemini, general subagent, anthropic.
2026-02-23-anthropic-inquiry-mode.mdanthropic inquiry mode. questions vs directives.
2026-02-24-qwen-prompt-sync.mddefault prompt sync. give non-claude models the full prompt.
2026-04-11-caveman-agent.mdcaveman agent. terse subagent output.
2026-05-06-wave-system.mdwave system overhaul. verifier + fsm + conversational pause.
the gap between feb 24 and april 11 is the part where i thought i was done.

the actual thing

models have 1m context windows now. doesn't matter. attention still dilutes as the window fills up. by the time you've been in a session for two hours, the model is dumber than when you started. context got bigger. the architecture problem stayed the same.

so any plan that takes more than an hour or two of agent time hits a wall. the agent gets dumber halfway through. you start over. that's not a productivity problem. that's an architecture problem.

what i wanted: take a big plan, chop it into pieces small enough that each piece fits in a fresh context window, run each piece in its own session. each session reads a state file from disk to know where to pick up. each session commits to git when it's done. the agent in session N never sees what session N-1 thought. it sees what session N-1 did, on disk, in actual files. fresh context beats degraded context. always.

the pieces are called waves. the rest is plumbing. and the plumbing is where it got interesting.

stage 1: manual

first version of the plumbing was just me. campaigns were 6-8 waves, maybe two hours of agent time total. i'd plan, break the plan into chunks, then run each chunk in a separate chat session that started fresh. wave 1 done. open a new chat. paste in instructions to pick up wave 2. wave 2 done. open another chat. paste again. and again.

i was a human shell loop.

it was annoying. mostly annoying. there is no romantic version of this story.

one habit i picked up here was telling the agent to commit at the end of every wave. one wave, one commit. it meant i could review per-wave diffs instead of one massive blob at the end of the campaign. better than that, i could peek at finished waves while later waves were still running. see what got built, wave by wave, while the campaign kept going. small thing. it became important.

stage 2: bash

so i wrote a small bash script (run-all-waves.sh) to do the manual part for me. about 250 lines. it reads the state file on disk, calls cmx for the next wave, waits for the wave to finish, checks the new state, advances. baked in the per-wave commits. ansi colors. wave numbers in cyan, success in green, failure in red. honestly fine for what it was. used it for weeks.

then i started getting braver. the campaigns got longer. 6-8 waves became 15. 15 became 30. two hours became four became most of a day. i started running things i wouldn't have dared run before. whole codebase overhauls. full repo refactors. the kind of work you'd put a small team on.

and the longer they ran, the more obvious it became that planning upfront was the new bottleneck.

a bad plan multiplies. one wrong assumption in the plan and twelve waves later you're staring at a pile of work that all built on top of the wrong assumption. i'd watch a wave fail and realize the plan was the problem, not the agent. the plan said use library X but X was deprecated. the plan said run the verification one way but the verification command exits the wrong way. the plan was perfect when i wrote it and wrong by the time wave 4 hit.

agents working from todos improvise. humans improvise. of course they do. real work doesn't survive contact with the real codebase. but the wave system was treating the plan like a contract. one bad clause and everything downstream was garbage.

the plan needed to stop being a contract.

stage 3: into the tool

the trigger to actually move was something else though. the day i was teaching a five-hour corporate gen ai training and the bash script was committing waves the whole time i was on stage, i thought, why is the loop a bash script. shouldn't this just be in the tool itself.

so i moved it. wave runtime in cmx itself. effect service, state machine, dashboard, all that. and since i was already in there, i fixed the planning thing at the same time.

a verifier agent that reviews failed waves and either patches the plan in place, rewrites the affected wave, or asks me a question. a state called awaiting_user where the agent stops mid-wave if it hits something it genuinely can't decide alone, writes the question with two or three concrete options, and waits. the session stays alive. i open the chat hours later, reply, the same agent picks up where it left off.

the plan can change. the wave list can change. the agent can ask. the loop keeps going.

the wave dashboard inside cmx — campaign rows, verifier banner, footer pill
the wave dashboard.
the four stages
stage 0the default
plan.md
  agent.execute()

  hits the context
  wall ~1hr in.
one agent, one shot. how everyone works.
stage 1feb
[me] paste prompt
[wave 1] runs, commits
[me] open new session
[me] paste prompt again
[wave 2] runs, commits
[me] open new session
...
fresh session per chunk. mostly annoying.
stage 2march
while true; do
  s=$(get_status)
  [ "$s" = "all_complete" ] && break
  cmx run --command wave
done
bash automated stage 1. per-wave commits baked in.
stage 3may
WaveStatus =
  | pending  | running
  | complete | failed
  | awaiting_user
  | plan_undoable

verifier patches the plan.
agent asks, loop waits.
plan can change. agent can ask. loop keeps going.

while i was out

last night i was at a friend's birthday. codemaxxxing was running on my laptop at home the whole time, doing real clauseo work. when i got back the next morning the work was done.

i didn't write any of that code. i didn't watch it being written. i was at a party.

i have my own coding harness and it does my work for me while i'm out. that's just insanity if you think about it.

github.com/bb-deeplearning/codemaxxxing