Skip to content

fix(transcription): persist real segment end times, not a fixed 1s span#4

Open
farce1 wants to merge 1 commit into
mainfrom
fix/segment-end-time
Open

fix(transcription): persist real segment end times, not a fixed 1s span#4
farce1 wants to merge 1 commit into
mainfrom
fix/segment-end-time

Conversation

@farce1

@farce1 farce1 commented Jun 13, 2026

Copy link
Copy Markdown
Owner

What

Transcript segments were persisted with end_time_ms = start_time_ms + 1000 (a fabricated 1-second span), and the diarization alignment query (diarization/worker.rs) ignored the stored column and recomputed the same start + 1000 span. Since VAD segments range ~0.15–25s, speaker-to-text overlap was wrong for any segment that isn't ~1s long, degrading diarization accuracy and exported timestamps.

This computes the real segment duration from the decoded chunk's sample count and uses it consistently on both the write and read sides.

Changes

  • transcription/worker.rs: add pure helpers samples_to_ms + build_segment_result; carry duration_ms on each segment (removes duplicated inline timestamp math; uses saturating arithmetic).
  • transcription/mod.rs: SegmentResult gains duration_ms; persist end_time_ms = start + duration instead of start + 1000.
  • diarization/worker.rs: alignment query reads the real end_time_ms column instead of (start_time_ms + 1000). The existing end_time_ms.max(start + 1) guard handles zero/short spans.

Verification (TDD)

  • RED→GREEN unit tests in worker.rs (incl. a regression guard asserting real duration ≠ the old fixed 1000ms).
  • Full Rust gate run locally: cargo check --all-targets ✅, cargo clippy --all-targets --all-features -- -D warnings ✅, cargo test → the 4 new tests pass; the only failures are the pre-existing model_archive_consts_tests (the REPLACE_WITH_ SHA256 release placeholders), unrelated to this change.

⚠️ CI will be red — not because of this PR

main's CI is currently red on three maintainer-only release blockers, all independent of this change:

  1. release-config-checkREPLACE_WITH_ SHA256/pubkey placeholders (Plan 03 Task 0).
  2. Rust Checksvendor/vc_redist.x64.exe is not committed yet (Plan 05 Task 1); the Tauri build script fails on the missing resource. (Verified locally with a temporary untracked placeholder; not committed.)
  3. Frontend Checks — separate pre-existing failure.

Do not merge until release prep is complete. This is a staged hardening fix (Track A) from a Handy (cjpais) vs openNotes transcription review; code-only, no new deps.

Every transcript segment was stored with end_time_ms = start + 1000ms, and
the diarization alignment query recomputed the same fabricated span instead
of reading the stored column. VAD segments span 0.15-25s, so speaker-to-text
overlap was wrong for any segment != ~1s, degrading diarization and exports.

Compute the real duration from the decoded chunk's sample count
(samples_to_ms) and carry it on SegmentResult; store start+duration as
end_time_ms and read the real end_time_ms column during alignment.
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