1c133c8970
Investigating Grant's real 38-min group call: 'Marty' was a GARBAGE cluster (192 segs, 0.37s mean, 186 ≤2 words, 125 single words flanked by the same other speaker — diarization micro-fragments split mid-sentence, then LLM-named 'Marty'). Same for 'Message'/'HI'. - SpeakerReconciler.smoothFragments: dissolve non-self clusters whose MEDIAN segment duration ≤ 1s (≥3 segs) — reassign each fragment to the temporally-nearest real speaker. (Median, not max, so one stray long segment can't rescue a fragment cluster — the bug in the first cut.) On the real call: 7 speakers (3 junk) → 4 real (Marty/Message/HI absorbed into Grant/Jonathan/Me/MH). Runs before LLM naming. - LLM naming guardrails: forbid assigning the self name or ANY already-taken name to another voice (fixes 'Grant' = the user's name pinned on a remote speaker); prompt demands self-intro / direct-address evidence (mention ≠ presence), 'precision over coverage', one name per speaker. - Open saved session now offers Open Editor vs Re-process, so newer logic can be applied to past calls (+ always-visible progress from the prior fix). NOTE: the self-name guardrail needs the app to KNOW the user's name — selfName is still 'Me', so set it in Settings (e.g. 'Grant') so the LLM can't reuse it. 62/62 XCTest.