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).
388 lines
25 KiB
Markdown
388 lines
25 KiB
Markdown
# 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.
|
||
|
||
Phase 4 closure note (2026-05-26): ROADMAP SC #1 (SW state persistence — after
|
||
>5min idle + export, archive still contains non-empty video buffer)
|
||
empirically verified via Plan 04-08 A33 harness assertion. Spike re-run at
|
||
tests/uat/spike-a33-sw-persistence.ts produces videoSize=1,797,178 bytes
|
||
(1.8 MB) vs 8505-byte baseline; offscreen RAM-only `segments: Blob[]` at
|
||
src/offscreen/recorder.ts:91 architecturally sound (segments survive SW kill
|
||
structurally — POST-KILL probe count=3); previous Plan 04-04 SPIKE FAILED
|
||
outcome was test-methodology issue (canvas.captureStream invisible-source
|
||
throttling per Chrome bug 653548), not architectural. See
|
||
.planning/phases/04-harden-clean-up-optional/04-VERIFICATION.md
|
||
Per-Requirement Scorecard SC #1 row.
|
||
|
||
### DOM Capture
|
||
|
||
- [x] **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.
|
||
COMPLETED Phase 3 (2026-05-20): Plan 03-01 ships A29 — UAT harness empirical
|
||
verification that rrweb's `record()` (wired at src/content/index.ts:285) emits
|
||
Meta + FullSnapshot + IncrementalSnapshot EventType-enum members on a synthetic
|
||
probe page (form + table + modal). 4 EventType checks GREEN; rrweb/session.json
|
||
from the assembled archive contains > 0 events. Probe HTML in
|
||
tests/uat/extension-page-harness.html (NO textarea per rrweb 2.0.0-alpha.4
|
||
issue #1596). A29 GREEN: cc13f31. UAT harness 33/33 GREEN. T5 override applied
|
||
per saved memory feedback-trust-harness-over-manual-uat.md (harness coverage
|
||
canonical for SPEC §10 #4; operator UAT retired by explicit delegation).
|
||
VERIFICATION at .planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-VERIFICATION.md.
|
||
|
||
Phase 4 closure note (2026-05-26): A29 cs-injection-world rewrite + strict-
|
||
sentinel filter (Plan 04-03 commits 73eb9b6 + b341a71) — flake closed 5/5
|
||
PASS across consecutive UAT runs (was ~2/3 historical baseline per Plan
|
||
03-03 SUMMARY); iana.org-leftover flake CLOSED. driveA29 host-side strict-
|
||
sentinel filter requires IncrementalSource.Mutation + adds[*].node.textContent
|
||
containing 'a29-mutation-sentinel' (only our injection can produce). A29.2
|
||
strict-sentinel = PRIMARY check; A29.3 (Meta) + A29.4 (FullSnapshot) preserved
|
||
as defense-in-depth. UAT harness 33 → 36 GREEN end-of-Phase-4 (+A33 SW state
|
||
persistence via Plan 04-08; +A34 fetch+XHR network_error via Plan 04-05;
|
||
+A35 live-DOM inline-SVG via Plan 04-06 with 5 sub-checks incl. A35.5 light+
|
||
dark equality decouple-proof). See 04-VERIFICATION.md Cross-Cutting Hardening
|
||
Items row H2.
|
||
|
||
### Event Logging
|
||
|
||
- [x] **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.
|
||
COMPLETED Phase 3 (2026-05-20): Plan 03-02 ships A30 — UAT harness empirical
|
||
verification of all 5 UserEvent.type literal values (click, input, navigation,
|
||
js_error, network_error) via synthetic triggers injected through
|
||
chrome.scripting.executeScript ISOLATED-world into the content-script realm
|
||
on a fresh https://example.com probe tab (cs-injection-world pattern; works
|
||
around chrome-extension://-no-content-script per Chrome match-pattern spec).
|
||
6-check A30 GREEN (1 SAVE ack + 1 entry-present + 5 type-presence checks);
|
||
logs/events.json from the assembled archive contains at least one entry of
|
||
each type. A30 GREEN: 116432a. UAT harness 33/33 GREEN. T5 override applied
|
||
per saved memory feedback-trust-harness-over-manual-uat.md (harness coverage
|
||
canonical for SPEC §10 #5; operator UAT retired by explicit delegation).
|
||
§10 #8 (password-filter) covered by Plan 03-03 A31 (PARTIAL per D-P3-02
|
||
charter — REQ-password-confidentiality remains Out of Scope v1).
|
||
VERIFICATION at .planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-VERIFICATION.md.
|
||
|
||
Phase 4 closure note (2026-05-26): ROADMAP SC #2 (fetch + XHR network_error
|
||
empirical capture) CLOSED via Plan 04-05 (A34 commits a20372a + 0712c24) —
|
||
cs-injection-world fires fetch(404) + XMLHttpRequest(404) from a probe tab
|
||
on https://example.com; driveA34 host-side JSZip-parses logs/events.json
|
||
and confirms 2 network_error entries with meta.status === 404 (skip-mode
|
||
UAT 35/35 GREEN; A34 real ~25s; all 6 sub-checks PASS — A34.1 SAVE ack +
|
||
A34.0a events.json present + A34.2 fetch entry + A34.3 XHR entry + A34.4
|
||
fetch meta.status===404 + A34.5 XHR meta.status===404).
|
||
Plan 04-01 P1 #11 fetch URL extraction fix validated end-to-end via A34.4 —
|
||
the fetch network_error entry's target carries the real URL
|
||
(`https://example.com/404-fetch-a34-<stamp>`) NOT the literal `[object Request]`
|
||
that the pre-fix `args[0]?.toString()` implicit coercion produced. Plan 04-01
|
||
P1 #14 navigation URL tracking (module-level `let previousUrl` at
|
||
src/content/index.ts:29) + P1 #15 rrweb timestamp normalization (Date.now()
|
||
at emit time at line 315) are unit-tested at tests/content/ (9 tests across
|
||
3 files in NEW tests/content/ directory). See 04-VERIFICATION.md
|
||
Per-Requirement Scorecard SC #2 row + Audit P1 Polish #11/#14/#15 rows.
|
||
|
||
### Export
|
||
|
||
- [x] **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.
|
||
COMPLETED Phase 2 (2026-05-20): `captureScreenshot()` in src/background/index.ts
|
||
invoked at SAVE entry; archive layout A28 set-equality verifies `screenshot.png`
|
||
presence in the zip (UAT harness 29/29 GREEN). Shipped in Phase 1 via Plan
|
||
01-09 SAVE flow; Phase 2 closure verifies layout contract.
|
||
|
||
- [x] **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.
|
||
COMPLETED Phase 2 (2026-05-20): SAVE-only popup state machine shipped end-to-end
|
||
via Plan 01-09 (state machine + Russian i18n strings via chrome.i18n.getMessage
|
||
with `|| <en-const>` fallback per Plan 01-12 pattern). Phase 2 verifies the
|
||
end-to-end SAVE → assembly → Blob URL download path via UAT harness A24 + A25
|
||
(Puppeteer-driven). 171/171 vitest GREEN.
|
||
|
||
- [x] **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.
|
||
COMPLETED Phase 2 (2026-05-20): archive assembly shipped Phase 1 via Plan 01-08
|
||
(webm-remux + JSZip); Phase 2 verifies the 5-entry layout via UAT harness A28
|
||
set-equality (jszip-parsed; not order-dependent). 29/29 UAT GREEN.
|
||
|
||
- [x] **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 `<specifics>`
|
||
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).
|
||
COMPLETED Phase 2 (2026-05-20): SessionMetadata in src/shared/types.ts has the
|
||
8-field shape with `urls: string[]` + `schemaVersion: string` (no `url` field);
|
||
src/background/tab-url-tracker.ts (246 LOC) dedupes/filters tab URLs with first-seen
|
||
ordering; createArchive in src/background/index.ts emits all 8 fields with
|
||
`schemaVersion: '2'`. Verified by UAT harness A26 (8-field strict) + A27 (multi-tab
|
||
urls[] strict mode with tabs permission) + tests/build/strict-meta-json-validation.test.ts
|
||
(8 tests) + tests/background/meta-json-urls-schema.test.ts (5 tests).
|
||
|
||
### Manifest & Install
|
||
|
||
- [x] **REQ-manifest-permissions**: `manifest.json` declares exactly the
|
||
permission set in DEC-011 + Amendment 1 (`desktopCapture` per D-01,
|
||
`activeTab`, `tabs` per Amendment 1, `downloads`, `scripting`, `storage`,
|
||
`offscreen`, `notifications`; `host_permissions: ["<all_urls>"]`) and requests
|
||
a user gesture for `desktopCapture` via getDisplayMedia on activation.
|
||
Binding: DEC-011 + Amendment 1 (added `tabs` per Phase 2 D-P2-02 meta.urls
|
||
requirement 2026-05-20), CON-manifest-permissions.
|
||
Phase 2 verification (2026-05-20): manifest.json permissions array intact incl.
|
||
`tabs` entry (tests/i18n/manifest-i18n.test.ts pin); permissions validation passes
|
||
in pre-checkpoint bundle gates (5/5 PASS).
|
||
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.
|
||
|
||
Phase 4 closure note (2026-05-26): ROADMAP SC #3 (generate-icons ESM/CJS
|
||
compatibility under package.json type:module) + SC #4 (dead-code grep —
|
||
permissions.request absence) both CLOSED via Plan 04-02 (commit f251297).
|
||
SC #3 closure: `git mv generate-icons.js generate-icons.cjs` (Node 14+
|
||
treats .cjs as CJS regardless of package.json type:module per
|
||
nodejs.org/api/packages.html#determining-module-system); `node
|
||
generate-icons.cjs` exits 0; `npm run build` exits 0. SC #4 closure:
|
||
tests/build/dead-code-grep.test.ts regression-pins `permissions.request`
|
||
absence in src/. ALSO: Plan 04-02 4-mechanism layered CSP-hardening
|
||
mitigation flipped SW chunk `new Function` polarity 1 → 0 (closes Plan
|
||
01-12 Wave 7 setimmediate polyfill deferred-items entry end-to-end);
|
||
pre-checkpoint bundle gates 6/6 PASS at every Phase 4 checkpoint boundary;
|
||
NEW Tier-2 production-bundle filename-leak gate added by Plan 04-08
|
||
(verifies 0 hits of `synthetic-display-source` in dist/). See
|
||
04-VERIFICATION.md Per-Requirement Scorecard SC #3 + SC #4 rows + Cross-
|
||
Cutting Hardening Items rows H1/H3/H4.
|
||
|
||
### Performance & Security
|
||
|
||
- [x] **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.
|
||
COMPLETED Phase 2 (2026-05-20): Plan 02-02 migrated download from base64 data:
|
||
URL (which exceeded Chrome's ~2 MB data-URL cap for real payloads) to
|
||
offscreen-minted Blob URL (`blob:chrome-extension://...`) via
|
||
`URL.createObjectURL` per D-P2-01 (closes audit P0-6). chrome.downloads.onChanged
|
||
listener revokes the URL on state.current==='complete' | 'interrupted'.
|
||
Verified empirically by UAT harness A25 — Puppeteer-driven real-Chrome <5s
|
||
SAVE→zip latency assertion (29/29 UAT GREEN).
|
||
|
||
- [ ] **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) | Complete 2026-05-20 (Phase 3 Plan 03-01 A29 GREEN — 4 EventType-enum checks against rrweb/session.json from probe-HTML-driven archive; UAT harness 33/33 GREEN; T5 override per saved memory feedback-trust-harness-over-manual-uat.md) |
|
||
| REQ-user-event-log | Phase 2 (originally) → **Phase 3** (post-2026-05-20 re-phasing) | Complete 2026-05-20 (Phase 3 Plan 03-02 A30 GREEN — 5 UserEvent.type presence checks against logs/events.json via cs-injection-world pattern; UAT harness 33/33 GREEN; T5 override per saved memory feedback-trust-harness-over-manual-uat.md) |
|
||
| 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-26 — Phase 4 closure (executor-created aggregator at .planning/phases/04-harden-clean-up-optional/04-VERIFICATION.md; pending independent gsd-verifier audit + Phase 4 row + completed_phases marker flips). Phase 4 introduced NO new REQs but added verification status notes to REQ-video-ring-buffer (ROADMAP SC #1 via Plan 04-08), REQ-rrweb-dom-buffer (A29 cs-injection-world rewrite via Plan 04-03), REQ-user-event-log (ROADMAP SC #2 + audit P1 #11/#14/#15 via Plan 04-05 + Plan 04-01), REQ-install-clean (ROADMAP SC #3 + SC #4 + Plan 04-02 build hygiene + Plan 04-08 Tier-2 leak gate). UAT harness 33 → 36 GREEN (+A33 + A34 + A35); vitest 171 → 188 GREEN (+17); pre-checkpoint bundle gates 6/6 PASS (Gate 2 polarity flipped 1 → 0); Tier-1 FORBIDDEN_HOOK_STRINGS unchanged at 12; NEW Tier-2 production-bundle filename-leak gate; 3 /gsd-debug sessions documented; operator-empirical ack 2026-05-26 "Confirmed fixed — close Plan 04-06".*
|
||
*Earlier update: 2026-05-20 — Phase 3 closed (REQ-rrweb-dom-buffer + REQ-user-event-log marked Complete via gsd-verifier Phase 3 aggregator; §10 #8 PARTIAL per D-P3-02 + A31 GREEN existing-minimum verification; §10 #9 awaits operator chrome://memory-internals per D-P3-04 + A32 informational scaffolding shipped; UAT harness 29 → 33 GREEN; T5 overrides applied for §10 #4/#5/#8 PARTIAL per saved memory feedback-trust-harness-over-manual-uat.md). VERIFICATION.md at .planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-VERIFICATION.md.*
|
||
*Earlier update: 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*
|