Comments in library/ and internal/ that quoted a person, attributed a decision to one, used first person,
named fleet agents or carried private host names now state the same technical fact in neutral words:
poster-render (including the comments it writes into generated posters), packet-render, the poster and
research scripts, PosterWall, DataTable, the legends, the layouts and the gates. The network-policy note
states the policy itself. Behaviour is unchanged: a few printed gate messages and reason labels drop an
agent name, the poster-render integrity pin follows its comment-only edit, and series.json changes only in
its _meta and _why notes. The historical poster design snapshots (library/scripts/posters/snapshots/),
which nothing reads, are removed.
Only the browser seat runs browsers, and only inside internal/browser-slot.sh.
That rule was remembered, not enforced: an agent ran a gate it took for a
headless source check and it launched Chromium outside the slot.
internal/lib/playwright-guarded.mjs is now the one way a repo file reaches
playwright: its launch(), launchPersistentContext(), launchServer(), connect()
and connectOverCDP() exit 75 (NOT MEASURED) with a message naming
browser-slot.sh unless DOXA_BROWSER_SLOT is set, and browser-slot.sh exports it
for the command it runs, so a bash -c grandchild inherits it. All 72 files that
imported playwright switch to it (internal/lib/browser.mjs and 64 internal gates;
plugin-designs scripts: doxa-research-map 3, my-upg-100-list 2,
research-map-plus-grid 2, research-dashboard 1): a mechanical import swap.
check:browser-gates-guarded (gates:pre) fails a direct import;
bun run browser-gates lists the 97 scripts that launch a browser. isBrowserGate
moves to internal/lib/browser-gates.mjs so the runner and the check share it.
Last tick I fixed the one executable literal the tree rename broke, and
wrote that the remaining mentions "will mislead the next reader but
break nothing." That second half was wrong, and worth correcting rather
than leaving.
Six of them are RUNNABLE COMMANDS — usage lines, a --leaf example, two
PROBE_PATH invocations, a BASE= export. Copy-pasting one aims a probe at
a folder that no longer exists, and the failure is silent: a 404 loads
as an empty document and every gate then reports whatever "nothing"
looks like in its own vocabulary. That is exactly how I produced three
confident fake findings in a single sitting last tick — a frame probe
reporting "0 images, no wall" on two different leaves, and a basemap
gate reporting "map never finished its style". A comment that names a
path a reader will then USE is not inert documentation.
So the six say <TREE_NAME> now, which is what the code reads and what
_tree-name.mjs exists to make authoritative.
WHAT IS DELIBERATELY LEFT ALONE, because rewriting it would falsify the
record: 19 mentions are historical narrative — "public/doxa-maps was…",
the census that motivated _tree-name.mjs, and check-catalog-identity's
citation of https://nuxtbase.app/app/doxa-maps/manifest.json returning a
200 sign-in page. That URL is EVIDENCE of a past false-200, not an
instruction; its code already reads TREE_NAME.
Live literals across internal/ are now zero, except public-hygiene's
doxa-life/doxa-maps, which is the private REPO name and correctly
unrelated to the tree.
The output tree was renamed doxa-maps → dx-maps. The name has always
been a config knob, and _tree-name.mjs exists precisely so a rename is
one line — but three gates still built their URLs from the literal, so
they fetched a folder that no longer exists.
THE FAILURE MODE IS WHY THIS MATTERS MORE THAN A PATH FIX. A gate
pointed at a missing tree does not error; it loads a 404, finds an empty
document, and reports whatever "nothing" looks like in its own terms.
Measured in one sitting, all three of these were artifacts of the rename
rather than findings about the product:
a frame probe returned 0 images and no wall, twice, on two different
leaves — which I first read as "the composite mounts the wall in a
second pane";
check-basemap-labels-localized returned NOT MEASURED, "map never
finished its style";
and every leaf under my plugin answered 404 while the card-fits gate
had been passing, because IT was already migrated and my probes were
not.
Only the refuse-to-judge guards kept those from becoming filed defects.
WHAT WAS ACTUALLY LIVE, after separating comments from code: exactly ONE
executable literal across the 27 files that still mention the old name —
the --leaf default in check-gospel-rtl-shaping, which I added last tick
when parameterising that gate for the other raw-map owners. The rest are
prose, plus one in public-hygiene-check that is the private REPO name
(doxa-life/doxa-maps) and correctly unrelated. So the fleet-wide
migration was essentially complete and this closes it.
check-leaf-english-leaks now imports TREE_NAME for both its reachability
probe and its leaf URLs; check-poster-card-fits was already migrated in
code and only its comment still described the old path.
The bridge candidate — the "possibly a way in" offered to a group with nothing —
was chosen from Doxa's own pins: the biggest language among the UNREACHED groups
in that country that has Scripture and the film. That is not the language a
community shares with its neighbours. For Syenara Senufo in Mali it proposed
Minianka, one people group. Mali's vehicular language is Bambara.
The number beside it was worse than the pick. "8.8% of this country's mapped
population" is a share of Doxa's unreached pins, and a reader takes a percentage
for a share of the country. A percentage measured against a denominator nobody
can see is not a caveat, it is a wrong number.
CLDR publishes what each territory speaks and by what share, joined to ISO 639-3
through SIL's own Part1 column, and pinned rather than tracked from a moving
branch. 1,161 of 1,175 candidates now come from it; the remaining 14 keep the old
proxy and say on the row that their count is of this map's groups and not of the
country. Mali now reads French at 46% and official.
Where two languages are within five points the map names BOTH and says it will
not choose. Mali is exactly that: French 46% and official, Bambara 46% and not —
one is the administrative language and the other is what people share in a
market, and which bridges better depends on whether you are handing over a
booklet or starting a conversation. A tie-break would have quietly answered a
question nobody asked it. Both carry their own links, for the same reason the
first one does.
Two field lists were a field short, the same shape twice. The candidate filter
and the link resolver both read c.s for "has a readable Scripture" and forgot
that Faith Comes By Hearing carries text on the audio record — which excluded
Bambara from Mali's candidates entirely, and then, once it was named, offered it
the film while a full 66-book text sat one field away. There is now one
predicate.
The RTL gate read a hardcoded tree path. It reads the build config instead, and
was re-run against its baseline before the result was trusted.
upg-100-list builds its map RAW (`new gl.Map`) rather than through
useMapInstance, so it inherits none of the bundle entry's side effects —
including the RTL text plugin. It appeared to work only because the leaf
head PRELOADED the Mapbox peer, which let an entry-time registration
land in time. studio is removing that preload.
⚠ IT IS NOT A UI-LANGUAGE FEATURE, which is why it matters more than it
looks. A basemap draws each place in its OWN script, so over the Middle
East, Iran and Israel MOST labels are Arabic, Persian or Hebrew for
EVERY viewer in EVERY UI language. Unshaped they render reversed — a
WRONG NAME for exactly the groups this map is about — and it fails
silently: no error, no warning, just mirrored text that reads as a font
problem to anyone who does not know the script.
MEASURED with gospel's gate, which PANS to Arabia before judging because
the shaper registers lazily and reads 'deferred' at a world view:
before mapbox ok 58/61 RTL labels shaped
maplibre FAIL 62 RTL labels on screen, shaper 'requested'
after mapbox ok 58/61
maplibre ok 63/63 shaped
★ THE MAPBOX ARM PASSING BEFOREHAND IS THE FINDING. It is the preload
rescuing an entry-time call, so mapbox looks fine today and breaks the
moment that preload goes. MAPLIBRE ALREADY FAILED, with no preload to
rescue it — this was live for every keyless viewer, not only a future
regression. Measuring just the mapbox arm would have read "already
fine".
The install goes after the engine global resolves and before
new gl.Map: with the engine injected lazily, an index.js call runs
before `gl` exists and does nothing at all.
THE GATE IS PARAMETERISED, NOT FORKED. dx-shepherd routed it to the
other raw-map owners (cities-internet, key-cities, RegionCountryMap), so
it takes --leaf instead of hardcoding gospel's. Copying it would have
given each owner a drifting copy of the pan-first logic and the poison
arm — the two parts that needed corrections to get right.
Also carries the leak gate's third correction: the survivors of the
data and facet exclusions were in .rd-lt inside .rd-li and .rd-bl inside
.rd-bar — DashboardChartsRail renders `{{ s.key }}` beside `{{ s.value }}`
over chart.geometry, the same shape as a facet row. Chasing one class
name at a time is how that went wrong three times, so the rule is now
general: an element whose own text sits beside a sibling rendering a
NUMBER is enumerating data, not naming the UI. Section headings and
column titles have no numeric sibling and stay in scope.
The map is built raw, for the provider switch, so it never installed the RTL
text plugin — the same opt-out that cost it the engine stylesheet. Without the
plugin those labels draw as disconnected glyphs in the wrong order, which is
unreadable rather than merely ugly.
This was never an Arabic-locale bug, which is why it went unseen. The leaf does
not localise basemap labels, so every place is drawn in its own script: over
Arabia, 57 of 61 rendered symbols are Arabic for every viewer whatever their UI
language. An English reader sees broken Arabic they cannot evaluate.
It installs after the engine global resolves rather than at bundle entry. This
bundle injects its engine lazily, so at entry time there is no engine to install
into and the call would silently do nothing.
The gate pans to Arabia before judging. Registration alone proves little, since
the plugin is registered lazily and a freshly loaded map reports "deferred"
whether or not the shaper can actually be fetched; only real RTL text on screen
turns it "loaded". Asserting without panning would have failed a working map.