Files
mokosh/.planning/intel/constraints.md
Mark fb88830d29 docs(01-01): retire 2 constraints + add CON-display-capture-binding per D-A2
Append RETIRED blocks to CON-tab-capture-binding and
CON-service-worker-keepalive (the two SPEC-derived constraints that are
no longer valid under getDisplayMedia + port-keepalive). Add new
CON-display-capture-binding consolidating the replacement contract.
Originals stay intact for provenance; RETIRED is appended below each.
2026-05-15 17:14:15 +02:00

227 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.52 MB steady
- rrweb buffer: ~13 MB
- Event log: ~100300 KB
- Total steady-state expected component sum: ~2.65.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 ~510 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": [
"<all_urls>"
]
}
```
---
## 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": <epoch_ms>,
"type": "click | input | navigation | error | network",
"target": "<css_selector>",
"value": "<value_or_masked>",
"url": "<page_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`.