Commit Graph

6 Commits

Author SHA1 Message Date
74400ae6ac test(debug-01-08): complete SW-bundle-import gate — mock chrome.* surface
The Tier-1 SW-bundle-loadability gate (c75854c) stripped
Buffer/process/window/document from the spawned Node isolate
but did not mock chrome.*. A correctly-bundled SW that reaches
addListener calls at module init would (correctly) progress to
chrome.runtime.onMessage.addListener(...) and throw
ReferenceError because chrome was undefined — a false-positive
RED.

This commit adds a minimal Proxy-based chrome.* stub that
no-ops any chrome.<api>.<method>(...) chain. The gate now
verifies what its file-header comment claims: "bundled artifact
reaches module-init completion under SW-simulated globals."

RED->GREEN: the gate now correctly passes against the post-fix
bundle and would catch any future regression in SW
bundle-loadability.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 11:16:05 +02:00
c75854cbef test(debug-01-08): RED Tier-1 SW-bundle-loadability gate + corrected hypothesis
Adds tests/background/sw-bundle-import.test.ts that loads the built SW
chunk under SW-simulated globals (Buffer/process/window/document stripped)
via a spawned Node child process. Pins the orchestrator-side gap that
caused Plan 01-08's SW init crash: the prior deps test only checked
SOURCE packages under default Node globals, never the bundled output, so
Vite/Rollup's CJS-interop bug (tree-shaking the `ebml` package while
leaving a dangling `{tools:f}=Pc` destructure against an empty Pc) went
undetected until operator empirical smoke.

RED against HEAD aabbd0c — failure surfaces the exact production error
("Cannot read properties of undefined (reading 'readVint')"), proving
the test is a true regression gate, not a tautology.

Also rewrites .planning/debug/01-08-sw-incompatibility.md to reflect the
actual root cause (Vite/Rollup CJS interop) rather than the orchestrator's
initial falsified hypothesis (new Function + Buffer globals — disproven
by Node simulation showing the throw fires at module-init line 12:33809
before any CSP-eval or Buffer-ref code path executes).

Full vitest: 60 passing + 3 RED (this gate + the 2 pre-existing Task 5
fixture-dependent duration tests). No regressions.

Per feedback-pre-checkpoint-bundle-gates.md (auto-loaded memory): any
future plan executor whose work surfaces a SW must run this test before
any operator-empirical checkpoint.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 09:52:45 +02:00
407e683e9b test(01-08): RED unit tests for remuxSegments — single-EBML + monotonic + frame-count + size + empty
- 5 RED tests pinning the contract for src/background/webm-remux.ts
  (created in Task 3). All fail with "module missing" today — the
  Task 3 GREEN gate.
- Test 1: exactly 1 EBML header + 1 Segment magic in output.
- Test 2: output size within [0.7x, 1.3x] of input sum.
- Test 3: ffprobe format=duration >= 25_000 ms (skip-if-no-ffprobe).
- Test 4: ffprobe -count_frames in [905, 912] (per-seg sum 912 ± 3 boundary
  partial-frame drops, I-01 tightening).
- Test 5: empty input -> empty Blob (defense-in-depth).
- Fixture sliced at d13-confirmed byte offsets (0 / 509038 / 970967);
  verified against committed last_30sec.webm at Task 2 land time.
- Baseline counts: 13 files / 62 tests / 7 failed (2 webm-playback +
  5 new webm-remux) | 55 passed. tsc exit 0.
2026-05-17 09:23:53 +02:00
503531485c feat(01-08): install ts-ebml + webm-muxer; pin SW-compat via deps test
- Add ts-ebml ^3.0.2 (parse half) and webm-muxer ^5.1.4 (write half) per
  CONTEXT.md amendment D-14-remux; both MIT, both verified SW-compatible
  in the d13 debug-session library survey.
- tests/background/webm-remux-deps.test.ts pins two contracts:
  (a) named exports surface (Muxer + ArrayBufferTarget + Decoder).
  (b) both libraries import cleanly when window/document are absent on
      globalThis — guards the published dist against accidentally
      acquiring DOM globals on the hot path that would crash the
      Chrome service-worker runtime.
- Note: webm-muxer 5.1.4 upstream-deprecated in favor of Mediabunny; the
  pinned version still meets the d13 architectural requirement
  (single-EBML output via addVideoChunkRaw). Migration to Mediabunny is
  out of scope for Plan 01-08 and would require a new ADR.
- Baseline 53 GREEN + 2 new GREEN; tsc clean; 2 webm-playback duration
  RED still pending (drive to GREEN in Tasks 3-5).
2026-05-17 09:22:46 +02:00
246eadb2ef test(option-c): continuous 600 s port lifecycle pinning contract
Implements Option C step 3 per .planning/debug/empty-archive-port-race.md:

  "Continuous end-to-end vitest covering 600 s of port lifecycle
   (2 reconnects + simulated REQUEST_BUFFER round-trips). Becomes the
   new pinning contract for the port lifecycle."

The UAT Test 3 BLOCKER surfaced because no test exercised the full
operator timeline — 5+ minute recording with port-replacement windows
crossing real SAVE_ARCHIVE round-trips. This file pins that contract
end-to-end at the unit-test level.

What's exercised:
  - Both SW (src/background/index.ts) and offscreen recorder
    (src/offscreen/recorder.ts) loaded into the SAME chrome stub, with
    paired port-pair factory (one connect() yields offPort + swPort
    that talk to each other through captured listeners).
  - 12 ping/pong cycles (~300 s simulated wall-clock).
  - 3 SAVE_ARCHIVE round-trips (one before reconnect, two after each
    of the two forced reconnects).
  - 2 EXTERNAL port disconnects (port._disconnected=true) — simulates
    the SW eviction / port glitch path that the H1.b test pins.
  - JSZip mocked at file scope (vi.mock) because Node 22+ JSZip can't
    read native Blobs — preserves integration shape (size accounting)
    without depending on JSZip's Node compatibility.

Final assertions:
  1. All 3 saveArchive calls return success:true.
  2. EVERY BUFFER message that crossed the wire carried segments (no
     silent-loss path was reachable).
  3. PONGs round-tripped (proves health-probe loop closes).

Suite: 53 GREEN / 53 tests. tsc --noEmit exit 0; type-safety grep clean;
npm run build exit 0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 14:53:47 +02:00
4306d59dfd test(option-c): RED gate for request-id'd port protocol + health probe + error surface
Per .planning/debug/empty-archive-port-race.md "Fix Strategy: Option C
(Architectural)", land RED tests that pin the 4 sub-behaviours the
refactor must satisfy at the unit level. These complement the operator-
facing contract already pinned by port-reconnect-race.test.ts (H1+H2).

Offscreen side (tests/offscreen/port-health-probe.test.ts):
  A. Bootstrap installs no 290_000 ms pre-emptive reconnect timer
     (the timing-based race window from b064a21 is gone).
  B. Missed PONGs (5 PINGs without echo) trigger a clean reconnect via
     the same path the onDisconnect handler uses.
  C. PONG echoes within timeout keep the port alive indefinitely
     (counter-test for over-eager probe — already GREEN today).
  D. REQUEST_BUFFER with requestId → BUFFER response echoes the same id
     (the architectural mechanism that retires cross-talk).

SW side (tests/background/request-id-protocol.test.ts):
  1. getVideoBufferFromOffscreen sends REQUEST_BUFFER with a generated
     uuid requestId on the live videoPort.
  2. Stale BUFFER (mismatched requestId) is ignored — no resolution.
  3. Port replacement mid-request → SW re-issues REQUEST_BUFFER on the
     new port with the SAME requestId. Retires the H2 silent-drop class.
  4. Empty video segments → saveArchive returns {success:false, error}
     (operator-visible) instead of {success:true} with no-video archive.
  5. SW echoes PONG on PING, closing the health-probe loop.

Suite status: 10 files / 52 tests (42 GREEN, 10 RED).
  - 40 baseline + 2 new GREEN (port-health-probe C; request-id 2 & 4
    accidentally pass due to test-stub side effects — they will continue
    to pass after fix for the right reasons).
  - 3 RED in port-reconnect-race + 3 RED in port-health-probe + 4 RED
    in request-id-protocol.

Quality gates: tsc --noEmit exit 0; type-safety grep clean.
No production code touched in this commit — fix lands in subsequent commits.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 14:27:17 +02:00