Skip to content

fix(diarization): stop overlap merge from shrinking speaker turns - #835

Merged
altic-dev merged 1 commit into
altic-dev:mainfrom
YuriNachos:fix/speaker-merge-overlap-shrink
Aug 11, 2026
Merged

fix(diarization): stop overlap merge from shrinking speaker turns#835
altic-dev merged 1 commit into
altic-dev:mainfrom
YuriNachos:fix/speaker-merge-overlap-shrink

Conversation

@YuriNachos

Copy link
Copy Markdown
Contributor

Description

SpeakerDiarizationService.mergeAdjacentTurns welded consecutive same-speaker turns by taking the incoming turn's endSeconds unconditionally. Diarization segments can overlap at boundaries (overlapping speech, VAD imprecision), so a later same-speaker turn that ends inside the accumulated turn overwrote the end with an earlier timestamp and silently dropped the trailing audio range [turn.end, current.end] from the transcribed slice. The fix takes max(current.endSeconds, turn.endSeconds), so a merge can never reduce the covered time range.

Type of Change

  • 🐞 Bug fix

Related Issue or Discussion

Hardens the speaker-labeled file-transcription path landed in #378 (originally requested in #219). No standalone issue exists for the overlap case, so linking the feature it belongs to.

Testing

  • Tested on Intel Mac
  • Tested on Apple Silicon Mac
  • Tested on macOS version: macOS 26 (Tahoe), arm64
  • Ran linter locally: swiftlint --strict --config .swiftlint.yml Sources → 0 violations on the edited files
  • Ran formatter locally: swiftformat --config .swiftformat Sources (not a CI check; skipped to avoid unrelated formatting churn)
  • Ran tests locally: xcodebuild test -project Fluid.xcodeproj -scheme Fluid -destination 'platform=macOS,arch=arm64' -only-testing:FluidDictationIntegrationTests/SpeakerTurnMergingTests → 10 tests, 0 failures. The two new cases (testOverlappingSameSpeakerTurnDoesNotShrinkMergedRange, testTouchingSameSpeakerTurnExtendsToEnd) fail on the previous endSeconds: turn.endSeconds and pass with max(...).

Screenshots / Video

  • No UI/visual changes; screenshots/video are not applicable.

Notes

Pure logic change to a static, already unit-tested merge helper — no SettingsStore, UI, or model loading involved. Behavior for the normal non-overlapping case is unchanged (a later turn's end is >= the accumulated end there, so max collapses to the previous value).

mergeAdjacentTurns took the incoming turn's endSeconds unconditionally when
welding same-speaker turns. Diarization segments can overlap at boundaries
(overlapping speech, VAD imprecision), so a later turn that ends inside the
accumulated turn overwrote the end with an earlier timestamp and dropped the
trailing audio ([turn.end, current.end]) from the transcribed slice. Use
max(current.endSeconds, turn.endSeconds) so a merge never reduces the covered
range. Adds overlap + touching regression tests.
@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown

Greptile Summary

This PR prevents overlapping same-speaker diarization segments from shrinking an accumulated speaker turn and dropping trailing audio.

  • Uses the maximum of the accumulated and incoming end timestamps when merging.
  • Adds regression coverage for contained and extending overlapping turns.

Confidence Score: 5/5

The PR appears safe to merge, with the focused merge correction covered by appropriate regression tests.

The changed assignment prevents merged ranges from shrinking, while existing duration checks and downstream chunking continue to bound long-turn transcription.

Reviews (1): Last reviewed commit: "fix(diarization): stop overlap merge fro..." | Re-trigger Greptile

@altic-dev

Copy link
Copy Markdown
Owner

@YuriNachos you're awesome!

@altic-dev
altic-dev merged commit 4ce0584 into altic-dev:main Aug 11, 2026
6 checks passed
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.

2 participants