Compare commits

...

3 commits

Author SHA1 Message Date
kiyo9w
4b00323ae2 docs(decision): restore the far-unknown section's opening sentence
An earlier edit dropped the paragraph that introduces the section, leaving the
heading followed straight by a sentence starting 'and it hid...'. Restored, and
the document now has no heading without a blank line before it.
2026-09-29 04:43:02 +09:00
kiyo9w
c00b00499f test(server): verify the shipped configuration end to end
Still endpoint: 111 detections, 44 named, 42 correct, 95.5% precision.
Stream, 20 s pan 12: 83 tracks labelled, 0 label changes, 0 unexplained, 19/27
facings named at 82% precision, 0 wrong, 0 unenrolled false accepts.
2026-09-29 04:41:52 +09:00
kiyo9w
3eddc9eafc docs(decision): pace medians, and the packshot-OCR rejection
The pacing claim rested on single runs. Medians of three 12 s runs per pace,
through the shipped server: send 67% coverage / 88% precision, result 63% / 86%,
0 wrong in all six. The two paces are within 4 pp, so the sensitivity the audit
measured is gone and what is left is run-to-run noise.

The architecture sketch said the text signature was 'name + OCR of its
packshot'. The code scores the name alone, deliberately: adding the packshot's
own OCR is how l09 used to win l10's facings, because l09's packshot prints
l10's actual name. The sketch now says what the code does and why.
2026-09-29 04:40:32 +09:00
10 changed files with 10988 additions and 2 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,40 @@
{
"send": {
"coverage": [
0.63,
0.704,
0.667
],
"coverage_median": 0.667,
"precision": [
0.773,
0.884,
0.973
],
"precision_median": 0.884,
"wrong": [
0,
0,
0
]
},
"result": {
"coverage": [
0.63,
0.63,
0.704
],
"coverage_median": 0.63,
"precision": [
0.857,
0.825,
0.9
],
"precision_median": 0.857,
"wrong": [
0,
0,
0
]
}
}

File diff suppressed because one or more lines are too long

View file

@ -233,7 +233,8 @@ frame / native crop
│
├─ text lane: OCR (upsampled ×2 when crop height < 200 px)
│ ─► bigram similarity to every catalog row's text signature
│ (name + OCR of its packshot), including rows with no image
│ (the row's name only, including rows with no image; adding
│ the packshot's own OCR was tried and rejected - see below)
│
▼
decision: P(correct | local, text) from a small calibrated model
@ -691,6 +692,19 @@ The 12 s numbers are within run-to-run noise; the short clip is where the
pacing sensitivity lived, and it is now flat across pacings. Precision stays
100% and 0 unknowns are accepted at every pacing.
Re-measured 2026-09-29 as medians of three 12 s runs per pace, through the
shipped server with the calibrated accept lines
(`data/evaluations/2026-09-29-session/pace-medians/`):
pace coverage (3 runs) median precision (3 runs) median wrong
send 63 / 70 / 67 % 67 % 77 / 88 / 97 % 88 % 0
result 63 / 63 / 70 % 63 % 86 / 83 / 90 % 86 % 0
The two paces land within 4 pp of each other on coverage and 2 pp on precision,
with 0 wrong labels in all six runs. The pacing sensitivity the audit measured
is gone, and the spread across runs is now the run-to-run noise the audit said
the 12 s numbers were inside.
**The stream path now has a G1 number.** `code/score_stream.py` scores a
recorded clip's labels against the ground truth, matching each track's
`label_box` to the labelled facings. Three defects in the first version of
@ -820,6 +834,14 @@ with text, 55% at 81% without (2 false accepts against 8). The lane still adds
11 pp of coverage while raising precision by 14 pp, so the answer is unchanged
and the margin is wider than the audit's.
**Name-only signatures, and why.** The architecture sketch above originally
said the text signature was "name + OCR of its packshot". That was tried and
rejected: it is how l09 used to win l10's facings. l09's packshot prints
"マヨネーズ", which is l10's actual name, so a row with a photographed packshot
could explain a sibling's text better than the sibling's own name could. Every
row in the catalog has a name, so the packshot adds nothing but that confusion,
and `TextLane.scores_from_text` scores against the name alone.
**E-2 answered.** `LocalLane` is RootSIFT-only; ORB and BRISK survive only in
the `matcher` baseline lane, so there is nothing to drop from the shipped path.
@ -879,8 +901,10 @@ out of "210g"), and percentages are excluded because "カロリー 50% カット
claim about the contents. Measured on the corrected labels, full resolution:
precision 86% -> 91%, false accepts 8 -> 5, coverage unchanged at 79%.
### Far unknowns: the accept lines were tuned on a shelf that has no unknowns
Every threshold in this document was fitted on image6, where each crop is a
facing of a product the shelf actually holds. That is a closed-set tuning set,
and it hid the far-unknown rate completely: the shipped lane accepted 82 of
2650 crops from 60 Wikimedia Commons supermarket photos of milk, soy and snack
shelves - 3.09 %, against G3's 1 %.