436 lines
23 KiB
Markdown
436 lines
23 KiB
Markdown
---
|
|
phase: 01-stabilize-video-pipeline
|
|
plan: 01
|
|
type: execute
|
|
wave: 0
|
|
depends_on: []
|
|
files_modified:
|
|
- .planning/PROJECT.md
|
|
- .planning/REQUIREMENTS.md
|
|
- .planning/ROADMAP.md
|
|
- .planning/intel/decisions.md
|
|
- .planning/intel/constraints.md
|
|
- manifest.json
|
|
autonomous: true
|
|
scope_exception: "doc-text-only edits with no TypeScript compilation; cognitive load substantially lower than code plans of equal task count"
|
|
requirements:
|
|
- REQ-video-ring-buffer
|
|
requirements_addressed:
|
|
- REQ-video-ring-buffer
|
|
|
|
must_haves:
|
|
truths:
|
|
- "PROJECT.md DEC-003, DEC-010 reflect the getDisplayMedia + port-keepalive amendments"
|
|
- "REQUIREMENTS.md REQ-video-ring-buffer no longer says 'active-tab' and binds to getDisplayMedia"
|
|
- "ROADMAP.md Phase 1 Success Criterion #2 no longer references tab re-attach"
|
|
- "intel/decisions.md DEC-003 and DEC-010 carry an Amendment block"
|
|
- "intel/constraints.md CON-tab-capture-binding and CON-service-worker-keepalive are RETIRED with a CON-display-capture-binding added"
|
|
- "manifest.json permissions list contains desktopCapture (not tabCapture) and drops the now-unused alarms entry (D-05, D-A6)"
|
|
- "Every code-touching plan (02-07) sees a consistent doc baseline before it runs"
|
|
artifacts:
|
|
- path: ".planning/PROJECT.md"
|
|
provides: "Amended DEC-003 / DEC-010 rows and amended Constraints section"
|
|
contains: "getDisplayMedia"
|
|
- path: ".planning/REQUIREMENTS.md"
|
|
provides: "REQ-video-ring-buffer wording without 'active-tab' and bound to getDisplayMedia"
|
|
contains: "getDisplayMedia"
|
|
- path: ".planning/ROADMAP.md"
|
|
provides: "Phase 1 Success Criterion #2 with tab-reattach clause removed"
|
|
contains: "MediaRecorder"
|
|
- path: ".planning/intel/decisions.md"
|
|
provides: "DEC-003 and DEC-010 with Amendment blocks"
|
|
contains: "## Amendment"
|
|
- path: ".planning/intel/constraints.md"
|
|
provides: "RETIRED markers + new CON-display-capture-binding"
|
|
contains: "CON-display-capture-binding"
|
|
- path: "manifest.json"
|
|
provides: "Permission swap"
|
|
contains: "desktopCapture"
|
|
key_links:
|
|
- from: "manifest.json"
|
|
to: "intel/constraints.md"
|
|
via: "lockstep permission set"
|
|
pattern: "desktopCapture"
|
|
- from: "intel/decisions.md"
|
|
to: "PROJECT.md"
|
|
via: "Amendment block referenced from Key Decisions table"
|
|
pattern: "AMENDED"
|
|
---
|
|
|
|
<objective>
|
|
Doc-cascade for D-A1..D-A6 + manifest permission swap (D-05/D-A6). This is
|
|
Wave 0 work that MUST precede every code-touching plan in this phase so
|
|
downstream agents see a consistent baseline (DEC-003 amended to
|
|
`getDisplayMedia`, DEC-010 amended to port keepalive, manifest permissions
|
|
swapped to `desktopCapture`). Plan 01 makes zero code-runtime changes — only
|
|
text edits to planning docs and a single permissions edit in `manifest.json`.
|
|
|
|
Purpose: Phase 2 and later phases will read PROJECT.md / REQUIREMENTS.md /
|
|
ROADMAP.md to understand what was decided. Leaving them stale would carry the
|
|
old `chrome.tabCapture` contract forward and cause downstream agents to
|
|
silently re-introduce active-tab assumptions.
|
|
|
|
Output: Six amended doc files + the manifest permissions block in its final
|
|
Phase-1 shape.
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
|
</execution_context>
|
|
|
|
<context>
|
|
@.planning/PROJECT.md
|
|
@.planning/REQUIREMENTS.md
|
|
@.planning/ROADMAP.md
|
|
@.planning/intel/decisions.md
|
|
@.planning/intel/constraints.md
|
|
@.planning/phases/01-stabilize-video-pipeline/01-CONTEXT.md
|
|
@manifest.json
|
|
</context>
|
|
|
|
<threat_model>
|
|
## Trust Boundaries
|
|
|
|
| Boundary | Description |
|
|
|----------|-------------|
|
|
| extension manifest → Chrome runtime | Permissions block declares the API surface Chrome will grant; minimising this is the policy boundary |
|
|
|
|
## STRIDE Threat Register
|
|
|
|
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
|
|-----------|----------|-----------|-------------|-----------------|
|
|
| T-1-02 | Information Disclosure / over-privileged | `manifest.json` permissions array | mitigate | Drop `tabCapture` and `alarms` (no longer used); add `desktopCapture` (matches CONTEXT.md D-05 / D-A6). `host_permissions: ["<all_urls>"]` and `activeTab` retained — already justified by Phase 3 screenshot path. Grep gate: `grep -v '^#' manifest.json \| grep -c '"tabCapture"' == 0 && grep -v '^#' manifest.json \| grep -c '"desktopCapture"' == 1` |
|
|
|
|
(T-1-01 codec downgrade and T-1-04 port-hijack are addressed in Plans 03 and 04. T-1-03 stream-content-leakage is an accepted residual risk per CONTEXT.md D-04 — recorded in Plan 03's threat model.)
|
|
</threat_model>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Amend intel/decisions.md DEC-003 and DEC-010 (D-A1)</name>
|
|
<files>.planning/intel/decisions.md</files>
|
|
<read_first>
|
|
- .planning/intel/decisions.md (lines 48-60 DEC-003, lines 145-153 DEC-010)
|
|
- .planning/phases/01-stabilize-video-pipeline/01-CONTEXT.md §"Doc Amendments (precede code)" (D-A1)
|
|
</read_first>
|
|
<action>
|
|
Append an Amendment block to DEC-003 immediately AFTER line 59 (the `Confirming source` line). The amendment block reads VERBATIM:
|
|
|
|
```markdown
|
|
|
|
## Amendment (Phase 01-stabilize-video-pipeline, 2026-05-15)
|
|
|
|
- AMENDED-BY: Phase 01 CONTEXT.md D-01..D-05
|
|
- Replace `chrome.tabCapture.capture()` with `navigator.mediaDevices.getDisplayMedia()` called from the offscreen document.
|
|
- Offscreen document is created with `chrome.offscreen.Reason.DISPLAY_MEDIA` (replaces `USER_MEDIA`).
|
|
- Codec/bitrate/timeslice binding unchanged: `video/webm; codecs=vp9` @ 400 000 bps, MediaRecorder timeslice 2000 ms.
|
|
- Trade-off accepted: SPEC §1 "silent operation" is given up — Chrome's permanent "Sharing your screen" indicator is shown while recording. Phase 1 accepts this in exchange for broader capture coverage and elimination of `tabCapture` user-gesture juggling.
|
|
- Tab-switch re-attachment clause is REMOVED — `getDisplayMedia` captures a screen/window, not a tab. There is nothing to re-attach.
|
|
- Manifest permission `tabCapture` is REPLACED with `desktopCapture` (the latter is harmless: `getDisplayMedia` is a web standard API and does NOT actually require `desktopCapture`, but we declare it for clarity per CONTEXT.md D-05).
|
|
```
|
|
|
|
Then append an Amendment block to DEC-010 immediately AFTER line 152 (the `chrome.alarms` decision line). The amendment block reads VERBATIM:
|
|
|
|
```markdown
|
|
|
|
## Amendment (Phase 01-stabilize-video-pipeline, 2026-05-15)
|
|
|
|
- AMENDED-BY: Phase 01 CONTEXT.md D-17..D-18
|
|
- Replace `chrome.alarms`-driven 20 s keepalive with a long-lived `chrome.runtime.connect` port opened from the offscreen document to the Service Worker. The port emits a `PING` message every 25 s; both directions of traffic reset the SW's 30 s idle timer per Chrome 110+ semantics (developer.chrome.com/blog/longer-esw-lifetimes).
|
|
- The `alarms` permission is removed from `manifest.json` (it is no longer used by Phase 1; Phase 2 / 3 may re-add if needed).
|
|
- Port lifetime cap (~5 minutes per Chromium-extensions community gist sunnyguan/f94058f66fab89e59e75b1ac1bf1a06e) is mitigated by reconnecting on `onDisconnect` and pre-emptively at ~290 s.
|
|
- See `.planning/phases/01-stabilize-video-pipeline/01-RESEARCH.md` Pattern 5 for the canonical implementation.
|
|
```
|
|
|
|
Do not modify any other text in decisions.md.
|
|
</action>
|
|
<verify>
|
|
<automated>grep -c "AMENDED-BY: Phase 01" .planning/intel/decisions.md</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- `grep -c "AMENDED-BY: Phase 01" .planning/intel/decisions.md` returns 2
|
|
- `grep -c "getDisplayMedia" .planning/intel/decisions.md` returns at least 1
|
|
- `grep -c "port" .planning/intel/decisions.md` returns at least 1
|
|
- DEC-003 still has its original text intact (the amendment is APPENDED, not replacing)
|
|
- DEC-010 still has its original text intact (the amendment is APPENDED, not replacing)
|
|
</acceptance_criteria>
|
|
<done>Both decisions carry an Amendment block; downstream phases that grep DEC-003 / DEC-010 now find the new contract alongside the original.</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 2: Amend intel/constraints.md — retire two, add one (D-A2)</name>
|
|
<files>.planning/intel/constraints.md</files>
|
|
<read_first>
|
|
- .planning/intel/constraints.md (lines 95-111 CON-tab-capture-binding and CON-service-worker-keepalive)
|
|
- .planning/phases/01-stabilize-video-pipeline/01-CONTEXT.md §"Doc Amendments (precede code)" (D-A2)
|
|
</read_first>
|
|
<action>
|
|
Two edits, both in `.planning/intel/constraints.md`:
|
|
|
|
(1) Append a RETIRED block immediately AFTER line 102 (the end of CON-tab-capture-binding). VERBATIM text:
|
|
|
|
```markdown
|
|
|
|
### 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).
|
|
```
|
|
|
|
(2) Append a RETIRED block immediately AFTER line 111 (the end of CON-service-worker-keepalive). VERBATIM text:
|
|
|
|
```markdown
|
|
|
|
### 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).
|
|
```
|
|
|
|
(3) Append a brand-new constraint immediately AFTER the existing `CON-buffer-storage` block (after line 196). VERBATIM text:
|
|
|
|
```markdown
|
|
|
|
---
|
|
|
|
## 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.
|
|
```
|
|
|
|
Do not modify any other text in constraints.md.
|
|
</action>
|
|
<verify>
|
|
<automated>grep -c "RETIRED-BY: Phase 01" .planning/intel/constraints.md</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- `grep -c "RETIRED-BY: Phase 01" .planning/intel/constraints.md` returns 2
|
|
- `grep -c "## CON-display-capture-binding" .planning/intel/constraints.md` returns 1
|
|
- The original `## CON-tab-capture-binding` and `## CON-service-worker-keepalive` headings still exist (RETIRED is APPENDED below them, not replacing them)
|
|
- `grep -c "video-keepalive" .planning/intel/constraints.md` returns at least 1
|
|
</acceptance_criteria>
|
|
<done>Two retired constraints carry RETIRED-BY markers; CON-display-capture-binding exists as the consolidated replacement constraint.</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 3: Amend PROJECT.md Key Decisions table and Constraints section (D-A3)</name>
|
|
<files>.planning/PROJECT.md</files>
|
|
<read_first>
|
|
- .planning/PROJECT.md (lines 79-110 Constraints section, lines 113-134 Key Decisions table)
|
|
- .planning/phases/01-stabilize-video-pipeline/01-CONTEXT.md §"Doc Amendments (precede code)" (D-A3)
|
|
</read_first>
|
|
<action>
|
|
Three edits in `.planning/PROJECT.md`:
|
|
|
|
(1) DEC-003 row in the Key Decisions table — find line 124 starting `| **DEC-003**:` and replace the entire row with VERBATIM:
|
|
|
|
```markdown
|
|
| **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) |
|
|
```
|
|
|
|
(2) DEC-010 row — find line 131 starting `| **DEC-010**:` and replace the entire row with VERBATIM:
|
|
|
|
```markdown
|
|
| **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) |
|
|
```
|
|
|
|
(3) Constraints section — find line 100-101 (the `chrome.alarms` keepalive bullet) and replace with VERBATIM:
|
|
|
|
```markdown
|
|
- **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.
|
|
```
|
|
|
|
(this replaces the two bullets currently at lines 97-102 — the existing SW-keepalive bullet AND the existing tab-capture-binding bullet — with the two replacement bullets above. The bullet ordering and the rest of the Constraints section are unchanged.)
|
|
|
|
Do not modify any other text in PROJECT.md.
|
|
</action>
|
|
<verify>
|
|
<automated>grep -c "AMENDED by Phase 01" .planning/PROJECT.md</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- `grep -c "AMENDED by Phase 01" .planning/PROJECT.md` returns 2 (DEC-003 + DEC-010 rows)
|
|
- `grep -c "getDisplayMedia" .planning/PROJECT.md` returns at least 1
|
|
- `grep -c "long-lived port" .planning/PROJECT.md` returns at least 1
|
|
- `grep -c "RETIRED" .planning/PROJECT.md` returns at least 1
|
|
- The `## Key Decisions` heading and the `## Constraints` heading still exist
|
|
- All other rows of the Key Decisions table are untouched
|
|
</acceptance_criteria>
|
|
<done>PROJECT.md's Key Decisions table and Constraints section reflect the new contract; downstream readers of PROJECT.md see the amendments without needing to drill into intel/.</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 4: Amend REQUIREMENTS.md REQ-video-ring-buffer (D-A4)</name>
|
|
<files>.planning/REQUIREMENTS.md</files>
|
|
<read_first>
|
|
- .planning/REQUIREMENTS.md (lines 19-27 REQ-video-ring-buffer block)
|
|
- .planning/phases/01-stabilize-video-pipeline/01-CONTEXT.md §"Doc Amendments (precede code)" (D-A4)
|
|
</read_first>
|
|
<action>
|
|
Replace the entire REQ-video-ring-buffer entry (currently lines 19-27 starting `- [ ] **REQ-video-ring-buffer**`) with VERBATIM:
|
|
|
|
```markdown
|
|
- [ ] **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
|
|
unchanged: `video/webm; codecs=vp9` @ 400 000 bps with a `MediaRecorder`
|
|
timeslice of 2000 ms; a single continuous recorder runs for the whole
|
|
session. The first emitted chunk (WebM header) is retained indefinitely;
|
|
subsequent chunks rotate out by the 30-second TTL rule. Bindings: DEC-003
|
|
(AMENDED), DEC-009, CON-video-window, CON-video-codec,
|
|
CON-webm-header-retention, CON-display-capture-binding (replaces RETIRED
|
|
CON-tab-capture-binding).
|
|
- SPEC §10 acceptance criteria: #2, #3, #7.
|
|
```
|
|
|
|
Do not modify any other text in REQUIREMENTS.md.
|
|
</action>
|
|
<verify>
|
|
<automated>grep -c "AMENDED in" .planning/REQUIREMENTS.md</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- `grep -c "AMENDED in" .planning/REQUIREMENTS.md` returns at least 1
|
|
- `grep -c "getDisplayMedia" .planning/REQUIREMENTS.md` returns at least 1
|
|
- `grep -c "active-tab video" .planning/REQUIREMENTS.md` returns 0 (the old "active-tab" wording is removed)
|
|
- `grep -c "REQ-video-ring-buffer" .planning/REQUIREMENTS.md` returns at least 2 (the bullet + the Traceability table row)
|
|
- The Traceability table row for REQ-video-ring-buffer remains intact
|
|
</acceptance_criteria>
|
|
<done>REQ-video-ring-buffer reads correctly for Phase 1 and binds the new constraint set.</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 5: Amend ROADMAP.md Phase 1 description + Success Criterion #2 (D-A5)</name>
|
|
<files>.planning/ROADMAP.md</files>
|
|
<read_first>
|
|
- .planning/ROADMAP.md (lines 25, 33-66 Phase 1 block)
|
|
- .planning/phases/01-stabilize-video-pipeline/01-CONTEXT.md §"Doc Amendments (precede code)" (D-A5)
|
|
</read_first>
|
|
<action>
|
|
Two edits in `.planning/ROADMAP.md`:
|
|
|
|
(1) Replace line 25 VERBATIM with:
|
|
|
|
```markdown
|
|
- [ ] **Phase 1: Stabilize video pipeline** — Collapse offscreen duality, fix MediaRecorder shadow, fix WebM ring buffer playability, replace `chrome.tabCapture` with offscreen `getDisplayMedia` (AMENDED from original DEC-003)
|
|
```
|
|
|
|
(2) Replace Success Criterion #2 (currently lines 58-61 in the `**Success Criteria** (what must be TRUE):` block — "With the extension loaded and a tab open, a single continuous `MediaRecorder` ... without losing the WebM container header.") with VERBATIM:
|
|
|
|
```markdown
|
|
2. With the extension loaded and an operator session active, a single
|
|
continuous `MediaRecorder` is running on the operator-selected
|
|
screen/window source with timeslice 2000 ms; the recorder continues
|
|
unchanged across tab switches (no tab re-attach logic; AMENDED from the
|
|
original wording). The WebM container header is retained in the ring
|
|
buffer indefinitely.
|
|
```
|
|
|
|
Do not modify any other text in ROADMAP.md.
|
|
</action>
|
|
<verify>
|
|
<automated>grep -c "AMENDED" .planning/ROADMAP.md</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- `grep -c "AMENDED" .planning/ROADMAP.md` returns at least 2
|
|
- `grep -c "tab re-attach" .planning/ROADMAP.md` returns 0 (the old phrase is gone)
|
|
- `grep -c "getDisplayMedia" .planning/ROADMAP.md` returns at least 1
|
|
- Phases 2-5 sections remain untouched
|
|
</acceptance_criteria>
|
|
<done>ROADMAP.md Phase 1 description and Success Criterion #2 reflect the new contract; readers of ROADMAP.md see the amendment without needing to drill into CONTEXT.md.</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 6: Manifest permission swap — tabCapture → desktopCapture, drop alarms (D-A6 / D-05)</name>
|
|
<files>manifest.json</files>
|
|
<read_first>
|
|
- manifest.json (lines 6-14 permissions block)
|
|
- .planning/phases/01-stabilize-video-pipeline/01-CONTEXT.md §"Doc Amendments (precede code)" (D-A6)
|
|
- .planning/phases/01-stabilize-video-pipeline/01-PATTERNS.md §`manifest.json` (lines 444-476)
|
|
</read_first>
|
|
<action>
|
|
Replace the `"permissions": [...]` array (currently lines 6-14) VERBATIM with:
|
|
|
|
```json
|
|
"permissions": [
|
|
"desktopCapture",
|
|
"activeTab",
|
|
"downloads",
|
|
"scripting",
|
|
"storage",
|
|
"offscreen"
|
|
],
|
|
```
|
|
|
|
Specifically:
|
|
- Replace `"tabCapture"` → `"desktopCapture"` (per D-A6).
|
|
- Remove `"alarms"` (the alarms keepalive is deleted in Plan 05; declaring an unused permission expands attack surface, mitigating T-1-02).
|
|
- Keep `"activeTab"` (needed for `chrome.tabs.captureVisibleTab` in Phase 3 screenshot path — current code uses it at src/background/index.ts:190).
|
|
- Keep `"downloads"` (used at src/background/index.ts:305).
|
|
- Keep `"scripting"` (content script injection).
|
|
- Keep `"storage"` (currently unused by code but retained per SPEC §7; do not remove in this phase — that is Phase 5 hardening territory).
|
|
- Keep `"offscreen"` (required to call `chrome.offscreen.createDocument`).
|
|
|
|
Do not modify any other field in `manifest.json` (manifest_version, name, version, description, host_permissions, background, content_scripts, action, icons all remain untouched).
|
|
</action>
|
|
<verify>
|
|
<automated>node -e "const m=require('./manifest.json'); const p=m.permissions; if(p.includes('tabCapture')||p.includes('alarms')){process.exit(1)}; if(!p.includes('desktopCapture')||!p.includes('offscreen')){process.exit(2)}; console.log('ok')"</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- `grep -c '"tabCapture"' manifest.json` returns 0
|
|
- `grep -c '"desktopCapture"' manifest.json` returns 1
|
|
- `grep -c '"alarms"' manifest.json` returns 0
|
|
- `grep -c '"offscreen"' manifest.json` returns 1
|
|
- `grep -c '"activeTab"' manifest.json` returns 1
|
|
- `node -e "require('./manifest.json')"` exits 0 (JSON valid)
|
|
- `host_permissions` array still contains `"<all_urls>"` (unchanged)
|
|
</acceptance_criteria>
|
|
<done>manifest.json carries the final Phase-1 permissions set; downstream code-touching plans (02-07) operate against a manifest that matches the new API contract.</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<verification>
|
|
After all six tasks land:
|
|
|
|
1. `grep -c "AMENDED" .planning/PROJECT.md .planning/REQUIREMENTS.md .planning/ROADMAP.md` returns at least 4 lines (each file has at least one amendment marker; the precise totals are checked in each task's acceptance_criteria).
|
|
2. `grep -c "RETIRED-BY: Phase 01" .planning/intel/constraints.md` returns 2.
|
|
3. `grep -c "AMENDED-BY: Phase 01" .planning/intel/decisions.md` returns 2.
|
|
4. `grep -c '"tabCapture"' manifest.json` returns 0 and `grep -c '"desktopCapture"' manifest.json` returns 1.
|
|
5. `node -e "require('./manifest.json')"` exits 0 (JSON valid).
|
|
6. `node -e "require('./.planning/config.json')"` exits 0 (we did not touch config.json).
|
|
7. Every code-touching plan in Waves 0..2 can grep the doc baseline (manifest.json, PROJECT.md, REQUIREMENTS.md, ROADMAP.md, decisions.md, constraints.md) and find the amendments — no plan needs to back-patch a doc.
|
|
|
|
Commit cadence: ONE git commit per task (six atomic commits). Each commit message follows `docs(01-01): amend {file} per D-{ID}` style. The orchestrator handles commit creation.
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- All six tasks complete and verified.
|
|
- No file in the dependency closure carries the pre-amendment wording.
|
|
- manifest.json `permissions` array exactly matches the list specified in Task 6's action block.
|
|
- Plans 02..07 can run against a self-consistent doc baseline (no late doc patches required mid-phase).
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.planning/phases/01-stabilize-video-pipeline/01-01-SUMMARY.md` with:
|
|
- Which 6 files were amended and at which line ranges
|
|
- The exact text of the new CON-display-capture-binding block (so downstream plans can quote it)
|
|
- Confirmation of all six acceptance grep checks
|
|
- Six commit SHAs (one per task)
|
|
</output>
|