Skip to content

97 evidence snippets remain unverifiable, effectively all on closed-access sources #596

Open

Description

@realmarcin

Follow-up from #593. Filed so the backlog that PR exposes is tracked rather than left implicit in a diff.

What the number is

scripts/evidence_snippet_audit.py classifies every one of the 5271 evidence snippets. After #593:

bucket count meaning
MATCH 4765 literal substring of real source text
RENDERING 66 faithful quote, cache carries a PDF/XML extraction artefact
WEAK 3
MISMATCH 296 real source text exists and the snippet is not in it
NOCONTENT 141 no source on disk to check against — that is #591

MISMATCH is the bucket that matters. Every one of these is a claim where the paper is cached and the quote is not in it.

Why it grew, and why that is good

On main MISMATCH was 190 and NOCONTENT was 379. #593 gave 238 previously-unverifiable snippets a real source; 132 turned out faithful and 106 did not. The 106 were always wrong — they were simply unexaminable.

The worklist

296 snippets across 78 records. Concentrated:

16  BioAsteroid_ISS_Chondrite_Biomining_Consortium
15  Lunar_Simulant_Phosphate_Solubilizing_Bacteria_Nicotiana
15  Microcoleus_Massilia_Cyanosphere_Urea_Mutualism
13  Bacteroides_Eubacterium_Gnotobiotic_Gut_Model
13  Ostreococcus_Dinoroseobacter_BVitamin_Mutualism
11  Thalassiosira_Ruegeria_Phycosphere_Coculture
 9  Anammox_Granule_Metabolic_Interaction_Community
 8  Drosophila_FiveSpecies_Gnotobiotic_Gut_Microbiota

The top three are worth looking at first not because they are largest but because two of them (BioAsteroid, Lunar_Simulant) come from the space/regolith curation cohort, which suggests a systematic problem with one curation pass rather than 31 independent errors.

How to work it — and one rule that is easy to get wrong

uv run python scripts/evidence_snippet_audit.py --list-mismatch prints them with a diff against the closest cached text.

A MISMATCH is not automatically a fabrication. Before rewriting anything, check in this order:

  1. Is the cache abstract-only while the snippet is from Methods/Results? Then it is a retrieval gap, not a curation error — run cache_fulltext.py first. This is the mistake corrected in Two records I curated from abstracts were wrong, not just thin (#183) #577/The partial record was not partial, I searched badly (#183) #578 and it accounted for several apparent "misattributions" there.
  2. Is it a rendering artefact the normaliser did not catch? e.g. B S _PETase for BsPETase. Those belong in RENDERING; if one is landing in MISMATCH the normaliser needs the case, and the snippet must not be edited to match the cache (the justfile is explicit).
  3. Is the reference simply the wrong paper for the claim? Seen twice recently — a genome announcement cited for cultivation conditions.
  4. Only then treat it as a paraphrase to be replaced with a real quote, or a claim to be withdrawn.

Doing (4) first would "fix" the corpus by editing quotes to match whatever text happens to be cached, which is worse than the current state.

Activity

  1. realmarcin commented on Aug 15, 2026

    @realmarcin
    ContributorAuthor

    Correcting this issue's emphasis — I filed it wrong

    I opened this describing 296 MISMATCH snippets as "the real evidence backlog" and "fabrication suspects", and pointed at the space/regolith cohort as evidence of "one bad curation pass". I then ran the check I had told everyone else to run first, and the framing does not survive it.

    290 of the 296 (98%) sit on an abstract-only cache. Only 6 are mismatches against a paper whose full text is actually on disk.

    ABSTRACT-ONLY cache: 290  (98%)
    full text cached:      6  (2%)
    

    The two records I singled out are the clearest cases. All 16 of BioAsteroid's mismatches cite one reference (PMID:41617698, 3873-byte abstract-only cache); all 15 of Lunar_Simulant's cite one (PMID:37945659, 2967 bytes). Their snippets are Methods-level detail —

    "The medium used for this experiment was a solution of 50% v/v R2A medium"
    "Samples grew for 19 days at 19.5"
    "yeast extract 0.25; peptone 0.25; casamino acids 0.25; glucose 0.25"

    — quoted from a Methods section against a cache that only ever held the abstract. That is step 1 of the triage order in the issue body, and it is the #577/#578 error again: a property of my retrieval mistaken for a property of the curation. There is no evidence of a bad curation pass; there is a retrieval gap behind 78 references.

    So #591 is the fix for 98% of this issue, not curation triage. This should be worked after the re-sweep, not before, or the sweep will be re-deriving the same 290.

    The 6 that are real, characterised

    These are exactly the snippets that were validating circularly before #593 — they passed only because they were listed in the cache file. Now that the listing is gone they are checked against real full text, and they are three different things, none of them fabrication:

    1 — a rendering artefact the normaliser does not cover. PET ... P. putida KT2440 (ATCC(R) 47054). The cache says (ATCC® 47054). The curator wrote (R) for ®. This belongs in RENDERING, not MISMATCH, and per the justfile must not be fixed by editing the snippet.

    2 — table flattening. OMM12 ... "Lactobacillus reuteri I49, Enterococcus faecalis KB1, Blautia coccoides YL58". All three names are in the cache, but as separate rows of a strain table: ... Lactobacillus reuteri I49 DSM 32035 1 Bifidobacterium .... The curator joined three cells with commas. Faithful in content, not a contiguous quote.

    3 — a quote stitched from two places. PET ... "R. jostii was added to reduce the inhibition caused by terephthalic acid". The paper has R. jostii was added to the existing consortium to break down TPA at one point and adding R. jostii to reduce the inhibition caused by terephthalic acid (TPA) at another. The snippet welds the opening of one to the tail of the other. This is the only one of the six that is a genuine curation defect, and it is a paraphrase presented as a quote — the #347 class.

    Revised recommendation

    1. Do Re-sweep the abstract-only caches: some "needs access" verdicts predate the #586 fix #591 first. It removes ~290 of these.
    2. Teach the audit normaliser ®/(R) and the table-flattening case, so they land in RENDERING where they belong rather than inflating the suspect count.
    3. Re-run, and treat whatever survives as the actual curation backlog. On today's evidence that is a single-digit number, not 296.

    Leaving the original text above intact rather than editing it, since the wrong framing is the more useful record.

  2. realmarcin commented on Aug 31, 2026

    @realmarcin
    ContributorAuthor

    Measured the split this issue's own correction called for, then cleared the actionable half. PR #719.

    The number that matters is neither 296 nor 107

    What decides whether a MISMATCH means anything is whether the cited source is cached as full text. On an abstract-only cache, a Methods-level quote being absent proves nothing — the #605 rule. Split across 117:

    count
    abstract-only cache 104 (89%) absence is not evidence — a retrieval gap (#591)
    full text cached 13 (11%) absence IS evidence

    That shape agrees with your earlier correction (98% abstract-only); this pins the residual at 13.

    Two of my measurements were wrong before they were right, both in the same direction:

    • cache_text()'s second return value reads like "is full text" and means "has real content" — so my first pass reported 100% full-text, which is what made me check it.
    • I looked for caches as .md only, so three .txt PubMed dumps looked absent. Those dumps are abstracts, and that is the very distinction the split turns on.

    None of the 13 was a fabrication

    Every one had a contiguous fragment of 23–113 characters already present in its source. They were real quotes with a wrong span:

    • 7 near-miss paraphrases — "potentially" for "possibly", "available in" for "available from", a reordered clause;
    • 3 joining non-contiguous text with ..;
    • 1 MeSH indexing descriptor used as prose (Carbon Dioxide/metabolism, whose explanation admitted it: "The cached record indexes…");
    • 1 genuine meaning change — Ewaste_Bioleaching_Consortium cited "bioleaching of 10% (w/v) PCBs in a stirred tank bioreactor" where the source says abiotic chemical leaching, the step that prepared a metal-ion solution rather than the microbial one.

    All repaired to verbatim contiguous spans. Full-text mismatches: 13 → 0.

    The .. elisions were repaired rather than taught to the audit. CLAUDE.md forbids combining non-contiguous text, so making the tool accept the marker would have been weakening a check to make existing prose pass — and only 4 snippets KB-wide use .., so it is ad hoc rather than a convention.

    What is left here

    The residual 104 are all abstract-only. That is a retrieval problem, not a curation one, and the same class as #591. The next step is a cache-fulltext sweep over their references, after which each either resolves or becomes a real finding — a batch that wants a canary first and its own PR. The concentration is unchanged from your original worklist: Bacteroides_Eubacterium_Gnotobiotic_Gut_Model (13), Ostreococcus_Dinoroseobacter_BVitamin_Mutualism (13), Drosophila_FiveSpecies_Gnotobiotic_Gut_Microbiota (8), Yogurt_TwoSpecies_Starter_Culture (8).

    Worth retitling: "296 MISMATCH snippets across 78 records" now overstates by an order of magnitude, and the headline is the number people quote.

  3. realmarcin commented on Sep 1, 2026

    @realmarcin
    ContributorAuthor

    The residual is not a retrieval gap. Measured in #728.

    Following the abstract-only split, the next step was a cache-fulltext sweep over the 27 distinct references behind the remaining mismatches. It is a much smaller job than the snippet count suggests.

    Three canaries, each one useful:

    PMID:19321416 (13 of the 104) not open-access in Europe PMC (oa=False) — clean skip, file byte-identical
    PMID:30228381 (13 more) same
    PMID:25692519 Europe PMC reports OA but serves no full-text XML

    The first two proved only the no-op path, so a third was needed to exercise a successful write — and it also skipped.

    Then the free probe. A read-only isOpenAccess query over all 26 (PMID:38150661 excluded — an untracked local WIP cache):

    OPEN ACCESS       3
    NOT open access  21     (18 of them have a PMCID but no open licence)
    no EPMC record    2
    

    A PMCID is not evidence of fetchability — that is the trap here, and 18 references sit in it.

    Fetched, verified on disk: PMID_42098792.md 5,129 → 81,464 bytes and PMID_41343683.md 5,010 → 100,238 bytes, both with the full-text marker. The corpus moved MISMATCH 99 → 97, MATCH 5316 → 5318.

    The new full text also exposed one more .. non-contiguous snippet, repaired the same way as the thirteen in #719 — a defect that was unverifiable in either direction against the previous abstract-only cache.

    What this means for the issue

    The remaining 97 are effectively all on closed-access sources. That is neither a curation backlog nor a retrieval one — it is the institutional-access constraint #183 already tracks. Worth saying so in the title, because "296 MISMATCH snippets across 78 records" now overstates by 3× and reads like unfinished work that somebody could finish.

    Suggested disposition: retitle to the measured residual and cross-link #183, or close here and let #183 carry it.

  4. changed the title [-]296 MISMATCH snippets across 78 records: the real evidence backlog, now that it is visible[/-] [+]97 evidence snippets remain unverifiable, effectively all on closed-access sources[/+] on Sep 2, 2026
  5. realmarcin commented on Sep 2, 2026

    @realmarcin
    ContributorAuthor

    Retitled from "296 MISMATCH snippets across 78 records: the real evidence backlog, now that it is visible".

    The old title was the number people quoted, and it had stopped being true in two different ways:

    filed as 296
    after the #593 sweep 107
    after #719 repaired the 13 full-text cases 99
    after #728's fetch 97

    More importantly, "backlog" implied work someone could finish. Measured:

    So what is left is not a curation backlog and not a retrieval one: it is the institutional-access constraint #183 already tracks. A snippet on an abstract-only cache is unverifiable, which is a different claim from wrong — and the #605 rule says absence there proves nothing.

    The new title says the measured residual and what it is. Closing versus keeping this open alongside #183 is worth a decision; the number will not move again without institutional full-text access.

  6. realmarcin commented on Oct 6, 2026

    @realmarcin
    ContributorAuthor

    Additional source-coverage work exposed by the provenance repair in #1363 (head d35e526e30385056f3b99c9a93c85a0d791b309b): DCPP/PMID42613016 has 19 MISMATCH items against independently retrieved abstract text after curator-selected appendices are excluded; two snippets still match. This is a retrieval/provenance gap, not a finding that all 19 claims are false. RAMC/PMID41381587 retains 20 exact matches plus one ASSEMBLED item at growth_media[0].evidence[1] and one RENDERING difference, with its retrieved full body preserved. No biological record or cache was edited. Detailed paths and before/after counts are committed in reports/causal_graph_review/cache-provenance-20261006-batch26.json. This comment does not claim a new complete primary-source review or resolve this backlog.

  7. realmarcin commented on Oct 6, 2026

    @realmarcin
    ContributorAuthor

    Full-record DCPP assessment recorded in #1367: unchanged/needs_research, not a completed graph review. The entire independent abstract was read; current Europe PMC metadata reports isOpenAccess=N and lists free HTML, but ordinary HTML retrieval returned HTTP 403. No access control was bypassed and no primary body was committed. The repaired snippet audit retains two MATCH and 19 MISMATCH items; absence from the retrieved abstract is not proof of false biological claims. Exact three-strain comparisons, partner-specific detoxification and LC-MS details still require the primary body. This issue remains open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions