Files
Mark 586836f8a0 docs(01): VERIFICATION + Phase 1 closure markers — goal-backward audit GREEN
gsd-verifier goal-backward audit (2026-05-20) returned GREEN verdict on
Phase 1 (Stabilize Video Pipeline + whole-desktop capture + as-automatic-
as-platform-allows recording start):

- 17/17 must-haves verified: 11 REQs/charters + 6 cross-cutting gates
- 14/14 plans complete (01-01..01-09 + 01-11 spike-pivot + 01-12 + 01-13
  + 01-14 + 01-10)
- 5 operator empirical acks: Plan 01-07 (Chrome playback 2026-05-15) +
  Plan 01-13 (harness 2026-05-19) + Plan 01-12 (brand-fit 2026-05-20) +
  Plan 01-10 cycle-2 ("All good" 2026-05-20) + Plan 01-10 brand-rename
  follow-up (2026-05-20)
- Test gates: vitest 153/153 GREEN; UAT harness 24/24 GREEN; Tier-1 grep
  gate 12 FORBIDDEN_HOOK_STRINGS; pre-checkpoint bundle gates PASS
- 7 P0 audit defects: 6 closed in-Phase-1-scope; P0 #6 (data-sensitive
  masking) properly deferred to Phase 2

Marker flips landed:

- STATE.md status reflects Phase 1 COMPLETE; completed_phases 0 → 1
- ROADMAP.md Phase 1 row [ ] → [x] with closure-arc summary
- REQUIREMENTS.md REQ-video-ring-buffer In-progress → Complete 2026-05-20
- VERIFICATION.md committed (orchestrator-bundle pattern per verifier
  protocol)

Forward-looking deferred (NOT gaps):
- Phase 2: REQ-rrweb-dom-buffer + REQ-user-event-log +
  REQ-password-confidentiality (audit P0 #6)
- Phase 5 hardening: getDisplayMedia cursor visibility; setimmediate
  polyfill new Function pre-existing; tabs permission gap; dark-surface
  logo contrast; 2 ffprobe/ffmpeg test flakes

Phase 2 (Stabilize DOM + event-capture privacy) kickoff pending.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 12:31:36 +02:00

124 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
phase: 01-stabilize-video-pipeline
verified: 2026-05-20T12:25:00Z
verifier: gsd-verifier (re-verification pass after May 16 initial verification + 14-plan landing)
status: passed
score: 17/17 must-haves verified (11 REQs/charters + 6 cross-cutting gates)
re_verification:
previous_verified: 2026-05-16T09:11:33Z
previous_status: human_needed
previous_score: 10/10 + 2 ADVISORY + 3 operator-side residue
gaps_closed:
- "REQ-video-ring-buffer #7 multi-EBML playability (Plan 01-08 webm-remux)"
- "Whole-desktop charter (D-01 + D-15-display-surface; Plan 01-09)"
- "Brand identity (D-07 + D-08; Plan 01-12)"
- "First-install onboarding (D-17; Plan 01-10)"
- "UAT harness 15→24 + functional contract closure (Plan 01-13 + Plan 01-14)"
gaps_remaining: []
regressions: []
goal: "Phase 1 — Stabilize video pipeline + whole-desktop capture + as-automatic-as-platform-allows recording start. The video ring buffer captures the most recent 30 s of whole-desktop video continuously across tab switches, with a playable WebM remux + SPEC §10 #1/#2/#3/#7 green + brand-fit operator-facing surfaces + first-install onboarding."
verdict: ACHIEVED
---
# Phase 1 Verification — Stabilize Video Pipeline (Goal-Backward Audit)
**Verdict: ACHIEVED.** 14/14 functional plans landed; all REQs & decisions verified against codebase HEAD `d1ef77a`.
## Goal (verbatim, ROADMAP.md + PROJECT.md)
Stabilize video pipeline: continuous 30 s whole-desktop ring buffer via `getDisplayMedia` in offscreen; playable single-EBML WebM remux on export; toolbar + notification + first-install welcome activation; brand-fit operator-facing surfaces.
## Per-Requirement Scorecard
| # | Requirement / Decision | Evidence | Status |
|---|---|---|---|
| 1 | REQ-video-ring-buffer | `src/offscreen/recorder.ts:52-58` (`MAX_SEGMENTS=3 × 10s = 30s`); `:285-290` getDisplayMedia constraints; `:463-484` segment rotation; `src/background/webm-remux.ts` single-EBML remux; `tests/fixtures/last_30sec.webm` 1888636B ffprobe exit 0 | PASS |
| 2 | REQ-install-clean | `npm run build` exit 0, 9 chunks produced incl. welcome (3.51 kB) + offscreen + SW (375 kB); `grep googleapis dist/` → 0; 8-bit RGBA icons 406/784/1952 B; operator brand-fit ack 2026-05-20 | PASS |
| 3 | REQ-manifest-permissions | `manifest.json:7-15` — exactly `desktopCapture/activeTab/downloads/scripting/storage/offscreen/notifications`; NO `tabCapture`; `default_locale: "en"`; `__MSG_extName__` + `__MSG_extDesc__` + `__MSG_tooltipOff__` | PASS |
| 4 | REQ-onboarding (D-17) | `src/background/index.ts:263-287` openWelcomeIfFirstInstall gated by `details.reason === 'install'` + `chrome.storage.local['onboarding-completed']`; `:1067-1087` onInstalled wiring with `.catch` defense; A15/A16/A17 GREEN | PASS |
| 5 | D-01 whole-desktop charter | `recorder.ts:284-291``{video:{displaySurface:'monitor',cursor:'always'}, monitorTypeSurfaces:'include', audio:false}`; `:302-323` post-grant validation throws `wrong-display-surface` on mismatch; A3 + A23 harness GREEN | PASS |
| 6 | D-06 always-on charter (Amendment 3 reversal) | `src/background/index.ts:722-740` docstring locks no-finally; `:830-834` explicit NO finally block; `tests/background/save-archive-does-not-stop-recording.test.ts` (inverted); harness A14 inverted (commit 1baaf45) | PASS |
| 7 | D-07/D-08 brand identity | `_locales/en/messages.json:3-8` "Mokosh — Session Capture" + tagline; `_locales/ru/messages.json:3-8` "Mokosh — Запись сессии" + Cyrillic tagline; `tooltipOff` RU "Mokosh — щёлкните..."; operator brand-fit ack 2026-05-20 | PASS |
| 8 | D-13 + D-14 multi-EBML remux | `src/offscreen/recorder.ts:366-416` `startNewSegment` per-rotation self-contained; `src/background/webm-remux.ts` ts-ebml + webm-muxer; `tests/fixtures/last_30sec.webm` ffprobe + ffmpeg dry-run exit 0; commit dd7bf00 Buffer polyfill | PASS |
| 9 | T-1-04 sender-id check | `src/background/index.ts:384-388` port sender check; `:847-850` onMessage sender check; `recorder.ts:465-467` + onMessage enforced | PASS |
| 10 | SW respawn safety (CR-03) | `src/background/index.ts:962-986` `hasDocument()` + early-resolve `offscreenReadyResolve` on detected pre-existing offscreen; long-lived port (D-17, PORT_PING_MS=25_000) | PASS |
| 11 | Offscreen duality collapsed (P0-1) | `ls offscreen/` → ENOENT; `grep copy-offscreen vite.config.ts` → 0; `dist/src/offscreen/index.html` single source via crxjs rollupOptions.input | PASS |
## Cross-Cutting Gates
| Gate | Evidence | Status |
|---|---|---|
| vitest | 28 files / **153 tests / 153 GREEN** (SKIP_BUILD=1 after fresh `npm run build` — first-pass had 2 build-dependent + 1 known ffprobe flake, both resolved post-build) | PASS |
| UAT harness | 24 drivers (A0 grep gate + A1..A14 + A15..A17 + A18..A22 + A23); SUMMARY 01-10 verifies 24/24 GREEN | PASS |
| Tier-1 grep gate | 12 FORBIDDEN_HOOK_STRINGS (matches documented baseline); `dist/` contains 0 `__mokoshTest`/`installFakeDisplayMedia`/etc. | PASS |
| Pre-checkpoint bundle gates | 0 `googleapis`/`https://fonts` in dist; 0 test-hook leaks; manifest validation + en↔ru parity tests GREEN | PASS |
| tsc | `npx tsc --noEmit` exit 0 | PASS |
| Phase 1 surface `as any` / `@ts-ignore` | 0 in `src/offscreen/`, `src/background/index.ts`, `src/shared/`, `src/welcome/`, `src/popup/` (only comments mentioning the absence; `src/content/` matches are Phase 2 territory) | PASS |
## 7 P0 Audit Defects — Traceability
| P0 # | Defect | Closed by | Status |
|---|---|---|---|
| 1 | Offscreen duality (`offscreen/index.ts` + vite inline) | Plans 01-03 + 01-06 | CLOSED |
| 2 | MediaRecorder shadow bug | Plan 01-03 | CLOSED |
| 3 | WebM ring buffer 200ms→2000ms + playability | Plans 01-03/04/07 + D-13 + Plan 01-08 D-14-remux | CLOSED |
| 4 | Always-on capture (`onActivated`/`onUpdated`) | Plan 01-05 SW shrink + Plan 01-09 onStartup notification + Amendment 3 always-on charter | CLOSED (architecturally; `chrome.tabs.onActivated`/`onUpdated` absent — `grep` exit 1 — replaced by single MediaStream across rotations via D-15 amended) |
| 5 | tabCapture user gesture | Plan 01-09 D-01 obviation via `getDisplayMedia` in offscreen + toolbar `chrome.action.onClicked` + notification onClicked paths | CLOSED |
| 6 | rrweb data-sensitive masking | Phase 2 (deferred per REQUIREMENTS.md line 220) | DEFERRED to Phase 2 (out of Phase 1 scope) |
| 7 | base64 data: URL download | Plan 01-08 webm-remux + JSZip; Note: `downloadArchive` at `src/background/index.ts:709-710` still uses `data:application/zip;base64,` URL via `blobToBase64` (REVIEW-FIX WR-08 single-source) — accepted Phase 1 trade-off; Phase 3 owns Blob-URL minted in offscreen per ROADMAP line 27 | CLOSED-in-scope (Blob-URL refinement is Phase 3 P0-6 territory) |
## Operator-Empirical Acks (verbatim + commit refs)
| Date | Plan | Operator response | Commit |
|---|---|---|---|
| 2026-05-15 | 01-07 (D-12 + A3 closure) | Chrome playback clean, ffmpeg dry-run exit 0 | cd61cbc (fixture) |
| 2026-05-19 | 01-13 (harness UAT Task 9) | "all good" (recovery + restart-after-click) | 9c5ff8b + 1baaf45 |
| 2026-05-20 | 01-12 (Wave 7 brand-fit) | "all good" (toolbar Loom icon, popup palette, manifest:name resolution EN+RU, Lora display, chrome.i18n notification copy) | f319c7d + 66e6f50 |
| 2026-05-20 | 01-10 (cycle-2 onboarding) | "All good" (welcome page + canonical mark + Lora hero + Cyrillic tagline + onStartup CTA + notification.onClicked → startVideoCapture + reload-does-not-re-open + re-install branch) | 52dc2e6 + d1ef77a |
| 2026-05-20 | 01-10 (cycle-2 brand-rename follow-up) | (same-day brand-polish ack on `d21ed17`) | d21ed17 |
## Initial-Pass Residue (May 16) — Now Closed
The May 16 initial verification flagged 3 operator-side items as `human_needed`. All resolved by subsequent plans + operator UAT:
1. **OPR-1** (getDisplayMedia picker grant) → Plan 01-09 + Plan 01-14 ship `displaySurface:'monitor' + monitorTypeSurfaces:'include'`; operator empirically grants via picker; A3 + A23 harness GREEN.
2. **OPR-2** (continuous capture across tab switches) → Plan 01-09 D-15-display-surface confirms no per-tab re-acquisition; A11 buffer-continuity harness GREEN over 35 s wait.
3. **OPR-3** (SW idle-unload survival) → Plan 01-04 long-lived port + CR-03 fix verified; harness A2 (toolbar→record) reaches GREEN after SW respawn cycles.
## Documentation Drift (NOT a gap — orchestrator marker-flip territory)
REQUIREMENTS.md line 218 traceability table row reads "In progress (reopened 2026-05-16…)" but line 19 already shows `[x]` and SUMMARY chain + footer note (line 244) confirm the closure. STATE.md `progress.completed_phases: 0` and ROADMAP.md Phase 1 row `[ ]` are similarly pending marker flip. This is the explicit "Phase 1 final-closure marker flip pending" task the orchestrator owns post-verification per STATE.md `stopped_at` field.
## Forward-Looking Deferred Items (NOT gaps)
| Item | Owner | Source |
|---|---|---|
| REQ-rrweb-dom-buffer + REQ-user-event-log + REQ-password-confidentiality (P0 #6) | Phase 2 | REQUIREMENTS.md lines 220-222 |
| Popup state machine + base64→Blob URL (P0-4 + P0-6) | Phase 3 | ROADMAP.md line 27 |
| SPEC §10 full smoke pass (#1 install + #6 <5s latency + #8 password + #9 RAM) | Phase 4 | ROADMAP.md line 28 |
| getDisplayMedia cursor visibility refinement (already mitigated via `cursor:'always'` in Plan 01-09 — but Phase 5 refinement remains for picker-UI polish) | Phase 5 | STATE.md line 187 |
| setimmediate polyfill `new Function` in SW chunk | Phase 5 | deferred-items.md (pre-existing across Phase 1 history) |
| `tabs` permission gap | Phase 5 | 01-13-SUMMARY.md line 186 |
| 2 ffprobe/ffmpeg test flakes (build-dependent + frame-count timeout) | Phase 5 | This verification (153/153 GREEN with SKIP_BUILD=1; flakes are test-harness fragility, not production-code bugs) |
| Dark-surface logo contrast | Phase 5 | (designer follow-up) |
| ROADMAP 01-08..01-13 backfill verification | Phase 5 | 01-13-SUMMARY.md line 185 (now backfilled in ROADMAP lines 81-87) |
## Per-Plan Closure Anchor Map
| Plan | Closed | Commit | Operator Ack |
|---|---|---|---|
| 01-01..01-07 | 2026-05-15 | cd61cbc + REQ flip | smoke.sh + Chrome playback |
| 01-08 (webm-remux) | 2026-05-17 | 9c5ff8b (closure) | (build-time gate; no UAT needed) |
| 01-09 (toolbar+badge+notification) | 2026-05-19 (functional via harness) + 2026-05-20 (CTA-text fix) | Multiple incl. 4bba679 + a2dfc8c | "all good" + cycle-2 |
| 01-10 (welcome tab) | 2026-05-20 | 52dc2e6 + d1ef77a | cycle-2 "All good" + brand-rename ack |
| 01-11 (spike-pivot) | 2026-05-18 | ba5474c | (architectural learning only) |
| 01-12 (design integration) | 2026-05-20 | f319c7d + 66e6f50 | brand-fit "all good" |
| 01-13 (UAT harness) | 2026-05-19 | 9c5ff8b | Task 9 "all good" |
| 01-14 (monitorTypeSurfaces) | 2026-05-19 | b467123 | (single-task; harness GREEN) |
---
**Final Verdict: Phase 1 goal ACHIEVED.** All must-haves verified in code; all operator empirical acks recorded; all deferred items routed to correct future phase. Orchestrator may flip `REQUIREMENTS.md`/`ROADMAP.md`/`STATE.md` markers + advance `progress.completed_phases: 0 → 1`.
_Verified: 2026-05-20T12:25:00Z by Claude (gsd-verifier)_