The failure that started this was boring. A long session doing a change across several files would redo something it had already done. Not dramatically. It would just re-edit a file it had finished twenty minutes earlier, or mark a task complete based on what the conversation said rather than what was actually in the repo.
I tried the obvious things. Better system prompts. Stern reminders. A summary at the top of every message. They all worked for a few turns and then degraded, because they were all stored in the exact same place as the thing that was failing: the conversation buffer.
So I moved the state out of the chat window and onto disk.
A plan is now a markdown file in the repository. One row per task. Each row is a strict contract: what the task is, what it depends on, how to verify it before touching code, which role runs it, and whether an independent model validated it:
| # | Requires | Dep | Task | Verify | P | Est. Time (mins) | Worker (Suggested) | Validator (Suggested) | β Done | β Valid |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | π¨ Worker | β | Fix prop types in WBCode | /wbTest --scope=task-1 | P1 | 15 | -M=$WORKER | -M=$VALIDATOR | β | β 9/10 |
| 2 | π¨ Worker | 1 | Extract helpers into wbc-utils | npm test | P1 | 30 | -M=$WORKER | -M=$VALIDATOR | β | β 8/10 |
| 3 | β Validator | 2 | Audit exports for safety | /wbAudit --focus=exports | P0 | 20 | β | -M=$VALIDATOR | β¬ | β¬ |
| 4 | π§ Planner | 2 | Plan parser migration | /wbAudit wb-parser | P2 | 45 | β | β | β¬ | β¬ |
That was the architectural starting point. Once the workflow state became explicit and persistent, several other things became possible:
The session stopped mattering. Context compacts, a provider hits a rate limit, a run crashes overnight. None of that loses your progress. A new session opens the plan file, inspects the unchecked rows, and knows exactly where the work stands without needing a 20-minute re-explanation.
Dependencies became real data. Once a row specifies what it depends on (Dep: 1), parallelization and execution order can be derived deterministically from the dependency graph instead of something you hold in your head and pray the agent remembers.
The check moved to before the work. The Verify column gets written when the plan is authored, not after the task runs. Deciding how you will know a task succeeded before touching code is completely different from evaluating output when you are already psychologically invested in it.
Handoff stopped being a lossy transfer. Every agent reads the same codebase context and the same plan file. The next model picks up where the last one stopped. There is nothing to compress, because project state was never an ephemeral chat blob. The conversation became a working surface, not the source of truth. The repository became the source of truth.
What it costs: the unstructured exploratory chat is gone. Anything that did not become a task or a report does not survive. That is a real trade-off and I would not pretend otherwise.
I eventually packaged this pattern into an open-source tool called wb-flow. It keeps plans, task state, execution evidence, and validation artifacts in the repository, while the coding agent remains replaceable:
npx wb-flow
The conversation can disappear. The engineering state shouldn't.
Top comments (3)
"The Verify column gets written when the plan is authored, not after the task runs" is the strongest idea in the piece. Pre-registering what success looks like is the only mechanism I have found that survives being attached to your own output β once the code exists you grade it against what you built instead of what you meant to build.
The cost you name at the end is the honest one: if a thought never became a row it is invisible, and some of those were the useful detours. Curious whether an explicit "deliberately not now" section in the same file stops that loss without putting the conversation back in charge of state.
Glad that resonated! Pre-registering the
Verifycondition before touching code is the best way I found to beat confirmation bias.Regarding the "deliberately not now" ideas: yes, keeping them in local files is exactly the right approach.
In my setup, all agent memory is stored in a local
.wb/folder on disk:context.md) that every agent reads at the start of a run.This keeps the active plan focused on the current work, while ensuring good ideas are saved on disk for future plans rather than disappearing when the chat closes.
How do you currently handle side-thoughts and notes in your own setup?
Some comments may only be visible to logged-in visitors. Sign in to view all comments.