Shoot the README with the token the bundles ship, and make the fidelity gate ask

Two related fixes, both about a measurement that had outlived the thing it
measured.

The shot harness fetched its Mapbox token from doxa.life/api/maps/token on every
run. That token belongs to the Mapbox account `doxalife` and is URL-restricted
to doxa.life, which is why the harness also had to spoof a Referer header to get
any tiles at all. Meanwhile the built bundles carry a different token entirely —
`gosystems`, baked in from vite.doxa-maps-build-config.json — and that one is not
restricted. Measured with no Referer: mapbox-streets-v8, country-boundaries-v1
and bathymetry-v2 all return 200 on the baked token and 403 on the fetched one.
The harness was doing extra work to use the weaker of the two.

It now reads the build config first and keeps the fetch as a fallback. Beyond
simply working, a README image is evidence about the SHIPPED artifact, so it
should render with the credential the artifact ships with; rendering with a
different token means the picture stops proving what a reader downloads. The
local read is also deterministic — the network path degraded silently, setting
the token to empty when doxa.life was slow, after which every shot was taken
token-limited and still written to disk.

check:shot-fidelity had the same problem one layer up. It fired its tileset
findings whenever any file referenced a mapbox:// tileset, and printed
"Referer doxa.life -> 200 · 127.0.0.1 -> 403 · no referer -> 403" as though it
were a live reading. It was one, on 2026-09-21, against the token that shipped
then. After the token swap in 1b6316a the sentence kept printing — warning about
a blank void while the shots came out fully painted. A gate that states a
measured fact has to re-measure it, or it becomes a confident lie at exactly the
moment someone fixes what it describes. It now fetches one real tile with the
baked token and no Referer, and suppresses the tileset findings when that
returns 200.

Network failure is deliberately not treated as a restriction. An offline box
cannot tell "restricted" from "unreachable", and asserting a restriction that
may not exist is the defect being repaired.

Negative-tested: pointing the probe at the restricted doxalife token makes the
gate report RESTRICTED and fire all three findings; the shipped token makes it
report REACHABLE and suppress them. The first attempt at that test proved
nothing and is worth recording — the poison never applied, because doxa.life
returns 403 to Python's default user agent, so the copy was never written and
the unmodified gate ran and "passed". A negative test that cannot fail is the
same defect in miniature. Re-run with a browser UA, it discriminated correctly.

The 12 regenerated screenshots are the point of all this. cap3-monolithic-research
was read as an image, not inferred from the generator's exit code: it now shows
coastlines, country borders, place labels, ocean names and Mapbox/OpenStreetMap
attribution, with the 2,107 data dots sitting on real geography instead of an
empty void. Note the PNG got 67KB SMALLER while gaining all of that, so file size
was never going to answer the question.

check:shot-fonts still fails, and that is pre-existing and honest: this box has no
emoji font, so six bundles shoot tofu boxes. Verified by stashing these edits and
re-running — exit 1 either way. The markup is correct; the fix is a font on the
shot machine, never removing emoji from the product.
This commit is contained in:
doxa-maps-88655c70 2026-09-23 06:26:39 +00:00
parent 7311434a71
commit bd504063a1
14 changed files with 77 additions and 14 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 903 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,021 KiB

After

Width:  |  Height:  |  Size: 974 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 833 KiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 854 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 922 KiB

View file

@ -159,16 +159,57 @@ function tileDependentMapBundles() {
return out
}
/**
* ★ ASK THE TOKEN, DO NOT ASSERT ABOUT IT (added 2026-09-23).
*
* The two tileset findings below used to fire whenever any file referenced a `mapbox://` tileset,
* and printed a hardcoded "127.0.0.1 -> 403" as though it were a live measurement. It WAS one, on
* 2026-09-21, against the token that shipped then. The baked token has since been swapped
* (commit 1b6316a) to one that is NOT URL-restricted, and the old sentences kept printing —
* warning about a blank void while the shots came out fully painted.
*
* A gate that states a measured fact must re-measure it, or it becomes a confident lie at exactly
* the moment someone fixes the thing it describes. So: fetch one real tile with the token the
* bundles actually ship, sending no Referer, which is precisely what this shot machine does. 200
* means the tileset findings do not apply and are suppressed; 403 means they do.
*
* Network failure is NOT treated as 403. An offline box cannot distinguish "restricted" from
* "unreachable", and reporting a restriction that may not exist is the failure being fixed here.
*/
async function tilesetReachability() {
let token = ''
try {
const cfg = JSON.parse(readFileSync(join(ROOT, 'vite.doxa-maps-build-config.json'), 'utf8'))
if (typeof cfg.token === 'string' && cfg.token.startsWith('pk.')) token = cfg.token
} catch { /* no build config — fall through to unknown */ }
if (!token) return { state: 'unknown', why: 'no pk. token baked in vite.doxa-maps-build-config.json' }
const url = 'https://api.mapbox.com/v4/mapbox.country-boundaries-v1/3/4/3.vector.pbf?access_token=' + token
try {
const r = await fetch(url, { signal: AbortSignal.timeout(12000) })
if (r.status === 200) return { state: 'reachable', why: 'country-boundaries-v1 -> 200 with no Referer, on the baked token' }
if (r.status === 401 || r.status === 403) return { state: 'restricted', why: `country-boundaries-v1 -> ${r.status} with no Referer` }
return { state: 'unknown', why: `country-boundaries-v1 -> HTTP ${r.status}` }
} catch (e) {
return { state: 'unknown', why: `tile probe did not complete (${e?.name || 'error'}) — offline is not a restriction` }
}
}
const bundles = emojiBundles()
const fonts = emojiFontCount()
const tilesetFiles = restrictedTilesetFiles()
const tileBundles = tileDependentMapBundles()
const tiles = await tilesetReachability()
const tilesetFiles = tiles.state === 'reachable' ? [] : restrictedTilesetFiles()
const tileBundles = tiles.state === 'reachable' ? [] : tileDependentMapBundles()
const findings = [] // every condition reports; no early exit hides a later one
console.log(`SHOT-FIDELITY: ${bundles.length} bundle(s) render emoji; emoji fonts on this box: ` +
`${fonts === null ? 'UNKNOWN (no fc-list)' : fonts}`)
console.log(`SHOT-FIDELITY: ${tilesetFiles.length} file(s) source a Mapbox-hosted tileset ` +
`(mapbox://mapbox.*), which a URL-restricted token cannot fetch off its allowed origin.`)
console.log(`SHOT-FIDELITY: Mapbox tilesets are ${tiles.state.toUpperCase()} from this box — ${tiles.why}.`)
if (tiles.state === 'reachable') {
console.log(' So the tileset findings do not apply: shots taken here get a real basemap, not a blank void.')
} else {
console.log(` ${tilesetFiles.length} file(s) source a Mapbox-hosted tileset (mapbox://mapbox.*), which a`)
console.log(' URL-restricted token cannot fetch off its allowed origin.')
}
if (fonts === null) {
console.log(' i fc-list not available — cannot verify glyph coverage. Screenshots UNASSESSED.')
@ -181,10 +222,10 @@ if (tileBundles.length) {
'as a blank void when the token cannot fetch tilesets from this origin:',
` ${tileBundles.join(', ')}`,
'',
' Measured: the STYLE document returns 200 everywhere (so the map boots, the legend and',
' controls paint, the data layer is correct) while mapbox-streets-v8 / bathymetry-v2 /',
' country-boundaries-v1 all return 403 off doxa.life. A booted map showing its own UI and',
' its own data looks like a working map — only the coastlines and country fills are gone.',
' The STYLE document returns 200 everywhere (so the map boots, the legend and controls paint,',
' and the data layer is correct) while the TILESETS are refused. A booted map showing its own',
' UI and its own data looks like a working map — only the coastlines and country fills are',
` gone. Measured this run: ${tiles.why}.`,
'',
' Bundles that ship their own world-adm0.geojson are UNAFFECTED, which is why one cap-4 shot',
' looks perfect beside four blank ones. That contrast is a red herring, not a per-bundle bug.',
@ -197,8 +238,7 @@ if (tilesetFiles.length) {
'SHOT-FIDELITY: a tileset-backed map pane can shoot BLANK while the page reports OK.',
` files sourcing a mapbox:// tileset: ${tilesetFiles.join(', ')}`,
'',
' The shared pk. token is URL-restricted. Measured against country-boundaries-v1:',
' Referer doxa.life -> 200 (3/3) · 127.0.0.1 -> 403 · no referer -> 403',
` Measured THIS RUN against country-boundaries-v1 with the baked token: ${tiles.why}.`,
' The STYLE endpoint returns 200 from every origin, so every map BOOTS and only the TILES are',
' missing — which is why this first looked like "that surface has no map".',
'',

View file

@ -45,13 +45,36 @@ const server = createServer(async (req, res) => {
await new Promise(r => server.listen(0, '127.0.0.1', r))
const BASE = `http://127.0.0.1:${server.address().port}`
// Live token so maps paint fully.
// ★ SHOOT WITH THE TOKEN THE BUNDLES ACTUALLY SHIP, not one fetched over the network.
//
// This used to fetch https://doxa.life/api/maps/token unconditionally. That token belongs to the
// Mapbox account `doxalife` and is URL-restricted to doxa.life, which is why the shot harness had
// to spoof a Referer to make tiles load at all. Meanwhile the BUILT BUNDLES carry a different
// token — `gosystems`, baked in at build time from vite.doxa-maps-build-config.json — which is not
// URL-restricted. Measured 2026-09-23 with no Referer at all: mapbox-streets-v8,
// country-boundaries-v1 and bathymetry-v2 all return 200 on the baked token and 403 on the fetched
// one. So the harness was doing extra work to use the weaker of the two.
//
// Two reasons to prefer the baked token beyond it simply working. A README image is evidence about
// the SHIPPED artifact, so it should render with the credential the artifact ships with; rendering
// with a different token means the picture no longer proves what a reader downloads. And reading
// the build config is local and deterministic — the network path degrades silently, setting TK to
// '' when doxa.life is slow, after which every shot is taken token-limited and still written to
// disk. The fetch is kept only as a fallback for a tree whose build config has no baked token.
let TK = ''
let TK_SRC = ''
try {
const r = await fetch('https://doxa.life/api/maps/token', { signal: AbortSignal.timeout(8000) })
TK = r.ok ? ((await r.json()).token || '') : ''
const cfg = JSON.parse(await readFile(new URL('../vite.doxa-maps-build-config.json', import.meta.url), 'utf8'))
if (typeof cfg.token === 'string' && cfg.token.startsWith('pk.')) { TK = cfg.token; TK_SRC = 'build config (the token the bundles ship)' }
} catch {}
console.log(TK ? `token: acquired (${TK.length} chars) — maps will paint` : 'token: NONE — maps token-limited')
if (!TK) {
try {
const r = await fetch('https://doxa.life/api/maps/token', { signal: AbortSignal.timeout(8000) })
TK = r.ok ? ((await r.json()).token || '') : ''
if (TK) TK_SRC = 'doxa.life/api/maps/token (fallback — needs the Referer header below)'
} catch {}
}
console.log(TK ? `token: ${TK.length} chars from ${TK_SRC}` : 'token: NONE — maps token-limited')
// ★ SwiftShader — WITHOUT THESE ARGS EVERY MAP SHOT IS TAKEN WITH NO GL CONTEXT.
// This script was written under the belief "this VPS has no WebGL", which was a LAUNCH-FLAG