Record all six defects and the 9% baseline

Adds decision entries for the unpaired set-of-mark label, the interjection
verifier false positive, and the vision-blob clearing bug, plus the per-run
speaker audit script used to measure the chapter.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 23:59:32 +04:00
parent b68f96a9b2
commit 63f7918a3e
7 changed files with 229 additions and 52 deletions
+64 -49
View File
@@ -1,71 +1,86 @@
# HANDOFF, 2026-08-11 session
# HANDOFF, 2026-08-11 late session
Live state lives in `NEXT.md`. This file is only what this session did.
Live state is in `NEXT.md`. This file is only what this session did.
## Asked
1. Add the buckets to rustfs.
2. Fix the bucket saving on the orchestrator side.
3. Run the title recap.
Continue from the previous handoff: fix speaker attribution, then rerun and re-read the named-speaker
share. Mid-session: what happens to unidentified people in a two-person panel, can a known character be
mis-named, and keep watch during the run.
Mid-session: check `manga.kvmx.ru`, and cross-check whether the run got dialogue and identities right.
## Result
The named-speaker share is **9 of 95 speech lines, 9%**. The previous 30% counted fake tails. All 9 binds
are `Choi Haeseon`, the over-merged row. `script` passed 116/116 for the first time.
**Identity, not attribution, is now the constraint.** 26 of 113 detected people carry an identity. 25 of
the 26 are that one row. This chapter caps near 23% named even with perfect balloon binding.
Six defects, four found by measuring the run rather than by reading code. Each has a decision entry:
| # | defect | entry |
| --- | --- | --- |
| 1 | `tail` stamped on a model guess at confidence 1.0 | `decisions/speaker-attribution.md#no-fake-tail` |
| 2 | a two-word cast name always failed the script verifier | `#multiword-cast-names` |
| 3 | `/stage/clear dialogue` deleted nothing and reported success | `decisions/storage-layout.md#clear-vision-blob` |
| 4 | gemma's speaker answer echoed the prompt label, became a name | `#prompt-label-answers` |
| 5 | `som_face` stamped on a mark that paired to nobody | `#unpaired-mark` |
| 6 | one two-letter interjection halted the chapter at 112/116 | `#interjection-false-positive` |
## Changed
Workers, `/home/kami/Programs/n8n-worker`, branch `restore-runtime`:
Workers, `/home/kami/Programs/n8n-worker`, branch `restore-runtime`, commits `e8941d8 8071137 a965077`
plus docs:
- `worker_crop.py` panels -> `s3://panels/`
- `worker_tts.py` wavs -> `s3://audio/`
- `worker_layers.py` layers -> `s3://layers/`
- `worker_render.py` clips and `chapter.mp4` -> `s3://video/`
- `decisions/storage-layout.md`, `caveats/speaker-attribution.md`, indexes, `JOURNAL.md`, `NEXT.md`
- `worker_vision.py`: `_annotate_speaker_methods`, `_apply_speaker_labels`, new `_present_keys`
- `decisions/speaker-attribution.md` (new, 5 sections), `decisions/storage-layout.md#clear-vision-blob`,
`caveats/speaker-attribution.md`, `caveats/audit-open.md#dishonest-clearing`, both indexes,
`JOURNAL.md`, `NEXT.md`
Orchestrator, `/mnt/server/home/kami/docker-apps/manga-infra/orchestrator`:
Orchestrator, `/mnt/server/home/kami/docker-apps`, commits `b18b6b4 603d388 db8d7c5 ccc3a8e` plus the
interjection commit:
- `minio_layout.py` per-artifact bucket constants, `BUCKETS`, `parse_key` accepts any of them
- `service.py` `_s3_delete_prefix` takes `<bucket>/<prefix>`, `_stage_s3_prefixes` no longer slices,
new `_ensure_buckets` in the lifespan
- `test_minio_layout.py` updated, one test added
Infrastructure, homesrv:
- six buckets created on `rfs` (rustfs, `127.0.0.1:9010`)
- `manga-fetch` started, exited 2 weeks, `/job/create` fails without it
- `manga-web` started, exited 2 weeks, `manga.kvmx.ru` -> nginx -> `localhost:8083`
- orchestrator rebuilt and restarted
- `mc` aliases `mio` and `rfs` now exist on homesrv
- `correctness.py`: tokenized `allowed`, `_ID_SHAPED` guard in `normalize_speaker`, interjection
stopwords, short-quote grounding skip
- `db.py`: `_STAGE_VISION_KEYS` and the strip pass in `clear_stage_data`
- `test_script_verify.py`, `test_correctness.py`, `test_db.py`: one case each
## Measured
Job `778297bc-e7ce-439d-91b5-8a027060d17f`, chapter `7c944dd4-e972-42c7-ba60-9f6939548e80`,
"Teto X Egen", 116 panels.
Job `778297bc-e7ce-439d-91b5-8a027060d17f`, chapter `7c944dd4-e972-42c7-ba60-9f6939548e80`, 116 panels.
- 109 orchestrator tests pass. `worker_crop.py`, `worker_tts.py`, `worker_render.py` self-checks pass.
`worker_layers.py` self-check fails on the missing `legacy/qwen_layered_workflow.json`, which
predates this session.
- buckets after the run: `raw` 64MiB/79, `panels` 101MiB/116, `manga` 366MiB/491, `audio` `layers`
`video` still empty because the run had not reached those stages.
- stage times: crop 85s, vision ~4min, identity ~1min, reconcile ~7min, dialogue ~8min.
- 24 of 81 speech lines resolve to a named character, 30%.
- 26 of 113 detected people got an identity, 23%, and 25 of the 26 went to one character.
- 3 of 3 sampled two-character panels attribute both speakers to the wrong person.
- 113 orchestrator tests pass. `worker_vision.py` self-check passes.
- `dialogue` 116/116, `direct` 116/116, `scene` 116/116, `script` 116/116.
- speech lines 95, named 9. Multi-character panels 0 of 40 by design. Single-character 9 of 55.
- `speaker_method`: `unknown` 47, `model_solo` 28, `solo_prior` 8, `som_face` 7, `turn_taking` 5.
- unresolved name refs 3, all `brown ponytail, green dress`, from a neighbouring panel in the same
8-panel window. Was 24 of 51 before the fix.
- identity assignments 26, of which `character_afa762` "Choi Haeseon" holds 25.
- registry duplicates that block a correct bind: `seonho` matches 2 rows, `lim seonho` matches 2 rows.
- buckets during `tts`: `panels` 116, `raw` 79, `manga` 491, `audio` 1, `layers` 0, `video` 0.
## Open
- The `script` stage failed at 87/116 with `unsupported-proper-noun: ['Choi', 'Haeseon']` on 28 beats.
Not OOM, the worker stayed healthy. One-line fix named in
`caveats/speaker-attribution.md#multiword-name-verifier`. Not applied.
- The run stopped in `direct` at 113/116. `scene script tts layers render assemble` never ran. Resume:
Since then it reached `scene` 116/116 and failed in `script`. Fix the verifier, then:
- **The run is still going.** It was in `tts` at 26/116 when this was written, with `layers render
assemble` unrun. `tts` is the bottleneck. Read it:
```bash
ssh kami@192.168.1.104 "curl -s -X POST http://127.0.0.1:9090/stage/clear -H 'Content-Type: application/json' -d '{\"job_id\":\"778297bc-e7ce-439d-91b5-8a027060d17f\",\"stage\":\"script\"}'"
ssh kami@192.168.1.104 "curl -s -X POST 'http://127.0.0.1:9090/job/resume?job_id=778297bc-e7ce-439d-91b5-8a027060d17f'"
/usr/bin/ssh kami@192.168.1.104 "curl -s 'http://127.0.0.1:9090/job/status?job_id=778297bc-e7ce-439d-91b5-8a027060d17f'"
```
- Speaker attribution is wrong in multi-character panels and the fix is not written
(`caveats/speaker-attribution.md`). No code was changed for it.
- Objects from the 2026-07-17 run still sit under `manga/<manga_id>/<chapter_id>/{pages,panels,audio,
layers,clips}`. Nothing reads them. They are the rollback, not live data.
- `rustfs` holds empty buckets. No mirror, no cutover.
If it failed, clear the failed stage and resume:
```bash
/usr/bin/ssh kami@192.168.1.104 "curl -s -X POST http://127.0.0.1:9090/stage/clear -H 'Content-Type: application/json' -d '{\"job_id\":\"778297bc-e7ce-439d-91b5-8a027060d17f\",\"stage\":\"<stage>\"}'"
/usr/bin/ssh kami@192.168.1.104 "curl -s -X POST 'http://127.0.0.1:9090/job/resume?job_id=778297bc-e7ce-439d-91b5-8a027060d17f'"
```
Note: plain `ssh` is the kitty ssh kitten and refuses non-interactive stdin. Use `/usr/bin/ssh`.
- Defects 5 and 6 landed after `dialogue` had already run, so this run's 7 `som_face` lines are still
labelled from the unpaired-mark path. The next dialogue pass fixes that. No name was affected.
- The audit script is `docker exec manga-orchestrator python3 /tmp/audit_speakers.py`, source in this
session's scratchpad. It is not in the repo. Copy it in if the metric is to be tracked per run.
- The 3 cross-panel unresolved refs need the window's whole present-list, not one panel's.
- Workers were restarted twice this session and are running in tmux `manga-workers`. Nothing watches
them, and nothing watches the homesrv containers.