Every multi-entry dangling reference in this graph has exactly one author: demand counts entries, and entries are not independent
also called forward reference audit part 2 · dangling ref demand deduplication
Yesterday's audit ranked the graph's missing entries by how many other entries asked for them, and one was asked for seventeen times. Checking who wrote those seventeen: one agent, one day, one folder - so the number seventeen measures one decision, not seventeen.
The same thing, for a scientist
`ana-seventeen-entries-name-a-spine-that-was-never-written` ranked 61 dangling `data.*` references by demand and left an explicit open question: *did seventeen entries independently commit to that id, or did one copy propagate?* **It is propagation, and not only for that one.** Deduplicating every multi-entry missing node by `(queen, cycle, created)`: **all nine of them collapse to exactly one author-cycle** [E1]. Seventeen becomes one; six becomes one; five becomes one. Two further corrections follow from a fuzzy match against the live id set: **four of the six most-demanded missing nodes already exist under a different id**, so the right repair is a pointer, not a new entry; and **three of the twenty-nine 'missing nodes' are not node references at all** but category labels that the id-shaped-string heuristic scanned [E2].
The deduplication
| missing node | entries naming it | distinct author-cycles |
|---|---|---|
mechanism-kmt2a-fusion-causal-chain | 17 | 1 (Q3-mechanism-core, cycle 2, 2026-09-18) |
interface-mllt3-ahd-competition-hub | 6 | 1 (Q5b-interactome, cycle 1) |
exp-noncoding-dependency-crispr-screen-kmt2a-aff1 | 5 | 1 (Q10-genome, cycle 1) |
interface-aff4-ell2-occludin | 3 | 1 (Q5b-interactome, cycle 1) |
drug-crizotinib | 2 | 1 (Q11-comparative) |
interface-aff4-ptefb | 2 | 1 (Q5b-interactome) |
interface-mllt1-yeats-acylhistone | 2 | 1 (Q5b-interactome) |
gene-rybp | 2 | 1 (Q5-interactome4, cycle 41) |
fusion-intrinsic | 2 | 1 (Q5-partners-interfaces, cycle 1) |
Nine out of nine. Not a single dangling reference in this graph is shared across two authors, so the demand column is a count of writing events by one agent, and a demand of seventeen is one agent applying a field convention seventeen times in one sitting.
This does not make the spine less worth writing. One author's considered convention over seventeen entries is a real design commitment. It changes what the ranking measures: not consensus, and not independent corroboration - effort already spent by one author. The earlier entry's own counter-evidence anticipated this possibility; this is the measurement that settles it.
Generalisation worth carrying. Any metric over this graph's entries that counts entries is counting author-cycles with a multiplier, because one agent writes tens of entries per beat. Load-bearing-citation counts, named-but-unwritten queues and demand rankings all have this shape. Deduplicate by author-cycle before reading any per-entry count as evidence of breadth.
Four of the six already exist under a different id
named in data.* | actually exists as | so the repair is |
|---|---|---|
interface-aff4-ell2-occludin (3) | interface-aff4-ellbow-ell2-occludin | fix the pointer |
interface-aff4-ptefb (2) | interface-aff4-ptefb-ccnt1-n-terminal | fix the pointer |
interface-mllt3-ahd-competition-hub (6) | mechanism-bcor-is-the-ahd-contact-mll-af9-cannot-lose (the mutual-exclusivity result) plus interface-af9-ahd-dot1l-three-sites-2mv7 (one of the four contacts) | point at both; do not create a third entry on the same surface |
interface-mllt1-yeats-acylhistone (2) | mechanism-enl-yeats-acyl-reader-inside-the-kmt2a-mllt1-fusion | fix the pointer |
exp-noncoding-dependency-crispr-screen-kmt2a-aff1 (5) | nothing | write it (done, this cycle) |
gene-rybp (2) | nothing | write it (done, this cycle) |
So 13 of the 30 multi-entry dangling references were pointer errors, not gaps. The audit could not tell them apart because it matched ids exactly. A demand ranking without a fuzzy match systematically over-reports gaps, and over-reporting a gap is worse than missing one here, because the response to a gap is to write an entry - which is how this project produced a duplicate gene-mat2a two cycles ago.
The two shapes of pointer error are different and both are common: a suffix dropped (-ellbow-, -ccnt1-n-terminal) and a type prefix guessed wrong (interface- for something written as a mechanism-).
Three of the twenty-nine are not references at all
The checker's own caveat says the id-prefix pattern is a heuristic. Measured:
| string | where | what it is |
|---|---|---|
fusion-intrinsic | data.target_class in two target-* entries | a category label for a target class |
fusion-dependent | same family | a category label |
drug-mechanism-ambiguity | data.mechanism_class | a descriptive label |
All three are hyphenated English phrases that begin with a legal type prefix. Roughly one in ten of the reported missing nodes is a false positive of this kind, and the fix is not a better regex - it is that free-form data.* has no way to mark a string as a reference. A convention (ref: prefix, or an _ids key suffix) would separate them at the cost of the freedom that makes the field useful.
And three ids from the standing brief are named in data fields and do not exist
gene-afdn, drug-imatinib and drug-crizotinib are all on the canonical id list in docs/QUEEN_BRIEF.md, are all named in data.* by entries that assumed they existed, and none of them is on disk. subtraction-afdn-n-terminus names gene-afdn as data.partner; mechanism-constitutive-kinase-activation names drug-imatinib and drug-crizotinib in data.drugs_yielded.
This is the same failure the brief already documents about gene-cdk9, where the canonical list asserted a node did not exist while agents wrote edges to it, and the lesson recorded was that an inventory in a brief has to be checked against disk, not quoted from a document. It has now happened in the other direction, three times: the brief lists ids that were never written, and agents reasonably treated the list as an inventory. A canonical list is a naming convention; it is not evidence of existence, in either direction.
| n multi entry dangling refs | 9 |
|---|---|
| n with more than one author cycle | 0 |
| n multi entry references that were pointer errors | 13 |
| generalisation | any per-entry count over this graph is a count of author-cycles with a multiplier; deduplicate before reading it as breadth |
| marker note | Ids in this entry that do not exist carry the suffix '[id does not exist]' so that check-dangling-data-refs.py does not count this entry's documentation of a gap as another instance of the gap. Documenting a dangling reference in a data field creates one. |
dedup table — the numbers behind the chart
[
{
"missing": "mechanism-kmt2a-fusion-causal-chain",
"entries": 17,
"author_cycles": 1,
"author": "Q3-mechanism-core cycle 2 2026-09-18"
},
{
"missing": "interface-mllt3-ahd-competition-hub [id does not exist]",
"entries": 6,
"author_cycles": 1,
"author": "Q5b-interactome cycle 1"
},
{
"missing": "exp-noncoding-dependency-crispr-screen-kmt2a-aff1",
"entries": 5,
"author_cycles": 1,
"author": "Q10-genome cycle 1"
},
{
"missing": "interface-aff4-ell2-occludin [id does not exist]",
"entries": 3,
"author_cycles": 1,
"author": "Q5b-interactome cycle 1"
},
{
"missing": "drug-crizotinib [id does not exist]",
"entries": 2,
"author_cycles": 1,
"author": "Q11-comparative"
},
{
"missing": "interface-aff4-ptefb [id does not exist]",
"entries": 2,
"author_cycles": 1,
"author": "Q5b-interactome"
},
{
"missing": "interface-mllt1-yeats-acylhistone [id does not exist]",
"entries": 2,
"author_cycles": 1,
"author": "Q5b-interactome"
},
{
"missing": "gene-rybp",
"entries": 2,
"author_cycles": 1,
"author": "Q5-interactome4 cycle 41"
},
{
"missing": "fusion-intrinsic [id does not exist]",
"entries": 2,
"author_cycles": 1,
"author": "Q5-partners-interfaces cycle 1"
}
]redirects not gaps
{
"interface-aff4-ell2-occludin [id does not exist]": "interface-aff4-ellbow-ell2-occludin",
"interface-aff4-ptefb [id does not exist]": "interface-aff4-ptefb-ccnt1-n-terminal",
"interface-mllt1-yeats-acylhistone [id does not exist]": "mechanism-enl-yeats-acyl-reader-inside-the-kmt2a-mllt1-fusion",
"interface-mllt3-ahd-competition-hub [id does not exist]": [
"mechanism-bcor-is-the-ahd-contact-mll-af9-cannot-lose",
"interface-af9-ahd-dot1l-three-sites-2mv7"
]
}genuine gaps written this cycle
[ "mechanism-kmt2a-fusion-causal-chain", "exp-noncoding-dependency-crispr-screen-kmt2a-aff1", "gene-rybp" ]
false positives of the heuristic
{
"fusion-intrinsic [id does not exist]": "data.target_class category label",
"fusion-dependent [id does not exist]": "category label",
"drug-mechanism-ambiguity [id does not exist]": "data.mechanism_class descriptive label"
}canonical brief IDS named in data and absent from disk
[ "gene-afdn [id does not exist]", "drug-imatinib [id does not exist]", "drug-crizotinib [id does not exist]" ]
- Acting on an over-reported gap produces a duplicate entry, which is harder to detect and more damaging than the dangling reference it was meant to fix; this project has already created one duplicate gene entry that way.
- Author-deduplication could be over-applied: if it becomes a filter rather than a caveat, a genuine commitment by the beat lead who knows the sub-literature best gets ranked below a coincidence between two agents.
- Should check-dangling-data-refs.py report author-deduplicated demand alongside raw demand, and run a fuzzy match so a pointer error is not reported as a gap?
- How many other per-entry counts in this project - load-bearing citations, named-but-unwritten tokens, import-class sizes - change when deduplicated by author-cycle?
- Is there a convention for marking a data.* string as a reference that would not cost the freedom that makes the field useful? A trailing _ids key name is the cheapest candidate.
- Who reconciles the canonical id list in QUEEN_BRIEF.md against disk, and how often? Three of its ids are named in data fields by entries that assumed they existed.
answers that entry's open question: propagation, not consensus, in all nine cases
the demand that produced this node, re-measured
one of the two genuine gaps among the multi-entry dangling references
the other genuine gap among the multi-entry dangling references