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.
check:no-silent-engine is in gates:post as of main 23976fb0 and scans every plugin for
a cross-engine fallback, so this leaf's own static arm is deleted. Two gates owning one
source-level rule meant my leaf was checked twice while every other leaf was checked
once, and the narrower copy is always the one that drifts.
What stays is the part no source read can do: two providers across engine present,
engine blocked and both blocked, with the CDN blocked by request routing the way a proxy
or an offline kiosk does it, and the engine identified from the canvas class rather than
a debug handle. All six still pass after the deletion.
--poison now NAMES where the falsifiable arm went instead of exiting 0 as though it had
self-tested — and it names it correctly: the tree-wide gate's flag is --self-test, not
--poison, which I checked in its source rather than assuming the convention my own gates
use. Its package.json description no longer claims a static arm this file does not have.
resources-map resolved its engine as `engineGlobal(provider) || window.mapboxgl`.
engineGlobal already defaults to mapbox, so that fallback could only ever fire for
provider 'maplibre' — and then it returned MAPBOX. A page that chose the keyless
engine silently got the one that needs a token, and because the profile only
assigns accessToken when the provider is not maplibre, the substitute had no token
either: it would have 401'd on every tile. The fix is the deletion. The requested
engine or a named failure, with a console warning for whoever is debugging and the
reader's line through messages.* (English kept inline until the key lands).
check:engine-contract measures it: two providers across engine present, engine
blocked and both blocked, with the CDN blocked by request routing the way a proxy
or an offline kiosk does it. Three of those six arms first failed for reasons that
were mine, not the product's, and each is written down in the gate: Mapbox cannot
mount at all on a static tree without a token, 11s was not long enough for a leaf
that fetches 4 MB before the map exists, and engine attribution read from a debug
handle scored Mapbox-with-a-bad-token as "engine null" — the canvas class cannot
lie about who drew it.
Also in this landing: the pin caveat is translated in 11 locales from the shared
pins.* area, read through this leaf's own guarded t() rather than by mounting
library ApproxPinNote.vue — that component calls useI18n() unguarded, and this
bundle is embeddable in hosts that never called app.use(i18n), where an unguarded
call throws during setup and the shadow boundary swallows it. Same wording either
way. Both "Show all groups" buttons now use the key that already exists in 11
locales, and the engine's own control labels get the provider arm.