Commit Graph

15 Commits

Author SHA1 Message Date
e8a2e7696d docs(04-04): complete harden-clean-up-optional plan 04-04 — SW persistence spike FAILED, plan-fix ceremony required
Plan 04-04 (spike→auto) closes at Task 1 (Wave 0 SPIKE) with an empirical
NO on the RESEARCH Q2 MEDIUM-confidence hypothesis A3 (offscreen-document
independent lifecycle anchored by active MediaRecorder). Task 2 (Wave 1
A33 verification-only harness assertion) BLOCKED by the plan's explicit
gating condition (videoSize > 100_000); ROADMAP SC #1 remains OPEN.

Spike empirical numbers (one HEADLESS=1 run; 308.7s wall-clock; full log
at /tmp/04-04-spike.log; reproducible via the committed spike script):
  - assertA2 prime:        PASSED (REC state established)
  - 5-min wall-clock idle: elapsed cleanly
  - stopServiceWorker CDP: succeeded (worker.close() returned)
  - SAVE_ARCHIVE ack:      {success: true} (event-driven SW respawn worked)
  - video/last_30sec.webm: 8505 bytes (sanity floor 100 KB; healthy 1-3 MB)
  - ffprobe on extracted:  'End of file' + 'Duplicate element' (no clusters)
  - rrweb/session.json:    [] (empty)
  - logs/events.json:      [] (empty)
  - meta.urls:             chrome-extension://* only (real-page URLs LOST)

Conclusion: src/offscreen/recorder.ts:91 `let segments: Blob[] = []` RAM-
only architecture does NOT survive 5-min SW idle + Puppeteer CDP worker.
close(). Architectural change required to close ROADMAP SC #1 (canonical
recommendation per 04-RESEARCH.md Q2 sub-question b Option C: IndexedDB
persistence in offscreen — Blobs serialize cleanly via structured-clone;
per-segment write ~3 MB; ~3 writes per 30s window). Per saved memory
`feedback-gsd-ceremony-for-fixes.md` the architectural fix routes through
/gsd-plan-phase rewrite OR /gsd-debug ceremony — NOT improvised inline
inside Plan 04-04.

Task 1 persisting artifacts (committed at 3726eee):
  - tests/uat/lib/harness-page-driver.ts: +43/-6 lines
    - Browser type added to puppeteer import
    - stopServiceWorker(browser, extensionId) helper (Chrome devrel
      canonical pattern; Puppeteer >=22.1.0 worker.close())
    - findLatestZip exported (was module-internal)
  - tests/uat/spike-a33-sw-persistence.ts NEW +202 lines
    - One-shot reproducible empirical investigation script
    - Reusable for future SW-lifecycle regression (the eventual plan-fix
      re-runs this script as its A33-verification gate)
    - Committed (not deleted) per the spike-FAILED forensic-evidence pattern

Task 2 was NOT committed (BLOCKED by gating condition); UAT count stays
33/33; Tier-1 FORBIDDEN_HOOK_STRINGS inventory unchanged at 12; A33 not
introduced.

Pre-checkpoint bundle gates (per saved memory feedback-pre-checkpoint-
bundle-gates.md): 6/6 GREEN unchanged from Plan 04-03 baseline (zero
production source changes in Plan 04-04).
  - SW chunk new Function: 0 (Plan 04-02 polarity preserved)
  - SW chunk eval:         0 (preserved)
  - SW chunk Buffer.:      1 (pre-existing JSZip polyfill; logged deferred)
  - SW chunk window./doc.: 0/0 (preserved)
  - dist/ grep × 12 hooks: 0 matches (Tier-1 inventory invariant held)
  - Manifest:              validates clean

vitest baseline: 183 tests total. Sequential `npm test` showed 180/183 with
3 pre-existing flakes in tests/background/blob-url-download.test.ts +
tests/background/webm-remux.test.ts + tests/offscreen/webm-playback.test.ts;
all 3 PASS in isolation. Per 04-CONTEXT.md items 9-10 these are documented
pre-existing issues (parallel-vitest Tier-1-build-step race + 2 ffprobe/
ffmpeg flakes pre-dating Phase 3) — NOT a Plan 04-04 regression (Plan 04-04
made zero source-code changes that could possibly affect them).

Files committed:
  - .planning/phases/04-harden-clean-up-optional/04-04-SUMMARY.md NEW
  - .planning/STATE.md: position advanced 4→5 / 7; progress 87% → 90%;
    2 decision entries logged; session metadata updated
  - .planning/ROADMAP.md: Phase 4 row count 2/7 → 4/7; Plan 04-04
    checklist box ticked with full SPIKE FAILED annotation; SC #1 marked
    OPEN with empirical evidence inline

Next step (out of Plan 04-04 scope; routed per spike-first contract):
plan-fix ceremony for IndexedDB persistence layer at src/offscreen/*.
The plan-checker/planner owns whether to (a) rewrite Plan 04-04 in-place,
(b) insert a new plan slot (e.g., 04-08), or (c) close Plan 04-04 as
spike-findings + open a fresh follow-up plan. Recommendation in SUMMARY:
option (b) or (c) — keep Plan 04-04 as the canonical spike-findings record.
2026-05-21 20:02:42 +02:00
303644f8cc docs(04-03): complete harden-clean-up-optional plan 04-03 — A29 flake fix
A29 (rrweb DOM verification) rewritten in-place via the canonical cs-
injection-world pattern + strict-sentinel filter. Closes ~2/3 flake
documented in Plans 03-02 + 03-03 SUMMARYs (A29 was "passing" by
reading iana.org leftover DOM events from A27/A28's still-open probe
tabs; a real rrweb regression at src/content/index.ts:284 would have
been masked).

Plan 04-03 task commits (atomic; sequential foreground mode):
- 73eb9b6: Task 1 — A29 page-side cs-injection-world skeleton +
  sentinel-bearing <div> injection
- b341a71: Task 2 — A29 host-side strict-sentinel filter (RESEARCH Q3
  Code Example Pattern 3); IncrementalSource added to @rrweb/types
  import binding; A29.2 PASS × 5/5 consecutive UAT runs

Empirical evidence:
- vitest 183/183 GREEN preserved (Plan 04-02 baseline)
- UAT harness 33/33 GREEN × 5 consecutive runs
- A29 strict-sentinel: mutationEvents=1, sentinelEvents=1 in ALL 5 runs
- Tier-1 FORBIDDEN_HOOK_STRINGS unchanged at 12
- SW chunk: 0 new Function, 0 eval (Plan 04-02 baseline held)
- Pre-checkpoint bundle gates 5/5 PASS

STATE.md + ROADMAP.md updated per sequential workflow:
- Plan counter advanced 3 → 4 of 7
- Progress 83% → 87% (26/30 plans complete)
- Decision log entry added for Plan 04-03
- ROADMAP Phase 4 04-03 row flipped to [x]
2026-05-21 17:01:58 +02:00
6a1fc32826 docs(04-02): complete harden-clean-up-optional plan 04-02 — build hygiene
Plan 04-02 closes three independent build-hygiene fixes consolidated into
one plan because they share the build-gate-grep test-scaffold pattern:

1. **setimmediate polyfill replacement** — layered 4-mechanism CSP-hardening
   eliminates the `new Function` literal from the SW chunk (grep -c flips
   1→0 across all three SW chunks). Runtime guard + nodePolyfills exclude
   + resolve.alias + Rollup post-transform plugin. Option α (force JSZip
   unbundled lib/index.js) attempted + reverted because it broke
   readable-stream-browser propagation causing UAT A30+ regressions;
   Option β (post-transform plugin) preserves JSZip's pre-bundled
   distribution verbatim while excising the offending literal.

2. **ROADMAP SC #3** (generate-icons ESM/CJS) — `git mv generate-icons.js
   generate-icons.cjs` resolves the `require('fs')` under
   `package.json type: module` via Node's `.cjs`-as-CJS rule.

3. **ROADMAP SC #4** (dead-code grep) — `tests/build/dead-code-grep.test.ts`
   regression-pins `permissions.request` absence in `src/`.

Plus closure of Plan 01-12 Wave 7's setimmediate deferred-items entry.

Task commits:
  - 630d40c test(04-02): Wave 0 RED — no-new-function + dead-code-grep
  - f251297 feat(04-02): Wave 1 GREEN — setimmediate replacement + CJS rename + closure

Verification:
  - vitest 180/180 → 183/183 GREEN on clean run (+3 net new tests)
  - UAT harness 33/33 GREEN preserved (REVISION iter-2 WARNING 1 empirical pin)
  - Pre-checkpoint bundle gates 5/5 PASS; SW CSP-safety polarity flipped 1→0
  - tsc-clean preserved; npm run build exit 0; node generate-icons.cjs exit 0

STATE.md: Plan 3/7 (Plan 04-02 complete); 25/30 total plans; 83% progress.
ROADMAP.md: Phase 4 progress 2/7 plans complete (04-01 + 04-02).
deferred-items.md: Plan 01-12 Wave 7 setimmediate entry CLOSED end-to-end.

SUMMARY at `.planning/phases/04-harden-clean-up-optional/04-02-SUMMARY.md`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 15:41:54 +02:00
f72bca5c46 docs(04-01): complete audit-p1-polish-content-script plan
Plan 04-01 closure marker — 04-01-SUMMARY.md + STATE.md position advance
(Plan 1 of 7 -> Plan 2 of 7; Plan 04-02 build hygiene queued NEXT in Wave 1)
+ ROADMAP plan-progress table flip ([ ] -> [x] 04-01-PLAN.md row).

Plan delivered (per SUMMARY):
- Audit P1 #11 fetch URL extraction fix (TWO sites; instanceof Request narrow)
- Audit P1 #14 navigation URL tracking fix (module-level previousUrl)
- Audit P1 #15 rrweb emit timestamp normalization (Date.now() Unix epoch)
- 9 new vitest tests under tests/content/; baseline 171 -> 180/180 GREEN
- tsc-clean preserved; Tier-1 hook-strings inventory unchanged at 12
- Audit P1 polish backlog CLOSED 3/3

Per-task commits (TDD pair):
- 3dbc51c test(04-01): Wave 0 RED — content-script test scaffolds
- 7da30af feat(04-01): Wave 1 GREEN — 3 surgical edits in src/content/index.ts

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 14:34:03 +02:00
dbcf4827f6 wip: phase-04 paused — 7 plans validated iter-2 PASSED, ready for execution .planning/phases/04-harden-clean-up-optional/.continue-here.md .planning/HANDOFF.json 2026-05-21 10:25:29 +02:00
3c1280ed2d docs(04): plan-phase closure — 3 cosmetic advisories from checker iter-2 resolved
Plan-checker iter-2 returned VERIFICATION PASSED with 3 cosmetic advisories:
- Dim 11: RESEARCH.md "## Open Questions" missing "(RESOLVED)" suffix → fixed
- Dim 12: PATTERNS.md:886 stale dispatchSaveArchiveForA33 example → added
  DEPRECATED banner citing Plan 04-04 REVISION iter-2 Option B canonical pattern
- VALIDATION.md frontmatter "4 revised tasks" mismatched per-task map (5 rows) → fixed

All 4 BLOCKER+WARNING issues from iter-1 verified resolved by iter-2 plan-checker
(VERIFICATION PASSED). 3 cosmetic items now resolved as well. 2 advisory items
left as-is per iter-1 (W2 scope-sanity at 04-06; W3 conservative 04-03 dep).

Phase 4 plans cleared for execution:
- 7 plans across 6 waves (Wave 1: 04-01+04-02 parallel; Waves 2-6 single-plan)
- Plan-checker iter-2 VERIFICATION PASSED
- Test baselines preserved: vitest 171/171 · UAT harness 33/33 · Tier-1 12

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 10:21:03 +02:00
76fffb35b9 fix(04): revise plans per checker iter-1 — 2 BLOCKERS + 2 WARNINGS fixed
Plan-checker iter-1 found 2 BLOCKERS + 4 WARNINGS. Iter-2 revision applies
surgical fixes to 4 plans + VALIDATION:

BLOCKER 1 (Plan 04-06 Task 4): wrong SW chunk glob `dist/assets/index*-bg.js`
matched zero files → Gates 2/3/4 silently PASSED. Replaced with canonical
`dist/assets/index.ts-*.js` (verified empirically: index.ts-8LkXuqac.js
on disk; RESEARCH Q1). Added glob-existence pre-gate `ls | wc -l >= 1`
to fail-loudly on future Vite chunk-naming shift.

BLOCKER 2 (Plan 04-04 Task 1): spike called non-existent
__mokoshHarness.dispatchSaveArchive (verified: harness surface is
assertA1..A31 + getManifestVersion only). Applied Option B — spike
+ driveA33 now dispatch SAVE_ARCHIVE via chrome.runtime.sendMessage
inline in page.evaluate (matches 9 existing assertA* methods:
A5/A11/A12/A13/A26/A28/A29/A30/A31). No new harness helper introduced.

WARNING 1 (Plan 04-02 Task 2): verify omitted UAT harness run. Added
`HEADLESS=1 SKIP_PROD_REBUILD=0 npm run test:uat 2>&1 | grep -c 'UAT
harness: 33/33 assertions passed'` to verify command (stdout format
confirmed at tests/uat/harness.test.ts:537).

WARNING 4 (Plan 04-07 Task 1): weak operator-ack gate (placeholder would
pass). Added `grep -cE 'approved|All good|APPROVED|approved by|operator
ack|all good' 04-VERIFICATION.md` to verify command. Covers both
canonical Plan 04-06 resume-signal ("approved" lowercase) AND prior-art
Plan 01-10 cycle-2 ack ("All good" titlecase).

WARNINGS 2 + 3 left as-is (truly advisory: scope-sanity threshold +
conservative dependency without file overlap).

04-VALIDATION.md per-task map rows updated for the 5 revised task entries
(04-02 T2 + 04-04 T1 + 04-04 T2 + 04-06 T4 + 04-07 T1). Frontmatter
adds `revised: 2026-05-21` + iter-2 notes block.

3 plans unchanged on disk (04-01, 04-03, 04-05).

Empirical confirmations used in revision:
- Harness surface: grep extension-page-harness.ts:4018 confirms
  __mokoshHarness.{assertA1..A31, getManifestVersion}; no dispatchSaveArchive
- SW chunk filename: ls dist/assets/ shows index.ts-8LkXuqac.js;
  no index*-bg.js matches
- SAVE_ARCHIVE precedent count: 9 existing assertA* methods use the
  chrome.runtime.sendMessage pattern
- UAT harness stdout format: harness.test.ts:537 emits canonical
  "UAT harness: N/N assertions passed"

Ready for plan-checker iter-3 re-verification.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 10:00:07 +02:00
526ac78046 docs(04): create phase plan — 7 plans for Phase 4 hardening (audit P1 polish + flake stabilization + SW persistence + visual polish + closure)
Wave structure:
- W1 (parallel): 04-01 (Audit P1 polish #11/#14/#15 TDD) + 04-02 (build/CSP hygiene: setimmediate polyfill + dead-code + generate-icons.cjs)
- W2: 04-03 (A29 cs-injection-world rewrite; closes flake)
- W3: 04-04 (A33 SW state persistence; spike-first + CDP worker.close())
- W4: 04-05 (A34 fetch+XHR network_error; ROADMAP SC #2 + validates Plan 04-01 P1 #11 end-to-end)
- W5: 04-06 (dark-logo currentColor + cursor verification + 01-07-SUMMARY back-patch; operator empirical)
- W6: 04-07 (04-VERIFICATION.md aggregator + ROADMAP backfill + v1 close prep)

Honors locked decisions D-P4-01..05 (full Phase 4 + all 3 P1 polish + both visual items + alpha-independent + ROADMAP backfill).
Implements RESEARCH Q1 (setimmediate option a), Q2 (spike-first SW persistence), Q3 (A29 cs-injection-world), Finding 4 (cursor already shipped — verification only).
UI-SPEC dark-logo currentColor strategy with inline-SVG injection landed per UI-SPEC §"Implementation amendment".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 09:30:49 +02:00
f012c8c103 docs(04): pattern map — ~30 anticipated files mapped (21 exact + 8 role-match + 1 NEW pattern stopServiceWorker CDP helper) .planning/phases/04-harden-clean-up-optional/04-PATTERNS.md 2026-05-21 08:29:19 +02:00
7178d14154 docs(phase-04): add validation strategy — Wave 0 anticipates 6 new unit test files per RESEARCH .planning/phases/04-harden-clean-up-optional/04-VALIDATION.md 2026-05-21 08:03:10 +02:00
d1f676707e docs(04): research phase domain — setimmediate, SW persistence, A29 race fix + cursor finding .planning/phases/04-harden-clean-up-optional/04-RESEARCH.md 2026-05-21 08:01:27 +02:00
266aa95235 docs(04): UI-SPEC.md status approved — 5/6 PASS + 1 FLAG non-blocking (dim 4 inherited type scale)
UI-checker verdict: APPROVED. Dimension breakdown:
- 1 Copywriting: PASS (17-key matrix inherited + locked; zero new copy)
- 2 Visuals: PASS (no new screen; dark-logo is stroke binding change)
- 3 Color: PASS (Loom palette inherited; semantic accents declared)
- 4 Typography: FLAG (8 sizes / 4 weights exceed standard thresholds but
  correctly captured as Phase 1-locked inherited from operator brand-fit
  ack 2026-05-20; Phase 4 adds zero new sizes/weights) — non-blocking
- 5 Spacing: PASS (all multiples of 4; locked; no new values)
- 6 Registry Safety: PASS (vanilla DOM + DOMParser; no shadcn; no third-party)

Three checker observations addressed:
1. `?url` → `?raw` bundling: correctly preserves @crxjs auto-WAR (SVG
   content stays in JS bundle as string literal vs base64 data URL)
2. A17.8 sub-check update: concrete enough (raw-SVG-source string-search
   for `currentColor` + `viewBox='0 0 32 32'`); optional A17.8a/A17.8b split
   well-described
3. Dark-mode contrast: deep-indigo stroke on madder-orange wrapper is
   readable; operator empirical checkpoint (acceptance criterion #6) is
   the designated gate for WCAG ratio judgment

Implementation contract = 5 file edits + 6 acceptance criteria. Planner can
now use UI-SPEC as design context for the visual-polish Phase 4 plan.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 07:46:34 +02:00
55cefbaa32 docs(04): UI design contract — thin scope (dark-logo currentColor strategy)
Phase 4 carries one genuine designer-side decision: dark-surface logo contrast
strategy. Recommends Option A — `currentColor` SVG + CSS color driven via the
existing `.dark, [data-theme="dark"]` block in tokens.css (lines 234-251). Post-
research amendment: welcome.ts must swap `?url` (data URL → <img>) for `?raw`
(inline <svg> via DOMParser) because <img>-rendered SVGs do not inherit parent
CSS color — `currentColor` only resolves on inline DOM SVG.

Cursor visibility constraint (Plan 01-07 obs 2026-05-15) is listed as
behavioral-only inheritance, not a design surface — 1-line change in
src/offscreen/recorder.ts per Chrome CursorCaptureConstraint enum.

Inherits Phase 1 design system as read-only (Lora display + IBM Plex Sans UI
+ Loom palette + Mokosh mark + canonical tokens.css + 17-key i18n matrix).
Zero new tokens, zero new copy, zero new colors. PNG icons unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 22:48:06 +02:00
74ac8ac342 docs(04): preserve plan-phase preferences captured pre-UI-SPEC exit
User invoked /gsd-plan-phase 4 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 4 produces UI-SPEC.md):
- UI gate: generate UI-SPEC.md first — unlike Phase 3 (false positive),
  Phase 4 has genuine dark-logo work; UI-SPEC should be thin-but-real
  (dark-logo design only; cursor visibility listed as inherited behavioral
  change, not a design surface)
- Research gate: research first (light, ~10-20 min) — scope-limited to:
  setimmediate polyfill replacement strategy + SW state persistence 5min
  idle test patterns + chrome.scripting.executeScript world:'ISOLATED'
  best practices for A29 cs-injection-world fix. Researcher NOT to
  investigate already-deferred items (rrweb v2, SW-RAM, masking).

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

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 22:42:13 +02:00
8b31fbe3de docs(04): capture phase context — discuss-phase complete (5 D-P4-* locked decisions; full Phase 4 scope) .planning/phases/04-harden-clean-up-optional/04-CONTEXT.md .planning/phases/04-harden-clean-up-optional/04-DISCUSSION-LOG.md 2026-05-20 22:16:57 +02:00