Files
manga-recap-pipeline/caveats/speaker-attribution.md
T
kami a965077e6b Do not stamp som_face on a mark that paired to nobody
_set_of_mark labels a detected face `unknown` when gated pairing matched it to no
present character. An answer pointing at that mark grounds nothing, yet it carried
som_face, the highest-trust provenance. All 7 som_face lines in the first 36
panels of the rerun were this case. Same defect class as the fake tail label.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 23:44:22 +04:00

4.2 KiB

speaker-attribution

Limits found by cross-checking the 2026-08-11 chapter run against the panel images.

Nothing attributes a speaker in a multi-character panel

The false tail label is gone (decisions/speaker-attribution.md#no-fake-tail). What replaced it is a refusal, not an answer: with two or more characters present, every speech line now returns unknown. On a chapter like this one that costs 31 of 81 speech lines their speaker. The narration then falls back to a generic-handle. That is the honest floor, and it is not the fix.

The measurement that forced it, on job 778297bc, chapter 7c944dd4. Three two-character panels were checked against the art. All three are wrong, each with the two speakers swapped:

panel key line truth pipeline
p010.png "…definitely an Egen guy, Seonho!" the woman Seonho, the person addressed
p010.png "Y-you think so?" Seonho Choi Haeseon
p012.png "Want me to send you the link?" the woman the man
p059.png "If team leader Choi says it, it must be true." the man Choi Haeseon

The last row needs no image: the line refers to Choi in the third person and is attributed to Choi.

The grounded path exists and almost never fires. Only 2 of 81 speech lines got som_face, because attribution marks need face_detect boxes that survive _pair_faces_to_present, and these webtoon close-ups rarely produce them. Inference, not measured: the face detector was not instrumented.

worker_vision.py:356 already carries the ponytail: note that multi-character attribution needs per-balloon geometry. bubble_detect.py:9 records that the det/seg heads carry balloon fill and tail tips and are unused.

Revisit trigger: the share of narrated lines with a named speaker is the Phase 1 headline metric (ROADMAP.md). The 30% read on this run counted attributions the sample says are wrong. The next run will read lower and will be the first honest number. Raising it means binding a balloon to a speaker by tail geometry, using the unused det/seg heads.

One character id covers two different women

character_afa7623b is stored as "black bob, white sweater" and is assigned both to that person (p059.png) and to the brown-bob green-top coworker (p010.png, p012.png). It took 25 of the 26 identity assignments in the chapter, against 113 detected people. Coverage is 23%.

Revisit trigger: any work on the identity Tier-2 decider. A single id absorbing a whole chapter is the signature to watch for.

The character registry carries five weeks of wrong names

The registry holds 53 characters for manga ef105a86, 41 of them unnamed, with "Kei" three times and "Kanade" twice. Kei, Kanade, Zen, Rico, K3, and Watanabe occur zero times in this chapter's text. Only Haeseon and Seonho do. /stage/clear leaves the per-manga registry intact by design, so every rerun inherits the whole pile.

Duplicate rows also make a correct name unresolvable. This manga holds Choi Haeseon, Seonho with aliases ["Lim Seonho", "Seonho"], and a separate Lim Seonho. An answer of "Lim Seonho" matches two rows, so normalize_speaker returns candidates and raises ambiguous-speaker instead of binding. The pipeline read the name correctly and still cannot name the speaker.

Revisit trigger: before any run that is meant to produce a clean baseline. Either scope the registry to a chapter or add a reviewed reset. Merging the duplicate rows needs the reversible-merge design first (caveats/audit-open.md#destructive-reconcile).

One invented word still halts the chapter

The multi-word name failure is fixed (decisions/speaker-attribution.md#multiword-cast-names). The blast radius it exposed is not. run_stage_script retries a rejected beat once, then raises, so a single unsupported token ends the run at that beat. On job 778297bc one of the 29 lost beats cited ['Blur'], an onomatopoeia the model invented. The verifier was right, and the whole chapter still stopped.

Revisit trigger: the next unsupported-proper-noun halt that is a true positive. The likely answer is to flag the beat for review and continue, which is #136 gate work, not a verifier change.