feat(webapp): snap misheard character names to what the GM says they are (#579) #581
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/579-heard-as-aliases"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #579.
Why. On a real session "Viq" was transcribed as Vic, Vick or Nick in all 22 mentions, and no amount of vocabulary bias changes that (#577 measured prompt and hotwords as equivalent): Whisper will not overturn a common English word the audio already matches. So the GM says what a name is heard as, and the pipeline corrects it.
What.
campaign_characters.heard_as(JSONB list, migration6b7c8d9e0f1a), exposed on the character create/update/response schemas with validation (at most 20, each 1–50 characters, no case-insensitive duplicates, and a 400 for an alias that equals the character's own name or another character's name in the campaign). A puresnap_namesstep inaudio_service, whole-word and case-insensitive, longest alias first, possessives handled, "Victor" untouched by "Vic", applied inprocess_audioafter the hallucination filter and before the merge; the order is pinned by a test because snapping first would let the echo rule delete a corrected one-word line. Counts per canonical name land onsummarisation_runs.name_snapsand the run API; the log carries only totals since the keys are campaign content. The same aliases join the ASR vocabulary at the alias tier. The eval harness runs the step in the production position (a no-op on the fixture manifest). On the campaign page the character editor gains an "Also heard as" field and the card shows the list.Calls a reviewer should see.
nullon PATCH means "unchanged",[]clears. Collisions are refused at write time and dropped again at read time, and an alias two characters both claim is dropped for both rather than first-wins. Word-timing entries are corrected but not counted, soname_snapsis per mention. A GM acting on another member's character may set this field, unlike the sheet fields, because what the transcriber mishears is a property of the recording.Known gap, filed as #580. Aliases do not survive a campaign export/import round-trip.
Tests: backend full suite 3,024 passed (new
test_name_snapping.py); frontend 846 passed, eslint and build clean; migration upgraded, downgraded and re-upgraded on a real database; formatted with CI's pinned ruff.🤖 Generated with Claude Code