Partly, and your version is the better one.
The shape of the unknown is stored and queryable: a partial identity like api:GET:?/clients says "route known, mount point unknown", so every deliberately incomplete edge can be selected. What is not stored is the reason for that particular gap. The reasons live in refusals.md as a catalogue of patterns the indexer refuses to infer, which is documentation rather than data on the node.
That split is the weak part, and a reason code on the instance, drawn from the same catalogue, is the fix. Gaps then become countable per reason instead of visible one at a time, and the series gets an honest metric: which gaps shrank because the indexer got better, and which stayed because the information genuinely is not in the code.
On the copying: that asymmetry is why the file exists at all. A gap costs one lookup. A fabricated edge costs trust in the whole graph, and it is the one thing nobody can audit later, because it looks exactly like the edges that were earned.