Browser back-button breaks cellblock state: mobile stuck on CELLMATE FOUND, desktop jumps to Scanning #109
Labels
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/cellblock#109
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Behavior (operator iPhone+desktop multiplayer playtest 2026-06-22, deployed round-18)
Browser back/forward navigation interacts badly with cellblock state:
Reproduction sequence (two-client versus session):
Observed result:
Side observation:
Severity: substantive
Substrate-state desync between server-state and client-displayed-state. Mobile gets "stuck" with no apparent recovery without page reload. Affects multiplayer playability when either player accidentally uses browser back-button.
Likely root cause (NEEDS PROBE)
Cellblock client probably doesn't handle browser history API events (popstate). Browser back-button moves through history entries without notifying the app's state-machine; the app doesn't realize the user "navigated back" and doesn't update its UI accordingly.
Distinct from cellblock#93 (ws.onclose latent gap) — though related family. #93 is socket-drop-handler-missing; this is browser-history-event-handler-missing. Both produce "stuck" client state but via different mechanisms.
Fix-direction (Shipwright lane, probe-first)
Acceptance criteria
Cross-refs
Anchor
2026-06-22 operator iPhone+desktop versus playtest. Empirically reproduced + side-observation distinguishing forward (works) vs backward (breaks).
AC-tick (pre-merge) — addressed in PR #117 (head
bcaa4af):grepforpushState|replaceState|popstate|hashchange|history.|location.hashinclient/src/→ empty. Zero history-API usage confirmed at source.pushStatesentinel +popstatere-push (AC2 option (a)). Note: purereplaceState(the tracker's lean) does not achieve this — with zero accumulated in-app entries there's nothing to replace away, so Back still unloads the page; thepushState-sentinel trap is what actually makes Back a same-document no-op. Full reasoning in the PR decision tree.#109versus.spectest driveshistory.back()against the #92 WS-mock; mutation-proven (remove thepopstatelistener → reds). 55/55 green,tscclean.Mechanism:
pushStatesentinel +popstatere-trap (NOT purereplaceState). No-op suppression (NOT Back→leave) per the operator's ratified direction. Awaiting Surveyor review + CI green before merge.