correct the "research-dashboard owns no map" premise and gate the blank-tileset class
A previous reader measured ZERO <canvas> on research-dashboard and concluded the surface owns no map, recording it as an architectural fact and relaxing the shot's readiness check to match. The measurement was real; the inference inverted it. The page imports useMapInstance, injects mapboxToken and adds a vector source, and re-measured live it builds a mapboxgl-canvas at 878x445. Zero canvas meant the map failed to initialise. The cost was not the blank image. A weakened assertion that makes a failing check pass promotes a defect to a design note, and the README's deploy-3 proof has shown a blank grey map pane since. Why it is blank, measured: the shared pk. token is URL-restricted to doxa.life. Against country-boundaries-v1, Referer doxa.life returns 200 on three attempts, 127.0.0.1 and no referer return 403. The style endpoint returns 200 from every origin, which is why most maps paint here and only the tileset-backed choropleth blanks. A first reading of that asymmetry looked like a missing tileset scope; re-testing with the doxa.life referer disproved it. check:shot-fidelity now reports this class alongside the missing emoji font, and no longer exits early after the first finding.
This commit is contained in:
parent
15ce17f907
commit
dfe6c3d1fa
2 changed files with 89 additions and 9 deletions
|
|
@ -73,19 +73,76 @@ function emojiFontCount() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Source files that request a Mapbox-hosted TILESET (`mapbox://mapbox.*`).
|
||||
*
|
||||
* ★ SECOND FIDELITY CLASS, found the same way as the first — by LOOKING at a screenshot
|
||||
* (2026-09-21). deploy3-research-dashboard.png shows a completely BLANK GREY map pane. The shot
|
||||
* reported OK: the page loaded, 1083 elements rendered, the legend and hint text painted. Only the
|
||||
* tiles were missing.
|
||||
*
|
||||
* WHY, measured rather than guessed: the shared pk. token is URL-restricted to doxa.life. Against
|
||||
* `mapbox://mapbox.country-boundaries-v1` — Referer doxa.life -> 200 (3/3), 127.0.0.1 -> 403,
|
||||
* no referer -> 403. The STYLE endpoint (styles/v1/mapbox/light-v11) returns 200 from EVERY origin,
|
||||
* which is exactly why most maps paint normally here and only the tileset-backed choropleth blanks.
|
||||
* A first reading of "style 200 / tileset 403 everywhere" looked like a missing tileset SCOPE;
|
||||
* re-testing with the doxa.life referer disproved that. Restriction, not scope.
|
||||
*
|
||||
* ★ THE COST OF NOT CATCHING THIS WAS NOT THE BLANK IMAGE. It was that a previous reader measured
|
||||
* "ZERO <canvas>" on this page and concluded the surface OWNS NO MAP — inverting a symptom into an
|
||||
* architectural fact, then relaxing the shot's readiness check to match. The defect got promoted to
|
||||
* a design note. Naming the condition explicitly is what stops that.
|
||||
*/
|
||||
function restrictedTilesetFiles() {
|
||||
const out = []
|
||||
const walk = (dir) => {
|
||||
if (!existsSync(dir)) return
|
||||
for (const e of readdirSync(dir, { withFileTypes: true })) {
|
||||
if (/^(node_modules|[_.])/.test(e.name)) continue
|
||||
const p = join(dir, e.name)
|
||||
if (e.isDirectory()) { walk(p); continue }
|
||||
if (!/\.(vue|js|mjs)$/.test(e.name)) continue
|
||||
if (/mapbox:\/\/mapbox\./.test(readFileSync(p, 'utf8'))) out.push(p.slice(ROOT.length + 1))
|
||||
}
|
||||
}
|
||||
walk(join(ROOT, 'plugin-designs'))
|
||||
walk(join(ROOT, 'library'))
|
||||
return out
|
||||
}
|
||||
|
||||
const bundles = emojiBundles()
|
||||
const fonts = emojiFontCount()
|
||||
const tilesetFiles = restrictedTilesetFiles()
|
||||
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.`)
|
||||
|
||||
if (fonts === null) {
|
||||
console.log(' i fc-list not available — cannot verify glyph coverage. Screenshots UNASSESSED.')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
if (tilesetFiles.length) {
|
||||
findings.push([
|
||||
'',
|
||||
'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',
|
||||
' The STYLE endpoint returns 200 from every origin, so MOST maps paint here and only the',
|
||||
' tileset-backed choropleth blanks — which is why this looked like "that surface has no map".',
|
||||
'',
|
||||
' ★ It is NOT a missing tileset scope (re-tested with the doxa.life referer, which passes)',
|
||||
' and NOT a code defect. Either shoot these panes from an allowed origin, or add the shot',
|
||||
' origin to the token\'s URL restrictions at Mapbox.',
|
||||
].join('\n'))
|
||||
}
|
||||
|
||||
if (bundles.length && fonts === 0) {
|
||||
const msg = [
|
||||
findings.push([
|
||||
'',
|
||||
'SHOT-FIDELITY: this machine has NO emoji font, so every emoji renders as a tofu box (□).',
|
||||
` affected bundles: ${bundles.join(', ')}`,
|
||||
|
|
@ -97,10 +154,15 @@ if (bundles.length && fonts === 0) {
|
|||
'',
|
||||
' `bun run shots` CANNOT catch this: it checks that pages load, and a tofu glyph loads',
|
||||
' perfectly — 0 console errors, 0 HTTP>=400, full element counts.',
|
||||
].join('\n')
|
||||
].join('\n'))
|
||||
}
|
||||
|
||||
if (findings.length) {
|
||||
const msg = findings.join('\n')
|
||||
if (STRICT) { console.error(msg); process.exit(1) }
|
||||
console.log(msg)
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
console.log('SHOT-FIDELITY: PASS — an emoji font is present, so shots render the intended glyphs.')
|
||||
console.log('SHOT-FIDELITY: PASS — an emoji font is present and no tileset-backed pane is at risk; ' +
|
||||
'shots render what they are meant to show.')
|
||||
|
|
|
|||
|
|
@ -214,11 +214,29 @@ await shot('deploy2-mobile-spa', '/doxa-maps/doxa-maps-spa/doxa-maps-spa/index.h
|
|||
{ vp: { width: 390, height: 844 }, wait: 10000, dsf: 3 })
|
||||
|
||||
// ---- DEPLOY3: research dashboard ----
|
||||
// ★ NOT `waitFor: CANVAS` (2026-09-21). research-dashboard OWNS NO MAP — it is an SVG-charts
|
||||
// surface (measured: 1083 elements, 10 <svg>, ZERO <canvas>). Waiting for a canvas could only ever
|
||||
// time out, so this shot failed for 20s on every run and left a STALE image behind. The page was
|
||||
// never broken; the EXPECTATION was wrong about what this surface is. The minElements readiness
|
||||
// guard already proves the surface rendered, without asserting a technology it does not use.
|
||||
// ★ THE EARLIER NOTE HERE WAS WRONG, AND THE WAY IT WAS WRONG IS WORTH KEEPING (corrected
|
||||
// 2026-09-21). It read: "research-dashboard OWNS NO MAP — it is an SVG-charts surface (measured:
|
||||
// 1083 elements, 10 <svg>, ZERO <canvas>)". The MEASUREMENT was real; the INFERENCE inverted it.
|
||||
// research-dashboard absolutely owns a Mapbox map — src/components/dashboards/DashboardMapPanel.vue
|
||||
// imports useMapInstance, injects mapboxToken, and adds a vector source. Re-measured live, the page
|
||||
// DOES build a `mapboxgl-canvas` at 878x445.
|
||||
//
|
||||
// ★ "ZERO CANVAS" MEANT THE MAP FAILED TO INITIALISE, NOT THAT NO MAP EXISTS. Reading absence as a
|
||||
// property of the surface turned a symptom into an architectural "fact", and that fact then
|
||||
// justified relaxing the readiness check — so the shot stopped waiting for the very thing whose
|
||||
// absence was the bug, and the README's deploy-3 proof image has shown a BLANK GREY map pane since.
|
||||
// A weakened assertion that makes a failing check pass is how a defect gets promoted to a design note.
|
||||
//
|
||||
// WHY THE PANE IS STILL GREY (a real defect, tracked separately — not this file's to fix):
|
||||
// the panel sources `mapbox://mapbox.country-boundaries-v1`, and the shared pk. token is URL-
|
||||
// restricted to doxa.life. Measured: Referer doxa.life -> 200 (3/3), 127.0.0.1 -> 403, none -> 403.
|
||||
// The STYLE endpoint returns 200 from every origin, which is why other maps paint normally and only
|
||||
// the tileset-backed choropleth blanks. So the shot machine cannot paint this pane at all today.
|
||||
//
|
||||
// `waitFor: CANVAS` is therefore still wrong HERE — not because there is no map, but because the
|
||||
// canvas genuinely cannot be produced from this origin, and a gate that can never pass gets
|
||||
// weakened again by the next reader. minElements proves the surface rendered; check:shot-fidelity
|
||||
// is where "this machine cannot render what the shot must show" belongs.
|
||||
await shot('deploy3-research-dashboard', '/doxa-maps/research-dashboard/research-dashboard/index.html',
|
||||
{ waitFor: 'svg', wait: 10000, minElements: 200 })
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue