From a9550858ed3ad638d98b559330a1e54a2fe92427 Mon Sep 17 00:00:00 2001 From: doxa-maps-88655c70 <88627970+doxa-maps-88655c70@users.noreply.github.com> Date: Fri, 25 Sep 2026 08:20:11 +0000 Subject: [PATCH] Browser gates: measure THIS build, or measure nothing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- internal/_serves-this-tree.mjs | 38 +++++++++++++++++++++ internal/check-aria-labels-localized.mjs | 11 ++++++ internal/check-card-deck.mjs | 11 ++++++ internal/check-deck-click.mjs | 9 +++++ internal/check-fixed-anchoring.mjs | 11 ++++++ internal/check-gospel-composed-filters.mjs | 9 +++++ internal/check-legend-info-localized.mjs | 10 ++++++ internal/check-map-unmount-mid-init.mjs | 11 ++++++ internal/check-mfe-two-tab.mjs | 11 ++++++ internal/check-nav-reachable-mobile.mjs | 8 +++++ internal/check-poster-degrades-honestly.mjs | 11 ++++++ internal/check-poster-print-fallback.mjs | 11 ++++++ internal/check-poster-raster.mjs | 11 ++++++ internal/check-print-geometry.mjs | 11 ++++++ internal/check-scrim-covers-viewport.mjs | 11 ++++++ internal/check-studio-every-plugin.mjs | 11 ++++++ internal/verify-5-capabilities.mjs | 11 ++++++ internal/verify-map-paint.mjs | 11 ++++++ 18 files changed, 217 insertions(+) diff --git a/internal/_serves-this-tree.mjs b/internal/_serves-this-tree.mjs index eb1bd63ce..13c11e1cf 100644 --- a/internal/_serves-this-tree.mjs +++ b/internal/_serves-this-tree.mjs @@ -85,3 +85,41 @@ export async function serveThisTree(dir) { } 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 +} diff --git a/internal/check-aria-labels-localized.mjs b/internal/check-aria-labels-localized.mjs index c15b9a076..c67bd36bf 100644 --- a/internal/check-aria-labels-localized.mjs +++ b/internal/check-aria-labels-localized.mjs @@ -27,8 +27,19 @@ // // Usage: node internal/check-aria-labels-localized.mjs [locales] 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 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_) { 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,') diff --git a/internal/check-card-deck.mjs b/internal/check-card-deck.mjs index 2c2dec078..1beaf8587 100644 --- a/internal/check-card-deck.mjs +++ b/internal/check-card-deck.mjs @@ -13,8 +13,19 @@ // Usage: node internal/check-card-deck.mjs [lang] [stock] // PACKET_ORIGIN (default http://127.0.0.1:4898) · PACKET_API · PACKET_ISO3 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 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 ISO3 = process.env.PACKET_ISO3 || 'LAO' const LANG = process.argv[2] || 'en' diff --git a/internal/check-deck-click.mjs b/internal/check-deck-click.mjs index 05c9dc235..153637296 100644 --- a/internal/check-deck-click.mjs +++ b/internal/check-deck-click.mjs @@ -17,8 +17,17 @@ import { chromium } from 'playwright' import { readFileSync, existsSync } from 'node:fs' import { resolve, dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' +import { requireThisTree } from './_serves-this-tree.mjs' 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 [stock] [expectedPage]'); process.exit(2) } const STOCK = process.argv[3] || '' const EXPECT_PAGE = process.argv[4] || (STOCK === 'pokerLandscape' ? '3.5in 2.5in' : '2.5in 3.5in') diff --git a/internal/check-fixed-anchoring.mjs b/internal/check-fixed-anchoring.mjs index dc3e6f4f8..c2f5efa4a 100644 --- a/internal/check-fixed-anchoring.mjs +++ b/internal/check-fixed-anchoring.mjs @@ -34,8 +34,19 @@ * exactly where the old probe passed, which is the property that makes it worth having. */ 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 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 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}` diff --git a/internal/check-gospel-composed-filters.mjs b/internal/check-gospel-composed-filters.mjs index 1dd239964..6df377008 100644 --- a/internal/check-gospel-composed-filters.mjs +++ b/internal/check-gospel-composed-filters.mjs @@ -29,11 +29,20 @@ import { chromium } from 'playwright' import { serveReaped } from './_serve-reaped.mjs' import { resolve, dirname } from 'node:path' import { fileURLToPath } from 'node:url' +import { requireThisTree } from './_serves-this-tree.mjs' const HERE = dirname(fileURLToPath(import.meta.url)) const PUBLIC = resolve(HERE, '../public') const PORT = Number(process.env.PORT || 5399) 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' let srv = null diff --git a/internal/check-legend-info-localized.mjs b/internal/check-legend-info-localized.mjs index 544d09022..c86204f15 100644 --- a/internal/check-legend-info-localized.mjs +++ b/internal/check-legend-info-localized.mjs @@ -32,11 +32,21 @@ import { chromium } from 'playwright' import { readFileSync, existsSync } from 'node:fs' import { join, dirname } from 'node:path' 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 LOCALES = join(REPO, 'library/i18n/locales') 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_) { 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') diff --git a/internal/check-map-unmount-mid-init.mjs b/internal/check-map-unmount-mid-init.mjs index 1b01e5f03..9b1c2c748 100644 --- a/internal/check-map-unmount-mid-init.mjs +++ b/internal/check-map-unmount-mid-init.mjs @@ -24,9 +24,20 @@ * actually removed before release, the race was not staged and it exits 2, not 0. */ 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 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 '); process.exit(2) } // Production map plugins that go through useMapInstance, opened by their studio key. diff --git a/internal/check-mfe-two-tab.mjs b/internal/check-mfe-two-tab.mjs index d03a54841..2d4e467b1 100644 --- a/internal/check-mfe-two-tab.mjs +++ b/internal/check-mfe-two-tab.mjs @@ -13,8 +13,19 @@ // // Usage: node internal/check-mfe-two-tab.mjs [expectedTabCount] 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 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 [tabs]'); process.exit(2) } const WANT_TABS = Number(process.argv[3] || 2) diff --git a/internal/check-nav-reachable-mobile.mjs b/internal/check-nav-reachable-mobile.mjs index 9ca2a3a67..7753cacca 100644 --- a/internal/check-nav-reachable-mobile.mjs +++ b/internal/check-nav-reachable-mobile.mjs @@ -37,10 +37,18 @@ import { readFileSync, existsSync } from 'node:fs' import { resolve, dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { chromium } from 'playwright' +import { requireThisTree } from './_serves-this-tree.mjs' const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..') const MANIFEST = join(ROOT, 'public', 'doxa-maps', 'manifest.json') 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. const VIEWPORT = { width: Number(process.env.W || 414), height: Number(process.env.H || 896) } diff --git a/internal/check-poster-degrades-honestly.mjs b/internal/check-poster-degrades-honestly.mjs index 8ba1da8b1..0ff59870e 100644 --- a/internal/check-poster-degrades-honestly.mjs +++ b/internal/check-poster-degrades-honestly.mjs @@ -25,8 +25,19 @@ // // Usage: node internal/check-poster-degrades-honestly.mjs [zoneId] 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 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) { console.log('POSTER-DEGRADES: SKIP — no wall url given.') console.log(' Serve the TREE ROOT (public/), not public/, or assetsBase resolves') diff --git a/internal/check-poster-print-fallback.mjs b/internal/check-poster-print-fallback.mjs index 480b1f968..a9aaadb3a 100644 --- a/internal/check-poster-print-fallback.mjs +++ b/internal/check-poster-print-fallback.mjs @@ -24,12 +24,23 @@ // // Usage: node internal/check-poster-print-fallback.mjs [zoneId] 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 // that carries posters/.html (posterSources:true or bundlePosters:true). 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. 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) { 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') diff --git a/internal/check-poster-raster.mjs b/internal/check-poster-raster.mjs index f588d80cb..100ffce67 100644 --- a/internal/check-poster-raster.mjs +++ b/internal/check-poster-raster.mjs @@ -17,8 +17,19 @@ // Usage: node internal/check-poster-raster.mjs [zoneId] // PACKET_ORIGIN (default http://127.0.0.1:4898) 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 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 HTML = `${ORIGIN}/library/scripts/posters/out/posters/${ZONE}.html` diff --git a/internal/check-print-geometry.mjs b/internal/check-print-geometry.mjs index 7ce5df5c2..642b94c98 100644 --- a/internal/check-print-geometry.mjs +++ b/internal/check-print-geometry.mjs @@ -14,8 +14,19 @@ // Usage: node internal/check-print-geometry.mjs // PACKET_ORIGIN (default http://127.0.0.1:4898) — a static server over the repo root 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 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 ISO3 = process.env.PACKET_ISO3 || 'LAO' diff --git a/internal/check-scrim-covers-viewport.mjs b/internal/check-scrim-covers-viewport.mjs index 26eb59480..24865c1dc 100644 --- a/internal/check-scrim-covers-viewport.mjs +++ b/internal/check-scrim-covers-viewport.mjs @@ -44,8 +44,19 @@ * Exit: 0 all pass · 1 any fail · 2 dev server unreachable (a precondition, not a defect). */ 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 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 VW = 1280, VH = 900 diff --git a/internal/check-studio-every-plugin.mjs b/internal/check-studio-every-plugin.mjs index da2731cfe..319ce116d 100644 --- a/internal/check-studio-every-plugin.mjs +++ b/internal/check-studio-every-plugin.mjs @@ -24,9 +24,20 @@ * another worktree's tree — so this one refuses to guess. */ 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 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_) { console.error('check-studio-every-plugin: pass --url , e.g. --url http://localhost:5299/') process.exit(2) diff --git a/internal/verify-5-capabilities.mjs b/internal/verify-5-capabilities.mjs index d1394d5b5..72670f6d2 100644 --- a/internal/verify-5-capabilities.mjs +++ b/internal/verify-5-capabilities.mjs @@ -33,9 +33,20 @@ * Exits non-zero if any level fails, so it can gate a release. */ 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 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. const REPS=[ // ★ CORRECTED 2026-09-20 by the manifest reconciliation added below, on its FIRST RUN. diff --git a/internal/verify-map-paint.mjs b/internal/verify-map-paint.mjs index 7993171cc..f13a39ee4 100644 --- a/internal/verify-map-paint.mjs +++ b/internal/verify-map-paint.mjs @@ -30,6 +30,9 @@ * Exits non-zero if any leaf fails, so it can become a gate. */ 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. const GL_ARGS = [ @@ -41,6 +44,14 @@ const GL_ARGS = [ ] 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. // 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