Strategist · Designer · Operator

Launch
with Ben



Claude Code

The Plan I Wrote in April and Never Opened Again

A markdown build plan that went stale the week it was written, the four ways it failed once agents were doing the work, and the issue trees that replaced it.


On 2026-04-27 I committed a 277-line build plan for a content editor. I never edited it again. The editor got built. It runs today on ByteMD, R2 and Cloudflare Access, exactly as the plan said, and it also ships translation, revision history and a health endpoint, none of which appear in the plan even once. It does not use Preact, which the plan names four times.

Nothing about that is unusual. What changed is that I stopped writing the plan.

277lines in the plan
1commits ever touching it
3shipped features it never mentions

The loop I used to run

The old loop was four steps, and for a year it was the only one I had.

Idea→talk it through in chat→write a markdown plan→put an agent to work

It is the shape GitHub’s Spec Kit formalised, the one IBM and Microsoft now write up as spec-driven development, and it is a genuinely reasonable answer to the question every agent forces on you: what exactly am I asking for. The agent needs scope. A document is scope. That much holds.

Here is what did not hold, on my work, once the agent was the thing doing the building.

The four things that broke

1. The plan was missing scope before anything started

docs/editor-plan.md covers architecture, roles, seven views, storage bindings, a permissions table. It is not a lazy document. And the three surfaces that turned out to matter most were invisible to it, because they had not happened yet:

TermTimes in the planShipped
ByteMD5yes
Preact4no
translate0yes
revisions0yes
health0yes

Translation is the one that stings. The editor’s translation endpoint now sits next to a whole class of problems I could not have named in April. In August one of them became its own piece of work: vpn#482, “Translated pages run months-old versions of the hubs.” A plan written before the site had 16 languages cannot warn you about that. That is not a flaw in the writing. It is what a document written first is.

2. It was wrong within weeks and nothing told me

Preact appears four times. The shipped editor is a single 4,942-line static/index.html with no framework at all. Somewhere between April and now I made that call, and I made it in a terminal, and the plan kept saying Preact.

An agent reading that plan has no way to know. It is a confident, well-structured, internally consistent document, and it is wrong in a specific place. This is the same failure I wrote up in AI trusts your docs, and that’s the problem: hand a model bad ground truth and it will validate the bad ground truth, thoroughly and fast.

You can defend against it. You instruct the agent to re-verify every claim in the document before acting on it. I did that for a while. It works, and it means every task now starts with a research phase that re-derives things you already knew, which is slow and which you pay for on every single run.

A markdown plan: one file, no state, no owner, no closing condition. Wrong in a way that reads exactly like being right.

An issue: has a state, an owner, a parent, a close event, and a comment thread where the correction lives next to the claim.

3. No track record

Ask me what markdown-planned work I finished in April and I have to go and read files. The plan does not know it is done. editor-plan.md is sitting in docs/ right now, in the present tense, telling any agent that opens it that the editor will be built in Preact.

Multiply that by every project. Three months of finished work leaves behind a folder of documents that all still sound like proposals.

This is the least interesting failure and the one I hit most often. A board answers “what shipped last week” and “what is blocked” in one click. A folder of markdown answers neither without reading.

Those four are what the format cost me. Here is the same list against what an issue does instead:

What brokeWhat an issue tree does instead
Scope missing before work startsScope is added as sub-issues when the work reveals it, without invalidating the parent
Stale and confidently wrongCorrections land as comments on the claim, and the issue’s state changes with reality
No track recordClosed is a fact with a date and an author, not a judgement about a file
Not searchableFilters on label, state, parent and text, from the CLI or the board

What I replaced it with

GitHub issues, in trees. Not a new tool, and that is most of the appeal.

Take vpn#482 as the counterpart to the editor plan. Opened 2026-08-12. Four named sub-issues:

1
Inventory the 28 English-only gates and rule on each
2
Ship the homepage advisor quiz to all 16 languages
3
Bring /vpn/ to parity across every language
4
Define hub parity for the languages still queued

All four closed. The parent closed on 2026-08-14 with four comments on it. Two days, and the record of what was decided sits on the thing that was decided about.

Four properties matter, and only the first is about writing:

What I ask of an issue tree

Do

  • The parent states the problem, not the solution. Sub-issues hold the solution and can be wrong.
  • One sub-issue is one agent’s worth of work, scoped so two agents never touch the same files.
  • Closing requires a comment with the command and its output, not the word “done”.
  • Sub-issues get added mid-flight. A tree that only shrinks was scoped as a document.

The second one is the one that took me longest to internalise, and it exists because of worktrees. Agents work in parallel now. A task scoped as prose (“improve the translation pipeline”) cannot be handed to one worktree safely. A task scoped as a sub-issue with named files can. The issue tree is not just a record, it is the thing that makes the parallelism safe.

Sub-issues are a real GitHub primitive, not a convention I invented, which matters because it means the parent/child link is in the REST API and an agent can walk it.

What four boards look like 24 days in

I started this on 2026-07-27. Everything below was read live from the GitHub REST API on 2026-08-20 and written to docs/content/seeds/board-receipts-2026-08-20.json before this post was drafted, because a piece arguing for a track record that cannot show one is doing the exact thing it complains about.

BoardIssuesOpenClosedParentsSub-issuesagentic
vpn-astro6213602619046377
uxxray4091322773721238
askbowtie103267794011
launchwithben45202552416
Total1,178538640141739142

The median tree is 4 sub-issues. The largest is 36. That is the granularity difference in one number: the editor got one 277-line file, and vpn#224 gets 36 individually closeable pieces.

Now the number that does not flatter me. 561 of the 640 closed issues carry at least one comment, which is 88% and sounds excellent. It is not the thing I actually want. I want closures that carry evidence: the command, the output, the URL. So I sampled 60 closed issues, spread evenly across the four boards, and read the comments.

46 of 60closed with a written note
17 of 60with a command or a code block
6 of 60with a link to the result

Twenty-eight percent. The format made a record possible and did not make me disciplined. That is worth saying plainly, because the honest version of “I switched to issues” is that the structure holds and the standard on top of it still has to be enforced, the way anything else gets enforced around here: audit it before it spreads.

On “AI project management tools”

If you search for a way to manage what your agents are doing, you get product listicles. Atlassian, Planner, a dozen vendors with an AI badge on a Kanban board.

The contrarian answer is the boring one. Your agents already understand git and they already understand issues, because both are in their training data and both have a stable API. There is no adapter to write, no schema to teach, no MCP server to keep alive. gh issue list --label agentic works from any session, in any repo, at no cost. I run 142 agentic-labelled issues across four boards on exactly that, and the entire tooling budget is a folder of shell scripts.

I am not claiming the vendors are useless. I am claiming that for a solo operator whose workers are coding agents, the thing you would buy is a worse fit than the thing you already have.

Where a spec still wins

Two cases, and I want to concede them properly rather than wave at them.

Greenfield, before a codebase exists. There is nothing to grep. There are no consumers to check. A document is the only artifact available, and writing one is the correct move. The editor plan was a good document. Its architecture section was right, and the editor was built on it.

A team that needs shared intent. I cannot speak to this at all. My boards are one operator’s, and the strongest argument for spec-driven development is several people agreeing on a target before anyone writes code. Nothing in my numbers touches that, and I would not trust anyone who told you otherwise from a sample of one.

I also do not think the failure I am describing is exotic. Augment Code, Isoform and Arcturus Labs have all made the drift argument. What none of them publish, and what I have tried to put in this post, is a plan you can open and a board you can count.

What this does not cover

There is also no control. I did not run a markdown arm beside an issue arm on the same work, so none of this isolates the format from everything else that changed at the same time. And the boards are private, so what I can publish is the counts and the method, not a screenshot. Every figure above is reproducible with gh api --paginate repos/OWNER/REPO/issues?state=all, which is the whole point of putting them in a committed file.

Sources

Related:

Ben Peetermans

Ben Peetermans

I build MVPs and run ad campaigns with AI, and I write these notes from real projects. Twenty years shipping for the web. If you want someone who works with these tools every day to build yours, that is what I do.