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>
16 KiB
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 |
|
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 truthsrc/shared/fonts/*.woff2(8 files, ~155 KB total) — self-hosted under MV3 CSPsrc/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-keyattributes (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.