1
0
This repository has been archived on 2026-08-25. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
tera/src/test/data/wireContract.test.ts
T
karti db074e9cf7 feat: tone-mapped render rig, studio devices, LA fidelity pass, UI overhaul
The build the studios needed, across eight workstreams and one strict file
partition.

**The render rig was the quality ceiling.** The renderer ran three's
NoToneMapping default while atmosphere drove the sun to 2.35 and assets set
emissives to 3.2, so every value above 1.0 hard-clipped to flat white — which is
why walls blew out and every fitting looked like a white rectangle. ACES filmic
tone mapping and an explicit output colour space land in `stage.ts`, and the
atmosphere intensity table and palette headroom are re-tuned against the new
curve rather than left tuned for the clipping we removed.

`engine/environmentRig.ts` builds a PMREM environment at runtime, procedurally,
so nothing binary is committed. There was no environment map anywhere before, so
every `metalness > 0` role had nothing to reflect and rendered dull grey — a
defect the code already documented against itself in `office/optimus.ts`, where a
whole material role was abandoned over it, and worked around in `modelX.ts` with
a fake emissive that this change deletes. Atmosphere remains the sole light
owner; the rig derives from the `LightingState` it already produced.

**Studio hardware exists.** There was no device concept anywhere in the product:
no type, no route, no state. `devices/types.ts` fixes a declaration/state/
capability/command contract that a smart light, a thermostat, a door sensor and a
charger all fit without a schema change, and both studios now carry a desk mic
and a computer speaker with deterministic simulated behaviour behind an adapter
seam a real API can occupy later. Reads are the demo and are open; commands are a
signed-in action and are kept off the read body entirely, because a shared cache
replaying a GET that turned a microphone on is exactly what the fail-closed
cache default exists to prevent.

**The ADS-B licence hole is closed.** `TERA_ADSB_ENDPOINT` accepted any URL, the
response was served publicly cacheable, and the attribution hardcoded adsb.lol
regardless of where the endpoint pointed — one env var away from republishing
non-redistributable data under an open-terms credit. The host is now allowlisted,
the credit is derived from the host actually configured, public cacheability is
conditional on redistributability, and a refused endpoint demotes to simulated
flights and says so in `degraded[]`. The gate is on the source, not the feature:
live aircraft and their detail cards stay open to anonymous visitors.

**The LA studio was never the smaller pack** — 16 rooms and 248 props against
SF's 4 and 28. Its deficit was fidelity per square metre: 98 of those props were
ceiling troffers, it bound no props to seats, placed none of the habitat kit, and
12 of its 16 rooms had no viewpoint. Density comes from new asset kinds rather
than more instances, because `furnish.ts` draws once per kind and folds colour
into the batch key, so repeat instances add nothing the eye can read.

**The interface stops being forty imperative mutations.** Every visibility
decision moves into a pure, tested `ui/chromeState.ts` and one applier, so the
chrome has coverage for the first time. Deleted: ~100 lines of CSS and two
bindings targeting elements that no longer exist, and a `body:has()` rule that
shifted the desktop layout by 160px for touch controls hidden there. Fixed: the
office picker tabs that drew their label and their badge on top of each other.
Added: a first-run flow, because the product is two verbs and neither was ever
stated on screen. Mobile is designed on its own terms instead of being the
desktop with things hidden — the plan view comes back, and the keyboard-only
shortcuts button is replaced by touch controls.

`arena/studioOps.ts` frames the whole thing as the multi-variable environment it
is, wrapping the same simulators the renderer drives rather than a headless copy.

Also removed `input/vehicle.ts`, which nothing but its own test imported.

Tests 385 -> 961, all passing. Typecheck, build, performance budgets across six
matrix cells, no-binaries, provenance, dependency licences, zero-config boot and
arena source hashes all green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 19:44:24 -07:00

381 lines
15 KiB
TypeScript

/**
* The boundary between this bundle and a deployment, from the browser's side.
*
* Three things meet here and all three are easy to get wrong quietly:
*
* 1. **The wire bodies are JSON and stay JSON.** `src/server/wire.ts` compiles
* to nothing, so nothing in it can be checked by running it — but the shapes
* it declares are the shapes both sides build, and a body that does not
* survive `JSON.parse(JSON.stringify(x))` unchanged is a body the two sides
* will disagree about. The device bodies are new and carry the first
* optional-reading type on the wire, which is exactly where a `undefined`
* versus `null` mistake hides.
* 2. **`/health` is read defensively.** `sources.devices` and `degraded` are
* newer than servers this client will meet, and a missing field has to fall
* the safe way rather than throw or be assumed.
* 3. **The seam chooses a strategy and says which.** An anonymous visitor and a
* zero-config clone both get the local simulator, alive and labelled; a
* signed-in viewer on a configured box gets the deployment's readings. What
* must never happen is a studio that looks live and is not, or a control
* that appears to work and changes nothing anybody else can see.
*/
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { resolveAccess } from "../../access.ts";
import { createTeraClient } from "../../adapters/http.ts";
import { createDeviceSource, createNullDeviceSource } from "../../devices/adapter.ts";
import { initialDeviceState, type DeviceDeclaration, type DeviceState } from "../../devices/types.ts";
import type {
DeviceCommandBody,
DeviceCommandResultBody,
DevicesBody,
HealthBody,
} from "../../server/wire.ts";
Object.defineProperty(globalThis, "window", {
configurable: true,
value: { location: { origin: "https://office.example.test" } },
});
const DECLARATION: DeviceDeclaration = {
id: "mic-1",
kind: "mic",
label: "Desk mic",
assetId: "tera:device.mic.desk",
anchor: { levelId: "l1", propId: "mic-prop", seatId: "desk-01" },
capabilities: ["power", "mute", "gain", "level"],
provenance: "simulated",
disclosure: "Simulated studio hardware. Demonstration data, never presence data.",
};
function json(body: unknown, status = 200): Response {
return new Response(JSON.stringify(body), {
status,
headers: { "content-type": "application/json" },
});
}
function deployment(routes: Record<string, () => Response>): typeof fetch {
return (async (input: RequestInfo | URL) => {
const url = String(input);
for (const [path, answer] of Object.entries(routes)) {
if (url.includes(path)) return answer();
}
throw new TypeError("Failed to fetch");
}) as typeof fetch;
}
const health = (over: Partial<HealthBody> = {}): HealthBody => ({
ok: true,
service: "tera-api",
version: "0.1.0",
uptimeSeconds: 1,
sources: { weather: "nws", flights: "adsb", satellites: "none", markers: "none", devices: "sim" },
auth: { mode: "none", entryUrl: null },
regions: [{ id: "sf", lat: 37.77, lng: -122.42, radiusKm: 120 }],
degraded: [],
...over,
});
describe("the bodies are JSON, and stay JSON", () => {
it("round-trips a devices body unchanged", () => {
const body: DevicesBody = {
officeId: "hq",
devices: [
{ id: "mic-1", kind: "mic", powered: true, muted: false, gainDb: 12, levelDb: -22.4, observedAt: 17, synthetic: true },
{ id: "spk-1", kind: "speaker", powered: false, volume: 0.35, playing: false, observedAt: 17, synthetic: true },
],
observedAt: 17,
source: "sim",
synthetic: true,
ttlSeconds: 5,
};
assert.deepEqual(JSON.parse(JSON.stringify(body)), body);
});
it("round-trips a command and its result unchanged", () => {
const command: DeviceCommandBody = { command: { deviceId: "mic-1", op: "gain", value: 18 } };
assert.deepEqual(JSON.parse(JSON.stringify(command)), command);
const result: DeviceCommandResultBody = {
officeId: "hq",
device: initialDeviceState(DECLARATION, 17),
observedAt: 17,
};
assert.deepEqual(JSON.parse(JSON.stringify(result)), result);
});
it("omits a reading a device does not have, rather than nulling it", () => {
// The difference matters on the wire as well as in the panel: `null` would
// survive JSON as a *reading of zero information* that a consumer has to
// special-case, while an absent key is already the thing every consumer
// checks for. `initialDeviceState` is where the rule is implemented.
const state = initialDeviceState({ ...DECLARATION, capabilities: ["power"] }, 1);
const round = JSON.parse(JSON.stringify(state)) as DeviceState;
assert.equal("levelDb" in round, false);
assert.equal("muted" in round, false);
assert.equal(round.powered, false);
assert.equal(round.synthetic, true);
});
it("declares regions and a device source on the health body", () => {
// A compile-time assertion made at runtime: `health()` above is typed as a
// `HealthBody`, so this file would not build if either field left the type.
const body = health();
assert.equal(body.sources.devices, "sim");
assert.equal(body.regions[0]?.id, "sf");
});
});
describe("what the browser learns from /health", () => {
it("reports the device source and the demotions to the interface", async () => {
const access = await resolveAccess(
deployment({
"/health": () =>
json(
health({
degraded: ["TERA_WEATHER_SOURCE=nws needs TERA_WEATHER_CONTACT.", "and another"],
}),
),
}),
);
assert.equal(access.feeds?.devices, true);
// Built, served, and — until now — read by nobody. This is the whole point
// of the field: "why is the weather always clear" answers itself.
assert.deepEqual(access.degraded, [
"TERA_WEATHER_SOURCE=nws needs TERA_WEATHER_CONTACT.",
"and another",
]);
});
it("falls the safe way when the server is older than this client", async () => {
const older = health();
delete (older.sources as Partial<HealthBody["sources"]>).devices;
delete (older as Partial<HealthBody>).degraded;
const access = await resolveAccess(deployment({ "/health": () => json(older) }));
// No field means no feed and no request. A poll against a box that never
// heard of the route is a 404 per TTL per tab, forever.
assert.equal(access.feeds?.devices, false);
assert.deepEqual(access.degraded, []);
});
it("drops anything in degraded that is not a sentence", async () => {
const access = await resolveAccess(
deployment({ "/health": () => json(health({ degraded: [1, null, { a: 1 }, "real"] as never })) }),
);
// `[object Object]` in front of an operator who is already looking at this
// list because something is wrong.
assert.deepEqual(access.degraded, ["real"]);
});
it("has nothing to report about a deployment that does not exist", async () => {
const access = await resolveAccess(deployment({}));
assert.equal(access.tier, "member");
assert.equal(access.feeds, null);
assert.deepEqual(access.degraded, []);
});
});
describe("a zero-config clone", () => {
it("gets an empty device feed that does not claim to be live", async () => {
const client = createTeraClient({ fetch: deployment({}) });
const feed = await client.devices("hq");
assert.deepEqual(feed.value, []);
assert.equal(feed.live, false);
assert.equal(feed.source, "none");
});
it("gets a studio that is alive anyway, from the simulator in this tab", () => {
const source = createDeviceSource({ declarations: [DECLARATION], client: null });
source.command({ deviceId: "mic-1", op: "power", value: true });
let peak = -60;
for (let i = 0; i < 400; i += 1) {
source.tick(0.1);
peak = Math.max(peak, source.current().states[0]?.levelDb ?? -60);
}
assert.ok(peak > -58, `peak ${peak}`);
// Alive, and honest about it: `live` is "a deployment answered" and
// `synthetic` is "nobody observed this", and both are what the panel shows.
assert.equal(source.current().live, false);
assert.equal(source.current().synthetic, true);
assert.equal(source.current().source, "sim");
source.stop();
});
});
describe("the seam", () => {
it("is nothing at all for an office that declares no devices", () => {
const source = createDeviceSource({ declarations: [] });
assert.deepEqual(source.current().states, []);
assert.equal(source.current().source, "none");
source.tick(1);
assert.deepEqual(source.current().states, []);
});
it("reads the API when the deployment has a source and the viewer may read it", async (t) => {
const body: DevicesBody = {
officeId: "hq",
devices: [{ id: "mic-1", kind: "mic", powered: true, observedAt: 1, synthetic: true }],
observedAt: 1,
source: "sim",
synthetic: true,
ttlSeconds: 5,
};
const client = createTeraClient({ fetch: deployment({ "/devices": () => json(body) }) });
const readings: unknown[] = [];
const source = createDeviceSource({
declarations: [DECLARATION],
client,
officeId: "hq",
serverHasDevices: true,
onReading: (reading) => readings.push(reading),
});
t.after(() => source.stop());
// Before anything lands, the panel has instruments to draw rather than an
// empty box that would flicker into existence a poll later.
assert.equal(source.current().states.length, 1);
assert.equal(source.current().live, false);
await new Promise((resolve) => setTimeout(resolve, 0));
await new Promise((resolve) => setTimeout(resolve, 0));
assert.equal(source.current().live, true);
assert.equal(source.current().states[0]?.powered, true);
assert.equal(readings.length, 1);
// The server's clock, not ours: ticking must not advance a second set of
// numbers over the top of a real feed.
const before = JSON.stringify(source.current().states);
source.tick(5);
assert.equal(JSON.stringify(source.current().states), before);
});
it("skips the API entirely when /health said this box has no devices", async (t) => {
let asked = 0;
const client = createTeraClient({
fetch: deployment({
"/devices": () => {
asked += 1;
return json({});
},
}),
});
const source = createDeviceSource({
declarations: [DECLARATION],
client,
officeId: "hq",
serverHasDevices: false,
});
t.after(() => source.stop());
await new Promise((resolve) => setTimeout(resolve, 0));
assert.equal(asked, 0);
assert.equal(source.current().source, "sim");
});
it("reports a refused command rather than quietly applying it locally", async (t) => {
// The one asymmetry between the two strategies, and it is deliberate: on a
// real deployment a control that appears to work and changes nothing
// anybody else can see is worse than one that says no.
const client = createTeraClient({ fetch: deployment({}) });
const source = createDeviceSource({
declarations: [DECLARATION],
client,
officeId: "hq",
serverHasDevices: true,
});
// Registered before the assertions, not after them: a watch left running by
// a failed assertion keeps its back-off timer alive and hangs the runner
// long after the failure it is hiding.
t.after(() => source.stop());
const result = await source.command({ deviceId: "mic-1", op: "power", value: true });
assert.equal(result, null);
// The instruments are still there, at rest and not live — a deployment that
// has stopped answering is not an office that has no hardware in it.
assert.equal(source.current().states.length, 1);
assert.equal(source.current().states[0]?.powered, false);
assert.equal(source.current().live, false);
});
it("refuses a command the declaration does not allow, before spending a request", async (t) => {
let asked = 0;
const client = createTeraClient({
fetch: deployment({
"/command": () => {
asked += 1;
return json({});
},
}),
});
const source = createDeviceSource({
declarations: [DECLARATION],
client,
officeId: "hq",
serverHasDevices: true,
});
t.after(() => source.stop());
assert.equal(await source.command({ deviceId: "mic-1", op: "volume", value: 0.5 }), null);
assert.equal(await source.command({ deviceId: "somebody-elses", op: "power", value: true }), null);
assert.equal(asked, 0);
});
it("applies a command locally, and openly, on the simulated strategy", async () => {
const source = createDeviceSource({ declarations: [DECLARATION], client: null });
const state = await source.command({ deviceId: "mic-1", op: "power", value: true });
assert.equal(state?.powered, true);
assert.equal(state?.synthetic, true);
source.stop();
});
it("publishes only when a reading a viewer could see has changed", () => {
const readings: unknown[] = [];
const source = createDeviceSource({
declarations: [DECLARATION],
client: null,
onReading: (reading) => readings.push(reading),
});
// Powered off, so every step produces the same floor reading and only
// `observedAt` moves — which is deliberately not in the signature.
for (let i = 0; i < 50; i += 1) source.tick(0.1);
assert.equal(readings.length, 0);
void source.command({ deviceId: "mic-1", op: "power", value: true });
source.tick(0.1);
assert.ok(readings.length > 0);
source.stop();
});
it("does no work at all once stopped", async () => {
const source = createDeviceSource({ declarations: [DECLARATION], client: null });
void source.command({ deviceId: "mic-1", op: "power", value: true });
for (let i = 0; i < 20; i += 1) source.tick(0.1);
source.stop();
const frozen = JSON.stringify(source.current().states);
for (let i = 0; i < 20; i += 1) source.tick(0.1);
assert.equal(JSON.stringify(source.current().states), frozen);
assert.equal(await source.command({ deviceId: "mic-1", op: "mute", value: true }), null);
});
it("survives a tab that was backgrounded for ten minutes", () => {
const source = createDeviceSource({ declarations: [DECLARATION], client: null });
void source.command({ deviceId: "mic-1", op: "power", value: true });
// Six hundred seconds of `dt` would be six thousand steps in one frame.
source.tick(600);
// Still a valid reading, and it arrived without a hitch.
const level = source.current().states[0]?.levelDb ?? 0;
assert.ok(level >= -60 && level <= 0, `${level}`);
});
it("has a null source for anything that genuinely has nothing to say", () => {
const source = createNullDeviceSource();
assert.deepEqual(source.current().states, []);
assert.equal(source.current().source, "none");
assert.equal(source.current().synthetic, true);
source.tick(1);
source.refresh();
source.setOccupancy(["desk-01"]);
source.stop();
});
});