Two enrollment defects, both found by trying to enroll real packshots.
`rebuild_catalog.py` crashed on every successful run: the report referenced
`small` but the call to `below_pyramid_floor` was missing, so the pyramid-floor
check the enrollment protocol asks for never ran and the tool died with a
NameError after writing the catalog.
The name/OCR check read one orientation. A packshot whose identifying text runs
vertically - the やまや めんたいマヨネーズ image reads 明太手屋さんが only when
rotated - was refused as a mismatch, which is the worst failure this check has:
it rejects good data while claiming to validate it. `best_orientation_text`
tries all four right-angle rotations and picks the one that explains the most of
the catalog name, not the one that reads the most characters, because the
upright pass returns stray kana that concatenate longer than the real read.
The regression test goes through `audit`, not the helper: the bug was that
`audit` called a single-orientation read, and a helper unit test would have
passed on the broken code. Verified to fail before the fix and pass after.
Data now lives in the repo, not /tmp:
data/packshots/source/ packshots as downloaded, with ATTRIBUTION.json
data/evaluations/ per-session run artifacts, so a number in
DECISION.md traces to the run that produced it
sku_l09 is re-sourced at 1000x1000 from Matsukiyo's Rakuten image, replacing
the 305px view that the README documents as the reason l09 wins facings it
should not.
|
||
|---|---|---|
| .. | ||
| references/rejected | ||
| README.md | ||
| sku_l01.jpg | ||
| sku_l02.jpg | ||
| sku_l03.jpg | ||
| sku_l05.jpg | ||
| sku_l06.jpg | ||
| sku_l09.jpg | ||
| sku_l11.jpg | ||
| stock.csv | ||
LOPIA clean catalog
Official manufacturer pack shots, one front view per SKU. This replaces the
views in ../stock-lopia/, which were 71-119 px crops cut from the test shelf
add/image6.jpg itself: one 18 px sliver, duplicate crops, a wrong product on
sku_l09, and five SKUs with no view at all. Enrolling from the test shelf is
why every dark package collapsed onto one SKU and why the identity head was
trained on its own exam.
Rebuild or extend with:
python code/rebuild_catalog.py --source stock-lopia-clean --output stock-lopia-clean \
--replace --min-views 1 --csv stock-lopia/stock.csv
--min-views 1 because official pages publish a single front view per JAN. The
default floor of 2 exists to catch accidental single-view enrollment from shelf
crops, where several views are available.
Provenance
| SKU | Product | Source | Image |
|---|---|---|---|
| sku_l01 | キユーピー エッグケア 305g | kewpie.co.jp | 4901577090301L.jpg |
| sku_l02 | キユーピー 血圧ケア アマニ油マヨネーズ 200g | kewpie.co.jp | 4901577060052L.jpg |
| sku_l03 | キユーピー からしマヨネーズ 200g | kewpie.co.jp | 4901577338779L.jpg |
| sku_l05 | キユーピー ゼロ ノンコレステロール 310g | kewpie.co.jp | 4901577092381L.jpg |
| sku_l06 | キユーピー 内臓脂肪ケア フィッテ 210g | kewpie.co.jp (discontinued 2026秋) | 4901577083600L.jpg |
| sku_l09 | ピュアセレクト コクうま カロリーカット65% 360g | ajinomoto.co.jp | A140600321 |
| sku_l11 | キユーピー ハーフ 400g | kewpie.co.jp | 4901577031083L.jpg |
Kewpie images follow https://img.kewpie.co.jp/products_src/g3/imgs/<JAN13>L.jpg;
Ajinomoto images follow
https://www.ajinomoto.co.jp/products/Image.aspx?PicType=0&PIMNO=<PIMNO>.
Known gaps
Five SKUs in ../stock-lopia/stock.csv have no official pack shot here, so no
image lane can match them. They stay in stock.csv as text-only rows: the text
lane builds a signature from the printed name, which is how it can name or veto
a near-unknown the matcher cannot see. They are the current image-coverage
ceiling, not a recognition failure:
| SKU | Catalog name | Why it is missing |
|---|---|---|
| sku_l04 | やまや めんたいマヨネーズタイプ 200g | Yamaya's current lineup has no 200 g mentaiko mayo |
| sku_l07 | 丸和油脂 ラッキーマヨネーズ 200g | Maruwa's current catalog has no 200 g Lucky Mayonnaise |
| sku_l08 | スパイシーストーム ペリペリミックス 30g | No official 30 g Peri-Peri Mix found |
| sku_l10 | ピュアセレクト マヨネーズ 450g | Ajinomoto's current lineup is 400/250/600 g/1 kg; no 450 g |
| sku_l12 | 焼肉のたれ 中辛 | Brand not recorded in the catalog; ambiguous |
The catalog names for these five disagree with the manufacturers' current lineups, so the shelf tags and the CSV need reconciling before enrollment.
Keep the text-only rows when rebuilding: the CSV carry-over must preserve every source row, not just the SKUs with a kept view. Dropping these five costs the text lane the signatures that cover them.
sku_l09.jpg is enrolled but only 305 px tall, below the 800 px source floor
the enrollment protocol wants (§8 of the architecture decision). Its matcher
scores dwarf the other references (85-129 inliers against 10-40), so it wins
facings it should not; re-source it before trusting l09 precision. Measured on
the corrected image6 labels, l09 is the largest single-SKU share of accepts at
both resolutions: 18 of 48 accepts (37.5%) at full, 11 of 38 (28.9%) at live,
against a true share of 13 of 61 facings (21.3%). That is a hubness ratio of
1.76 and 1.36 against the completion gate's limit of 2.0, so G7 passes; the
stricter internal 30% share heuristic is what raises the alarm at full
resolution. Re-sourcing the reference is the fix, not a threshold change.
Rejected
references/rejected/kewpie-mayonnaise-450g.jpg is Kewpie Mayonnaise 450g (JAN
4901577042072). It was briefly filed as sku_l09 and then as sku_l10 because
the catalog's names pointed there, but it is neither product: l09 is Ajinomoto
Pure Select コクうま カロリーカット 65% 360g and l10 is Pure Select マヨネーズ
450g. It is kept as provenance for that mix-up and is never enrolled.