Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions apps/viewer-web/e2e/world-cell-cold-boot.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { expect, test } from "@playwright/test";

test.use({ serviceWorkers: "block" });

test("cold authority fetch cannot be preempted by the recovery watchdog", async ({ page }) => {
test.setTimeout(45_000);
let delayedAuthority = false;
await page.route("**/keyxym-v26/keyxym-v26.wasm**", async (route) => {
delayedAuthority = true;
await new Promise((resolve) => setTimeout(resolve, 9_000));
await route.continue();
});

const response = await page.goto("/world-cell-theater/", { waitUntil: "domcontentloaded" });
expect(response?.ok()).toBe(true);
await page.waitForTimeout(8_500);
expect(delayedAuthority).toBe(true);
await expect(page.locator("html")).not.toHaveAttribute("data-world-cell-mode", "visual-preview");
await expect(page.locator("html")).not.toHaveAttribute("data-world-cell-mode", "boot-recovery");
await expect(page.locator("html")).toHaveAttribute("data-world-cell-mode", "authoritative", {
timeout: 25_000,
});
await expect(page.locator("html")).toHaveAttribute("data-keyxym-authority", "verified");
await expect(page.locator("#start-button")).toBeEnabled();
});
4 changes: 4 additions & 0 deletions apps/viewer-web/e2e/world-cell-webkit-smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ test("iPhone WebKit exposes a basic camera fallback when the release module fail

const response = await page.goto("/world-cell-theater.html", { waitUntil: "domcontentloaded" });
expect(response?.ok()).toBe(true);
await page.evaluate(() => {
(window as typeof window & { tessarynWorldCellBootFailure?: (reason: string) => void })
.tessarynWorldCellBootFailure?.("The World Cell release module could not load.");
});

await expect(page.locator("html")).toHaveAttribute("data-world-cell-mode", "boot-recovery", {
timeout: 15_000,
Expand Down
2 changes: 2 additions & 0 deletions apps/viewer-web/scripts/verify-live-release.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ if (keyxymManifest.schema !== "keyxym.browser-runtime-provenance/v11" ||
const legacyTheater = (await fetchBytes("world-cell-theater.html")).bytes.toString("utf8");
if (!/type="module"[^>]+src="\.\/assets\//u.test(legacyTheater) ||
!legacyTheater.includes('id="retained-source-frame"') ||
!legacyTheater.includes("const timeoutMs = 45000") ||
legacyTheater.includes("/src/world-cell-authority-entry.ts")) {
throw new Error("live legacy World Cell Theater route is not the built application entry");
}
Expand All @@ -113,6 +114,7 @@ if (!canonicalInventory || canonicalRoute.bytes.byteLength !== canonicalInventor
if (!/<base href="\.\.\/">/u.test(canonicalTheater) ||
!/type="module"[^>]+src="\.\.\/assets\//u.test(canonicalTheater) ||
!canonicalTheater.includes('id="retained-source-frame"') ||
!canonicalTheater.includes("const timeoutMs = 45000") ||
canonicalTheater.includes("/src/world-cell-authority-entry.ts")) {
throw new Error("live extensionless World Cell Theater route lacks its root asset contract");
}
Expand Down
9 changes: 5 additions & 4 deletions apps/viewer-web/src/world-cell-authority-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ const root = document.documentElement;
root.dataset.worldCellBoot = "module-started";
root.dataset.worldCellMode = "initializing";

const BOOT_PHASE_TIMEOUT_MS = 8_000;
const PREVIEW_LOAD_TIMEOUT_MS = 12_000;
const BOOT_PHASE_TIMEOUT_MS = 20_000;
const PREVIEW_LOAD_TIMEOUT_MS = 20_000;

function setText(id: string, value: string): void {
const node = document.getElementById(id);
Expand Down Expand Up @@ -133,13 +133,14 @@ async function enterPreview(error: unknown): Promise<void> {
}

async function boot(): Promise<void> {
const serviceWorkerRefresh = refreshServiceWorker();
// Theater and authority artifacts are network-only in the service worker.
// Refresh it concurrently, never on the provenance/WASM critical path.
void refreshServiceWorker();
try {
// Keyxym v0.26 owns monocular RGBA feature tracking, relative pose recovery,
// forming output, geometry, quality, and receipts. A verified spatial sensor
// is optional evidence that promotes scale from relative to metric; it is not
// a prerequisite for loading or executing the reconstruction authority.
await serviceWorkerRefresh;
const { verifyKeyxymV26Bundle } = await withTimeout(
import("./keyxym-v26-provenance"),
BOOT_PHASE_TIMEOUT_MS,
Expand Down
1 change: 1 addition & 0 deletions apps/viewer-web/tests/live-scan-release-gate.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ test("live release verification requires the calibrated spatial continuum and re
assert.match(source, /relative-native-triangles/);
assert.match(source, /RELATIVE RECONSTRUCTION READY/);
assert.match(source, /retained-source-frame/);
assert.match(source, /const timeoutMs = 45000/);
assert.match(source, /tessaryn\/spatial-calibration\/v1/);
assert.match(source, /Metric capture requires an exact browser media-frame identity/);
assert.match(source, /Host-verified synchronized RGB-D/);
Expand Down
13 changes: 7 additions & 6 deletions apps/viewer-web/tests/world-cell-mobile-boot.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ test("mobile boot always leaves VERIFYING through authority, preview, or visible
assert.match(theater, /dataset\.worldCellMode = "booting"/);
assert.match(theater, /dataset\.worldCellBoot = "html-ready"/);
assert.match(theater, /new Set\(\["booting", "initializing", "boot-error"\]\)/);
assert.match(theater, /const timeoutMs = 8000/);
assert.match(theater, /const timeoutMs = 45000/);
assert.match(theater, /window\.tessarynWorldCellBootFailure = recover/);
assert.match(theater, /WORLD CELL MODULE UNAVAILABLE/);
assert.match(theater, /START BASIC CAMERA/);
Expand All @@ -31,16 +31,17 @@ test("mobile boot always leaves VERIFYING through authority, preview, or visible

assert.match(entry, /dataset\.worldCellBoot = "module-started"/);
assert.match(entry, /dataset\.worldCellMode = "initializing"/);
assert.match(entry, /const BOOT_PHASE_TIMEOUT_MS = 8_000/);
assert.match(entry, /const PREVIEW_LOAD_TIMEOUT_MS = 12_000/);
assert.match(entry, /const serviceWorkerRefresh = refreshServiceWorker\(\)/);
assert.match(entry, /const BOOT_PHASE_TIMEOUT_MS = 20_000/);
assert.match(entry, /const PREVIEW_LOAD_TIMEOUT_MS = 20_000/);
assert.match(entry, /void refreshServiceWorker\(\)/);
assert.match(entry, /"World Cell preview module load"/);
assert.match(entry, /installEmergencyShell\(previewError\)/);

assert.doesNotMatch(entry, /hasVerifiedSpatialAdapter/);
const authoritativeServiceWorkerWait = entry.indexOf("await serviceWorkerRefresh");
assert.doesNotMatch(entry, /await serviceWorkerRefresh/);
const concurrentServiceWorkerRefresh = entry.indexOf("void refreshServiceWorker()");
const provenanceVerification = entry.indexOf("verifyKeyxymV26Bundle");
assert.ok(authoritativeServiceWorkerWait >= 0 && provenanceVerification > authoritativeServiceWorkerWait);
assert.ok(concurrentServiceWorkerRefresh >= 0 && provenanceVerification > concurrentServiceWorkerRefresh);
assert.ok(
entry.indexOf('dataset.worldCellMode = "initializing"') < entry.indexOf("async function boot"),
"module startup state must be visible before asynchronous work",
Expand Down
5 changes: 4 additions & 1 deletion apps/viewer-web/world-cell-theater.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,10 @@
root.dataset.worldCellMode = "booting";
root.dataset.worldCellBoot = "html-ready";
const startupModes = new Set(["booting", "initializing", "boot-error"]);
const timeoutMs = 8000;
// A cold mobile edge may need to fetch, hash, compile, and instantiate both
// authority WASM modules. Keep an eventual recovery bound without racing a
// valid first boot into the non-authoritative preview.
const timeoutMs = 45000;
let basicStream = null;

const setText = (id, text) => {
Expand Down
Loading