The freshness gate named exactly five: country-posters, my-upg-100-list,
poster-design, poster-sections, regions-dashboard (they compile PosterWall
and/or the country poster type). Rebuilt the five, regenerated the tree and
SRI. Only these five bundle .js change; the doxa-maps-spa leaf updates its
embedded integrity hash.
Renamed from F to avoid colliding with the pilot's show-header arm F. A phone +
a non-withheld desktop-only large sheet via countryPosterType rejects
poster.phoneLimitAll (records) and reads it (unsupported); poison-proven by
neutralising phoneBlocked.
countryPosterType mirrors the Country Posters wall's phone rule on top of the
India tab's withheld API: phoneBlocked = isPhonePrint() && largeSheet(c)?.desktopOnly
(largeSheet is null while a country is withheld, so this bites only a non-withheld
large sheet — India in DEV preview, or any future one). records() reject
poster.phoneLimitAll and unsupported() reads it, after the permanent reasons
(withheld, an unsupported non-large sheet) so a device reason never outranks a
permanent one. So the delegating regions list and any dxm-poster-section embed
cannot print India's 60x96 on a phone.
Takes the pilot's side for both conflicted files (countryPosterType.js = the
India tab's withheld API; check-poster-section.mjs = the pilot's) so no combined
resolution is hidden in the merge. The sort tie-break (PosterWall.vue) and its
gate arm (check-poster-wall-host-seams) auto-merge unchanged. The phone-limit
and the renamed section-gate arm follow as separate commits on top.
Re-adds the fork-leaders catalogue entries after merging the pilot
(the merge took the pilot's package.json; this restores the new gate's
registration in a separate, reviewable commit).
Closed, the folder sat mid-drawer under the one short Posters section with
empty space below, so it read as a caption with nothing under it and was easy
to miss on a phone. Open, its plugins show like any section's rows; a reader
can still collapse it. check:posterverse-shelf asserts the open default, and
its self-test plants a closed folder.
The samples arm is now a function the self-test can poison: with withholding
switched off, India (no sheet tier, no outlines) must fail as a sample that
cannot be drawn. Closes the branch the arm had no poison for.
India, the one large-sheet country, now prints at 5 x 8 ft only, so the
5.5 x 5.5 ft and 3 x 5 ft side-lane cards would have drawn India's 60x96 sheet
under their own label. They now sample the largest drawable countries (China
at 66x66, Sudan at 36x60) through the same shared sheet path, and their
details say that no country prints at this size today
(posterDesign.missing.noCountryAtSize, 11 locales). The 60x96 card keeps
India and stays withheld. check:poster-design-catalogue now checks every
sample: drawable, or withheld by countrySheet.js.
A host that serves the tree with Last-Modified and no Cache-Control lets a browser run its cached files for
hours. Measured: a typed-URL revisit after a deploy requested none of the gallery, the manifest or the bundles,
so a returning reader ran the old files, or an old manifest against a new bundle.
- The manifest is fetched with cache 'no-cache', so it is always revalidated (a 304 when unchanged).
- A fingerprint of the manifest (every bundle's integrity) is kept per tree. When it differs from the reader's
last visit, every bundle the browser already holds gets one conditional request before any tab mounts:
a 304 refreshes it, and a 200 is cancelled at its headers, which drops the stale copy. The plain <script>
that follows, the gallery's own or a composite's for its children, then runs the new file at the same URL.
- A version query is not used: loadScriptOnce keys its registry by the full href, so X.js?v= next to a
composite's plain X.js would run the bundle twice.
- A first visit with an empty cache costs nothing extra (only-if-cached finds nothing held), and so does an
ordinary visit with an unchanged manifest. The mount waits at most 8 s for the check.
PosterWall orders items by descending count with a stable, fixed-locale (en-US)
name tie-break for equal counts — BUT only when both items carry a count, so a
count-less wall (the Poster Design template gallery) keeps its authored order
(the sort is stable). Every host with counts (the Country Posters wall and every
dxm-poster-section: DX Life /regions, the Regions dashboard, Poster Sections)
shows the densest prayer need first, in an order that never depends on the
reader's browser.
countryPosterType mirrors the Country Posters wall's phone rule: on a phone a
desktop-only large sheet (India's 60x96) is blocked — records reject
poster.phoneLimitAll and the card reads the same message — so the delegating
regions list and any poster-section embed cannot print it on a phone.
Gates (poison-proven): check-poster-wall-host-seams arm M — a counted tie fixture
(mis-sorts if the tie-break is removed) AND a count-less gallery fixture
(alphabetises if the tie-break is unconditional); check-poster-section arm F — a
phone + a desktop-only large sheet via the type is blocked.
A preset page loads only poster-sections.js, so a preset of a poster type
registered by another plugin's script (upg100-list) could only say No
posters. The generator now gives no presets to a type whose file is not on
the tree, and check:poster-sections fails on any such preset: 9 presets
remain (7 regions, all regions, configure).
The tree generator writes a page per preset but never deletes one, so the
dropped presets' pages (the 10 upg100 ones and countries-other) are removed,
and a new arm holds the built preset pages to exactly the presets.