Record two GPU cycles: the gate works, coverage is the open question
No worker code changed. This is the evidence from the 2026-08-12 16:39 and 17:38 runs, and where each finding now lives. The fourth session's four identity changes all work on real panels. Panel 7's two wrong bindings are gone. The lead going unassigned there is correct and was measured, not assumed: face_detect finds one face on the whole panel at conf 0.599, nothing else above 0.056 even at a 0.04 threshold, and the crop shows him drawn from behind. Two decisions, both closed: a roster name is a guess so it never reaches detection, and merged_into is exactly one hop deep. Two caveats, both open: detection can order a bbox backwards (1 in 117), and identity coverage has fallen on every run since the gate landed (70 -> 61 -> 50). Coverage is the thing to settle next, and not by reading the number. identity_labels already holds 145 rows of ground truth. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,3 +45,5 @@ still live belongs in `caveats/`.
|
||||
| [A detection with no detected face never enrolls or binds](identity-bbox.md#face-gates-enrollment) | closed |
|
||||
| [A resolver NONE mints an anonymous character, it does not clear the crop](identity-bbox.md#none-mints-an-anonymous-character) | closed |
|
||||
| [The extras gate runs at enrollment and at narration, not at the speaker prompt](identity-bbox.md#extras-gate-consumers) | closed |
|
||||
| [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 |
|
||||
|
||||
@@ -183,3 +183,41 @@ previous behaviour.
|
||||
|
||||
Forbids: adding a fourth consumer of `vision["characters"]` without deciding which side of this line it is
|
||||
on. The blob keeps every detection on purpose, so the audit can still see what was gated.
|
||||
|
||||
## A roster name is a guess, so it never reaches detection {#roster-does-not-name}
|
||||
|
||||
`service.py` seeded `known_characters` with `_roster_char_hints` before every detect call, so the chapter
|
||||
roster's names were in front of gemma before any panel had identified anyone. On the 2026-08-12 16:39 run
|
||||
that put "Seonho (short brown hair, yellow plaid shirt)" on a different man wearing glasses, who then held
|
||||
15 assignments under the lead's name. The real lead was minted separately from the p010 caption as
|
||||
"Lim Seonho", and p020 held both as two people in one panel.
|
||||
|
||||
The seeding is removed. A name now reaches detection only from a registry row, and a registry row is named
|
||||
from an in-panel caption or address through `name_claims`. The distinction is evidence: a roster name is a
|
||||
claim about art nobody has looked at yet, and a registry row carries an embedding plus the panel that
|
||||
named it.
|
||||
|
||||
The roster still feeds `roster_cast` in `run_stage_dialogue`. There the names are matched against speech,
|
||||
not against faces, so a wrong guess costs an unresolved speaker rather than a wrong face binding.
|
||||
|
||||
Confirmed on the 17:38 run: "Lim Seonho" came back as one row with 25 assignments, so dropping the hint
|
||||
did not split the lead across the panels before his caption. "Seonho" fell to 1 assignment.
|
||||
|
||||
Not covered: detection still reads a name off the panel and can attach it to the wrong body. p011 and p026
|
||||
emit `name: "Seonho"` on `person_2` with no roster hint present. That is a separate mechanism and it is
|
||||
what keeps the glasses man named at all.
|
||||
|
||||
## `merged_into` is exactly one hop deep {#merge-chains-flatten}
|
||||
|
||||
A merge chain means `merged_into` points at a row that is itself merged, so anything resolving one hop
|
||||
lands on a retired character. Roster readers filter `merged_into IS NULL` and were never affected.
|
||||
|
||||
Two rules, one per direction, and both are needed:
|
||||
|
||||
- `merge_characters` resolves the keeper to its chain root before merging. Bounded 64-step walk, the cap
|
||||
only exists so a cycle cannot hang reconcile.
|
||||
- retiring a loser repoints every row whose `merged_into` was that loser.
|
||||
|
||||
The keeper walk alone is not enough, which the 17:38 run proved by producing
|
||||
`477c1894 -> a92d9df4 -> 4fb94c15` with the walk deployed. At merge time that pair was fine. The chain
|
||||
formed later, when a row that was already somebody's keeper was itself retired.
|
||||
|
||||
Reference in New Issue
Block a user