63f7918a3e
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>
163 lines
10 KiB
Markdown
163 lines
10 KiB
Markdown
# 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.
|
|
|
|
## 2026-08-11 Rerun from dialogue: the honest speaker number is 9%
|
|
|
|
Command: `/job/cancel`, `/stage/clear dialogue`, `./start_workers.sh`, `/job/resume` on job
|
|
`778297bc-e7ce-439d-91b5-8a027060d17f`, twice. `docker compose up -d --build orchestrator` three times.
|
|
Outcome: `dialogue` 116/116. 112 orchestrator tests pass, `worker_vision.py` self-check passes.
|
|
|
|
The named-speaker share is 9%, 9 of 95 speech lines, down from a reported 30% that counted fake tails.
|
|
Multi-character panels contribute 0 of 40 lines by design. Single-character panels give 9 of 55. All 9
|
|
binds are `Choi Haeseon`, the row that covers two different women.
|
|
|
|
Five defects, four of them found by measuring the run rather than by reading code.
|
|
|
|
1. The fake `tail` label, fixed before the run (`decisions/speaker-attribution.md#no-fake-tail`).
|
|
2. The multi-word cast name in the script verifier
|
|
(`decisions/speaker-attribution.md#multiword-cast-names`).
|
|
3. `/stage/clear dialogue` deleted nothing and reported success. dialogue and direct write onto the
|
|
per-panel vision blob and had no `_STAGE_TABLES` entry, so `run_stage_dialogue` saw
|
|
`"dialogue" in vision` and would have skipped all 116 panels. The proof is the second clear:
|
|
116 dialogue blobs and 75 direct blobs stripped that the first had left. This is
|
|
`caveats/audit-open.md#dishonest-clearing` firing exactly where it was filed.
|
|
4. gemma answers the speaker field with whatever the prompt showed, most often the character
|
|
description, and every such answer became a free-form name that no registry entry matched. 28 of 51
|
|
sampled lines (`decisions/speaker-attribution.md#prompt-label-answers`). After the fix, 3 of 95.
|
|
5. All 7 `som_face` lines pointed at a mark whose face paired to no present character, so the
|
|
highest-trust provenance sat on a line with no speaker. Same defect class as the fake tail.
|
|
|
|
Identity is now the binding constraint, not attribution. 26 of 113 detected people carry an identity,
|
|
23%, and 25 of the 26 are the one over-merged row. Even perfect balloon binding caps this chapter near
|
|
23% named. The person who does hold an identity is stored as `Lim Seonho` while a separate row is named
|
|
`Seonho` with alias `Lim Seonho`, so either name matches two rows, raises `ambiguous-speaker` and binds
|
|
nothing.
|
|
|
|
Two more defects surfaced after `dialogue` finished. All 7 `som_face` lines pointed at a mark whose face
|
|
paired to no present character (`decisions/speaker-attribution.md#unpaired-mark`). Then `script` halted
|
|
at 112/116 because the narrator wrote `"...Hm?"` for the source line `"Uh... hum...?"`, and both verifier
|
|
rules fired on that two-letter interjection
|
|
(`decisions/speaker-attribution.md#interjection-false-positive`). After the fix, `script` passed 116/116,
|
|
the first time this chapter has cleared the verifier. `tts` then ran for the first time.
|