Skip to content

v1.25.0 ·

The wrong facts were too unimportant to read

The knowledge graph is what every agent reads before it reads any code. aidlc knowledge query costs one command; re-deriving a fact costs a session. So the graph earns its keep by being right, and the failure nobody had a name for is an entry that is wrong in a way that looks exactly like being correct.

On 22 August the website cutover deleted the old site package, directory and all. The graph described it for seventeen days. A query for the site package answered with the deleted one first, and listing that directory failed. There were eight module entries and seven dependency entries whose source named that package's manifest. Fifteen entries in a graph of two hundred and three.

byAge flags anything unverified for thirty days, which on a real graph is most of it, correct entries included. degradeChanged intersects each entry's source with git diff --name-only, which sounds right until you notice that a path that no longer exists stops appearing in diffs. The change signal goes quiet exactly when the entry becomes wrong.

The report that opened this got two things wrong. It counted seven module entries when the population was fifteen, because the dependency entries are the same defect. And it said the stale entries were compiled into CLAUDE.md and fed to every agent. They were not. aidlc knowledge context ranks by confidence against a two-thousand-token budget, and all fifteen carried confidence: 0.6 from auto-discovery, so they lost to the hand-written 0.9 entries. The ranking worked. It is also why nobody noticed. The wrong facts were too unimportant to be read, until someone ran a query, where confidence protects nothing.

What changed

I fixed the data in .aidlc/knowledge/: twelve entities removed, three re-sourced, sixteen relationship edges removed, three added. Three of the fifteen, marked, react and react-dom, were still real dependencies, declared in packages/website/package.json at the versions the entries already recorded.

And there is a new check, knowledge-stale-sources, a report-only aidlc doctor migration that ships to every project through aidlc update. It names entries whose source no longer resolves, and dangling relationships from the same read. Dangling edges were zero across all one hundred and ninety-five before the fix, which made that class the guard on the first. A project with no .aidlc/knowledge/ is skipped without a parse.

A source that is absolute, or escapes the project root once resolved, is reported as a defect and never handed to a filesystem call. A tracked YAML file is not a trusted one.

Why report-only

A migration that deletes the entries was the tempting version. The data rules it out. Twelve wanted deleting and three wanted a corrected source, and nothing distinguishes the two. A confirm-tier migration applies unprompted under --yes, so the first unattended run would have deleted three correct facts to tidy a path. Deleting knowledge is the loss this graph exists to prevent.

I also rejected writing the follow-up down. A lesson in prose is not a work item, and this project has paid for that before.

What it does not fix

Report-only fixes nothing by itself. It turns an invisible defect into one line somebody has to read. Against seventeen days of silence that is the difference. Against a maintainer who never runs aidlc doctor, it is nothing. I accepted that.

The pull request bumped no version. The owner then asked for a release, and it went out as a minor, since a new check shows up in every project's doctor output. Report tier means no exit code changes and no CI can newly fail. This repo's own test over its committed graph files also ships, but only guards this one repository. 49 tests are new.