Verify identity persistence on HTML5 (sys.save writes to IDBFS) #17
Labels
No labels
area:defold
area:docs
area:infra
area:protocol
area:testing
kind:bug
kind:chore
phase:breadth
phase:core
phase:hardening
phase:slice
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
yuris/spacetimedb-defold#17
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?
Identity persistence is proven on native and unverified on HTML5, and there is a concrete reason to doubt it rather than assume it.
stdb.sys_storageusessys.save/sys.load. On HTML5 that writes to Emscripten's IDBFS, which is an in-memory filesystem flushed to IndexedDB asynchronously — a write is not durable at the momentsys.savereturns. A page closed before the flush loses the token, and the player silently gets a new identity on the next load. That is exactly the failure #8 fixed for the header case, arriving by a different route.The native tier proves this properly:
tools/conformance.shruns the engine twice, the second time with noSTDB_TOKEN, and fails unless both runs report the same identity. The HTML5 harness only does a single page load, so it proves the?token=transport works but says nothing about persistence.Work
tools/html5-conformance.mjswith a second load of the same page, noSTDB_TOKENin the query string, reusing the same browser profile so IndexedDB survivesSMOKE: identity 0x…, mirroring the native checkstdb/init.luarather than in the harness — most likely an explicit IDBFS sync, or storing the token inlocalStorageviahtml5.runon HTML5Acceptance
The harness fails if the second load reports a different identity. Whichever way it lands, the finding gets written into the README's identity-persistence section — a token that quietly does not persist is worse than one that documented itself as not persisting.
Note the profile handling: the harness currently creates a throwaway
--user-data-dirper run and deletes it, which is right for isolation but means IndexedDB cannot survive between runs. The two loads must share one profile within a single run.Verified, and it persists.
7dc33bc.What the harness does now
Load 1 is handed a token in the query string as before. On its
PASS, the harness navigates the same page in the same browser process withSTDB_TOKENremoved, and requires both loads to reachPASSreporting the same identity — the shape the native tier has always used across two engine processes.Two details the description called out, both handled:
--user-data-dirstays throwaway; the second load happens within the same run, so IndexedDB is the same origin in the same Chromium. Isolation between runs is preserved, which is what that profile was for.restartedresets before the second load, so load 2 bounces the server exactly as native run 2 does rather than getting a softer test than the first.Also refreshed the timeout per load: two full phase sequences do not fit in one 120s budget, and the CI runner already spends ~13s of it in reconnect backoff.
No fix was needed in
stdb/init.lua. The IDBFS flush happens well before the reload, sosys.save/sys.loadwork unmodified on HTML5 — no explicit sync, nolocalStoragefallback viahtml5.run.The check can actually fail
A green assertion that has never gone red is not evidence, so I ran a negative control:
storage = falsein the smoke client, everything else identical.Exit 1, both identities printed. Note the failure mode this guards: load 2 still reports
PASSon its own terms, because a brand-new anonymous identity connects perfectly happily. That is the same silent-success trap #8 found with the droppedAuthorizationheader — nothing errors, the player is just someone else now. The control was reverted; only the harness change is committed.What this does not prove
The harness reloads roughly 15s after the token is saved, so it demonstrates the flush happens, not the flush is prompt. A tab closed in the second between
sys.savereturning and IDBFS reaching IndexedDB is still untested and still plausible. README now states that limit rather than advertising durability nobody measured — if a shutdown path ever depends on it, that is the case to test.Closing: the acceptance criterion is met (the harness fails on identity mismatch) and the finding is in the README's identity-persistence section.