feat(A.3 #25): aggressive buffer trim tied to commit points

New streaming::buffer_trim module with two pure helpers:

- sample_index_for_seconds(end_secs, sample_rate) -> u64: converts
  LocalAgreement::last_committed_end_secs() into an absolute sample
  index. Defensive against negative end_secs (treats as 0) so a future
  clock-skewed timestamp cannot wrap to a huge u64.
- trim_buffer_to_commit_point(buffer, buffer_start_sample,
  commit_sample_index) -> new_buffer_start_sample: drains the prefix
  of the capture buffer that falls below the commit point and returns
  the new absolute-index origin.

Edge cases covered by tests:
- commit before buffer start → no drain
- commit equal to buffer start → no drain
- commit inside buffer → drain prefix, advance origin
- commit at buffer end → drain all, origin moves forward
- commit past buffer end → drain all, origin parks at commit (rare
  edge after a committer reset)
- sample_index_for_seconds rounds nearest, negatives clamp to 0
- integration with LocalAgreement::last_committed_end_secs

trim_bounds_buffer_over_long_session is the acceptance fixture for
the ufal #120/#102 failure mode: 100 cycles of 16_000 captured samples
with a 200-sample tentative tail per cycle, and the buffer stays below
2× the tentative envelope instead of growing to 1.6M samples.

Integration into src-tauri/src/commands/live.rs deferred to the
dogfood session that wires VadChunker and LocalAgreement end-to-end —
the trim is a one-line replacement at the maybe_dispatch_chunk drain
site once the committer is feeding it commit points.
This commit is contained in:
2026-04-22 07:52:48 +01:00
parent da2340325f
commit cea15c12c7
3 changed files with 194 additions and 1 deletions

View File

@@ -6,9 +6,11 @@
//! threshold tuning can be validated against real microphone captures
//! rather than synthetic fixtures (brief items #21, #24, #25).
pub mod buffer_trim;
pub mod commit_policy;
pub mod rms_vad;
pub use buffer_trim::{sample_index_for_seconds, trim_buffer_to_commit_point};
pub use commit_policy::{CommitDecision, CommitPolicy, LocalAgreement, Token};
pub use rms_vad::RmsVadChunker;