Skip to content

Meetings: record the diarizer and voiceprint model that actually ran - #1920

Merged
r3dbars merged 3 commits into
mainfrom
claude/infallible-bun-37eb8c
Sep 29, 2026
Merged

r3dbars merged 3 commits into
mainfrom
claude/infallible-bun-37eb8c

Conversation

@r3dbars

@r3dbars r3dbars commented Sep 29, 2026

Copy link
Copy Markdown
Owner

What was wrong

Every meeting saved since Nemotron became the default (#1887) says diarization_engine: pyannote_offline. The formatter had that value hardcoded. The pipeline log Using local Parakeet V2 + PyAnnote pipeline and the raw footer + PyAnnote (local) were hardcoded too.

I checked the 2026-09-29 meetings in the local logs: both runs (14:08 and 14:24 UTC) used Nemotron fast128 with the redimnet2-b4 embedder. No pyannote fallback happened, so the files are wrong about their own engine.

What changed

  • DiarizationEngine gets activeRunDescriptor (DiarizationRunDescriptor: backend + voiceprint model id). The protocol default is pyannote with no model, so existing conformers and test stubs keep working. DiarizationService builds it from activeBackend, so a Nemotron load failure reads pyannote. The voiceprint model is the injected embedder's id, else Nemotron's fallback embedder, else pyannote's native wespeaker.
  • The pipeline reads the descriptor right before it diarizes (system track, or mic when local speaker split is on) and stores it in TranscriptionResult.diarization.
  • The formatter writes diarization_engine: nemotron_offline | pyannote_offline | none. none means no diarizer ran, e.g. a mic-only meeting without split. It also writes an optional quoted voiceprint_model: "redimnet2-b4".
  • The log line and the raw footer name the real backend. The pyannote path's "Offline diarization starting" log now carries backend too, so a fallback shows up in the logs.
  • CaptureKit parser: voiceprintModel: String?. MCP engines gains voiceprint_model, left out of the JSON when absent.
  • QA TranscriptValidator accepted only pyannote_offline, so it would have failed every correct Nemotron file. It now accepts all three values and still rejects unknown ones.
  • docs/capture-format.md documents the values and the new key. Files saved before 2026-09-29 always say pyannote_offline, so in older files that value should be read as "unknown backend".
  • Goldens regenerated: two-person call = Nemotron + ReDimNet2; imported = pyannote fallback + wespeaker; mic-only room = none.
  • Hand-kept smoke source lists get DiarizationBackend.swift.

Older transcripts parse as before: no key is required, and unknown values are kept.

Tests

Behavior tests, no source reads:

  • Pipeline end to end with a stub diarizer: Nemotron is recorded; Nemotron swapped to pyannote during model load records pyannote; a diarizer with no model name writes no voiceprint_model.
  • Parser reads the new keys; the legacy file has no voiceprint.
  • MCP JSON includes or omits voiceprint_model.
  • QA validator accepts current and legacy engines and rejects unknown ones.
  • Writer/kit contract and goldens updated.

Checks

  • bash check.sh: swift test, CaptureKit/CLI/MCP/QA packages, integration smoke, source pins, test shape, and doc paths all pass. In that run, build.sh failed in 0.4 s because it ran before build-deps; run-tests.sh and the e2e smoke failed on the missing source-list entry (fixed in a1386a8). Rerun after the fix: build.sh --no-open ✅, run-tests.sh 19963/19963 ✅, run-e2e-smoke.sh ✅.
  • concurrency-census --check fails with Sources/UI at 54 against a baseline of 51. This diff touches nothing in Sources/UI (the warnings are in MenuBar/Overlay files), so this was already on main.
  • Review: a /code-review pass found nothing, but it ran in the same session that wrote the code. An independent review (codex review or a separate thread) is still owed per AGENTS.md.

🤖 Generated with Claude Code

diarization_engine was hardcoded to pyannote_offline, so every Nemotron
meeting since #1887 said pyannote. The pipeline now reads the diarizer's
activeRunDescriptor right before it diarizes (a Nemotron load fallback
reads pyannote) and the formatter writes nemotron_offline /
pyannote_offline / none, plus an optional voiceprint_model key. The
'+ PyAnnote pipeline' log line and the raw footer name the real backend.
CaptureKit and MCP surface voiceprint_model; older files read unchanged.
@r3dbars
r3dbars merged commit 52ea4ec into main Sep 29, 2026
8 checks passed
@r3dbars
r3dbars deleted the claude/infallible-bun-37eb8c branch September 29, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant