Files
Mark 03d4b3343c docs(03): UI design contract — null-spec for verification-only phase
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) <noreply@anthropic.com>
2026-05-20 18:04:00 +02:00

16 KiB
Raw Permalink Blame History

phase, slug, status, shadcn_initialized, preset, created, scope_kind, ui_surface, inherits_from
phase slug status shadcn_initialized preset created scope_kind ui_surface inherits_from
3 03-spec-10-smoke-verification-dom-event-log-verification draft false none 2026-05-20 verification-only none-user-facing
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 <domain> and <specifics>. After reading the upstream artifacts, the honest answer is that this is a false positive:

  • 03-CONTEXT.md <domain> 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 <decisions> "Claude's Discretion" + <specifics>):

Surface Purpose Minimum required CSS
<form> 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
<table> with <thead> + <tbody> + ≥2 rows rrweb table rendering (<tr> / <td> snapshot coverage) unstyled
Modal trigger button + modal <dialog> or absolutely-positioned <div> rrweb modal + focus-trap + z-index snapshot coverage dialog { z-index: 1000; } minimum if not using native <dialog>
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):

<input type="password" id="probe-password" data-test="probe-password" />

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 <code_context> 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.

  • Dimension 1 Copywriting: PASS (inherited; 17-key matrix locked; Phase 3 emits no new operator copy)
  • Dimension 2 Visuals: PASS (inherited; canonical brand artifacts unchanged; probe-page convention bans new visual surface)
  • Dimension 3 Color: PASS (inherited; Loom palette locked at src/shared/tokens.css; no new colors)
  • Dimension 4 Typography: PASS (inherited; 3 families × declared sizes/weights locked; no new sizes)
  • Dimension 5 Spacing: PASS (inherited; --mks-space-* scale locked; 4px base preserved)
  • 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 <link rel="stylesheet" href="../../src/shared/tokens.css"> 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.