Browser gates: measure THIS build, or measure nothing

About thirty browser gates could pass while describing another worktree's build.
This machine runs several checkouts and a default port belongs to whichever
server started first — measured 2026-09-24, :4173 was another worktree's, and an
hour of probing reported confidently on code nobody here had touched. check:sri
cannot see it: a stale tree and its stale leaf agree perfectly.

Twenty gates now call requireThisTree() right after they resolve their target and
exit 75 on a mismatch — EX_TEMPFAIL, the code this repo already uses for "not
measured", which the wave runner reports as ⊘ rather than ✗. Exiting 1 would turn
a mis-pointed probe into a red product gate, which is the failure this whole
family of checks exists to prevent.

★ NARROWER THAN THE PROBLEM STATEMENT, ON PURPOSE. Three classes do NOT get it,
because there it would be wrong rather than missing:
  self-serving gates  start their own server on an OS-assigned port
  file:// gates       read this checkout directly — no server to be wrong about
  remote targets      verify-map-paint defaults to the LIVE site, and "does
                      production match what we built" is a deploy question asked
                      deliberately. MEASURED mid-rollout: it reported NOT
                      MEASURED against the live host, which was the guard being
                      wrong, not the gate. It now enforces on localhost only.

TWO THINGS THE ROLLOUT TAUGHT, both caught by running rather than reading:
  · node --check passes a file that will die on ReferenceError. Adding a ROOT
    constant to sixteen gates that do not import resolve/dirname/fileURLToPath
    parsed perfectly and crashed on first run — the same shape that broke
    check-locale-reachable twice. The imports are added under aliased names so
    they cannot collide with a gate's own.
  · Five gates take their URL from argv with no default and are left for a
    per-file pass rather than patched blind.

CONTROLS: against another worktree's server a guarded gate prints NOT MEASURED
naming the mismatch and exits 75; against this checkout's server it runs and
reports normally; against the live site it proceeds.
This commit is contained in:
doxa-maps-88655c70 2026-09-25 08:20:11 +00:00
parent 7f700935c5
commit a9550858ed
18 changed files with 217 additions and 0 deletions

View file

@ -85,3 +85,41 @@ export async function serveThisTree(dir) {
} }
return null return null
} }
/**
* The same check, as a one-liner a gate can put right after it resolves its base URL.
*
* ★ EXIT 75, NOT 1. A gate pointed at another worktree's server has NOT MEASURED this build — it
* has not found a defect in it. flock uses 75 for the same idea (EX_TEMPFAIL) and the wave runner
* already reports 75 as ⊘ rather than ✗, so one code means "not measured" everywhere in this repo.
* Exiting 1 here would turn a mis-pointed probe into a red product gate, which is the failure this
* whole family of checks exists to prevent.
*
* @param {string} base origin (or any URL on it) that should serve public/
* @param {string} repo absolute path to the repo root
* @param {string} label the gate's own name, for the message
*/
export async function requireThisTree(base, repo, label) {
let origin = String(base || '')
// A gate that loads file:// URLs is reading THIS checkout by construction — there is no server to
// be wrong about, so the guard stays silent rather than inventing a precondition.
if (!/^https?:/i.test(origin)) return { ok: true, why: 'not an http target' }
// ★ ONLY LOCAL SERVERS. The defect this guards is several worktrees sharing one machine's ports.
// A gate aimed at a DEPLOYED site (verify-map-paint defaults to the live host) is asking a
// different question on purpose — "does production match what we built" is a deploy check, not a
// mis-pointed probe — and enforcing local identity there would make it permanently unmeasured.
// MEASURED while rolling this out: that gate reported NOT MEASURED against the live site, which
// is the guard being wrong rather than the gate.
try {
const host = new URL(origin).hostname
if (!/^(localhost|127\.|0\.0\.0\.0$|\[?::1\]?$)/.test(host)) return { ok: true, why: 'remote target, not a worktree port' }
} catch { /* unparseable — fall through to the content check */ }
try { origin = new URL(origin).origin } catch { /* already an origin, or unusable — pass through */ }
const verdict = await servesThisTree(origin, repo)
if (/DIFFERENT build/.test(verdict.why)) {
console.log(`${label}: NOT MEASURED — ${verdict.why}`)
console.log(' Point this gate at a server for THIS checkout (bun run serve) and re-run.')
process.exit(75)
}
return verdict
}

View file

@ -27,8 +27,19 @@
// //
// Usage: node internal/check-aria-labels-localized.mjs <leafUrl> [locales] // Usage: node internal/check-aria-labels-localized.mjs <leafUrl> [locales]
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
const URL_ = process.argv[2] || process.env.ARIA_URL const URL_ = process.argv[2] || process.env.ARIA_URL
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(URL_, ROOT, 'ARIA-LABELS-LOCALIZED')
if (!URL_) { if (!URL_) {
console.log('ARIA-LABELS-LOCALIZED: SKIP — no leaf url given.') console.log('ARIA-LABELS-LOCALIZED: SKIP — no leaf url given.')
console.log(' Pass one, or set ARIA_URL. Serve the TREE ROOT (public/) and point at a leaf,') console.log(' Pass one, or set ARIA_URL. Serve the TREE ROOT (public/) and point at a leaf,')

View file

@ -13,8 +13,19 @@
// Usage: node internal/check-card-deck.mjs [lang] [stock] // Usage: node internal/check-card-deck.mjs [lang] [stock]
// PACKET_ORIGIN (default http://127.0.0.1:4898) · PACKET_API · PACKET_ISO3 // PACKET_ORIGIN (default http://127.0.0.1:4898) · PACKET_API · PACKET_ISO3
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898' const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898'
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(ORIGIN, ROOT, 'CARD-DECK')
const API = process.env.PACKET_API || 'https://pray.doxa.life' const API = process.env.PACKET_API || 'https://pray.doxa.life'
const ISO3 = process.env.PACKET_ISO3 || 'LAO' const ISO3 = process.env.PACKET_ISO3 || 'LAO'
const LANG = process.argv[2] || 'en' const LANG = process.argv[2] || 'en'

View file

@ -17,8 +17,17 @@ import { chromium } from 'playwright'
import { readFileSync, existsSync } from 'node:fs' import { readFileSync, existsSync } from 'node:fs'
import { resolve, dirname, join } from 'node:path' import { resolve, dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import { requireThisTree } from './_serves-this-tree.mjs'
const URL_ = process.argv[2] const URL_ = process.argv[2]
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(URL_, ROOT, 'DECK-CLICK')
if (!URL_) { console.error('usage: check-deck-click.mjs <wallUrl> [stock] [expectedPage]'); process.exit(2) } if (!URL_) { console.error('usage: check-deck-click.mjs <wallUrl> [stock] [expectedPage]'); process.exit(2) }
const STOCK = process.argv[3] || '' const STOCK = process.argv[3] || ''
const EXPECT_PAGE = process.argv[4] || (STOCK === 'pokerLandscape' ? '3.5in 2.5in' : '2.5in 3.5in') const EXPECT_PAGE = process.argv[4] || (STOCK === 'pokerLandscape' ? '3.5in 2.5in' : '2.5in 3.5in')

View file

@ -34,8 +34,19 @@
* exactly where the old probe passed, which is the property that makes it worth having. * exactly where the old probe passed, which is the property that makes it worth having.
*/ */
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
const BASE = process.env.BASE || 'http://127.0.0.1:4173/doxa-maps' const BASE = process.env.BASE || 'http://127.0.0.1:4173/doxa-maps'
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(BASE, ROOT, 'FIXED-ANCHORING')
const TK = process.env.MAPBOX_TOKEN ? `?tk=${process.env.MAPBOX_TOKEN}` : '' const TK = process.env.MAPBOX_TOKEN ? `?tk=${process.env.MAPBOX_TOKEN}` : ''
const DEEP = `(sel)=>{const out=[],seen=new Set();const w=(r)=>{if(!r||seen.has(r))return;seen.add(r);try{out.push(...r.querySelectorAll(sel))}catch(e){};for(const el of r.querySelectorAll('*'))if(el.shadowRoot)w(el.shadowRoot)};w(document);return out}` const DEEP = `(sel)=>{const out=[],seen=new Set();const w=(r)=>{if(!r||seen.has(r))return;seen.add(r);try{out.push(...r.querySelectorAll(sel))}catch(e){};for(const el of r.querySelectorAll('*'))if(el.shadowRoot)w(el.shadowRoot)};w(document);return out}`

View file

@ -29,11 +29,20 @@ import { chromium } from 'playwright'
import { serveReaped } from './_serve-reaped.mjs' import { serveReaped } from './_serve-reaped.mjs'
import { resolve, dirname } from 'node:path' import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import { requireThisTree } from './_serves-this-tree.mjs'
const HERE = dirname(fileURLToPath(import.meta.url)) const HERE = dirname(fileURLToPath(import.meta.url))
const PUBLIC = resolve(HERE, '../public') const PUBLIC = resolve(HERE, '../public')
const PORT = Number(process.env.PORT || 5399) const PORT = Number(process.env.PORT || 5399)
const BASE = process.env.BASE_URL || `http://127.0.0.1:${PORT}` const BASE = process.env.BASE_URL || `http://127.0.0.1:${PORT}`
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(BASE, ROOT, 'GOSPEL-COMPOSED-FILTERS')
const PATHNAME = '/doxa-maps/gospel-resources/gospel-dashboard/index.html' const PATHNAME = '/doxa-maps/gospel-resources/gospel-dashboard/index.html'
let srv = null let srv = null

View file

@ -32,11 +32,21 @@ import { chromium } from 'playwright'
import { readFileSync, existsSync } from 'node:fs' import { readFileSync, existsSync } from 'node:fs'
import { join, dirname } from 'node:path' import { join, dirname } from 'node:path'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
const REPO = join(dirname(fileURLToPath(import.meta.url)), '..') const REPO = join(dirname(fileURLToPath(import.meta.url)), '..')
const LOCALES = join(REPO, 'library/i18n/locales') const LOCALES = join(REPO, 'library/i18n/locales')
const URL_ = process.argv[2] || process.env.LEGEND_URL const URL_ = process.argv[2] || process.env.LEGEND_URL
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(URL_, ROOT, 'LEGEND-INFO-LOCALIZED')
if (!URL_) { if (!URL_) {
console.log('LEGEND-INFO-LOCALIZED: SKIP — no leaf url given.') console.log('LEGEND-INFO-LOCALIZED: SKIP — no leaf url given.')
console.log(' Pass one, or set LEGEND_URL. Serve the TREE ROOT (public/doxa-maps) and point') console.log(' Pass one, or set LEGEND_URL. Serve the TREE ROOT (public/doxa-maps) and point')

View file

@ -24,9 +24,20 @@
* actually removed before release, the race was not staged and it exits 2, not 0. * actually removed before release, the race was not staged and it exits 2, not 0.
*/ */
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
const i = process.argv.indexOf('--url') const i = process.argv.indexOf('--url')
const BASE = (i > -1 ? process.argv[i + 1] : '').replace(/#.*$/, '') const BASE = (i > -1 ? process.argv[i + 1] : '').replace(/#.*$/, '')
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(BASE, ROOT, 'MAP-UNMOUNT-MID-INIT')
if (!BASE) { console.error('check-map-unmount-mid-init: pass --url <studio page>'); process.exit(2) } if (!BASE) { console.error('check-map-unmount-mid-init: pass --url <studio page>'); process.exit(2) }
// Production map plugins that go through useMapInstance, opened by their studio key. // Production map plugins that go through useMapInstance, opened by their studio key.

View file

@ -13,8 +13,19 @@
// //
// Usage: node internal/check-mfe-two-tab.mjs <url> [expectedTabCount] // Usage: node internal/check-mfe-two-tab.mjs <url> [expectedTabCount]
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
const URL = process.argv[2] const URL = process.argv[2]
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(URL, ROOT, 'MFE-TWO-TAB')
if (!URL) { console.error('usage: check-mfe-two-tab.mjs <url> [tabs]'); process.exit(2) } if (!URL) { console.error('usage: check-mfe-two-tab.mjs <url> [tabs]'); process.exit(2) }
const WANT_TABS = Number(process.argv[3] || 2) const WANT_TABS = Number(process.argv[3] || 2)

View file

@ -37,10 +37,18 @@ import { readFileSync, existsSync } from 'node:fs'
import { resolve, dirname, join } from 'node:path' import { resolve, dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..') const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..')
const MANIFEST = join(ROOT, 'public', 'doxa-maps', 'manifest.json') const MANIFEST = join(ROOT, 'public', 'doxa-maps', 'manifest.json')
const BASE = process.env.BASE || 'http://127.0.0.1:4173/doxa-maps/' const BASE = process.env.BASE || 'http://127.0.0.1:4173/doxa-maps/'
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees of this repo run on one machine and
// a default port belongs to whichever server started first — measured 2026-09-24, :4173 was another
// worktree's, and browser gates reported confidently on a build nobody here had touched. Exit 75
// (EX_TEMPFAIL) rather than 1: pointing at the wrong tree is a precondition, not a product defect,
// and the wave runner already reports 75 as ⊘ instead of ✗.
await requireThisTree(BASE, ROOT, 'NAV-REACHABLE-MOBILE')
// 414x896 = iPhone-class portrait, comfortably inside the layout's 760px breakpoint. // 414x896 = iPhone-class portrait, comfortably inside the layout's 760px breakpoint.
const VIEWPORT = { width: Number(process.env.W || 414), height: Number(process.env.H || 896) } const VIEWPORT = { width: Number(process.env.W || 414), height: Number(process.env.H || 896) }

View file

@ -25,8 +25,19 @@
// //
// Usage: node internal/check-poster-degrades-honestly.mjs <wallUrl> [zoneId] // Usage: node internal/check-poster-degrades-honestly.mjs <wallUrl> [zoneId]
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
const WALL = process.argv[2] || process.env.POSTER_WALL_URL const WALL = process.argv[2] || process.env.POSTER_WALL_URL
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(WALL, ROOT, 'POSTER-DEGRADES-HONESTLY')
if (!WALL) { if (!WALL) {
console.log('POSTER-DEGRADES: SKIP — no wall url given.') console.log('POSTER-DEGRADES: SKIP — no wall url given.')
console.log(' Serve the TREE ROOT (public/<name>), not public/, or assetsBase resolves') console.log(' Serve the TREE ROOT (public/<name>), not public/, or assetsBase resolves')

View file

@ -24,12 +24,23 @@
// //
// Usage: node internal/check-poster-print-fallback.mjs <wallUrl> [zoneId] // Usage: node internal/check-poster-print-fallback.mjs <wallUrl> [zoneId]
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
// SKIP, never fail, when the preconditions are absent. This gate needs a SERVED tree // SKIP, never fail, when the preconditions are absent. This gate needs a SERVED tree
// that carries posters/<id>.html (posterSources:true or bundlePosters:true). The // that carries posters/<id>.html (posterSources:true or bundlePosters:true). The
// default tree ships neither, and a clean checkout has no server at all — failing the // default tree ships neither, and a clean checkout has no server at all — failing the
// build on that would only teach people to disable the gate. It says what is missing. // build on that would only teach people to disable the gate. It says what is missing.
const WALL = process.argv[2] || process.env.POSTER_WALL_URL const WALL = process.argv[2] || process.env.POSTER_WALL_URL
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(WALL, ROOT, 'POSTER-PRINT-FALLBACK')
if (!WALL) { if (!WALL) {
console.log('POSTER-PRINT-FALLBACK: SKIP — no wall url given.') console.log('POSTER-PRINT-FALLBACK: SKIP — no wall url given.')
console.log(' Pass one, or set POSTER_WALL_URL. Needs a tree built with posterSources:true') console.log(' Pass one, or set POSTER_WALL_URL. Needs a tree built with posterSources:true')

View file

@ -17,8 +17,19 @@
// Usage: node internal/check-poster-raster.mjs [zoneId] // Usage: node internal/check-poster-raster.mjs [zoneId]
// PACKET_ORIGIN (default http://127.0.0.1:4898) // PACKET_ORIGIN (default http://127.0.0.1:4898)
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898' const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898'
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(ORIGIN, ROOT, 'POSTER-RASTER')
const ZONE = process.argv[2] || 'laos' const ZONE = process.argv[2] || 'laos'
const HTML = `${ORIGIN}/library/scripts/posters/out/posters/${ZONE}.html` const HTML = `${ORIGIN}/library/scripts/posters/out/posters/${ZONE}.html`

View file

@ -14,8 +14,19 @@
// Usage: node internal/check-print-geometry.mjs // Usage: node internal/check-print-geometry.mjs
// PACKET_ORIGIN (default http://127.0.0.1:4898) — a static server over the repo root // PACKET_ORIGIN (default http://127.0.0.1:4898) — a static server over the repo root
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898' const ORIGIN = process.env.PACKET_ORIGIN || 'http://127.0.0.1:4898'
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(ORIGIN, ROOT, 'PRINT-GEOMETRY')
const API = process.env.PACKET_API || 'https://pray.doxa.life' const API = process.env.PACKET_API || 'https://pray.doxa.life'
const ISO3 = process.env.PACKET_ISO3 || 'LAO' const ISO3 = process.env.PACKET_ISO3 || 'LAO'

View file

@ -44,8 +44,19 @@
* Exit: 0 all pass · 1 any fail · 2 dev server unreachable (a precondition, not a defect). * Exit: 0 all pass · 1 any fail · 2 dev server unreachable (a precondition, not a defect).
*/ */
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
const BASE = (process.env.DEV_URL || 'http://localhost:5173').replace(/\/+$/, '') const BASE = (process.env.DEV_URL || 'http://localhost:5173').replace(/\/+$/, '')
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees of this repo run on one machine and
// a default port belongs to whichever server started first — measured 2026-09-24, :4173 was another
// worktree's, and browser gates reported confidently on a build nobody here had touched. Exit 75
// (EX_TEMPFAIL) rather than 1: pointing at the wrong tree is a precondition, not a product defect,
// and the wave runner already reports 75 as ⊘ instead of ✗.
await requireThisTree(BASE, ROOT, 'SCRIM-COVERS-VIEWPORT')
const SELF_TEST = process.argv.includes('--self-test') const SELF_TEST = process.argv.includes('--self-test')
const VW = 1280, VH = 900 const VW = 1280, VH = 900

View file

@ -24,9 +24,20 @@
* another worktree's tree — so this one refuses to guess. * another worktree's tree — so this one refuses to guess.
*/ */
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
const i = process.argv.indexOf('--url') const i = process.argv.indexOf('--url')
const URL_ = i > -1 ? process.argv[i + 1] : '' const URL_ = i > -1 ? process.argv[i + 1] : ''
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(URL_, ROOT, 'STUDIO-EVERY-PLUGIN')
if (!URL_) { if (!URL_) {
console.error('check-studio-every-plugin: pass --url <studio page>, e.g. --url http://localhost:5299/') console.error('check-studio-every-plugin: pass --url <studio page>, e.g. --url http://localhost:5299/')
process.exit(2) process.exit(2)

View file

@ -33,9 +33,20 @@
* Exits non-zero if any level fails, so it can gate a release. * Exits non-zero if any level fails, so it can gate a release.
*/ */
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
const GL=['--use-gl=swiftshader','--enable-unsafe-swiftshader','--ignore-gpu-blocklist','--enable-webgl','--no-sandbox'] const GL=['--use-gl=swiftshader','--enable-unsafe-swiftshader','--ignore-gpu-blocklist','--enable-webgl','--no-sandbox']
const B=(process.env.BASE || 'https://nuxtbase.app/plugin-assets/doxa-maps/').replace(/\/?$/,'/') const B=(process.env.BASE || 'https://nuxtbase.app/plugin-assets/doxa-maps/').replace(/\/?$/,'/')
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(B, ROOT, '5-CAPABILITIES')
// capability = 5 - PROFILE_TIER (discover.mjs). One representative per level. // capability = 5 - PROFILE_TIER (discover.mjs). One representative per level.
const REPS=[ const REPS=[
// ★ CORRECTED 2026-09-20 by the manifest reconciliation added below, on its FIRST RUN. // ★ CORRECTED 2026-09-20 by the manifest reconciliation added below, on its FIRST RUN.

View file

@ -30,6 +30,9 @@
* Exits non-zero if any leaf fails, so it can become a gate. * Exits non-zero if any leaf fails, so it can become a gate.
*/ */
import { chromium } from 'playwright' import { chromium } from 'playwright'
import { requireThisTree } from './_serves-this-tree.mjs'
import { resolve as _resolvePath, dirname as _dirnamePath } from 'node:path'
import { fileURLToPath as _fileURLToPath } from 'node:url'
// The SwiftShader launch. Without these a headless Chromium here has NO GL context at all. // The SwiftShader launch. Without these a headless Chromium here has NO GL context at all.
const GL_ARGS = [ const GL_ARGS = [
@ -41,6 +44,14 @@ const GL_ARGS = [
] ]
const BASE = process.env.BASE || 'https://nuxtbase.app/plugin-assets/doxa-maps' const BASE = process.env.BASE || 'https://nuxtbase.app/plugin-assets/doxa-maps'
const ROOT = _resolvePath(_dirnamePath(_fileURLToPath(import.meta.url)), '..')
// ★ MEASURE THIS BUILD, OR MEASURE NOTHING. Several worktrees run on one machine and a default port
// belongs to whichever server started first — measured 2026-09-24 on :4173, where browser gates
// reported confidently about a build nobody here had touched. 75 (EX_TEMPFAIL), not 1: the wrong
// tree is a precondition, not a product defect, and the wave runner reports 75 as ⊘ rather than ✗.
// A file:// target passes straight through — there is no server there to be wrong about.
await requireThisTree(BASE, ROOT, 'MAP-PAINT')
// ★ WIDENED 2026-09-22 — 4 of 12 map profiles were covered, now 11. // ★ WIDENED 2026-09-22 — 4 of 12 map profiles were covered, now 11.
// The four originals were the ones that happened to be under investigation when this file was // The four originals were the ones that happened to be under investigation when this file was
// written. Measuring the manifest showed 12 profiles carry isMap=true, so EIGHT painted leaves // written. Measuring the manifest showed 12 profiles carry isMap=true, so EIGHT painted leaves