Repository navigation
The deploy-floor CI lane builds the bundle it certifies but never boots it #196
Description
Status, 2026-09-27
Done: the boot check exists in-repo.
tests/browser/smoke.mjswaits for#appand asserts thePress any keytitle sentinel.deploy-pages.ymlruns it and thetests/e2esuite before publishing, andpr-preview.ymlruns it on PRs labelleddeploy-preview. The Playwright scripts the body below points at live outside this repo.To close this issue:
- Run
tests/browser/smoke.mjsagainst the bundle intest.yml's pinned lane, after theWASM build smokestep (l.112), which builds the bundle and never loads it. No branch or PR for this exists yet.- Decide whether the
latest (upstream smoke test)lane gets the same step (it iscontinue-on-error, per the Scope section below).
pinned (deploy floor) in test.yml resolves .let-go-version, installs that let-go, compiles each test namespace, runs xsofy/test/run.lg, and runs the Layer-1 runtime smoke. It never runs make wasm, and never loads the result.
deploy-pages.yml resolves the same .let-go-version and builds the WASM bundle with it. So the lane named for the deploy floor exercises a different thing than the deploy does, and a let-go version that cannot build a working bundle passes it.
That is not hypothetical. The pin was stale in exactly that way until #195: on cf195a67, all three lane steps pass, and the bundle they certify dies at namespace load.
error loading xsofy.input: ExecutionError: calling dev?
caused by bit-shift-left expected Int
Reproduced 3 runs out of 3 in headless Chromium under COI headers. The suite was green the whole time, because nothing in it builds the bundle. The gap had been open since 2026-07-16, when the SHA pin landed.
Suggested check
Two steps at the end of the pinned lane:
make wasm— theid="app"guard already in the Makefile catches a stale builder, but only if something runs it in CI.- Load
dist/index.htmlin a headless browser withCross-Origin-Opener-Policy: same-originandCross-Origin-Embedder-Policy: require-corp, and fail on a page error or a missing title sentinel.
The COI headers are load-bearing: lg's wasm input ring is SharedArrayBuffer backed, so a plain static server boots to a read-key failure rather than the game, and the bundled coi-serviceworker.js fallback is not reliable under headless automation. local-scripts/coi-serve.py in the joint workspace exists for this, and the repo already carries Playwright smoke scripts under local-scripts/browser-smoke-playwright/ that could host the check.
Worth knowing if you reuse smoke.mjs as the starting point: it still waits for #terminal, which #378 renamed to #app, so it would need that one-line update to be meaningful against a current bundle.
Scope
This is about the floor lane specifically. The latest (upstream smoke test) lane has the same shape, and would benefit from the same two steps, but it is continue-on-error so a gap there is cheaper.
Happy to open the PR if the shape above looks right, or to take a different one if you would rather the boot check live in its own workflow than extend the matrix.
Activity
[-]The deploy-floor CI lane never builds or boots the bundle it certifies[/-][+]The deploy-floor CI lane builds the bundle it certifies but never boots it[/+]mparrett commentedon Sep 20, 2026
Correction to the title and the opening paragraph: the lane does build the bundle.
test.yml'sWASM build smokestep has run thebuild-wasmaction since #69, so it builds exactly whatdeploy-pages.ymlbuilds. What it never does is load the result.That makes the gap narrower and more specific than filed, not wider. The failure quoted below is at namespace load, so a build-only lane passes it by construction — adding
make wasmwould change nothing, and only a headless boot closes it.Reproduced again on 2026-09-20 in headless Chromium under COI headers, with the bundle built from the #195 branch at the old pin
cf195a67. Worth recording how it surfaces, since it defeats the obvious checks: it arrives onconsole.lograther thanconsole.erroror stderr, and the format string is botched (error loading %s: %vprinted literally, arguments trailing in%!(EXTRA ...)), so neither an error-channel watcher nor a grep for the assembled message finds it. A boot gate has to assert the title screen appears, not that no error was logged.Title corrected. Same wrong claim was in #195's body and
.let-go-version; both fixed there.