--- phase: 01-stabilize-video-pipeline plan: 10 type: execute wave: 4 depends_on: - 01-09 - 01-13 files_modified: - manifest.json - vite.config.ts - vite.test.config.ts - src/welcome/welcome.html - src/welcome/welcome.ts - src/welcome/welcome.css - src/welcome/copy.ts - src/welcome/welcome-tokens.css - src/background/index.ts - tests/background/onboarding.test.ts - tests/uat/extension-page-harness.ts - tests/uat/extension-page-harness.html - tests/uat/lib/harness-page-driver.ts - tests/uat/harness.test.ts autonomous: false requirements: - REQ-video-ring-buffer tags: - onboarding - welcome - chrome.runtime.onInstalled - chrome.storage - web_accessible_resources - design-swap-in-ready - css-variables - i18n-keys - D-17-onboarding - D-02-welcome-layout - D-08-tagline - harness-A15-A17 must_haves: truths: - "On first install (chrome.runtime.onInstalled with reason 'install') AND chrome.storage.local.get('onboarding-completed') returns nothing, exactly ONE welcome tab opens automatically pointing at chrome.runtime.getURL('src/welcome/welcome.html'). After the tab opens, chrome.storage.local.set is called with {'onboarding-completed': true, 'installed-at': }." - "On subsequent installs (reason 'update' or 'chrome_update') OR when 'onboarding-completed' is already true, NO welcome tab opens (chrome.tabs.create is NOT called)." - "The welcome page renders a hero (.welcome-hero slot) containing a placeholder mark, the D-08 tagline string (Russian primary + English subtitle), 2-3 explainer lines, a primary instruction pointing the operator at the toolbar icon (NOT a Start button — toolbar onClicked owns the start path per Plan 01-09 D-16-toolbar), and a privacy/safety footer." - "The welcome page contains NO hardcoded hex color values in welcome.css — every color is sourced from a --mks-* CSS custom property defined in welcome-tokens.css (placeholder palette today; swapped for tokens.css import in Plan 01-12)." - "All copy strings live in a single source-of-truth src/welcome/copy.ts exporting a const COPY map; welcome.ts reads keys via COPY['welcome.hero.title'] style access. When Plan 01-12 lands _locales/, the swap is a one-commit change of copy.ts reading chrome.i18n.getMessage(key)." - "Typography uses font-family: var(--mks-font-display, ) and var(--mks-font-ui, ) — when Plan 01-12 self-hosts Newsreader (or designer-picked Cyrillic-capable alternative per brand-decisions-v1-followup-display-font.md) the bundled face resolves; until then the system fallback renders." - "The welcome page references NO REQUEST_PERMISSIONS message type, NO chrome.runtime.sendMessage start path, NO duplicate getDisplayMedia trigger. Its CTA is informational — points operator at the toolbar icon (01-09 owns toolbar onClicked → picker)." - "Onboarding unit test covers BOTH first-install AND subsequent-install paths AND the storage-key contract via three synthesized onInstalled events + chrome.storage.local.get mock setups." - "UAT harness extends with three new assertions (A15, A16, A17). A15 = onboarding flag observability (chrome.storage.local 'onboarding-completed' is true AND 'installed-at' is a number AT LEAST ONCE during this session). A16 = subsequent-install does NOT re-open (post-A15 settle observation: no new welcome tabs spontaneously appear; chrome.tabs.query count delta is 0 over 2-second window). A17 = design-swap readiness invariant: welcome.html parses; .welcome-hero slot exists; welcome.css contains zero #hex literals (regex /#[0-9a-fA-F]{3,8}/ match count == 0); welcome.html contains ≥ 7 data-mokosh-key attributes; bundled welcome JS chunk contains substring 'COPY['." - "npm run test:uat reports 18/18 GREEN at plan close (existing 15 + A15 + A16 + A17). npm test (vitest) reports baseline 98 GREEN + 3 new onboarding tests GREEN = 101 GREEN; Tier-1 forbidden-strings inventory unchanged at 10 (no new test-hook surface introduced)." artifacts: - path: "src/welcome/welcome.html" provides: "Welcome page markup. Hero wrapped in
...
...