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
+31 -17
View File
@@ -39,28 +39,42 @@ contain the right person. Coverage is still the `has_face` gate plus those refus
## Next
1. **Deploy the two tracklet fixes and run the fourth cycle.** Neither has touched a GPU. Rebuild the
orchestrator image, reset the registry, run vision/identity/reconcile, then re-check the lead's crops.
Expect roughly 30 tracklets over 64 crops instead of 12, so identity goes from about 1m25s to 3 or 4
minutes. Watch the lead's assignment count against 36.
1. **Re-crop the chapter and run the fifth cycle.** Four changes are written and tested since the fourth
cycle, and none has touched a GPU.
Neither fix is sufficient. Bare hair colour still links different men, and the cat still joins its
neighbours. Do not add a crop-to-crop cosine to close that: measured on this run's 22 embeddings,
different people reach 0.93 while the same person reaches 0.96, so no threshold exists
(`caveats/audit-open.md#cosine-not-identity`).
- `merge_faceless_captions` is wired into both crop endpoints. It was written, never called, and
`context_fragment_links` was called instead. A stranded caption fragment now vstacks into the
face-bearing fragment it belongs to, so panel count and every panel index change.
- three naming fixes in `db.add_name_claim` (`decisions/identity-naming.md`): alias grouping, a caption
as strong evidence, and a name held by another character refusing to promote onto a second one.
Agreed next step after the cycle, chosen by the user and not started: **stop letting cosine pick the
gallery.** There are 9 live characters. `run_stage_identity` builds `union_cands` from the members'
cosine top-k shortlists, so a metric that cannot separate people decides who is even considered. Send
the live cast instead, gender-gated, capped and logged when truncated. Note two traps found while
reading it: `/vision/resolve` sends up to 3 reference images per candidate
(`worker_vision.py:1057`), so 9 candidates is 27 images plus the query and needs a cap; and only a crop
with a non-empty cosine shortlist enters `shortlists` at all, so an empty top-k currently drops the crop
from resolution entirely.
**Clear `s3://panels/<manga>/<chapter>/panels/` before re-cropping.** `crop_webtoon` skips the upload
when the key exists, so a re-crop after a slicing change silently keeps the previous run's images.
Wiring the merge is a slicing change. Everything downstream is invalidated by it, so this is a full
re-run and not a stage rerun.
Expected: fewer than 116 panels, `2b1b12a1` named `Choi Haeseon` from the p040 caption, the lead's
`conflicting-name-claims` flag gone, and the green-dress woman no longer named `Seonho` but carrying a
`name-already-taken` flag instead.
Not fixed by any of it. Bare hair colour still links different men. Do not add a crop-to-crop cosine to
close that. Measured on 22 embeddings, different people reach 0.93 and the same person reaches 0.96, so
no threshold exists (`caveats/audit-open.md#cosine-not-identity`).
Then, separately, test embedding the FACE box rather than the person box. `face_detect` already finds
the face and pairs it for `has_face`. That is the likely root cause of cosine measuring scene instead of
person, and the test is to re-embed these same 22 detections and recompute the matrix.
person. The test is to re-embed these same 22 detections and recompute the matrix.
1b. **The head/body split that started the crop question is NOT fixed.** The wired merge only folds a
fragment that has text and no face. A body fragment carries no dialogue, so `_merge_plan` leaves it
solo and it becomes its own panel and its own shot. Finding it needs a different signal, most likely a
face touching the bottom edge of one fragment with a textless fragment below. No evidence has been
gathered yet on how often this chapter does it.
1c. **Three items from `ARCHITECTURE.md` are cheap against the current code.** A `plane` field per
detection for art-in-art, same-panel co-presence demoted to a weak cannot-link once the plane exists,
and `offscreen` as a fourth `speaker_ref` kind.
2. ~~**Order the corners in `_bbox_to_pixels`.**~~ **Done 2026-08-12, run and verified on a GPU.** 0
degenerate boxes over 119 detections (`decisions/identity-bbox.md#bbox-corners-ordered`).
3. **Vision boxes animals as people and dresses them.** `p081` and `p108` are cats, described