Milestone v1 (v2.0.0): Mokosh — Session Capture #1
@@ -6,6 +6,7 @@ wave: 6
|
|||||||
depends_on:
|
depends_on:
|
||||||
- 01-09
|
- 01-09
|
||||||
- 01-13
|
- 01-13
|
||||||
|
- 01-14
|
||||||
files_modified:
|
files_modified:
|
||||||
- src/shared/tokens.css
|
- src/shared/tokens.css
|
||||||
- src/shared/fonts/Lora-VariableFont.woff2
|
- src/shared/fonts/Lora-VariableFont.woff2
|
||||||
@@ -91,9 +92,9 @@ must_haves:
|
|||||||
- "src/popup/index.html title element becomes '__MSG_extName__' (or empty, populated by JS via chrome.i18n.getMessage('extName')); span.button-text remains empty (populated by JS per RESEARCH Pitfall 3); src/popup/index.ts updateUI() reads buttonText.textContent = chrome.i18n.getMessage('popupSaveCta') in idle case, 'popupSaveDone' in done case; the 'Архив успешно сохранён!' literal at saveArchive() success branch (line 91) becomes chrome.i18n.getMessage('popupSaveDone'); the info-text 'Последние 30 сек видео + 10 мин лога' at index.html line 15 becomes a data-mks-key='popupInfoText' attribute populated by JS. src/popup/style.css imports `../shared/tokens.css` and ALL hardcoded hex literals (#2563eb, #1d4ed8, #94a3b8, #f8f9fa, #0891b2, #059669, #dc2626, #64748b) are replaced with var(--mks-*) references (--mks-rec for save button, --mks-success for done state, --mks-error for error, --mks-fg-2 for info text, --mks-surface for body bg, --mks-fg-disabled for disabled, --mks-warning for warning info)."
|
- "src/popup/index.html title element becomes '__MSG_extName__' (or empty, populated by JS via chrome.i18n.getMessage('extName')); span.button-text remains empty (populated by JS per RESEARCH Pitfall 3); src/popup/index.ts updateUI() reads buttonText.textContent = chrome.i18n.getMessage('popupSaveCta') in idle case, 'popupSaveDone' in done case; the 'Архив успешно сохранён!' literal at saveArchive() success branch (line 91) becomes chrome.i18n.getMessage('popupSaveDone'); the info-text 'Последние 30 сек видео + 10 мин лога' at index.html line 15 becomes a data-mks-key='popupInfoText' attribute populated by JS. src/popup/style.css imports `../shared/tokens.css` and ALL hardcoded hex literals (#2563eb, #1d4ed8, #94a3b8, #f8f9fa, #0891b2, #059669, #dc2626, #64748b) are replaced with var(--mks-*) references (--mks-rec for save button, --mks-success for done state, --mks-error for error, --mks-fg-2 for info text, --mks-surface for body bg, --mks-fg-disabled for disabled, --mks-warning for warning info)."
|
||||||
- "If Plan 01-10 (welcome tab) has landed before Plan 01-12 executes: src/welcome/welcome-tokens.css placeholder is REPLACED with a one-liner `@import '../shared/tokens.css';`, and any per-key copy literals in src/welcome/copy.ts are migrated to chrome.i18n.getMessage('<key>') reads (welcomeHeroRu, welcomeHeroEn) with the in-file COPY map removed or reduced to a fallback shim. If Plan 01-10 has NOT yet landed: src/welcome/* files are NOT created by Plan 01-12; the canonical tokens.css is import-ready from src/shared/tokens.css and Plan 01-10 executor can swap to it from day 1 (no placeholder welcome-tokens.css needed)."
|
- "If Plan 01-10 (welcome tab) has landed before Plan 01-12 executes: src/welcome/welcome-tokens.css placeholder is REPLACED with a one-liner `@import '../shared/tokens.css';`, and any per-key copy literals in src/welcome/copy.ts are migrated to chrome.i18n.getMessage('<key>') reads (welcomeHeroRu, welcomeHeroEn) with the in-file COPY map removed or reduced to a fallback shim. If Plan 01-10 has NOT yet landed: src/welcome/* files are NOT created by Plan 01-12; the canonical tokens.css is import-ready from src/shared/tokens.css and Plan 01-10 executor can swap to it from day 1 (no placeholder welcome-tokens.css needed)."
|
||||||
- "vite.config.ts gains a `define` block setting __VITE_DEV__ = JSON.stringify(process.env.VITE_DEV === '1') per RESEARCH §12 D-09 spirit-satisfaction (defensive flag for any future inline smoke-mode check; smoke.sh continues to live outside Vite's input set entirely — verified by `grep -rn 'smoke\\|SMOKE\\|data:text/html' src/` returning empty). vite.test.config.ts inherits via mergeConfig. scripts/README.md (NEW) documents the smoke isolation invariant in one paragraph."
|
- "vite.config.ts gains a `define` block setting __VITE_DEV__ = JSON.stringify(process.env.VITE_DEV === '1') per RESEARCH §12 D-09 spirit-satisfaction (defensive flag for any future inline smoke-mode check; smoke.sh continues to live outside Vite's input set entirely — verified by `grep -rn 'smoke\\|SMOKE\\|data:text/html' src/` returning empty). vite.test.config.ts inherits via mergeConfig. scripts/README.md (NEW) documents the smoke isolation invariant in one paragraph."
|
||||||
- "Tier-1 forbidden-strings inventory in tests/background/no-test-hooks-in-prod-bundle.test.ts AND tests/uat/harness.test.ts is UNCHANGED at 10 strings (no new test-mode symbols introduced by Plan 01-12; the i18n + tokens + font work uses production chrome.* APIs end-to-end). Verified by file-diff after plan close."
|
- "Tier-1 forbidden-strings inventory in tests/background/no-test-hooks-in-prod-bundle.test.ts AND tests/uat/harness.test.ts is UNCHANGED at 12 strings post-Plan-01-14 (no new test-mode symbols introduced by Plan 01-12; the i18n + tokens + font work uses production chrome.* APIs end-to-end). Plan 01-14 established the 12-string baseline by adding `lastGetDisplayMediaConstraints` + `get-last-getDisplayMedia-constraints` for its monitorTypeSurfaces harness. Verified by file-diff after plan close."
|
||||||
- "UAT harness extended with 5 new assertions A18-A22: A18 = Lora WOFF2 loads from chrome.runtime.getURL('shared/fonts/Lora-VariableFont.woff2') OR equivalent emitted asset path (response.ok && content-length > 50000 — Lora variable Latin+Cyrillic is ~80-120KB after subsetting). A19 = icons are NOT the Bug A placeholders (icon128.png file size differs from the known 2615-byte 16-bit-RGB placeholder; OR icon128.png file content hash differs from the placeholder content hash). A20 = chrome.runtime.getManifest().name === 'Mokosh — Session Capture' (i18n resolution test; the en-locale fallback always returns this exact string per default_locale='en'). A21 = getComputedStyle on a test element with CSS class .mks-display-1 inside the harness page resolves to a font-family stack starting with 'Lora' (not 'Newsreader', not system fallback). A22 = welcome page tokens.css is loaded if 01-10 has landed (fetch chrome.runtime.getURL('src/welcome/welcome.html') returns 200 + welcome.css resolves --mks-rec to '#b2543d'); skip with a documented diagnostic if 01-10 has not landed."
|
- "UAT harness extended with 5 new assertions A18-A22: A18 = Lora WOFF2 loads from chrome.runtime.getURL('shared/fonts/Lora-VariableFont.woff2') OR equivalent emitted asset path (response.ok && content-length > 50000 — Lora variable Latin+Cyrillic is ~80-120KB after subsetting). A19 = icons are NOT the Bug A placeholders (icon128.png file size differs from the known 2615-byte 16-bit-RGB placeholder; OR icon128.png file content hash differs from the placeholder content hash). A20 = chrome.runtime.getManifest().name === 'Mokosh — Session Capture' (i18n resolution test; the en-locale fallback always returns this exact string per default_locale='en'). A21 = getComputedStyle on a test element with CSS class .mks-display-1 inside the harness page resolves to a font-family stack starting with 'Lora' (not 'Newsreader', not system fallback). A22 = welcome page tokens.css is loaded if 01-10 has landed (fetch chrome.runtime.getURL('src/welcome/welcome.html') returns 200 + welcome.css resolves --mks-rec to '#b2543d'); skip with a documented diagnostic if 01-10 has not landed."
|
||||||
- "Every Plan 01-13 harness assertion (A0-A14) and Plan 01-10 assertion (A15-A17, IF landed) remains GREEN after Plan 01-12 changes (no regression). vitest baseline grows by 6 tests (icons-present + tokens-adopted + fonts-present + no-remote-fonts + manifest-i18n + locale-parity) from 98 GREEN to 104 GREEN; npm run test:uat grows from 15/15 (or 18/18 with 01-10) to 20/20 (or 23/23 with 01-10 + 01-12) — all GREEN."
|
- "Every Plan 01-13 harness assertion (A0-A14), Plan 01-14 assertion (A23), and Plan 01-10 assertion (A15-A17, IF landed) remains GREEN after Plan 01-12 changes (no regression). vitest baseline grows by 6 tests (icons-present + tokens-adopted + fonts-present + no-remote-fonts + manifest-i18n + locale-parity) from 100 GREEN (post-01-14) to 106 GREEN; npm run test:uat grows from 16/16 (post-01-14, or 19/19 with 01-10) to 21/21 (or 24/24 with 01-10 + 01-12) — all GREEN."
|
||||||
- "MV3 architectural constraints from 01-11-SUMMARY enforced: NO `await import(...)` anywhere in src/background/index.ts (chrome.i18n.getMessage is a synchronous API; no dynamic imports required); test-mode symbols stay in dist-test/ only via __MOKOSH_UAT__ define-token (Plan 01-12 introduces no new test-mode symbols)."
|
- "MV3 architectural constraints from 01-11-SUMMARY enforced: NO `await import(...)` anywhere in src/background/index.ts (chrome.i18n.getMessage is a synchronous API; no dynamic imports required); test-mode symbols stay in dist-test/ only via __MOKOSH_UAT__ define-token (Plan 01-12 introduces no new test-mode symbols)."
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: "src/shared/tokens.css"
|
- path: "src/shared/tokens.css"
|
||||||
@@ -202,10 +203,10 @@ must_haves:
|
|||||||
provides: "Adds driveA18, driveA19, driveA20, driveA21, driveA22 host-side wrappers following the existing driveA4 pattern (page.evaluate → window.__mokoshHarness.assertXX). No new host-side filesystem or ffprobe primitives; all A18-A22 work runs page-side via fetch + getComputedStyle + chrome.runtime.getManifest."
|
provides: "Adds driveA18, driveA19, driveA20, driveA21, driveA22 host-side wrappers following the existing driveA4 pattern (page.evaluate → window.__mokoshHarness.assertXX). No new host-side filesystem or ffprobe primitives; all A18-A22 work runs page-side via fetch + getComputedStyle + chrome.runtime.getManifest."
|
||||||
min_lines: 60
|
min_lines: 60
|
||||||
- path: "tests/uat/harness.test.ts"
|
- path: "tests/uat/harness.test.ts"
|
||||||
provides: "Orchestrator extended with A18-A22 entries. FORBIDDEN_HOOK_STRINGS list UNCHANGED at 10 entries (no new test-mode symbols introduced). Assertion count grows from 15/15 (post-01-13) or 18/18 (post-01-10+01-13) to 20/20 or 23/23 (post-01-12). Bail-on-first-failure orchestration unchanged."
|
provides: "Orchestrator extended with A18-A22 entries. FORBIDDEN_HOOK_STRINGS list UNCHANGED at 12 entries post-Plan-01-14 (no new test-mode symbols introduced by Plan 01-12). Assertion count grows from 16/16 (post-01-13+01-14) or 19/19 (post-01-10+01-13+01-14) to 21/21 or 24/24 (post-01-12). Bail-on-first-failure orchestration unchanged."
|
||||||
contains: "A18"
|
contains: "A18"
|
||||||
- path: ".planning/STATE.md"
|
- path: ".planning/STATE.md"
|
||||||
provides: "Wave 7 closure update: completed_plans increments by 1 (Plan 01-12 closes); decision-log appends '[Phase 01-12]: design integration landed — Lora self-hosted (R2 per designer 2026-05-19) + tokens.css canonical + 8 i18n strings + branded icons + manifest:name i18n; UAT harness 20/20 GREEN (or 23/23 if 01-10 also landed); operator brand-fit ack received'. percent recomputed."
|
provides: "Wave 7 closure update: completed_plans increments by 1 (Plan 01-12 closes); decision-log appends '[Phase 01-12]: design integration landed — Lora self-hosted (R2 per designer 2026-05-19) + tokens.css canonical + 8 i18n strings + branded icons + manifest:name i18n; UAT harness 21/21 GREEN (or 24/24 if 01-10 also landed); operator brand-fit ack received'. percent recomputed."
|
||||||
- path: ".planning/ROADMAP.md"
|
- path: ".planning/ROADMAP.md"
|
||||||
provides: "Phase 1 Plans list gains `- [x] 01-12-PLAN.md — Design integration (R2 Lora, tokens.css, 8 i18n strings, branded icons, manifest i18n)` entry after 01-13. If Plan 01-10 not yet in list, also add its entry as `- [ ]` placeholder unless already present."
|
provides: "Phase 1 Plans list gains `- [x] 01-12-PLAN.md — Design integration (R2 Lora, tokens.css, 8 i18n strings, branded icons, manifest i18n)` entry after 01-13. If Plan 01-10 not yet in list, also add its entry as `- [ ]` placeholder unless already present."
|
||||||
key_links:
|
key_links:
|
||||||
@@ -304,9 +305,9 @@ Output:
|
|||||||
- Wave 1: src/shared/fonts/ + src/shared/tokens.css + scripts/subset-fonts.sh; fonts-present + no-remote-fonts flip GREEN.
|
- Wave 1: src/shared/fonts/ + src/shared/tokens.css + scripts/subset-fonts.sh; fonts-present + no-remote-fonts flip GREEN.
|
||||||
- Wave 2: icons/icon{16,48,128}.png + scripts/rasterize-icons.sh + src/shared/brand/; icons-present flips GREEN.
|
- Wave 2: icons/icon{16,48,128}.png + scripts/rasterize-icons.sh + src/shared/brand/; icons-present flips GREEN.
|
||||||
- Wave 3: manifest.json + _locales/{en,ru}/messages.json; manifest-i18n + locale-parity flip GREEN; manifest:name resolves to "Mokosh — Session Capture" on extension reload.
|
- Wave 3: manifest.json + _locales/{en,ru}/messages.json; manifest-i18n + locale-parity flip GREEN; manifest:name resolves to "Mokosh — Session Capture" on extension reload.
|
||||||
- Wave 4: src/popup/style.css + src/popup/index.html + src/popup/index.ts + src/background/index.ts; tokens-adopted flips GREEN; existing 98+ vitest tests stay GREEN (i18n-call-site migration is behavior-equivalent for the chrome.* mock pattern used by existing tests).
|
- Wave 4: src/popup/style.css + src/popup/index.html + src/popup/index.ts + src/background/index.ts; tokens-adopted flips GREEN; existing 100+ vitest tests stay GREEN (i18n-call-site migration is behavior-equivalent for the chrome.* mock pattern used by existing tests).
|
||||||
- Wave 5: src/welcome/* conditional migration (if 01-10 landed) OR skip; vite.config.ts __VITE_DEV__ define-token + scripts/README.md.
|
- Wave 5: src/welcome/* conditional migration (if 01-10 landed) OR skip; vite.config.ts __VITE_DEV__ define-token + scripts/README.md.
|
||||||
- Wave 6: tests/uat/extension-page-harness.ts + tests/uat/lib/harness-page-driver.ts + tests/uat/harness.test.ts extended with A18-A22; npm run test:uat reports 20/20 (or 23/23 with 01-10) GREEN.
|
- Wave 6: tests/uat/extension-page-harness.ts + tests/uat/lib/harness-page-driver.ts + tests/uat/harness.test.ts extended with A18-A22; npm run test:uat reports 21/21 (or 24/24 with 01-10) GREEN.
|
||||||
- Wave 7: operator checkpoint; STATE.md + ROADMAP.md sync; SUMMARY produced.
|
- Wave 7: operator checkpoint; STATE.md + ROADMAP.md sync; SUMMARY produced.
|
||||||
</objective>
|
</objective>
|
||||||
|
|
||||||
@@ -645,7 +646,7 @@ async function assertA21(): Promise<AssertionRecord> {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tier-1 forbidden-strings inventory (UNCHANGED at 10)
|
### Tier-1 forbidden-strings inventory (UNCHANGED at 12 post-Plan-01-14)
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
const FORBIDDEN_HOOK_STRINGS: ReadonlyArray<string> = [
|
const FORBIDDEN_HOOK_STRINGS: ReadonlyArray<string> = [
|
||||||
@@ -659,9 +660,12 @@ const FORBIDDEN_HOOK_STRINGS: ReadonlyArray<string> = [
|
|||||||
'__mokoshOffscreenQuery',
|
'__mokoshOffscreenQuery',
|
||||||
'get-display-surface',
|
'get-display-surface',
|
||||||
'get-segment-count',
|
'get-segment-count',
|
||||||
|
'lastGetDisplayMediaConstraints', // added by Plan 01-14
|
||||||
|
'get-last-getDisplayMedia-constraints', // added by Plan 01-14
|
||||||
];
|
];
|
||||||
// Plan 01-12 introduces NO new test-mode symbols (A18-A22 use production chrome.* APIs
|
// Plan 01-12 introduces NO new test-mode symbols (A18-A22 use production chrome.* APIs
|
||||||
// + fetch + getComputedStyle exclusively). Do NOT extend this list.
|
// + fetch + getComputedStyle exclusively). Do NOT extend this list beyond the 12 entries
|
||||||
|
// established by Plan 01-14.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Locale-parity test shape
|
### Locale-parity test shape
|
||||||
@@ -729,7 +733,7 @@ describe('_locales/ key parity', () => {
|
|||||||
- 6 test files exist at the documented paths
|
- 6 test files exist at the documented paths
|
||||||
- vitest discovers all 6 + reports them in `npx vitest run tests/build tests/i18n`
|
- vitest discovers all 6 + reports them in `npx vitest run tests/build tests/i18n`
|
||||||
- At least one case per file is RED today (per behavior above)
|
- At least one case per file is RED today (per behavior above)
|
||||||
- npm run build / build:test still pass (these tests do not change source code yet — the existing 98 vitest GREEN baseline stays GREEN; only the 6 new tests are RED)
|
- npm run build / build:test still pass (these tests do not change source code yet — the existing 100 vitest GREEN baseline (post-01-14) stays GREEN; only the 6 new tests are RED)
|
||||||
- Atomic commit `test(01-12): wave-0 — scaffold RED unit tests for tokens / fonts / icons / no-remote-fonts / manifest-i18n / locale-parity`
|
- Atomic commit `test(01-12): wave-0 — scaffold RED unit tests for tokens / fonts / icons / no-remote-fonts / manifest-i18n / locale-parity`
|
||||||
</done>
|
</done>
|
||||||
</task>
|
</task>
|
||||||
@@ -931,7 +935,7 @@ describe('_locales/ key parity', () => {
|
|||||||
- manifest.json:name === '__MSG_extName__'; :description === '__MSG_extDesc__'; :default_locale === 'en'; :action.default_title === '__MSG_tooltipOff__'
|
- manifest.json:name === '__MSG_extName__'; :description === '__MSG_extDesc__'; :default_locale === 'en'; :action.default_title === '__MSG_tooltipOff__'
|
||||||
- npm run build succeeds + dist/_locales/{en,ru}/messages.json exist + dist/manifest.json carries the new i18n shape
|
- npm run build succeeds + dist/_locales/{en,ru}/messages.json exist + dist/manifest.json carries the new i18n shape
|
||||||
- tests/i18n/manifest-i18n.test.ts + tests/i18n/locale-parity.test.ts GREEN
|
- tests/i18n/manifest-i18n.test.ts + tests/i18n/locale-parity.test.ts GREEN
|
||||||
- Existing 98 vitest baseline + 6 new tests = 104 vitest GREEN
|
- Existing 100 vitest baseline (post-01-14) + 6 new tests = 106 vitest GREEN
|
||||||
- Atomic commit `feat(01-12): wave-3 task-1 — manifest i18n (__MSG_*__ + default_locale='en') + _locales/{en,ru}/messages.json (12 keys; D-07 + D-08 baked in)`
|
- Atomic commit `feat(01-12): wave-3 task-1 — manifest i18n (__MSG_*__ + default_locale='en') + _locales/{en,ru}/messages.json (12 keys; D-07 + D-08 baked in)`
|
||||||
</done>
|
</done>
|
||||||
</task>
|
</task>
|
||||||
@@ -989,7 +993,7 @@ describe('_locales/ key parity', () => {
|
|||||||
|
|
||||||
The fallback `|| <const>` pattern reduces the need for chrome.i18n stubs in tests that don't depend on the displayed text; tests that DO depend on text shape need the identity-passthrough stub.
|
The fallback `|| <const>` pattern reduces the need for chrome.i18n stubs in tests that don't depend on the displayed text; tests that DO depend on text shape need the identity-passthrough stub.
|
||||||
|
|
||||||
6. Run `npm test` — expect 104+ GREEN (98 existing + 6 new tests + any new copy in popup tests adjusted via chrome.i18n stub).
|
6. Run `npm test` — expect 106+ GREEN (100 existing post-01-14 + 6 new tests + any new copy in popup tests adjusted via chrome.i18n stub).
|
||||||
|
|
||||||
7. Run `npm run build` then re-run `tests/build/no-remote-fonts.test.ts` — expect GREEN (dist/tokens.css contains zero `googleapis` / `https://fonts`).
|
7. Run `npm run build` then re-run `tests/build/no-remote-fonts.test.ts` — expect GREEN (dist/tokens.css contains zero `googleapis` / `https://fonts`).
|
||||||
</action>
|
</action>
|
||||||
@@ -1002,7 +1006,7 @@ describe('_locales/ key parity', () => {
|
|||||||
- src/background/index.ts uses chrome.i18n.getMessage at every operator-facing copy site (badge titles + 2 notification call sites; verified by grep ≥ 4 occurrences); BADGE_REC_COLOR === '#b2543d'
|
- src/background/index.ts uses chrome.i18n.getMessage at every operator-facing copy site (badge titles + 2 notification call sites; verified by grep ≥ 4 occurrences); BADGE_REC_COLOR === '#b2543d'
|
||||||
- tests/build/tokens-adopted.test.ts ALL cases GREEN (including (b)+(c) which were RED in Wave 0)
|
- tests/build/tokens-adopted.test.ts ALL cases GREEN (including (b)+(c) which were RED in Wave 0)
|
||||||
- tests/build/no-remote-fonts.test.ts GREEN (after npm run build)
|
- tests/build/no-remote-fonts.test.ts GREEN (after npm run build)
|
||||||
- vitest baseline 104+ GREEN (existing 98 + 6 new); no regressions in tests/background/*
|
- vitest baseline 106+ GREEN (existing 100 post-01-14 + 6 new); no regressions in tests/background/*
|
||||||
- Atomic commit `feat(01-12): wave-4 task-1 — adopt tokens.css + chrome.i18n.getMessage in src/popup/ + src/background/ (loom palette + RU i18n + en fallback)`
|
- Atomic commit `feat(01-12): wave-4 task-1 — adopt tokens.css + chrome.i18n.getMessage in src/popup/ + src/background/ (loom palette + RU i18n + en fallback)`
|
||||||
</done>
|
</done>
|
||||||
</task>
|
</task>
|
||||||
@@ -1036,7 +1040,7 @@ describe('_locales/ key parity', () => {
|
|||||||
|
|
||||||
5. Create scripts/README.md (single paragraph per RESEARCH §12): document that smoke.sh + future dev-only scripts live in this directory + are NOT bundled by npm run build + the production dist/ contains no smoke artifacts. Cross-reference RESEARCH.md §12 for the no-op-confirmation rationale.
|
5. Create scripts/README.md (single paragraph per RESEARCH §12): document that smoke.sh + future dev-only scripts live in this directory + are NOT bundled by npm run build + the production dist/ contains no smoke artifacts. Cross-reference RESEARCH.md §12 for the no-op-confirmation rationale.
|
||||||
|
|
||||||
6. Run npm test + npm run build + npm run build:test — expect all GREEN baseline + 6 new tests.
|
6. Run npm test + npm run build + npm run build:test — expect all GREEN baseline (100 post-01-14) + 6 new tests = 106 GREEN.
|
||||||
|
|
||||||
7. (Optional but recommended per RESEARCH §12 + the existing Tier-1 gate pattern): add a `tests/build/no-smoke-in-dist.test.ts` test asserting `grep -rn smoke dist/` returns 0 matches post-build. RED today if any smoke string leaks; GREEN per current architecture. Keep this OPTIONAL — if context budget tight, defer to a follow-up plan.
|
7. (Optional but recommended per RESEARCH §12 + the existing Tier-1 gate pattern): add a `tests/build/no-smoke-in-dist.test.ts` test asserting `grep -rn smoke dist/` returns 0 matches post-build. RED today if any smoke string leaks; GREEN per current architecture. Keep this OPTIONAL — if context budget tight, defer to a follow-up plan.
|
||||||
</action>
|
</action>
|
||||||
@@ -1048,7 +1052,7 @@ describe('_locales/ key parity', () => {
|
|||||||
- IF 01-10 NOT landed: src/welcome/* unchanged; STATE.md gains deferral note
|
- IF 01-10 NOT landed: src/welcome/* unchanged; STATE.md gains deferral note
|
||||||
- vite.config.ts:define block contains __VITE_DEV__ entry
|
- vite.config.ts:define block contains __VITE_DEV__ entry
|
||||||
- scripts/README.md exists + documents smoke-isolation invariant
|
- scripts/README.md exists + documents smoke-isolation invariant
|
||||||
- vitest baseline 104+ GREEN (+ N welcome keys added to messages.json if 01-10 landed; locale-parity stays GREEN)
|
- vitest baseline 106+ GREEN (+ N welcome keys added to messages.json if 01-10 landed; locale-parity stays GREEN)
|
||||||
- Atomic commit `feat(01-12): wave-5 task-1 — welcome i18n migration (conditional on 01-10) + __VITE_DEV__ define + scripts/README.md`
|
- Atomic commit `feat(01-12): wave-5 task-1 — welcome i18n migration (conditional on 01-10) + __VITE_DEV__ define + scripts/README.md`
|
||||||
</done>
|
</done>
|
||||||
</task>
|
</task>
|
||||||
@@ -1057,9 +1061,9 @@ describe('_locales/ key parity', () => {
|
|||||||
<name>Wave 6 Task 1: Extend UAT harness with A18-A22 (font / icon / manifest-i18n / Lora-resolved / welcome-tokens)</name>
|
<name>Wave 6 Task 1: Extend UAT harness with A18-A22 (font / icon / manifest-i18n / Lora-resolved / welcome-tokens)</name>
|
||||||
<files>tests/uat/extension-page-harness.ts, tests/uat/lib/harness-page-driver.ts, tests/uat/harness.test.ts</files>
|
<files>tests/uat/extension-page-harness.ts, tests/uat/lib/harness-page-driver.ts, tests/uat/harness.test.ts</files>
|
||||||
<behavior>
|
<behavior>
|
||||||
The 01-13 harness gains 5 new assertions following the established Approach-B pattern (page-side assertA* + host-side driveA* wrapper + harness.test.ts orchestrator entry). Each assertion uses production chrome.* APIs + fetch + getComputedStyle (no new test-mode symbols). After this wave: `npm run test:uat` reports 20/20 GREEN (or 23/23 with 01-10's A15-A17 already in place).
|
The 01-13 + 01-14 harness gains 5 new assertions following the established Approach-B pattern (page-side assertA* + host-side driveA* wrapper + harness.test.ts orchestrator entry). Each assertion uses production chrome.* APIs + fetch + getComputedStyle (no new test-mode symbols). After this wave: `npm run test:uat` reports 21/21 GREEN (or 24/24 with 01-10's A15-A17 already in place). A0-A14 (Plan 01-13) and A23 (Plan 01-14) remain GREEN as no-regression guarantees.
|
||||||
|
|
||||||
Tier-1 FORBIDDEN_HOOK_STRINGS list stays at 10 entries (no new test-mode surface introduced).
|
Tier-1 FORBIDDEN_HOOK_STRINGS list stays at 12 entries post-Plan-01-14 (no new test-mode surface introduced by Plan 01-12).
|
||||||
</behavior>
|
</behavior>
|
||||||
<action>
|
<action>
|
||||||
1. Extend tests/uat/extension-page-harness.ts: add 5 page-side methods to window.__mokoshHarness per the `<interfaces>` block shapes:
|
1. Extend tests/uat/extension-page-harness.ts: add 5 page-side methods to window.__mokoshHarness per the `<interfaces>` block shapes:
|
||||||
@@ -1071,21 +1075,21 @@ describe('_locales/ key parity', () => {
|
|||||||
|
|
||||||
2. Extend tests/uat/lib/harness-page-driver.ts: add driveA18 / driveA19 / driveA20 / driveA21 / driveA22 wrappers following the established driveA4 pattern (page.evaluate(() => window.__mokoshHarness.assertXX())). No new host-side fs / ffprobe / zip primitives.
|
2. Extend tests/uat/lib/harness-page-driver.ts: add driveA18 / driveA19 / driveA20 / driveA21 / driveA22 wrappers following the established driveA4 pattern (page.evaluate(() => window.__mokoshHarness.assertXX())). No new host-side fs / ffprobe / zip primitives.
|
||||||
|
|
||||||
3. Extend tests/uat/harness.test.ts: import driveA18..A22; add entries to the orchestrator's assertion list in sequence (after A14, or A17 if 01-10 landed). Keep FORBIDDEN_HOOK_STRINGS UNCHANGED at 10 entries — verify by `wc -l` diff before/after this task.
|
3. Extend tests/uat/harness.test.ts: import driveA18..A22; add entries to the orchestrator's assertion list in sequence (after A14, or A17 if 01-10 landed, with A23 from 01-14 elsewhere in the list). Keep FORBIDDEN_HOOK_STRINGS UNCHANGED at 12 entries (the 01-14-established baseline) — verify by `wc -l` diff before/after this task.
|
||||||
|
|
||||||
4. Run npm run build:test (rebuilds dist-test/). Then run `npm run test:uat` (or just `tsx tests/uat/harness.test.ts`). Expected output: 20/20 (or 23/23) GREEN.
|
4. Run npm run build:test (rebuilds dist-test/). Then run `npm run test:uat` (or just `tsx tests/uat/harness.test.ts`). Expected output: 21/21 (or 24/24) GREEN.
|
||||||
|
|
||||||
5. Run `npx vitest run tests/background/no-test-hooks-in-prod-bundle.test.ts` — confirm Tier-1 grep gate GREEN (no new hook strings leaked into dist/).
|
5. Run `npx vitest run tests/background/no-test-hooks-in-prod-bundle.test.ts` — confirm Tier-1 grep gate GREEN (no new hook strings leaked into dist/).
|
||||||
</action>
|
</action>
|
||||||
<verify>
|
<verify>
|
||||||
<automated>grep -c "assertA1[89]\|assertA2[012]" tests/uat/extension-page-harness.ts && grep -c "driveA1[89]\|driveA2[012]" tests/uat/lib/harness-page-driver.ts && grep -c "driveA1[89]\|driveA2[012]" tests/uat/harness.test.ts && (wc -l tests/uat/harness.test.ts && grep "FORBIDDEN_HOOK_STRINGS" tests/uat/harness.test.ts -A 13 | grep -c "'") && npx vitest run tests/background/no-test-hooks-in-prod-bundle.test.ts 2>&1 | tail -5 && (npm run test:uat 2>&1 | tail -25 || echo "test:uat invocation needs verification; check for 20/20 or 23/23 GREEN")</automated>
|
<automated>grep -c "assertA1[89]\|assertA2[012]" tests/uat/extension-page-harness.ts && grep -c "driveA1[89]\|driveA2[012]" tests/uat/lib/harness-page-driver.ts && grep -c "driveA1[89]\|driveA2[012]" tests/uat/harness.test.ts && (wc -l tests/uat/harness.test.ts && grep "FORBIDDEN_HOOK_STRINGS" tests/uat/harness.test.ts -A 15 | grep -v "^#" | grep -c "'") && npx vitest run tests/background/no-test-hooks-in-prod-bundle.test.ts 2>&1 | tail -5 && (npm run test:uat 2>&1 | tail -25 || echo "test:uat invocation needs verification; check for 21/21 or 24/24 GREEN")</automated>
|
||||||
</verify>
|
</verify>
|
||||||
<done>
|
<done>
|
||||||
- 5 new assertA* methods on window.__mokoshHarness (verified by grep ≥ 5)
|
- 5 new assertA* methods on window.__mokoshHarness (verified by grep ≥ 5)
|
||||||
- 5 new driveA* wrappers in harness-page-driver.ts
|
- 5 new driveA* wrappers in harness-page-driver.ts
|
||||||
- harness.test.ts orchestrator runs all 20 (or 23 with 01-10) assertions sequentially
|
- harness.test.ts orchestrator runs all 20 (or 23 with 01-10) assertions sequentially
|
||||||
- npm run test:uat exits 0 with 20/20 (or 23/23) GREEN
|
- npm run test:uat exits 0 with 21/21 (or 24/24) GREEN
|
||||||
- Tier-1 forbidden-strings inventory in no-test-hooks-in-prod-bundle.test.ts UNCHANGED at 10 entries (no new test-mode symbols)
|
- Tier-1 forbidden-strings inventory in no-test-hooks-in-prod-bundle.test.ts UNCHANGED at 12 entries post-Plan-01-14 (no new test-mode symbols added by Plan 01-12)
|
||||||
- Atomic commit `feat(01-12): wave-6 task-1 — harness A18-A22 (font reachability + icon-distinct + manifest-i18n + Lora-resolved + welcome-tokens)`
|
- Atomic commit `feat(01-12): wave-6 task-1 — harness A18-A22 (font reachability + icon-distinct + manifest-i18n + Lora-resolved + welcome-tokens)`
|
||||||
</done>
|
</done>
|
||||||
</task>
|
</task>
|
||||||
@@ -1099,7 +1103,7 @@ describe('_locales/ key parity', () => {
|
|||||||
</verify>
|
</verify>
|
||||||
<done>Operator types 'approved' after running the how-to-verify steps. See <resume-signal>.</done>
|
<done>Operator types 'approved' after running the how-to-verify steps. See <resume-signal>.</done>
|
||||||
<what-built>
|
<what-built>
|
||||||
Plan 01-12 lands the full design integration: Lora self-hosted (R2 designer reply); IBM Plex Sans + Mono self-hosted (Latin + Cyrillic); src/shared/tokens.css canonical (Newsreader → Lora substitution + .mks-word class + zero remote @import); icons rasterized from Loom mark (replaces Bug A placeholders); manifest:name + :description + :default_title migrated to chrome i18n (__MSG_*__ + _locales/{en,ru}/messages.json); 12 i18n keys land with D-07 + D-08 + Brief §02 verbatim Russian copy; src/popup/ + src/background/ use chrome.i18n.getMessage at every operator-facing site + tokens.css palette; BADGE_REC_COLOR madder-rust per D-04; welcome page (if 01-10 landed) inherits canonical tokens; vite __VITE_DEV__ defensive define; UAT harness 20/20 (or 23/23) GREEN with A18-A22 covering font reachability + icon-distinct + manifest-i18n + Lora-resolved + welcome-tokens.
|
Plan 01-12 lands the full design integration: Lora self-hosted (R2 designer reply); IBM Plex Sans + Mono self-hosted (Latin + Cyrillic); src/shared/tokens.css canonical (Newsreader → Lora substitution + .mks-word class + zero remote @import); icons rasterized from Loom mark (replaces Bug A placeholders); manifest:name + :description + :default_title migrated to chrome i18n (__MSG_*__ + _locales/{en,ru}/messages.json); 12 i18n keys land with D-07 + D-08 + Brief §02 verbatim Russian copy; src/popup/ + src/background/ use chrome.i18n.getMessage at every operator-facing site + tokens.css palette; BADGE_REC_COLOR madder-rust per D-04; welcome page (if 01-10 landed) inherits canonical tokens; vite __VITE_DEV__ defensive define; UAT harness 21/21 (or 24/24) GREEN with A18-A22 covering font reachability + icon-distinct + manifest-i18n + Lora-resolved + welcome-tokens (A0-A14 from 01-13 and A23 from 01-14 remain GREEN as no-regression guarantees).
|
||||||
</what-built>
|
</what-built>
|
||||||
<how-to-verify>
|
<how-to-verify>
|
||||||
1. Fresh build + load:
|
1. Fresh build + load:
|
||||||
@@ -1130,7 +1134,7 @@ describe('_locales/ key parity', () => {
|
|||||||
- Verify: welcome hero renders D-08 tagline in Lora; warm-linen background; mark slot shows the Loom mark; Russian + English parallel-text copy renders correctly.
|
- Verify: welcome hero renders D-08 tagline in Lora; warm-linen background; mark slot shows the Loom mark; Russian + English parallel-text copy renders correctly.
|
||||||
|
|
||||||
7. Harness gate:
|
7. Harness gate:
|
||||||
- `npm run test:uat` exits 0 with 20/20 GREEN (or 23/23 with 01-10).
|
- `npm run test:uat` exits 0 with 21/21 GREEN (or 24/24 with 01-10).
|
||||||
- Tier-1 grep gate GREEN: `npx vitest run tests/background/no-test-hooks-in-prod-bundle.test.ts`.
|
- Tier-1 grep gate GREEN: `npx vitest run tests/background/no-test-hooks-in-prod-bundle.test.ts`.
|
||||||
|
|
||||||
8. Type "approved" if brand fit accepted, OR describe specific issues for follow-up.
|
8. Type "approved" if brand fit accepted, OR describe specific issues for follow-up.
|
||||||
@@ -1145,7 +1149,7 @@ describe('_locales/ key parity', () => {
|
|||||||
1. Create .planning/phases/01-stabilize-video-pipeline/01-12-SUMMARY.md following the template at $HOME/.claude/get-shit-done/templates/summary.md AND mirroring the structural choices of 01-13-SUMMARY.md (frontmatter with phase/plan/subsystem/tags/requires/provides/affects/tech-stack/key-files/decisions/metrics; body sections One-Liner / What Landed by Wave / Test Counts / Deviations from Plan / Architectural Notes Worth Carrying Forward / Self-Check / Known Limitations / Bridge to Phase 1 Closure).
|
1. Create .planning/phases/01-stabilize-video-pipeline/01-12-SUMMARY.md following the template at $HOME/.claude/get-shit-done/templates/summary.md AND mirroring the structural choices of 01-13-SUMMARY.md (frontmatter with phase/plan/subsystem/tags/requires/provides/affects/tech-stack/key-files/decisions/metrics; body sections One-Liner / What Landed by Wave / Test Counts / Deviations from Plan / Architectural Notes Worth Carrying Forward / Self-Check / Known Limitations / Bridge to Phase 1 Closure).
|
||||||
|
|
||||||
Key content:
|
Key content:
|
||||||
- One-Liner: "Design integration landed end-to-end: Lora self-hosted (R2 designer reply 2026-05-19); src/shared/tokens.css canonical; 12 i18n keys via _locales/{en,ru}; branded Loom icons replace placeholders; src/popup + src/background use chrome.i18n.getMessage + loom palette; harness 20/20 (or 23/23) GREEN with A18-A22; operator brand-fit ack received."
|
- One-Liner: "Design integration landed end-to-end: Lora self-hosted (R2 designer reply 2026-05-19); src/shared/tokens.css canonical; 12 i18n keys via _locales/{en,ru}; branded Loom icons replace placeholders; src/popup + src/background use chrome.i18n.getMessage + loom palette; harness 21/21 (or 24/24) GREEN with A18-A22; operator brand-fit ack received."
|
||||||
- Wave-by-wave breakdown with commit refs.
|
- Wave-by-wave breakdown with commit refs.
|
||||||
- Test Counts table: vitest before/after; harness before/after.
|
- Test Counts table: vitest before/after; harness before/after.
|
||||||
- Architectural Notes: R2 substitution rationale; OFL attribution pattern; tokens.css as single source of truth; chrome.i18n.getMessage fallback pattern (|| <const>); .mks-word class as engineering working-defn (designer overridable); icons-as-static-artifacts (NOT regenerated in prebuild per RESEARCH §3 anti-pattern).
|
- Architectural Notes: R2 substitution rationale; OFL attribution pattern; tokens.css as single source of truth; chrome.i18n.getMessage fallback pattern (|| <const>); .mks-word class as engineering working-defn (designer overridable); icons-as-static-artifacts (NOT regenerated in prebuild per RESEARCH §3 anti-pattern).
|
||||||
@@ -1201,7 +1205,7 @@ describe('_locales/ key parity', () => {
|
|||||||
| T-01-12-05 | Tampering | Vite asset hashing breaking @font-face url() resolution at runtime | mitigate | RESEARCH §2 Pattern A validated empirically (tokens.css → relative url(./fonts/x.woff2) → Vite rebases → @crxjs auto-WAR). UAT harness A18 walks document.styleSheets to resolve the actual emitted URL (handles hashing); fetch + size check verifies runtime reachability. Pattern B fallback (public/fonts/) documented in RESEARCH §2 if Pattern A misfires. |
|
| T-01-12-05 | Tampering | Vite asset hashing breaking @font-face url() resolution at runtime | mitigate | RESEARCH §2 Pattern A validated empirically (tokens.css → relative url(./fonts/x.woff2) → Vite rebases → @crxjs auto-WAR). UAT harness A18 walks document.styleSheets to resolve the actual emitted URL (handles hashing); fetch + size check verifies runtime reachability. Pattern B fallback (public/fonts/) documented in RESEARCH §2 if Pattern A misfires. |
|
||||||
| T-01-12-06 | Spoofing | `__MSG_@@extension_id__` substitution in manifest fields (not supported per Chrome docs) | accept | Plan 01-12 does NOT use @@extension_id; documented as RESEARCH §11 anti-pattern + per the explicit "Anti-pattern" subsection. Low blast radius (only affects if engineer ignores docs). |
|
| T-01-12-06 | Spoofing | `__MSG_@@extension_id__` substitution in manifest fields (not supported per Chrome docs) | accept | Plan 01-12 does NOT use @@extension_id; documented as RESEARCH §11 anti-pattern + per the explicit "Anti-pattern" subsection. Low blast radius (only affects if engineer ignores docs). |
|
||||||
| T-01-12-07 | Information Disclosure | chrome.i18n.getMessage returning empty string when default_locale lacks key (RESEARCH Pitfall 4) | mitigate | The `|| <const>` fallback pattern uniformly applied in src/popup/index.ts + src/background/index.ts (Wave 4) ensures missing-key cases degrade to literal English-ish text rather than blank UI. tests/i18n/locale-parity.test.ts asserts key-parity to catch missing keys at unit-test time. |
|
| T-01-12-07 | Information Disclosure | chrome.i18n.getMessage returning empty string when default_locale lacks key (RESEARCH Pitfall 4) | mitigate | The `|| <const>` fallback pattern uniformly applied in src/popup/index.ts + src/background/index.ts (Wave 4) ensures missing-key cases degrade to literal English-ish text rather than blank UI. tests/i18n/locale-parity.test.ts asserts key-parity to catch missing keys at unit-test time. |
|
||||||
| T-01-12-08 | Elevation of Privilege | Test-mode hook strings leaking into production dist/ (T-1-11-01 + T-1-13-* inheritance) | accept | Plan 01-12 introduces ZERO new test-mode symbols (A18-A22 use production chrome.* + fetch + getComputedStyle exclusively). Tier-1 grep gate at tests/background/no-test-hooks-in-prod-bundle.test.ts remains at 10 entries; no extension needed. Verified by file-diff at task end. |
|
| T-01-12-08 | Elevation of Privilege | Test-mode hook strings leaking into production dist/ (T-1-11-01 + T-1-13-* + T-1-14-* inheritance) | accept | Plan 01-12 introduces ZERO new test-mode symbols (A18-A22 use production chrome.* + fetch + getComputedStyle exclusively). Tier-1 grep gate at tests/background/no-test-hooks-in-prod-bundle.test.ts remains at 12 entries post-Plan-01-14; no extension needed. Verified by file-diff at task end. |
|
||||||
| T-01-12-09 | Tampering | OFL license/attribution non-compliance | mitigate | src/shared/fonts/LICENSE-Lora.txt + LICENSE-IBM-Plex.txt ship verbatim per OFL-1.1 attribution best practice (RESEARCH §7); src/shared/fonts/README.md cross-references upstream URLs + R2 substitution rationale. |
|
| T-01-12-09 | Tampering | OFL license/attribution non-compliance | mitigate | src/shared/fonts/LICENSE-Lora.txt + LICENSE-IBM-Plex.txt ship verbatim per OFL-1.1 attribution best practice (RESEARCH §7); src/shared/fonts/README.md cross-references upstream URLs + R2 substitution rationale. |
|
||||||
</threat_model>
|
</threat_model>
|
||||||
|
|
||||||
@@ -1210,13 +1214,13 @@ Phase-level invariants to assert post-plan:
|
|||||||
|
|
||||||
1. **Build cleanliness:** `npm run build` exits 0; `npm run build:test` exits 0; `npx tsc --noEmit` exits 0.
|
1. **Build cleanliness:** `npm run build` exits 0; `npm run build:test` exits 0; `npx tsc --noEmit` exits 0.
|
||||||
2. **MV3 CSP compliance:** zero `googleapis` / `https://fonts` matches in dist/ (tests/build/no-remote-fonts.test.ts).
|
2. **MV3 CSP compliance:** zero `googleapis` / `https://fonts` matches in dist/ (tests/build/no-remote-fonts.test.ts).
|
||||||
3. **Vitest baseline grown:** 98 → 104+ GREEN (+6 new unit tests; +N if welcome migration adds keys).
|
3. **Vitest baseline grown:** 100 (post-01-14) → 106+ GREEN (+6 new unit tests; +N if welcome migration adds keys).
|
||||||
4. **UAT harness 20/20 (or 23/23 with 01-10) GREEN:** `npm run test:uat` exits 0; A0 Tier-1 grep gate GREEN; A1-A14 (or A1-A17 with 01-10) GREEN; A18-A22 GREEN.
|
4. **UAT harness 21/21 (or 24/24 with 01-10) GREEN:** `npm run test:uat` exits 0; A0 Tier-1 grep gate GREEN; A1-A14 (or A1-A17 with 01-10) + A23 (Plan 01-14) GREEN; A18-A22 GREEN.
|
||||||
5. **Font bundle present:** all 7 or 8 WOFF2 files exist under src/shared/fonts/; total bundle ≤ 350KB; LICENSE files + README.md present.
|
5. **Font bundle present:** all 7 or 8 WOFF2 files exist under src/shared/fonts/; total bundle ≤ 350KB; LICENSE files + README.md present.
|
||||||
6. **Icons rasterized:** icons/icon{16,48,128}.png are 8-bit RGBA PNGs at correct dims + clearing FLOOR; differ in content from the Bug A placeholders.
|
6. **Icons rasterized:** icons/icon{16,48,128}.png are 8-bit RGBA PNGs at correct dims + clearing FLOOR; differ in content from the Bug A placeholders.
|
||||||
7. **Manifest i18n wired:** chrome://extensions name reads "Mokosh — Session Capture" (en) or "Mokosh — Запись сессии" (ru); operator-facing tooltips + notification copy + popup CTA all resolve via chrome.i18n.getMessage.
|
7. **Manifest i18n wired:** chrome://extensions name reads "Mokosh — Session Capture" (en) or "Mokosh — Запись сессии" (ru); operator-facing tooltips + notification copy + popup CTA all resolve via chrome.i18n.getMessage.
|
||||||
8. **Tokens adopted:** src/popup/style.css has 0 hex literals + imports tokens.css; src/welcome/welcome.css (if 01-10 landed) imports tokens.css; BADGE_REC_COLOR is madder-rust #b2543d.
|
8. **Tokens adopted:** src/popup/style.css has 0 hex literals + imports tokens.css; src/welcome/welcome.css (if 01-10 landed) imports tokens.css; BADGE_REC_COLOR is madder-rust #b2543d.
|
||||||
9. **Tier-1 forbidden-strings inventory UNCHANGED at 10 entries.**
|
9. **Tier-1 forbidden-strings inventory UNCHANGED at 12 entries post-Plan-01-14.**
|
||||||
10. **R2 substitution complete:** zero `Newsreader` references anywhere in src/shared/tokens.css; --mks-font-display === '"Lora", "Iowan Old Style", "Times New Roman", serif'.
|
10. **R2 substitution complete:** zero `Newsreader` references anywhere in src/shared/tokens.css; --mks-font-display === '"Lora", "Iowan Old Style", "Times New Roman", serif'.
|
||||||
11. **Operator brand-fit ack:** Wave 7 checkpoint received "approved".
|
11. **Operator brand-fit ack:** Wave 7 checkpoint received "approved".
|
||||||
</verification>
|
</verification>
|
||||||
@@ -1234,8 +1238,8 @@ Phase-level invariants to assert post-plan:
|
|||||||
- [ ] If Plan 01-10 landed: welcome-tokens.css = `@import '../shared/tokens.css';`; welcome.ts uses chrome.i18n.getMessage
|
- [ ] If Plan 01-10 landed: welcome-tokens.css = `@import '../shared/tokens.css';`; welcome.ts uses chrome.i18n.getMessage
|
||||||
- [ ] vite.config.ts has `__VITE_DEV__` defensive define
|
- [ ] vite.config.ts has `__VITE_DEV__` defensive define
|
||||||
- [ ] scripts/{rasterize-icons.sh,subset-fonts.sh,README.md} all present
|
- [ ] scripts/{rasterize-icons.sh,subset-fonts.sh,README.md} all present
|
||||||
- [ ] UAT harness A18-A22 implemented + GREEN; npm run test:uat exits 0 with 20/20 (or 23/23 with 01-10) GREEN
|
- [ ] UAT harness A18-A22 implemented + GREEN; npm run test:uat exits 0 with 21/21 (or 24/24 with 01-10) GREEN
|
||||||
- [ ] Tier-1 forbidden-strings inventory UNCHANGED at 10 entries
|
- [ ] Tier-1 forbidden-strings inventory UNCHANGED at 12 entries post-Plan-01-14
|
||||||
- [ ] Operator empirical brand-fit ack ("approved") received at Wave 7 checkpoint
|
- [ ] Operator empirical brand-fit ack ("approved") received at Wave 7 checkpoint
|
||||||
- [ ] 01-12-SUMMARY.md exists + STATE.md + ROADMAP.md synced
|
- [ ] 01-12-SUMMARY.md exists + STATE.md + ROADMAP.md synced
|
||||||
- [ ] All commits atomic + follow `feat(01-12)/test(01-12)/docs(01-12): wave-N task-M — <one-liner>` convention
|
- [ ] All commits atomic + follow `feat(01-12)/test(01-12)/docs(01-12): wave-N task-M — <one-liner>` convention
|
||||||
|
|||||||
Reference in New Issue
Block a user