File the over-merge findings: two tracklet fixes, and cosine is not identity
The user checked the lead's crops. LIM SEONHO's 36 assignments cover at least six different men, a chibi and a cat, so 36 of 68 is a bug. 22 came from native resolves and 14 from reconcile merges. Two fixes are written in the orchestrator repo, tested, not deployed and not run on a GPU. `link_tracklets` caps a tracklet's panel span, because `window` bounded each pair while transitivity was unbounded and the lead's 22 native assignments came from tracklets spanning 22 and 30 panels. And one shared appearance tokenizer drops generic words, because whole chains hung on the word `short` and one pair on the word `hair`. The obvious third fix is ruled out by measurement. Over all 22 crop embeddings, the cat scores up to 0.82 against men, two different men score 0.93, and the highest pair is 0.96. No threshold separates them, so crop-to-crop cosine is not a link signal. Item 1 of the agreed plan, sending the live cast instead of a cosine top-k gallery, is not started. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -48,3 +48,5 @@ still live belongs in `caveats/`.
|
||||
| [A roster name is a guess, so it never reaches detection](identity-bbox.md#roster-does-not-name) | closed |
|
||||
| [`merged_into` is exactly one hop deep](identity-bbox.md#merge-chains-flatten) | closed |
|
||||
| [`_bbox_to_pixels` orders the corners, because the model sometimes swaps them](identity-bbox.md#bbox-corners-ordered) | closed |
|
||||
| [A tracklet is bounded by span, not only by pairwise distance](identity-bbox.md#tracklet-span-cap) | closed, GPU pending |
|
||||
| [A generic word is not identity evidence, and one tokenizer serves both consumers](identity-bbox.md#generic-tokens) | closed, GPU pending |
|
||||
|
||||
@@ -243,3 +243,62 @@ does not already enforce. The self-check feeds the real swapped box in and asser
|
||||
which fails without the sort.
|
||||
|
||||
Proven on the 18:07 run: 0 degenerate boxes over 119 detections.
|
||||
|
||||
## A generic word is not identity evidence, and one tokenizer serves both consumers {#generic-tokens}
|
||||
|
||||
**Closed, 2026-08-12, not yet run on a GPU.**
|
||||
|
||||
The tracklet linker and reconcile's pair pre-filter each carried their own copy of the appearance
|
||||
tokenizer, and both linked on words that describe a person without distinguishing them. Measured over the
|
||||
18:07 run's 22 crops for the lead:
|
||||
|
||||
```
|
||||
p056~p057 hair=['short'] cloth=- two different men
|
||||
p047~p054 hair=['hair'] cloth=- "brown hair" vs "dark hair", the field name in its own value
|
||||
p109~p110 hair=- cloth=['shirt','white']
|
||||
```
|
||||
|
||||
`tracklets.appearance_tokens` is now the single implementation and subtracts a `GENERIC` set: length words
|
||||
(`short`, `long`, `medium`, `shoulder`, `length`), `hair`/`haired`, garment words (`shirt`, `top`,
|
||||
`jacket`, `coat`, `sleeve`), and filler (`plain`, `casual`, `none`, `unknown`). `service._appearance_tokens`
|
||||
delegates to it, so reconcile's pre-filter is fixed by the same change. That pre-filter is what let the
|
||||
pink tank top reach `/vision/same` at all.
|
||||
|
||||
Four asserts cover it and all four fail with `GENERIC` emptied.
|
||||
|
||||
Measured effect on those 22 crops, with candidate overlap forced to pass (the shortlists are not stored,
|
||||
so this is the most permissive assumption and the real split can only be finer):
|
||||
|
||||
| | tracklets | worst span |
|
||||
| --- | --- | --- |
|
||||
| as it ran | 3 | 30 panels |
|
||||
| span cap only | 8 | 8 |
|
||||
| span cap + `GENERIC` | 9 | 8 |
|
||||
|
||||
The stopwords alone split out `p054`, the beige-jacket man, and `p089`, the red-robe chibi.
|
||||
|
||||
**Not fixed by this.** Bare hair colour still links different men: `order 56` through `62` stay in one
|
||||
five-crop tracklet on `brown`, and the cat at `p098` still joins its neighbours the same way. The obvious
|
||||
next lever, a crop-to-crop cosine, is ruled out by `caveats/audit-open.md#cosine-not-identity`.
|
||||
|
||||
## A tracklet is bounded by span, not only by pairwise distance {#tracklet-span-cap}
|
||||
|
||||
**Closed, 2026-08-12, not yet run on a GPU.**
|
||||
|
||||
`window=8` bounded each PAIR, and linking is transitive, so nothing bounded the group. The 18:07 run
|
||||
resolved 12 tracklets over 64 crops, and the lead's 22 native assignments fell into two of them spanning
|
||||
panels 47-69 and 80-110. One gemma answer then covered a grey blazer, a denim jacket, a red robe and a cat.
|
||||
The two blocks are visible in the stored confidences: eleven rows at 0.95 and ten at 1.0.
|
||||
|
||||
`link_tracklets` now rejects a merge whose resulting group would span more than `window` panels:
|
||||
|
||||
```python
|
||||
orders = [dets[m].get("panel_order", m) for m in gi + gj]
|
||||
if max(orders) - min(orders) > window:
|
||||
continue
|
||||
```
|
||||
|
||||
This makes the module docstring's claim true. The self-check links three compatible detections at panels 1,
|
||||
9 and 17 and asserts they do not land in one tracklet; it returns `[[0, 1, 2]]` with the cap disabled.
|
||||
|
||||
Cost: 3 resolve calls become 8 for this character, so identity should go from about 1m25s to 3 or 4 minutes.
|
||||
|
||||
Reference in New Issue
Block a user