Restore a clean baseline before promoting the c647f61 prototype to
production paths (Wave 1) and building out Approach-B driver
scaffolding (Wave 2). All deletions trace back to falsifications
documented in 01-11-SUMMARY.md.
Deleted — broken Approach-A files:
- src/test-hooks/sw-hooks.ts
MV3 SW blocks dynamic import (Chromium es_modules.md;
w3c/webextensions#212). The gated `await import('../test-hooks/
sw-hooks')` from 01-11 Wave 1 never resolved → SW silently died →
production listeners never registered. File was dead-on-arrival;
no fix possible while MV3 SWs disallow dynamic import. Approach-B
replaces SW-side instrumentation with the extension-internal
harness page's chrome.action.* + chrome.notifications.* surface
(full privilege; no monkey-patching needed).
- tests/uat/lib/{launch,extension,sw,offscreen,assertions}.ts
Popup-bridge architecture (01-11 dbd977c) — falsification 2 +
falsification 3 in 01-11-SUMMARY: `sw.evaluate` exposes only
chrome.{loadTimes,csi}, NOT chrome.action.* / chrome.notifications.*
/ chrome.runtime.sendMessage; setPopup-juggling for extension-id
resolution turned out to be unnecessary (browser.extensions()
works directly per the prototype). These files will be reborn in
Wave 2 around the extension-page architecture.
Kept: tests/uat/lib/zip.ts (host-side JSZip work — architecture-
agnostic; A12+A13 still use it) and tests/uat/lib/test-hook-
contract.d.ts (type mirror — extended in Wave 3 but kept as-is here).
- tests/uat/prototype/probe_{offscreen,sw,tabs,tabs2}.mjs
Feasibility-research probes (01-11 spike) that empirically falsified
the Approach-A hypotheses. The findings are encoded in 01-11-
SUMMARY.md; the probes themselves are dead code.
- tests/uat/harness.test.ts
01-11 Wave 2 popup-bridge orchestrator (dbd977c). Imports the
now-deleted tests/uat/lib/{assertions,extension,sw,offscreen,launch}
modules — would not typecheck after this commit. Reborn in
Wave 3A as the Approach-B orchestrator (extension-internal page
driver + A0 grep gate + 13 assertion drivers).
Reverted — SW-side dynamic-import gate comment block:
- src/background/index.ts lines 13-29
The existing comment block (post-spike) described the SW-side
gated dynamic import that never landed. Rewritten to cite 01-13
Approach-B explicitly, link to 01-11-SUMMARY.md falsification,
and clarify that the Tier-1 grep gate's enduring value is
catching regressions in the offscreen chunk's __MOKOSH_UAT__
gate (the SW chunk is hook-free by construction).
Updated — Tier-1 grep gate FORBIDDEN_HOOK_STRINGS inventory:
- tests/background/no-test-hooks-in-prod-bundle.test.ts
Removed: `simulateUserStop` (Approach-A naming; replaced by
Approach-B `dispatchEndedOnTrack` which matches the W3C
dispatchEvent semantics per RESEARCH §7 BLOCKER — track.stop()
does NOT fire 'ended' per spec, so the simulation MUST use
dispatchEvent).
Added: `installFakeDisplayMedia`, `uninstallFakeDisplayMedia`,
`dispatchEndedOnTrack`, `__mokoshOffscreenQuery`.
Total inventory: 8 surface strings (was 5). Each MUST be absent
from every file under dist/ post-build.
Verification (all GREEN):
- `npm run build` — exit 0; dist/ populated.
- `grep -rln <forbidden> dist/` — 0 matches.
- `npm run build:test` — exit 0; dist-test/ populated; offscreen-hooks
chunk contains `installFakeDisplayMedia` (gate runs correctly
against the test build's distinct artifact).
- `npx tsc --noEmit` — exit 0 (root + tests/uat/tsconfig.json).
- `npx vitest run` — 92/92 tests passing (was 89; the +3 new tests
come from the FORBIDDEN_HOOK_STRINGS list expanding 5 → 8 — each
forbidden string is one parametric `it(...)` block).
Both prior-failing tests now GREEN:
- tests/background/sw-bundle-import.test.ts (was missing dist/ → 92/92
requires the test run to have a current dist/; vitest gate test
rebuilds via execFile when SKIP_BUILD≠1, otherwise relies on prior
`npm run build`).
- tests/background/no-test-hooks-in-prod-bundle.test.ts (was failing
on stale dist; now GREEN against the freshly-rebuilt clean bundle).
Wave 1 (next): promote tests/uat/prototype/{extension-page-harness.html,
extension-page-harness.ts,a6.test.ts} to tests/uat/ via `git mv`;
update vite.test.config.ts rollup input.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Task 1 of Plan 01-11 (Puppeteer UAT harness).
- npm install --save-dev puppeteer@^25.0.2 tsx@^4 @types/node
resolved: puppeteer@25.x, tsx@4.22.1, @types/node@25.8.0
pulls ~150MB Chromium binary at install time (T-1-11-03 — accepted,
package-lock pins resolved hashes via @puppeteer/browsers).
- package.json scripts: add build:test + test:uat (per RESEARCH §10
two-bundle orchestration); existing dev/build/preview/test untouched.
- vite.test.config.ts: extends ./vite.config.ts via mergeConfig with
mode:'test' + build.outDir:'dist-test' + emptyOutDir:true. Verified
npm run build:test produces dist-test/ in 7.93s; npm run build keeps
producing dist/ in 7.67s (no clobber).
- tsconfig.json `include: ["src"]` already covers src/test-hooks/**/*
via wildcard — no edit needed.
- tests/background/no-test-hooks-in-prod-bundle.test.ts: Tier-1 gate
mirroring sw-bundle-import.test.ts's execFile pattern. Greps the
BUILT dist/ tree for 5 forbidden hook surfaces (one `it` per surface
for granular failure isolation): __mokoshTest, simulateUserStop,
getSegmentCount, setCurrentStream, setSegmentCountGetter. All 5
surfaces absent today (RED-then-GREEN polarity inverted — the gate
is GREEN now and MUST stay GREEN after Task 2 lands the hooks).
SKIP_BUILD=1 escape hatch for developer iteration.
- .gitignore: add dist-test/ (no point versioning generated test bundle).
Verification:
- npx tsc --noEmit: exit 0
- npm run build: exit 0; dist/ populated (375.37 kB SW chunk)
- npm run build:test: exit 0; dist-test/ populated (identical chunk sizes —
the gated dynamic imports do not land until Task 2; this commit only
proves the two-bundle plumbing)
- SKIP_BUILD=1 npx vitest run tests/background/no-test-hooks-in-prod-bundle.test.ts:
6/6 GREEN (1 build-sanity + 5 forbidden-surface)
- SKIP_BUILD=1 npx vitest run (full suite): 89/89 GREEN
(83 baseline + 6 new Tier-1 surfaces = 89)
Working-tree cleanup: a stale 5.4 MB tests/fixtures/last_30sec.webm
(unrelated operator smoke regen present at session spawn) was stashed
before running the baseline — it caused the webm-playback test to time
out at 5s. After stashing back to HEAD's 1.9 MB fixture, baseline passes
cleanly. Not committing the fixture restoration here (pre-existing
working-tree state, not part of Task 1).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>