AGENTS.md: document speaker designation + discovery rules session

This commit is contained in:
B.D. Murphy
2026-09-25 18:41:20 -07:00
parent f7094e2b1f
commit b224c5f10f

View File

@@ -154,7 +154,48 @@ Each pass has quality gates. Quality is the primary concern; generation speed is
## Current Session Summary
### Session: Orphan name-token review UI (spec 17 Phase 3) — committed 3bc6945
### Session: Speaker designation + discovery over-detection (spec 17 §3.1/§3.2 + rules)
- **Trigger**: reviewer reported obvious speakers missing from Last Dwarf (the six men
in ch5 identified only as "the oldest"/"the tallest"/"the young one"/"the one with the
biggest sword"; the scum group), which they had to add by hand. And: "I would rather
combine speakers than be missing them" + "show all possible speakers with designations
for clear and needs to be checked."
- **New `umbraaudio/analysis/speaker_confidence.py`**: deterministic (no LLM) identification
confidence + `clear`/`needs_review` per speaker. **Categorical/blocking** defects always
need a human: narration verb in the name, `(Scene N)` label, uncapitalised, name made
only of role/comparative words, probable unmerged duplicate, `unidentified`, zero
dialogue. **Graded** penalties: unknown gender, no traits/description, thin utterance
share, high needs_review share, unevidenced aliases.
- Duplicate detection tuned to avoid FALSE merges: "Lieutenant" vs "Lieutenant
Stonesplitter" are NOT duplicates (extra word is a proper name); "Walking oldest" vs
"Walking Tallest" are NOT (difflib raised to 0.92). Real pairs found: Guard 1/Guard 2,
Rielan/Rieland, The Girl/The Girl helping, Officer/Older Officer.
- **UI** (registered as a Jinja global in the clean `__init__.py`, so routes.py untouched):
every speaker row gets `✓ clear` / `⚠ needs check`; hover a needs-check badge for the
machine-readable reasons; collapsible "N speakers need checking" panel at top + header
counts. Row template guards `{% if designations is undefined %}` so a standalone
`/speakers/partial-row/N` still works without 66 extra queries. Page loads in ~60ms.
**Last Dwarf: 32 clear / 34 need checking** — every hand-added speaker is flagged.
- **Discovery prompt** (`CHARACTER_DISCOVERY_PROMPT.md`): new **Rule 8 "Every Speaking Line
Is a Speaker"** (designations are valid names; if two may be the same person still list
both + flag unsure — over-detect, because a bad merge is permanent and a duplicate costs
one click) and **Rule 9 "Name Hygiene"** (no narration verbs in names, no "(Scene N)",
consistent capitalisation). Rule 6 extended: a designation IS unidentified; never upgrade
"the tallest" into a guessed proper name. `tests/test_discovery_prompt_rules.py` guards
all of it.
- **NOTE**: the new prompt rules only affect FUTURE discovery runs. Re-running discovery
is required for them to change speakers.json; existing entries are untouched meanwhile
(the designation panel flags the current mess).
- Commits `6ef66f6` (confidence + UI), `f7094e2` (prompt rules). Full suite **447 passed**
(8 pre-existing/parallel failures unchanged).
### Previous Session: Name-token review UI (spec 17 Phase 3) — 3bc6945, abb9975
- Phase 3 UI + 2 bug fixes (broken onclick quoting, scanner missing "Witch")
### Previous Session: Orphan name-token scanner + resolution (spec 17 Phase 2) — c338370, 4d900d7
- (scanner, resolution actions, CLI, name_tokens table; 3 bugs found by infra review and fixed)
### Session: Orphan name-token scanner + resolution actions (spec 17 Phase 2)
- **Key move: a SEPARATE router module** (`umbraaudio/web/name_token_routes.py`) instead of
adding routes to the hot, concurrently-edited `routes.py`. Registered via a 2-line change
to the clean `umbraaudio/web/__init__.py` (`app.include_router(name_token_router)`). This