[Recording] Log a per-speaker captured/expected ratio so a timeline regression is one grep away #327

Closed
opened 2026-08-25 20:38:46 +00:00 by claude-bot · 1 comment
Contributor

Severity: MEDIUM. Found in the August 2026 session lifecycle review (#319).

Why

The dev stack cannot exercise the Discord bot at all (no token), so the capture fix is prod-only to verify end to end. It needs a tripwire that proves itself on the first real session without anyone inspecting audio.

The data has always been there and was never compared. close() already logs file_bytes per user (recording.py:236-240) and the upload already logs the wall-clock duration (recording.py:733-736) — into the same log stream, never diffed. Meanwhile the live dashboard has been publishing seconds_captured next to elapsed_seconds every two seconds since the feature shipped (services/recording_status.py:7,26,54). The smoking gun was on screen the whole time.

Proposed fix

  1. In close(), log per user: expected_bytes = duration_s * 192000, written_bytes, and ratio. One grep after the first post-deploy session proves the fix (ratio ~1.0) or disproves it (ratio ~0.2). This requires passing duration_s or started_at into the sink — currently absent, which is itself telling.
  2. Emit a WARNING when any ratio falls below 0.9.
  3. Surface the existing seconds_captured vs elapsed_seconds divergence on the recording dashboard as a visible warning rather than two numbers a human has to compare.
  4. Log the untapped per-SSRC library counters (jitter_synthetic_packets, opus_decode_ok/err, rtp_unknown_ssrc_dropped) available via vc.get_recv_diagnostics(), which the bot never surfaces.

Acceptance criteria

  • close() logs expected/written/ratio per speaker
  • A ratio below 0.9 logs a WARNING naming the speaker
  • The recording dashboard shows a visible warning when captured time falls behind elapsed time
  • get_recv_diagnostics() counters are logged at stop
  • Documented in docs/OPERATIONS.md as the post-deploy verification step for the capture fix
**Severity: MEDIUM.** Found in the August 2026 session lifecycle review (#319). ## Why The dev stack cannot exercise the Discord bot at all (no token), so the capture fix is **prod-only to verify end to end**. It needs a tripwire that proves itself on the first real session without anyone inspecting audio. The data has always been there and was never compared. `close()` already logs `file_bytes` per user (`recording.py:236-240`) and the upload already logs the wall-clock `duration` (`recording.py:733-736`) — into the same log stream, never diffed. Meanwhile the live dashboard has been publishing `seconds_captured` next to `elapsed_seconds` every two seconds since the feature shipped (`services/recording_status.py:7,26,54`). The smoking gun was on screen the whole time. ## Proposed fix 1. In `close()`, log per user: `expected_bytes = duration_s * 192000`, `written_bytes`, and `ratio`. One grep after the first post-deploy session proves the fix (ratio ~1.0) or disproves it (ratio ~0.2). This requires passing `duration_s` or `started_at` into the sink — currently absent, which is itself telling. 2. Emit a WARNING when any ratio falls below 0.9. 3. Surface the existing `seconds_captured` vs `elapsed_seconds` divergence on the recording dashboard as a visible warning rather than two numbers a human has to compare. 4. Log the untapped per-SSRC library counters (`jitter_synthetic_packets`, `opus_decode_ok/err`, `rtp_unknown_ssrc_dropped`) available via `vc.get_recv_diagnostics()`, which the bot never surfaces. ## Acceptance criteria - [ ] `close()` logs expected/written/ratio per speaker - [ ] A ratio below 0.9 logs a WARNING naming the speaker - [ ] The recording dashboard shows a visible warning when captured time falls behind elapsed time - [ ] `get_recv_diagnostics()` counters are logged at stop - [ ] Documented in `docs/OPERATIONS.md` as the post-deploy verification step for the capture fix
Author
Contributor

Shipped — closing as part of a v3.11.5 bookkeeping sweep.

bot/questboard_bot/cogs/recording.py:356, in close():

ratio is the capture tripwire (#327): with a correct session clock it must be ~1.0. Anything near 0.2 means tracks are speech-only again and the timeline has regressed. One grep after the first real session settles it.

It logs written_bytes / expected_bytes per speaker and raises an AUDIO_DIAG short_track warning below 0.9. services/recording_status.py:30 carries the live counterpart, distinguishing track position (silence included) from decoded speech.

The design intent held: the ratio is exactly the signal that made #320 diagnosable after the fact, and it is why a regression would now be one grep rather than another lost session.

Shipped — closing as part of a v3.11.5 bookkeeping sweep. `bot/questboard_bot/cogs/recording.py:356`, in `close()`: > ratio is the capture tripwire (#327): with a correct session clock it must be ~1.0. Anything near 0.2 means tracks are speech-only again and the timeline has regressed. One grep after the first real session settles it. It logs `written_bytes / expected_bytes` per speaker and raises an `AUDIO_DIAG short_track` warning below 0.9. `services/recording_status.py:30` carries the live counterpart, distinguishing track position (silence included) from decoded speech. The design intent held: the ratio is exactly the signal that made #320 diagnosable after the fact, and it is why a regression would now be one grep rather than another lost session.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Quest-Board#327
No description provided.