v1.82.0 ·
Running discovery again erased what we wrote
The problem
aidlc discover seeds the knowledge graph through KnowledgeWriter.importBatch, the same
path aidlc knowledge import uses. On a graph people have already written up, a re-run does
three kinds of damage:
- Overwrite.
mergeEntities(packages/cli/src/knowledge/writer.ts) keeps the incoming description whenever it is non-empty, so "Module at packages/cli/src/core/ (has index)" replaces a hand-written paragraph. - Duplicates.
seedFromScan(packages/cli/src/knowledge/seed.ts) builds module ids from the folder path, and the writer matches by id only. A module written up asmenu-modulegets a second entitymodule-rasensio-aidlc-menuwith the samename. - Noise. Every merge bumps
lastVerifiedand addsmetadata: {}, and every relationship is rewritten with a newlastVerified— or, when the edge lives in the legacyrelationships.yaml, written a second time as a new record file. An unchanged repo still produces a diff of about 100 files.
How it could be solved
The simplest fix was to make every merge keep the old description, and it was wrong. The same merge serves a person who adds a fact by hand, and when that person writes a new description they mean to replace the old one. So discovery got its own way in. It fills a description only when the stored one is empty or still one of the short placeholders discovery writes itself, and it leaves the name, tags and everything else on an existing entry alone. The placeholder is recognised by its shape, not by who wrote the entry, because an entry that discovery created and a person later rewrote still says discovery created it.
The duplicates needed a judgment about how close is close enough. A folder found on disk is matched to an existing entry with the same name or the same source path, and nothing looser. When exactly one entry matches, discovery writes into it. When two do, it writes nothing for that folder and says which two, because quietly attaching facts to the wrong module is worse than leaving one gap a person can see. On this project that left one folder unmatched and one near-duplicate added under a name nobody had used, and both are visible in the output rather than buried in the diff.
How AIDLC solves it
Running aidlc discover again on a project whose knowledge graph people have written up no longer
damages it. Discovery now replaces a description only when it is empty or still one that discovery
itself wrote, and it never changes an entry's name, source, author, confidence or tags. When it
finds a module that is already written up under a different id, it adds its facts to that entry
instead of creating a thin second copy, and when two entries could be the one it found, it writes
nothing for that module and prints a warning naming both. Nothing whose facts did not change is
rewritten, so running discovery twice on an unchanged project leaves an empty diff.
On this repository the first run after the fix added only the ten modules that have no entry yet
and modified no existing file; before it, the same run replaced a seven-line description, created
14 duplicate modules and touched about 100 files. aidlc knowledge add and aidlc knowledge import keep their behaviour, where a new description replaces the old one.
Patch: no command, flag or file format changes. The discover summary line now reads
N entities added, M updated, K unchanged instead of N entities added, M merged, and discovery
warnings are printed on stderr.
Changes
packages/cli/src/knowledge/seed.ts—isDiscoveryPlaceholder.packages/cli/src/knowledge/writer.ts—mergeDiscovered,KnowledgeWriter.importDiscovered.packages/cli/src/commands/discover.ts— usesimportDiscovered; new summary; warnings on stderr.packages/cli/test/discover-clobbers-knowledge.test.ts— new, 20 tests.packages/content/docs/knowledge-graph.md— re-runningdiscoverand why..aidlc/knowledge/decisions/discover-imports-separately-from-knowledge-add.yamland one relationship — the decision.packages/website/content/blog/overrides/discover-clobbers-knowledge-post.jsonand-options.md— this release's post.