--- phase: 03 slug: spec-10-smoke-verification-dom-event-log-verification plan: 01 type: execute wave: 1 depends_on: [] files_modified: - tests/uat/extension-page-harness.html - tests/uat/extension-page-harness.ts - tests/uat/lib/harness-page-driver.ts - tests/uat/harness.test.ts autonomous: true requirements: - REQ-rrweb-dom-buffer tags: - uat-harness - a29 - rrweb - spec-10-4 - approach-b - probe-html user_setup: [] must_haves: truths: - "rrweb session.json contains > 0 events after a probe-page interaction" - "rrweb emits at least one Meta event (EventType=4) on session start" - "rrweb emits at least one FullSnapshot (EventType=2) on session start" - "rrweb emits at least one IncrementalSnapshot (EventType=3) after a DOM mutation on the probe page" - "UAT harness exits 0 with 29 + 1 = 30/30 assertions GREEN (A0..A28 baseline preserved + new A29)" artifacts: - path: "tests/uat/extension-page-harness.html" provides: "Probe HTML (form + table + modal trigger + DOM mutation source) appended below existing scaffold; tokens.css link in head untouched" contains: "id=\"probe-form\"" - path: "tests/uat/extension-page-harness.ts" provides: "assertA29 page-side stub registered on window.__mokoshHarness" contains: "assertA29" - path: "tests/uat/lib/harness-page-driver.ts" provides: "driveA29 host-side: triggers probe-page DOM mutation, runs setupFreshRecording + SAVE, JSZip-parses rrweb/session.json, EventType enum grep" contains: "driveA29" - path: "tests/uat/harness.test.ts" provides: "driveA29 import + wrapped driver + drivers-array push entry with banner comment" contains: "driveA29" key_links: - from: "tests/uat/harness.test.ts" to: "tests/uat/lib/harness-page-driver.ts driveA29" via: "import + wrapped driver const + drivers-array push" pattern: "driveA29Wrapped" - from: "tests/uat/lib/harness-page-driver.ts driveA29" to: "tests/uat/extension-page-harness.ts assertA29" via: "page.evaluate(() => window.__mokoshHarness.assertA29())" pattern: "harness.assertA29\\(\\)" - from: "tests/uat/lib/harness-page-driver.ts driveA29" to: "@rrweb/types EventType enum" via: "import { EventType } from '@rrweb/types'" pattern: "import.*EventType.*from.*@rrweb/types" --- Extend the UAT harness with A29 — empirical verification that SPEC §10 #4 (rrweb DOM event recording on typical pages) is satisfied. Production wiring at `src/content/index.ts:284-309` already ships `rrweb.record()` + `maskInputOptions.password=true`; A29 confirms it actually emits the required EventType events on a synthetic probe page (form + table + modal + DOM-mutation trigger). Purpose: Closes REQ-rrweb-dom-buffer empirical verification gap. Phase 1 shipped the wiring; Phase 3 confirms it works end-to-end through a real Chrome instance + a real probe page. Output: 4-check A29 assertion (events.length > 0 + Meta present + FullSnapshot present + IncrementalSnapshot present); UAT count 29 → 30 GREEN; probe HTML appended to extension-page-harness.html below the existing `
` scaffold (head unchanged; tokens.css link
preserved for A18/A21).



@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md



@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/REQUIREMENTS.md
@.planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-CONTEXT.md
@.planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-RESEARCH.md
@.planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-PATTERNS.md
@.planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-UI-SPEC.md
@.planning/phases/02-stabilize-export-pipeline/02-04-SUMMARY.md
@src/content/index.ts
@tests/uat/extension-page-harness.html





From @rrweb/types/dist/index.d.ts (lines 186-194):
```typescript
export declare enum EventType {
  DomContentLoaded = 0,
  Load = 1,
  FullSnapshot = 2,
  IncrementalSnapshot = 3,
  Meta = 4,
  Custom = 5,
  Plugin = 6
}
```

From tests/uat/lib/assertions.ts (lines 25-44):
```typescript
export interface CheckRecord {
  readonly name: string;
  readonly expected: unknown;
  readonly actual: unknown;
  readonly passed: boolean;
}
export interface AssertionRecord {
  readonly passed: boolean;
  readonly name: string;
  readonly checks: ReadonlyArray;
  readonly diagnostics: ReadonlyArray;
  readonly error?: string;
}
```

From tests/uat/extension-page-harness.ts (line 169):
```typescript
interface AssertionResult {
  passed: boolean;
  name: string;
  checks: Array<{ name: string; expected: unknown; actual: unknown; passed: boolean }>;
  diagnostics: string[];
  error?: string;
}
function diag(result: AssertionResult, line: string): void;   // line 190
async function setupFreshRecording(): Promise<{ ok: boolean; error?: string }>;  // line 825
async function sendMessageWithTimeout(msg: unknown, timeoutMs: number, label: string): Promise;  // line 234
```

From tests/uat/lib/harness-page-driver.ts (lines 1395, 41):
```typescript
function findLatestZip(downloadsDir: string): string | null;  // host-side; mtime-sort wins
import JSZip from 'jszip';  // host-only, not bundled to page
```

From src/content/index.ts (verifier subject — READ-ONLY):
```typescript
// Lines 284-311: record({ emit(event){ rrwebEvents.push(event) }, maskInputOptions: { password: true, ... } })
// Line 318: chrome.runtime.onMessage 'GET_RRWEB_EVENTS' returns { events, userEvents }
// Line 82: setupInputLogging filter — if (target.type === 'password') return;
```

From src/background/index.ts (READ-ONLY):
```typescript
// GET_RRWEB_EVENTS handler in createArchive: chrome.tabs.sendMessage(activeTabId, { type: 'GET_RRWEB_EVENTS' })
// Result lands in rrweb/session.json inside the assembled zip
```


# Plan Anchors

- **Approach B pattern source:** Plan 02-04 driveA26 (canonical host-side
  JSZip read; chains off prior SAVE) — see `02-04-SUMMARY.md` and
  `tests/uat/lib/harness-page-driver.ts:1421-1567` for the exact 3-phase
  shape (page-side stub → findLatestZip → JSZip-parse).
- **RESEARCH Pitfall 1 (MUST OBSERVE):** synthetic probe HTML produces
  `Meta` + `FullSnapshot` on load but NOT `IncrementalSnapshot` unless a
  DOM mutation happens between page load and SAVE. Plan must inject a
  mutation pre-SAVE (e.g. click the modal trigger button or input text).
- **RESEARCH Pitfall 4 (HARD BAN):** Probe HTML MUST NOT include
  `