Skip to content

retune(art-edge): within-image relative colour comparison; snip does not clear the validation bar, not persisted - #734

Open
WilfordGrimley wants to merge 1 commit into
masterfrom
art-edge-relative-comparison
Open

retune(art-edge): within-image relative colour comparison; snip does not clear the validation bar, not persisted#734
WilfordGrimley wants to merge 1 commit into
masterfrom
art-edge-relative-comparison

Conversation

@WilfordGrimley

Copy link
Copy Markdown

Description

Retunes local_art_edge.classify_art_edge_continuity from an ABSOLUTE per-band
pixel-variance test (local_fallback._BORDER_UNIFORMITY_STD_THRESHOLD, tuned
for classify_border_color's different question) to a WITHIN-IMAGE relative
colour comparison: does the band beside the art crop match the border colour
this same image's layout_class (classify_border_color's own output)
already says it has?

This fixes the specific, confirmed defect: dark, textured, off-hue artwork
beside a real border used to read extended purely because it was dark and
flat (low absolute variance), not because it matched or mismatched the
border's actual colour. See
docs/reports/2026-08-06-art-edge-relative-comparison.md
for the full defect reproduction, the retune's own colour-distance/threshold
justification, and the validation methodology.

Validated against Scryfall's own images before any persistence decision
(three cohorts: 30 confirmed extended-art, 20 confirmed borderless, 20
confirmed ordinary framed — label and pixels from the same authoritative
source, unlike the earlier catalogue-cohort measurement this supersedes,
which name-matched uploads to printings without ever confirming the pixels
themselves). Result: does not clear the stated bar — 0/30 recall on
genuine extended-art images (worse than the pre-retune classifier's 1/30 on
the same images), 0 false positives on both negative cohorts. Root cause
traced and documented in the report: classify_border_color's own
"not uniform → borderless" catch-all misreads 20/30 extended-art images, and
for the remaining 10 the trimmed-image edge-band geometry shrinks to ~2px on
a Scryfall image (no bleed margin) — too thin for a reliable colour
reference. Both causes are upstream of this module's scope
(local_fallback.py, PROTECTED CORE).

Per the brief's own stated fallback for a classifier that does not clear
its validation bar: no ImageEvidence.art_edge_class field, no migration, no
Stage C extraction wiring, no EXTRACTOR_OWNERSHIP/manifest entry, no vote
wiring.
classify_art_edge_continuity ships as the new implementation,
evidence-only, called from nowhere but its own tests — exactly the state the
pre-retune code was already in, on more defensible internals. Docs updated
to record the measured result (docs/identification-pipeline.md,
docs/pipeline-fidelity-gate.md's calculator roster entry) rather than
"pending a validation pass".

Checklist

  • I have installed pre-commit and installed the hooks with pre-commit install before creating any commits.
  • I have updated any related tests for code I modified or added new tests where appropriate.
  • I have manually tested my changes as follows:
    • Rewrote MPCAutofill/cardpicker/tests/test_local_art_edge.py for the new
      layout_class-driven comparison: border-colour-match → framed (black
      and white), the defect reproduction (dark off-hue artwork does NOT read
      extended), a genuine colour-mismatch positive (extended), the
      borderless short-circuit (proved via a monkeypatch that raises if
      pixel sampling is ever reached), an ambiguous-layout_class abstention,
      a two-directional mutation-proof test on the distance threshold, the
      pre-existing coordinate-frame asymmetry tests, and degenerate-input
      abstention. test_local_art_edge.py alone: 23 passed. Full
      cardpicker/tests/ suite (order-dependence, issue Test suite is order-dependent: leaked fetch-failure window trips the envelope across files (8 failures on master) #679): 3678 passed, 8
      skipped, 0 failed.
    • Built a one-off, non-committed synthetic-image probe
      (/tmp/opencode/scratch_art_edge/probe3.py) reproducing the pre-retune
      bug by hand against the code this PR replaces, confirming the retuned
      code no longer exhibits it.
    • Built a one-off, non-committed Scryfall validation probe
      (/tmp/opencode/scratch_art_edge/scryfall_validation.py) fetching 70
      real Scryfall card images across three ground-truth cohorts (rate-limited
      via the existing SCRYFALL_REST/SCRYFALL_CDN destinations, no image
      pixels persisted to disk or DB at any point) and running both the
      pre-retune and retuned classifiers against identical inputs — see the
      report for the full numbers and root-cause trace.
    • docs_lint.py, check_extractor_manifest_sync.py,
      check_extractor_ownership_totality.py all clean (unaffected, since no
      persistence/extraction code changed).
  • I have updated any relevant documentation or created new documentation where appropriate.
    • docs/identification-pipeline.md and docs/pipeline-fidelity-gate.md's
      calculator roster entry updated to record the measured (negative) gate
      result instead of "pending a validation pass".
    • docs/reports/2026-08-06-art-edge-relative-comparison.md — the full
      measurement writeup.

…lear the validation bar, not persisted

classify_art_edge_continuity retuned from an absolute per-band pixel-variance
test (tuned for classify_border_color's different question) to a within-image
comparison: does the band beside the art crop match the border colour
ImageEvidence.layout_class already found for this same image, by Euclidean RGB
distance. Fixes the specific defect this was scoped to fix (dark, textured,
off-hue artwork no longer gets read as a border merely for being dark and flat
- confirmed by a constructed reproduction and pinned by a new test that fails
against the pre-retune behaviour), and drops the now-redundant edge-band
uniformity re-test.

Validated against Scryfall's own images (label and pixels from the same
source, unlike the catalogue-cohort measurement this supersedes, which
name-matched uploads to printings and never confirmed the pixels themselves)
across three cohorts: 30 confirmed extended-art, 20 confirmed borderless, 20
confirmed ordinary framed. Result: 0/30 recall on genuine extended-art images
(worse than the pre-retune classifier's 1/30 on the same images), 0 false
positives on both negative cohorts. Does not clear the bar stated before
measuring. Root cause traced and documented: classify_border_color's own
catch-all misreads 20/30 extended-art images as borderless, and for the
remaining 10 the trimmed-image edge-band geometry shrinks to ~2px on a
Scryfall image, too thin for a reliable colour reference - both upstream of
this module's own scope.

No ImageEvidence field, migration, Stage C wiring, or EXTRACTOR_OWNERSHIP
entry added, per the brief's own stated fallback for a classifier that does
not clear its validation bar.

Full report: docs/reports/2026-08-06-art-edge-relative-comparison.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant