1
0

feat: real fire on the boards, the LA office as a twin, and a night sky worth reading

The world stops being a simulation of California and starts being California.

**THE PROMOTION GATE WAS THE FIRST COMMIT, BEFORE ANY ORANGE PIXEL EXISTED.**
On today's live store the SoCal board contains 22 incidents. Every one has NULL
acreage and fifteen are nameless LA County dispatch numbers. Drawn naively that
is 22 orange marks over Los Angeles on a day nothing is burning — in a frame that
contains no other warm colour, so one glyph would be the most salient object on
the board and twenty-two would spend its credibility permanently.

`acres >= 10 AND contained < 80 AND type != 'RX' AND last_seen = max(last_seen)`
returns 0 on SoCal, exactly 5 on California, 0 on the Bay — same body, same day,
three correct answers. The empty board is a deliverable, not a fallback: it says
"No active fire on this board — CAL FIRE and WFIGS, just now", states that 21
records were gated and why, lists the largest fires burning OUTSIDE the frame
with distances, and counts the hot pixels it is deliberately not drawing.

**The privacy leak is structurally impossible rather than carefully avoided.**
cloud-1 serves a projection; the four home-relative columns never leave that box.
`observations.threat` was the one that nearly got through — it is
`(16/distance)^2 x log10(acres) x momentum x containment x wind-alignment`, so
with acreage and containment public it inverts to a distance circle around a
house and three fires give an intersection. A grep of the built bundle for
distance_km, bearing_deg, threat, 7762 and the street name returns nothing.

**Deliberately not used, and both would have produced a confident wrong answer:**
the store's `air` table retains only the last parameter of each poll, so all 78
rows read "Good" while the live feed reports ozone 101 "Unhealthy for Sensitive
Groups" — haze driven off it would clear the sky during a smoke event. And
`weather` is written only inside the NWS alerts loop, so a quiet day stores no
wind at all. Tera's own per-region NWS wind is already correct and already what
the clouds drift on.

Satellite detections are drawn as evidence and never as incidents. The permanent
industrial heat source 4.7 km from the owner's house is flagged persistent and
dropped, asserted by a test that first proves it is present in the fixture.
MODIS integer confidence and VIIRS string confidence are branched on `sat`.

**The LA office is a twin.** Its entire authored second storey — Model Loft,
Model Bay, The Materials Room, 430 lines nobody had ever stood in — is reachable
on foot: a walker crosses level-1 to level-2 in 73 fixed steps, floorY 0 to 5,
verified against the real pack rather than a synthetic plan. Its two studio
devices read real hardware through a field-allowlisted bridge: mute, volume and
reachability only. Never level, because there is no passive level upstream and
obtaining one would record a room with people in it. Never dB, because upstream
is gainPct across four different native scales. The bridge refuses all writes.

Fixed at its root: an anonymous visitor was getting permanently at-rest
instruments backing off against a 401. The tier moves into `createDeviceSource`,
so anon gets the living simulator three file headers already promised.

**Item 8 is closed, not fixed, and the correction is the point.** The Bay Area
"stutter" was GPU power management — the card sat at 500 MHz of 2725 through
every run that reproduced it, 4096/2048/1024/256 shadow maps all render in
1.21-1.31 ms, and two consecutive runs over a byte-identical dist gave 33.4 then
16.7. The allowance is removed and the cell is back to 16.7. Geometry is the
gate; frame time is advisory.

Item 7 was re-scoped after measuring: 1,069,006 of the Bay Area's 2,265,056
triangles were the second submission of the same buildings into the shadow pass.
Mobile now has its own triangle caps and bay-area mobile draws 1,266,096.

Also: bridges and the freeway corridor light up at night as emission, not lights
— 1,614 deck lamps and 18 tower heads on the Bay in two draw calls. The single
change that made US-101 legible was moving its edge lines from the lit material
to the unlit one: retroreflective paint, the argument the SFO night frame already
makes. California went 21,991 lamps to 4,051, clustered at the 17 town districts,
because a rural interurban corridor genuinely is unlit.

Tests 1137 -> 1340, server 280. All ten budget cells pass on first attempt with
no cap raised.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-22 18:01:11 -07:00
parent b7f5c41da5
commit b25f217e3e
91 changed files with 15111 additions and 401 deletions
+246 -2
View File
@@ -75,6 +75,7 @@ import {
} from "../engine/atmosphere.ts";
import { MAX_EXTRA_TRAFFIC } from "../engine/flights.ts";
import { daylightPhase, solarPosition, sunTimes } from "../engine/solar.ts";
import type * as THREE from "three";
import type { Stage } from "../engine/stage.ts";
/**
@@ -888,7 +889,104 @@ export function createGodmode(options: GodmodeOptions): Godmode {
renderLedger();
});
perfSection.body.append(frameLine, frameNote, drawLine, memLine, ledgerNote, ledgerTable);
/**
* GPU time per frame, which is the number the interval above cannot give you.
*
* The interval is floored at the refresh rate by vsync, so a board that
* renders in 1.2 ms and one that renders in 15 both read 16.7 and look
* identical — and a whole day was once spent on a frame-drop hypothesis that
* one glance at this readout would have settled. `EXT_disjoint_timer_query_webgl2`
* is the only way to ask a browser what the GPU actually spent.
*
* Three properties of the extension decide the shape of this code:
*
* - **It is optional**, and absent on most Safari and on any browser with
* the mitigation for the timing side channels enabled. Absent means the
* row says so and nothing else changes.
* - **The result is not ready on the frame that issued it.** A query is
* polled on later frames until `QUERY_RESULT_AVAILABLE`, which is why
* there is a queue rather than a variable.
* - **A disjoint result is garbage and must be thrown away**, not averaged
* in. `GPU_DISJOINT_EXT` latches when the driver preempted or reclocked
* mid-query — which on this repo's box is exactly the condition worth
* measuring around, so a lying number here would be worse than no number.
*
* One query in flight at a time. The panel is an instrument and instruments
* that cost frames are lying about the thing they measure.
*/
const gpuLine = el("div", "gm-line");
const gpuNote = el("div", "gm-hint");
gpuNote.textContent =
"time the GPU spent on one frame, which vsync hides from the interval above";
/**
* Per-layer visibility, with what turning each one off is worth.
*
* Matched by `Object3D.name` against the scene root rather than through a
* handle, deliberately: this panel must keep working across a city switch that
* disposes the whole stage, and across an office, without `main.ts` having to
* publish a layer registry that exists only for a debug drawer. The names are
* the ones the layers already set on themselves.
*
* The delta beside each chip is the honest way to answer "what does this
* cost": hide it, let the next frame land, and subtract the renderer's own
* counters. Every measurement behind the handheld shadow-caster cut in
* `blocks.ts` was taken this way, with a patched bundle, because the panel
* could not do it yet.
*/
const layerChips = el("div", "gm-chips");
const layerNote = el("div", "gm-hint");
layerNote.textContent = "hidden layers, and what the last hide was worth";
const layerDelta = el("div", "gm-line");
const LAYERS: { name: string; label: string }[] = [
{ name: "blocks", label: "buildings" },
{ name: "terrain", label: "terrain" },
{ name: "clouds", label: "clouds" },
{ name: "satellites", label: "satellites" },
{ name: "nightlights", label: "night lights" },
{ name: "flights", label: "aircraft" },
{ name: "sky", label: "sky dome" },
];
const hidden = new Set<string>();
/** The counters from the frame before the last toggle, for the delta. */
let beforeToggle: Sample | null = null;
let toggledLabel = "";
function sceneRoot(): THREE.Object3D | null {
return place.stage.current()?.scene ?? null;
}
function applyLayerVisibility() {
const root = sceneRoot();
if (!root) return;
for (const { name } of LAYERS) {
const object = root.getObjectByName(name);
if (object) object.visible = !hidden.has(name);
}
}
for (const layer of LAYERS) {
const chip: HTMLButtonElement = button("gm-chip", layer.label, () => {
beforeToggle = sample();
toggledLabel = layer.label;
if (hidden.has(layer.name)) hidden.delete(layer.name);
else hidden.add(layer.name);
applyLayerVisibility();
// The panel's existing convention for a latched chip, so it picks up the
// amber `gm-chip[aria-pressed="true"]` rule and reads correctly to a screen
// reader rather than only to a stylesheet.
chip.setAttribute("aria-pressed", String(hidden.has(layer.name)));
// The delta needs a frame drawn with the new state before it means
// anything; `refreshLive` picks it up on its next tick.
setText(layerDelta, `${toggledLabel}: measuring…`);
});
chip.setAttribute("aria-pressed", "false");
layerChips.append(chip);
}
perfSection.body.append(frameLine, frameNote, gpuLine, gpuNote, drawLine, memLine);
perfSection.body.append(layerNote, layerChips, layerDelta);
perfSection.body.append(ledgerNote, ledgerTable);
perfSection.body.append(ledgerReset);
// ---- Overlays -------------------------------------------------------------
@@ -908,8 +1006,67 @@ export function createGodmode(options: GodmodeOptions): Godmode {
refresh();
});
const copyButton = button("gm-chip", "copy pose", () => copyPose());
/**
* Stand on the board and look up — the reverse of every other pose in this
* product, and the only one from which the sky is a subject rather than a
* backdrop.
*
* This matters more than a debug convenience. A map camera looks *down*: at
* the boards' resting pose the top of the frame is still several degrees below
* horizontal, so nothing above the horizon is ever in shot — not the moon
* `atmosphere.ts` computes to a hundredth of a degree, not the constellation,
* not a moonrise. Every one of those is drawn and correct and, from the poses
* the product ships with, invisible. This is the one button that shows them,
* and it is how the sky work in this round was judged at all.
*
* It drives the controls directly rather than going through a flight, because
* `SceneKit.flyTo` interpolates between two *orbit* poses and this is not one:
* the target is put a board span away in the direction the camera is already
* facing and lifted well above it, which is an orbit whose polar angle is
* past anything `maxPolarAngle` permits by hand. Restoring is a second press,
* from the pose remembered on the first.
*/
let restorePose: { position: THREE.Vector3; target: THREE.Vector3 } | null = null;
const lookUpChip: HTMLButtonElement = button("gm-chip", "look up", () => {
const current = place.stage.current();
if (!current) return;
const { camera, controls } = current;
if (restorePose) {
camera.position.copy(restorePose.position);
controls.target.copy(restorePose.target);
restorePose = null;
lookUpChip.setAttribute("aria-pressed", "false");
} else {
restorePose = { position: camera.position.clone(), target: controls.target.clone() };
// The heading the camera already has, flattened, so pressing this does not
// also spin the board: whatever compass direction was being looked at is
// the one the sky is read in.
const heading = controls.target.clone().sub(camera.position);
heading.y = 0;
if (heading.lengthSq() < 1e-6) heading.set(0, 0, -1);
heading.normalize();
const reach = Math.max(1, camera.position.distanceTo(controls.target));
// Forty degrees up: high enough to clear the horizon band and to hold a
// moon at any elevation it reaches from this latitude, low enough that the
// ground is still in the bottom of the frame and the shot has somewhere to
// stand.
// Written out per component rather than through a second `Vector3`,
// because this module imports three for its types only — a value import
// for one addition would pull the whole library into a panel that is
// dynamically imported precisely so that it does not.
controls.target.set(
camera.position.x + heading.x * reach * 0.6,
camera.position.y + reach * 0.5,
camera.position.z + heading.z * reach * 0.6,
);
lookUpChip.setAttribute("aria-pressed", "true");
}
controls.update();
refresh();
});
lookUpChip.setAttribute("aria-pressed", "false");
const copyNote = el("div", "gm-hint");
overlayChips.append(poseChip, bodiesChip, airChip, copyButton);
overlayChips.append(poseChip, bodiesChip, airChip, lookUpChip, copyButton);
overlaySection.body.append(overlayChips, copyNote);
body.append(
@@ -944,6 +1101,70 @@ export function createGodmode(options: GodmodeOptions): Godmode {
let lastRefresh = 0;
let raf = 0;
/*
* The GPU timer. See `gpuLine` for the argument; this is the machinery.
*
* Typed structurally rather than against `WebGL2RenderingContext` because
* `EXT_disjoint_timer_query_webgl2` has no lib.dom type — it is an extension
* object with two constants and two methods, and writing them out is smaller
* than any declaration file that would cover it.
*/
interface TimerExtension {
TIME_ELAPSED_EXT: number;
GPU_DISJOINT_EXT: number;
}
const gl = (() => {
const context = place.stage.renderer.getContext();
return typeof WebGL2RenderingContext !== "undefined" &&
context instanceof WebGL2RenderingContext
? context
: null;
})();
const timer = (gl?.getExtension("EXT_disjoint_timer_query_webgl2") ??
null) as TimerExtension | null;
/** The query currently being measured or polled, and the last good answer. */
let gpuQuery: WebGLQuery | null = null;
let gpuMeasuring = false;
let gpuMs: number | null = null;
/**
* One query in flight, opened before the frame is drawn and closed after.
*
* This runs from the panel's own rAF, which is registered before the stage's
* — `createGodmode` is constructed after `createStage`, and rAF callbacks fire
* in registration order — so the begin lands ahead of the scene's draw calls
* and the end lands after them, without a hook inside the stage's loop. That
* ordering is the whole trick and is why this can measure a renderer it does
* not own.
*/
function gpuBegin() {
if (!gl || !timer || gpuMeasuring) return;
if (gpuQuery === null) gpuQuery = gl.createQuery();
if (gpuQuery === null) return;
gl.beginQuery(timer.TIME_ELAPSED_EXT, gpuQuery);
gpuMeasuring = true;
}
function gpuEnd() {
if (!gl || !timer || !gpuMeasuring) return;
gl.endQuery(timer.TIME_ELAPSED_EXT);
gpuMeasuring = false;
}
/** Poll the outstanding query. A disjoint result is discarded, never averaged. */
function gpuPoll() {
if (!gl || !timer || gpuQuery === null || gpuMeasuring) return;
if (gl.getQueryParameter(gpuQuery, gl.QUERY_RESULT_AVAILABLE) !== true) return;
const disjoint = gl.getParameter(timer.GPU_DISJOINT_EXT) === true;
const nanoseconds = gl.getQueryParameter(gpuQuery, gl.QUERY_RESULT) as number;
gl.deleteQuery(gpuQuery);
gpuQuery = null;
// A disjoint means the driver preempted or reclocked mid-query, which on the
// box this was written on is exactly the condition worth measuring around.
// A lying number here would be worse than no number.
if (!disjoint && Number.isFinite(nanoseconds)) gpuMs = nanoseconds / 1e6;
}
interface Sample {
geometries: number;
textures: number;
@@ -990,6 +1211,12 @@ export function createGodmode(options: GodmodeOptions): Godmode {
function frame(now: number) {
raf = requestAnimationFrame(frame);
// Close the query this callback opened one frame ago, then poll it, then
// open the next one — so the stage's draw calls, which run after this
// callback returns, land inside the query that was just begun.
gpuEnd();
gpuPoll();
gpuBegin();
if (lastFrame !== 0) {
intervals[intervalAt] = now - lastFrame;
intervalAt = (intervalAt + 1) % FRAME_SAMPLES;
@@ -1303,7 +1530,24 @@ export function createGodmode(options: GodmodeOptions): Godmode {
`${median.toFixed(1)} ms median · ${p95.toFixed(1)} p95 · ` +
`${median > 0 ? Math.round(1000 / median) : 0} fps`,
);
setText(
gpuLine,
timer === null
? "gpu — EXT_disjoint_timer_query_webgl2 not available in this browser"
: gpuMs === null
? "gpu — waiting for a query that is not disjoint"
: `gpu ${gpuMs.toFixed(2)} ms`,
);
const now = sample();
if (beforeToggle !== null) {
const dCalls = now.calls - beforeToggle.calls;
const dTris = now.triangles - beforeToggle.triangles;
setText(
layerDelta,
`${toggledLabel}: ${fmtSigned(dCalls)} calls · ${fmtSigned(dTris)} tris`,
);
beforeToggle = null;
}
setText(drawLine, `draw ${fmtInt(now.calls)} calls · ${fmtTris(now.triangles)} tris`);
setText(
memLine,