From 03d4b3343c5e05868e304b3685264e37a7e6fa08 Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 20 May 2026 18:04:00 +0200 Subject: [PATCH] =?UTF-8?q?docs(03):=20UI=20design=20contract=20=E2=80=94?= =?UTF-8?q?=20null-spec=20for=20verification-only=20phase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 3 is verification-only; /gsd-ui-phase 3 trigger on "page" keyword is a false positive. UI-SPEC.md confirms no new user-facing UI surface in scope; locks the Phase 1 design system (Lora + IBM Plex Sans + Loom palette + Mokosh mark + tokens.css + 17 i18n keys) as read-only inherited context; declares minimal probe-page conventions for internal Puppeteer test fixtures (Plans 03-01..03-05 per D-P3-01). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../03-UI-SPEC.md | 232 ++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 .planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-UI-SPEC.md diff --git a/.planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-UI-SPEC.md b/.planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-UI-SPEC.md new file mode 100644 index 0000000..e8734b0 --- /dev/null +++ b/.planning/phases/03-spec-10-smoke-verification-dom-event-log-verification/03-UI-SPEC.md @@ -0,0 +1,232 @@ +--- +phase: 3 +slug: 03-spec-10-smoke-verification-dom-event-log-verification +status: draft +shadcn_initialized: false +preset: none +created: 2026-05-20 +scope_kind: verification-only +ui_surface: none-user-facing +inherits_from: + - 01-12-SUMMARY.md (design system locked: Lora display + IBM Plex Sans UI + Loom palette + Mokosh mark + canonical tokens.css + 16 i18n keys with en↔ru parity) + - 01-10-SUMMARY.md (welcome page pattern: data-mokosh-slot + data-mokosh-key + data-mokosh-i18n-key three-pipeline DOM population) +--- + +# Phase 3 — UI Design Contract + +> Visual and interaction contract for frontend phases. Generated by gsd-ui-researcher, verified by gsd-ui-checker. + +--- + +## Scope Determination + +**Phase 3 has NO user-facing UI surface in scope.** + +The `/gsd-ui-phase 3` orchestrator triggered on the "page" keyword in 03-CONTEXT.md `` and ``. After reading the upstream artifacts, the honest answer is that this is a false positive: + +- 03-CONTEXT.md `` explicitly states: *"No new production-code feature work; the rrweb wiring + event-log wiring already shipped in Phase 1 (`src/content/index.ts`). Phase 3 confirms what's shipped + writes the §10 sweep VERIFICATION."* +- All "page" references in Phase 3 plans (03-01, 03-02, 03-03, 03-04, 03-05 per D-P3-01) point to **synthetic Puppeteer test fixtures internal to `tests/uat/extension-page-harness.ts`** — probe HTML for rrweb DOM verification (form + table + modal) and event-log trigger surfaces (password input + click target + 404 endpoint). These pages never ship in production and never reach an operator. +- All user-facing UI surfaces (popup, welcome page, brand identity, badges, icons, fonts, palette, i18n) were **LOCKED by Phase 1** (Plans 01-09 / 01-10 / 01-12 / 01-14). Phase 3 INHERITS them and MUST NOT modify them. + +This UI-SPEC therefore captures **inherited design-system facts** that downstream Phase 3 planners and executors must respect (read-only), plus **minimal probe-page conventions** for the internal test fixtures. It contains NO new design directives. + +--- + +## Design System (INHERITED — DO NOT MODIFY) + +The design system is **closed for Phase 3.** Plan 01-12 Wave 7 operator brand-fit ack 2026-05-20 verbatim "all good" sealed the canonical artifacts. Phase 3 planners must NOT introduce new tokens, new fonts, new colors, new copy keys, new icons, new layout primitives, OR new component patterns into the user-facing surface. + +| Property | Value | Source | +|----------|-------|--------| +| Tool | none (manual canonical token system) | Plan 01-12 Wave 1 Task 2 — `src/shared/tokens.css` | +| Preset | not applicable | — | +| Component library | none (vanilla DOM; three-pipeline populate pattern for welcome page) | Plan 01-10 patterns-established | +| Icon library | static PNG artifacts at `icons/icon{16,48,128}.png` (8-bit RGBA; Loom mark rasterized from `src/shared/brand/mokosh-mark.svg` via `scripts/rasterize-icons.sh`) | Plan 01-12 Wave 2 | +| Display font | `"Lora", "Iowan Old Style", "Times New Roman", serif` (Cyreal foundry; OFL-1.1; full Cyrillic via R2 substitution 2026-05-19) | Plan 01-12 Wave 1 Task 2 + brand-decisions-v1-followup-display-font.md | +| UI font | `"IBM Plex Sans", "Segoe UI", -apple-system, BlinkMacSystemFont, sans-serif` (OFL-1.1; full Cyrillic) | `src/shared/tokens.css` line 146 | +| Mono font | `"IBM Plex Mono", "SF Mono", Menlo, Consolas, monospace` (OFL-1.1; full Cyrillic) | `src/shared/tokens.css` line 147 | + +**Read-only canonical sources:** + +- `src/shared/tokens.css` (~355 lines) — single source of truth +- `src/shared/fonts/*.woff2` (8 files, ~155 KB total) — self-hosted under MV3 CSP +- `src/shared/brand/{mokosh-mark.svg,mokosh-lockup.svg}` — canonical brand assets +- `_locales/{en,ru}/messages.json` — 17 i18n keys per locale (Plan 01-12 + Plan 01-10 closure-cycle split notifStartup → notifStartupCta + notifRecordingStarted) +- `icons/icon{16,48,128}.png` — committed static artifacts (NOT regenerated at build time) + +--- + +## Spacing Scale (INHERITED) + +Declared values from `src/shared/tokens.css` lines 178-188. Phase 3 must not introduce new spacing values. + +| Token | Value | Usage | +|-------|-------|-------| +| `--mks-space-1` | 4px | Icon gaps, inline padding | +| `--mks-space-2` | 8px | Compact element spacing | +| `--mks-space-3` | 12px | (used by component CSS as needed) | +| `--mks-space-4` | 16px | Default element spacing | +| `--mks-space-5` | 20px | (used by component CSS as needed) | +| `--mks-space-6` | 24px | Section padding | +| `--mks-space-8` | 32px | Layout gaps | +| `--mks-space-10` | 40px | (used by component CSS as needed) | +| `--mks-space-12` | 48px | Major section breaks | +| `--mks-space-16` | 64px | Page-level spacing | +| `--mks-space-20` | 80px | (used by component CSS as needed) | + +Exceptions: none in Phase 3 (no new component CSS is in scope). + +--- + +## Typography (INHERITED) + +Declared values from `src/shared/tokens.css` lines 151-167 + semantic helpers lines 254-333. Phase 3 must not introduce new font sizes or weights. + +| Role | Size | Weight | Line Height | Token / class | +|------|------|--------|-------------|---------------| +| Body | 15px | 400 (regular) | 1.5 | `.mks-body` | +| Label (small) | 13px | 400 | 1.5 | `.mks-body-sm` | +| Heading | 17px | 600 (semibold) | 1.3 | `.mks-h3` | +| Heading large | 20px | 600 | 1.3 | `.mks-h2` | +| Heading display | 28px | 400 | 1.15 | `.mks-h1` | +| Display | 40px (or 56px for hero) | 400 | 1.15 | `.mks-display-2` / `.mks-display-1` | + +Inherited type scale (full list at `tokens.css` lines 151-158): 11, 13, 15, 17, 20, 28, 40, 56 px. Phase 3 must not add intermediate sizes. + +Inherited weights (lines 164-167): 400 regular, 500 medium, 600 semibold, 700 bold. + +--- + +## Color (INHERITED — Loom palette per D-04) + +Declared values from `src/shared/tokens.css` lines 89-137. Phase 3 must not introduce new colors. + +| Role | Value | Usage | +|------|-------|-------| +| Dominant (60%) | `--mks-linen-50` = #faf7f1 | Page background | +| Surface raised (cards/popup) | `--mks-linen-100` = #f3eee4 | Card / popup surface | +| Secondary (30%) | `--mks-linen-200` = #e8e0d0 | Hairline / divider on linen | +| Foreground primary | `--mks-ink-900` = #181b2a | Primary text, deepest surface | +| Accent (10%) — REC | `--mks-madder-600` = #b2543d | Recording state badge + REC dot only | +| Accent — success | `--mks-moss-600` = #5a7349 | "Готово ✓" SAVE-success state only | +| Accent — warning | `--mks-amber-600` = #c98b3a | Recoverable error / SAVING transient state only | +| Destructive | `--mks-brick-600` = #a23a2b | Unrecoverable error state only | + +Accent reserved for: REC badge background; REC pulse-dot; SAVE button primary-CTA fill (madder-700 at hover); SAVING transient (amber-600); DONE transient (moss-600); ERROR (brick-600). Per Plan 01-12 Wave 4 BADGE_REC_COLOR flip from material-green to madder. + +Phase 3 must NOT introduce additional accent surfaces. Probe-page fixtures (Section "Test Fixture Conventions" below) MAY remain unstyled. + +--- + +## Copywriting Contract (INHERITED — read-only) + +All operator-facing copy is locked. Phase 3 must NOT add operator-facing strings. + +| Element | Copy | Source | +|---------|------|--------| +| Extension name (EN) | "Mokosh — Session Capture" | _locales/en/messages.json extName (D-07) | +| Extension name (RU) | "Mokosh — Запись сессии" | _locales/ru/messages.json extName | +| Extension description (EN) | "Thirty seconds ago, always at hand." | _locales/en/messages.json extDesc (D-08) | +| Extension description (RU) | "Тридцать секунд назад, всегда под рукой." | _locales/ru/messages.json extDesc | +| Primary CTA (popup SAVE) | "Сохранить отчёт об ошибке" (`popupSaveCta`) | Plan 01-09 + REQ-popup-ui | +| Empty state heading | "Готов к записи" (popupSavePrompt + popupInfoText) | Plan 01-12 Wave 3 | +| Saving transient | "Сохраняю..." (`popupSaving`) | Plan 01-09 state machine | +| Done transient | "Готово! ✓" (`popupSaveDone`) | Plan 01-09 state machine | +| Startup notification CTA | "Mokosh ready. Click to start a recording." (`notifStartupCta` — split from notifStartup per closure-cycle debug 4bba679) | Plan 01-10 cycle-1 debug fix | +| Recording started notification | (`notifRecordingStarted`) | Plan 01-10 cycle-1 debug fix | +| Recovery notification | (`notifRecovery`) | Plan 01-09 + Plan 01-12 | +| Welcome hero (RU) | "Тридцать секунд назад, всегда под рукой." (`welcomeHeroRu`) | Plan 01-10 D-08 | +| Welcome hero (EN) | "Thirty seconds ago, always at hand." (`welcomeHeroEn`) | Plan 01-10 D-08 | +| Toolbar tooltip (off / rec / err) | `tooltipOff` / `tooltipRecPrefix` / `tooltipErr` | Plan 01-12 Wave 3 | + +**Phase 3 may emit VERIFICATION.md operator-instruction copy** (e.g. §10 #9 RAM-ceiling step: "Load extension; idle 5 min; open `chrome://memory-internals`; verify extension background RAM < 50 MB.") — that is documentation copy, not operator-facing UI, and is outside this contract. + +**Destructive actions in Phase 3:** none. Phase 3 has no buttons, no confirmations, no UI state. It is a verification-only phase. + +--- + +## Test Fixture Conventions (INTERNAL — Phase 3-scoped) + +The five Phase 3 plans (per D-P3-01) extend `tests/uat/extension-page-harness.ts` with new `assertA*` methods (A29+ continuing from Plan 02-04's A24-A28). For rrweb DOM probing per §10 #4 (Plan 03-01) the harness page must include synthetic HTML structures sufficient to exercise rrweb's typical-page coverage. + +**Probe HTML composition** (Plan 03-01 planner discretion per 03-CONTEXT.md `` "Claude's Discretion" + ``): + +| Surface | Purpose | Minimum required CSS | +|---------|---------|----------------------| +| `
` with text + email + password input + submit button | rrweb input variety + §10 #8 password-filter probe (Plan 03-03) | unstyled OR minimal — fields need to be present in the DOM tree, not styled | +| `` with `` + `` + ≥2 rows | rrweb table rendering (`` / `
` snapshot coverage) | unstyled | +| Modal trigger button + modal `` or absolutely-positioned `
` | rrweb modal + focus-trap + z-index snapshot coverage | `dialog { z-index: 1000; }` minimum if not using native `` | +| 404-target trigger button (for `fetch(...)` → network_error) | §10 #5 event-log trigger (Plan 03-02) | unstyled | +| Error-trigger button (for `throw new Error(...)` → js_error) | §10 #5 event-log trigger (Plan 03-02) | unstyled | + +**Probe HTML MUST NOT:** +- Import the canonical `src/shared/tokens.css` (the harness page already imports it for A18/A21 Lora-resolution coverage; the probe sub-tree should appear unstyled to keep rrweb snapshots focused on structural DOM, not on the design system) +- Use the canonical brand `var(--mks-*)` tokens (probe pages are not branded) +- Import any `_locales/*` strings via chrome.i18n (probe pages are not i18n'd; assertion text can be inline English) +- Inject any `data-mokosh-slot` / `data-mokosh-key` / `data-mokosh-i18n-key` attributes (those are reserved for the production welcome page DOM population pipelines per Plan 01-10) + +**Probe HTML MAY use** plain `data-test-*` attributes for assertion-side querySelector targeting. This is the established pattern from prior harness fixtures. + +**Synthetic password input convention** (Plan 03-03): + +```html + +``` + +The harness driver types a sentinel value (e.g. `"secret-do-not-log-123"`) into this input via `page.type`. Plan 03-03 assertion then greps `events.json` parsed from the assembled archive for absence of the sentinel. **Negative-assertion test pattern** — the absence of the sentinel proves the existing `src/content/index.ts:82` `if (target.type === 'password') return;` filter fires. This is the explicit PARTIAL §10 #8 closure per D-P3-02 charter alignment. + +**FORBIDDEN_HOOK_STRINGS lockstep** (per Plan 02-04 + Plan 01-12 + Plan 01-13 patterns): the Phase 3 probe pages must NOT introduce new test-mode symbols into the production bundle. A29+ assertions ride existing production surfaces (rrweb's already-shipped wiring, the existing `fetch` interception, etc.) — they are NOT hooks. If a planner finds an A29+ assertion requires a new test-mode symbol, that symbol must be `__MOKOSH_UAT__` Vite-define-token gated AND added to FORBIDDEN_HOOK_STRINGS in `tests/background/no-test-hooks-in-prod-bundle.test.ts`. See Plan 02-04 SUMMARY for the most recent precedent. + +--- + +## Registry Safety + +| Registry | Blocks Used | Safety Gate | +|----------|-------------|-------------| +| shadcn official | none — manual canonical token system | not applicable | +| Third-party | none | not applicable | + +Phase 3 introduces no third-party UI dependencies. The probe-page composition is hand-authored vanilla HTML inside the existing `tests/uat/` test surface. + +--- + +## Inherited Visual Contracts to Preserve + +Phase 3 verification will incidentally exercise these contracts (via existing harness assertions A0-A28 that MUST remain GREEN per 03-CONTEXT.md `` Integration Points). Phase 3 must not regress any of them. + +| Contract | Source | How Phase 3 preserves it | +|----------|--------|--------------------------| +| MV3 CSP self-host invariant (0 `googleapis` / 0 `https://fonts` in `dist/`) | Plan 01-12 Wave 1 Task 2 + `tests/build/no-remote-fonts.test.ts` | Phase 3 ships no new fonts; pre-checkpoint bundle gate (Plan 03-05) re-verifies | +| en↔ru i18n parity (17 keys × 2 locales) | Plan 01-12 Wave 3 + Plan 01-10 cycle-1 split + `tests/i18n/locale-parity.test.ts` | Phase 3 ships no new locale keys; pre-checkpoint bundle gate (Plan 03-05) re-verifies | +| Icons rendering at 16/48/128 (8-bit RGBA) | Plan 01-12 Wave 2 + `tests/build/icons-present.test.ts` + harness A19 | Phase 3 does not modify icons; A19 remains GREEN | +| `--mks-font-display` resolves to Lora stack | Plan 01-12 Wave 1 Task 2 + harness A21 | Phase 3 does not modify tokens.css; A21 remains GREEN | +| `--mks-rec` resolves to `rgb(178, 84, 61)` = #b2543d | Plan 01-12 Wave 4 BADGE_REC_COLOR + harness A17.7 | Phase 3 does not modify palette; A17.7 remains GREEN | +| BADGE_REC_COLOR madder + 3-state state machine | Plan 01-09 + Plan 01-12 Wave 4 | Phase 3 makes no badge changes | +| Welcome page first-install activation (onInstalled('install') + storage flag + tabs.create) | Plan 01-10 Wave 2 helper + harness A15/A16/A17 | Phase 3 makes no onboarding changes | + +--- + +## Checker Sign-Off + +This UI-SPEC is a **null-spec** for Phase 3 — it confirms the absence of in-scope UI surface and freezes inherited Phase 1 design facts as read-only. The 6 design quality dimensions are evaluated against the inherited surface, not against any new Phase 3 work. + +- [x] Dimension 1 Copywriting: PASS (inherited; 17-key matrix locked; Phase 3 emits no new operator copy) +- [x] Dimension 2 Visuals: PASS (inherited; canonical brand artifacts unchanged; probe-page convention bans new visual surface) +- [x] Dimension 3 Color: PASS (inherited; Loom palette locked at `src/shared/tokens.css`; no new colors) +- [x] Dimension 4 Typography: PASS (inherited; 3 families × declared sizes/weights locked; no new sizes) +- [x] Dimension 5 Spacing: PASS (inherited; `--mks-space-*` scale locked; 4px base preserved) +- [x] Dimension 6 Registry Safety: PASS (no shadcn use; no third-party registry; vanilla DOM only) + +**Approval:** pending checker review (draft status) + +--- + +## Notes for Downstream Phase 3 Agents + +**Planner (`gsd-planner`):** Phase 3 plans should NOT include any UI design tasks. Plans 03-01 through 03-05 are all verification (harness assertions + VERIFICATION.md aggregation) per D-P3-01. The probe-page HTML composition is internal harness work and falls under the "Test Fixture Conventions" section above. + +**Executor (`gsd-executor`):** When extending `tests/uat/extension-page-harness.ts` or `tests/uat/extension-page-harness.html`, treat the existing canonical `` import as load-bearing (harness assertions A18 + A21 depend on it). Add probe HTML below the existing harness scaffold; do not strip the tokens.css link. + +**UI auditor (if spawned):** Phase 3 has no user-facing surface to audit. Run audit against Phase 1 + Phase 2 surfaces (popup + welcome page + badges + notifications + manifest + icons) if a regression sweep is desired. + +**Ceremony note:** If during execution the planner discovers Phase 3 needs operator-facing UI work (e.g. a new VERIFICATION.md operator instruction is genuinely UI-mediated), route through `/gsd-debug` or `/gsd-discuss-phase` per `feedback-gsd-ceremony-for-fixes.md`. Do not hot-edit this UI-SPEC or the canonical design system.