Ppdd.bot
中EN

If it's not in the ledger, it doesn't exist

Commit follow-ups as files alongside the code. Archive them once resolved; don't delete them.

When an agent notices a problem along the way, the most common place it ends up is one line at the end of a reply:

"Also, there's a potential issue in XX; this could be a follow-up."

Nothing's wrong with the sentence. The problem is where it lives. When the session closes, it sinks with the rest of the conversation, and nobody goes back through chat history looking for it. The next person to hit the same problem starts from scratch.

In late July I added a skill for recording follow-ups to my company's repo. The commit message put the problem plainly:

In AI sessions, risks and leftovers found outside the current scope end up by default as a line in the reply, "could be a follow-up," and disappear completely when the session ends. Nobody looks back.

The fix was simple too: write them as files and commit them with the code.

One follow-up, one file

The repo has a directory called the ledger. Each follow-up is one Markdown file, named with the date and a short slug. The header has a few fixed fields: a title, the concrete next step, evidence (down to file and line), and the date it was recorded. The body explains what the problem is, why it wasn't fixed this time, and how much it matters.

Once it's a file, the follow-up lives next to the code. It has commit history, it can be reviewed and grepped, and the agent in a new session can read it. One line in the rules file:

A ledger entry sitting in the working tree is the same as not writing it.

Written but not committed is about as good as left in the reply.

Later it turned out committing wasn't enough either. One time in August I found a feature branch holding 20 commits of ledger entries and doc edits, while the fix that branch existed for had long since been merged to main through another PR. Those follow-ups were riding a branch nobody looked at anymore, which was the same as not having them. They all got moved to a clean branch off main and merged in their own PR. The rules file later got a line: ledger entries and pure doc changes don't ride feature branches; they go in on their own, based on main.

Resolve and archive, don't delete

When a follow-up is dealt with, the file isn't deleted. It's moved with git mv into an archive/ subdirectory, and two fields are added to the header: the outcome and the date. There are four outcomes: done, won't fix, duplicate, obsolete. The end of the body records the PR that did it, or why it won't be done.

Why not delete? A real example. On July 27 an entry was recorded saying a frontend status check used a stale reference, which could make the status bar text disagree with the card actually shown. During a ledger cleanup on October 15, it turned out that code no longer existed; the old feature had been removed entirely in another PR. So the entry was marked "obsolete" and archived, with the commit that made it obsolete noted at the end.

Had it simply been deleted, someone seeing a similar problem months later wouldn't know it had ever been recorded, or how it went away. What archive/ keeps is a record of decisions.

More gets recorded than resolved

Now some less flattering numbers. As of today, the ledger has 328 unresolved entries and 221 archived ones. September alone produced 201 entries that are still unresolved.

Things get recorded faster than they get resolved. On October 17 there was a bulk cleanup: all 342 unresolved entries at the time were checked against the code, and only 25 were archived. The rest all still had work left, so they stayed.

The ledger's README has a section called "health metrics," and its first line is: what matters isn't how many entries were recorded, it's the rate they get resolved.

Another time, in late September, the agent was reviewing a colleague's PR for me and recorded the problems it found in the ledger. I told it: "No need, just fix them directly, don't bother with the ledger."

That made the rule clearer to me. The ledger is for things you've decided not to do this time, not for things you don't feel like doing now. If it can be fixed on the spot, split it into a PR and fix it. Only what you've decided against, or can't do yet, goes in the ledger. Otherwise the ledger just keeps getting thicker until it's one more place nobody reads.

A version to copy

In the rules file:

## Follow-ups
- Before writing "do later / out of scope / could be a follow-up" in a
  reply, decide: if it can be fixed now, fix it in its own PR; if it
  really won't be done now, write it to docs/ledger/, not just the reply
- One file per item: docs/ledger/<YYYYMMDD>-<slug>.md, committed with
  the code; don't let it ride a feature branch
- Once resolved, git mv it to docs/ledger/archive/ and add resolution
  and resolved; don't delete the file

A template for each entry:

---
title: One sentence on what the problem is
next_action: The concrete next step
evidence: [path/to/file.ts:123]
created: 2026-11-04
# Add when resolved:
# resolution: done | wontfix | duplicate | obsolete
# resolved: 2026-11-20
---
Why it wasn't fixed this time, and how much it matters.
When resolving, add at the end: the PR that did it, or why it won't be done.

The rule doesn't forbid the agent from saying "this could be a follow-up." It just wants a file path to come after it.