Files
mokosh/.planning/PROJECT.md
Mark 5d0b40c9b6 docs(04-07): closure markers — REQUIREMENTS + ROADMAP + STATE + PROJECT for Phase 4 v1 close-prep
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).
2026-05-26 14:08:17 +02:00

17 KiB
Raw Permalink Blame History

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

Validated in Phase 1 (closed 2026-05-20 via verifier audit GREEN 17/17 must-haves):

  • Continuous 30 s whole-desktop video ring buffer (REQ-video-ring-buffer; D-13 restart-segments)
  • Exact manifest permission set per SPEC §7 + DEC-011 Amendment 1 (REQ-manifest-permissions)
  • 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):

  • One-shot screenshot at export time (REQ-screenshot-on-export; A28 archive layout)
  • Russian-language popup with SAVE-only state machine (REQ-popup-ui; A24 + A25)
  • ZIP archive layout session_report_YYYY-MM-DD_HH-MM-SS.zip with 5-entry shape (REQ-archive-layout; A28 set-equality)
  • meta.json 8-field schema with urls: string[] + schemaVersion: '2' per D-P2-02 + D-P2-03 (REQ-meta-json-schema; A26 + A27)
  • 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):

  • 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)
  • 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)
  • 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):

  • 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)
  • 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)
  • 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)
  • 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).
  • 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
  • /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)
  • 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

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

  • 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 ~310 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

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.