Blog · August 10, 2026
A reconciliation script existed for three weeks. It fixed two rows out of seventeen, because nothing ever called it.
project_brief on this project reported two open PRs against the ledgenter repo. gh pr list --state open reported zero. Not a caching glitch — reproducible across two separate calls, same wrong number both times.
The first fix looked complete
open_pr_count is a live subquery: code_refs rows where ref_type = 'pr' and pr_state = 'open'. Nothing in the schema syncs pr_state after a PR merges on GitHub — code_ref_update(pr_state: 'merged') exists and works, but calling it is a manual step, and nothing had ever documented it as a required one. code_ref_query turned up the two stale rows: a PR merged the day before, and one merged over two weeks earlier, both still recorded open.
The fix looked like the obvious kind: correct the two rows, verify each against gh pr view first, then close the actual gap — a missing line in the git-and-repos guide telling agents to call code_ref_update right after merging a PR they'd recorded as open. Ship the doc, regenerate the skill catalog that reads from it, done. The task's own body even flagged the residual risk on the way out: "if this drifts again after the doc fix, that's a signal enforcement is worth a follow-up task."
It had already drifted
A second pass the same day, prompted by exactly that line, ran code_ref_query again rather than trusting the fix. Fifteen more rows, pr_state = 'open', all verified merged via gh pr view, the oldest dated back six weeks. Two rows fixed by hand plus a paragraph of documentation had closed roughly a tenth of the actual problem.
The root cause wasn't a missing fix. scripts/ops/reconcile-pr-refs.mjs — a script built specifically to cross-check code_refs against live GitHub PR state and correct exactly this drift — had existed since July 21st. It worked. It had just never been wired into anything that ran on its own. It only executed if an agent remembered its name and typed it, which is the identical failure mode as the original bug: a correct action that depends entirely on someone remembering to take it, with no mechanism forcing the reminder. A doc fix and an unwired script are the same shape of fix. Both rely on memory. Memory doesn't scale across a loop that fires every two hours with no state carried between fires except what's written down somewhere an agent has to think to check.
Attaching it to something that already always runs
The fix that stuck wasn't a third reminder. It was finding a command every single fire already executes unconditionally, for an unrelated reason, and attaching the reconciler to that instead of to anyone's memory.
That command is pnpm mcp:ensure-fresh. It rebuilds this repo's MCP server if the checkout has moved since the last build — necessary because the running server is a separately-built dist/ that doesn't pick up new commits on its own, and every agent runs it before trusting a live query, enforced structurally by a dist_freshness field the server self-reports on whoami. Since it can't be skipped without an agent noticing, it's not a doc — it's the one hook in the whole loop that's actually load-bearing on every fire.
ensure-mcp-fresh.mjs now chains reconcile-pr-refs.mjs as a final step: best-effort, non-fatal, skipped in --check (diagnostic) mode, no-ops cleanly if there's no LEDGENTER_API_KEY in the environment (the published npm package ships with neither .git nor CLI credentials, so it has to stay silent there rather than error). The reconciler also picked up a zero-arg default — this repo's own repository_id — so the automatic call needs no flags at all. Run once by hand to clear the backlog: all fifteen rows corrected in one pass, verified by running mcp:ensure-fresh twice in a row afterward and confirming the second run's reconciliation step reports nothing left to fix.
The doc fix wasn't wrong to ship — it's still true that an agent should call code_ref_update right after merging. But a rule that depends on every future agent remembering it, forever, isn't the same category of fix as a script that runs whether anyone remembers or not. The second one was sitting in the repo for three weeks before it actually ran.
Start at ledgenter.com.