Skip to content

Four Stage D readers gate on collector_line_ocr but read six extractors' fields ungated; two degrade STRICT into a PERMANENT non-rescannable wrong skip #621

Description

@WilfordGrimley

What

Four Stage D readers gate on collector_line_ocr but read the fields of six extractors ungated.

That is: the guard checks that one extractor ran, then the body reads fields belonging to five others without checking whether they ran. A missing field from an unchecked extractor is read as if it were a measured absence.

Two of the four degrade in the STRICT direction — the missing input makes the reader more confident, not less.

The permanent-wrong-answer case

The worst instance: a missing artist_ocr makes a real old-frame card fail a frame-mismatch veto. The card is skipped. And that skip reason is deliberately not rescannable — by design, so the pipeline does not churn on it.

So the wrong answer is PERMANENT for that content hash. Re-running the pipeline does not fix it. Fixing the extractor later does not fix it. The card stays wrong until someone finds it by hand.

This is the difference between a bug and an unsound reader: a lenient degradation produces a recoverable miss; a strict degradation behind a non-rescannable skip produces an irrecoverable one.

The fix already exists in this codebase

The correct pattern is REQUIRED_EXTRACTOR_KEYS — declare the extractors a reader depends on, and abstain (rather than decide) when any of them did not run. Three other modules already implement it. These four readers simply do not use it.

What would close it

  1. Each of the four readers declares its real extractor dependency set via REQUIRED_EXTRACTOR_KEYS — all six extractors whose fields it reads, not just collector_line_ocr.
  2. Missing dependency ⇒ abstain, never a strict verdict.
  3. A test per reader asserting that with a dependency absent the reader abstains, specifically covering the artist_ocr-absent / old-frame / frame-mismatch-veto path.
  4. A remediation sweep for cards already carrying the permanent non-rescannable skip issued under the strict degradation — a one-off retraction, since the normal rescan cannot reach them. Size the affected population as part of the fix; it is currently unmeasured.

LIVE vs LATENT

LIVE in code on master. The permanent skips are latent in proportion to how often the unchecked extractors have failed — which is exactly the number item 4 above must measure. Note 10,127 cards have no ImageEvidence row at all (filed separately), so "extractor did not run" is not a rare state.

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions