docs(decision): correct the record against the re-measured evidence

The audit's own numbers were right; several claims built on them were not, and
the advisors found each one:

- 'wins both axes at both resolutions' - false at live, where the lane trades
  59% coverage for 93% precision against Van's 66% at 39%. Stated as the trade
  it is.
- G1's bootstrap now exists: the local lane's correct set is a strict superset
  of Van's on the stream, so the 95% lower bound is a hard +0.0 pp - a floor of
  that pairing, not a margin. tracks_final.json is level with Van and does not
  clear it.
- The far-unknown rate is 0.066% on 4580 crops at the shipped configuration,
  not 0.30% on 2650 at the old one.
- The E-3 ablation compared text-presence *and* a different argmax; both arms
  now go through the same DecisionPolicy ordering. Text adds 9-10 pp of
  coverage at full resolution while raising precision.
- The sweep table swept one axis while pinning the other; replaced with the
  joint sweep.
- The two Re-measured tables are dated snapshots, labeled as such.
This commit is contained in:
kiyo9w 2026-09-29 09:28:19 +09:00
parent 730a5e782b
commit 7736465bee
2 changed files with 132 additions and 43 deletions

View file

@ -178,6 +178,63 @@ class TextLaneSignatureTests(unittest.TestCase):
"sku_l08",
)
def test_one_shared_pair_is_refused_by_the_floor_alone(self):
"""Everything but the evidence floor says answer, and it says no.
"アンース" holds one pair the catalog knows - "ース" - so the row scores
a perfect 1.0 with the whole margin over an empty runner-up, and the
read carries three pairs, so `carries_identity` passes as well. Only
`TEXT_MIN_SHARED` stands between a coincidental pair and a named
product, which is why the test asserts the score is 1.0: it pins the
floor as the only thing doing the refusing.
"""
from identity_lanes import DecisionPolicy, TextLane
lane = TextLane.from_catalog(
[{"sku_id": "sku_x", "product_name": "オイスターソース"}],
"no-such-dir",
ocr_engine=None,
)
read = "アンース"
self.assertEqual(lane.scores_from_text(read)["sku_x"], 1.0)
self.assertIsNone(
DecisionPolicy(signatures=lane.signatures).decide(
[], [("sku_x", 1.0)], text_read=read
)["best_sku"],
"one shared pair is not enough to name a row",
)
def test_a_thin_read_still_vetoes_even_though_it_cannot_name(self):
"""The floor is a floor on naming, not on contradicting.
"北海道塩" shares three bigrams with sku_b - one short of the floor -
so it cannot name that row. It is still the row the text prefers over
the local answer, and the local lane clears its own line at 5.0 against
a line of 4.0, so if the floor also sat under the veto this would come
back as sku_a: a three-bigram read would have rescued a match the
geometry earned.
"""
from identity_lanes import DecisionPolicy, TextLane
lane = TextLane.from_catalog(
[
{"sku_id": "sku_a", "product_name": "キューピー ハーフマヨネーズ 400g"},
{"sku_id": "sku_b", "product_name": "北海道塩"},
],
"no-such-dir",
ocr_engine=None,
)
read = "北海道塩"
ranked = sorted(lane.scores_from_text(read).items(),
key=lambda kv: kv[1], reverse=True)
self.assertEqual((ranked[0][0], ranked[0][1]), ("sku_b", 1.0))
self.assertIsNone(
DecisionPolicy(signatures=lane.signatures).decide(
[("sku_a", 5.0)], ranked, text_read=read
)["best_sku"],
"a read too thin to name a row still refuses the local answer",
)
class FakeDetector:
"""Records concurrency and returns fixed boxes."""