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>
132 lines
3.0 KiB
JSON
132 lines
3.0 KiB
JSON
{
|
|
"core": [
|
|
"voice-picker",
|
|
"benchmark-voice-picker",
|
|
"voice-inspector",
|
|
"seed-finder",
|
|
"voice-sources",
|
|
"fishaudio-browser",
|
|
"voice-cache",
|
|
"jobs",
|
|
"image-cache",
|
|
"integrations",
|
|
"routing",
|
|
"voice-clone",
|
|
"voice-library",
|
|
"tts-preview",
|
|
"generation",
|
|
"benchmark",
|
|
"stt",
|
|
"namespace"
|
|
],
|
|
"lazy": {
|
|
"s-rehearser": [
|
|
"rehearser-parse",
|
|
"rehearser-cast",
|
|
"rehearser-train",
|
|
"rehearser-training-ui",
|
|
"rehearser-voice-design",
|
|
"rehearser-io",
|
|
"rehearser-playback",
|
|
"rehearser-recording",
|
|
"rehearser",
|
|
"rehearser-library",
|
|
"rehearser-stage",
|
|
"rehearser-voice-picker"
|
|
],
|
|
"s-reader": [
|
|
"rehearser-parse",
|
|
"rehearser-cast",
|
|
"rehearser-train",
|
|
"rehearser-training-ui",
|
|
"rehearser-voice-design",
|
|
"rehearser-io",
|
|
"rehearser-playback",
|
|
"rehearser-recording",
|
|
"rehearser",
|
|
"rehearser-library",
|
|
"rehearser-stage",
|
|
"rehearser-voice-picker",
|
|
"character-identity",
|
|
"characters-library",
|
|
"reader",
|
|
"audiobook/network",
|
|
"audiobook-parse",
|
|
"audiobook-segmentation",
|
|
"audiobook-spans",
|
|
"audiobook-cast",
|
|
"audiobook-pipeline",
|
|
"audiobook-cast-spans",
|
|
"audiobook-preview-export",
|
|
"audiobook",
|
|
"character-sheets"
|
|
],
|
|
"s-library": [
|
|
"rehearser-parse",
|
|
"rehearser-cast",
|
|
"rehearser-train",
|
|
"rehearser-training-ui",
|
|
"rehearser-voice-design",
|
|
"rehearser-io",
|
|
"rehearser-playback",
|
|
"rehearser-recording",
|
|
"rehearser",
|
|
"rehearser-library",
|
|
"rehearser-stage",
|
|
"rehearser-voice-picker",
|
|
"character-identity",
|
|
"characters-library",
|
|
"reader",
|
|
"audiobook/network",
|
|
"audiobook-parse",
|
|
"audiobook-segmentation",
|
|
"audiobook-spans",
|
|
"audiobook-cast",
|
|
"audiobook-pipeline",
|
|
"audiobook-cast-spans",
|
|
"audiobook-preview-export",
|
|
"audiobook",
|
|
"character-sheets",
|
|
"library",
|
|
"character-columns",
|
|
"library-characters",
|
|
"sillytavern"
|
|
],
|
|
"s-caststudio": [
|
|
"rehearser-parse",
|
|
"rehearser-cast",
|
|
"rehearser-train",
|
|
"rehearser-training-ui",
|
|
"rehearser-voice-design",
|
|
"rehearser-io",
|
|
"rehearser-playback",
|
|
"rehearser-recording",
|
|
"rehearser",
|
|
"rehearser-library",
|
|
"rehearser-stage",
|
|
"rehearser-voice-picker",
|
|
"character-identity",
|
|
"characters-library",
|
|
"reader",
|
|
"audiobook/network",
|
|
"audiobook-parse",
|
|
"audiobook-segmentation",
|
|
"audiobook-spans",
|
|
"audiobook-cast",
|
|
"audiobook-pipeline",
|
|
"audiobook-cast-spans",
|
|
"audiobook-preview-export",
|
|
"audiobook",
|
|
"character-sheets",
|
|
"library",
|
|
"character-columns",
|
|
"library-characters",
|
|
"sillytavern",
|
|
"studio"
|
|
],
|
|
"s-magazine": [
|
|
"magazine"
|
|
]
|
|
}
|
|
}
|