# The browser became a test surface, and the version bound is the foot-gun _2026-09-22 · booth_ U3 moved load-bearing logic out of Python and into JavaScript: which fragment lands at which anchor, what gets appended, and whether a `
` scattered down a report still owns the controls pointing at it. **The Python suite is blind to every one of those.** Shipping U3 with only payload-shape tests would have deleted ~10 real tests and replaced them with assertions that cannot see the thing the operator actually depends on. So `tests/test_embed_browser.py` drives a real Chromium against a real uvicorn on an ephemeral port. 12 tests. It found nothing on the first run — but the probe that preceded it settled a design question no amount of spec-reading would have. ## The probe, and why it had controls **Question:** if a control carrying `form="F"` is inserted into the DOM *before* `` exists, does it become that form's control? The HTML spec resets form owner on insertion and on the `form` attribute changing — it does NOT list "a matching form was inserted later". The U3 design inserts fragments in visual order, so this happens routinely. Four conditions, N=3 each, in Chromium 151 headless: | condition | `input.form?.id` | |---|---| | A — form inserted first (**positive control**) | `F, F, F` | | B — control inserted first (**the question**) | `F, F, F` | | C — `form="NOPE"`, no such form (**negative control**) | `null, null, null` | | D — remove and re-set the attribute (the proposed fix) | `F, F, F` | The positive control proves the instrument can see association at all; the negative proves it is not manufacturing it. Without both, B's answer means nothing — that is the whole lesson of [[2026-09-22-vacuous-falsifiers]] applied before the code instead of after. **The answer is: Chromium re-resolves it, so the fix is unnecessary there.** The fix shipped anyway. **Sensitivity floor: ONE ENGINE.** The operator's own browser was not measured, the failure mode is a form that looks filled in and POSTs a 400, and the guard is three lines. The measurement says "not needed here"; it does not say "not needed". ## The foot-gun, which bit before the tests were written Browsers are **box-wide** in `/opt/ms-playwright` with `PLAYWRIGHT_BROWSERS_PATH` wired globally — there is no per-project `playwright install`. Each playwright release pins **one** Chromium revision, and a release wanting a revision the shared store lacks dies with: Executable doesn't exist at /opt/ms-playwright/chromium_headless_shell-1243/… That is not a missing-dependency error and it does not name the real problem. The store had 1223 / 1228 / 1234; `playwright` 1.63 wanted 1243. The mapping: 1.60 -> 1223 1.61 -> 1228 1.62 -> 1234 1.63 -> 1243 Hence `playwright>=1.60,<1.63` in `pyproject.toml`, **with the upper bound as the point** and the reason in a comment beside it. A bare `playwright` would break the suite on the next resolve, opaquely. ## The hermeticity trade, and how it is paid A browser layer makes the suite non-hermetic — it can go red for an environment reason. `tests/test_embed_browser.py` therefore **skips, never fails**, when playwright or a usable browser is missing (`pytest.importorskip`, plus a `pytest.skip` on any launch failure). `pytest -q` stays green anywhere; the browser layer is purely additive. ⚠ **The failure mode of that choice: if those 12 tests start SKIPPING on this box, U3's placement logic is untested and the suite still says green.** If the count drops from 431, check the skip reason before anything else — the pinned bound has probably drifted past the shared store. Related: [[2026-09-22-u3-declared-embed-seam-landed]].