From 496cd880916af2c274109c80a82c67ae0a759b83 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Tue, 29 Sep 2026 04:21:58 +0000 Subject: [PATCH] Make NOT MEASURED name the blocked requests instead of guessing why This gate reported a 403 as "tileset entitlement, not the embed" and printed only the first blocked URL. Both halves were wrong. The claim is disproved. Measured on this gate's own token: /v4/ streets-v8 and country-boundaries both return 200 -- with no Referer, and from research.nuxtbase.app, maps-dev.nuxtbase.app, doxa.life, 127.0.0.1 and example.com. The token is unrestricted and entitled. The old conclusion rested on three no-Referer probes, which cannot tell a URL-restricted token from a missing entitlement; it named a cause those probes could not support. Whatever 403s is a different request -- a style, a sprite, glyphs, a composite -- or a different token than the one measured. Printing one URL is what hid that. A leaf blocked on forty tiles showed whichever tile lost the race, so the tileset was never legible and a second blocked endpoint was invisible behind the first. NOT MEASURED now names every distinct blocked path, with tile coordinates folded to {z}/{x}/{y} so one blocked tileset is one fact rather than forty, and styles, sprites and glyphs stay separate -- which is exactly the class the evidence now points at. It also names where the token came from (env var or the leaf's own baked one), never its value: the query string is stripped before any path is printed, asserted in the exercise below. The real-failure arm gets the same treatment. The gate asserts no cause any more. It reports what was blocked and lets the reader judge. Exercised on six URLs spanning two tilesets, a sprite and a glyph range: 6 -> 4 distinct facts, and a planted token value does not appear in the output. --- internal/check-mapbox-drew.mjs | 45 ++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/internal/check-mapbox-drew.mjs b/internal/check-mapbox-drew.mjs index 28a8b7ce1..c344587e5 100644 --- a/internal/check-mapbox-drew.mjs +++ b/internal/check-mapbox-drew.mjs @@ -20,11 +20,18 @@ * rendered fully blank while "a real GL canvas exists at 1200x780" passed. So drawing is asserted * with queryRenderedFeatures() > 0 on the leaf's own rendered features, not by canvas geometry. * - * ★ THREE EXIT STATES, BECAUSE TWO WOULD FORCE A LIE. On this sandbox the Mapbox /v4/ composite - * raster endpoint and country-boundaries both 403 — proven outside the browser with no Referer, with - * 127.0.0.1 and with localhost, so it is TILESET ENTITLEMENT, not the embed (PRODUCTION-MATRIX:235). - * Counting that as a failure would manufacture work for every owner; counting it as a pass would be - * false. It exits 75 NOT MEASURED instead, and says which endpoint. + * ★ THREE EXIT STATES, BECAUSE TWO WOULD FORCE A LIE. When a tile endpoint 403s, the leaf draws + * nothing through no fault of its owner. Counting that as a failure would manufacture work for every + * owner; counting it as a pass would be false. It exits 75 NOT MEASURED instead, NAMING every + * distinct blocked request path and the token's source, so the next reader can tell which + * credential was in play without the gate ever printing it. + * ✗ AN EARLIER VERSION CALLED THIS "TILESET ENTITLEMENT" AND THAT WAS WRONG. Measured 2026-09-29 by + * rega on this gate's own token: /v4/ streets-v8 and country-boundaries both return 200, with no + * Referer and from research.nuxtbase.app, maps-dev.nuxtbase.app, doxa.life, 127.0.0.1 and + * example.com. The token is unrestricted and entitled. The old claim rested on three no-Referer + * probes, which cannot distinguish a URL-restricted token from a missing entitlement. Whatever 403s + * is a different request or a different token — which is exactly what the gate must now report + * instead of guessing. * * USAGE MAP_TOKEN=pk.… node internal/check-mapbox-drew.mjs [--dir ] [--only a/b,c/d] * Run through internal/browser-slot.sh — it needs the browser seat. @@ -91,8 +98,30 @@ async function serve(dir) { return { port, stop: () => { try { srv.kill() } catch (_) {} } } } -// The endpoints known to 403 on the sandbox token. Entitlement, not the owner's bug. +// Endpoints whose 403 is NOT the leaf owner's bug, so a leaf blocked on one is NOT MEASURED +// rather than FAILED. +// +// ✗ WHY THIS NO LONGER CLAIMS "ENTITLEMENT" (corrected 2026-09-29). It used to report a 403 here +// as "tileset, not the embed", on the strength of three no-Referer probes. MEASURED since, by rega, +// with the very token this gate runs on: /v4/ streets-v8 AND country-boundaries return 200 — with +// no Referer, and with research.nuxtbase.app, maps-dev.nuxtbase.app, doxa.life, 127.0.0.1 and +// example.com. The token is unrestricted and entitled, so whatever 403s here is a DIFFERENT +// request (a style, sprite, glyphs, a composite with terrain) or a different token than the one +// tested. Three no-Referer cases cannot tell a URL-restricted token from a missing entitlement, +// and the old comment stated a conclusion those cases could not support. +// So this list stays — a 403 on a tile endpoint still makes a leaf unjudgeable — but the gate now +// NAMES every distinct blocked path and where its token came from, and asserts no cause. const ENTITLEMENT = [/\/v4\//, /country-boundaries/] +// Where the token came from, so a NOT MEASURED says which credential was in play. Never the value. +const TOKEN_SOURCE = process.env.MAP_TOKEN ? 'env MAP_TOKEN' + : process.env.MAPBOX_TOKEN ? 'env MAPBOX_TOKEN' + : 'none in env (the leaf used its own baked token, if any)' +// Distinct request paths, query dropped and TILE COORDINATES folded to {z}/{x}/{y}: one blocked +// tileset requested over 40 tiles is ONE fact, not forty, and a reader needs the tileset name, not +// which tile happened to be first. The query goes first, so a token can never reach the output. +const pathsOf = (urls) => [...new Set(urls.map((u) => String(u) + .replace(/\?.*/, '') + .replace(/\/\d+\/\d+\/\d+(?=(\.|@|$))/, '/{z}/{x}/{y}')))] async function measure(page, url, provider) { const errs = [] @@ -143,10 +172,10 @@ for (const id of leaves) { if (!drew) { notMeasured.push(`${id}: no sized canvas appeared within 30s`); continue } // ── 4. THE ENGINE. A silent fallback is the failure worth catching. ── if (drew.engine !== 'mapbox') { fails.push(`${id}: asked for ?provider=mapbox and the canvas that drew is ${drew.engine.toUpperCase()} — a silent fallback`); continue } - if (otherForbidden.length) { fails.push(`${id}: 403 on ${otherForbidden[0]} — not the known entitlement endpoints`); continue } + if (otherForbidden.length) { fails.push(`${id}: 403 on ${pathsOf(otherForbidden).join(' , ')} — not a tile endpoint [token: ${TOKEN_SOURCE}]`); continue } // ── 5/6. DREW, or an entitlement 403 that makes it unjudgeable. ── if (drew.features > 0) { passes.push(`${id}: mapbox canvas, ${drew.features} rendered feature(s)`); continue } - if (entitlement.length) { notMeasured.push(`${id}: 0 features and an entitlement 403 (${entitlement[0].replace(/\?.*/, '')}) — tileset, not the embed`); continue } + if (entitlement.length) { notMeasured.push(`${id}: 0 features; 403 on ${pathsOf(entitlement).join(' , ')} [token: ${TOKEN_SOURCE}]`); continue } if (errs.length) { fails.push(`${id}: 0 rendered features, page error: ${errs[0].slice(0, 90)}`); continue } fails.push(`${id}: mapbox canvas drew 0 rendered features, and no 403 explains it`) }