From 69f8f4cfd7f7a30fd4b9308e86f422c594981875 Mon Sep 17 00:00:00 2001 From: KoalaDev <6156589+Shik3i@users.noreply.github.com> Date: Fri, 26 Jun 2026 10:01:04 +0200 Subject: [PATCH] fix(extension): trust HOST_BLOCKED as authoritative (join race, EC-5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hcmHandleBlocked no longer re-checks local control mode before acting. Background only sends HOST_BLOCKED to a gated guest, so the message itself is authoritative — adopt host-only/guest role from it. Fixes the join race where a HOST_BLOCKED arriving before the CONTROL_MODE broadcast was silently ignored. Also corrects the EC-4 note: "let catch-up re-sync" is invalid (sync is event-driven, no continuous catch-up); the right fix is a buffer-aware deferred snap-back. Co-Authored-By: Claude Opus 4.8 --- docs/host-control-mode-EDGECASES.md | 17 ++++++++++------- extension/content.js | 7 ++++++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/docs/host-control-mode-EDGECASES.md b/docs/host-control-mode-EDGECASES.md index 5a2f1c5..501bd42 100644 --- a/docs/host-control-mode-EDGECASES.md +++ b/docs/host-control-mode-EDGECASES.md @@ -39,13 +39,16 @@ Deferred by decision (see §8): host grace period on disconnect (EC-10). ### Pre-test self-audit (open, watch during device testing) - **EC-4/EC-1 snap-back thrash:** for *involuntary* events we still actively seek+play, - which can fight a buffering player for the duration of the stall. Likely fix: on - involuntary, don't re-play — let catch-up re-sync — or use an exponential cooldown. - Decide after watching it on Netflix/YouTube. -- **Control-mode race at join:** a `HOST_BLOCKED` arriving before content.js learns the - mode is ignored (`hcmIsGuestGated()` false). Fix: trust `HOST_BLOCKED` as - authoritative (background only sends it to gated guests) instead of re-checking local - mode. Small change, deferred pending test. + which can fight a buffering player for the duration of the stall. NOTE: "just let + catch-up re-sync" is NOT a valid fix — sync is event-driven, there is no continuous + catch-up loop, so skipping the snap-back risks leaving the guest stuck paused/behind + until the host next acts. Correct fix is a **buffer-aware deferred snap-back**: when + involuntary + buffering, wait for readyState>=3 (à la pollSeekReady) then seek+play + once — avoids thrash AND guarantees re-sync. Build after device testing reveals which + players fire pause() vs only 'waiting'. +- ~~**Control-mode race at join:**~~ FIXED — `hcmHandleBlocked` now treats `HOST_BLOCKED` + as authoritative (adopts host-only/guest role) instead of re-checking local mode, + since background only sends it to gated guests. - **Dialog/badge text is English-only** — content.js has no i18n loader; the in-page strings aren't localized yet. Follow-up. diff --git a/extension/content.js b/extension/content.js index 6514556..387a907 100644 --- a/extension/content.js +++ b/extension/content.js @@ -175,7 +175,12 @@ // Entry point: background told us our local action was blocked in host-only. function hcmHandleBlocked(action, target) { - if (!hcmIsGuestGated()) return; + // HOST_BLOCKED is only ever sent to a gated guest (background verifies + // host-only + !host before sending), so it's authoritative. Adopt the + // role/mode from it in case our CONTROL_MODE broadcast hasn't landed yet + // (join race, EC-5) — otherwise we'd miss the dialog/snap-back. + hcmControlMode = 'host-only'; + hcmAmHost = false; if (Date.now() < hcmSnapBackCooldownUntil) return; // EC-4 loop guard if (hcmDesynced) return; // already solo, nothing to do