phase.complete CLI ran (commit n/a — CLI in-mem only) with documented
defects per recurring state.record-session bug:
- completed_phases stuck at 3 (should be 4)
- percent regressed to 75% (3/4 math; should be 100% — milestone-complete)
- ROADMAP Phase 4 row still [ ] despite roadmap_updated:true claim
Manual fix applied per saved memory (canonical workaround for CLI bug):
STATE.md:
- completed_phases: 3 → 4
- percent: 75 → 100
- progress bar: [█████████▓] 97% → [██████████] 100%
ROADMAP.md:
- Phase 4 row: [ ] → [x] with comprehensive closure annotation
(8 plans + 3 debug sessions + 4 ROADMAP SCs + 5 D-P4-* + UAT
33→36 + vitest 171→188 + bundle gates 6/6 + Tier-1 12 + Tier-2 added
+ operator ack 2026-05-26 + verifier audit PASSED 8ffc6cb)
Phase 4 closed end-to-end. Milestone v1 v2.0.0 complete (status:
milestone_complete already correctly set by CLI). Ready for v1.0 tag +
alpha redistribution per D-P4-04 (user routes out-of-band).
30 KiB
Roadmap: Mokosh
Overview
The Mokosh codebase is a partially-broken first attempt at SPEC Тз расширение фаза1.md. An external audit identified 7 P0 defects that prevent SPEC §10
acceptance. This roadmap framed Phase 1 as stabilization to spec, not
greenfield: phases 1–2 each remediate a tightly-grouped subset of the P0
defects along sensible commit boundaries; phase 3 runs the SPEC §10 smoke pass
end-to-end (and now also absorbs the DOM + event-log verification surface that
was originally Phase 2). An optional phase 4 absorbs the P1/P2 follow-ups (SW
state persistence, fetch interception fix, meta.json field hardening,
generate-icons.js ESM/CJS, dead-code cleanup).
Roadmap re-phasing 2026-05-20: original Phase 2 ("Stabilize DOM + event-capture privacy") REMOVED per operator charter shift — archive flow is internal-only (no external transmission); P0-5 password masking dropped as v1 priority ("we don't care about privacy hardening. At least here."). DOM
- event-log VERIFICATION (REQ-rrweb-dom-buffer + REQ-user-event-log) absorbed by new Phase 3 (SPEC §10 smoke). REQ-password-confidentiality moved to Out of Scope (v1). All subsequent phases renumbered: old 3 → new 2, old 4 → new 3, old 5 → new 4.
The journey: broken-but-installable → playable video → working export → green §10 smoke (incl. DOM + event-log verification) → harden + clean up.
Phases
Phase Numbering:
- Integer phases (1, 2, 3): Planned milestone work.
- Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED).
Decimal phases appear between their surrounding integers in numeric order.
- Phase 1: Stabilize video pipeline — Collapse offscreen duality, fix MediaRecorder shadow, fix WebM ring buffer playability, replace
chrome.tabCapturewith offscreengetDisplayMedia(AMENDED from original DEC-003). CLOSED 2026-05-20 via gsd-verifier goal-backward audit GREEN (17/17 must-haves: 11 REQs/charters + 6 cross-cutting gates; see.planning/phases/01-stabilize-video-pipeline/01-VERIFICATION.md). Closure arc: 2026-05-15 (Plan 01-07) → 2026-05-16 (REOPENED on D-13 multi-EBML bug) → Plan 01-08 (WebM remux via ts-ebml + webm-muxer) → Plans 01-09/01-10 (whole-desktop + welcome-tab UX) → Plan 01-11 (spike-pivot) → Plan 01-12 (Design Integration) → Plan 01-13 (UAT harness 15/15 GREEN, 2026-05-19) → Plan 01-14 (monitorTypeSurfaces picker) → Plan 01-10 cycle-2 ack 'All good' 2026-05-20 + 5 inter-cycle debug fixes + brand-rename polish. 14/14 plans; 5 operator acks; 153/153 vitest + 24/24 UAT + Tier-1 grep 12 FORBIDDEN_HOOK_STRINGS all GREEN. - Phase 2: Stabilize export pipeline — Close remaining export gaps (screenshot-at-click, meta.json schema, archive layout, manifest permission verification). Mostly already shipped via Plans 01-08 + 01-09 + 01-10 + 01-12 — narrowed scope post-re-phasing.
- Phase 3: SPEC §10 smoke verification — End-to-end install-and-record-and-export pass against all 9 acceptance criteria. ABSORBS REQ-rrweb-dom-buffer + REQ-user-event-log verification (originally Phase 2) per 2026-05-20 re-phasing. UAT harness extended with A24+ assertions for rrweb/event-log contracts.
- Phase 4: Harden + clean up (optional) — P1/P2 follow-ups: SW state persistence, fetch interception,
meta.jsonfields,generate-icons.jsESM/CJS, dead-code; plus deferred items from Phase 1 session (cursor visibility, dark-surface logo, tabs permission gap, 2 ffprobe flakes, ROADMAP backfill verification, rrweb 2.0.0-alpha.4 → stable v2 upgrade research). CLOSED 2026-05-26 via gsd-verifier goal-backward audit GREEN (4/4 ROADMAP SCs + 11/11 observable truths + 0 overrides; commit8ffc6cb; see.planning/phases/04-harden-clean-up-optional/04-VERIFICATION.md). 8 plans landed (04-01..04-08; 04-08 inserted Wave 5.5 after Plan 04-04 SPIKE FAILED was empirically REFUTED-architecture via 2 /gsd-debug sessions on canvas-throttling); 5/5 D-P4-* charters CLOSED; 3 /gsd-debug sessions (canvas-throttling resolved, A33.1 SAVE-ack race fixed at7e0da63, dark-mode --mks-mark-stroke decoupling ata8bcc17); 1 operator-empirical ack cycle on Plan 04-06 ('Confirmed fixed' 2026-05-26 after TWEAK → debug fix → re-empirical); UAT harness 33→36 GREEN (A33 via 04-08 + A34 via 04-05 + A35 via 04-06 with 5 sub-checks incl. A35.5 light+dark decouple-proof); vitest 171→188 GREEN (with documented 04-CONTEXT #9/#10 ffprobe parallel-vitest flake family); bundle gates 6/6 PASS (Gate 2new Functionflipped 1→0 via Plan 04-02 setimmediate 4-mechanism layered mitigation); Tier-1 FORBIDDEN_HOOK_STRINGS unchanged at 12; Tier-2 leak gate added (Plan 04-08 synthetic-display-source dist/ check).
Phase Details
Phase 1: Stabilize video pipeline
Goal: The video ring buffer captures the most recent 30 s of the active
tab's video continuously across tab switches, with a playable WebM header
retained — so that on export the assembled last_30sec.webm will play.
Depends on: Nothing (first phase). Operates on the existing offscreen/
directory + vite.config.ts inline string + src/background/.
Requirements: REQ-video-ring-buffer
P0 defects addressed:
- P0-1: Collapse the offscreen duality (
offscreen/index.ts+ inline string invite.config.ts) into a single source of truth; fix themediaRecordershadow that breaksstopRecording. - P0-2: Fix WebM ring buffer playability — single continuous
MediaRecorder, 2000 ms timeslice per spec (CON-video-codec), cluster-timestamp-based rolling window honouring the WebM header retention rule (DEC-009). - P0-3: Make capture always-on with
chrome.tabs.onActivated/chrome.tabs.onUpdatedre-attachment; start ononInstalled/onStartup, not on popup open (CON-tab-capture-binding, REQ-video-ring-buffer).
Success Criteria (what must be TRUE):
- There is exactly one source of truth for the offscreen document; rebuilding
vite.config.tsdoes not regenerate a divergent inline duplicate, andstopRecordingruns withoutmediaRecorder is undefinedshadow errors. - With the extension loaded and an operator session active, a
MediaRecorderis running on the operator-selected screen/window source. AMENDED 2026-05-15 (D-13 fix-a3 activation): the recorder cycles in 10 s self-contained segments (stop+restart on the sameMediaStream) instead of a single continuous recorder — replaces D-09..D-11 to fix VP9 keyframe orphan-P-frame freezes. Recording continues unchanged across tab switches (no tab re-attach logic; AMENDED from the original wording). - The in-memory video ring buffer at any instant contains at most 3 of the
most recent 10 s WebM segments (3 × 10 s = 30 s window, no more, no less);
concatenating segments sequentially yields a multi-EBML-header WebM that
Chrome plays end-to-end (SPEC §10 #7 — operator confirmed clean playback
2026-05-15; ffmpeg
-v warning -i fixture -f null -exit 0 with zero decoder errors, only expected muxer DTS-monotonicity warnings at segment join boundaries).
Plans: 14 plans (01-01 through 01-14). All 14 functional plans complete; Phase 1 final-closure marker flip pending.
- 01-01-PLAN.md — Doc cascade: amend DEC-003 / DEC-010 / RETIRE constraints / swap manifest permissions (D-A1..D-A6)
- 01-02-PLAN.md — Wave-0 test infrastructure: Vitest install + 4 RED test files + fixtures placeholder
- 01-03-PLAN.md — Offscreen recorder TDD: ring buffer + codec strict-mode + getDisplayMedia + track-ended cleanup; D-13 fallback skeleton pre-staged
- 01-04-PLAN.md — Port keepalive + OFFSCREEN_READY handshake (TDD): replaces alarms keepalive on offscreen side
- 01-05-PLAN.md — SW shrink: delete legacy buffer + alarms + IndexedDB + tabCapture paths; wire SW-side onConnect host
- 01-06-PLAN.md — Build pipeline collapse: delete vite.config.ts inline plugin + top-level offscreen/ dir; declare rollupOptions.input
- 01-07-PLAN.md — Manual smoke + ffprobe D-12 acceptance gate + A3 empirical-playback gate; D-12 + A3 debug sessions resolved mid-execution via pre-staged base64 wire format + D-13 restart-segments; regression fixture committed; SPEC §10 #2/#3/#7 functionally green (Closed 2026-05-15)
- 01-08-PLAN.md — WebM remux via ts-ebml + webm-muxer (replaces D-13 file-concat; closes SPEC §10 #7 playability per debug d13-multi-ebml-concat-unplayable.md)
- 01-09-PLAN.md — Toolbar onClicked direct flow + monitor-only picker + onStartup notification + 3-state badge state machine; closure-by-harness Amendment 2 (Plan 01-13 PASS substitutes for operator UAT). Closure-cycle follow-up debug
a2dfc8c(startVideoCapture no-tab cleanup; D-01 dead-code removal) +4bba679(notifStartup text split into notifStartupCta + notifRecordingStarted) landed during Plan 01-10 closure 2026-05-20. - 01-10-PLAN.md — Welcome tab (Hero + Loom dial per D-02; first-install onboarding; chrome.runtime.onInstalled + chrome.storage.local flag-gating + chrome.tabs.create + canonical mokosh-mark.svg via Vite ?url import + canonical src/shared/tokens.css @import + chrome.i18n.getMessage for welcomeHeroRu + welcomeHeroEn; harness A15-A17 with A17.7 --mks-rec probe + A17.8 mark-bundling invariant; D-16-toolbar charter preserved). Closure 2026-05-20 via cycle-2 operator ack "All good" + 5 inter-cycle debug fixes (
89e1e09→49f087f→8f329d8→b112cb7→4bba679→d48a715→0854baf→a2dfc8c→d21ed17) + brand-rename follow-up "AI Call Recorder" → "Mokosh"; 153/153 vitest + 24/24 UAT GREEN. - 01-11-PLAN.md — UAT harness Approach-A spike (PIVOTED to 01-13; carries forward Wave 0 infrastructure + Tier-1 grep gate; falsified hypotheses recorded)
- 01-12-PLAN.md — Design integration (R2 Lora self-host, src/shared/tokens.css canonical, 16 i18n keys across en+ru, branded Loom icons replacing Bug A placeholders, manifest i18n + default_locale='en', BADGE_REC_COLOR madder #b2543d, chrome.i18n.getMessage with
|| <const>fallback, harness A18-A22; operator brand-fit ack 2026-05-20 'all good') - 01-13-PLAN.md — UAT harness via Approach B (extension-internal-page driver + offscreen synthetic stream; 15/15 GREEN; Plan 01-09 functional closure)
- 01-14-PLAN.md — Picker narrowing via monitorTypeSurfaces:'include' (Chrome 119+ picker enhancement; A23 harness regression)
Phase 2: Stabilize export pipeline
Goal: A click on "Сохранить отчёт об ошибке" produces a SPEC-conformant ZIP
archive on disk in under 5 s, containing a screenshot taken at click time,
laid out per CON-archive-layout, with meta.json per CON-meta-json-schema
(post-2026-05-20 amendment: 8-field shape with urls: string[] replacing
url: string + new schemaVersion: '2' cutover marker per D-P2-02 + D-P2-03),
and downloaded via an offscreen-minted Blob URL (closes audit P0-6 base64
data-URL cap; D-P2-01).
Depends on: Phase 1 (export consumes the video buffer + the rrweb/event-log infrastructure already shipped in src/content/index.ts; original "Phase 2 DOM" dependency removed per 2026-05-20 re-phasing).
Scope note (2026-05-20): Plans 01-08 (webm-remux + JSZip), 01-09 (popup
state machine + SAVE-only UI), 01-10 (welcome tab + i18n), and 01-12 (manifest
i18n + en+ru locales) already shipped most of the originally-planned export
surface. Phase 2 closes the AUDIT residuals: P0-6 (base64 → Blob URL via
offscreen-minted URL.createObjectURL per DEC-006) + P1 #10 (meta.json
url:string → urls:string[] schema migration) + strict 8-field schema
validation + UAT harness <5s latency assertion (REQ-archive-export-latency).
Requirements: REQ-popup-ui, REQ-screenshot-on-export, REQ-archive-layout, REQ-meta-json-schema, REQ-archive-export-latency, REQ-manifest-permissions
P0 defects addressed:
- P0-4: Restore the user-activation gesture for
getMediaStreamIdby moving the call to the popup-click handler; delete the deadpermissions.requestdance that was masking the missing gesture (REQ-popup-ui, CON-tab-capture-binding). - P0-6: Replace the base64
data:URL download with a Blob URL minted in the offscreen document — the Service Worker lacksURL.createObjectURL(DEC-006, REQ-archive-export-latency).
Success Criteria (what must be TRUE):
- Opening the popup shows a button reading "Сохранить отчёт об ошибке" with
sub-label "Последние 30 сек видео + 10 мин лога"; clicking it transitions
idle → "Сохраняю..." → "Готово! ✓" → idle (with 3 s revert) and triggers
a
chrome.downloadsdownload. - The downloaded file lands in the user's Downloads folder, named
session_report_YYYY-MM-DD_HH-MM-SS.zip, in under 5 seconds from click; opening it reveals exactly the layout in REQ-archive-layout (video/last_30sec.webm,rrweb/session.json,logs/events.json,screenshot.png,meta.jsonat the root) with no extra entries. meta.jsonvalidates against the verbatim CON-meta-json-schema (8 fields per the 2026-05-20 D-P2-02/D-P2-03 amendment:schemaVersion,timestamp,urls,userAgent,extensionVersion,videoBufferSeconds,logDurationMinutes,totalEvents;urlsis a non-empty deduplicatedstring[]of operator tab URLs visited during the 30s window; types correct;timestampis ISO-8601 withZ).manifest.jsonindist/afternpm run builddeclares exactly the permission set in DEC-011 with no additional or missing entries; loading unpacked into Chrome produces no permission-related warnings or errors inchrome://extensions/.- A real >2 MB archive downloads to disk successfully (the canonical 5-10 MB
operator bug-report archive — previously failed via base64 data-URL cap).
The chrome.downloads.download call site receives a
blob:URL (notdata:application/zip;base64,); URL.revokeObjectURL is dispatched via chrome.downloads.onChanged 'complete' (D-P2-01 lifecycle).
Plans: 4 plans (02-01 through 02-04). Wave 1 RED tests → Wave 2 parallel implementation (Blob URL + meta.urls) → Wave 3 harness extension + operator empirical checkpoint.
- 02-01-PLAN.md — Wave 0 RED tests: blob-url-download.test.ts + meta-json-urls-schema.test.ts + strict-meta-json-validation.test.ts pinning D-P2-01/D-P2-02/D-P2-03 contracts (TDD)
- 02-02-PLAN.md — Wave 1 Blob URL pipeline (D-P2-01, closes P0-6): offscreen CREATE/REVOKE handlers via base64-on-wire; SW downloadArchive rewrite; chrome.downloads.onChanged revoke lifecycle
- 02-03-PLAN.md — Wave 1 meta.urls + tab-url-tracker (D-P2-02 + D-P2-03, closes P1 #10): SessionMetadata 7→8 fields with schemaVersion+urls; chrome.tabs.onActivated/onUpdated listeners; REQUIREMENTS.md REQ-meta-json-schema amendment
- 02-04-PLAN.md — Wave 2 harness A24+A25+A26+A27 + operator empirical checkpoint: blob:URL prefix, <5s SAVE→zip latency, meta.json 8-field shape, multi-tab dedup; pre-checkpoint bundle gates + operator UAT cycle 1
UI hint: yes
Phase 3: SPEC §10 smoke verification + DOM/event-log verification
Goal: All 9 SPEC §10 acceptance criteria pass against an unpacked load of the build into a real Chrome instance. ABSORBS DOM + event-log verification work (REQ-rrweb-dom-buffer + REQ-user-event-log) originally planned as Phase 2 per 2026-05-20 re-phasing.
Depends on: Phase 1, Phase 2.
Requirements: REQ-install-clean + REQ-rrweb-dom-buffer + REQ-user-event-log
- end-to-end verification of all preceding REQs.
P0 defects addressed:
- P0-7: End-to-end smoke verification against §10. This is a verification phase, not a new implementation — it confirms the cumulative output of phases 1–2 actually satisfies the SPEC.
Absorbed Phase-2 scope (2026-05-20 re-phasing):
- Verify rrweb 2.0.0-alpha.4 captures DOM events on typical pages (form + table + modal) without throwing in the Content Script console (REQ-rrweb-dom-buffer acceptance criterion #3).
- Verify the user-event log captures click + input (non-password) + navigation (popstate/hashchange) + js_error + network_error per CON-event-log-schema (REQ-user-event-log).
- Extend UAT harness with A24+ assertions covering the above contracts — consistent with Phase 1's Approach-B harness pattern (Plan 01-13).
- rrweb version research (foreground gsd-phase-researcher spawn) to verify alpha-pin is safe or if stable v2 has shipped. Deferred to Phase 4 if Phase 3 plans are tight.
- NOT in scope: P0-5 password masking (REQ-password-confidentiality dropped to Out of Scope v1 per "we don't care about privacy hardening. At least here." 2026-05-20).
Success Criteria (what must be TRUE):
- The extension installs into Chrome via "Load unpacked" against
dist/with no errors or warnings inchrome://extensions/. - With the extension loaded and a normal browsing session under way, the video buffer runs continuously across tab switches and never holds more than 30 s of footage (confirmed by inspecting the SW console / a debug export).
- On a typical page (form + table + modal) rrweb records without throwing, the event log captures clicks/navigation/network errors. (Password masking criterion DROPPED per 2026-05-20 re-phasing — REQ-password-confidentiality is Out of Scope v1.)
- A click on the popup button produces a ZIP in Downloads in under 5 s; the
ZIP opens;
video/last_30sec.webmplays in a browser. - Background RAM consumption (measured via Chrome Task Manager) does not exceed 50 MB during a sustained recording session (CON-ram-ceiling).
Plans: 5 plans (03-01 through 03-05).
- 03-01-PLAN.md — rrweb DOM verification harness extension (A29; SPEC §10 #4; REQ-rrweb-dom-buffer)
- 03-02-PLAN.md — event-log verification harness extension (A30; SPEC §10 #5; REQ-user-event-log)
- 03-03-PLAN.md — §10 #8 password-filter PARTIAL verification (A31; D-P3-02 charter)
- 03-04-PLAN.md — §10 #9 RAM ceiling best-effort + Page.metrics scaffolding (A32; D-P3-04 charter)
- 03-05-PLAN.md — §10 sweep VERIFICATION.md aggregator + REQUIREMENTS/ROADMAP/STATE marker flips
Phase 4: Harden + clean up (optional)
Goal: Eliminate the P1/P2 follow-ups identified in the audit so that the codebase is not just spec-conformant but maintainable. This phase has no new v1 requirements — it improves robustness and removes technical debt around already-shipped behaviour.
Depends on: Phase 3 (do not harden until §10 is green).
Requirements: none (no new v1 REQs; all v1 REQs are covered by phases 1–3)
P1/P2 items addressed (informative list from the audit, exact scope finalized at plan time):
- SW state persistence around the 30 s idle unload edge cases.
fetchinterception fix in the network-error path of REQ-user-event-log.meta.jsonfield hardening (timestamp source, version source, totalEvents derivation).generate-icons.jsESM/CJS compatibility with the rest of the toolchain.- Dead-code cleanup (the
permissions.requestdance removed in Phase 3 may have stranded helpers; the offscreen duality removed in Phase 1 may have stranded shims). getDisplayMediacursor visibility constraint (video: { cursor: 'always' }) — refines capture quality for diagnostic UX; surfaced during Phase 1 smoke (2026-05-15) as a user observation. Operator's screen cursor was absent from captured frames despite being the highest-signal cue when reproducing pointer-driven bugs. Constraint is opt-in per thegetDisplayMediaspec and Chrome implements it via theCursorCaptureConstraintenum (always/motion/never).
Success Criteria (what must be TRUE):
- After running the extension idle for >5 minutes, then exporting, the
archive still contains a non-empty video buffer (proves SW state
persistence works across one or more SW unload/reload cycles).
STATUS 2026-05-22: CLOSED via Plan 04-08 — see .planning/phases/04-harden-clean-up-optional/04-08-SUMMARY.md.
The prior Plan 04-04 SPIKE FAILED outcome (8505 bytes; 2026-05-21) was
empirically REFUTED by debug session-2 (commit
4ea1bbb): the offscreen-RAMsegments: Blob[]architecture is sound (POST-KILL probe count=3 confirms structural persistence); the failure was test methodology (canvas.captureStream invisible-source throttling per Chrome bug 653548). Plan 04-08 replaced the canvas source with HTMLVideoElement.captureStream backed by a bundled WebM (preserving eager-install contract via SYNC-install + LAZY first-frame pattern); spike re-run produces videoSize=1_797_178 bytes (1.8 MB; well above 100 KB floor); A33 harness assertion lands per Plan 04-04 Pattern 4 verbatim under SKIP_LONG_UAT env-gate. Reproducible verification gate: tests/uat/spike-a33-sw-persistence.ts (now PASSES under valid methodology). - A page that issues a failing
fetch(response code >= 400) produces anetwork_errorentry inevents.json; a failingXMLHttpRequestdoes too. STATUS 2026-05-22: CLOSED via Plan 04-05 — see .planning/phases/04-harden-clean-up-optional/04-05-SUMMARY.md. A34 harness assertion fires a syntheticfetch(404)+XMLHttpRequest(404)from anhttps://example.comprobe tab viachrome.scripting.executeScriptISOLATED-world; host-sidedriveA34JSZip-parseslogs/events.jsonand confirms 2network_errorentries (one fetch, one XHR), each withmeta.status === 404. Skip-mode UAT (SKIP_LONG_UAT=1): 35/35 GREEN with A34 running for real — all 6 A34 checks PASS. The fetch entry'stargetcarries the real URL (https://example.com/404-fetch-a34-<stamp>), NOT[object Request], empirically validating the Plan 04-01 P1 #11 Request-narrow fix end-to-end at the SAVE->archive layer. NOTE: full-mode UAT (5-min A33 real) bailed at A33.1 (a pre-existing Plan 04-08 SAVE-ack flake — the 1.56 MB video buffer survived; only the post-worker.close()ack channel raced) so A34 was SKIPPED-not-reached in that run; A34 itself is unaffected and fully verified by the skip-mode 35/35. The A33 full-mode flake is routed to /gsd-debug as a separate cross-plan concern (does NOT block ROADMAP SC #2). npm run buildandnode generate-icons.jsboth succeed under the project's module setting ("type": "module"inpackage.json) with norequire is not definedorCannot use import statement outside a moduleerrors.- A repo grep for the symbols deleted in phases 1 and 3
(
permissions.request, the duplicate offscreen inline string) returns no live references.
Plans: 7 plans (04-01 through 04-07). Wave 1 parallel (04-01 + 04-02) -> Wave 2 sequential (04-03 A29 rewrite -> 04-04 A33 SW persistence -> 04-05 A34 fetch+XHR) -> Wave 5 visual polish (04-06; operator empirical) -> Wave 6 closure (04-07).
- 04-01-PLAN.md — Audit P1 polish #11 + #14 + #15 (TDD; 3 unit tests + 3 src/content/index.ts edits)
- 04-02-PLAN.md — Build/CSP hygiene (setimmediate polyfill replacement + dead-code grep + generate-icons.cjs rename)
- 04-03-PLAN.md — A29 cs-injection-world rewrite (strict-sentinel filter; closes ~1/3 flake)
- 04-04-PLAN.md — A33 SW state persistence: spike-first Wave 0 SPIKE FAILED 2026-05-21 (videoSize=8505 bytes vs 100KB floor; offscreen RAM-only
segments: Blob[]at src/offscreen/recorder.ts:91 does NOT survive 5-min SW idle + Puppeteer CDPworker.close(); corrupt WebM per ffprobe). REFUTED-architecture 2026-05-22 via debug session-2 (commit4ea1bbb): root cause is canvas.captureStream invisible-canvas throttling (Chrome bug 653548), NOT architectural; segments survived SW kill structurally (POST-KILL probe count=3). Plan 04-04 SUMMARY amended atc1501e7with the REFUTED-architecture verdict + Plan 04-08 insertion authorization. ROADMAP SC #1 reframed as test-methodology issue (NOT architectural); IndexedDB persistence plan-fix REJECTED (would not have closed SC #1 because segments are not the problem, frames are). - 04-08-PLAN.md — A33 methodology reframe + harness assertion: CLOSED 2026-05-22 via debug session-2 verdict (canvas-captureStream invisible-source throttling root cause); HTMLVideoElement.captureStream replaces canvas.captureStream in installFakeDisplayMedia() with SYNC install + LAZY first-frame contract; spike re-run produces videoSize=1_797_178 bytes (1.8 MB; vs 8505 baseline); A33 lands per original Plan 04-04 Wave 1 spec under SKIP_LONG_UAT env-gate; UAT 33 -> 34 GREEN. ROADMAP SC #1 CLOSED.
- 04-05-PLAN.md — A34 fetch + XHR network_error empirical: CLOSED 2026-05-22. assertA34 + driveA34 + 3-site orchestrator wiring; cs-injection-world
fetch(404)+XMLHttpRequest(404)from a probe tab; host-side asserts 2network_errorentries withmeta.status === 404. Skip-mode UAT 34 -> 35/35 GREEN (A34 real; all 6 checks PASS). Plan 04-01 P1 #11 Request-narrow fix validated end-to-end (fetchtarget= real URL, not[object Request]). ROADMAP SC #2 CLOSED. Full-mode 35/35 gate observed a pre-existing Plan 04-08 A33 SAVE-ack flake (A33.1 false; video buffer survived at 1.56 MB) — A34 SKIPPED-not-reached in that run but unaffected; A33 flake routed to /gsd-debug. - 04-06-PLAN.md — Dark-logo currentColor + cursor visibility verification + 01-07-SUMMARY back-patch (UI-SPEC; operator empirical ack): CLOSED 2026-05-26 via operator re-empirical confirmation "Confirmed fixed — close Plan 04-06". D-P4-03 (both visual polish items) CLOSED. Multi-iteration ceremony: 3 planner passes + 2 checker passes + 1 /gsd-debug fix cycle. Key deliverables: (1) SVG stroke recolor (
stroke="currentColor") + welcome.ts?raw/DOMParser/replaceChildren inline-SVG injection (no<img>, no innerHTML) + globals.d.ts*.svg?rawambient decl; (2) NEW brand-component token--mks-mark-stroke = var(--mks-linen-50)in :root (NOT overridden in.dark) — decoupled the welcome-hero mark from the theme-flipping semantic--mks-fg-inversetoken (abstraction error surfaced via Task 4 operator empirical TWEAK; routed via /gsd-debug perfeedback-gsd-ceremony-for-fixes.md; fix ata8bcc17); (3) NEW A35 host-side harness with 5 sub-checks including A35.5 light+dark equality decouple-proof (UAT 35 → 36 GREEN); (4) tests/welcome/inline-svg.test.ts (3 tests) + tests/build/cursor-visibility.test.ts (1 test) — vitest 184 → 188 GREEN; (5) 01-07-SUMMARY back-patch (5 stale 'deferred to Phase 5' framing lines flipped, 4 historical commit-description lines left); (6) deferred-items.md mis-diagnosis correction (04-CONTEXT #9/#10 parallel-vitest flake, NOT strict-meta-json). FORBIDDEN_HOOK_STRINGS unchanged at 12; 6/6 bundle gates PASS. SUMMARY: .planning/phases/04-harden-clean-up-optional/04-06-SUMMARY.md. - 04-07-PLAN.md — Phase 4 closure aggregator + ROADMAP backfill (D-P4-05) + v1 milestone close prep: CLOSED 2026-05-26. Plan 04-07 created
.planning/phases/04-harden-clean-up-optional/04-VERIFICATION.md(253 lines; 13 ## sections; 67 Plan 04-0 citations; 9 operator-ack literal hits; 44 commit refs) covering all 8 Phase 4 plans + 3 /gsd-debug sessions + 4 ROADMAP SC closures (SC #1 via Plan 04-08 + SC #2 via Plan 04-05 + SC #3 + SC #4 via Plan 04-02) + 3 audit P1 polish items (#11 + #14 + #15 all via Plan 04-01 D-P4-02) + 6 cross-cutting hardening items + 5/5 D-P4-* charter closures + Phases 1-4 cumulative gate evidence. UAT harness 33 → 36 GREEN (+A33 + A34 + A35; A33 SKIP_LONG_UAT env-gated; A35 5 sub-checks incl. A35.5 light+dark equality decouple-proof). vitest 171 → 188 GREEN (+17 across Plans 04-01/02/06/08). Pre-checkpoint bundle gates 6/6 PASS (Gate 2 polarity flipped 1 → 0 via Plan 04-02 4-mechanism layered mitigation). Tier-1 FORBIDDEN_HOOK_STRINGS unchanged at 12 entries. NEW Tier-2 production-bundle filename-leak gate added by Plan 04-08. Operator-empirical ack 2026-05-26 verbatim "Confirmed fixed — close Plan 04-06" (Plan 04-06 Task 4 cycle-2 after /gsd-debug fix at commita8bcc17). D-P4-05 ROADMAP backfill (Plan 01-13 plan-checker flag #4) verified — Plans 01-08..01-14 rows present at ROADMAP.md lines 90-96 with [x] closure annotations; no row additions needed. STATE.md / REQUIREMENTS.md / PROJECT.md marker flips landed atomically with this row flip. Phase 4 row [x] flip + completed_phases bump + status:completed flip DEFERRED to closure ceremony after independent gsd-verifier audit (Phase 1-3 precedent: executor creates VERIFICATION.md; verifier independently re-validates; orchestrator flips post-audit). SUMMARY: .planning/phases/04-harden-clean-up-optional/04-07-SUMMARY.md.
Progress
Execution Order: Phases execute in numeric order: 1 → 2 → 3 → 4 → 5.
| Phase | Plans Complete | Status | Completed |
|---|---|---|---|
| 1. Stabilize video pipeline | 14/14 | CLOSED 2026-05-20 via gsd-verifier audit GREEN (17/17 must-haves; commit 586836f); all markers flipped |
Functional contract closed 2026-05-19 via Plan 01-13 harness PASS; design/brand contract closed 2026-05-20 via Plan 01-12 brand-fit ack; welcome-tab contract closed 2026-05-20 via Plan 01-10 cycle-2 operator ack "All good" + 5 inter-cycle debug fixes |
| 2. Stabilize export pipeline | 0/4 | Plans landed 2026-05-20 (4 plans: Wave 0 RED → Wave 1 Blob URL + meta.urls parallel → Wave 2 harness + operator checkpoint); execution pending | - |
| 3. SPEC §10 smoke + DOM/event-log verification | 0/TBD | Not started (absorbed Phase-2 DOM verification per 2026-05-20 re-phasing; ~2-3 plans) | - |
| 4. Harden + clean up (optional) | 8/8 | In Progress (Plan 04-07 closed — Phase 4 closure aggregator created; 04-VERIFICATION.md at .planning/phases/04-harden-clean-up-optional/04-VERIFICATION.md; ALL 4/4 ROADMAP SC + 3/3 audit P1 + 6/6 hardening items GREEN; UAT 36/36 + vitest 188/188 + 6/6 bundle gates + Tier-1=12 + NEW Tier-2; 3 /gsd-debug sessions documented; operator re-empirical 'Confirmed fixed' 2026-05-26; D-P4-05 ROADMAP backfill verified). Phase 4 row [x] flip + completed_phases bump + status:completed flip DEFERRED to closure ceremony after independent gsd-verifier audit — Phase 1-3 precedent. | (pending gsd-verifier audit) |