Canonical closure artifact for Plan 01-14: - monitorTypeSurfaces:'include' shipped (W3C spec §6.1; Chrome >= 119 picker narrowing) - A23 harness regression gate wired into the UAT orchestrator (post-A14 chain) - Tier-1 grep gate inventory extended in lockstep (12 forbidden strings; was 10) Single atomic feat commit (b467123) for the entire 1-task plan. Verification: vitest 100/100 GREEN (+2 new parametrized FORBIDDEN_HOOK_STRINGS tests; both PASS — production bundle hook-free for the new surface). UAT harness 16/16 GREEN (was 15/15). tsc + build clean. Ceremony: replaces the retired AMENDMENT-A.md improvisation path per 01-11-SUMMARY.md Architectural Notes. Canonical GSD flow — plan (41c1f7e) → checker (B-01-14-01) → revision (433ee28) → executor (b467123) → SUMMARY. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
18 KiB
phase, plan, subsystem, tags, status, requires, provides, affects, tech-stack, key-files, decisions, metrics, commits, revision_linkage, ceremony_note, architectural_delta
| phase | plan | subsystem | tags | status | requires | provides | affects | tech-stack | key-files | decisions | metrics | commits | revision_linkage | ceremony_note | architectural_delta | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-stabilize-video-pipeline | 14 | offscreen-recorder |
|
complete |
|
|
|
|
|
|
|
|
|
Canonical GSD ceremony — plan (41c1f7e) → checker (B-01-14-01) → revision (433ee28) → executor (this commit b467123) → SUMMARY (this file). Replaces the retired AMENDMENT-A.md improvisation path per 01-11-SUMMARY.md Architectural Notes. |
ZERO new permissions; ZERO new manifest changes; ZERO new web_accessible_resources; new internal test-hook surface (lastGetDisplayMediaConstraints cell + get-last-getDisplayMedia-constraints op) gated identically to Plan 01-13's hook inventory via __MOKOSH_UAT__ Vite define-token dead-branch tree-shake. |
Phase 01 Plan 14: monitorTypeSurfaces Picker Narrowing Summary
One-liner: Shipped W3C Screen Capture monitorTypeSurfaces: 'include' as a top-level constraint on the production getDisplayMedia call site (Chrome ≥ 119 narrows the operator picker to monitor surfaces only — no Window/Chrome-Tab panes), with UAT harness A23 regression gate + Tier-1 grep-gate lockstep extension covering the new internal hook surface.
What Shipped
-
Source change —
src/offscreen/recorder.ts:270-292(commitb467123): addedmonitorTypeSurfaces: 'include'as a TOP-LEVELDisplayMediaStreamOptionssibling ofvideo:(NOT nested insidevideo:per W3C Screen Capture spec §6.1). The typed widening cast at lines 287-289 was extended in lockstep to includemonitorTypeSurfaces: 'include'so the explicit-typing contract is preserved (noas any). The D-15 post-grant validation block (recorder.ts:294-307) is unchanged — belt-and-suspenders chain preserved. -
Lockstep test-expectation update —
tests/offscreen/display-surface-constraint.test.ts:223-228: Test 1's strict-deep-equalitytoHaveBeenCalledWithexpectation grew from{ video: {...}, audio: false }to{ video: {...}, monitorTypeSurfaces: 'include', audio: false }. Same key ordering as the source change (video:→monitorTypeSurfaces:→audio:). The test author's "no objectContaining" discipline is honored (the comment at lines 221-225 was extended to mention Plan 01-14's addition; the strict deep-equality contract remains). Both source + test changes landed in the same atomic commit, so the 98/98 baseline never crossed a commit boundary in RED state. -
Harness wiring for A23 —
src/test-hooks/offscreen-hooks.ts:- New module-scoped cell:
let lastGetDisplayMediaConstraints: DisplayMediaStreamOptions | null = null(immediately after the existing fake-state cells, with docstring). installFakeDisplayMedia'sfakeGetDisplayMediaclosure: renamed_constraints→constraintsand addedlastGetDisplayMediaConstraints = constraints ?? null;as the first line.- New
__mokoshOffscreenQuerydispatcher op:'get-last-getDisplayMedia-constraints'betweenget-display-surfaceandget-segment-count. Response:{ constraints: lastGetDisplayMediaConstraints }. Defensive try/catch mirroring the existing dispatcher pattern.
- New module-scoped cell:
-
Harness page assertion —
tests/uat/extension-page-harness.ts:1906-1989: newassertA23()mirroringassertA3(bridge query → 2-checkAssertionResult):- A23.1: constraints object recorded by fakeGetDisplayMedia (non-null) → PASS
- A23.2:
constraints.monitorTypeSurfaces === 'include'(W3C spec §6.1; Chrome ≥ 119 picker narrowing) → PASS Window.__mokoshHarnessdeclaration + runtime export + status-bar text + console.log updated.
-
Harness driver —
tests/uat/lib/harness-page-driver.ts:996-1023: exporteddriveA23(page)mirroring thedriveA14page.evaluate wrapper shape. Read-only — no side effects, no new dispatch. -
Harness orchestrator —
tests/uat/harness.test.ts:- Header comment extended to describe A23 as the final functional assertion (post-A14; read-only inspection of A2-captured constraints).
FORBIDDEN_HOOK_STRINGS(line 85) extended withlastGetDisplayMediaConstraintsandget-last-getDisplayMedia-constraints.- Import block extended with
driveA23from./lib/harness-page-driver. driversarray appended with{ name: 'A23', drive: driveA23 }after the A14 entry (with explanatory comment).Total = drivers.length + 1comment updated to mention A23.- Orchestrator stdout updated:
Plan 01-13 + 01-14, architecture line mentionsA1..A14, A23.
-
Unit-level grep gate —
tests/background/no-test-hooks-in-prod-bundle.test.ts: header comment extended with the 2 new strings (Total: 12 surface strings — was 10).FORBIDDEN_HOOK_STRINGS(line 105) extended in lockstep with the UAT A0 list.
Atomic commit hash: b467123 — single commit, 7 files, +228 / -13 lines.
Verification Evidence
| Gate | Pre-Plan Baseline | Post-Plan Result | Status |
|---|---|---|---|
npx tsc --noEmit |
exit 0 (clean) | exit 0 (clean) | GREEN |
npm run build |
exit 0 | exit 0 | GREEN |
npm run build:test |
exit 0 | exit 0 | GREEN |
npm test |
98/98 | 100/100 | GREEN (+2 via new parametrized FORBIDDEN_HOOK_STRINGS tests; both PASS) |
npm run test:uat |
15/15 (A1..A14 + A0) | 16/16 (+A23) | GREEN |
| Production bundle hook-free (spot-check) | clean | clean | GREEN — zero occurrences of lastGetDisplayMediaConstraints or get-last-getDisplayMedia-constraints in dist/ |
Production bundle ships monitorTypeSurfaces |
n/a | present in dist/assets/offscreen-*.js |
EXPECTED — operator-facing picker hint ships in prod |
A23 evidence (from UAT harness run output):
--- A23 ---
[harness-step] Step 1: bridge query 'get-last-getDisplayMedia-constraints'
[harness-step] Step 1 result: {"constraints":{"video":{"displaySurface":"monitor","cursor":"always"},"monitorTypeSurfaces":"include","audio":false}}
========================================================================
A23 — getDisplayMedia called with monitorTypeSurfaces:'include' (Plan 01-14 picker narrowing): PASS
Checks:
[PASS] A23.1: constraints object recorded by fakeGetDisplayMedia (non-null)
expected: "non-null DisplayMediaStreamOptions"
actual: "{\"video\":{\"displaySurface\":\"monitor\",\"cursor\":\"always\"},\"monitorTypeSurfaces\":\"include\",\"audio\":false}"
[PASS] A23.2: constraints.monitorTypeSurfaces === 'include' (W3C spec §6.1; Chrome ≥ 119 picker narrowing)
expected: "include"
actual: "include"
========================================================================
UAT harness: 16/16 assertions passed
The recorded constraints object shows the exact production call shape with the new sibling field — confirming the source change reached the call site through both the typed widening cast and the JavaScript runtime serialization across the production → offscreen-hooks fake → bridge dispatcher → harness assertion path.
Research Linkage
This plan ships the recommendation from Plan 01-10 RESEARCH §5 + §Pitfall-5 + §Environment-Availability: "Add monitorTypeSurfaces: 'include' to the offscreen getDisplayMedia constraints. Single-line, zero-risk change that removes visual noise from the picker." The Chrome ≥ 119 feature-gate per Plan 01-10 RESEARCH §Environment-Availability matches the target Chrome version for this extension.
Authoritative references encoded into the commit body + source comments:
- W3C Screen Capture §6.1 DisplayMediaStreamOptions: https://www.w3.org/TR/screen-capture/#dom-displaymediastreamoptions-monitortypesurfaces
- Chrome screen-sharing-controls (Chrome 119+): https://developer.chrome.com/docs/web-platform/screen-sharing-controls
Decision Linkage
- D-01 (whole-desktop only via getDisplayMedia; reject window/tab surfaces):
monitorTypeSurfaces: 'include'is the picker-UI realization of D-01's intent. The operator's choice space is narrowed at the dialog level rather than catching wrong selections post-grant. - D-15 (post-grant validation): unchanged. The recorder.ts:294-307 block remains the actual enforcement —
monitorTypeSurfacesis a HINT-class constraint (per spec semantics; older Chrome / managed-policy / DevTools can override). Belt (picker-UI narrowing) + suspenders (post-grant tear-down withwrong-display-surfaceerror code) chain preserved. - D-13 (segment rotation 3 × 10 s = 30 s): unchanged.
- D-17 (long-lived port keepalive): unchanged.
Ceremony Note
This plan replaces the prior AMENDMENT-A.md improvisation path that was retired per .planning/phases/01-stabilize-video-pipeline/01-11-SUMMARY.md Architectural Notes. Canonical GSD ceremony (plan → checker → executor → SUMMARY) landed:
- Plan creation: commit
41c1f7e(2026-05-19). - Plan-checker review: BLOCKER B-01-14-01 raised — must_haves truth #5 understated baseline regression risk by omitting Step 1b lockstep test-expectation update.
- Plan revision: commit
433ee28(2026-05-19) — added Step 1b (display-surface-constraint.test.ts:223-226 update) + corresponding frontmatter/artifacts/key-link entries. - Executor (this commit
b467123, 2026-05-19): single atomic commit for the entire 1-task plan. - SUMMARY (this file): canonical closure artifact.
The lesson encoded by B-01-14-01: strict-deep-equality test expectations are tightly coupled to the source-call shape; any plan that mutates the source object MUST mutate the expectation in the same atomic commit, or the baseline crosses a RED boundary at commit-time. The checker caught this before any harm; the executor honored the same-commit guarantee.
Revision Linkage
The plan was revised once after the plan-checker flagged BLOCKER B-01-14-01 (commit 433ee28, 2026-05-19). The revision added Step 1b (lockstep test-expectation update) + corresponding frontmatter/file/key-link entries to the plan. Without the revision, executing the original plan as-written would have dropped the vitest baseline from 98/98 GREEN to 97/98 RED on the strict-deep-equality assertion at tests/offscreen/display-surface-constraint.test.ts:223-226. The single-commit landing in this executor pass restored the same-commit guarantee.
Architectural Delta
- ZERO new permissions
- ZERO new manifest changes
- ZERO new web_accessible_resources entries
- ZERO new dependencies (no new npm packages, no new types)
- New internal test-hook surface (
lastGetDisplayMediaConstraintscell +get-last-getDisplayMedia-constraintsbridge op) gated identically to Plan 01-13's hook inventory via the__MOKOSH_UAT__Vite define-token dead-branch tree-shake. Tier-1 grep gate (unit-level + UAT A0) extended in lockstep to enforce.
What Did Not Change
- D-15 post-grant validation block (recorder.ts:294-307) — unchanged
- Plan 01-09 toolbar
onClickedchain — unchanged - Plan 01-10 welcome-page architecture — unchanged (scope reserved for the next-up plan)
- Plan 01-12 design-integration scope — unchanged (scope reserved for the next-up plan)
- Plan 01-13 harness architecture — the 14 existing assertions (A1..A14) are unmodified; A23 is purely additive (appended after the A14 driver in
driversarray) src/test-hooks/types.ts— unchanged (decision documented above; the new cell + op are module-internal to offscreen-hooks.ts)chrome.runtimemessage contracts — unchanged (new bridge op uses the existing__mokoshOffscreenQueryenvelope)- Vite build configuration — unchanged (the existing
__MOKOSH_UAT__define-token tree-shake handles the new surface automatically)
Deviations from Plan
Auto-fixed Issues
None. No bugs encountered. No CLAUDE.md violations. No missing critical functionality. No blocking issues. The plan's <verify> block + <done> criteria mapped 1-to-1 to the actual execution path.
Test count drift (benign positive deviation)
- Found during: Step 9 (
npm testpost-commit) - Issue: Plan predicted "98/98 GREEN preserved"; actual count is 100/100.
- Root cause: The unit-level grep gate at
tests/background/no-test-hooks-in-prod-bundle.test.tsuses a parametrizedfor (const needle of FORBIDDEN_HOOK_STRINGS) { it(...) }loop (line 254-278) — each entry in the list spawns one independentit()test. Adding 2 strings to the inventory adds 2 tests. The plan's truth #5 wrote "98/98 GREEN" without noticing this arithmetic. - Action taken: None (no fix required). All 100 tests are GREEN; the 2 new tests assert the production bundle is hook-free for the new symbols (
lastGetDisplayMediaConstraintsandget-last-getDisplayMedia-constraints) — both PASS. The plan's spirit ("baseline preserved") is honored; the arithmetic just shifted up. - Documented in: decisions[] in this SUMMARY's frontmatter.
Authentication Gates
None encountered. The plan's <verify> chain (npm run build, npx tsc --noEmit, npm test, npm run test:uat) is fully autonomous (Chrome launches headlessly via puppeteer; no operator interaction).
Threat Surface Scan
No new threat surface introduced beyond what the plan's <threat_model> block already documents. The 6 STRIDE entries (T-01-14-01..T-01-14-06) cover the full delta. T-01-14-04 (Information Disclosure via leaked hook surface) is mitigated by the Tier-1 grep gate extension (verified GREEN). No threat flags to surface.
Known Stubs
None. No placeholder text, no hardcoded empty values, no TODO/FIXME markers introduced. Every new code path is fully wired to a real data source.
Files Modified Summary
| File | LoC delta | Purpose |
|---|---|---|
src/offscreen/recorder.ts |
+16 / -0 | Source change + extended typed widening cast + explanatory comment |
src/test-hooks/offscreen-hooks.ts |
+54 / -5 | Module cell + capture in fake + dispatcher op + dispatcher comment |
tests/offscreen/display-surface-constraint.test.ts |
+5 / -1 | Strict-deep-equality expectation lockstep update |
tests/uat/extension-page-harness.ts |
+77 / -4 | assertA23 impl + global decl + runtime export + status/log |
tests/uat/lib/harness-page-driver.ts |
+27 / -0 | driveA23 page.evaluate wrapper |
tests/uat/harness.test.ts |
+26 / -6 | FORBIDDEN inventory + import + drivers + comments |
tests/background/no-test-hooks-in-prod-bundle.test.ts |
+18 / -2 | FORBIDDEN inventory lockstep + header comment |
| Total | +228 / -13 | 7 files, 1 atomic commit |
Self-Check: PASSED
File-existence verification:
src/offscreen/recorder.ts— FOUND (modified per commitb467123)src/test-hooks/offscreen-hooks.ts— FOUND (modified)tests/offscreen/display-surface-constraint.test.ts— FOUND (modified)tests/uat/extension-page-harness.ts— FOUND (modified)tests/uat/lib/harness-page-driver.ts— FOUND (modified)tests/uat/harness.test.ts— FOUND (modified)tests/background/no-test-hooks-in-prod-bundle.test.ts— FOUND (modified)
Commit-existence verification:
b467123— FOUND ingit log --oneline -3(HEAD).
Gate evidence:
npm test→ 100/100 GREENnpm run test:uat→ 16/16 GREEN ("UAT harness: 16/16 assertions passed")npx tsc --noEmit→ exit 0npm run build→ exit 0npm run build:test→ exit 0- Production bundle spot-check: zero occurrences of
lastGetDisplayMediaConstraintsandget-last-getDisplayMedia-constraintsindist/