Files
ddidderr 3042b7743b feat!: use whole-recording Pyannote speaker diarization
Sampled Gemini voice matching could leave one person under separate IDs
across transcription chunks. Use hosted Precision-2 on the complete
recording and align its exclusive speaker timeline with MAI word timing.
Preserve transcription text, order, and timestamps; leave ambiguous word
assignments unknown instead of merging identities to satisfy a count.

Upload lossless FLAC, bound polling, retry transient status reads against
the same job, and validate results before emitting stdout. Keep optional
speaker-count and hosted model overrides. Disable MAI diarization and use
30-minute transcription uploads in both modes. Respect environment keys,
keep authentication out of process arguments, and save optional diagnostics
without audio, credentials, or signed upload URLs.

Test Plan:
- python3 -B -m unittest -v: all 101 regression tests passed, including
  mocked provider upload, polling, alignment, failure, and cleanup paths.
- bash -n transcribe and shellcheck transcribe: passed.
- git diff --cached --check: passed.
- Prepared the 74-minute input locally and verified identical decoded PCM
  hashes for the normalized WAV and full-recording lossless FLAC.
- Live API testing was explicitly deferred by the user; mocked results do
  not establish speaker accuracy on the recording.

BREAKING CHANGE: Default diarization requires PYANNOTE_API_KEY or its
1Password reference. --speaker-model accepts hosted precision-2 or
community-1 instead of OpenRouter audio-chat model IDs.
2026-09-12 11:18:30 +02:00

3.1 KiB

Repository instructions

Automatic commits are mandatory

  • Automatically commit each completed, validated change before finishing a task. Do not wait for the user to ask for a commit or request confirmation.
  • Keep commits focused. Include the implementation, regression tests, and relevant documentation together; commit independent changes separately.
  • Inspect staged and unstaged changes before committing. Stage only files that belong to the task. Do not commit user recordings, generated transcripts, credentials, or unrelated changes.
  • Use Conventional Commit subjects and explain the change and validation in the commit body, including a Test Plan: section.
  • Run the relevant checks, including python3 -B -m unittest -v, bash -n transcribe for shell changes, and git diff --cached --check. Report any validation that could not be completed; never claim a mocked provider test proves live API behavior.
  • After committing, inspect the commit and working tree, and report the commit hash with any remaining work. Do not push unless requested.

Project layout

  • transcribe: CLI options, audio preparation, and transcription requests.
  • chunks.py: upload boundaries and ordered overlap stitching.
  • subtitles.py: timestamp validation and SRT cue formatting.
  • transcript.py: readable text paragraphs and speaker markers.
  • diarization.py: whole-recording Pyannote jobs and speaker timeline alignment.
  • test_*.py and tests/fake_provider.py: local regression tests without real credentials or provider requests.

Keep the CLI and its four Python helpers together. Preserve transcript order and emit stdout only after all chunks, the enabled Pyannote job, and output conversion succeed. MAI provides text and timestamps with provider diarization disabled. Speaker identities come from one Pyannote job on the whole recording; MAI request-local speaker IDs must not establish identity. Align Pyannote's exclusive timeline without changing transcription text, word order, or timestamps. Validate the returned timeline and leave ambiguous or tied word assignments unknown with warnings. Keep chunk details out of the final transcript. Progress, processing details, and errors belong on stderr.

The normal command uses hosted precision-2 and detects the speaker count automatically. --speakers supplies an optional known count; --speaker-model accepts hosted precision-2 or community-1. --no-diarization skips Pyannote and strips unsolicited speaker labels from MAI responses. MAI uploads default to 30-minute chunks in either mode, with eight concurrent workers.

Respect existing OPENROUTER_API_KEY and PYANNOTE_API_KEY environment values. Resolve missing keys through op only when using the relevant key reference; do not invent a default PYANNOTE_API_KEY_REF. Diagnostics are opt-in, belong in a new private directory, and may retain completed stages after a later failure. Save only chunks.json, transcript.json, diarization.json, and labeled.json as applicable. Do not save audio, credentials, or signed URLs in diagnostics, and never commit diagnostics or generated transcripts.