September 11, 2026

For the way we’ve been building Taproot, I chose to manage the backlog in the repository.

That choice has limits. If a project had a lot of community participation, frequent handoffs, or people who need to manage work without a checkout, I would pick GitHub Issues. For a solo engineer or a small technical team working closely with coding assistants, keeping the backlog in the repo has one practical advantage: the explanation of the work lives right next to the work.

Retro cartoon of a smiling calculator holding a pencil and a long paper receipt

Tasks need somewhere to call home

Each task gets a permanent identifier and its own Markdown file. Structured metadata records priority, effort, milestone, and dependencies. The body explains the problem, the intended scope, and what counts as done. A generator builds a human-readable index and a machine-readable backlog, and validation catches inconsistencies.

When work finishes, we keep the task and its completion record. When we decide against something, we keep that decision too.

At the time of this review, Taproot’s committed index contained 761 items: 140 active, 528 completed, and 93 removed. Those numbers don’t prove productivity. They do show the system has held up through a long stretch of real development, so we’re well past experimenting with a folder of TODOs.

The reason for all that structure is obvious once you work with coding assistants like Claude Code and OpenAI Codex. Conversations move on, and a fresh session has to recover what matters. Decisions made during implementation need a durable place to live, the same reason we lean on documentation-first development with AI.

The backlog gives the next person, or the next assistant, a place to start.

A task file can explain why we rejected an approach that looks obvious, which dependency has to land first, and what still needs proving. I don’t have to carry as much project history in my head and repeat it. An assistant that picks up a task without the conversation that created it still gets useful context.

GitHub Issues can do much of this

There’s a fair objection here: GitHub Issues can hold all those explanations too.

The GitHub CLI makes that objection stronger. An assistant can search issues, pull their bodies and comments, and request structured JSON without opening a browser. GitHub’s documented CLI fields include parent issues, sub-issues, and blocking relationships. So “the AI can read files” is a weak reason by itself. GitHub CLI documentation.

What files give us is a particular relationship with version control.

A task’s scope can change on the same branch as its implementation. The reviewer sees the revised requirement, the code, the tests, and the completion record in one diff. Check out an earlier commit and you get the task as it stood alongside that version of the software. This is the same benefit we got from moving Taproot into a monorepo: the assistant can see everything related to the change in one place.

We can commit all the work for a task together, from backlog refinement through closeout. That’s a real advantage.

GitHub Issues have their own history, but their current state doesn’t depend on which branch you have checked out. That separation helps when you’re coordinating people. It helps less when you want the specification and the implementation to be one reviewable change. For our workflow, that matters more than whether fetching an issue takes an extra command.

It also comes with a responsibility. If the implementation quietly weakens the acceptance criteria, putting both changes in the same commit doesn’t make that okay. Someone still has to review the scope change. Versioning makes the change visible, but a person still has to judge it.

Does this system produce better code?

I think our current workflow helps us produce better code, with one important qualification: most of that benefit comes from the process, and the file format gets less of the credit.

Before implementation, we read the task against the actual code and fix assumptions that no longer hold. We identify dependencies and architectural constraints. Afterward we verify the result, require an independent review (part of how we enforce coding standards), and leave a record of what changed and what was checked.

Those habits improve what goes into the coding and how closely we look at what comes out.

We could keep all of that if the task lived in GitHub Issues. When I asked the assistant to compare the two approaches, it drew a useful distinction:

A carefully maintained issue would serve me better than an outdated local file. Neither storage system can compensate for an unclear problem or unverified assumptions.

What the local system does is make our preferred process convenient. Updating the task is just part of editing the repository. A search for a concept turns up its implementation, tests, and task history with the same tools, and the completion record travels with the fix. Good habits are easier to keep when they’re that close at hand.

Does this system help us work faster?

For focused implementation and broad backlog editing, I prefer the local system. For coordinating people, I would usually choose GitHub.

Locally, the assistant can look at several related tasks, compare them with the code, redraw their boundaries, and regenerate the index as one proposed change. There are no separate remote updates, and I can review the whole result before I share it.

GitHub is more convenient when the next step is assigning someone, asking for clarification, pulling a contributor into a discussion, or showing the plan across repositories. Projects already has table, board, and roadmap views, custom fields, and automation. GitHub also supports explicit issue dependencies. We would have to build or maintain all of that ourselves. GitHub Projects documentation, issue dependencies.

We haven’t run a controlled comparison, so I can’t put a number on either speed claim. The assistant’s assessment included a caveat worth keeping:

Fast retrieval also isn’t the same as fast delivery. Time spent fixing a generator, resolving an index conflict, or maintaining Trellis belongs in the accounting.

Trellis automates some of that bookkeeping, which cuts down the routine work. Maintaining the tooling still takes time, and I wouldn’t leave that cost out of an honest comparison.

What keeping the backlog in Git doesn’t solve

Backlog refinement has turned up work that had already shipped, duplicate tasks, and items whose original assumptions no longer matched the product. We consolidated some and removed others.

Keeping the backlog next to the code didn’t keep it correct on its own. It did make it easy to analyze the backlog against the full repository and fix those problems in one change.

Long task files are another problem. A detailed history helps when you’re digging into an old decision, but it can bury the current requirement. An assistant that reads everything spends time and context on material that no longer governs the work.

A useful backlog needs a short statement of where things stand now, with the history still within reach. Wherever it lives, it needs regular pruning.

Git brings its own coordination costs. Two branches can grab the same next task number. Generated indexes can conflict even when the tasks underneath are unrelated. Someone on an old branch sees an old backlog.

A task marked completed locally hasn’t necessarily been merged or deployed. Our local completion gate is not a production release signal.

These problems get more noticeable as the number of independent contributors grows. Even one engineer running several agents can run into concurrency problems you’d normally expect from a bigger team.

Where's the boundary?

I wouldn’t draw the line at a particular headcount. I would ask how work enters the project and how often people need to coordinate.

A small open-source project with lots of outside bug reporters may be better off with GitHub Issues from day one. A larger group of engineers who work through disciplined repository changes might be quite comfortable with file-based planning.

GitHub pulls ahead when a shared, always-visible view of the work matters more than keeping task state attached to a code revision.

For a solo engineer or a small technical team, most of the collaboration may already happen in the repository. In that setting, keeping the backlog there removes friction. As more people need to take part without working in the repository, the same choice starts to add friction. That’s the tradeoff I would watch.

From Taproot’s backlog to Trellis

Our experience became the starting point for Trellis. We took the conventions that worked in Taproot and started turning them into a reusable toolkit: configurable metadata, validation, generated indexes, import support, task history, a trellis CLI and a trellis-mcp MCP server, and portable work and review playbooks.

If you're comparing tools, Backlog.md takes a similar approach: tasks as Markdown files in the repository, with a CLI, a Kanban view, and MCP support for AI agents.

That was worth doing. It forced us to sort out which parts of the system were general and which were assumptions specific to Taproot.

The next improvements should make everyday work easier: seeing what’s ready to pick up, recovering the context for an unfamiliar task, and handling concurrent changes without extra bookkeeping. A viewer could help people navigate the backlog while making it clear which branch or revision they’re looking at.

I’ll judge those improvements by whether they reduce confusion and maintenance. Every feature we add is also something we have to maintain.

Why I’m keeping it

I don’t think our backlog has been a waste of time. It has supported a lot of work, preserved our decisions, and given us a repeatable way to go from a problem to a reviewed change. Trellis gives us a chance to make that easier to adopt elsewhere. Still, having built it is no reason to keep it forever.

For Taproot today, I’ll keep the repository backlog and improve the parts that get in the way of development. If participation and coordination become the bigger challenge, I’ll weigh whether adapting Trellis is worth the effort or whether GitHub would serve us better. Either way, useful specifications and decisions can stay in the repository.

We keep looking at how we work and what helps us ship quality code quickly, and I’ll keep sharing what we learn here.