doxa-maps/internal/check-packets-all.mjs
doxa-maps-88655c70 96bd068bfc
Some checks are pending
build-gate / build (push) Waiting to run
packets: the all-packets gate says how many ZONES it covered
"PACKETS-ALL: PASS — every generated packet renders, in every locale present"
is true and reads like "every packet is fine". It counts FILES. Only the zones
someone generated are ever in that directory.

MEASURED 2026-09-24: 11 packets, all of them the SAME zone (laos) in 11
locales, against 28 poster zones in out/posters. The suite proved one zone's
layout eleven times and had never rendered the other 27 -- any of which can
carry a different data shape: fewer groups, a missing photo, a map that does
not resolve. The packet gate itself is strong; the claim about its reach was
not.

It now prints "zones covered : N of M" with the zone names, and names the
shortfall. Running it today reports 2 of 28.

NOT a failure, deliberately. Generating 28 zones x 11 locales means a network
fetch per zone and ~100MB of artefacts; checking only what exists is a real
trade. The problem was never the cap, it was that the cap was silent -- a
summary line that overclaims is how a green board stops meaning anything. The
PASS text now ends with what it does NOT cover, and points at packet:ci, which
builds a second zone from a committed fixture with no network.
2026-09-24 22:49:23 +00:00

91 lines
5 KiB
JavaScript

#!/usr/bin/env node
// check-packets-all — run check-packet-render over EVERY generated packet.
//
// ★ WHY THIS WRAPPER EXISTS. check-packet-render takes a path, and with no path it
// SKIPs at exit 0 — deliberately, so a build is not failed on a file that may not have
// been generated. The consequence, measured 2026-09-24: the gate was in package.json,
// all 11 locale packets passed it, and it was in NEITHER gates:pre NOR gates:post. It
// only ever ran when a human remembered to type a filename. A gate nobody invokes
// protects nothing — the same "present but unwired" state the two i18n gates were in.
//
// So this sweeps the directory and gates the WHOLE SET. That matters beyond wiring:
// checking one hand-named packet proves one locale. The packet ships in 11, and the
// failures that actually occur are locale-specific — a script font that does not load,
// an RTL document laid out LTR, a translated page header whose word order breaks a
// parser. Those are invisible if the gate is pointed at laos.html and nothing else.
//
// SKIP (exit 0) only when the directory is genuinely absent or empty: packets are
// generated on demand and a clean checkout has none. A skip says so out loud, with the
// count, so "0 packets checked" can never read as "all packets passed".
import { existsSync, readdirSync } from 'node:fs'
import { resolve, dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { spawnSync } from 'node:child_process'
const HERE = dirname(fileURLToPath(import.meta.url))
// Repo-relative, never an author's worktree: this gate lives in two repos and the
// packets are generated in the one that owns the poster scripts.
const REPO = process.env.DOXA_REPO || resolve(HERE, '..')
const DIR = process.env.PACKET_DIR
|| resolve(REPO, 'library/scripts/posters/out/packets')
if (!existsSync(DIR)) {
console.log(`PACKETS-ALL: SKIP — no packet directory at ${DIR}`)
console.log(' Packets are generated on demand (node library/scripts/posters/packet.mjs);')
console.log(' a clean checkout has none, so this is not a failure.')
process.exit(0)
}
const files = readdirSync(DIR).filter((f) => f.endsWith('.html')).sort()
if (!files.length) {
console.log(`PACKETS-ALL: SKIP — ${DIR} contains no .html packets`)
process.exit(0)
}
const gate = join(HERE, 'check-packet-render.mjs')
const failed = []
for (const f of files) {
const res = spawnSync(process.execPath, [gate, join(DIR, f)], { encoding: 'utf8' })
const ok = res.status === 0
console.log(` ${ok ? '✓' : '✗'} ${f}`)
if (!ok) {
failed.push(f)
// Print the failing gate's own reasons rather than a generic "it failed" —
// the detail is what makes a red build actionable.
const detail = `${res.stdout || ''}${res.stderr || ''}`
.split('\n').filter((l) => l.trim().startsWith('-') || l.includes('FAIL'))
for (const line of detail) console.log(` ${line.trim()}`)
}
}
// ★ SAY HOW MANY ZONES THIS ACTUALLY COVERED. "every generated packet renders" is true and reads
// like "every packet is fine" — but only the zones someone generated are ever here. MEASURED
// 2026-09-24: 11 packets, ALL of them the SAME zone (laos) in 11 locales, against 28 poster zones
// in out/posters. So the suite proved one zone's layout 11 times and had never rendered the other
// 27, any of which could carry a different data shape (fewer groups, a missing photo, an
// unresolvable map). A silent cap reads as full coverage; naming it is the difference between
// "verified" and "verified what happened to be lying around".
// NOT a failure — generating 28 zones x 11 locales means a network fetch per zone and ~100MB of
// artefacts, which is a deliberate trade, not an oversight. The gate's job here is to stop the
// PASS line from overclaiming.
const zoneOf = (f) => f.replace(/\.html$/, '').replace(/\.[a-z]{2}$/, '')
const zones = [...new Set(files.map(zoneOf))].sort()
let totalZones = null
try {
const postersDir = resolve(REPO, 'library/scripts/posters/out/posters')
if (existsSync(postersDir)) totalZones = readdirSync(postersDir).filter((f) => f.endsWith('.html')).length
} catch { /* the denominator is a nicety; its absence must not fail the gate */ }
console.log(`\nPACKETS-ALL: ${files.length} packet(s) checked, ${files.length - failed.length} passed`)
console.log(` zones covered : ${zones.length}${totalZones ? ` of ${totalZones}` : ''} — ${zones.join(', ')}`)
if (totalZones && zones.length < totalZones) {
console.log(` ⚠ ${totalZones - zones.length} zone(s) have NO packet here and were not rendered by`)
console.log(' anything. Generate another with: bun run packet:ci (one zone, committed fixture,')
console.log(' no network), or ONLY=<zone> node library/scripts/posters/packet.mjs.')
}
if (failed.length) {
console.error(`PACKETS-ALL: FAIL — ${failed.length} packet(s): ${failed.join(', ')}`)
process.exit(1)
}
console.log(`PACKETS-ALL: PASS — every generated packet renders, across ${zones.length} zone(s) `
+ 'and every locale present. This does NOT cover zones no one generated.')