Something in CI actually requires page 2

THE HALF I OWED. check-packet-render gained --expect-funnel last commit so a
packet with no funnel page can fail — but nothing passed the flag, and I said so
to regions-plugin while advising them not to reuse the pattern as though
declarable meant covered: "I have traded an invisible defect for a visible
obligation, which is better but not the same as fixed." This is the obligation.

check-packets-all now passes --expect-funnel for every packet it sweeps.

WHY IT CAN BE UNCONDITIONAL. Every packet in out/ is produced by
library/scripts/posters/packet.mjs, which always passes FUNNEL to buildPacket. So
a packet there without page 2 was either generated before the funnel existed or
by a caller that dropped the argument, and this sweep should say both out loud.
Verified across all 16 packets in out/ — the 4 fixtures, the Arabic tibet, and
all 11 laos locales, which I regenerated for this: 95 groups, 9 sheets each (was
8), 95 photos, page 2 present in every one. So the requirement matches a property
the pipeline actually holds rather than one it aspires to.

THE ESCAPE HATCH IS DELIBERATELY AWKWARD: PACKETS_ALL_NO_FUNNEL=1, which prints a
warning. A legitimate funnel-less host is a real state and deserves to be
recordable, but it must be a decision someone takes rather than a default that
quietly tolerates a missing page.

Verified: node --check clean; the arg construction exercised both ways (flag
present by default, absent under the env var). All 16 packets satisfy the sheet
arithmetic with 0 failures. Hindi laos re-checked as the longest-label locale —
5 rows, 5 bars, 0 Devanagari digits, longest label 51 chars so the wrap slack is
not even consumed.

NOT re-run end to end: check-packets-all spawns check-packet-render per packet,
which launches Chromium, and the Playwright policy reserves browsers to rega.
That is also how I learned this wrapper starts browsers — I ran it earlier
without realising and reported it.
This commit is contained in:
Doxa Maps 2026-09-26 06:59:13 +00:00
parent 1570b7e55e
commit 4e65147696

View file

@ -43,9 +43,32 @@ if (!files.length) {
}
const gate = join(HERE, 'check-packet-render.mjs')
// ★ THE FUNNEL PAGE IS REQUIRED HERE, and this line is the half of the fix that was missing.
// check-packet-render gained --expect-funnel after a merge deleted the call site supplying the funnel
// data and every gate stayed green (regions-plugin, 2026-09-26). But a DECLARABLE expectation that
// nothing declares is not a closed hole — it is an invisible defect traded for a visible obligation.
// I said as much to regions and then owed the second half.
//
// ⚠ WHY IT CAN BE UNCONDITIONAL HERE. Every packet in out/ is produced by
// library/scripts/posters/packet.mjs, which always passes FUNNEL to buildPacket. So a packet in this
// directory WITHOUT page 2 was either generated before the funnel existed or generated by a caller
// that dropped the argument — and both are things this sweep should say out loud. Verified
// 2026-09-26 across all 16 packets in out/ (4 fixtures, the ar tibet, and all 11 laos locales
// regenerated): every one has page 2, so this requires a property the pipeline actually holds rather
// than one it aspires to.
// ⚠ ESCAPE HATCH, deliberately awkward to reach: PACKETS_ALL_NO_FUNNEL=1. If a legitimate host ever
// generates funnel-less packets, that is a real state and this flag records it — but it must be a
// decision someone takes, not a default that quietly tolerates a missing page.
const EXPECT_FUNNEL = process.env.PACKETS_ALL_NO_FUNNEL !== '1'
if (!EXPECT_FUNNEL) {
console.log('PACKETS-ALL: ⚠ PACKETS_ALL_NO_FUNNEL=1 — page 2 is NOT required this run.')
}
const failed = []
for (const f of files) {
const res = spawnSync(process.execPath, [gate, join(DIR, f)], { encoding: 'utf8' })
const args = EXPECT_FUNNEL ? [gate, join(DIR, f), '--expect-funnel'] : [gate, join(DIR, f)]
const res = spawnSync(process.execPath, args, { encoding: 'utf8' })
const ok = res.status === 0
console.log(` ${ok ? '✓' : '✗'} ${f}`)
if (!ok) {