You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Declare local_phash's skip reasons at source (protected-core exception)
`local_phash.find_best_match` returned "no-hashable-candidates" and
"no-clear-winner" as bare inline literals. The roster tether added in
#567 derives the skip-reason roster from module-level
`*_SKIP_REASON = "<literal>"` declarations, and it cannot enumerate
literals it cannot see - so a NEW literal added inside `find_best_match`
would have reached `CardScanLog.skip_reason` (~2.7M rows, no `choices`
list, no FK) with nothing to catch it.
#567 could not close that: `local_phash.py` is PROTECTED CORE
(docs/upstreaming/license-provenance.md §2). It mirrored the two
constants in the consuming module instead and documented the residual
gap. The owner granted a narrow exception on 2026-07-29 to close it.
- declare PHASH_NO_HASHABLE_CANDIDATES_SKIP_REASON and
PHASH_NO_CLEAR_WINNER_SKIP_REASON in `local_phash.py`, export them,
and return them by name
- delete the mirror in `local_identify_printing_tags.py`, which now
imports the one constant it uses; one declaration per value
- record the exception, its reasoning and - the part that matters - its
LIMITS in license-provenance.md §2.1, a new exception log. It permits
declaring skip-reason constants in this one file. It is not a licence
to edit protected core; the next such change needs its own ruling.
`local_phash.py` stays on the protected list.
- two guards in test_skip_reason_roster.py for the regressions the
tether is structurally blind to: the mirror coming back, and a bare
literal returning at the origin
Naming-only. The string VALUES are untouched - and so are the constant
NAMES, so the roster's pinning test and the doc's Constant column needed
no edit at all. A `CardScanLog` row written after this is byte-identical
to one written before.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013NhYmT1PxCcyemA16dFDxN
Copy file name to clipboardExpand all lines: docs/reference/skip-reasons.md
+32-21Lines changed: 32 additions & 21 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -140,11 +140,17 @@ longer exists in the code; it wrote `fetch_failed` like the rest.
140
140
|`no-clear-winner-margin`|`PHASH_NO_CLEAR_WINNER_MARGIN_SKIP_REASON`|`local-phash-v1`| A candidate cleared the threshold, but the runner-up was too close behind it. | Live |
141
141
142
142
`no-hashable-candidates` and `no-clear-winner` are the two values whose
0 commit comments