The packet's pages take the spec's order: triangle second, wheel before points

Diffing the full packet against its card found every PAGE present after
tonight's supplier work -- and two of them in the wrong ORDER. The card
puts the inverted triangle at page 2, in front of the life calendar, so
the packet opens with the argument (twelve thousand narrowing to THIS
list) before the meditations; and it closes wheel-then-points, so the
last thing in a reader's hands is what to pray rather than how long.

The plan card flagged this reorder and would not apply it silently,
because the file says the order is the product spec: both changes are the
spec's own, confirmed through the shepherd, and the two stale order
comments update in this same commit as that card required. The file
header now also says which copy of the comment is authoritative, since
this is the second time it has gone stale.

The variant filter is keyed, never indexed -- the reorder moved lines
and could not move meanings, which is exactly the case that comment was
written for. Verified in-process on both variants (full: map, funnel,
life, christian, profiles, sets, wheel, points; lightweight: map,
funnel, profiles, wheel, points) and on the regenerated 28-zone output;
the headless packets-all reports 28 of 28 with maps, groups and sets,
and every packet gate stays green. Sheet 0 is still the map page, which
is the one positional assertion any gate makes.
This commit is contained in:
Doxa Maps 2026-09-28 22:41:46 +00:00
parent 8b8e9fee9c
commit 3408088647

View file

@ -11,11 +11,13 @@
// strings, language, the zone, its groups, photos, and the map SVG. That is what
// lets the same code run under Node and in a browser tab.
//
// PAGE ORDER IS THE PRODUCT SPEC, do not reorder:
// PAGE ORDER IS THE PRODUCT SPEC — change it only when the spec does, and update THIS comment in
// the same commit (it has gone stale twice; buildPacket's own comment is the authoritative copy):
// 1 the map one-pager
// 2..n the people groups, 20 per page, with photos
// n+1 the 12 prayer points
// n+2 the prayer wheel
// 2 the inverted triangle (funnel)
// 3 the life calendar 4 the %-evangelical grid (full detail only)
// 5..n the people groups, 20 per page, with photos
// then the bounded/centered sets (full only), the prayer WHEEL, the 12 prayer POINTS
//
// I18N: every human-readable string comes from packet-strings.json. A new language
// is a NEW BLOCK there, never a code change, and fallback is PER KEY so a
@ -1005,15 +1007,18 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null, de
// is already at the edge of readable. A ninth belongs in an options object; flagged here so the
// next person adding a page makes that change rather than extending the line again.
function buildPacket(zone, groups, photos, mapSvg, funnel = null, christian = null, variant = 'full', sets = null) {
// ★ PAGE ORDER IS THE DRIVER'S, 2026-09-27, and it is an argument rather than a layout:
// ★ PAGE ORDER IS THE PRODUCT SPEC (A1, superseding the 2026-09-27 order this comment used to
// record — the reorder is the spec's own deliberate change, confirmed via the shepherd, and the
// stale "do not reorder" note updates in the SAME commit that reorders, as the plan card required):
// 1 map — where this zone is
// 2 life calendar — 100 years x 52 weeks, a whole human life on one page
// 3 the SAME grid — shaded by the evangelical share of these groups' POPULATION
// 4 funnel — 12,379 -> 7,341 -> 4,754 -> 2,107 -> this list, 1 of N
// 2 funnel — the inverted triangle: 12,379 narrowing to THIS list, the argument first
// 3 life calendar — 100 years x 52 weeks, a whole human life on one page
// 4 the SAME grid — shaded by the evangelical share of these groups' POPULATION
// 5..n people groups with photos and the three prayer columns
// then the 12 prayer points and the prayer wheel
// Pages 2 and 3 are deliberately adjacent: the reader learns to read 5,200 boxes as their own
// life, and then sees the same 5,200 boxes answer "how many of these people know Christ".
// then the bounded/centered sets (full only), the prayer WHEEL, and the 12 prayer POINTS —
// wheel before points, so the packet closes on what to pray rather than how long.
// Pages 3 and 4 stay adjacent: the reader learns to read 5,200 boxes as their own life, then
// sees the same 5,200 boxes answer "how many of these people know Christ".
// ⚠ KEYED, NOT INDEXED. The omit-set names pages; it never carries positions. An index-based
// filter reads identically today and silently drops the WRONG page the first time this order
// changes — and the order above is the Driver's, so it is expected to change again.
@ -1023,15 +1028,15 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null, de
const keep = (key) => !(omit && omit.has(key));
const pages = [
keep('map') && mapPage(zone, groups, mapSvg),
keep('funnel') && funnelPage(zone, groups, funnel),
keep('life') && lifePage(zone),
keep('christian') && christianPage(zone, christian),
keep('funnel') && funnelPage(zone, groups, funnel),
// NOT behind keep() — see the VARIANTS comment: dropping list pages drops people.
...listPages(zone, groups, photos),
// BACK MATTER: after the profiles, before the wheel (brief A1). Full-detail only.
// BACK MATTER: after the profiles (brief A1). Full-detail only.
keep('sets') && setsPage(zone, sets),
keep('points') && pointsPage(),
keep('wheel') && wheelPage(),
keep('points') && pointsPage(),
].filter(Boolean);
// ⚠ dir MUST be set for right-to-left languages or the packet renders Arabic
// left-aligned — readable glyphs in the wrong place, which looks like a