ARCHITECTURE.md step 0. eval/chapter-truth.json holds the 38 occurrences the user walked crop by crop on the 19:44 run of 2026-08-12, and audit_registry.py now prints purity per cluster and fragmentation per person against it. All six baseline numbers reproduce. Rows key on page-space geometry, purity is a share, and fragmentation is a count of ids, so nothing in the file names a panel_id or a character_id. The fifth cycle re-crops and calls /characters/reset, and the file survives both. That was the ordering trap in the handoff. 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. Four fixes to the audit itself, 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 Seonhos summed into one line - the default worked example was panel_index 7, a panel vision skips. NEXT.md's "panel 7" is panel_order 7, one lower - nothing about skipped panels. 41 of 116 are skip=True, four checked and all four correct, and they hold 28 of the chapter's 122 dialogue lines That last count is the measured case for an offscreen speaker_ref kind: 23% of dialogue sits on panels with no character to attribute to. Checks: audit_registry.py --selftest covers the IoU match, the greedy tie-break and the purity maths with no database. ruff check . exits 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3.2 KiB
Repository guidance
Restarting one worker
Python binds a module at process start, so a worker keeps serving the code it loaded. Run
./check_stale.sh before any stage run meant to prove a change. It exits non-zero and names the tmux
window for every worker older than its file (decisions/identity-bbox.md#stale-worker-invalidates).
tmux respawn-window -k does not re-run the window's command. It leaves a bare shell and the worker
stays down, silently. Restart by re-sending the send-keys line from start_workers.sh for that one
worker, then confirm on /health and with check_stale.sh:
M="export MIOPEN_USER_DB_PATH=$HOME/.config/miopen MIOPEN_SYSTEM_DB_PATH=$HOME/.config/miopen MIOPEN_FIND_MODE=2 && unset MIOPEN_FIND_ENFORCE"
tmux send-keys -t manga-workers:vision C-c
tmux send-keys -t manga-workers:vision "$M && source $PWD/.venv/bin/activate && python -m uvicorn worker_vision:app --app-dir $PWD --host 0.0.0.0 --port 8002" C-m
curl -s http://127.0.0.1:8002/health && ./check_stale.sh
The orchestrator's equivalent is docker compose up -d --build orchestrator on homesrv, because the image
bakes its source. That recreates the container, which drops any docker cp'd file such as
audit_registry.py.
Measuring the registry
audit_registry.py reads /data/manga.db, so it runs inside the container and needs two files copied
in. Both are dropped by a rebuild. From this repo, on workpc:
tar cf - audit_registry.py eval/chapter-truth.json | /usr/bin/ssh kami@192.168.1.104 \
"cat > /tmp/audit.tar && docker cp /tmp/audit.tar manga-orchestrator:/tmp/ \
&& docker exec manga-orchestrator tar xf /tmp/audit.tar -C /app \
&& docker exec manga-orchestrator python3 /app/audit_registry.py"
.venv/bin/python audit_registry.py --selftest # the IoU match and purity maths, no db needed
It prints purity and fragmentation against eval/chapter-truth.json, which is the 19:44 run of
2026-08-12 walked crop by crop (decisions/measurement-spine.md). Every baseline line says
= baseline or the delta, so a regression is visible without reading the numbers.
Traps. The audit's second argument is panel_index, and NEXT.md's "panel 7" is panel_order 7, one
lower. A truth row matches on page-space geometry at IoU 0.5. A row printed as unmatched means the
detection moved more than half its area, not that the character was lost.
Video analysis
When diagnosing render motion, transitions, timing, or visual artifacts, use
scripts/analyze_video_frames.sh instead of manually seeking through the video.
scripts/analyze_video_frames.sh VIDEO [OUTPUT_DIR] \
--window START:DURATION [--window START:DURATION ...]
The script creates:
- timestamped overview contact sheets sampled at 2 fps;
- scene-change frames and a
scene-timestamps.txtindex; - optional dense 10-fps contact sheets for specified transition windows.
Inspect the overview first, then request dense windows around transitions or artifacts. Sampling and
scene sensitivity can be adjusted with OVERVIEW_FPS, WINDOW_FPS, and SCENE_THRESHOLD.
The generated files are analysis artifacts and belong in /tmp or another requested output directory;
do not commit them to the repository.