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>
The gallery gemma chose from was the union of the tracklet members' cosine
shortlists. Cosine cannot separate people on this data, so a metric that
cannot tell two men apart decided who gemma was allowed to consider, and the
right character was often not on the list.
The gallery is now the live cast: gender-compatible rows from
get_known_characters, named first, capped, re-read per tracklet so a minted
character is visible to later ones. Every crop reaches the resolver now,
including one whose cosine top-k was empty; those used to be dropped.
worker_vision spreads reference images across a budget instead of sending 3
per candidate, so a 9-character cast costs 9 images and not 27.
Ran on a GPU, 19:44-19:52 UTC. The lead's assignments drop from 36 to 16 and
14 of the 16 are him; the other two are art inside a panel.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The user checked the lead's crops. LIM SEONHO's 36 assignments cover at least
six different men, a chibi and a cat, so 36 of 68 is a bug. 22 came from
native resolves and 14 from reconcile merges.
Two fixes are written in the orchestrator repo, tested, not deployed and not
run on a GPU. `link_tracklets` caps a tracklet's panel span, because `window`
bounded each pair while transitivity was unbounded and the lead's 22 native
assignments came from tracklets spanning 22 and 30 panels. And one shared
appearance tokenizer drops generic words, because whole chains hung on the
word `short` and one pair on the word `hair`.
The obvious third fix is ruled out by measurement. Over all 22 crop
embeddings, the cat scores up to 0.82 against men, two different men score
0.93, and the highest pair is 0.96. No threshold separates them, so
crop-to-crop cosine is not a link signal.
Item 1 of the agreed plan, sending the live cast instead of a cosine top-k
gallery, is not started.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`_bbox_to_pixels` sorts each coordinate pair after clamping. Run B returned
`p007 person_1` as `[226, 417, 130, 551]`, x1 > x2, which cropped to nothing
and lost that detection silently. The third GPU cycle came back with 0
degenerate boxes over 119 detections.
The plan's first item cannot run as written. All 145 rows of `identity_labels`
belong to chapter 8ca8249b, a different manga. Chapter 7c944dd4 has none, so
`/review/identity` reports `accuracy: null`. Scoring 8ca8249b gives 7/138 on
an identity run that predates every fix.
The cycle also settled the coverage question. All 68 assignments landed on
face-bearing detections and none on a gated one, so recall among face-bearing
detections is 96%, up from 82%. Coverage is the `has_face` gate and nothing
else. What is now open is precision: the lead holds 36 of 68 assignments.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
No worker code changed. This is the evidence from the 2026-08-12 16:39 and
17:38 runs, and where each finding now lives.
The fourth session's four identity changes all work on real panels. Panel 7's
two wrong bindings are gone. The lead going unassigned there is correct and
was measured, not assumed: face_detect finds one face on the whole panel at
conf 0.599, nothing else above 0.056 even at a 0.04 threshold, and the crop
shows him drawn from behind.
Two decisions, both closed: a roster name is a guess so it never reaches
detection, and merged_into is exactly one hop deep. Two caveats, both open:
detection can order a bbox backwards (1 in 117), and identity coverage has
fallen on every run since the gate landed (70 -> 61 -> 50).
Coverage is the thing to settle next, and not by reading the number.
identity_labels already holds 145 rows of ground truth.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The registry reset deleted Lim Seonho and character_afa7623b, so there is nothing
to merge or split until the rerun mints a new set. What was done instead is the
safety net for that rerun, since reconcile runs inside it: a merge retires the
losing row rather than deleting it, and records which assignments moved.
Half-closes caveats/audit-open.md#destructive-reconcile. The unmerge path and the
split stay unwritten on purpose, with the revisit trigger named.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The run completed: chapter.mp4 at 50MiB from 49 clips. layers reported
completed 116/116 with an empty bucket, so nothing has parallax, and the completed
job still carries the error string from a failure three resumes earlier. Both
recorded as caveats, neither fixed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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>
Implements every P0 from AUDIT.md plus four P1s, across both halves of the
pipeline. Verified by CPU-only self-checks and the orchestrator test suite.
No GPU work ran and no pipeline ran.
workpc:
- worker_scene: read speaker_ref, not the rewritten speaker field. Every line
narrated as "Someone" before this. Emit `actions` for the verifier.
- worker_script: declare beat + verifier_feedback (pydantic dropped both, so
the retry was blind) and render them as a repair prompt.
- worker_vision: gate face->identity pairing on containment, assign globally
shortest-first, map an out-of-range resolver index to `unresolved` instead
of minting a character, parse JSON with raw_decode.
- session_manager: tear down a server whose lease vanished mid-load, and spawn
the supervisor respawn unlocked.
orchestrator (edited in place, NOT committed there):
- tracklets: canonicalize gender, add co-presence cannot-links, block
transitive bridges across a hard constraint.
- correctness: stop failing valid narration on sentence-initial capitals and
short quotes; read action evidence from the singular key.
- db: stop orphan flags leaking into every chapter; resolve by flag id.
- service: TTS returns instead of raising under GATES, auto-resolves under
autonomous mode; job admission control; registry names on dialogue resume.
- session_proxy: queue on 409 instead of stealing the lease; run heartbeats.
Docs restructured per the repo-structure layout: CLAUDE.md is a pointer table,
NEXT.md replaces HANDOFF.md, plus ROADMAP.md, JOURNAL.md, decisions/ and
caveats/. AUDIT.md now points at those instead of restating them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XD7cAy81MZrc7gCr6aZGWr