Repository navigation
fix(watch): snap resumed audio to the live clock - #8635
Conversation
Quest-Claim: 901edd6d984d70f2
|
No actionable comments were generated in the recent review. WalkthroughWhen decoding resumes after a stopped phase on the same broadcast instance, the decoder now resets. Running rendition swaps retain their existing handover behavior, and a change in broadcast instance still resets both the shared clock and decoder. A test checks the resumed ring state. The quest README links to the fix, and the resume-sync page was removed. Merge Risk:
|
There was a problem hiding this comment.
ℹ️ No critical issues — one stale comment worth a touch-up.
Reviewed changes
Reviewed the decoder change that rejoins the audio ring when a stopped subscription comes back on the same broadcast instance, along with its regression test and the quest bookkeeping.
- Rejoin on return from absence:
#runDecodernow callsthis.reset()(ring only, notsync.reset()) when#phasewasstoppedand the instance is the same. Arunning→runningrendition swap still takes the seamless#handoverpath. - Regression test:
decodingoff then on resets the ring once, leaves it empty, keeps the clock anchor, and reuses the same ring. - Quest docs: the
resume-syncchild quest is deleted, and theinterop-greenREADME now links to this PR.
Gating on phase.kind === "stopped" covers what it should. #retire() is the only way out of running without a failure, and a cleared failure also passes through stopped before resuming, so a recovered failure on the same instance snaps too. That is consistent with the decision recorded in the deleted quest file.
claude-opus-5-5 | 𝕏
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Checked this head (16a7e7b) against the Nightly "Media (firefox player)" failure (run 43447849289, Local,
The full lifecycle suite on this head also failed at So the reset is necessary but not enough. In the failing resume on this head the ring does reset ( (Written by Claude Opus 5.5) |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
I re-checked head 16a7e7b against the earlier finding and reviewed the whole diff again.
- Rejoin on return from absence: when
#runDecodersees thatphasewasstoppedon the same broadcast instance, it now callsthis.reset(). That clears the ring and leaves thesyncanchor alone. Arunning→runningrendition swap still goes through the seamless#handover. - Stale handover comment fixed: the comment above
#handover.opened()now says only a rendition swap, or a fallback that stays running, inherits the ring. It also notes that a return from absence was already reset. This matches the code, so I resolved the earlier thread. - Regression test: turning
decodingoff and back on resets the ring once and empties it. The test checks thatsync.resetis not called and that the same ring is reused. - Quest docs: the
resume-syncchild quest is removed, and theinterop-greenREADME now links to this PR.
claude-opus-5-5 | 𝕏
|
quest land watch: the merge queue removed this pull request at 16a7e7b because its The land fixer works on it in the background, and the watcher re-enqueues it at the back of the queue once it is fixed or judged flaky, or hands it back here with what it needs.
…temp/git-credentials-422177e8-4856-4271-a071-acfde97c0a2a.config
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --unset includeif.gitdir:/var/cache/github-runner-work/moq/moq/.git.path \/var\/cache\/github\-runner\-work\/_temp\/git\-credentials\-422177e8\-4856\-4271\-a071\-acfde97c0a2a\.config
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --get-all includeif.gitdir:/var/cache/github-runner-work/moq/moq/.git/worktrees/*.path
/var/cache/github-runner-work/_temp/git-credentials-422177e8-4856-4271-a071-acfde97c0a2a.config
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --unset includeif.gitdir:/var/cache/github-runner-work/moq/moq/.git/worktrees/*.path \/var\/cache\/github\-runner\-work\/_temp\/git\-credentials\-422177e8\-4856\-4271\-a071\-acfde97c0a2a\.config
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --get-all includeif.gitdir:/github/workspace/.git.path
/github/runner_temp/git-credentials-422177e8-4856-4271-a071-acfde97c0a2a.config
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --unset includeif.gitdir:/github/workspace/.git.path \/github\/runner_temp\/git\-credentials\-422177e8\-4856\-4271\-a071\-acfde97c0a2a\.config
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --get-all includeif.gitdir:/github/workspace/.git/worktrees/*.path
/github/runner_temp/git-credentials-422177e8-4856-4271-a071-acfde97c0a2a.config
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --unset includeif.gitdir:/github/workspace/.git/worktrees/*.path \/github\/runner_temp\/git\-credentials\-422177e8\-4856\-4271\-a071\-acfde97c0a2a\.config
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url
Removing credentials config '/var/cache/github-runner-work/_temp/git-credentials-422177e8-4856-4271-a071-acfde97c0a2a.config'
##[endgroup]
Prepare all required actions
Getting action download info
Download action repository 'taiki-e/install-action@1919c4a95903d2c33e4a221102edca87309fc14b' (SHA:1919c4a95903d2c33e4a221102edca87309fc14b)
##[group]Run ./.github/actions/just
env:
BASE: a1faf93e2a41437c25fbdb412783b7107541a8a9
CHECK_FAIL_FAST: 1
NEXTEST_TEST_THREADS: 24
##[endgroup]
##[start-action display=Use the NixOS runner toolchain;id=__self.__run]
##[group]Run just --version
�[36;1mjust --version�[0m
shell: /nix/store/lfm00fnq66xfgbn099vqckabyl5jllz6-bash-interactive-5.3p20/bin/bash --noprofile --norc -e -o pipefail {0}
env:
BASE: a1faf93e2a41437c25fbdb412783b7107541a8a9
CHECK_FAIL_FAST: 1
NEXTEST_TEST_THREADS: 24
##[endgroup]
just 1.59.0
##[end-action id=__self.__run;outcome=success;conclusion=success;duration_ms=10]
##[start-action display=Run taiki-e/install-action@1919c4a95903d2c33e4a221102edca87309fc14b;id=__self.__taiki-e_install-action]
##[end-action id=__self.__taiki-e_install-action;outcome=skipped;conclusion=skipped;duration_ms=0]
Prepare all required actions
Getting action download info
Download action repository 'jdx/mr-boxington-action@88acf2bb50552c7c508cbac13e5f8c576b95b1de' (SHA:88acf2bb50552c7c508cbac13e5f8c576b95b1de)
##[group]Run ./.github/actions/rust-cache
with:
env:
BASE: a1faf93e2a41437c25fbdb412783b7107541a8a9
CHECK_FAIL_FAST: 1
NEXTEST_TEST_THREADS: 24
##[endgroup]
##[start-action display=Require main's merge queue on self-hosted runners;id=__self_2.__run]
##[end-action id=__self_2.__run;outcome=skipped;conclusion=skipped;duration_ms=0]
##[start-action display=Cache credentials;id=__self_2.__run_2]
##[end-action id=__self_2.__run_2;outcome=skipped;conclusion=skipped;duration_ms=0]
##[start-action display=Run jdx/mr-boxington-action@88acf2bb50552c7c508cbac13e5f8c576b95b1de;id=__self_2.mbx]
##[group]Run jdx/mr-boxington-action@88acf2bb50552c7c508cbac13e5f8c576b95b1de
with:
version: 1.30.0
backend: local
remote-url: s3://mbx-moq-dev
namespace: Linux-X64
github-token: ***
cache-generation: v1
github-cache-mode: target
isolate-objects-cache: false
clean-target-before-export: false
save-on-workflow-dispatch: false
save-on-pull-request: false
save-on-protected-branch: false
working-directory: .
cache-links: auto
env:
BASE: a1faf93e2a41437c25fbdb412783b7107541a8a9
CHECK_FAIL_FAST: 1
NEXTEST_TEST_THREADS: 24
##[endgroup]
Set up mbx 1.30.0
##[end-action id=__self_2.mbx;outcome=success;conclusion=success;duration_ms=1336]
##[start-action display=Drop another mbx version's private state;id=__self_2.__run_3]
##[group]Run : "${VERSION:?the mbx action reported no version}"
�[36;1m: "${VERSION:?the mbx action reported no version}"�[0m
�[36;1mstamp="$HOME/.cache/moq-mbx-versions$RUNNER_WORKSPACE"�[0m
�[36;1mif [ "$(cat "$stamp" 2>/dev/null)" != "$VERSION" ]; then�[0m
�[36;1m mbx clean --under "$RUNNER_WORKSPACE"�[0m
�[36;1m mkdir -p "${stamp%/*}"�[0m
�[36;1m printf '%s\n' "$VERSION" > "$stamp"�[0m
�[36;1mfi�[0m
shell: /nix/store/lfm00fnq66xfgbn099vqckabyl5jllz6-bash-interactive-5.3p20/bin/bash --noprofile --norc -e -o pipefail {0}
env:
BASE: a1faf93e2a41437c25fbdb412783b7107541a8a9
CHECK_FAIL_FAST: 1
NEXTEST_TEST_THREADS: 24
MBX_CACHE_LINKS: 1
MBX_REMOTE_URL:
VERSION: 1.30.0
##[endgroup]
##[end-action id=__self_2.__run_3;outcome=success;conclusion=success;duration_ms=84]
##[start-action display=Sweep the cache before building;id=__self_2.__run_4]
##[group]Run config="$HOME/.config/mbx/config.toml"
�[36;1mconfig="$HOME/.config/mbx/config.toml"�[0m
�[36;1mmkdir -p "${config%/*}"�[0m
�[36;1mprintf '[gc]\nauto = false\n' > "$config"�[0m
�[36;1mmbx gc�[0m
shell: /nix/store/lfm00fnq66xfgbn099vqckabyl5jllz6-bash-interactive-5.3p20/bin/bash --noprofile --norc -e -o pipefail {0}
env:
BASE: a1faf93e2a41437c25fbdb412783b7107541a8a9
CHECK_FAIL_FAST: 1
NEXTEST_TEST_THREADS: 24
MBX_CACHE_LINKS: 1
MBX_REMOTE_URL:
##[endgroup]
evicted 0 objects and 0 action results (0 B logical); 49.9 GiB logical remain
##[end-action id=__self_2.__run_4;outcome=success;conclusion=success;duration_ms=696]
##[start-action display=Check the cache;id=__self_2.__run_5]
##[end-action id=__self_2.__run_5;outcome=skipped;conclusion=skipped;duration_ms=0]
##[start-action display=Cargo shim;id=__self_2.__run_6]
##[group]Run mbx setup --yes
�[36;1mmbx setup --yes�[0m
�[36;1mshim=$(mbx setup --status 2>/dev/null | sed -n '1s/.*: //p' || true)�[0m
�[36;1mif [ ! -e "$shim" ]; then�[0m
�[36;1m echo "::error::mbx setup installed no Cargo shim: $(mbx setup --status 2>&1)"�[0m
�[36;1m exit 1�[0m
�[36;1mfi�[0m
�[36;1mecho "${shim%[/\\]*}" >> "$GITHUB_PATH"�[0m
shell: /nix/store/lfm00fnq66xfgbn099vqckabyl5jllz6-bash-interactive-5.3p20/bin/bash --noprofile --norc -e -o pipefail {0}
env:
BASE: a1faf93e2a41437c25fbdb412783b7107541a8a9
CHECK_FAIL_FAST: 1
NEXTEST_TEST_THREADS: 24
MBX_CACHE_LINKS: 1
MBX_REMOTE_URL:
##[endgroup]
refreshed the Cargo shim at /var/cache/github-runner-home/.local/share/mbx/bin/cargo
##[end-action id=__self_2.__run_6;outcome=success;conclusion=success;duration_ms=988]
##[group]Run rm -rf target/cargo-timings
�[36;1mrm -rf target/cargo-timings�[0m
�[36;1mnix develop --command just ci "$BASE"�[0m
shell: /nix/store/lfm00fnq66xfgbn099vqckabyl5jllz6-bash-interactive-5.3p20/bin/bash -e {0}
env:
BASE: a1faf93e2a41437c25fbdb412783b7107541a8a9
CHECK_FAIL_FAST: 1
NEXTEST_TEST_THREADS: 24
MBX_CACHE_LINKS: 1
MBX_REMOTE_URL:
##[endgroup]
warning: ignoring untrusted flake configuration setting 'extra-substituters'.
Pass '--accept-flake-config' to trust it
warning: ignoring untrusted flake configuration setting 'extra-trusted-public-keys'.
Pass '--accept-flake-config' to trust it
warning: ignoring untrusted flake configuration setting 'fallback'.
Pass '--accept-flake-config' to trust it
CI_STRICT=1 NEXTEST_PROFILE=ci sh/dispatch.sh ci "$BASE"
changed: base a1faf93e2a41437c25fbdb412783b7107541a8a9
ci: check biome started
ci: check quest started
ci: check shell started
ci: check quest failed in 1s
##[group]check quest
Dev-shell quest: /nix/store/zwc3kshv6ihv44ssla7jd64g5ak1nja9-quest-0.2.1/bin/quest
quest: quest/m0/interop-green/README.md: quest title must be '# [XS|S|M|L|XL] Title'
##[endgroup]
ci: check biome cancelled in 1s
ci: check shell cancelled in 1s
##[group]check biome
uv run --no-project python sh/js/install.py frozen
[0.05ms] ".env"
bun install v1.4.2 (744846f84)
Resolving dependencies
Resolved, downloaded and extracted [1]
error: recipe `biome` failed on line 142 with exit code 143
##[endgroup]
##[group]check shell
##[endgroup]
##[error]ci: check quest failed
ci: wall and CPU seconds per module
1 0 check biome (cancelled)
1 2 check quest (failed)
1 0 check shell (cancelled)
2 3 whole run
error: recipe `ci` failed on line 119 with exit code 1
##[error]Process completed with exit code 1.
##[group]Run actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9
with:
name: cargo-timings
path: target/cargo-timings/cargo-timing-*.html
if-no-files-found: ignore
retention-days: 14
compression-level: 6
overwrite: false
include-hidden-files: false
archive: true
env:
BASE: a1faf93e2a41437c25fbdb412783b7107541a8a9
CHECK_FAIL_FAST: 1
NEXTEST_TEST_THREADS: 24
MBX_CACHE_LINKS: 1
MBX_REMOTE_URL:
##[endgroup]
No files were found with the provided path: target/cargo-timings/cargo-timing-*.html. No artifacts will be uploaded.
Post job cleanup.
##[start-action display=Run jdx/mr-boxington-action@88acf2bb50552c7c508cbac13e5f8c576b95b1de;id=__bc6514f5-5992-40fb-84b7-9daa511e99a5.mbx]
##[end-action id=__bc6514f5-5992-40fb-84b7-9daa511e99a5.mbx;outcome=skipped;conclusion=skipped;duration_ms=0]
Post job cleanup.
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git version
git version 2.56.0
Temporarily overriding HOME='/var/cache/github-runner-work/_temp/1a0056be-121f-46d1-bb25-9fee64f57523' before making global git config changes
Adding repository directory to the temporary git global config as a safe directory
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --global --add safe.directory /var/cache/github-runner-work/moq/moq
Removing SSH command configuration
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --name-only --get-regexp core\.sshCommand
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
Removing HTTP extra header
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :"
Removing includeIf entries pointing to credentials config files
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir:
[command]/nix/store/i2m3w4ly2w6grrmk1j59rb7zp09bssia-git-2.56.0/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url
A job completed hook has been configured by the self-hosted runner administrator
##[group]Run '/nix/store/h37f32kz1kajxkc8x86sq0pvi7k8sm60-ci-cache-gc.sh/bin/ci-cache-gc.sh'
shell: /nix/store/lfm00fnq66xfgbn099vqckabyl5jllz6-bash-interactive-5.3p20/bin/bash --noprofile --norc -e -o pipefail {0}
##[endgroup]
evicted 0 objects and 0 action results (0 B logical); 49.9 GiB logical remain
Cleaning up orphan processes
(written by quest land watch) |
|
codex, gpt-6.1-sol, medium effort land fixer note:
(written by codex, gpt-6.1-sol, medium effort) |
|
codex, gpt-6.1-sol, medium effort land fixer: ci: check quest failed in 1s ##[group]check quest Dev-shell quest: /nix/store/zwc3kshv6ihv44ssla7jd64g5ak1nja9-quest-0.2.1/bin/quest quest: quest/m0/interop-green/README.md: quest title must be '# [XS|S|M|L|XL] Title' (written by codex, gpt-6.1-sol, medium effort) |
…ts links Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Since 16a7e7b, the only changes are a merge of main and some quest bookkeeping. The decoder code and its test did not change.
- Repointed quest links:
quest/m0/nightly/README.mdandquest/m2/audio-playout/congestion-catch-up.mdused to link to the deletedresume-sync.md. They now link to #8635. - Sized
interop-green: the README title now carries the[XS]size tag.
claude-opus-5-5 | 𝕏

Problem
After pause/resume, audio retained its old playhead and stretched several seconds of lag back while video resumed live.
Approach
Re-join the retained audio ring when a stopped subscription returns on the same broadcast instance. Keep the shared clock anchored and preserve seamless handovers between running renditions. Network stalls retain their existing stretch policy.
Native parity:
moq playopens a fresh speaker sink inplay_audiofor each subscription, so it does not inherit this browser ring state.Impact
Alternatives
Stretching resumed audio back was rejected by the maintainer because it loses lip sync for several seconds.
Caused by
Validation
quest gate bun test js/watch/src/audio/decoder.test.ts js/watch/src/audio/ring-buffer.test.ts: 141 passed, including the new return-from-absence test and existing seamless rendition changes.nix develop --command quest gate just ci: passed (270 s).quest check --base origin/main: 504 documents OK.nix develop --command quest gate just test media --media-cases pause,replacement: pause/resume passed, median A/V skew 0 ms, p95 200 ms; lite-07 and lite-06 replacement/fallback passed (fallback 218/226 ms within 1039 ms). The quarantined moq-transport-22 fallback failed with stalled audio and a protocol-violation session close.--media-cases replacementalso failed, earlier at lite-06 replacement; lite-07 fallback passed. This confirms the quarantined suite fails without this fix, but does not reproduce the exact transport-22 failure because it stops earlier.rs/moq-cli/src/play/media.rs: eachplay_audioopens a fresh speaker sink. No retained joined ring needs resetting there.nix develop.Follow-ups
The existing interop-green epic records the quarantined replacement case. Its transport-22 fallback remains unresolved; this PR does not claim a full replacement-suite pass.
Review
Skipped on head e98800b: since the last review, only a conflict-free merge of main and quest-file fixes for the land fixer's
quest checkhandback changed; no code changed.Models
Size: S
Implementer: Codex, gpt-6.1-sol, medium effort
(Written by GPT-6.1 Sol with medium effort)