Files
manga-recap-pipeline/HANDOFF.md
T
kami 0d281016e7 Cut the dead attic workers, and file what the audit left standing
attic/worker_ocr.py and attic/worker_parse.py are 224 lines imported by nothing
and named in no doc. The OCR stage was removed when narration moved to the
director beat. The two design notes in attic/ stay, they are history.

worker_vision._panel_size had one reference and it was the definition.

The audit's larger finding is filed rather than fixed: call_gemma4,
_extract_json and _strip_thought exist in both worker_vision and worker_script
and have already diverged. That matters because the JSON repair pass can
fabricate dialogue, so a fix would land in one copy and not the other. It is
caveats/audit-open.md#gemma-helpers-duplicated with its revisit trigger.

HANDOFF.md carries the rest: _wrap2 against textwrap, the duplicated ONNX
preprocessing, and worker_layers pointing at a legacy/ directory that was never
tracked in git.

Checked: ruff clean, worker_vision and worker_render self-checks pass.

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

5.4 KiB

HANDOFF, 2026-08-13 (eighth session)

Live state is in NEXT.md. This file is only what this session did. The previous handoff is in JOURNAL.md.

Asked

Push the repo to Gitea and open a PR to master. Then, from the PR review: fix the s3 URI constants, run ruff and fix what it finds, push, run a ponytail audit, fix, push, merge. Then audit.

Result

No GPU work. Nothing ran on a pipeline stage. PR #1 is open at https://gitea.kvmx.ru/kami/manga-recap-pipeline/pulls/1, master <- restore-runtime.

master held only the reconstruction commit ff6a512. All 27 commits of real work sat unpushed on restore-runtime.

Landed

commit what
12d4ed8 the ARCHITECTURE.md rewrite, which was finished but uncommitted
be63b22 deleted a 0-byte file named II, d[i+4:i+12]))\n"; done, added by 8113bdf
bec9411 s3 URI templates into transport.py, plus ruff.toml and the lint fixes

S3 URIs

Eight templates now live in transport.py: PANEL_URI, PAGE_PANEL_URI, AUDIO_URI, AUDIO_FLAT_URI, LAYER_URI, CLIP_URI, CHAPTER_URI, CHAR_PNG_URI, CHAR_NPY_URI. Five workers formatted their own before.

transport.ids_from_uri replaces three separate copies of the same parse in worker_tts, worker_layers and worker_render. It raises on a uri too short to carry the ids instead of returning a wrong pair. worker_render._mc_from_uri is gone, its 6 call sites repointed.

Lint

ruff check . exits 0. Ruff's defaults found 115. Fixed: implicit Optional in 8 signatures, an unparenthesized implicit concatenation inside the ASS filter list, 5 subprocess.run calls now saying check=False out loud, 1 unused import, 1 duplicate exception handler, 1 non-executable shebang, 4 dict() calls and 2 startswith chains.

12 rules are off in ruff.toml, each with its reason. The ASYNC ones matter: ffmpeg and ffprobe run synchronously inside async def endpoints, so a busy worker cannot answer /health. That is already caveats/audit-open.md#blocking-event-loop, tracked as [#199], and it needs a per-handler refactor rather than a lint fix.

CLAUDE.md said "There is no lint or build step". It now names ruff check . and the rule that every output URI is a template in transport.py.

Audit findings

Applied:

  • delete: attic/worker_ocr.py and attic/worker_parse.py, 224 lines, imported by nothing and named in no doc. attic/char-recognition.md and attic/plan-workpc.md kept, they are design history.
  • delete: worker_vision._panel_size, 8 lines, one reference and it is the definition.

Found and NOT applied, in order of size:

  • shrink: call_gemma4, _extract_json and _strip_thought each exist twice, in worker_vision.py and worker_script.py, and have already diverged. worker_vision.call_gemma4 is 21 lines and takes a content list, worker_script's is 8 and takes a prompt string plus a system prompt. The two _extract_json bodies carry the same comment about raw_decode but different error text. This is the live risk: caveats/audit-open.md#repair-fabricates says the JSON repair pass can fabricate dialogue, and a fix would land in one copy. A shared gemma.py costs one new file and removes about 25 duplicated lines. Not done because it touches the two largest workers and nothing has run on a GPU since.
  • stdlib: worker_render._wrap2, 16 lines of greedy word-wrap with a 2-line cap, is close to textwrap.wrap(text, width, max_lines=2, placeholder="…"). Not identical: _wrap2 does rstrip(".,") before the ellipsis, and textwrap reserves width for the placeholder, so the break points differ. It renders burned-in subtitles, so the diff is user-visible. Verify against the render self-check before swapping.
  • shrink: _letterbox and _load are duplicated between bubble_detect.py and face_detect.py, two ONNX detectors with the same preprocessing. About 16 lines.
  • delete: worker_layers.py:14 points LAYERED_WORKFLOW at legacy/qwen_layered_workflow.json. legacy/ was never tracked in git and is absent from disk, so the module's self-check has never been able to pass here. This is the other half of caveats/audit-open.md#layers-writes-nothing.

Checks

ruff check .                          # All checks passed
.venv/bin/python worker_render.py     # ok, ffmpeg ran, about 4 minutes

Self-checks pass: transport, collage, bubble_detect, test_vision_parse, worker_crop, worker_scene, worker_script, worker_identity, worker_tts, session_manager, worker_vision, worker_render, face_detect.

worker_layers fails, and did before this branch, on the missing legacy/ file above.

Next command

The fifth GPU cycle is still the next pipeline work. It is blocked only on the GPU being free. The exact sequence is in JOURNAL.md under the seventh session, and NEXT.md item 1 holds the expectations. Clear the panels prefix first or the wired caption merge will not take effect.

Before that, or instead of it while the GPU is busy, ARCHITECTURE.md step 0 is the measurement spine: eval/chapter-truth.json plus purity and fragmentation printed by audit_registry.py.

One ordering trap, unresolved: the truth file cannot be keyed on panel_id or character_id. The fifth cycle re-crops and calls /characters/reset, which destroys both. Key it on page-space geometry, or write it after the fifth cycle rather than before.