# Requirements: Mokosh **Defined:** 2026-05-15 **Core Value:** When an operator hits a bug, one click produces a self-contained archive that lets support reproduce what happened — in under 5 s, no server, no password leaks. All requirements below are extracted from the SPEC `Тз расширение фаза1.md`. The intel files `.planning/intel/requirements.md`, `.planning/intel/constraints.md`, and `.planning/intel/decisions.md` carry the verbatim wording, source citations, and technical bindings; this file is the GSD-shaped projection of those facts. ## v1 Requirements Requirements for the Phase 1 SPEC. Each maps to one phase in ROADMAP.md. ### Video - [x] **REQ-video-ring-buffer**: The extension maintains an in-memory ring buffer containing the most recent 30 seconds of captured video. AMENDED in Phase 01: video is acquired via `navigator.mediaDevices.getDisplayMedia()` invoked from the offscreen document (with `chrome.offscreen.Reason.DISPLAY_MEDIA`), NOT `chrome.tabCapture` as originally specified. The captured stream is screen-or-window-scoped per the operator's one-time selection in Chrome's native picker, and continues unchanged across tab switches. Encoding is `video/webm; codecs=vp9` @ 400 000 bps. Ring-buffer mechanism FURTHER AMENDED in Phase 01 fix-a3 (debug session webm-playback-freeze, resolved 2026-05-15): the original D-09..D-11 single-continuous-`MediaRecorder` + age-trim approach was retired in favor of D-13 restart-segments — the recorder stop()/start()s every 10 s on the same `MediaStream`, keeping the last 3 self-contained ~10 s WebM segments (3 × 10 s = 30 s window). Each segment carries its own EBML header + seed VP9 keyframe and is independently decodable, eliminating the orphan-P-frame freeze observed with the trim approach. Bindings: DEC-003 (AMENDED), DEC-009, CON-video-window, CON-video-codec, CON-display-capture-binding (replaces RETIRED CON-tab-capture-binding). CON-webm-header-retention RETIRED in favor of D-13 per-segment header isolation. - SPEC §10 acceptance criteria: #2, #3 — green 2026-05-15 (D-12 ffprobe gate). #7 (last_30sec.webm plays back in a browser) — **REOPENED 2026-05-16**: D-13's concat-of-self-contained-segments architecture produces a multi-EBML-header file that standards-compliant Matroska parsers (mpv, ffmpeg, Chrome's HTMLMediaElement) play only as the first segment (~9.94 s) and silently drop segments 2 and 3. The 2026-05-15 "operator-confirmed clean Chrome playback" assessment was insufficient — it checked playback ran without freezing but did not measure total duration. Plan 01-08 (WebM remux via ts-ebml + webm-muxer) will replace `mergeVideoSegments`'s file-concat with a real single-EBML-headered remux, restoring SPEC §10 #7. See `.planning/debug/d13-multi-ebml-concat-unplayable.md` for the byte-level root-cause evidence. ### DOM Capture - [ ] **REQ-rrweb-dom-buffer**: The extension records DOM events via rrweb (`rrweb.record()`) running in the Content Script over a rolling 10-minute window, capped at 5 000 events (oldest dropped on overflow). Sensitive fields are masked via rrweb v2 `maskInputFn` covering `input[type=password]` and `[data-sensitive="true"]`. Bindings: DEC-004, CON-rrweb-window, CON-sensitive-data-masking. - SPEC §10 acceptance criteria: #4. ### Event Logging - [ ] **REQ-user-event-log**: The extension logs user and runtime events over a rolling 10-minute window. Captured types: `click` (records target selector and element text), `input` (excludes password fields), `navigation` (`popstate`, `hashchange`, page transitions), `js_error` (`window.onerror`, `window.onunhandledrejection`), `network_error` (`fetch` / `XMLHttpRequest` with response code >= 400). Each entry conforms to the verbatim `CON-event-log-schema`. Bindings: CON-event-log-window, CON-event-log-schema, CON-sensitive-data-masking. - SPEC §10 acceptance criteria: #5, #8. ### Export - [ ] **REQ-screenshot-on-export**: On "Save archive" click, the extension captures a PNG screenshot of the active tab via `chrome.tabs.captureVisibleTab()` and includes it as `screenshot.png` in the archive. Binding: DEC-008. - [ ] **REQ-popup-ui**: The extension exposes a minimal popup with a single button labeled "Сохранить отчёт об ошибке" and a sub-label "Последние 30 сек видео + 10 мин лога". Button state machine: `idle → "Сохраняю..." → "Готово! ✓" → idle` (3 s revert). On click: (1) capture screenshot, (2) request video buffer + event log from SW, (3) request rrweb snapshots from Content Script, (4) assemble archive, (5) trigger download, (6) display "Готово! ✓". Russian strings are part of the contract and preserved verbatim. - [ ] **REQ-archive-layout**: The archive is named `session_report_YYYY-MM-DD_HH-MM-SS.zip` and contains exactly: ``` session_report_2025-05-15_14-32-10.zip ├── video/ │ └── last_30sec.webm ├── rrweb/ │ └── session.json ├── logs/ │ └── events.json ├── screenshot.png └── meta.json ``` Binding: CON-archive-layout. - SPEC §10 acceptance criteria: #7. - [ ] **REQ-meta-json-schema**: `meta.json` inside the archive conforms to the verbatim schema (D-P2-02 + D-P2-03 cutover; replaces the 7-field `url: string` shape per audit P1 #10 amendment 2026-05-20): ```json { "schemaVersion": "2", "timestamp": "2025-05-15T14:32:10Z", "urls": ["https://example.com/", "https://app.example.com/dashboard"], "userAgent": "Chrome/...", "extensionVersion": "1.0.0", "videoBufferSeconds": 30, "logDurationMinutes": 10, "totalEvents": 143 } ``` All 8 fields required. Acceptance: - `schemaVersion === '2'` (marks the D-P2-02 url→urls cutover; future schema bumps increment) - `timestamp` ISO-8601 with `Z` suffix - `urls` is a `string[]` whose entries each match `/^(https?|chrome-extension):\/\//` (per CONTEXT.md `` filter rules — exclude chrome://, about:, devtools://, file://). Empty array IS permitted per F2 (whole-desktop-no-tab session is a meaningful operator state); non-empty arrays validate each entry. - `urls` is deduplicated; ordering is first-seen-first across the rolling recording window - `extensionVersion` matches semver - `totalEvents` is a non-negative integer - exactly 8 keys; no extras Binding: CON-meta-json-schema (this REQ-text supersedes the original CON-meta-json-schema 7-field shape — the original is preserved in the SPEC for provenance; this REQ documents the Phase 2 cutover). ### Manifest & Install - [x] **REQ-manifest-permissions**: `manifest.json` declares exactly the permission set in DEC-011 (`tabCapture`, `activeTab`, `downloads`, `scripting`, `storage`; `host_permissions: [""]`) and requests a user gesture for `tabCapture` on first activation. Binding: DEC-011, CON-manifest-permissions. COMPLETED Phase 1 Plan 01-12 (2026-05-20): manifest:name + :description + :action.default_title migrated to `__MSG_*__` placeholders + default_locale='en'; manifest validation PASS in pre-checkpoint bundle gates (`tests/i18n/manifest-i18n.test.ts` shape + `tests/i18n/locale-parity.test.ts` en↔ru parity); permissions baseline UNCHANGED (Plan 01-12 added ZERO new permissions). Operator brand-fit ack 2026-05-20. - SPEC §10 acceptance criteria: #1. - [x] **REQ-install-clean**: The extension installs in Chrome without errors via the unpacked-extension load flow. COMPLETED Phase 1 Plan 01-12 (2026-05-20): fresh `npm run build` produces clean dist/; load unpacked into Chrome shows manifest:name "Mokosh — Session Capture" (EN) or "Mokosh — Запись сессии" (RU) with no permission warnings, no remote-font CSP errors (0 `googleapis` / 0 `https://fonts` in dist/ verified by `tests/build/no-remote-fonts.test.ts`), branded Loom-mark icons rendering at 16/48/128 sizes (8-bit RGBA), and 16 i18n keys per locale with en↔ru parity. Operator brand-fit ack 2026-05-20 "all good" on the empirical load. - SPEC §10 acceptance criteria: #1. ### Performance & Security - [ ] **REQ-archive-export-latency**: From the moment the user clicks the export button, the ZIP archive lands in the "Downloads" folder in under 5 seconds. Binding: CON-archive-export-latency. - SPEC §10 acceptance criteria: #6. - [ ] **REQ-password-confidentiality**: Passwords do not appear in rrweb snapshots OR the user event log. Masking is enforced via rrweb v2 `maskInputFn` AND explicit value filtering in the event logger for password fields. Binding: CON-sensitive-data-masking. - SPEC §10 acceptance criteria: #8. ## v2 Requirements Deferred to a future phase per SPEC §9 ("Что НЕ входит в Фазу 1"). Tracked but not in current roadmap. ### Server & Diagnostics - **SRV-01**: Upload captured archives to a remote server. - **SRV-02**: AI-driven diagnostics of captured sessions. - **SRV-03**: Automatic ticket creation from captured reports. - **SRV-04**: Analytics dashboard summarising captured sessions. ### Capture - **CAP-01**: Audio recording in addition to video. ## Out of Scope Explicitly excluded in Phase 1. Documented to prevent scope creep. | Feature | Reason | |---------|--------| | Server upload | SPEC §9 — Phase 2 work. Phase 1 is local-only via `chrome.downloads`. | | AI diagnostics | SPEC §9 — Phase 2 work. | | Automatic ticketing | SPEC §9 — Phase 2 work. | | Analytics dashboard | SPEC §9 — Phase 2 work. | | Audio recording | SPEC §9 — Phase 2 work. | | `chrome.storage` / IndexedDB persistence of rolling buffers | CON-buffer-storage — buffers are in-memory only in Phase 1. | | Recording inactive tabs | CON-tab-capture-binding — `chrome.tabCapture` is active-tab-bound by design. | ## Phase 1 Acceptance Criteria (SPEC §10 verbatim) For traceability, all SPEC §10 acceptance criteria are listed once here, each cross-referenced to its supporting REQ-* entries. The developer-facing success metric for the whole project is "all 9 pass". 1. The extension installs in Chrome without errors. → REQ-install-clean, REQ-manifest-permissions 2. The video buffer runs continuously on any tab. → REQ-video-ring-buffer 3. The buffer always contains no more than 30 seconds of video. → REQ-video-ring-buffer 4. rrweb records DOM events without errors on typical pages (forms, tables, modal windows). → REQ-rrweb-dom-buffer 5. The event log captures clicks, navigation, and network errors. → REQ-user-event-log 6. On button press, the archive is downloaded to "Downloads" in < 5 seconds. → REQ-archive-export-latency 7. The archive opens; `last_30sec.webm` plays back in a browser. → REQ-archive-layout, REQ-video-ring-buffer 8. Passwords do not appear in the log or rrweb snapshots. → REQ-password-confidentiality 9. Extension RAM consumption does not exceed 50 MB in the background. → CON-ram-ceiling (NFR, not a functional REQ). ## Traceability Which phase covers which requirement. See ROADMAP.md for phase details. | Requirement | Phase | Status | |-------------|-------|--------| | REQ-video-ring-buffer | Phase 1 | Complete 2026-05-20 (Plans 01-08 WebM remux + 01-14 monitorTypeSurfaces; verified via gsd-verifier audit; fixture `tests/fixtures/last_30sec.webm` ffprobe + ffmpeg dry-run GREEN; Chrome playback confirmed) | | REQ-rrweb-dom-buffer | Phase 2 (originally) → **Phase 3** (post-2026-05-20 re-phasing) | Pending (verification absorbed by smoke phase; UAT harness A24+ extension planned) | | REQ-user-event-log | Phase 2 (originally) → **Phase 3** (post-2026-05-20 re-phasing) | Pending (same verification context as REQ-rrweb-dom-buffer) | | REQ-password-confidentiality | Phase 2 (originally) → **Out of Scope (v1)** | DEFERRED per 2026-05-20 charter shift ("we don't care about privacy hardening. At least here.") — archive flow is internal-only (no external transmission); P0-5 password masking re-classified as Phase 4 optional hardening or v2 work | | REQ-popup-ui | Phase 3 (originally) → **Phase 2** (renumbered) | Pending (largely shipped via Plan 01-09 SAVE-only popup + Plan 01-12 i18n; residual gaps in Phase 2) | | REQ-screenshot-on-export | Phase 3 (originally) → **Phase 2** (renumbered) | Pending | | REQ-archive-layout | Phase 3 (originally) → **Phase 2** (renumbered) | Pending (substantively shipped via Plans 01-08 webm-remux + JSZip; verification in Phase 2) | | REQ-meta-json-schema | Phase 2 | Pending (implementation landed via Plan 02-03; harness validation deferred to Plan 02-04) | | REQ-archive-export-latency | Phase 3 (originally) → **Phase 2** (renumbered) | Pending | | REQ-manifest-permissions | Phase 3 (originally) → Phase 1 closure via Plan 01-12 i18n migration | Complete (2026-05-20 — manifest __MSG_*__ + default_locale='en' + 16 i18n keys per locale; permissions DEC-011 baseline unchanged; operator brand-fit ack) | | REQ-install-clean | Phase 4 (originally) → Phase 1 closure via Plan 01-12 design integration | Complete (2026-05-20 — fresh build + load unpacked clean; zero remote-font CSP errors; branded icons rendering; en+ru manifest:name resolution; operator brand-fit ack) | **Coverage:** - v1 requirements: 11 total - Mapped to phases: 10 (REQ-password-confidentiality deferred to Out of Scope v1 per 2026-05-20) - Unmapped: 0 ✓ - Out of Scope: 1 (REQ-password-confidentiality) **2026-05-20 re-phasing note:** Original Phase 2 ("Stabilize DOM + event-capture privacy") REMOVED entirely. REQ-rrweb-dom-buffer + REQ-user-event-log verification ABSORBED by new Phase 3 (SPEC §10 smoke + DOM/event-log). All subsequent phases renumbered: old 3 → new 2, old 4 → new 3, old 5 → new 4. Note on CON-ram-ceiling (SPEC §10 #9): tracked as a non-functional constraint verified in Phase 4 (smoke verification) rather than as a standalone functional REQ, per the intel synthesis. Phase 4 success criteria include the RAM-ceiling check. --- *Requirements defined: 2026-05-15* *Updated 2026-05-20 — REQ-meta-json-schema amended for Plan 02-03 (D-P2-02 + D-P2-03 8-field cutover: `url: string` → `urls: string[]`; new `schemaVersion: "2"` field; F2 empty-array permission). Traceability table entry flipped to "Pending (implementation landed via Plan 02-03; harness validation deferred to Plan 02-04)".* *Earlier update: 2026-05-20 — Plan 01-10 closure (welcome tab; first-install activation; canonical mark + canonical tokens + canonical chrome.i18n welcomeHero; 24/24 UAT GREEN; operator cycle-2 ack "All good"). Plan 01-10 introduced no new functional REQs; it consumed REQ-video-ring-buffer (already Complete via Plan 01-07) by adding the first-install operator-facing activation surface that complements the always-on capture pipeline. Phase 1 final functional plan delivered; final-closure marker flip pending (REQUIREMENTS / ROADMAP / STATE markers + optional /gsd-verify-work 1).* *Earlier update: 2026-05-20 — REQ-install-clean + REQ-manifest-permissions marked Complete on Plan 01-12 closure (design integration + manifest i18n + operator brand-fit ack)* *Earlier update: 2026-05-15 — REQ-video-ring-buffer marked Complete on Phase 1 (Plan 01-07) closure*