Also suppress groups whose keys sit in closed fixed-local issues (Sonar is not re-scanned between batches).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The rows were added to the DOM but the overflow:auto list was shrunk to zero
height by the flex column panel once the charts filled it. Adds tests for
#n + time rows, error rows and stats arriving after done.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Red while the mic is hot (live or recording), blue when off; label toggles
Stop/Start microphone (DE+EN); pulse only without reduced motion; reset to
blue when microphone access fails.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ID3 provenance tags (synthetic speech, generator, version, date, opt-in
voice name) on magazine MP3/ZIP/EPUB exports via a stream-copied temp copy;
verify endpoint and CLI; AudioSeal tier is a documented stub.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Single-voice health endpoint (GET /api/voices/{id}/health), problems stored in
meta on import, shown in the Try-out voice panel; architecture note and docs.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
"Page N" entries come from review stand-ins created after Approve saved only
the visible page's regions. New core/magazine_untitled.py classifies untitled
entries (continuation, article head, advert, picture page, contents, junk),
proposes merges into the previous article with confidence and evidence
(optional LLM check in the ambiguous band), and suggests titles
(deterministic, optional validated and cached LLM titles). Exposed through
derived GET /articles fields, GET /untitled, quality report, undoable
merge-into-previous / accept-title routes, POST /titles/suggest and
scripts/magazine_untitled.py (dry run by default, --apply backs up first).
Merges mark audio_stale; no audio is deleted; real titles are never
overwritten.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Menu is grouped into View (Picture/Text/Split radios), Show and Playback
(real switches) and Theme (Light|Auto|Dark segmented control). Fixes the
Dark option looking disabled: its data-theme=dark attribute matched the
app-wide dark palette selector. Adds automatic advance to the next article
with audio (switch, default on) with End of magazine state.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Real-library audit (270 records) traced the data damage to:
- identity matching on ANY shared token ("Zwerg", "der Zwerg", "Mann") with
"longer text wins" merging (Arthag b02 = Kolon's species/relationships), and
- csRosterCanonicalName renaming a sheet to the first cast name among its
aliases, which saved 16 whole-sheet copies (Zwerg/Kolon = Arthag b03,
Fremder = Mann, Alchimist = Promos ...).
Fixes:
- static/js/character-identity.js + core/character_records.py: generic labels
are never identity evidence; csFindMergeKey, csConsolidateAliasDuplicates,
csRosterCanonicalName, clSameIdentity use it; own name always wins; clUpsert
writes to the exact-name record before any alias scan; no seed rename onto a
name that has its own record.
- _charsheets_parse: in cast-target mode drop other cast members' names from
aliases / first / last name (Kolon: "Sharraz Garthai"), strip reasoning
leakage ("Warte:", "Der Text sagt ...") from every text field.
- _character_scene_evidence: only a quote naming the character is used,
otherwise its own mannerisms (16 panels showed another character's scene).
- _character_age_category: Junge/Mädchen/boy/girl, number words, Sommer/
Winter ages, evidence clause, age-tagged quotes; "15 Jahre älter" is no age.
- scripts/audit_character_records.py (read-only) and
scripts/clean_character_records.py (dry run by default, --apply backs up).
Tests: tests/test_character_record_hygiene.py, tests/character-identity.test.mjs.
Docs: architecture/character-extraction.md, Manual, CHANGELOG.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Extraction notes in race_species that mention another character's species
("Mensch (oder Zwerg, ...)", "... 'Der Zwerg' wird separat erwähnt ...")
switched on the dwarf body lock (short legs, full beard) for human characters
and carried a sentence about another character into the Subject clause.
Confirmed on the real library: Marrad, Kolon and Arthag (book 02).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>