# HANDOFF, 2026-08-13 (ninth session) Live state is in `NEXT.md`. This file is only what this session did. The previous handoff is in `JOURNAL.md`. ## Asked Get up to speed from the eighth handoff, pick the next work, then commit to `master`. Then: can the merged-panel bug be fixed. ## Result No GPU work. No stage ran. `master` is at `bc19f9e` and pushed, plus the crop fix below still to commit. `ARCHITECTURE.md` step 0, the measurement spine, is built for the character half and its DoD is met. ## Landed | what | where | | --- | --- | | `eval/chapter-truth.json`, 38 labelled occurrences | new file | | purity and fragmentation, plus a `--selftest` | `audit_registry.py` | | a short slice is absorbed, not dropped | `worker_crop.py:slice_webtoon` | | the design, 4 sections | `decisions/measurement-spine.md` | ### Step 0, the measurement spine ``` truth: 38 labelled occurrences, 38 matched an assignment at IoU >= 0.5, 0 unmatched LIM SEONHO [b1dd5659] lead 14/16 = 0.88 = baseline (wrong: photo_of_lead 1, chibi_of_lead 1) character_2b1b12a1 woman_a 13/13 = 1.00 = baseline Seonho [f0d4e901] woman_b 7/9 = 0.78 = baseline (wrong: woman_a 2) fragmentation lead 1, woman_a 2, woman_b 1 all = baseline ``` Rows key on page-space geometry. Purity is the largest share of one true person in a cluster. Fragmentation is the count of ids holding one person. So neither needs a `character_id`. The file survives the re-crop and the `/characters/reset` that the fifth cycle runs. That was the handoff's open ordering trap. `NEXT.md` said 2 of woman B's 9 crops were really woman A and never said which. They are `panel_order` 31 and 33, identified from `p030` and `p032`. ### The crop fix, answering "can we fix the merged panels bug" There is no merged-panel bug. `_merge_plan` only groups adjacent fragments and `slice_webtoon` cuts at gutter midpoints, so a vstacked panel's `[x, y0, w, sum(heights)]` is the exact page region. The real defect was one line up. A segment under `min_seg=64` was skipped outright, so the 116 panels have a 62px hole between `panel_order` 70 and 71 and lose 18px at the strip's end. A merge spanning that hole would report a bbox 62px short of the page span. Every page-space mapping across it would then be wrong by that much, silently. The 62px held the credits line at `p_050.png` row 338. `slice_webtoon` now absorbs a short band into its neighbour (`decisions/measurement-spine.md#slices-tile-the-strip`). ### Audit fixes, all pre-existing - 20 characters counted where 14 are live and 6 are merge losers kept on purpose - the assignment spread keyed on `name`, so the two characters named `Seonho` summed into one line of 11 - the default worked example was `panel_index` 7, a panel vision skips. `NEXT.md`'s "panel 7" is `panel_order` 7, one lower, the office shot with 6 detections - nothing about skipped panels. 41 of 116 are `skip=True`, four checked and all four correct ## Open - **Step 0's dialogue half.** 30 lines with their true speaker, typed `visible | offscreen | narrator | unknown`. `dialogue` is an empty array in the truth file. It needs the chapter watched panel by panel, because no per-line speaker truth exists anywhere to transcribe. - **28 of 122 dialogue lines sit on skipped panels**, which hold no character at all. 23% of dialogue cannot resolve to a visible speaker under any linker. This is the measured case for `offscreen` as a fourth `speaker_ref` kind, and it is not built. - The eighth handoff's five unapplied audit findings are all still unapplied, `gemma.py` first. ## Checks ```bash .venv/bin/python audit_registry.py --selftest # IoU match, greedy tie-break, purity maths .venv/bin/python worker_crop.py # the slice must tile the strip with no hole ruff check . # All checks passed ``` The live audit ran against `/data/manga.db` in `manga-orchestrator` and reproduced every baseline number. Both files must be inside the container and a rebuild drops them, recipe in `AGENTS.md`. ## Next command The fifth GPU cycle, unchanged as the next pipeline work, and now measurable on both sides. The GPU is idle. The workers are **down**, so it starts with `./start_workers.sh` then `./check_stale.sh`. `slice_webtoon` changed, so the re-crop is now mandatory rather than merely planned, and **clear `s3://panels///panels/` first** or `crop_webtoon` keeps the old images. Run the audit after the cycle and compare against `= baseline`. Expect the panel count to drop and one panel to grow by 62px. A row printed as `unmatched` means the detection moved more than half its area.