Files
manga-recap-pipeline/JOURNAL.md
T
kami e8941d8ceb Stop labelling a model guess as a read tail
_annotate_speaker_methods stamped `tail`, the highest-trust provenance, on any
line whose speaker matched a present local_id, at gemma's confidence of 1.0. No
balloon was read. Three of three sampled two-character panels had the speakers
swapped, so a multi-character guess is now dropped to unknown, and a solo-panel
guess is kept as model_solo at 0.7.

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

7.8 KiB

JOURNAL

Append-only, newest last. One block per session or run. Not a changelog: this records what happened on the day a number was produced, so a later postmortem can find it.

2026-08-11 Audit second pass [no task]

Command: none. Source reading only. Outcome: finished. AUDIT.md grew from 565 to 771 lines with a ## Second-pass findings section: 4 new P0, 6 new P1, 13 P2, 5 additions to the Phase 1 list. Produced: commit 6d9df5b, AUDIT.md:566.

2026-08-11 Audit Phase 1 implemented [#203]

Command: python worker_scene.py worker_script.py worker_vision.py session_manager.py, pytest -q --ignore=test_api.py in the orchestrator. Outcome: finished. All self-checks pass, 108 orchestrator tests pass. No GPU work, no pipeline run. test_api.py was skipped because fastapi is not installed in the workpc venv. Produced: decisions/audit-phase1.md, caveats/audit-open.md, ROADMAP.md, and this scaffold.

One existing test asserted the bug: test_name_binding.test_conflict_flags_and_stays_unnamed relied on orphan flags leaking into every chapter, because it never created panel rows. It now creates them.

2026-08-11 Orchestrator half committed and deployed [no task]

Command: pytest -q --ignore=test_api.py, then docker compose up -d --build orchestrator on homesrv. Outcome: finished. 108 tests pass. Commits 1c60710 (orchestrator half) and 94bd4d8 (minio pin) in /mnt/server/home/kami/docker-apps. Orchestrator and minio both answer health on homesrv.

The rebuild recreated minio as a side effect and it crash-looped with exec format error: the compose pin was the arm64 manifest digest of minio/minio:latest and homesrv is amd64. Repinned to the amd64 digest. Nothing about Phase 1 caused this, but any compose action that recreates minio would have hit it, so it was latent, not new.

Still unrun against a real chapter.

2026-08-11 S3 viewer and storage swap, tasks #116/#117 [#116 #117]

Command: docker compose on homesrv, dig, openssl s_client. No pipeline, no GPU. Outcome: partial. Viewer works, storage swap staged and unfinished.

#117 needed no new software. stowage at ~/docker-apps/stowage was already configured against the manga MinIO and had been dead since 2026-07-19 with exec /sbin/tini: exec format error: its digest pin was the arm64 manifest. Repinned to amd64 sha256:91be7f13, chowned data/ to uid 65532 for the new image, and it serves. MinIO had the identical bug, repinned to sha256:a1a8bd4a. A sweep of all 470 local images on homesrv found exactly those two arm64; nothing else in the homelab is affected.

#116 is staged, not done. rustfs runs alongside MinIO on 127.0.0.1:9010/9011, pinned sha256:19b105cc, data at /mnt/hdd2/rustfs. Buckets are empty: the mc mirror of audio layers manga panels raw video (350M, all in manga) has NOT run. /mnt/hdd2/minio/data is untouched and is the rollback. RustFS is 1.0.0-beta.12, labeled build-type=prerelease. Cutover would give rustfs 9000/9001 and repoint MINIO_ENDPOINT=minio:9000 in the orchestrator plus stowage/config.yaml; transport.py:95 needs no change if rustfs takes 192.168.1.104:9000.

Side quest, unrelated to the pipeline: the shared 41-domain cert stopped renewing. Root cause was DNS, not nginx. Every *.kvmx.ru name pointed at a hard A record for 109.229.102.117 while the line had moved to 109.229.127.149; the Mercusys DDNS at kvmx-home.mercusysddns.com was correct the whole time but nothing in the zone referenced it. Fixed with CNAME * -> kvmx-home.mercusysddns.com at reg.ru. Certificate now issues.

Two measurement traps worth remembering. The ISP transparently intercepts ports 80 and 443 by Host/SNI, so curl from workpc to ANY address returns kvmx.ru content and proves nothing about external reachability; bare TCP connects also succeed against arbitrary addresses and then hang. Three wrong root causes came out of trusting those probes before checking them.

Also patched ~/scripts/migrate-kvmx-https.sh:54 on homesrv. need_stream_module used sudo -n nginx -V and sudo -n nginx -T; the NOPASSWD rule covers only nginx -t, so it reported "stream module is not loaded" whenever it meant "could not ask for a password". Both checks now run without sudo. bash -n passes and both conditions evaluate true.

2026-08-11 Per-artifact buckets, rustfs buckets, baseline chapter run [#116]

Command: mc mb on rustfs, docker compose up -d --build orchestrator, pytest -q --ignore=test_api.py, ./start_workers.sh, then /job/create + /stage/clear + /job/resume for chapter 7c944dd4-e972-42c7-ba60-9f6939548e80 of "Teto X Egen" as job 778297bc-e7ce-439d-91b5-8a027060d17f. Outcome: partial. Storage split landed and is proven by the run. The run itself was still in direct when the session ended. Produced: decisions/storage-layout.md, caveats/speaker-attribution.md, 109 orchestrator tests pass.

Artifacts now split one bucket per class instead of everything under manga (decisions/storage-layout.md#bucket-per-artifact). Both MinIO and rustfs hold all six buckets. The run put 79 pages in raw and 116 panel crops in panels, so the split works end to end.

Two containers on homesrv had been dead for two weeks and blocked the work. manga-fetch was exited, so /job/create failed with httpx.ConnectError; manga-web was exited, so manga.kvmx.ru had nothing behind it on port 8083. Both started with docker compose up -d. Neither is related to the storage change. Neither was caught by any check, because nothing watches these containers.

Stage timings, 116 panels: crop 85s, vision ~4min, identity ~1min, reconcile ~7min for 35 pairs, dialogue ~8min. Faster than the 2026-07-17 run at 75 panels. The webtoon crop that 500'd in July succeeded this time.

Quality cross-check against the panel images, the point of the run. Dialogue text extraction is accurate. Character detection is accurate. Speaker attribution is not: three of three sampled two-character panels attribute both speakers to the wrong person, always swapped (caveats/speaker-attribution.md#tail-is-not-geometry). 24 of 81 speech lines resolve to a named character, which is the Phase 1 headline metric at 30%, and the sample says that 30% is not trustworthy. 26 of 113 detected people got an identity, and 25 of those 26 went to one character that turns out to cover two different women.

The run then reached scene 116/116 and failed in script at 87/116, not on OOM: 28 beats were rejected by the script verifier as unsupported-proper-noun: ['Choi', 'Haeseon'] (caveats/speaker-attribution.md#multiword-name-verifier). No two-word cast name can pass that check.

2026-08-11 Speaker provenance and the multi-word cast name

Command: .venv/bin/python worker_vision.py, pytest -q --ignore=test_api.py in the orchestrator. Outcome: both pass, 110 orchestrator tests. Nothing deployed, no GPU work, no pipeline run. Produced: decisions/speaker-attribution.md, two caveats rewritten.

_annotate_speaker_methods stopped stamping tail on a model guess. With two or more characters present the guess is dropped to unknown at confidence 0.0. With one present it is kept as model_solo at 0.7, the same claim the solo backstop already makes (decisions/speaker-attribution.md#no-fake-tail). Grounded som_face and solo_prior rows are untouched. Nothing outside worker_vision.py reads the literal tail, checked across both repos.

verify_script now tokenizes each cast name into allowed, so Choi Haeseon passes as two tokens (decisions/speaker-attribution.md#multiword-cast-names). That is the 28 beats job 778297bc lost.

The remaining ['Blur'] beat is a true positive that still halts the whole chapter, now recorded as caveats/speaker-attribution.md#one-word-halts-chapter.

Neither fix is live. The orchestrator container is not rebuilt and the workers are not restarted.