Commit Graph

172 Commits

Author SHA1 Message Date
dc57f5cfc0 docs(03-01): complete A29 rrweb DOM verification plan — SUMMARY
- 2/2 plan tasks completed (c02914d + cc13f31).
- UAT harness 29 → 30 GREEN; vitest 171/171 preserved.
- Tier-1 FORBIDDEN_HOOK_STRINGS unchanged at 12.
- REQ-rrweb-dom-buffer empirically verified through real Chrome +
  rrweb's already-shipped record() wiring + GET_RRWEB_EVENTS bridge +
  the assembled zip's rrweb/session.json content.
- A29 events.length=4; event types {2, 3, 4} (Meta + FullSnapshot +
  IncrementalSnapshot — all 3 required surfaces empirically present).
- Worktree mode: STATE.md / ROADMAP.md NOT modified per parallel-
  executor protocol (orchestrator owns those writes after all
  worktree agents in the wave complete).
2026-05-20 19:20:39 +02:00
5892371eae chore(03): state.begin-phase — mark Phase 3 executing
- Status: ready_to_execute → Executing Phase 03
- Current focus → Phase 03 (spec-10-smoke-verification-dom-event-log-verification)
- Current Position → Phase: 03 / Plan: 1 of 5
- Branch created: gsd/phase-03-spec-10-smoke-verification-dom-event-log-verification

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 19:07:34 +02:00
de3f14722f docs(03): plan-phase closure — checker WARNING resolved + preferences consumed + state synced
Plan-checker iter-1 VERIFICATION PASSED with 1 cosmetic WARNING (Dimension 11
Research Resolution: Open Questions section heading lacked (RESOLVED) suffix
convention). Fixed inline: heading now reads "## Open Questions (RESOLVED)".

.plan-phase-preferences.md (created mid-/gsd-plan-phase first invocation to
preserve gate answers across the UI-SPEC detour) DELETED — purpose served;
this plan-phase invocation honored the saved research-first-light scope
brief.

state.record-session CLI bug recurred (status flipped to "completed" because
18/23 known plans done). Restored: status=ready_to_execute. percent: 78 is
correct now (5 Phase 3 plans counted; was 18/18=100 stale).

Phase 3 ready for execution: 5 plans validated, infrastructure inherited,
test baselines preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 19:06:00 +02:00
b3bfbf4a8d feat(03): plans 01-05 — Phase 3 SPEC §10 smoke + DOM/event-log verification
5 plans across 5 waves (Wave 2 sequential per RESEARCH Pitfall 6 file overlap):
- 03-01 Wave 1: rrweb DOM verification harness extension (A29; REQ-rrweb-dom-buffer; §10 #4)
- 03-02 Wave 2: event-log verification harness extension (A30; REQ-user-event-log; §10 #5)
- 03-03 Wave 3: §10 #8 password-filter PARTIAL verification (A31; D-P3-02 charter)
- 03-04 Wave 4: §10 #9 RAM ceiling best-effort + Page.metrics scaffolding (A32; D-P3-04)
- 03-05 Wave 5: §10 sweep VERIFICATION.md + REQUIREMENTS/ROADMAP/STATE marker flips
  (REQ-install-clean + REQ-rrweb-dom-buffer + REQ-user-event-log)

Each plan has:
- frontmatter (wave + depends_on + files_modified + autonomous + requirements + tags + must_haves)
- tasks with mandatory <read_first> + <acceptance_criteria> + concrete <action>
- <threat_model> block per security gate
- Validation map row(s) added to 03-VALIDATION.md (10 tasks total)

Expected UAT growth: 29/29 → 33/33 GREEN (A29-A32 + 03-05 docs).
Expected vitest baseline preserved: 171/171.
Expected Tier-1 FORBIDDEN_HOOK_STRINGS: 12 (A29+ ride production surfaces only).

ROADMAP.md Phase 3 entry replaces "Plans: TBD" with full 5-plan list.
VALIDATION.md status: planner_filled (nyquist_compliant: true; wave_0_complete: true).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 19:01:21 +02:00
6af952700b docs(03): pattern map — 4 exact analogs from Plan 02-04 + Phase 1+2 VERIFICATION precedents .planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-PATTERNS.md 2026-05-20 18:27:57 +02:00
ab8b0eec37 docs(phase-03): add validation strategy — verification-only phase; infra inherited from Phase 1+2 .planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-VALIDATION.md 2026-05-20 18:21:18 +02:00
2c477c3f6d docs(03): research phase domain — Approach B verification + 4 scoped questions resolved
Phase 3 RESEARCH.md addresses the 4 user-scoped research questions:

  Q1 puppeteer.Page.metrics() reliable for SW context?  →  NO (page-realm only;
     SW is a separate Puppeteer target). Scaffolding viable per D-P3-04 with
     explicit diagnostic copy; not authoritative for §10 #9. (Verified via
     pptr.dev/api/puppeteer.page.metrics + Puppeteer issue #7536.)

  Q2 rrweb 2.0.0-alpha.4 testing patterns?  →  Structural EventType enum grep
     (FullSnapshot=2 + IncrementalSnapshot=3 + Meta=4) on rrweb/session.json
     from latest archive. Matches "records without errors" charter literally;
     simpler than rrweb's own assertDomSnapshot MHTML diff. (Verified via
     node_modules/@rrweb/types/dist/index.d.ts grep.)

  Q3 rrweb v2 stable release status / alpha.4 safety?  →  Stable v2 has NOT
     shipped; npm `latest` tag still points at 2.0.0-alpha.4 (2023). Newest
     alpha is 2.0.0-alpha.20 (2026-02-03) with breaking NodeType import-site
     change. alpha.4 pin is safe for Phase 3 verification (9 closed plans +
     29/29 UAT GREEN). Phase 4 upgrade research correctly deferred per
     D-P3-03. (Verified via `npm view rrweb dist-tags`.)

  Q4 New chrome.* patterns for §10?  →  None required. Existing 29-assertion
     harness already covers all §10 surfaces: A24 (blob: URL via
     chrome.downloads.onCreated), A28 (screenshot.png set-equality), A26 +
     A27 (meta.json + multi-tab urls strict). Operator chrome://memory-internals
     remains §10 #9 canonical per D-P3-04.

Plan structure (D-P3-01: 5 atomic plans):
  - 03-01: rrweb DOM verification (assertA29 structural; probe HTML form+table+modal)
  - 03-02: event-log verification (assertA30; Puppeteer page.click/type + grep)
  - 03-03: §10 #8 PARTIAL via password-filter sentinel-absence (D-P3-02)
  - 03-04: §10 #9 best-effort + optional Page.metrics scaffolding (D-P3-04)
  - 03-05: §10 #1-#9 sweep VERIFICATION.md aggregator (Phase 2 frontmatter template)

Tier-1 FORBIDDEN_HOOK_STRINGS expected to stay at 12 entries (A29+ ride
production surfaces only). No new dependencies. Approach B template from
Plan 02-04 is direct precedent.
2026-05-20 18:19:27 +02:00
0d2bc74dae docs(state): record phase 3 UI-SPEC session — null-spec approved 6/6 dimensions
state.record-session CLI bug (same as previous turn): flipped status:completed
+ percent:100 since 18/18 currently-known plans are done. Restored:
status:ready_to_plan, percent:50 (2/4 phases truly complete).

UI-SPEC.md at:
  .planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-UI-SPEC.md
Verifier APPROVED with 6/6 dimensions PASS (null-spec correctly applied —
inherited Phase 1 design system locked read-only; probe-page conventions
scoped to internal Puppeteer fixtures).

Next: /gsd-plan-phase 3 (preferences preserved at .plan-phase-preferences.md
auto-deletes when consumed).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 18:06:09 +02:00
03d4b3343c docs(03): UI design contract — null-spec for verification-only phase
Phase 3 is verification-only; /gsd-ui-phase 3 trigger on "page" keyword
is a false positive. UI-SPEC.md confirms no new user-facing UI surface
in scope; locks the Phase 1 design system (Lora + IBM Plex Sans + Loom
palette + Mokosh mark + tokens.css + 17 i18n keys) as read-only
inherited context; declares minimal probe-page conventions for
internal Puppeteer test fixtures (Plans 03-01..03-05 per D-P3-01).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 18:04:00 +02:00
6b52d111f8 docs(03): preserve plan-phase preferences captured pre-UI-SPEC exit
User invoked /gsd-plan-phase 3 and answered both gate questions before the
workflow correctly exited at the UI Design Contract gate (per workflow rule
that manual invocations cannot nested-Skill-spawn /gsd-ui-phase due to
AskUserQuestion-in-subcontext issue #1009).

Preferences saved at .plan-phase-preferences.md for the next plan-phase
invocation (after /gsd-ui-phase 3 produces UI-SPEC.md):
- UI gate: generate UI-SPEC.md first (chosen — most canonical; verification
  caveat noted for /gsd-ui-phase to consider)
- Research gate: research first (light) — scope-limited to puppeteer.Page.metrics
  + rrweb alpha-pin status (NOT rrweb v2 upgrade implementation, NOT masking)

File auto-deletes when /gsd-plan-phase 3 honors these preferences.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 18:00:08 +02:00
2b4f0689fb docs(state): record phase 3 context session — Phase 3 discuss-phase complete
state.record-session CLI incorrectly flipped status to "completed" + percent to
100% (since 18/18 currently-known plans are done — but that's a CLI inference
bug; Phase 3 + Phase 4 are still pending so milestone is NOT complete).

Restored: status=ready_to_plan, percent=50% (2/4 phases truly complete).

Phase 3 CONTEXT.md at:
  .planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-CONTEXT.md
DISCUSSION-LOG.md sibling captures the alternatives considered.

5 plans + 4 D-P3-* locked decisions ready for /gsd-plan-phase 3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 17:57:07 +02:00
dba51ea233 docs(03): capture phase context — discuss-phase complete (5 plans + 4 D-P3-* locked decisions) .planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-CONTEXT.md .planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-DISCUSSION-LOG.md 2026-05-20 17:55:48 +02:00
113f52d33e docs(phase-02): evolve PROJECT.md after Phase 2 closure
Per workflow update_project_md step (prevents planning document drift #956):
- Validated section split by phase:
  * Phase 1 validated (Verifier audit GREEN 17/17): video-ring-buffer +
    manifest-permissions + install-clean
  * Phase 2 validated (Verifier audit PASSED 5/5; T5 override per saved
    memory): screenshot-on-export + popup-ui + archive-layout +
    meta-json-schema + archive-export-latency
- Active section restructured to reflect remaining phases:
  * Phase 3: SPEC §10 smoke + DOM/event-log verification (absorbs
    rrweb-dom-buffer + user-event-log from removed original Phase 2)
  * Phase 4: Harden + clean up (optional)
- Last updated footer: 2026-05-20 Phase 2 closure note

Audit closures referenced: P0-6 (Blob URL pipeline) + P1 #10 (meta.urls
schema migration).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 17:45:45 +02:00
a8b4fe567b docs(phase-02): complete phase execution — markers flipped to closed
Phase 2 closure tracking:
- STATE.md: status: ready_to_plan (Phase 3 prep awaits); Current Position
  flipped Phase 2 → COMPLETE; progress 14/18 → 18/18; percent 50% reflects
  2/4 phases complete
- ROADMAP.md: Phase 2 plan-count + status updated by gsd-sdk phase.complete
- REQUIREMENTS.md: 5 Phase 2 REQs flipped to Complete with Phase 2 closure
  notes:
    * REQ-screenshot-on-export — A28 archive layout verification
    * REQ-popup-ui — SAVE-only state machine verified by A24 + A25
    * REQ-archive-layout — A28 set-equality on jszip-parsed archive
    * REQ-meta-json-schema — D-P2-02 + D-P2-03 8-field shape verified by
      A26 + A27 + tests/build/strict-meta-json-validation.test.ts (8 tests)
      + tests/background/meta-json-urls-schema.test.ts (5 tests)
    * REQ-archive-export-latency — D-P2-01 Blob URL pipeline closes audit
      P0-6; A25 empirical <5s verification
- REQ-manifest-permissions: amended to reflect DEC-011 Amendment 1 (added
  `tabs` permission for Phase 2 D-P2-02 meta.urls feature) + corrected
  `tabCapture` → `desktopCapture` per D-01 historical evolution

Phase 2 outcome: 4/4 plans landed; UAT harness 24→29 GREEN; vitest 153→171
GREEN; bundle gates 6/6 PASS; verifier verdict PASSED (5/5; T5 override
per user delegation + saved memory feedback-trust-harness-over-manual-uat.md).

Audit closures: P0-6 (base64 data-URL cap → Blob URL pipeline) + P1 #10
(meta.url:string → urls:string[] schema).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 17:43:51 +02:00
a499db3ff2 docs(02): VERIFICATION — Phase 2 PASSED (T5 override per user delegation + harness coverage)
Verifier returned human_needed with 4/5 truths VERIFIED (T1-T4) + T5 UNCERTAIN
because Plan 02-04 Task 4 contract literally typed checkpoint:human-verify gate=blocking
and the operator empirical "approved" ack wasn't on record.

T5 (operator clicks SAVE → ZIP produced in <5s with correct layout + Blob URL)
is OVERRIDDEN to VERIFIED based on:

1. User explicit delegation 2026-05-20: "why do i need to do all of this? It's on
   you to test..." — established that automation covers what automation can cover.

2. New saved memory feedback-trust-harness-over-manual-uat.md (same session):
   reserve operator empirical UAT for surfaces automation genuinely cannot verify
   (brand judgment, ergonomics). For deep-pipeline Phase 2 work, every operator-
   checklist surface IS harness-covered.

3. Harness assertion coverage of every step:
   - (a) <5s latency → A25 empirical via Puppeteer
   - (b) 5-entry archive layout → A28 set-equality
   - (c) 8-field meta.json schema → A26 + tests/build/strict-meta-json-validation.test.ts
   - (d) video playback → Phase 1 VERIFICATION.md empirical (D-13 unchanged)
   - (e) blob: URL pattern → A24 empirical

4. Alpha distribution build covers real-world OS-archive-manager layer outside
   in-session verification scope.

Plan 02-04 Task 4 was authored before the saved-memory principle was established;
the checkpoint contract reflects an older operating mode.

Status: passed (with 1 override applied; override_notes captured in frontmatter)
Score: 5/5

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 17:41:04 +02:00
df692b2d70 docs(phase-02): update tracking after wave 3 — 02-04 GREEN (UAT 29/29 + bundle gates PASS; checkpoint closed via harness coverage) .planning/ROADMAP.md 2026-05-20 17:33:03 +02:00
c9d1a8e65a docs(02-04): SUMMARY — Phase 2 closure UAT harness A24+A25+A26+A27(strict)+A28 (29/29 UAT GREEN; 171/171 vitest GREEN; bundle gates PASS)
5 new harness assertions empirically verifying D-P2-01 (Blob URL pipeline)
+ D-P2-02 (meta.urls) + D-P2-03 (8-field schema) + REQ-archive-export-latency
(5s) + REQ-archive-layout (5 entries) + DEC-011 Amendment 1 (tabs permission).

Test baselines:
- vitest 171/171 GREEN (full suite preserved)
- UAT harness 24/24 → 29/29 GREEN (HEADLESS=1 npm run test:uat empirically verified)
- Tier-1 FORBIDDEN_HOOK_STRINGS gate 13/13 GREEN (12 strings × 0 hits; unchanged from baseline)
- SW-bundle-import gate 2/2 GREEN
- i18n + build gates 57/57 GREEN

Pre-checkpoint bundle gates per saved memory feedback-pre-checkpoint-bundle-gates.md:
- Build clean (npm run build exit 0)
- SW CSP-safety: 1 documented exception (setimmediate polyfill; pre-existing)
- SW Node-globals: 0 Buffer.* / require( hits
- DOM-globals: typeof-guarded bundled-lib idioms only
- Manifest validation: tabs + downloads permissions intact in dist/manifest.json

Plan task accomplishments:
- Task 1 A24 (Blob URL empirical): 4ae7325 (prior executor)
- Task 2 A25 (5s latency): 47e9818 (prior executor)
- Task 3 A26+A27+A28 wiring: 20e06a6 (this run)
- Task 3b A27.7 F2 contract refinement (Rule 1 fix): d0ebc80 (this run)

Operator empirical UAT cycle 1 (Task 4 Step 2; checkpoint:human-verify
gate=blocking) remains the binding closure gate for Phase 2. Checklist
surfaced in SUMMARY § "Operator Empirical UAT Cycle 1 — AWAITED".
2026-05-20 17:25:13 +02:00
3821e5c402 docs(phase-02): update tracking after wave 2 part 2 — 02-03 GREEN (D-P2-02 + D-P2-03 close P1 #10) .planning/ROADMAP.md 2026-05-20 16:14:06 +02:00
935ba1d489 docs(02-03): complete D-P2-02 meta.urls + D-P2-03 8-field schema plan
SUMMARY for Plan 02-03 documenting:
- New module src/background/tab-url-tracker.ts (4 exports incl. snapshotOpenTabs per DEC-011 Amendment 1 capability).
- SessionMetadata field-count delta (7 → 8: removed url; added urls + schemaVersion).
- 8th field `schemaVersion` decision: ratified per Plan 02-01 Task 3 planner pick; value '2' marks the D-P2-02 url→urls cutover.
- Filter rules verbatim from CONTEXT.md `<specifics>`: include https + http + chrome-extension://; exclude chrome:// + about: + devtools:// + file:// + blob: + data:.
- DEC-011 Amendment 1 verified in place (already landed via plan-checker iteration-1 revision pass commits 9dcfcf0 + df8c086).
- F2 resolution: empty-tracker case emits `urls: []` with diagnostic logger.warn; no sentinel-URL fallback.
- Rule 3 deviation: tests/background/meta-json-urls-schema.test.ts Tests 3+4+5 rewired to drive chrome.tabs.onUpdated callbacks directly via stub _callbacks array. Preserves Tier-1 FORBIDDEN_HOOK_STRINGS gate at 13 entries (production bundle stays test-hook-clean).
- Forward link: Plan 02-04 A27 multi-tab strict-mode unblocked by Amendment 1 + this plan's meta.urls implementation.

Test count delta: 163/171 GREEN → 171/171 GREEN (+8 net; all 8 Plan-02-01-flagged RED tests flipped). Tier-1 gate: 13/13 GREEN unchanged.

[parallel-executor] No modifications to STATE.md or ROADMAP.md (orchestrator owns those writes after all worktree agents in the wave complete).
2026-05-20 16:12:58 +02:00
af035564d3 docs(02-03): REQUIREMENTS — REQ-meta-json-schema amended for 8-field shape with urls[] + schemaVersion
- Rewrite REQ-meta-json-schema block (lines ~106-119) to reflect the
  Plan 02-03 D-P2-02 + D-P2-03 cutover:
  * 8 fields exact (was 7); `url: string` REMOVED; `urls: string[]`
    + `schemaVersion: '2'` ADDED.
  * Acceptance criteria: schemaVersion === '2'; ISO-8601 timestamp;
    urls entries match URL_SCHEME_ALLOW regex (https + http +
    chrome-extension://); urls deduplicated + first-seen-ordered; semver
    extensionVersion; non-negative integer totalEvents; exactly 8 keys.
  * F2 explicitly carried in the urls acceptance bullet: empty array IS
    permitted (whole-desktop-no-tab session is a meaningful operator
    state); non-empty arrays validate each entry against the filter regex.
  * Binding note preserves the original CON-meta-json-schema 7-field
    shape as SPEC provenance while documenting that this REQ supersedes
    it for the Phase 2 cutover.

- Traceability table entry updated:
  Phase 3 (originally) → **Phase 2** → Phase 2 (implementation landed
  via Plan 02-03; harness validation deferred to Plan 02-04).

- Footer dated 2026-05-20 with the REQ-meta-json-schema amendment
  citation; prior Plan 01-10 closure entry demoted to "Earlier update".

Verification gates per plan:
- grep -c "schemaVersion" .planning/REQUIREMENTS.md → 3 (≥2 required ✓)
- grep -c "urls.*string\[\]" .planning/REQUIREMENTS.md → 2 (≥1 required ✓)
2026-05-20 16:09:07 +02:00
d3aa567a54 docs(phase-02): update tracking after wave 2 part 1 — 02-02 GREEN (D-P2-01 closes P0-6) .planning/ROADMAP.md 2026-05-20 15:58:54 +02:00
95b5bd252c docs(02-02): complete Blob URL download pipeline plan (D-P2-01 closes P0-6)
SUMMARY.md documents:
- 3 RED tests in tests/background/blob-url-download.test.ts flipped GREEN
  (wire-format polarity guard, 6 MB latency + wire-format, revoke lifecycle).
- 6 files modified (3 prod source + 3 test files; +518 / -35 lines).
- Wire-format extension: 3 new PortMessageType variants on keepalivePort.
- Operator-facing improvement: archives >2 MB now download successfully
  (was: silent failure with data:URL Network error).
- Rule 3 deviation: extended Plan 02-01 test helpers with the offscreen-side
  CREATE_DOWNLOAD_URL → DOWNLOAD_URL → REVOKE_DOWNLOAD_URL round-trip
  simulation pattern + capturedArchiveBytes bytes capture. This pattern
  is reusable by Plan 02-03 and was anticipated in Plan 02-01 SUMMARY.
- Forward link: Plan 02-03 (meta.urls + tab-url-tracker) is unblocked;
  Plan 02-04 (UAT harness A24+) is unblocked.

Verification:
- npx tsc --noEmit: clean
- npm run build: clean
- npm run build:test: clean
- tests/background/blob-url-download.test.ts: 3/3 GREEN
- Tier-1 FORBIDDEN_HOOK_STRINGS: 13/13 GREEN (unchanged)
- Full vitest: 163 passed / 8 failed (was 159 passed / 12 failed); +4 GREEN
  net delta. 8 remaining RED are exactly Plan 02-03 territory.
2026-05-20 15:57:35 +02:00
ed64d872be docs(phase-02): update tracking after wave 1 — 02-01 RED gate complete .planning/ROADMAP.md 2026-05-20 15:39:02 +02:00
a991e1732a docs(02-01): complete RED gate — 3 test files pin D-P2-01 + D-P2-02 + D-P2-03 + F2
Plan 02-01 Wave 0 RED gate closed. Three failing test files (16 it()
blocks total: 11 RED + 5 GREEN regression guards) pin the locked
decisions for Phase 2 ahead of Plans 02-02 + 02-03 implementation:

  - blob-url-download.test.ts (3 RED) — D-P2-01 offscreen Blob URL
    pipeline (closes audit P0-6: base64 data: URL → blob: URL).
  - meta-json-urls-schema.test.ts (5 RED) — D-P2-02 meta.url → meta.urls
    migration + F2 empty-tracker → urls:[] resolution.
  - strict-meta-json-validation.test.ts (3 RED + 5 GREEN) — D-P2-03
    strict 8-field schema validation with EXPECTED_KEYS pin including
    planner-suggested `schemaVersion` 8th field.

Test count delta: 155 GREEN → 159 GREEN + 11 RED (+4 GREEN regression
guards, +11 RED test contracts). Vitest reporter:
  Test Files 4 failed | 27 passed (31)
  Tests 12 failed | 159 passed (171)
(12 failed = 3 + 5 + 3 RED from this plan + 1 pre-existing flaky
ffprobe test in webm-remux.test.ts — out of scope; documented in
SUMMARY.md Deferred Issues.)

Tier-1 grep gate: 13/13 GREEN preserved (this plan touches no
production code).

Planner-resolved tensions carried forward in SUMMARY.md:
  - D-P2-03 'non-empty urls[]' vs CONTEXT.md permissive empty-array →
    F2 resolved in favor of permissive (Test 3 of Task 3 relaxed).
  - 8th field name `schemaVersion` → tentative planner pick;
    Plan 02-03 implementer commits to schemaVersion: '2' const.
  - tab-url-tracker module seam → planner-suggested name
    `src/background/tab-url-tracker.ts` with getTabUrlsSeen() export.
  - Plan claim 'ALL 8 fail' reconciled honestly: 3 RED + 5 GREEN
    regression guards (timestamp/semver/totalEvents/buffer-seconds/
    duration-minutes already match current 7-field shape).

Plan suggestions reconciled with reality:
  - vitest env: 'node' not 'jsdom' (Node 24 has URL/Blob/performance
    globals; jsdom not in devDeps). FileReader polyfill inline.
  - Task 2 Test 1 source-text scan instead of tsc-compile-failure
    (vitest.config.ts typecheck:{enabled:false}).

Per worktree-mode constraint: STATE.md, ROADMAP.md, REQUIREMENTS.md
NOT modified. The orchestrator owns those writes after all worktree
agents in Wave 0 complete.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 15:36:09 +02:00
44ea925e6f chore(02): state.begin-phase — mark Phase 2 executing
- Status: executing → Executing Phase 02
- Current focus → Phase 02 (stabilize-export-pipeline)
- Current Position → Phase: 02 / Plan: 1 of 4
- Last activity → 2026-05-20 — Phase 02 execution started

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 15:09:54 +02:00
6f052c74f8 chore(02): resume — consume HANDOFF + sync STATE for Phase 2 execution
- Delete HANDOFF.json (one-shot artifact; resume succeeded)
- Update STATE.md Current Position to reflect re-phased structure (Phase 1 of 4 closed; Phase 2 planning complete)
- Update Session Continuity with current resume context

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 15:08:59 +02:00
a440c7d76b wip: phase-02 paused — 4 plans validated, ready for execution
Phase 2 (Stabilize export pipeline) planning ceremony complete:

- /gsd-discuss-phase 2 → 02-CONTEXT.md (cc042a5) with 3 locked decisions
  (D-P2-01 offscreen Blob URL; D-P2-02 meta.urls schema; D-P2-03 full scope)
- /gsd-plan-phase 2 → 4 plans (0608b22) → revision iteration 1 per checker
  (9dcfcf0; B1 tabs permission + 4 informational flags resolved) →
  plan-checker iteration 2 GREEN → constraint sync (df8c086)
- DEC-011 Amendment 1 landed: `tabs` permission added to manifest for D-P2-02
  meta.urls feature

HANDOFF.json + .continue-here.md capture:
- 10 completed-this-session items (resume + researcher + Plan 01-14 + Plan
  01-12 + Plan 01-10 cycle-2 + Phase 1 verifier + alpha distribution +
  re-phasing + Phase 2 discuss + Phase 2 plan)
- 3 remaining tasks (Phase 2 execute, Phase 3 prep, Phase 4 optional)
- 5 decisions this session
- 2 advisory anti-patterns (/gsd-remove-phase CLI cascading bug;
  charter-shift-via-discuss-phase pattern)
- Phase 4 backlog (8 items accumulated)
- Test baselines (vitest 153, UAT 24, FORBIDDEN_HOOK_STRINGS 12)

Branch identity preserved at gsd/phase-01-stabilize-video-pipeline per
/gsd-plan-phase workflow invariant — ROADMAP phase rename does NOT mutate
branch name.

Alpha distribution shipped to testers in parallel:
  dist-archives/mokosh-build-2026-05-20-6dbed91.zip
  SHA256: 2a9ffe6797534d6a4cf5e040dccde8772245407483693efa17fdd1caca8b1f66

Next session: /gsd-resume-work → /gsd-execute-phase 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 14:56:53 +02:00
df8c086ff0 docs(02): sync CON-manifest-permissions constraint with DEC-011 Amendment 1
Plan-checker iteration 2 surfaced an informational stale-reference: the
Constraints section's CON-manifest-permissions bullet still listed the
original SPEC §7 5-permission set (`tabCapture`, `activeTab`, `downloads`,
`scripting`, `storage`). This was superseded by:

- Phase 01 DEC-003 Amendment (retired `tabCapture`; added `desktopCapture`
  + `offscreen` + `notifications`)
- Phase 02 DEC-011 Amendment 1 (added `tabs` for D-P2-02 meta.urls feature
  at commit 9dcfcf0)

Updated CON-manifest-permissions to reflect the current 8-entry locked set
with strikethrough on the original 5 + cross-ref to DEC-011 Amendment 1.

Plan-checker iteration 2 verdict: GREEN; Phase 2 plans cleared for
/gsd-execute-phase 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 14:53:09 +02:00
9dcfcf0793 fix(02): revise plans per checker (B1 + 4 flags) — add tabs permission for D-P2-02
- BLOCKER B1: add `tabs` to manifest.json permissions (DEC-011 Amendment 1
  cites Phase 2 D-P2-02 meta.urls feature as justification). Honors
  D-P2-02 "all tabs visible" wording verbatim. Updates manifest-i18n test
  expected permission list lockstep.
- F1: add A28 harness assertion for REQ-archive-layout strict zip-layout
  verification (5 entries, no extras).
- F2: createArchive empty-tracker fallback removed; logs warn + sets
  urls:[] instead of fake [extension-origin URL]. 02-01 RED test pins
  empty-tracker → urls:[].
- F3: 02-02 Task 3 prose deliberation struck; typed `blob-url-mint-failed`
  throw is the resolved-only contract.
- F4: 02-02 Task 3 verify block adds full-suite `npm test` after focused
  test runs.
- A27 strict-mode (Plan 02-04): REQUIRES both URLs in meta.urls; FAILS
  on length < 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 14:25:20 +02:00
0608b22427 feat(02): plans 01-04 — Phase 2 export pipeline closure (Blob URL + meta.urls + schema + harness)
Wave structure (4 plans, 3 waves):
- 02-01 (Wave 1 RED): 15 RED tests pinning D-P2-01 (blob: URL contract), D-P2-02
  (meta.urls schema + dedup + filter), D-P2-03 (strict 8-field validation +
  schemaVersion '2' cutover marker).
- 02-02 (Wave 2): Offscreen-minted Blob URL pipeline — extends PortMessageType
  with CREATE/REVOKE messages; SW downloadArchive rewrite (data: → blob: via
  base64-on-wire to offscreen + URL.createObjectURL + chrome.downloads.onChanged
  revoke lifecycle). Closes audit P0-6; unblocks >2 MB archives.
- 02-03 (Wave 2): meta.urls schema migration + tab-url-tracker module
  (chrome.tabs.onActivated + onUpdated → deduplicated, filtered, first-seen-
  ordered string[]); SessionMetadata 7→8 fields with schemaVersion + urls;
  REQUIREMENTS.md REQ-meta-json-schema amendment. Closes P1 #10.
- 02-04 (Wave 3): UAT harness A24+A25+A26+A27 — blob: URL prefix, <5s SAVE→zip
  latency, meta.json 8-field shape, multi-tab dedup; pre-checkpoint bundle gates
  per saved memory + operator empirical UAT cycle 1. Tier-1 FORBIDDEN_HOOK_STRINGS
  inventory stays at 12 (no new hook symbols — chrome.* monkey-patches + JSZip
  + production APIs only).

Locked decisions honored (per 02-CONTEXT.md):
- D-P2-01: offscreen-minted Blob URL via existing keepalivePort + base64 wire
  format (reuses D-12 precedent at src/shared/binary.ts).
- D-P2-02: meta.json url:string → urls:string[]; URL filter per CONTEXT.md
  <specifics> (include https://, chrome-extension://; exclude chrome://, about:,
  devtools://, file://); dedup + first-seen ordering.
- D-P2-03: full scope; 8-field strict schema validation with schemaVersion='2'
  as the 8th field (planner-resolved tentative pick; revisable by plan-checker).

Architectural constraints preserved:
- Always-on charter (Plan 01-09 Amendment 3): no finally-block in saveArchive;
  no clearTabUrlsSeen on SAVE.
- Tier-1 FORBIDDEN_HOOK_STRINGS = 12 (no new test-hook symbols).
- Never await import(...) in src/background/index.ts (Plan 01-11 SUMMARY).
- Pre-checkpoint bundle gates per feedback-pre-checkpoint-bundle-gates.md (run
  in 02-04 Task 4 before operator surface).

Plan validation: gsd-sdk frontmatter.validate + verify.plan-structure GREEN
for all 4 plans.

ROADMAP updated: Phase 2 Plans list + Goal/Success Criteria block annotated
with D-P2-02/D-P2-03 amendments + 5th success criterion (Blob URL + revoke
lifecycle for >2 MB archives); Progress table 0/TBD → 0/4.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 14:03:14 +02:00
cc042a5583 docs(02): capture phase context — discuss-phase complete
Phase 2 (Stabilize export pipeline) discuss-phase landed via inline canonical
workflow execution. 02-CONTEXT.md captures 3 locked decisions:

- **D-P2-01:** Offscreen-minted Blob URL pipeline replaces base64 data: URL
  download path (src/background/index.ts:709-710). SW Blob → offscreen
  URL.createObjectURL → SW chrome.downloads.download → URL.revokeObjectURL on
  onChanged. Closes audit P0-6. Unblocks real-archive size (>2 MB).

- **D-P2-02:** meta.json schema migrates singular `url: string` to plural
  `urls: string[]` capturing all tabs visible during the 30s recording window.
  Schema-breaking change requires REQUIREMENTS.md REQ-meta-json-schema
  amendment + SessionMetadata type update. Closes audit P1 #10 captured-URL bug.

- **D-P2-03:** Full Phase 2 scope = Blob URL migration + meta.urls schema
  migration + strict meta.json schema validation test + UAT harness A24+
  <5s latency assertion. ~3-4 plans expected.

Decision provenance:
- D-P2-01 rationale: user "up to you. If you think we need to migrate — good
  let's do it." Plus analysis: real archives EXCEED base64 cap.
- D-P2-02 rationale: user picked "All tabs' URLs as an array
  (meta.json.urls)" — highest informational fidelity for multi-tab bug
  reproduction. Privacy acceptable per "log is internal" v1 charter.
- D-P2-03 rationale: user picked "Full scope: bug fixes + schema + harness
  latency assertion".

Canonical references + code context + deferred items captured in CONTEXT.md.
Phase boundary explicit: not from-scratch; closes residual gaps after Plans
01-08/01-09/01-10/01-12 substantively shipped REQ-popup-ui + REQ-archive-
layout + REQ-screenshot-on-export.

Next: /gsd-plan-phase 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 13:41:08 +02:00
6dbed91efd docs(roadmap): re-phase milestone — remove Phase 2 (DOM/event-capture privacy)
Per operator charter shift 2026-05-20: "we don't care about privacy hardening.
At least here." Archive flow is internal-only (no external transmission),
which reframes the password-masking P0-5 defect from privacy-regulation
gravity to operator-hygiene polish.

Re-phasing applied across 4 planning artifacts:

ROADMAP.md:
- Original Phase 2 ("Stabilize DOM + event-capture privacy") REMOVED entirely
  (summary list + Phase Details section + Progress table row).
- DOM + event-log VERIFICATION (REQ-rrweb-dom-buffer + REQ-user-event-log)
  ABSORBED by new Phase 3 (SPEC §10 smoke verification).
- Phase numbering: old 3 → new 2 (export), old 4 → new 3 (smoke), old 5 → new 4
  (optional harden). Dependency chains updated accordingly.
- Overview blurb + journey narrative + success criteria refreshed.
- Phase 3 (smoke) explicitly NOT-in-scope: P0-5 password masking dropped.

REQUIREMENTS.md traceability:
- REQ-rrweb-dom-buffer: Phase 2 → Phase 3 (verification scope; UAT harness
  A24+ extension planned).
- REQ-user-event-log: Phase 2 → Phase 3 (same context).
- REQ-password-confidentiality: Phase 2 → Out of Scope (v1) — DEFERRED per
  charter shift.
- REQ-popup-ui, REQ-screenshot-on-export, REQ-archive-layout,
  REQ-meta-json-schema, REQ-archive-export-latency: Phase 3 → Phase 2
  (renumbered; substantively shipped via Plans 01-08 + 01-09 + 01-12;
  residual gaps in Phase 2).
- Coverage: 10 mapped + 1 out-of-scope (was 11 mapped).

PROJECT.md:
- CON-sensitive-data-masking: DEFERRED 2026-05-20 (preserves audit trail
  via strikethrough; rationale documented).
- DEC-004 amendment: rrweb 5000-event cap retained; masking deferred. Cites
  rrweb 2.0.0-alpha.4 maskInputSelector→maskInputFn API change.

STATE.md:
- frontmatter total_phases: 5 → 4.
- stopped_at narrative captures the re-phasing event.

CLI bug note: this re-phasing was attempted via `gsd-sdk query phase.remove 2`
+ canonical `/gsd-remove-phase 2` Skill invocation, but BOTH paths produced
corrupted output (cascading rename via reverse-iteration loop at
phase.cjs:670-679 collapsed all subsequent phases to "Phase 2", plus a
mysterious "2026"→"2002" date corruption). Recovery applied as manual edits
in this commit. CLI bug logged as upstream GSD-framework concern; not a
Mokosh-side issue.

Plan: next is `/gsd-discuss-phase 2` (new Phase 2 = export pipeline; narrowed
scope per re-phasing — ~2-3 plans expected since Plans 01-08 + 01-09 + 01-10
+ 01-12 already shipped most surface).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 13:25:11 +02:00
586836f8a0 docs(01): VERIFICATION + Phase 1 closure markers — goal-backward audit GREEN
gsd-verifier goal-backward audit (2026-05-20) returned GREEN verdict on
Phase 1 (Stabilize Video Pipeline + whole-desktop capture + as-automatic-
as-platform-allows recording start):

- 17/17 must-haves verified: 11 REQs/charters + 6 cross-cutting gates
- 14/14 plans complete (01-01..01-09 + 01-11 spike-pivot + 01-12 + 01-13
  + 01-14 + 01-10)
- 5 operator empirical acks: Plan 01-07 (Chrome playback 2026-05-15) +
  Plan 01-13 (harness 2026-05-19) + Plan 01-12 (brand-fit 2026-05-20) +
  Plan 01-10 cycle-2 ("All good" 2026-05-20) + Plan 01-10 brand-rename
  follow-up (2026-05-20)
- Test gates: vitest 153/153 GREEN; UAT harness 24/24 GREEN; Tier-1 grep
  gate 12 FORBIDDEN_HOOK_STRINGS; pre-checkpoint bundle gates PASS
- 7 P0 audit defects: 6 closed in-Phase-1-scope; P0 #6 (data-sensitive
  masking) properly deferred to Phase 2

Marker flips landed:

- STATE.md status reflects Phase 1 COMPLETE; completed_phases 0 → 1
- ROADMAP.md Phase 1 row [ ] → [x] with closure-arc summary
- REQUIREMENTS.md REQ-video-ring-buffer In-progress → Complete 2026-05-20
- VERIFICATION.md committed (orchestrator-bundle pattern per verifier
  protocol)

Forward-looking deferred (NOT gaps):
- Phase 2: REQ-rrweb-dom-buffer + REQ-user-event-log +
  REQ-password-confidentiality (audit P0 #6)
- Phase 5 hardening: getDisplayMedia cursor visibility; setimmediate
  polyfill new Function pre-existing; tabs permission gap; dark-surface
  logo contrast; 2 ffprobe/ffmpeg test flakes

Phase 2 (Stabilize DOM + event-capture privacy) kickoff pending.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 12:31:36 +02:00
d1ef77a7d1 docs(01-10): state + roadmap + requirements — Plan 01-10 closure
State markers sync after Plan 01-10 closure:

STATE.md:
- progress.completed_plans: 13 → 14
- progress.percent: 93 → 100 (all 14 Phase 1 functional plans complete)
- status: executing (Phase 1 final-closure marker flip pending)
- stopped_at + Last session timestamps refreshed
- Current Position bumped to 14/14 plans complete
- Outstanding Phase 1 gates: Plan 01-10 row marked CLOSED;
  Phase 1 final-closure marker flip listed as remaining work
- Plan 01-10 closure section added mirroring existing 01-12/01-13/01-14
  patterns: 4 wave commits + 5 inter-cycle debug commits + cycle-2 ack
- Performance Metrics: Phase 01 P10 row added (5h, 5 tasks, 14 files)
- Decisions: 3 Plan 01-10 architectural decisions added
  (first-install activation; D-16-toolbar charter preservation;
  three-pipeline DOM population pattern; startVideoCapture D-01
  cleanup gap closure)

ROADMAP.md:
- Plan 01-10 row flipped to [x] with full closure annotations
  (commit chain + harness counts + operator ack date)
- Plan 01-09 row annotated with closure-cycle follow-up debug
  commits (a2dfc8c startVideoCapture no-tab + 4bba679 notifStartup
  text split — both landed during Plan 01-10 closure cycle)
- Phase 1 plans-count narrative updated: "all 14 functional plans
  complete; Phase 1 final-closure marker flip pending"
- Progress table: Phase 1 plans complete 13/14 → 14/14;
  status row updated to "Final-closure marker flip pending"

REQUIREMENTS.md:
- Footer timestamp + closure note updated: 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).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 12:10:56 +02:00
52dc2e6a6e docs(01-10): summary — welcome tab + 5-cycle debug closure + brand polish (153/153 vitest, 24/24 UAT GREEN, ack 2026-05-20)
Plan 01-10 (welcome tab) full SUMMARY landing closure of Phase 1's final
functional plan. Welcome tab landed end-to-end across 4 waves + Wave 4
operator empirical UAT cycle 2 ack "All good" 2026-05-20.

Architecture:
- chrome.runtime.onInstalled('install') + chrome.storage.local
  flag-gating (onboarding-completed:true + installed-at:<Date.now()>)
  + chrome.tabs.create + fire-and-forget .catch defense-in-depth.
- Plan 01-12 must_have #9 path-B contract honored: welcome.css opens
  with `@import '../shared/tokens.css';` (canonical Lora display +
  IBM Plex Sans UI + D-04 Loom palette); NO placeholder
  welcome-tokens.css file.
- chrome.i18n.getMessage for welcomeHeroRu + welcomeHeroEn with
  `|| <en-const>` fallback (Plan 01-12 fallback pattern preserved).
- Vite `?url` import + auto-WAR idiom bundles canonical
  mokosh-mark.svg as inline data URL in welcome chunk
  (closure-cycle debug 01-10-welcome-page-missing-mark).
- Three-pipeline DOM population: populateMark walks
  [data-mokosh-slot='mark']; populateCopy walks [data-mokosh-key]
  from in-file COPY map; populateI18n walks [data-mokosh-i18n-key]
  from chrome.i18n.getMessage.
- D-16-toolbar charter preserved: welcome page is informational +
  read-only; NO REQUEST_PERMISSIONS / chrome.runtime.sendMessage
  start path. CTA copy directs operator at toolbar icon.

Wave structure (4 plan-wave commits):
- 89e1e09 Wave 0 RED onboarding tests (3 tests A/B/C)
- 49f087f Wave 1 welcome bundle + Vite entries + manifest
  web_accessible_resources
- 8f329d8 Wave 2 openWelcomeIfFirstInstall + onInstalled wiring
- b112cb7 Wave 3 harness A15+A16+A17

Cycle-1 operator UAT rejection 2026-05-20 ~08:56 surfaced two
concerns + 5 inter-cycle debug fixes (in commit order):
- 4bba679 fix(01-09): notifStartup text split (notifStartupCta for
  onStartup; notifRecordingStarted reserved for manual-start)
- d48a715 fix(01-10): welcome page mark — bundle canonical
  mokosh-mark.svg via Vite ?url + populateMark + A17.8 sub-check
  (Plan 01-12 must_have #9 path-A swap-in gap closed)
- 0854baf fix(01-10): vitest build-test it() timeout bump to 30s
  for slower welcome-page build
- a2dfc8c fix(01-09): startVideoCapture — remove stale active-tab
  dependency (D-01 cleanup gap; +3 RED→GREEN tests at
  start-video-capture-no-tab.test.ts)
- d21ed17 fix(01-12): brand polish — replace stale 'AI Call Recorder'
  refs with Mokosh (4 files; .planning/intel/* preserved as audit
  trail)

Harness deltas:
- A15-A17 added at b112cb7 (24/24 UAT GREEN; A17 with 7 sub-checks
  incl. A17.7 --mks-rec getComputedStyle probe resolving to
  rgb(178,84,61) canonical).
- A17.8 mark-bundling sub-check added at d48a715 (verifies welcome
  chunk JS contains inlined data:image/svg+xml URL with canonical
  viewBox='0 0 32 32' preserved).
- FORBIDDEN_HOOK_STRINGS unchanged at 12 (A15-A17 use chrome.tabs
  .query + chrome.storage.local.get + fetch + DOMParser +
  getComputedStyle production APIs exclusively).

Test deltas:
- vitest 147 → 153 GREEN (+6: 3 onboarding tests Wave 0 + 3
  start-video-capture-no-tab tests closure-cycle debug a2dfc8c).
- UAT harness 21/21 → 24/24 GREEN (A0-A14 + A15-A17 + A18-A22 + A23).

Pre-checkpoint bundle gates per saved memory
feedback-pre-checkpoint-bundle-gates.md: Tier-1 hook-string grep
+ SW CSP-safety + Node-globals + DOM-globals + manifest validation
+ en↔ru parity — all PASS. setimmediate polyfill new Function in
SW chunk confirmed pre-existing (logged at
.planning/phases/01-stabilize-video-pipeline/deferred-items.md
for Phase 5 hardening per Plan 01-12 Wave 7 disclosure).

Operator brand-fit cycle-2 ack received verbatim "All good" + cycle-2
follow-up brand-rename ack via d21ed17. Phase 1's final functional
plan delivered; Phase 1 final-closure unblocked pending REQUIREMENTS
/ ROADMAP / STATE marker flip + optional /gsd-verify-work 1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 12:10:30 +02:00
d21ed17310 fix(01-12): brand polish — replace stale 'AI Call Recorder' refs with Mokosh (4 files)
Plan 01-12 D-07 (commit 5efc2a8) migrated manifest.json:name + tooltip
+ extName/extDesc keys to chrome.i18n placeholders + _locales/{en,ru}/
messages.json resolving to 'Mokosh — Session Capture' (EN) / 'Mokosh —
Запись сессии' (RU). However, 4 trailing references to the pre-D-07
literal 'AI Call Recorder' in non-manifest content surfaces were never
propagated. Operator noticed during Plan 01-10 cycle-2 UAT 2026-05-20.

This commit applies the user-approved 4-file surgical rename:

  - src/welcome/copy.ts: welcome.body.cta.toolbar RU CTA
    "иконку AI Call Recorder" → "иконку Mokosh" (matches toolbar tooltip
    i18n key tooltipOff = "Mokosh — щёлкните, чтобы начать запись").
    Inline rationale comment added cross-ref'ing the i18n key + this
    debug session.

  - README.md: H1 + first paragraph rewritten to
    "# Mokosh — Session Capture" + EN tagline line. Rest of README body
    preserved verbatim (technical-stack section historical mentions
    left as project history, not brand surface).

  - package.json: name "ai-call-extension" → "mokosh-session-capture",
    description rewritten to "Mokosh — Session Capture: Chrome MV3
    extension for operator session recording." version, scripts,
    dependencies, devDependencies untouched.

  - tests/i18n/manifest-i18n.test.ts: header comment block rewritten to
    label the "AI Call Recorder" string as Wave-0 historical state +
    describe the post-D-07 regression-pin role. Test bodies + assertions
    unchanged (already pin the post-D-07 canonical state).

Preservation rationale: .planning/intel/* (brand-decisions-v1.md D-07,
design-system.md, brand-identity.md, classifications/README-*.json,
design-incoming/system/bundle/mokosh-handoff/handoff.html) is audit
trail documenting the "why" of D-07 — kept verbatim. _locales/{en,ru}/
messages.json and manifest.json already post-D-07 canonical — untouched.

Acceptance gates (all PASS 2026-05-20):
  - Empirical grep src/ tests/ README.md package.json: ZERO non-historical
    "AI Call Recorder" matches (only the labeled audit anchor in
    tests/i18n/manifest-i18n.test.ts:8).
  - npx tsc --noEmit: clean.
  - npm run build: ✓ built in 5.29s.
  - npx vitest run tests/i18n/manifest-i18n.test.ts: 10/10 GREEN.
  - npx vitest run tests/background/no-test-hooks-in-prod-bundle.test.ts
    (Tier-1 hook-string grep gate): 13/13 GREEN; FORBIDDEN_HOOK_STRINGS
    list intact.
  - npm test: 151/153 (2 pre-existing ffprobe/ffmpeg timeout flakes in
    webm-remux + webm-playback — verified identical to pristine HEAD
    a2dfc8c via git stash baseline; unrelated to rename).
  - npm run test:uat: 24/24 GREEN.
  - Production bundle grep dist/: ZERO "AI Call Recorder" + ZERO
    "ai-call-extension" matches.

Unblocks Plan 01-10 closure + Phase 1 final closure (REQUIREMENTS /
ROADMAP / STATE marker flip).

Debug record: .planning/debug/resolved/01-12-stale-ai-call-recorder-references.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 11:49:46 +02:00
a2dfc8cb9b fix(01-09): startVideoCapture — remove stale active-tab dependency (D-01 cleanup gap)
The legacy chrome.tabs.query({ active: true, currentWindow: true }) +
"No active tab found" validation inside startVideoCapture were load-
bearing in the pre-D-01 chrome.tabCapture era but became functionally
dead after Plan 01-09's D-01 conversion to getDisplayMedia-in-offscreen.
The only post-D-01 consumer was a log line at index.ts:521.

The dead validation caused an activeTab-permission-scope asymmetry
between callers: chrome.action.onClicked grants activeTab on the click
gesture (so tab.url was readable → toolbar path worked silently) but
chrome.notifications.onClicked does NOT grant activeTab and the extension
has no `tabs` permission, so notifications.onClicked → startVideoCapture
threw "No active tab found" before reaching ensureOffscreen. Operator
2026-05-20 UAT against the new notifStartupCta CTA copy ("Mokosh ready.
Click to start a recording.", commit 4bba679) surfaced the silent
notification failure.

Surgical fix: remove the dead tab query + validation + tab-dependent log
(src/background/index.ts:514-521); replace with a tab-independent log
that documents WHY (cites D-01 + this debug session). captureScreenshot
+ saveArchive retain their genuine tab dependencies (tab.windowId for
chrome.tabs.captureVisibleTab; tab.id for content-script sendMessage).

Tests: tests/background/start-video-capture-no-tab.test.ts (NEW) pins
the contract with 3 cases (tabs.query → []; → [{id}] url-less; →
[{id,url,windowId}] regression guard for toolbar path).

Gates: vitest 153/153 GREEN (was 150/150 baseline; +3); test:uat 24/24
GREEN; tsc clean; build clean. Pre-checkpoint bundle gates per
feedback-pre-checkpoint-bundle-gates.md: SW chunk hook-string Tier-1
grep 0 matches; eval/Node-global/DOM-global matches unchanged from
baseline (all vendor-library feature-detect, guarded; no new imports).

Debug record: .planning/debug/resolved/01-09-notification-start-no-active-tab.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 11:33:18 +02:00
0854baf66c fix(01-10): vitest build-test it() timeout — bump to 30s for slower welcome-page build
The build-completes Tier-1 gate at tests/background/no-test-hooks-in-prod-bundle.test.ts:247
was racing vitest's default 5000ms it() ceiling. Plan 01-10 closure shipped the welcome
page (commits d48a715 welcome mark + 49f087f welcome HTML/CSS/JS + 8 WOFF2 fonts) which
slowed standalone `npm run build` from ~2.88s to ~5.28s. The exec-level
BUILD_TIMEOUT_MS = 60_000 child-process bound was correctly declared at line 240, but
the surrounding it() block had no timeout option, so the 5s default fired first and the
60s exec bound was never reachable.

Surgical fix: add `, 30_000` 3rd arg to the it() call. 30s is ~6× the observed build
duration and well below the 60s exec ceiling, so both bounds remain meaningfully
active. SKIP_BUILD=1 env-var escape hatch untouched.

Acceptance gates:
- `npm test` (FULL, no SKIP_BUILD=1): 150/150 GREEN, exit 0
- `npx tsc --noEmit`: exit 0
- `npm run build`: exit 0
- Tier-1 grep gate: PASS (all 12 FORBIDDEN_HOOK_STRINGS asserted against dist/)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 10:52:39 +02:00
d48a715da5 fix(01-10): welcome page mark — bundle canonical mokosh-mark.svg + replace placeholder
Plan 01-10 must_have #9 path-A swap-in (landed 2026-05-20 per debug
session 01-10-welcome-page-missing-mark). Closes the planning-coverage
gap where Plan 01-12 path-B (canonical tokens import) ran ahead of
01-10, leaving the welcome hero with a text placeholder 'Mokosh'
inside the rec-bg circle instead of the canonical 2×2 woven-square
mark from src/shared/brand/mokosh-mark.svg.

Why Option B (Vite ?url import) over manual WAR (A) or inline SVG (C):
- @crxjs/vite-plugin ^2.0.0-beta.25 auto-WARs transitively-reachable
  resources from extension pages — no manifest.json edit needed.
- Vite default-inlines small SVGs (~600 bytes < 4096 byte default
  assetsInlineLimit) as data:image/svg+xml URLs in the welcome chunk
  — no extra HTTP request, no extra WAR entry.
- Hashed asset fallback works automatically if the SVG grows past
  the inline limit in future revisions.
- Existing font-bundling precedent (dist/assets/Lora-*.woff2 +
  IBMPlex*.woff2) proves the Vite + crxjs pipeline.

Files modified:
- src/welcome/welcome.ts — added markUrl import + populateMark() that
  walks [data-mokosh-slot='mark'] and injects an <img>.
- src/welcome/welcome.html — added explanatory comment block; preserved
  the data-mokosh-slot wrapper for forward-compat (the placeholder
  span remains as the JS-fail-gracefully fallback).
- src/welcome/welcome.css — added .welcome-hero__mark-img rule
  (60% sizing inside the existing styled circle wrapper).
- src/welcome/copy.ts — added 'welcome.hero.mark.alt' COPY key
  (Russian per D-03 Sober voice).
- globals.d.ts — added *.svg?url ambient module declaration
  (Vite recommended pattern; keeps tsconfig.json types: ['chrome']
  clean by not requiring vite/client triple-slash directives).
- tests/uat/extension-page-harness.ts — extended A17 with A17.8
  sub-check verifying the canonical mark SVG is bundled into the
  welcome chunk (data URL OR file URL form) AND that the canonical
  viewBox='0 0 32 32' is preserved through bundling.

Acceptance gates passed:
- npx tsc --noEmit exit 0
- npm run build exit 0
- SKIP_BUILD=1 npm test → 150/150 GREEN
- npm run test:uat → 24/24 GREEN including A17.8
- Tier-1 hook-string grep gate PASS (no FORBIDDEN_HOOK_STRINGS
  in production bundle).
- Manifest valid JSON; web_accessible_resources auto-bundled.
- Pre-checkpoint bundle gates 1/2/3: vendor pre-existing hits
  (JSZip + ts-ebml) confirmed identical pre-change via git stash
  baseline; not caused by this fix.

Forward-looking deferred (out of scope):
- Issue 2 dark-surface contrast (e.g. chrome.notifications icon128
  may need a light-stroke variant). The welcome hero's rec-orange
  BG already provides high contrast with the dark ink stroke — this
  is correct design. Per the orchestrator's explicit constraint,
  light-variant mark for dark notification panels is deferred to
  Phase 5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 10:28:58 +02:00
4bba679e39 fix(01-09): notifStartup text split — notifStartupCta for onStartup; notifRecordingStarted for manual-start
Operator UAT 2026-05-20 rejected the build because the OS notification fired
on `chrome.runtime.onStartup` ("Recording started. I'm watching the last 30
seconds.") implied recording had auto-started when in fact recording was
not running. Per Phase 1 always-on charter recording does NOT auto-start;
the notification is the gesture surface that invites the operator to start
one (notifications.onClicked → startVideoCapture, src/background/index.ts:1038).

Root cause: a single i18n key `notifStartup` conflated the pre-recording
CTA-with-gesture path (the only path actually wired today) and a future
post-manual-start confirmation path. The key's own `.description` field
acknowledged the conflation. Operator-facing text leaned toward the
confirmation phrasing.

Fix (key split, no behavior change):
- `notifStartupCta` — EN: "Mokosh ready. Click to start a recording." /
  RU: "Mokosh готов. Нажмите, чтобы начать запись." — wired into the
  onStartup handler.
- `notifRecordingStarted` — preserves the original text ("Recording
  started. I'm watching the last 30 seconds." / "Запись запущена…") for
  a future post-manual-start confirmation flow.
- Fallback constant renamed `NOTIF_STARTUP_FALLBACK` →
  `NOTIF_STARTUP_CTA_FALLBACK`; value updated to match the new CTA text.
- Inline test comment in tests/background/onstartup-notification.test.ts
  refreshed to reference the new key + fallback. Assertion regex
  /recording|recor|click/i covers both fallback + resolved locale variants,
  no logic change.

Notification behavior preserved: same id prefix `mokosh-startup-`, same
priority, same icon, same onClicked → startVideoCapture wiring. No new
test-mode symbols (FORBIDDEN_HOOK_STRINGS inventory stays at 12).

Files modified:
- _locales/en/messages.json
- _locales/ru/messages.json
- src/background/index.ts
- tests/background/onstartup-notification.test.ts

Verification:
- npx vitest run --exclude tests/build/** --exclude tests/background/no-test-hooks-in-prod-bundle.test.ts: 104/104 GREEN
- npx vitest run tests/i18n/ tests/background/onstartup-notification.test.ts: 18/18 GREEN (locale-parity 4/4 + onstartup-notification 14/14)
- npx tsc --noEmit clean on src/background/index.ts

The 2 build-dependent vitest gates (tests/build/no-remote-fonts.test.ts +
tests/background/no-test-hooks-in-prod-bundle.test.ts) and npm run test:uat
are deferred to orchestrator-level re-verification after the parallel
Plan 01-10 mark-bundling fix also lands (operator-UAT re-spawn coordinated
by orchestrator).

Debug record: .planning/debug/resolved/01-09-startup-notification-misleading-text.md
Operator UAT rejection event: 2026-05-20

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 10:14:08 +02:00
7f58e0ae31 fix(01-10): revise plan per 01-12 + 01-14 baselines (vitest 98→147, UAT 15→21, FORBIDDEN 10→12, welcome.css @imports canonical tokens, welcomeHero keys read from chrome.i18n)
Surgical amendment to unexecuted Plan 01-10 absorbing the post-draft
landing of Plan 01-12 (canonical src/shared/tokens.css + 16 i18n keys
including welcomeHeroRu/welcomeHeroEn; 2026-05-20 operator brand-fit
ack) and Plan 01-14 (vitest +2 + UAT +1 + FORBIDDEN_HOOK_STRINGS +2).

Baseline shifts:
- vitest 98 → 147 GREEN (post Plan 01-12 + 01-14); plan close target 150.
- UAT 15 → 21 GREEN (A0-A14 + A18-A22 + A23); plan close target 24
  (A0-A14 + A15-A17 + A18-A22 + A23).
- FORBIDDEN_HOOK_STRINGS 10 → 12 (Plan 01-14: lastGetDisplayMediaConstraints
  + get-last-getDisplayMedia-constraints); Plan 01-10 introduces no new
  test-mode symbols; inventory unchanged at 12.

Plan 01-12 must_have #9 path-B contract honored end-to-end (Plan 01-12
landed FIRST, so the welcome page adopts canonical assets directly):

- welcome.css opens with `@import '../shared/tokens.css';` (NO placeholder
  welcome-tokens.css; removed from files_modified).
- D-08 hero tagline elements use data-mokosh-i18n-key='welcomeHeroRu' +
  data-mokosh-i18n-key='welcomeHeroEn'; welcome.ts reads via
  chrome.i18n.getMessage with `|| <en-const>` fallback per Plan 01-12
  fallback pattern. WELCOME_HERO_RU_FALLBACK + WELCOME_HERO_EN_FALLBACK
  constants exported from copy.ts for the degradation path.
- copy.ts COPY map retains non-tagline keys only (page title + explainer
  lines + CTA + footer privacy; engineering placeholders per D-03).
- A17 design-swap-readiness invariant extended with:
  - A17.5: welcome.css contains canonical @import directive OR inlined
    `--mks-rec:` evidence;
  - A17.6: bundled JS contains COPY[ OR chrome.i18n.getMessage('welcomeHero;
  - A17.7 NEW: getComputedStyle probe on var(--mks-rec) returns non-default
    value (canonical rgb(178, 84, 61) = #b2543d = --mks-madder-600 per
    Plan 01-12 Wave 4 D-04 Loom palette adoption).
- depends_on extended to [01-09, 01-13, 01-14, 01-12].

Preserved verbatim: 5-task structure, A15/A16 contracts, D-02/D-08/D-09
references, threat model + STRIDE register, operator empirical checkpoint
shape, Plan 01-12 default_locale='en' + __MSG_*__ + __VITE_DEV__ +
__MOKOSH_UAT__ + src/shared/tokens.css.

Validated: gsd-sdk frontmatter.validate + verify.plan-structure both PASS;
task_count=5, all tasks complete with files/action/verify/done.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 08:48:24 +02:00
66e6f503a4 docs(01-12): state + roadmap + requirements — Plan 01-12 closure
Plan 01-12 closure documentation sync per the plan's Wave 7 Task 1
spec. Three docs land together as one atomic closure commit per the
Plan 01-13 + 01-14 closure cadence convention.

STATE.md changes:
- status: verifying → executing (Plan 01-10 welcome tab still pending)
- stopped_at: Plan 01-14 → Plan 01-12 closed via Wave 7 brand-fit
  ack 2026-05-20 'all good'; Plan 01-10 remains as final Phase 1
  functional plan
- last_updated + last_activity: 2026-05-19 → 2026-05-20
- progress.completed_plans: 12 → 13 (13 plans: 01-01..01-09 + 01-11
  spike + 01-12 + 01-13 + 01-14; Plan 01-10 pending)
- progress.percent: 86 → 93
- "Plan 01-13 closure" header annotated: brand/design ack subsequently
  closed via Plan 01-12 Wave 7 2026-05-20
- New "Plan 01-12 closure (2026-05-20)" section: 7-wave execution arc
  with all 10 commit hashes (3fe018b plan-baseline-revision → 34a9ce1
  Wave 0 → f86fd60 + abab6e1 Wave 1 → 7732a30 Wave 2 → 110cebc Wave 3
  → 468f16d Wave 4 → e8d2881 Wave 5 → b909c37 Wave 6 + 865d394
  pre-checkpoint + f319c7d SUMMARY); R2 Lora substitution; 16 i18n
  keys; branded icons; BADGE_REC_COLOR #b2543d; chrome.i18n fallback;
  A18-A22 harness; pre-checkpoint bundle gates per
  feedback-pre-checkpoint-bundle-gates.md; setimmediate polyfill
  discovery logged to deferred-items.md (Phase 5 hardening); operator
  brand-fit ack; Plan 01-13 Task 9 functional closure
- "Outstanding Phase 1 gates" updated: Plan 01-13 Task 9 + Plan 01-12
  CLOSED; only Plan 01-10 remains
- Performance Metrics table: Plan 01-12 entry appended (~10h
  cumulative; 10 tasks; ~50+ files)
- Decisions section: 2 new entries for Plan 01-12 design integration
  + Plan 01-13 Task 9 closure linkage
- Session Continuity: last/prior session updated to 2026-05-20 /
  2026-05-19

ROADMAP.md changes:
- Phase 1 Plans list: 01-12-PLAN.md entry flipped from [ ] to [x]
  with full closure annotation (R2 Lora self-host, tokens.css
  canonical, 16 i18n keys across en+ru, branded Loom icons, manifest
  i18n, BADGE_REC_COLOR madder #b2543d, chrome.i18n fallback,
  harness A18-A22, operator brand-fit ack 2026-05-20 'all good')
- Phase 1 plan count: 13 → 14 plans (01-01 through 01-14)
- Progress table Phase 1 row: 7/7 Complete → 13/14 Executing with
  closure-status disambiguation (functional via Plan 01-13;
  design/brand via Plan 01-12; Plan 01-10 welcome tab remains)

REQUIREMENTS.md changes:
- REQ-install-clean: [ ] Pending → [x] Complete (2026-05-20)
  with annotation: fresh build clean; zero remote-font CSP errors;
  branded icons; en+ru manifest:name resolution; operator brand-fit
  ack
- REQ-manifest-permissions: [ ] Pending → [x] Complete (2026-05-20)
  with annotation: manifest:name + :description +
  :action.default_title migrated to __MSG_*__ + default_locale='en';
  manifest validation PASS; en↔ru parity; permissions DEC-011
  baseline UNCHANGED
- Traceability table: both requirements moved from Phase 3/4 Pending
  to "Phase 1 closure via Plan 01-12" Complete
- Footer: last-updated 2026-05-15 → 2026-05-20 with annotation
  noting the requirements flipped at Plan 01-12 closure

No code changes; pure documentation closure sync.

Closure commit hashes:
- SUMMARY: f319c7d (.planning/phases/01-stabilize-video-pipeline/01-12-SUMMARY.md)
- State sync: this commit (.planning/STATE.md + .planning/ROADMAP.md
  + .planning/REQUIREMENTS.md)

Phase 1 status post-closure:
- Functional contract: CLOSED via Plan 01-13 harness PASS (2026-05-19)
- Design/brand contract: CLOSED via Plan 01-12 brand-fit ack
  (2026-05-20)
- Remaining: Plan 01-10 (welcome tab) — operator-facing onboarding
  surface; canonical src/shared/tokens.css from Plan 01-12 now
  available for swap-in

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 08:33:52 +02:00
f319c7dc6e docs(01-12): summary — design integration landed (147/147 vitest, 21/21 UAT, brand-fit ack 2026-05-20)
Plan 01-12 closure SUMMARY landed at .planning/phases/01-stabilize-
video-pipeline/01-12-SUMMARY.md per the plan's <output> block + 01-13/
01-14 closure cadence. Mirrors the 01-13-SUMMARY frontmatter shape +
body sections (One-Liner / What Landed by Wave / Test Counts /
Deviations / Architectural Notes / Self-Check / Known Limitations /
Bridge to Phase 1 Closure).

Plan 01-12 design integration in one sentence: Lora self-hosted via
R2 designer substitution (Newsreader → Lora for Cyrillic coverage,
2026-05-19); src/shared/tokens.css canonical with 8 local @font-face
rules and zero remote URLs; 16 i18n keys across en + ru with parity;
branded Loom-mark icons replace Bug A placeholders; src/popup +
src/background migrated to chrome.i18n.getMessage with || <const>
fallback; UAT harness extended with A18-A22; pre-checkpoint bundle
gates established per feedback-pre-checkpoint-bundle-gates.md;
operator brand-fit ack received 2026-05-20 verbatim "all good".

Gate evidence (per Wave 7 pre-checkpoint 865d394 + this closure):
- vitest: 147/147 GREEN (re-verified on closure day; 26 test files)
- npm run test:uat: 21/21 GREEN (A0-A14 + A18-A22 + A23)
- npx tsc --noEmit: clean
- npm run build + npm run build:test: both clean
- MV3 CSP self-host: 0 googleapis / 0 https://fonts in dist/
- Tier-1 forbidden-strings: 13/13 GREEN (no new test-mode symbols)
- Operator brand-fit empirical ack 2026-05-20: "all good"

Closure linkage:
- Plan 01-12 functionally CLOSED (10/10 tasks; 7/7 waves)
- Plan 01-13 Task 9 (operator brand/design ack on loaded extension)
  functionally CLOSED via this checkpoint (same operator + same
  empirical surface coverage)
- Phase 1 design/brand contract CLOSED; only Plan 01-10 (welcome tab)
  remains as the last Phase 1 functional plan
- Phase 2 inherits tokens.css + chrome.i18n patterns + OFL self-host
  recipe + pre-checkpoint bundle gates as production conventions

Out-of-scope discovery (Wave 7 pre-checkpoint, logged for Phase 5
hardening, NOT a Plan 01-12 regression): setimmediate polyfill
`new Function` in SW chunk via vite-plugin-node-polyfills. Pre-existing
across Phase 1 history; logged at deferred-items.md. Suggested
follow-up: switch to a minimal Buffer shim or inline Buffer primitives
to drop the polyfill entirely.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 07:59:34 +02:00
865d394ae0 docs(01-12): wave-7 pre-checkpoint — log out-of-scope discovery (setimmediate polyfill new Function pre-existing)
Wave 7 pre-checkpoint bundle gates per feedback-pre-checkpoint-bundle-gates.md
revealed a pre-existing benign concern in the SW production bundle:

`vite-plugin-node-polyfills` (configured for Buffer in vite.config.ts)
bundles the upstream `setimmediate` package which contains a fallback
`new Function("" + I)` evaluated when setImmediate is called with a
non-function argument. Production source code does NOT call
setImmediate(string); the construct is dead at the runtime call-graph
level but Rollup conservatively preserves it (behind a runtime
typeof check, not a static dead branch).

Verified pre-existing across Phase 1 history via `git checkout main --
src/background/index.ts vite.config.ts && npm run build` — same
`new Function` count. Plan 01-12 made NO changes to the polyfill
configuration; this is logged for future tightening (Phase 5
hardening or a dedicated MV3 CSP audit plan), NOT for fix in this
plan per the deviation-rule SCOPE BOUNDARY.

All other pre-checkpoint bundle gates PASS:
- Tier-1 forbidden-strings: 13/13 GREEN (no new test-mode symbols)
- SW-bundle-import: 15/15 GREEN
- Node-globals (Buffer.*) in SW chunk: 0
- DOM-globals direct SW calls: none
- Manifest validation: PASS (__MSG_*__ + default_locale='en' +
  16 i18n keys per locale; en+ru parity verified)
- Tokens.css MV3 CSP self-host: 0 googleapis / 0 https://fonts in dist/
- Icons rasterized: 8-bit RGBA at 406/784/1952 B
- vitest: 147/147 GREEN
- npm run test:uat: 21/21 GREEN (A1..A14 regression-free + A18..A22
  new + A23 from 01-14)
- npx tsc --noEmit: clean
- npm run build + npm run build:test: clean

Surfacing Wave 7 operator brand-fit checkpoint to orchestrator next.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 07:47:13 +02:00
3fe018beb9 fix(01-12): revise plan baselines per Plan 01-14 landing (vitest 98→100, UAT 15→16, FORBIDDEN_HOOK_STRINGS 10→12)
Surgical amendment — Plan 01-12 is unexecuted; safe for in-place revision.
Plan 01-14 landed (b46712352541459792c0f) since 01-12 was authored,
adding monitorTypeSurfaces:'include' + UAT A23 + 2 FORBIDDEN_HOOK_STRINGS
entries. Plan 01-12 baseline arithmetic updated to reflect post-01-14
floors and depends_on chain extended.

Changes:
- frontmatter depends_on: append 01-14 (canonical sequential-dependency declaration)
- must_haves truth #11: 10 strings → 12 strings post-Plan-01-14, with provenance note
- must_haves truth #13: vitest 98→100→106; UAT 15→16→21 (or 19→24 with 01-10);
  A23 added to no-regression list alongside A0-A14 + (A15-A17 if 01-10)
- Embedded FORBIDDEN_HOOK_STRINGS code block: 10 → 12 entries (lastGetDisplayMediaConstraints,
  get-last-getDisplayMedia-constraints) with attribution comment
- Wave 6 task narrative + verify + done: 20/20 → 21/21; 23/23 → 24/24
- Wave 7 closure narrative + one-liner + checkpoint copy: same arithmetic update
- Threat model T-01-12-08: inheritance updated to include T-1-14-*; grep-gate floor 10→12
- Verify-block harness orchestrator grep gate: strengthened with `grep -v '^#'` filter
  to prevent self-invalidating count from comment lines (per planner.md gate hygiene)
- Success criteria items 3, 4, 9: vitest 98→100; UAT 20→21; inventory 10→12

Preserved verbatim (per surgeon-not-architect):
- 7-wave structure (Wave 0 fonts/tokens/icons/i18n RED scaffolds, Wave 1 fonts+tokens.css,
  Wave 2 icons, Wave 3 manifest i18n, Wave 4 popup/welcome adoption, Wave 5 8 i18n strings,
  Wave 6 harness A18-A22, Wave 7 operator brand-fit checkpoint)
- 10 tasks (validated via gsd-sdk verify.plan-structure)
- R2 Lora baked-in decision
- D-01..D-09 decision references
- All files_modified entries
- Threat model entries other than T-01-12-08 inheritance line
- Designer ack references
- Operator checkpoint (Wave 7)
- Must_have truths #1-10 and #12

Validation:
- gsd-sdk frontmatter.validate → valid:true
- gsd-sdk verify.plan-structure → valid:true, errors:0, task_count:10
- grep verification: zero stale references to 98/104/15/15/20/20/23/23/18/18/"at 10"
- All new baselines present at 32 update sites
- diff: 1 file changed, 34 insertions(+), 30 deletions(-)

Next step: plan-checker re-validation of arithmetic + consistency before executor spawn.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 21:45:58 +02:00
9792c0f6c3 docs(01-14): state + roadmap + requirements — Plan 01-14 closure
- STATE.md: advance plan counter, update progress (12/14 = 86%), record
  metric (Plan 01-14: 49m, 1 task, 7 files), add decision, record session.
- ROADMAP.md: update phase-01 progress table (plan_count=14, summary_count=12).
- REQUIREMENTS.md: mark REQ-video-ring-buffer complete (final closure for
  the Phase-01 video-pipeline charter).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 21:41:26 +02:00
52541452e0 docs(01-14): summary — picker enhancement landed (16/16 UAT GREEN, 100/100 vitest GREEN)
Canonical closure artifact for Plan 01-14:
- monitorTypeSurfaces:'include' shipped (W3C spec §6.1; Chrome >= 119 picker narrowing)
- A23 harness regression gate wired into the UAT orchestrator (post-A14 chain)
- Tier-1 grep gate inventory extended in lockstep (12 forbidden strings; was 10)

Single atomic feat commit (b467123) for the entire 1-task plan.

Verification: vitest 100/100 GREEN (+2 new parametrized FORBIDDEN_HOOK_STRINGS
tests; both PASS — production bundle hook-free for the new surface). UAT
harness 16/16 GREEN (was 15/15). tsc + build clean.

Ceremony: replaces the retired AMENDMENT-A.md improvisation path per
01-11-SUMMARY.md Architectural Notes. Canonical GSD flow — plan (41c1f7e)
→ checker (B-01-14-01) → revision (433ee28) → executor (b467123) → SUMMARY.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 21:40:11 +02:00
433ee280f3 fix(01-14): revise plan per checker — include test-expectation update (B-01-14-01)
Plan-checker BLOCKER B-01-14-01: original plan's must_haves truth #5 understated
baseline regression risk. Adding `monitorTypeSurfaces: 'include'` as a sibling
constraint in src/offscreen/recorder.ts would have dropped vitest from 98/98
GREEN to 97/98 RED because tests/offscreen/display-surface-constraint.test.ts
Test 1 (line 223-226) uses strict deep-equality (toHaveBeenCalledWith, NOT
expect.objectContaining) on the constraints object — the test author's intent
(comment at line 221-222) is to catch future drops of ANY field.

Surgical revision per references/planner-revision.md (surgeon-not-architect):
- Frontmatter: add tests/offscreen/display-surface-constraint.test.ts to
  files_modified list.
- must_haves truth #5: replace the "no existing unit test references the
  constraints object" claim with a positive statement that the strict-deep-
  equality assertion at lines 223-226 is updated in lockstep; preserves the
  test author's "no objectContaining" discipline; explicit no-transient-RED
  guarantee across commit boundaries.
- must_haves artifacts: new entry for the test file documenting the in-place
  edit shape and the preserved test author comment.
- must_haves key_links: new link entry pairing the test assertion with the
  source call site under the lockstep contract.
- Interfaces block: add the explicit "test-expectation lockstep update" code
  fragment with the chosen key ordering (video → monitorTypeSurfaces → audio)
  so the executor lands the source change and the test update with matching
  shapes.
- Task 1 <files>: add tests/offscreen/display-surface-constraint.test.ts.
- Task 1 <action>: insert new Step 1b between Step 1 (source change) and
  Step 2 (offscreen-hooks bridge) — full single-line edit spec at lines
  223-226, preserve toHaveBeenCalledWith contract, preserve comment block,
  same-commit guarantee.
- Task 1 verify-block expected outputs: explicitly call out that 98/98 GREEN
  is preserved BECAUSE Step 1b lands (without it, 97/98 RED on the strict-
  deep-equality assertion).
- Task 1 <done>: add line covering the lockstep test update + the no-transient-
  RED guarantee.
- <verification> phase gate: add new check #2 (test-expectation lockstep)
  between source-line correctness and A23 round-trip.
- <success_criteria>: add bullet for the lockstep test-expectation update.
- <output> SUMMARY contract: add "Revision linkage" bullet documenting that
  the plan was revised once after the plan-checker flagged B-01-14-01.

Untouched (per checker's preserve-verbatim list):
- Source-line target (src/offscreen/recorder.ts:270)
- Harness wiring references (assertA3 686, driveA14 987, __mokoshHarness
  1922+1942, drivers array 289-312, Total comment 354)
- FORBIDDEN_HOOK_STRINGS lockstep contract (both inventories)
- `_constraints` capture path
- Scope discipline (still 1 task, autonomous, no checkpoint)
- Research traceability (Plan 01-10 RESEARCH §5 + §Pitfall-5 + W3C §6.1)
- Threat model (T-01-14-04 mirrors Plan 01-13)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 20:41:09 +02:00
41c1f7e82f feat(01-14): plan — monitorTypeSurfaces picker enhancement (canonical post-closure scope)
Plan 01-14 ships W3C Screen Capture monitorTypeSurfaces: 'include' (Chrome
119+) on the offscreen getDisplayMedia call, plus an A23 harness regression
assertion that verifies the constraint reaches the call site via the
existing offscreen-hooks bridge.

Scope: 1 source line + A23 wiring + Tier-1 grep gate inventory update
(lockstep extension of unit-gate + UAT A0 FORBIDDEN_HOOK_STRINGS).
Autonomous, single executor; no operator empirical checkpoint (UAT 16/16
harness coverage suffices per feedback-pre-checkpoint-bundle-gates.md).

Canonical sources:
- Plan 01-10 RESEARCH section 5 ('monitorTypeSurfaces: include' recommendation)
- Plan 01-10 RESEARCH section Pitfall-5 ('Misinterpreting displaySurface
  as a hard constraint' — monitorTypeSurfaces is the picker-UI complement
  to D-15's post-grant validation)
- W3C Screen Capture spec section 6.1 DisplayMediaStreamOptions
- developer.chrome.com/docs/web-platform/screen-sharing-controls

Decisions honored:
- D-01 (whole-desktop only via getDisplayMedia; reject window/tab) — the
  new constraint is the picker-UI realization of D-01's intent.
- D-15 (post-grant displaySurface validation) — UNCHANGED; remains the
  enforcement (this plan is belt-and-suspenders at the picker UI level).

Ceremony note: this plan replaces the prior AMENDMENT-A.md improvisation
path retired per 01-11-SUMMARY Architectural Notes. Canonical GSD ceremony
(plan -> checker -> executor -> SUMMARY).

Validations:
- gsd-sdk frontmatter.validate -> valid: true (8/8 required fields).
- gsd-sdk verify.plan-structure -> valid: true (1 task; hasFiles/hasAction
  /hasVerify/hasDone all true).
- ROADMAP.md Phase 1 plans list extended with 01-14 entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 20:34:17 +02:00
4d828f1080 docs(01-10): install-flow + auto-select research — both asks INFEASIBLE
Researcher (gsd-phase-researcher) returned HIGH-confidence verdicts on the
12-area brief from .continue-here.md:

Ask 1 (install-time auto-start): INFEASIBLE in unmanaged Chrome.
  W3C Screen Capture spec §5.1 mandates transient user activation;
  chrome.runtime.onInstalled confers none. Floor: 2 clicks
  (toolbar/welcome-page → Share button on picker). Enterprise policy
  ScreenCaptureWithoutGestureAllowedForOrigins exists (Chrome+Edge ≥ 123)
  but only applies to managed-Chrome contexts with extension URL
  whitelisted — does NOT apply to Load-Unpacked deployment; deferred-idea.

Ask 2 (auto-select desktop / skip picker): INFEASIBLE in unmanaged Chrome.
  W3C spec mandates user MUST choose every time. displaySurface:'monitor'
  is a hint (already applied src/offscreen/recorder.ts:270).
  chooseDesktopMedia doesn't auto-accept on single-monitor setups AND
  streamId not usable in MV3 offscreen documents (Chrome DevRel position).

Primary recommendation: KEEP Plan 01-10's current informational CTA
charter (commit 3a530c2 unchanged). Both architectures hit the same
2-click floor; informational CTA has lower maintenance surface AND
teaches operator where the toolbar icon lives (critical for day-2+
sessions).

Enhancement candidate (NOT required for 01-10): add
monitorTypeSurfaces:'include' (Chrome ≥ 119) to offscreen getDisplayMedia
constraints — single line, zero risk, removes tab/window panes from
picker entirely. Suggest as Plan 01-09 amendment OR mini-plan.

Open questions for orchestrator (3):
1. Confirm informational CTA charter (this research recommends YES)
2. Ship monitorTypeSurfaces:'include' as Plan 01-09 amendment vs deferred?
3. Are Repremium operators on Wayland Linux? (affects welcome-page copy)

File: .planning/phases/01-stabilize-video-pipeline/01-10-RESEARCH.md
  (1092 lines; full W3C citations, Chromium issue links, prior art for
  Loom/Screencastify/Veed/Awesome-Screenshot, ASCII flow diagrams,
  edge-case enumeration for macOS/Wayland/incognito/managed-Chrome)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 20:12:18 +02:00