September 11, 2026

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

That preference has limits. I would choose GitHub Issues for a project with substantial community participation, frequent handoffs, or people who need to manage work without touching a checkout. But for a solo engineer or a small technical team working closely with coding assistants, our system has a practical advantage: the explanation of the work lives alongside the work itself.

Retro Calculator Bill.png

Tasks need somewhere to call home

We’ve been giving each task a permanent identifier and its own Markdown file. Structured metadata describes priority, effort, milestone, and dependencies. The body explains the problem, the intended scope, and what would count as completion. A generator produces the human-readable index and a machine-readable backlog. Validation catches inconsistencies.

When work finishes, we preserve the task and its completion record. When we decide against something, we preserve 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 establish productivity, but they do show that this system has supported sustained development. We’re well past experimenting with a folder of TODOs.

The motivation behind that structure is easy to understand when you work with coding assistants. Conversations move on. A fresh session needs to recover what matters. Decisions made during implementation need somewhere durable to live.

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

It can explain why a seemingly obvious approach was rejected, which dependency must land first, and what still needs proving. That reduces the amount of project history I have to carry around and repeat. It also gives an assistant useful context when it picks up a task without the conversation that created it.

GitHub Issues can do much of this...

There is a fair objection here: GitHub Issues can contain all those explanations too.

The GitHub CLI makes that objection stronger. An assistant can search issues, retrieve their bodies and comments, and request structured JSON without opening a browser. GitHub’s documented CLI fields also include parent issues, sub-issues, and blocking relationships. So “the AI can read files” is a weak justification on its own. 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 can see the revised requirement, the code, the tests, and the completion record in one diff. Checking out an earlier commit recovers the task as it existed alongside that version of the software.

We can commit the work associated with a task together, from backlog refinement through task closeout. That is a real advantage.

GitHub Issues have their own history, but their current state exists independently of the branch you have checked out. That separation is useful for coordinating people. It is less useful when you want the specification and implementation to form one reviewable change.

For our workflow, that distinction matters more than whether fetching an issue takes an extra command.

It also creates a responsibility. If the implementation quietly weakens the acceptance criteria, putting both changes in the same commit does not make that acceptable. Someone still has to review the scope change. Versioning makes the change visible; it doesn’t supply the judgment.

Does this system produce better code?

I think our current workflow helps us produce better code, with an important qualification: most of that benefit comes from the process.

Before implementation, we read the task against the actual code and refine assumptions that no longer hold. We identify dependencies and architectural constraints. We verify the result. We require an independent review. We leave a record of what changed and what was checked.

Those practices improve the inputs to coding and the scrutiny applied afterward.

We could keep those practices if the task lived in GitHub Issues. When I asked the assistant to compare the two approaches, it made 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.

The local system makes our preferred process convenient. Updating the task is part of editing the repository. Searching for a concept can find its implementation, tests, and task history through the same tools. The completion record can travel with the fix.

That makes good habits easier to sustain.

Does this system help us work faster?

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

Locally, the AI assistant can inspect several related tasks, compare them with the code, revise their boundaries, and regenerate the index as one proposed change. It can do that without separate remote updates, and I can review the entire result before sharing it.

GitHub is more convenient when the next action is assigning somebody, asking for clarification, bringing a contributor into a discussion, or showing the current plan across repositories. Projects already supplies table, board, and roadmap views, custom fields, and automation. GitHub also supports explicit issue dependencies. Those are substantial capabilities we would otherwise have to build or maintain. GitHub Projects documentation, issue dependencies.

We haven’t run a controlled comparison, so I can’t quantify 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 reduces 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

We have had instances where backlog refinement found 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 did not keep it automatically correct. It did make it convenient to analyze the backlog alongside the full repository and correct those problems in one change.

Long task files can become another problem. A detailed history is useful when investigating an old decision, but it can obscure the current requirement. An assistant that reads everything indiscriminately spends time and context on material that no longer governs the work.

A useful backlog needs a concise current statement and accessible history. It needs regular pruning, regardless of where it lives.

Git introduces its own coordination costs too. Two branches can allocate the same next task number. Generated indexes can conflict even when the underlying tasks are unrelated. Someone on an old branch can see an old backlog.

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

These problems become more noticeable as the number of independent contributors grows. Even one engineer running several agents can encounter concurrency problems normally associated with a larger team.

Where's the boundary?

I wouldn’t draw the boundary 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 many outside bug reporters may be better served by GitHub Issues immediately. A larger group of engineers working through disciplined repository changes might find file-based planning quite comfortable.

GitHub’s advantage grows when a shared, immediately 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, the repository may already be where most collaboration happens. In that setting, keeping the backlog there can remove friction. As more people need to participate without working directly in the repository, the same choice can start adding friction.

That is the tradeoff I would watch.

From Taproot’s backlog to Trellis

Our experience became the starting point for Trellis. We took conventions that had proved useful in Taproot and began turning them into a reusable toolkit: configurable metadata, validation, generated indexes, import support, task history, CLI and MCP operations, and portable work and review playbooks.

That was worthwhile. It forced us to discover which parts of the system were general and which were assumptions specific to Taproot.

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

I would judge those improvements by whether they reduce confusion and maintenance. Adding features creates work of its own.

Why I’m keeping it

I don’t think our backlog has been a waste of time. It has supported substantial work, preserved decisions, and given us a repeatable way to move from a problem to a reviewed change. Trellis gives us a chance to make that experience easier to adopt elsewhere.

But having built it is no reason to keep it forever.

For Taproot today, I will keep the repository backlog and improve the parts that interrupt development. If participation and coordination become the dominant challenge, I will consider whether adapting Trellis is worth the effort or whether GitHub would serve us better. Useful specifications and decisions can stay in the repository either way.

We continue to examine how we work and what helps us deliver quality code quickly. I’ll keep sharing what we learn on this website.