# i forked my coding tool because of course i did

> context engineering, wave executors, and the compulsion to make tools yours.

2026-02-23 -- 7 min -- ai, engineering, tools

canonical: https://rohans.lol/blog/codemaxxxing-context-engineering

---
## the qmk firmware thing but worse

i can't use something without wanting to change it. i customized my keyboard firmware beyond recognition in c. i spent months tuning the split layout on my crkbd until every key was exactly where my fingers expected it. so when i started using [opencode](https://opencode.ai) as my daily coding harness, it took about two days before i forked it.

the fork is called [codemaxxxing](https://github.com/bb-deeplearning/codemaxxxing). it's not a product. it's not a framework. it's my personal coding tool with my prompts, my agents, and my workflow baked in. i use it for everything i build at [clauseo](https://clauseo.chat) and every side project. the whole thing started because of four reasons that are embarrassingly practical.

one, make it mine. two, bake the best practices into the tool itself so my team follows them without config files. three, i was tired of typing the same plan-then-decompose-then-execute-wave-by-wave sequence every session. four, optimize hard for subagent parallelism, because subagents are the single best trick for keeping context windows clean.

none of this is "the best workflow." it's my workflow. it works for me.

## i've been doing this since the copy-paste era

i've been coding with ai since the early days. gpt-4 and copy-paste. you'd describe what you wanted, copy the output, paste it in, fix the 40% that was wrong, copy the error back, repeat. it was slow and tedious but it was magic compared to writing everything from scratch.

then cursor showed up and handled the copy-paste part. that was huge. suddenly ai went from editing one file to editing multiple files. then tools like claude code and opencode pushed it further, multi-file changes, running commands, debugging in a loop. the trajectory has been clear: every few months, the unit of work the ai handles gets bigger.

but here's what nobody talks about. the bigger the unit of work, the more the context window matters. when ai was editing one file, context didn't matter much. when it's doing a multi-hour overhaul across 30 files with test runs and debugging, context is the whole game.

## the context window is not memory

people think of the context window as memory. it's not. it's a sliding window that gets worse as it fills.

two things go wrong and they compound each other. first, early details rot. the agent read a file at the start of the session. fifty tool calls later, its "memory" of that file is shallow or wrong. compaction makes knowledge lossy. second, the model itself gets dumber as context fills up, even before anything gets evicted. transformers attend over the full sequence for every token they generate. as that sequence grows, attention gets diluted. the model is less precise about which details matter, less reliable at following constraints stated earlier, more likely to hallucinate.

a model at 30k tokens is genuinely a better thinker than the same model at 150k tokens. not because it forgot something. because it's spread thinner.

bigger context windows don't fix this. they delay the eviction while the attention dilution continues from the start. your 200k context session isn't twice as good as your 100k session. it's arguably worse for the last 50% of it.

## the cost thing nobody realizes

here's the part that actually made me go "oh shit." api pricing is input tokens times price plus output tokens times price. every api request in a conversation sends the entire conversation history as input. the first request sends the system prompt plus one message. the 50th request sends the system prompt plus every message, tool call, and tool result that came before it.

this means total input token spend across a session grows quadratically with the number of exchanges. not linearly. quadratically. the 80th request is paying for 79 messages of accumulated context.

four sessions of 20 exchanges each have far lower total input cost than one session of 80. same work gets done. fraction of the token spend.

## subagents are context isolation, not just parallelism

most people think of subagents as "do things in parallel for speed." speed is nice but it's the secondary benefit. the primary benefit is context isolation.

when a subagent runs, it gets its own fresh context window. it reads files, writes code, runs tests, debugs issues. all of that execution trace stays in the subagent's context. it never enters the parent's. the parent only sees a short result summary.

a wave with three parallel subagents might do 60 tool calls of real work, but the parent agent's context only grows by three messages. the parent stays sharp because its context stays small and clean. exactly the conditions where models perform best.

this is why i optimize so hard for subagent use in my fork. the prompts actively push the main agent to delegate work to subagents, split broad searches into multiple parallel agents, and never use explore agents as glorified file readers. every tool call that doesn't need to be in the parent's context shouldn't be.

## waves: ralph loops but i stay in the loop

the ralph loop is a bash script that runs an ai coding agent repeatedly until all tasks are done. each iteration is a fresh instance with clean context. memory persists via git history and a progress file on disk. geoffrey huntley coined it, named it after ralph wiggum, and it blew up because the core insight is so simple: fresh context beats degraded context. every time.

i love the insight. but ralph loops were too independent for me. the loop runs, you come back, it either worked or it didn't. i wanted something where i was still in the loop. where if something went wrong in one wave, the blast radius was contained to that wave and i could see exactly what happened.

so i built the wave executor. same core insight as ralph, different execution model.

instead of one session that does everything, you get N sessions that each do one thing well. each session starts fresh. reads a state file from disk. loads only what it needs for the current wave. executes. verifies. updates state. stops. a fresh session picks up exactly where the last one left off.

the key ideas:

**state on disk, not in memory.** progress is tracked in `STATE.md` as a finite state machine. a fresh session reads the state file and knows exactly where to pick up. it doesn't need to know what happened in prior sessions, how many sessions there were, or whether the last one crashed halfway through.

**the codebase itself is inter-wave state.** previous waves produce code and files on disk. subsequent waves read those actual files to understand what exists. not a summary of what was done. the real files. inter-wave communication is zero-cost and perfectly accurate.

**progressive disclosure.** each session loads only what it needs. the agent never reads the full plan, the full codebase history, or documentation meant for other phases. every document in the system is sized to be read in full. if an agent would need to paginate a file, it's too long. split it.

## it's the same pattern all the way down

waves keep inter-session context clean. subagents keep intra-session context clean. sub-subagents keep individual task context clean. the pattern is recursive and it applies at every level.

this is what context engineering actually is. not writing better prompts. designing systems that keep the model's context window useful. the prompt is like 10% of it. the other 90% is architecture: how you split work across sessions, how you isolate context with subagents, how you persist state to disk, how you structure documents so an agent with zero prior context can pick up and execute.

## the prompt iteration rabbit hole

the other thing that surprised me is how much the prompts themselves matter, and how model-specific they need to be. i run claude opus as my main model and gemini flash as the explore agent. same instructions, completely different prompting styles needed.

claude responds well to prohibitive framing. "don't add features beyond what was asked." "don't create helpers for one-time operations." gemini responds to prescriptive framing. "keep changes scoped to the request." "prefer inline logic for one-time operations." same instruction, different wording, measurably different results.

i ended up reading google's own gemini cli source code to understand how they prompt their own model. found 31 concrete observations about how gemini behaves differently from claude. turns out guidelines have an outsized effect on gemini compared to other models. on the convex leaderboard, gemini jumped from 89% to 95% with guidelines. biggest improvement of any model tested. so the prompt engineering isn't just nice to have, it's the difference between the model being useful or not.

each iteration follows the same loop. discover what's going wrong with concrete examples. research how other harnesses handle it. change the prompts. observe if it worked. repeat. it's the same loop as ralph, honestly. just applied to the prompts themselves instead of the code.

## the repo

the whole thing is at [github.com/bb-deeplearning/codemaxxxing](https://github.com/bb-deeplearning/codemaxxxing). the prompts and custom agents are portable to stock opencode if you don't want the fork. the iteration logs in `PROMPT_ITERATIONS/` document every change with the research that informed it.

it's not a product. it's a tool shaped like my brain. if you're building with ai daily and you haven't forked your harness yet, you should. the default prompts are fine. your prompts will be better because they'll be tuned to how you work, what models you use, and what failure patterns you keep hitting.

the tools don't matter. the models don't matter that much either. the context does.
