Adds GET .../articles/{id}/timings (exact per-sentence times via plan_sentences); the player uses them, falls back to the length estimate, and gives captions no time slot.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Fixed 1:1 sizes scaled with clamp(), no flex-shrink/stretch; overlay no longer clips when content is taller than the viewport.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The story moment was a ~5,400-character prompt whose period rules sat at
the end, out of reach of the 4-step model; it opened with "ears clearly
visible" and asked for studio photography by a photographer with a real
actor, and drew a modern man with headphones and a camera in a garden,
captioned with pseudo-text. The prop tile was a stock catalog photo. The
negative prompts were inert because those samplers run at cfg 1.0.
Story moment and signature-item prompts are now short, world-first and
positive-only: The Dark Eye, 900-1300 AD and the book profile's setting
(never the title), the same identity, appearance and costume as the
turnaround, the book moment, a period background and a hand-made,
unmarked world; the item is the character's own, in the craftsmanship
and colours of their costume, on a table in a medieval room. Text and
modern objects are added to the scene and prop negatives.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sheet composer drew light lines between the three poses and between
the top and bottom rows, cutting through capes and swords.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Also reuses the existing magFmtClock for the contents list (the duplicate
tripped the frontend collision gate).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A page either side marks as a full-page ad is skipped by that side's quality
run, so comparing its near-empty boxes against the same page freshly OCR'd
on the other side (ad-marking is a one-time manual step) was a review-state
difference, not a pipeline one, skewing whole-issue numbers. Verified: text
similarity 0.837->0.870, box precision 0.62->0.66 on the real re-import.
Also records the clean from-scratch re-ingest results: the ingest-time
duplicate-check ordering fix is proven in isolation (0 additional duplicates
found afterward, vs 13 before the fix), and the auto-chained Auto-fix ran
end to end.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A fresh import used to stop once laid out, leaving missed text, unverified
OCR and provable misspellings for a separate manual click. _ingest_sync now
runs _quality_run_sync itself, under the same job, so the ingest progress
bar carries through it and the reviewer opens an already-worked magazine.
An Auto-fix failure is reported as an ingest failure without losing the
ingest's own result.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The duplicate detector only ran once, before geometry fixes could merge or
grow a box into one that now duplicates another's text -- narrating it
twice. Now re-run after the geometry loop at ingest and after
recover_missing_text in the whole-issue quality run. Confirmed live: 13
such duplicates in a fresh import, 6 in the already-reviewed magazine.
TODO: F decided unnecessary per user; G updated with both universal fixes
from this pass.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>