check-experimental-shelf imported resolve(ROOT, 'node_modules/playwright/index.mjs')
dynamically, named no package specifier, and so launched Chromium outside the
slot while check:browser-gates-guarded passed it (upg100 found and measured it).
It now imports the guard, and an unslotted run exits 75. The check also fails a
path to node_modules/playwright (or playwright-core) anywhere in code; with the
old import restored it fails that file.
The runner recognises a browser gate from its file, comments included, so the
check's own comment made it one and it went NOT MEASURED on a headless seat.
The comment is reworded; detection is unchanged (stripping comments instead
dropped four real browser gates).
Excluding the two detector files by path also skipped any real import added to
them. The check now matches only a static import statement at the start of a
line or a literal import('playwright') / require('playwright') call, which the
detectors' escaped regex literals never are; only the guard itself is excluded.
Planted a real import in browser-gates.mjs and one in this check: both fail.
internal/lib/browser-gates.mjs holds the regex that looks for a playwright
import, so the check read it as an import once the file was tracked. The guard
and the two detectors are excluded by path, so a real import added to one of
them still fails.
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.