fix(bin): preserve complete hold-to-speak recordings - #95
Merged
Conversation
iPhone Safari flushes MediaRecorder in timeslice chunks and can fire stop before the last flush, so a full sentence became a few hundred bytes. Collect every chunk, assemble the file on stop, reject undersized captures, and log received audio bytes. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Fix the urgent field bug on the Starship bridge hold-to-speak control: the captain held the button and spoke full sentences, but the uploaded m4a files were 784 bytes and 11 KB (only the final instant of speech; transcripts "Bye." and "you"). A captain-side Sent must mean the entire press-to-release recording left the phone, not the last MediaRecorder chunk.
Required outcome:
What Changed
MediaRecordertimeslice and final flush into one audio file before uploading./speakrequests.Risk Assessment
✅ Low: The change is well-bounded, satisfies the capture-integrity requirements, preserves the early-release race protection, and introduces no material issues found in review.
Testing
The full bridge suite passed, covering the #90 release-during-permission race, complete Safari m4a blob assembly, undersized-capture rejection, the real
/speakforwarding path, and server byte-size logging. Focused evidence shows a 6,500-byte full capture reaching “Sent” while a 784-byte capture is rejected without POSTing. No screenshot was captured because meaningful verification requires iPhone Safari MediaRecorder events; a static rendered page would not demonstrate capture integrity.Evidence: Capture-integrity end-user transcript
A 3-second press assembled all chunks into one 6,500-byte audio/mp4 upload and displayed “Sent”. An undersized 8-second capture displayed “Recording was too small to send.” and made no POST.Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
Inspectedgit diff --unified=80 3418df5656d8dc5a613319525b68a1a7e3cbf3c1..57edb04c3a54f1f29fde54c8f2ccf94a9ba11e7cagainst the authoritative intentbash tests/fm-bridge-view.test.shExecuted the actualPAGE_JSin a MediaRecorder harness simulating Safari timeslice chunks, final flush ordering, a valid 3-second capture, and a truncated 8-second capture; saved the resulting user-visible state and upload transcriptgit status --short && git diff --exit-code✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.