Read stored ImageEvidence first in the lands identifier - #391
Merged
Conversation
local_lands_identify now consumes a card's current ImageEvidence row (same currency test as Stage D's calculators) for collector-line/ artist signals when one exists, skipping fetch+OCR entirely; falls back to the original live-fetch path only when no current evidence exists. Also wires the command into pilot_run_lifecycle's forced dry-run guard/counters-before-output rails (issues #345/#373). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…nd tests test_command_local_lands_identify.py was missing the standard _preserve_shared_factory_sequences fixture, letting its CanonicalArtistFactory calls permanently shift the process-global sequence counter and break test_views.py's snapshot expectations in a full-suite run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Issue #359, Phase 1 of the owner-approved post-2026-07-23 plan. Today
local_lands_identifyfetches a fresh image and runs fresh OCR forevery candidate card, ignoring the harvest-calculate pipeline's own
ImageEvidencerows — even though the issue's own live sizing found99.6% of the 1,609 unresolved basic-land cards already carry a
current one. This is a data-source patch only, never a logic change:
_current_evidence_for_card— the currency check (content_hashmatches the card's live
content_phash, plus both thecollector_line_ocr/artist_ocrextractor-version keys present) —same shape
local_calculate_verdicts's three Stage D calculatorsalready use.
_ocr_result_from_evidence— step 1's evidence-first replacementfor
run_ocr_for_card: reconstructs anOcrParseResultfromalready-persisted, already-parsed fields and calls the existing,
unmodified
local_ocr.validate_against_candidates— the exacttechnique
calculate_join_key_verdictalready established.evidence.artist_ocr_namedirectly replacesdetect_illus_anchorfor the artist step.
identify_land_printing(steps 2-3, artist-narrow + phash) iscompletely untouched.
_process_land_cardfactors the shared step-1-through-3 outcomelogic out of
run_lands_identify's loop so both the evidence-backedand live-fetch-fallback branches call the exact same code — this is
what guarantees the two data sources produce identical verdicts on
identical inputs, not just that each works in isolation.
live fetch + OCR + artist-detection path, unchanged, still gated by
--fetch-budget. An evidence-backed card never counts against thatbudget (new
LandsIdentifyResult.evidence_backedcounter, separatefrom
fetch_attempted).Also wires the management command into
pilot_run_lifecycle's forceddry-run guard / counters-before-output / ledger-counters rails
(issues #345/#373's convention, already used by
local_calculate_verdicts/consensus_recompute) —local_lands_identifywasn't on that PR's original five-command list, but a cheap
evidence-backed dry-run now makes the guard's cheap-preview rationale
hold here for the first time, and the "house lifecycle" ask in #359
covers it.
docs/features/catalog-completion-plan.md's Part 4 section updated inplace with the new sizing/behavior.
Checklist
pre-commitand installed the hooks withpre-commit installbefore creating any commits.test_local_lands_identify.py(36 tests, up from 19: currency-check unit tests, OCR-from-evidence unit tests, evidence-first orchestrator branching, and an explicit fixture proving the evidence-backed and live-fetch-fallback paths produce byte-identical verdicts on identical inputs).test_command_local_lands_identify.py(9 tests: dry-run default, stale-image guard, ledger self-recording, broken-pipe-during-summary hardening, forced-dry-run guard blocked/passed/skip-recorded).pytest cardpickersuite: 1847 passed, 4 skipped, 130/130 snapshots (a first attempt caught a real bug of my own — the new command test file was missing the standard_preserve_shared_factory_sequencesfixture, letting its factory calls permanently shift the process-global sequence counter and breaktest_views.py's snapshot expectations; fixed in a follow-up commit and reconfirmed clean).ruff/black/isortclean on all changed/added files;mypyshows zero new errors on the two changed core files (confirmed identical 212-error pre-existing baseline onmasterfor the same file set).docs/features/catalog-completion-plan.md's Part 4 section, in place).Part of #359 (Phase 1 only, per this repo's task framing — the read-only
full-pool sizing and the owner poll issue #359 also asks for are separate,
still-open pieces of that issue; not closing it here).