6fc0b2b60e
The owner has now asked four times why there are three boards, and the last
answer missed the point: reconciling the packs made them draw one California,
but you still *arrived* on the coarsest tier the product owns and still changed
boards by picking a name off a list. This changes both.
**The behaviour was already built and behind a second flag defaulted off.**
`handover()` in `ladder.ts` — promote/demote by camera stand-off, hysteresis at
0.9/1.15, a drag guard so a board never swaps under a finger — was pure, tested
and shipped a round ago, with `?handover=1` as the only way to see it. It is on
now, `?handover=0` turns it off. Measured on the deployed bundle first:
promotion into the Bay Area fired at the sixteenth wheel notch in from the state
pose, arrival clean, no boot card, no tab, no click on a name.
**And it did not work, for a reason worth writing down.** Landing on the Bay
with the flag on bounced straight back to the state board with no input at all.
Two wrong diagnoses on the way, both from reasoning instead of measuring:
1. "sf's ceiling equals its own widest pose, so the band is too tight." It is
not — `chapterStandoffMetres` puts the resting pose at 71.2 km against a
demote threshold of 81.9 km.
2. "the arrival flight carries the camera through the threshold, so guard on
`arriving()`." Right about the cause, wrong about the mechanism: the guard
went in and the bounce survived it.
A trajectory log settled it in one run. The handover tick arrived *before* the
first `arriving=true` sample, at 108,316 m — 1.5x sf's resting stand-off, which
is `arrivalStart`'s own offset. `arrive()` read:
kit.setPose(from);
arrival = { from, to: rest, elapsed: 0 };
`setPose` drives `OrbitControls`, which fires `change` **synchronously**, and
`main.ts` listens on that event. So the listener ran on the line *between* those
two statements: camera already 1.5x out, `arriving()` still false. A one-frame
ordering race, and the guard could not fire because the flag it reads was set one
statement too late. The assignment now goes first.
The guard stays, because the inequality behind it is structural rather than
incidental: `ARRIVAL_STANDOFF` is 1.5 and `DEMOTE` is 1.15, both global, so the
opening frame of *every* board sits outside that board's own retention band.
`handoverArrivalGuard.test.ts` asserts that relation and drives the real rule
through the opening stand-off to watch it demote, so neither the guard nor either
constant can be quietly simplified.
**The landing board is `DEFAULT_CITY_ID`, and it is the Bay Area.** It was
`CITIES[0]` in three places, which meant the state tier: seventeen districts over
1063x930 km at 1,919 m per unit, no city legible, and a left column whose first
offer is somewhere else to go. The detailed boards carry 52 and 47 districts at
94 and 391 m per unit. With free handover on, the state tier stops being a
destination and becomes what you get when you pull back — the role it is good at,
since it is the only board drawing 97.4% of California. A named constant rather
than reordering `CITIES`, because that array's order is the `?city=` fallback and
is read positionally by other consumers.
**Which caught a silent break in the capture harness, and this is the part that
would have cost a week.** `shots.mjs` and `films.mjs` built `?city=` only when a
shot declared one — and 4 of 21 shots and 1 of 4 films declare none, so they
inherited the app's default. Moving that default would have re-pointed five
pieces of marketing imagery at a different place while every filename, caption
and alt text stayed as it was. Both harnesses now name `california` themselves.
`performance-budget.mjs`'s `california` and `california-drive` cells had no query
at all for the same reason; `signature` would have failed them loudly rather than
mismeasuring, which is the harness working, but a harness that depends on an app
default reports someone else's change as its own flake.
Every harness also pins `handover=0`. A planted pose wider than a board's
retention band would otherwise demote to the coarser tier while the shutter is
open, and the frame that comes back is a real photograph of the wrong board.
Verified: bare URL lands on the Bay Area and stays there; `?city=california` and
`?city=socal` still deep-link; `?handover=0` stays put; zooming out from the Bay
demotes to the state tier at the second notch. 1,694 tests pass. All ten budget
cells pass with no cap raised, and every cell now measures the board it names.
Still true and now a decision rather than a doubt: 97.4% of California has no
board below 242 km of stand-off, so zooming into the middle of the state lands on
coarse ground. That picture has been looked at. Authoring Sacramento, Fresno and
the Central Valley is what retires it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
117 lines
4.5 KiB
TypeScript
117 lines
4.5 KiB
TypeScript
/**
|
|
* The one inequality that makes the arrival guard necessary.
|
|
*
|
|
* `main.ts`'s `maybeHandover` refuses to run while `handle.arriving()` is true.
|
|
* That line looks like belt-and-braces and is not: without it, landing on any
|
|
* board with the free-camera handover on threw the visitor straight back to the
|
|
* coarser tier they came from, with no input at all. It was measured on the
|
|
* deployed bundle twice — `?city=sf` alone stays on the Bay Area, `?city=sf` with
|
|
* the handover on reported "San Francisco Bay Area" and then "California".
|
|
*
|
|
* The cause is arithmetic rather than tuning, which is why it is asserted here
|
|
* rather than left to a screenshot. `arrivalStart` opens every board's
|
|
* unrequested move at `ARRIVAL_STANDOFF` times the resting stand-off, and
|
|
* `handover` demotes a board once the camera passes `DEMOTE` times that board's
|
|
* handover ceiling. A board's ceiling is its own widest authored pose, so the
|
|
* opening frame sits outside its own retention band for as long as
|
|
* `ARRIVAL_STANDOFF > DEMOTE` — and it does, for every board there will ever be,
|
|
* because both are single global constants.
|
|
*
|
|
* So this file exists to fail the day somebody "simplifies" one of three things:
|
|
* the guard, `ARRIVAL_STANDOFF`, or `DEMOTE`.
|
|
*/
|
|
|
|
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
|
|
import { ARRIVAL_STANDOFF } from "../engine/scene.ts";
|
|
import { DEMOTE, HANDOVER_STANDOFF_M, PROMOTE, handover } from "../engine/ladder.ts";
|
|
import SAN_FRANCISCO from "../cities/sf.ts";
|
|
import SOCAL from "../cities/socal.ts";
|
|
import CALIFORNIA from "../cities/california.ts";
|
|
|
|
const BOARDS = [CALIFORNIA, SAN_FRANCISCO, SOCAL].map((city) => ({
|
|
id: city.id,
|
|
bounds: city.bounds,
|
|
metresPerUnit: 111_320 / city.latScale,
|
|
}));
|
|
|
|
describe("the arrival guard", () => {
|
|
it("is required, because the opening move starts outside every board's retention band", () => {
|
|
assert.ok(
|
|
ARRIVAL_STANDOFF > DEMOTE,
|
|
`arrival opens at ${ARRIVAL_STANDOFF}x resting and a board is demoted above ` +
|
|
`${DEMOTE}x its ceiling — if this ever stops being true the guard in ` +
|
|
"maybeHandover may be reconsidered, and until then it may not",
|
|
);
|
|
});
|
|
|
|
it("would demote a board on its own opening frame, for each board that has a ceiling", () => {
|
|
/*
|
|
* The failure the guard prevents, reproduced through the real rule: put the
|
|
* camera where `arrivalStart` puts it — 1.5x the resting stand-off, which for
|
|
* a board at rest on its own widest pose is 1.5x its ceiling — and ask the
|
|
* ladder what board that is. It answers "a coarser one", every time.
|
|
*/
|
|
for (const [id, ceiling] of Object.entries(HANDOVER_STANDOFF_M)) {
|
|
const board = BOARDS.find((candidate) => candidate.id === id);
|
|
assert.ok(board, `no pack for ${id}`);
|
|
const centre = { lat: (board.bounds.minLat + board.bounds.maxLat) / 2,
|
|
lng: (board.bounds.minLng + board.bounds.maxLng) / 2 };
|
|
const opening = handover({
|
|
boards: BOARDS,
|
|
current: id,
|
|
lat: centre.lat,
|
|
lng: centre.lng,
|
|
standoffM: ceiling * ARRIVAL_STANDOFF,
|
|
dragging: false,
|
|
});
|
|
assert.equal(
|
|
opening,
|
|
"california",
|
|
`${id}'s opening frame does not demote, so this test is asserting nothing`,
|
|
);
|
|
|
|
// And once the move has landed, the same board is stable: no promotion out
|
|
// of it and no demotion off it. That is the state the guard hands over to.
|
|
const settled = handover({
|
|
boards: BOARDS,
|
|
current: id,
|
|
lat: centre.lat,
|
|
lng: centre.lng,
|
|
standoffM: ceiling,
|
|
dragging: false,
|
|
});
|
|
assert.equal(settled, null, `${id} is not stable at its own resting stand-off`);
|
|
}
|
|
});
|
|
|
|
const SF_CEILING = HANDOVER_STANDOFF_M.sf ?? 0;
|
|
|
|
it("still promotes on the way in, which is the behaviour being protected", () => {
|
|
// Below the ceiling by more than the hysteresis band: the Bay Area is the
|
|
// right board for a camera this close to San Francisco.
|
|
const promoted = handover({
|
|
boards: BOARDS,
|
|
current: "california",
|
|
lat: 37.77,
|
|
lng: -122.42,
|
|
standoffM: SF_CEILING * PROMOTE * 0.9,
|
|
dragging: false,
|
|
});
|
|
assert.equal(promoted, "sf");
|
|
});
|
|
|
|
it("never swaps a board out from under a finger", () => {
|
|
const held = handover({
|
|
boards: BOARDS,
|
|
current: "california",
|
|
lat: 37.77,
|
|
lng: -122.42,
|
|
standoffM: SF_CEILING * PROMOTE * 0.9,
|
|
dragging: true,
|
|
});
|
|
assert.equal(held, null);
|
|
});
|
|
});
|