Task 2 of Plan 04-07 — 4 marker file flips landing Phase 4 closure-prep (NOT formal Phase 4 closure; that happens at the ceremony AFTER the independent gsd-verifier audit per Phase 1-3 precedent). ROADMAP.md: - Plan 04-07 row flipped [ ] → [x] with full closure annotation (04-VERIFICATION.md citation + Phase 4 cumulative totals + D-P4-05 backfill verification + closure- ceremony deferral note) - Phase 4 progress table cell updated 7/8 → 8/8 with full closure-prep narrative - Phase 4 row [ ] LEFT UNFLIPPED — verifier audit + closure ceremony flips it STATE.md: - progress.completed_plans: 29 → 30 + progress.percent: 93 → 97 - progress.completed_phases: 3 (UNCHANGED) + status: executing (UNCHANGED) - stopped_at + last_updated + last_activity updated for Plan 04-07 closure - Current Position block updated to reflect Plan 04-07 completion + pending closure ceremony - Plan 04-07 closure section added at top of body - Performance metrics row added for Phase 04 P07 - Session Continuity entry prepended for Plan 04-07 - 2 Phase 04-07 decisions appended to Decisions list REQUIREMENTS.md: - 4 Phase 4 closure notes appended to existing REQ blocks (no existing REQ-* lines modified): - REQ-video-ring-buffer: ROADMAP SC #1 via Plan 04-08 (methodology reframe) - REQ-rrweb-dom-buffer: A29 cs-injection-world + UAT 33→36 GREEN summary - REQ-user-event-log: ROADMAP SC #2 via Plan 04-05 + audit P1 #11/#14/#15 via Plan 04-01 - REQ-install-clean: ROADMAP SC #3/SC #4/Plan 04-02 build hygiene + Plan 04-08 Tier-2 leak gate - Trailing footer line updated with 2026-05-26 Phase 4 closure citation PROJECT.md: - NEW Validated in Phase 4 section added (7 bullets covering all closures) - Active section evolved from Phase 4 backlog → Phase 4 closure-ceremony workstream + Deferred-to-v1.1/v2 maintenance milestone items - Trailing footer line updated with 2026-05-26 Phase 4 closure citation Acceptance criteria gates (all PASS per Plan 04-07 Task 2): - ROADMAP.md 04-07 row [x] = 1 - ROADMAP.md Phase 4 row [x] = 0 (correctly LEFT unflipped) - STATE.md completed_phases: 3 = 2 (frontmatter + body — UNCHANGED per spec) - STATE.md completed_plans: 30 = 1 (incremented by 1) - STATE.md status: executing = 1 (UNCHANGED per spec) - REQUIREMENTS.md "Phase 4 closure note" mentions = 4 (>= 3) - PROJECT.md "Validated in Phase 4" section = 1 - git diff --stat HEAD~1 HEAD shows only .planning/ files dirty (T-04-07-02 threat mitigation gate honored — docs-only commit; no source/test changes) Phase 4 row + completed_phases bump + status:completed flip explicitly DEFERRED to closure ceremony after the independent gsd-verifier audit per Phase 1-3 precedent (executor creates VERIFICATION.md; verifier independently re-validates with goal-backward audit; orchestrator flips markers post-verifier-audit).
191 lines
17 KiB
Markdown
191 lines
17 KiB
Markdown
# Mokosh
|
||
|
||
## What This Is
|
||
|
||
Mokosh is a Chrome Manifest V3 browser extension that silently and continuously
|
||
records an operator's browser session — the last 30 seconds of active-tab video,
|
||
the last 10 minutes of DOM events (via rrweb), and the last 10 minutes of user
|
||
and runtime events — and, on a single button press, packages everything plus a
|
||
screenshot into a self-contained ZIP delivered to the user's "Downloads" folder
|
||
for handoff to support.
|
||
|
||
The name is taken from Mokosh (Мокошь), the Slavic goddess of fate and weaving:
|
||
each operator session is a thread she weaves into the archive.
|
||
|
||
## Core Value
|
||
|
||
When an operator hits a bug, one click MUST produce a self-contained archive
|
||
that lets support reproduce what happened — in under five seconds, with no
|
||
server involved, and with the operator's passwords never appearing in the
|
||
output.
|
||
|
||
## Requirements
|
||
|
||
### Validated
|
||
|
||
<!-- Shipped and confirmed valuable. -->
|
||
|
||
**Validated in Phase 1 (closed 2026-05-20 via verifier audit GREEN 17/17 must-haves):**
|
||
- [x] Continuous 30 s whole-desktop video ring buffer (REQ-video-ring-buffer; D-13 restart-segments)
|
||
- [x] Exact manifest permission set per SPEC §7 + DEC-011 Amendment 1 (REQ-manifest-permissions)
|
||
- [x] Extension installs unpacked into Chrome without errors (REQ-install-clean)
|
||
|
||
**Validated in Phase 2 (closed 2026-05-20 via verifier audit PASSED 5/5 must-haves; T5 override per saved memory):**
|
||
- [x] One-shot screenshot at export time (REQ-screenshot-on-export; A28 archive layout)
|
||
- [x] Russian-language popup with SAVE-only state machine (REQ-popup-ui; A24 + A25)
|
||
- [x] ZIP archive layout `session_report_YYYY-MM-DD_HH-MM-SS.zip` with 5-entry shape (REQ-archive-layout; A28 set-equality)
|
||
- [x] `meta.json` 8-field schema with `urls: string[]` + `schemaVersion: '2'` per D-P2-02 + D-P2-03 (REQ-meta-json-schema; A26 + A27)
|
||
- [x] Click-to-SAVE latency < 5 s via Blob URL pipeline per D-P2-01 (REQ-archive-export-latency; A25 closes audit P0-6)
|
||
|
||
**Validated in Phase 3 (closed 2026-05-20 via verifier audit PASSED 5/5 ROADMAP + 9/9 SPEC §10 acceptance criteria; 4 overrides incl. §10 #9 user ack):**
|
||
- [x] 10 min / 5 000-event rrweb DOM buffer (REQ-rrweb-dom-buffer; A29 harness coverage verifies DOM events captured without errors on probe HTML — form + table + modal; masking deferred per DEC-004 Amendment + charter shift)
|
||
- [x] 10 min user/runtime event log (REQ-user-event-log; A30 harness coverage verifies all 5 UserEvent types — click + input + navigation + js_error + network_error; password filtering verified via A31 PARTIAL per D-P3-02 charter)
|
||
- [x] SPEC §10 full acceptance criteria sweep #1-#9 — Phase 1 (§10 #1/#2/#3/#7) + Phase 2 (§10 #6) + Phase 3 (§10 #4/#5/#8 PARTIAL/#9 best-effort) — 03-VERIFICATION.md aggregates evidence with T5 override pattern
|
||
|
||
**Validated in Phase 4 (closed 2026-05-26 via executor-created aggregator 04-VERIFICATION.md; pending independent gsd-verifier audit + closure-ceremony marker flips):**
|
||
- [x] All 4 ROADMAP success criteria CLOSED (SC #1 SW state persistence via Plan 04-08 methodology reframe — HTMLVideoElement.captureStream replaces canvas.captureStream; 1.8 MB videoSize vs 8505 baseline; SC #2 fetch + XHR network_error empirical via Plan 04-05 A34 — 2 entries with meta.status===404; SC #3 generate-icons ESM/CJS via Plan 04-02 `git mv .js → .cjs`; SC #4 dead-code grep via Plan 04-02 tests/build/dead-code-grep.test.ts regression pin)
|
||
- [x] All 3 audit P1 polish items CLOSED (P1 #11 fetch URL extraction + P1 #14 navigation URL tracking + P1 #15 rrweb timestamp normalization — all via Plan 04-01 D-P4-02 single dedicated TDD plan; src/content/index.ts surgical edits + 9 unit tests at NEW tests/content/ directory)
|
||
- [x] All 6 cross-cutting hardening items GREEN (setimmediate polyfill 4-mechanism mitigation via Plan 04-02; A29 cs-injection-world rewrite via Plan 04-03 — 5/5 PASS stress vs ~2/3 historical; cursor visibility regression-pinned via Plan 04-06 — shipped opportunistically by Plan 01-09; dark-surface logo contrast via Plan 04-06 — currentColor + DOMParser inline-SVG + NEW `--mks-mark-stroke` brand-component token decoupled from theme-flipping `--mks-fg-inverse` semantic token)
|
||
- [x] D-P4-02 + D-P4-03 + D-P4-05 charters CLOSED (D-P4-02 all 3 audit P1 polish items via Plan 04-01; D-P4-03 both visual polish items via Plan 04-06; D-P4-05 ROADMAP backfill verification for Plans 01-08..01-14 via Plan 04-07). D-P4-01 + D-P4-04 honored throughout (D-P4-01 full Phase 4 scope; D-P4-04 alpha out-of-band).
|
||
- [x] Cross-cutting gates: UAT harness 33 → 36 GREEN (+A33 + A34 + A35 with 5 sub-checks incl. A35.5 light+dark equality decouple-proof); vitest 171 → 188 GREEN (+17 tests across Plans 04-01/02/06/08); pre-checkpoint bundle gates 6/6 PASS (Gate 2 polarity flipped 1 → 0 via Plan 04-02 — closes Plan 01-12 Wave 7 setimmediate deferred-items entry end-to-end); Tier-1 FORBIDDEN_HOOK_STRINGS unchanged at 12; NEW Tier-2 production-bundle filename-leak gate added by Plan 04-08
|
||
- [x] /gsd-debug sessions: 3 documented + resolved (canvas-throttling sessions 1+2 → REFUTED-architecture verdict authorizing Plan 04-08 insertion; Plan 04-06 dark-mode mark decoupling → fix at commit a8bcc17; A33.1 SAVE-ack race → fix at commit 7e0da63)
|
||
- [x] Operator-empirical ack 2026-05-26 verbatim "Confirmed fixed — close Plan 04-06" (Plan 04-06 Task 4 cycle-2 after debug-fix; canonical aesthetics-judgment-is-non-automatable case per `feedback-trust-harness-over-manual-uat.md`)
|
||
|
||
### Active
|
||
|
||
<!-- Current scope. Building toward these. See REQUIREMENTS.md for IDs. -->
|
||
|
||
**Phase 4 closure ceremony (post Plan 04-07):**
|
||
- Independent gsd-verifier audit of `.planning/phases/04-harden-clean-up-optional/04-VERIFICATION.md` (Phase 1-3 precedent — verifier re-validates executor-created aggregator with goal-backward audit)
|
||
- ROADMAP.md Phase 4 row `[ ]` → `[x]` flip + CLOSED 2026-05-26 annotation
|
||
- STATE.md `progress.completed_phases: 3 → 4` + `progress.percent: 97 → 100` + `status: executing → completed` flip
|
||
- v1.0 tag + release notes + alpha redistribution (separate workstream per D-P4-04 charter — user-routed out-of-band)
|
||
|
||
**Deferred to v1.1 / v2 maintenance milestones:**
|
||
- rrweb 2.0.0-alpha.4 → stable v2 upgrade (D-P3-03 + D-P4-01 charter; alpha-pin stable across all 31 plans + 36/36 UAT GREEN)
|
||
- Programmatic SW-context RAM measurement via chrome.devtools.Memory API (D-P3-04 + D-P4-01 charter; A32 best-effort + chrome://memory-internals + alpha distribution coverage accepted)
|
||
- REQ-password-confidentiality v2 candidate (D-P3-02 charter shift 2026-05-20 — only revisit if charter reverses on "we don't care about privacy hardening")
|
||
- A29/A30/A31 cs-injection-world flake family (intermittent in full-suite runs; A29 specifically CLOSED via Plan 04-03 strict-sentinel; A30/A31 NOT in Plan 04-03 charter)
|
||
- 04-CONTEXT #9/#10 parallel-vitest ffprobe-timeout flake family (true clean baseline corrected to 188/188 GREEN; canonical Vitest mitigation: poolOptions.threads.singleThread:true OR raised testTimeout)
|
||
|
||
### Out of Scope
|
||
|
||
<!-- Explicit boundaries. Includes reasoning to prevent re-adding. -->
|
||
|
||
- Server upload of captured data — SPEC §9; reserved for Phase 2.
|
||
- AI-driven diagnostics — SPEC §9; reserved for Phase 2.
|
||
- Automatic ticket creation — SPEC §9; reserved for Phase 2.
|
||
- Analytics dashboard — SPEC §9; reserved for Phase 2.
|
||
- Audio recording — SPEC §9; reserved for Phase 2.
|
||
- Persisting rolling buffers to `chrome.storage` / IndexedDB — CON-buffer-storage;
|
||
buffers are in-memory only in Phase 1.
|
||
|
||
## Context
|
||
|
||
- **Source documents:** Russian-authored SPEC (`Тз расширение фаза1.md`) and a
|
||
Russian-authored README. All user-facing UI strings ("Сохранить отчёт об
|
||
ошибке", "Последние 30 сек видео + 10 мин лога", "Сохраняю...", "Готово! ✓")
|
||
are part of the contract and MUST be preserved verbatim. Section identifiers
|
||
and code use Latin script.
|
||
- **Codebase state:** A partially-broken first attempt at the SPEC already
|
||
exists under `src/` (background service worker, content script, popup) and
|
||
`offscreen/`. An external audit identified 7 P0 defects that prevent SPEC §10
|
||
acceptance. Phase 1 of this roadmap is remediation against the SPEC, not
|
||
greenfield. See ROADMAP.md.
|
||
- **Operator context (SPEC §1):** Operators work inside a browser and
|
||
periodically make mistakes that are hard to diagnose after the fact. The
|
||
extension runs silently in the background; the operator only interacts with
|
||
it when they need to file a report.
|
||
- **Build toolchain (DOC-only):** Vite + the `crxjs` plugin in TypeScript. The
|
||
SPEC does not prescribe a build tool, so this is auto-overridable by a future
|
||
ADR/SPEC.
|
||
|
||
## Constraints
|
||
|
||
- **Performance**: Click-to-archive-on-disk < 5 s (CON-archive-export-latency,
|
||
SPEC §10 #6) — drives synchronous Blob assembly and avoidance of base64 data
|
||
URLs.
|
||
- **Memory**: Background RAM ceiling 50 MB (CON-ram-ceiling, SPEC §10 #9).
|
||
Expected steady-state is ~3–10 MB; the ceiling is a hard upper bound, not a
|
||
target.
|
||
- **Video format**: `video/webm; codecs=vp9` @ 400 000 bps, `MediaRecorder`
|
||
timeslice 2000 ms, single continuous recorder (CON-video-codec). The first
|
||
chunk (WebM header) MUST be retained indefinitely (CON-webm-header-retention,
|
||
DEC-009) — without it, the assembled file is not playable.
|
||
- **Buffer windows**: Video 30 s rolling, rrweb 10 min / 5 000 events whichever
|
||
is tighter, user-event log 10 min (CON-video-window, CON-rrweb-window,
|
||
CON-event-log-window).
|
||
- **Sensitive data**: ~~`input[type=password]` and `[data-sensitive="true"]` MUST
|
||
be masked in rrweb (via v2 `maskInputFn`) AND the event logger MUST drop
|
||
password field values (CON-sensitive-data-masking).~~ **DEFERRED 2026-05-20**
|
||
per charter shift ("we don't care about privacy hardening. At least here.").
|
||
Archive flow is internal-only (no external transmission); CON-sensitive-data-
|
||
masking re-classified as Phase 4 optional hardening or v2 work. Operator-
|
||
facing password masking remains a future polish item but is no longer v1-blocking.
|
||
- **Service Worker lifecycle**: MV3 SW unloads after ~30 s idle; a long-lived
|
||
`chrome.runtime.connect` port from offscreen to SW emits a PING every 25 s
|
||
to keep the SW alive (CON-display-capture-binding, AMENDED from
|
||
CON-service-worker-keepalive).
|
||
- **Tab capture binding**: REMOVED (CON-tab-capture-binding RETIRED). The new
|
||
`getDisplayMedia` binding (CON-display-capture-binding) is screen/window-
|
||
scoped, not tab-scoped, and survives tab switches without re-attach.
|
||
- **Manifest permissions**: ~~`tabCapture`, `activeTab`, `downloads`,
|
||
`scripting`, `storage`~~ **SUPERSEDED by DEC-011 Amendment 1 (2026-05-20).**
|
||
Current locked set: `desktopCapture`, `activeTab`, `tabs`, `downloads`,
|
||
`scripting`, `storage`, `offscreen`, `notifications`;
|
||
`host_permissions: ["<all_urls>"]` — exactly this set, no more, no less
|
||
(CON-manifest-permissions, post-Phase-01 retirement of `tabCapture` per
|
||
DEC-003 Amendment + addition of `desktopCapture` + `offscreen` +
|
||
`notifications`; Phase 2 Amendment 1 adds `tabs` per D-P2-02). See Key
|
||
Decisions table DEC-011 row for full provenance.
|
||
- **Storage strategy**: All Phase 1 rolling buffers live in memory only
|
||
(CON-buffer-storage). `chrome.storage` is permitted but MUST NOT be used to
|
||
persist rolling buffers.
|
||
- **Network**: No server upload in Phase 1 (CON-no-server-upload). All export
|
||
is local-only via `chrome.downloads`.
|
||
|
||
## Key Decisions
|
||
|
||
<!-- Decisions that constrain future work. All 12 below are SPEC-Accepted
|
||
acting as ADR-equivalents for Phase 1 per orchestrator instruction. They
|
||
are LOCKED for Phase 1: any change requires a formal ADR. None are
|
||
formally LOCKED in the ingest classification — a future ADR can revise
|
||
any of them, but Phase 1 implementation MUST treat them as locked. -->
|
||
|
||
| Decision | Rationale | Outcome | Status |
|
||
|----------|-----------|---------|--------|
|
||
| **DEC-001**: Chrome Extension Manifest V3 | SPEC §2, §7 — required for `chrome.tabCapture`, `chrome.downloads`, `chrome.alarms`. | — Pending | locked (Phase 1) |
|
||
| **DEC-002**: Service Worker as background coordinator | SPEC §2, §3, §8 — MV3 has no persistent background page; SW coordinates video buffer + archive packaging. | — Pending | locked (Phase 1) |
|
||
| **DEC-003**: Active video via `getDisplayMedia()` (vp9 / 400 kbps / 2000 ms) | AMENDED by Phase 01: SPEC §2/§4.1/§7 originally specified `chrome.tabCapture`; Phase 01 swaps to `getDisplayMedia` invoked in the offscreen document with `chrome.offscreen.Reason.DISPLAY_MEDIA`. Codec/bitrate/timeslice binding unchanged. See `.planning/intel/decisions.md` DEC-003 Amendment. | — Pending | locked (Phase 1, post-Amendment) |
|
||
| **DEC-004**: DOM capture via rrweb with 5 000-event cap. ~~`maskInputSelector` masking~~ DEFERRED 2026-05-20 — `maskInputSelector` was rrweb 1.x; v2.0.0-alpha.4 requires `maskInputFn`. Per 2026-05-20 charter shift, masking deferred to Phase 4 (optional) or v2; AMENDED to "rrweb 5000-event cap; masking deferred". | SPEC §2, §4.2 — rrweb is the only mature DOM-recording option; cap is part of the memory contract; masking originally part of privacy contract (deferred). | — Pending | locked (Phase 1, post-Amendment) |
|
||
| **DEC-005**: Archive packaging via JSZip | SPEC §2, §3, §6 — only ZIP library bundled per SPEC. | — Pending | locked (Phase 1) |
|
||
| **DEC-006**: File download via `chrome.downloads` | SPEC §2, §5, §7 — no server upload in Phase 1 (SPEC §9). | — Pending | locked (Phase 1) |
|
||
| **DEC-007**: In-memory buffers only (no Phase 1 persistence) | SPEC §2, §4.1–§4.3 — rolling buffers in SW (video) and Content Script (rrweb + log). | — Pending | locked (Phase 1) |
|
||
| **DEC-008**: Screenshot via `chrome.tabs.captureVisibleTab` | SPEC §4.4, §5 — captured at export time, not continuously. | — Pending | locked (Phase 1) |
|
||
| **DEC-009**: WebM header chunk retained indefinitely | SPEC §4.1, §8 — WebM without its header is not playable. | — Pending | locked (Phase 1) |
|
||
| **DEC-010**: Service Worker keepalive via long-lived port | AMENDED by Phase 01: SPEC §8 originally specified `chrome.alarms` at 20 s; Phase 01 swaps to a `chrome.runtime.connect` port between offscreen and SW with 25 s ping cadence and 290 s pre-emptive reconnect. See `.planning/intel/decisions.md` DEC-010 Amendment. | — Pending | locked (Phase 1, post-Amendment) |
|
||
| **DEC-011**: Manifest permissions set | AMENDED 2026-05-20 (Amendment 1) by Plan 02-03: SPEC §7 originally specified `tabCapture`, `activeTab`, `downloads`, `scripting`, `storage` + `host_permissions: ["<all_urls>"]`. Phase 01 retired `tabCapture` (DEC-003 Amendment) and added `desktopCapture`, `offscreen`, `notifications`. Amendment 1 (2026-05-20) ADDS `tabs` to enable `chrome.tabs.get(tabId).url` + `chrome.tabs.query({})` for the Phase 2 D-P2-02 `meta.urls` feature (tab-url-tracker requires URL visibility beyond active-tab semantics). Current locked set: `desktopCapture`, `activeTab`, `tabs`, `downloads`, `scripting`, `storage`, `offscreen`, `notifications` + `host_permissions: ["<all_urls>"]`. Audit T-1-02 ("unused permissions expand attack surface") is acknowledged but overridden — the permission is genuinely USED by the meta.urls feature, so it is not unused. See `.planning/phases/02-stabilize-export-pipeline/02-CONTEXT.md` Revision Log. | — Pending | locked (Phase 1, post-Amendment 1) |
|
||
| **DEC-012**: Vite + crxjs + TypeScript build toolchain | README §"Технический стек" — DOC-level only; SPEC does not prescribe. | — Pending | locked (Phase 1) — auto-overridable by future ADR |
|
||
|
||
## Success Metric (Developer-Facing)
|
||
|
||
Phase 1 is "done" when all **9 SPEC §10 acceptance criteria** pass against an
|
||
unpacked load of the build into Chrome:
|
||
|
||
1. Extension installs in Chrome without errors.
|
||
2. Video buffer runs continuously on any tab.
|
||
3. Buffer never holds more than 30 s of footage.
|
||
4. rrweb records DOM events without errors on typical pages (forms, tables,
|
||
modals).
|
||
5. Event log captures clicks, navigation, and network errors.
|
||
6. Archive downloads to "Downloads" in < 5 s after button press.
|
||
7. Archive opens cleanly; `last_30sec.webm` plays back in a browser.
|
||
8. Passwords do not appear in the event log or rrweb snapshots.
|
||
9. Extension RAM consumption does not exceed 50 MB in the background.
|
||
|
||
The verbatim list lives in REQUIREMENTS.md under "Phase 1 Acceptance Criteria
|
||
(SPEC §10 verbatim)".
|
||
|
||
---
|
||
*Last updated: 2026-05-26 — Phase 4 closure aggregator created via Plan 04-07 (`.planning/phases/04-harden-clean-up-optional/04-VERIFICATION.md`; 253 lines; 4/4 ROADMAP SC + 3/3 audit P1 + 6/6 hardening items GREEN; UAT 36/36 + vitest 188/188 + 6/6 bundle gates + Tier-1=12 + NEW Tier-2; 3 /gsd-debug sessions; operator empirical ack "Confirmed fixed — close Plan 04-06" 2026-05-26). Phase 4 row [x] flip + completed_phases 3→4 + status:completed flip DEFERRED to closure ceremony after independent gsd-verifier audit (Phase 1-3 precedent). Prior: 2026-05-20 Phase 3 closure (verifier audit PASSED 5/5 ROADMAP + 9/9 SPEC §10 with 4 overrides); 2026-05-20 Phase 2 closure; 2026-05-15 initial bootstrap.*
|