Wire the caption merge, and write the target architecture down

merge_faceless_captions had been written and never called; both crop
endpoints called the non-destructive context_fragment_links instead, with no
decision recording that choice. Wiring it changes panel count and every panel
index, so the chapter needs a re-crop with the panels prefix cleared first --
crop_webtoon skips an upload when the key already exists, which is right for a
resume and silently wrong after a slicing change. Noted at the line.

It does not cover the head-in-one-shot body-in-the-next split that prompted
the question. _merge_plan only folds a fragment that has text and no face.

ARCHITECTURE.md is the target shape from the user's design, with what exists
against each section today. Nothing in it is built.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 00:39:57 +04:00
parent a386e9d910
commit 97cb4831f9
7 changed files with 495 additions and 21 deletions
+6 -2
View File
@@ -48,5 +48,9 @@ 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 |
| [A tracklet is bounded by span, not only by pairwise distance](identity-bbox.md#tracklet-span-cap) | closed |
| [A generic word is not identity evidence, and one tokenizer serves both consumers](identity-bbox.md#generic-tokens) | closed |
| [The gallery is the live cast, not cosine's top-k](identity-bbox.md#cast-is-the-gallery) | closed |
| [A name is a word set, not a string](identity-naming.md#alias-grouping) | closed, GPU pending |
| [A confident caption names a character on its own](identity-naming.md#caption-is-strong) | closed, GPU pending |
| [A name belongs to one character](identity-naming.md#one-name-one-character) | closed, GPU pending |
+51
View File
@@ -0,0 +1,51 @@
# Naming a character
How a discovered name reaches `characters.name`. The mechanism is `db.add_name_claim`, fed by the dialogue
stage through `service._absorb`.
## A name is a word set, not a string {#alias-grouping}
**Closed, 2026-08-13, not yet run on a GPU.**
Claims grouped on the casefolded name, so `Lim Seonho` from a p010 caption and `Seonho` from a p047 address
counted as two names for one character. `len(grouped) > 1` fired, a `conflicting-name-claims` flag was
filed, and promotion was blocked permanently on evidence that in fact corroborated.
`alias_groups` groups two names when one's word set contains the other's, and keeps the longer as
canonical. `Seonho` and `Lim Seonho` are one name and the registry stores `Lim Seonho`. `Seonho` and
`Haeseon` are still two, so a real conflict still flags.
## A confident caption names a character on its own {#caption-is-strong}
**Closed, 2026-08-13, not yet run on a GPU.**
Promotion needed two distinct panels, or one `self_intro` or `name_tag` claim above 0.9. On the 2026-08-12
chapter the only claim naming a main character was `Choi Haeseon`, a caption at p040 at confidence 1.0, and
it was discarded. She held 13 correct crops and stayed anonymous through the whole pipeline.
A caption is the narration naming the person it is drawn beside, which is how a webtoon introduces its
cast, so it joins `STRONG_EVIDENCE`. This is the loosest of the three changes and is only safe because of
the next one.
## A name belongs to one character {#one-name-one-character}
**Closed, 2026-08-13, not yet run on a GPU.**
Being addressed by name identifies the addressee. Choosing which drawn body that is fails often. Two panels
addressed `Seonho`, the dialogue model pointed `target_local_id` at the woman standing beside him, and two
independent claims promoted her. The registry then held a female `Seonho` over 9 crops beside the lead's
`LIM SEONHO`.
A promotion now checks every other live character of the same manga first, by alias group. A collision
refuses the promotion and files a `name-already-taken` flag carrying both ids. The collision is itself
evidence that either the addressee or the identity cluster is wrong, so it is worth surfacing rather than
resolving silently.
Deliberately not built: no attempt to decide WHICH character deserves the name. That needs the addressee
fixed, which is `ARCHITECTURE.md` section 3.
## Checks
`test_name_binding.py` replays the six real claims from the 2026-08-12 chapter. Each new assert was
confirmed to fail with its fix disabled: the caption test with `STRONG_EVIDENCE` reverted, the alias test
with casefold grouping restored. The taken-name test asserts a flag kind that only the new branch emits.