# Constraints (synthesized from SPEC) All constraints below are sourced from `Тз расширение фаза1.md` (the SPEC, precedence 0). The DOC (`README.md`, precedence 1) is a confirming source where noted; where it diverges, the SPEC takes precedence per the `ADR > SPEC > PRD > DOC` rule. Type taxonomy: - `nfr` — non-functional requirement (performance, memory, latency, security) - `protocol` — wire/file format or sequence contract - `schema` — data structure contract - `api-contract` — external API binding (Chrome extension APIs) --- ## CON-ram-ceiling - Source: `Тз расширение фаза1.md` §10 (acceptance criterion 9) - Type: nfr - Constraint: The extension's RAM footprint MUST NOT exceed **50 MB** while running in the background. - Component-level expected breakdown (SPEC §4, informative, not binding): - Video ring buffer: ~1.5–2 MB steady - rrweb buffer: ~1–3 MB - Event log: ~100–300 KB - Total steady-state expected component sum: ~2.6–5.3 MB - DOC confirming source: `README.md` §"Критерии приёмки Фазы 1" — restates the 50 MB ceiling identically. - DOC informational target: `README.md` §"Память" reports an expected steady-state of ~5–10 MB. This is a non-binding **estimate**, not a contradicting requirement; the binding ceiling remains 50 MB. See `INGEST-CONFLICTS.md` for the auto-resolved INFO entry. --- ## CON-archive-export-latency - Source: `Тз расширение фаза1.md` §10 (acceptance criterion 6) - Type: nfr - Constraint: From click to file landing in the Downloads folder MUST be **< 5 seconds**. - DOC confirming source: `README.md` §"Критерии приёмки Фазы 1". --- ## CON-video-window - Source: `Тз расширение фаза1.md` §4.1 - Type: nfr / protocol - Constraint: The video ring buffer MUST hold **exactly the most recent 30 seconds** of footage; older chunks are evicted after each new chunk arrives. - Exception (DEC-009): the first chunk (WebM header) is exempt from eviction. --- ## CON-rrweb-window - Source: `Тз расширение фаза1.md` §4.2, §8 - Type: nfr / protocol - Constraint: rrweb events MUST be retained for **at most 10 minutes** AND **at most 5 000 events**, whichever is tighter. Eviction sweep runs every 60 s on the time dimension; the 5 000-event cap is enforced on insert (oldest first out). --- ## CON-event-log-window - Source: `Тз расширение фаза1.md` §4.3 - Type: nfr / protocol - Constraint: The user event log MUST be retained for **at most 10 minutes**. --- ## CON-video-codec - Source: `Тз расширение фаза1.md` §4.1 - Type: protocol - Constraint: Video chunks MUST be encoded as `video/webm; codecs=vp9` at a target bitrate of `400 000 bps` (~3 MB/min raw). Chunk cadence (MediaRecorder timeslice) is `2000 ms`. --- ## CON-webm-header-retention - Source: `Тз расширение фаза1.md` §4.1, §8 - Type: protocol - Constraint: The first MediaRecorder chunk (WebM container header) MUST be retained in the buffer indefinitely; the assembled `last_30sec.webm` MUST remain playable in a browser. --- ## CON-tab-capture-binding - Source: `Тз расширение фаза1.md` §8 - Type: api-contract - Constraint: `chrome.tabCapture` operates only on the active tab. On tab activation change, the recorder MUST re-attach to the new active tab. First invocation requires a user gesture. ### RETIRED (Phase 01-stabilize-video-pipeline, 2026-05-15) - RETIRED-BY: Phase 01 CONTEXT.md D-01 / D-A2 - Reason: This phase replaces `chrome.tabCapture` with `navigator.mediaDevices.getDisplayMedia()`. The new API is not active-tab-bound; the recorder captures a screen / window selected once via Chrome's native picker and continues across tab switches. - Replacement: CON-display-capture-binding (below). --- ## CON-service-worker-keepalive - Source: `Тз расширение фаза1.md` §8 - Type: api-contract - Constraint: MV3 Service Workers unload after ~30 s of inactivity. The extension MUST keep the worker alive via a `chrome.alarms` alarm firing every **20 seconds**. ### RETIRED (Phase 01-stabilize-video-pipeline, 2026-05-15) - RETIRED-BY: Phase 01 CONTEXT.md D-17 / D-A2 - Reason: This phase replaces alarms-driven keepalive with a long-lived `chrome.runtime.connect` port between offscreen and Service Worker. Port-message traffic resets the SW idle timer per Chrome 110+ semantics. - Replacement: CON-display-capture-binding (binds the port-keepalive expectations alongside the new capture API). --- ## CON-manifest-permissions - Source: `Тз расширение фаза1.md` §7 - Type: api-contract / schema - Constraint: `manifest.json` MUST declare exactly: ```json { "permissions": [ "tabCapture", "activeTab", "downloads", "scripting", "storage" ], "host_permissions": [ "" ] } ``` --- ## CON-sensitive-data-masking - Source: `Тз расширение фаза1.md` §4.2, §8 - Type: nfr (security / privacy) - Constraint: Sensitive input fields MUST be masked in both rrweb snapshots and the event log. Specifically: - `input[type=password]` — value NEVER recorded; element MUST be masked in rrweb via `maskInputSelector`. - Any element with `data-sensitive="true"` — masked in rrweb via `maskInputSelector`. - The event logger MUST filter `input` events to drop password field values. --- ## CON-archive-layout - Source: `Тз расширение фаза1.md` §6 - Type: schema (file layout) - Constraint: The exported ZIP MUST follow the layout in REQ-archive-layout (verbatim, four top-level entries: `video/`, `rrweb/`, `logs/`, `screenshot.png`, `meta.json`). Filename pattern: `session_report_YYYY-MM-DD_HH-MM-SS.zip`. --- ## CON-meta-json-schema - Source: `Тз расширение фаза1.md` §6 - Type: schema - Constraint: `meta.json` MUST conform to the verbatim schema in REQ-meta-json-schema. All listed fields are required. --- ## CON-event-log-schema - Source: `Тз расширение фаза1.md` §4.3 - Type: schema - Constraint: Each entry in `events.json` MUST conform to: ```json { "timestamp": , "type": "click | input | navigation | error | network", "target": "", "value": "", "url": "", "meta": {} } ``` --- ## CON-buffer-storage - Source: `Тз расширение фаза1.md` §2 - Type: nfr - Constraint: All Phase 1 buffers MUST live in memory only (Service Worker for video, Content Script for rrweb + event log). `chrome.storage` is permitted but MUST NOT be used to persist the rolling buffers. --- ## CON-display-capture-binding - Source: Phase 01 CONTEXT.md D-01..D-17, RESEARCH.md Patterns 1 & 5 - Type: api-contract - Constraint: Video capture uses `navigator.mediaDevices.getDisplayMedia()` invoked once per session from the offscreen document with `chrome.offscreen.Reason.DISPLAY_MEDIA`. The Service Worker is kept alive by a long-lived `chrome.runtime.connect({ name: 'video-keepalive' })` port opened by the offscreen, with traffic in both directions at a minimum cadence of 25 s and pre-emptive reconnect at 290 s. - Replaces: CON-tab-capture-binding (RETIRED), CON-service-worker-keepalive (RETIRED). - UX trade-off: Chrome's permanent "Sharing your screen" indicator is shown while recording. SPEC §1 silent-operation property is intentionally relaxed. --- ## CON-no-server-upload - Source: `Тз расширение фаза1.md` §9 - Type: nfr (scope boundary) - Constraint: Phase 1 MUST NOT transmit any captured data to a remote server. All export is local-only via `chrome.downloads`.