---
title: "Алгоритм валидации прототипов под дизайн-гайд + дизайн-систему"
type: reference
status: approved
version: v2.13
updated: 2026-07-12
---

# Алгоритм валидации прототипов

> **Роль дока.** Машинный чек-лист для роёв-валидаторов: ~90 проверок с ID, сгруппированных по измерениям. Агент берёт каталог §3, прогоняет каждую проверку по каждому файлу, затем кросс-экранный барьер §4 и пост-проверку §5.
> **Как пользоваться.** Сначала §1 (классифицировать поверхность файла — без этого правило снесёт чужой by-design элемент), потом §3 как плоский реестр, §2 — эталоны для ссылок, §4/§5 — барьеры. Этот док владеет **только алгоритмом обнаружения**; значения — за `tokens.css`/`components.css`, идеология V3 — за `v3-minimalism-guide.md`, методология/устройство — за `DESIGN.md`.

---

## 0. Преамбула: как агент это прогоняет

**Цель.** Исчерпывающе ловить любое несоответствие прототипа [`DESIGN-GUIDE.md`](DESIGN-GUIDE.md) (чек-лист A1–D6, включая B9–B10) и дизайн-системе ([`components-gallery.html`](design-system/components-gallery.html), `tokens.css`+`components.css`) — не только очевидное.

**Принцип закалки.** Локальная валидность экрана ≠ глобальная согласованность набора: расхождение хрома *между* экранами одной поверхности — дефект сам по себе. Пер-экранные агенты в изоляции дрейфуют (каждый «чинит по-своему»: свой глиф, свой SOS, свой фиолетовый), и это видно только диффом, не осмотром одного экрана.

**Конвейер (4 шага).**
1. **Классифицировать поверхность** каждого файла (§1) — ДО применения правил.
2. **Пер-экранный проход** по каталогу §3.
3. **Кросс-экранный попарный дифф** §4 (diff SVG/CSS/JS-блоков, не визуальный осмотр).
4. **Пост-проверка оркестратором** §5 + флаги DK.

**Покрытие источников текста (CC-17).** Каждая проверка прогоняется по ВСЕМ источникам, не только по первому кадру: статический HTML device-зоны, JS-строки (`textContent`/`innerHTML`/`presets`/`SONA[]`/`buildDetail`), `aria`/`alt`-атрибуты, `content`-псевдоэлементы, подставляемые шаблоны. Главный класс пропусков — копи, генерящаяся по взаимодействию (текст дня в calendar собирается только в JS-строке `buildDetail`).

**Контракт владения.** Значения (hex, тени, радиусы, типошкала, длительности) — канон `tokens.css`/`components.css`; форма компонентов (SOS-путь, нав-глифы, аватары) — `components.css`/живая галерея; идеология V3 (определения криптоплиток, теста понятности) — `v3-minimalism-guide.md`; методология/устройство/карта экранов/decisions log — `DESIGN.md`. Этот док НЕ воспроизводит значения — он сверяет с каноном и описывает, КАК искать дрейф.

**Что НЕ чинить самому (флаг DK):** отсутствие SOS на не-иммерсивном экране (добавление = полный паттерн: кнопка `qranchor` + переход на `program/templates/crisis`); круглые кнопки-возврата `‹` на хаб-экранах (решение по поверхности); расхождение Кабинета vs канон; снос by-design `--purple`/3-слойного хрома Кабинета; бренд-марка (сонар-логотип), видео основателя, `.specpanel`; снятие декора канон-компонентов оверрайдом (TOK-5 — кандидат «впечь в канон»).

**Severity (один раз):** `blocker` — прямое нарушение ядра гайда, сборка не показывается; `high` — заметный дефект, чинить до показа; `medium` — заметный при сверке; `low` — гигиена/анти-ложноположительные.

---

## 1. Поверхности и границы (гейт области ДО правил)

Худший класс ошибки — снести by-design элемент чужой поверхности. Сначала классифицировать файл, потом применять правила.

| Поверхность | Сигнатуры-маркеры | Какие неймспейсы применяются |
|---|---|---|
| **Дневная петля патиента** | нижняя `.nav`, зачин Sona, `qranchor` | все (NAV/CON/CC/COL/TOK/GAM/A11Y/MOTION) |
| **Онбординг** | `onboarding/*`, `.onbnav` (Назад/Далее), `.kicker` | свои правила хрома; B5/B6/SOS не применять |
| **Иммерсивный плеер** | `practice/sound-therapy`·`audio-player`·`video-player`; тёмная тема, без хрома | DARK-*; хром/SOS не требовать |
| **Десктоп-Кабинет** | `cabinet-*`, desktop flex-layout, `.specpanel`, `.btabs`, 3 sticky-слоя, комменты «СЛОЙ 1/2/3 персистит» | CAB-*, CON-10; B5/SOS не применять |

**Ревью-леса (вычесть по сигнатуре ДО a11y-инвентаризации):** `.specpanel` (бежевая витрина, `display:none` <520px), `.back «← К карте интерфейсов»`, `.vbadge`, фейк-`.statusbar`, видео/бренд-марка основателя, hover-превью «нажми меня». **Крестик-возврат `wtop`/`.wclose` в рамке телефона УПРАЗДНЁН (реш. DK 2026-07-04, DESIGN-GUIDE B5a): его наличие в любом шаблоне/прототипе — дефект, а не леса к вычету** (продуктовые ✕ оверлеев/плееров — не он, см. C6f). Навигатор `index.html` целиком (гибрид-SPA: 4 проекции «По программе»/«По джобам»/«Петли/слои»/«По дням» + инстанс-шаблоны `program/templates/`) — ревью-поверхность, не продукт: продуктовые правила B5/B6/C6/SOS к нему не применять. Подробности замысла каждой поверхности — `DESIGN.md` «Карта экранов»/«Decisions Log».

**Анти-ложноположительные (исключения по области).**

| ID | sev | Что НЕ флагать |
|---|---|---|
| **NAV-11/NAV-12/CON-06 (C6f)** | high | Иммерсивный плеер: не требовать нав-бар и SOS — хрома НЕТ, SOS скрыт JS (`display:none`), вместо него всегда видимый ✕→«Сегодня». Нарушение — только если хром НЕ скрыт или ✕ отсутствует/ведёт в тупик. |
| **NAV-09/CON-06/CMP-6** | high | SOS отсутствует на НЕ-иммерсивном экране с хромом → флагать DK, НЕ дорисовывать. Проверять по `qranchor=0`. |
| **NAV-18** | medium | Онбординг: своя `.onbnav` (Назад/Далее) — не флагать отсутствие `.nav`/SOS. `.onbnav` содержит «nav», но это кнопки шага. Нарушение — только продуктовый нав-бар, протёкший в онбординг. |
| **NAV-19** | high | Кабинет (`cabinet-patient`): by-design topbar+крошка «К списку пациентов»+sticky safety+`.btabs` (3 sticky). B5/SOS не применять. Предохранитель — не вводить generic-фиолетовый литерал заново; весь фиолетовый из `var(--curator)` (`#7C6CD6`) и легальных производных. |
| **NAV-13** | low | `.monthnav`/`.nav-mo` — контент, не хром (ловятся grep на `nav` как FP). Нарушение только если `sticky/fixed` или дублируют переход разделов. |
| **NAV-15** | low | `.vbadge` — ревью-артефакт, на узком экране `display:none`. Не нав-слой. |
| **NAV-16/ADV-01** | low | Фейк-`.statusbar` — имитация ОС-бара, ок как первый элемент. Проверить, что под ней нет второго хедера/крошки. |
| **A11Y-SCAFFOLD-LEAK-01** | medium | `.back «← К карте»` (href `../../`) = лес ОК; продуктовая кнопка-возврат `‹` с href внутрь продукта (`../tools/` и т.п.) = B5-нарушение (истор. класс `.back-c` устранён). Различать по href. |
| **LEAK-1/LEAK-2/VER-2** | medium | `.specpanel`/`.vbadge`/фейк-`.statusbar`/бренд-марка/hover-превью — не продукт, исключить по сигнатуре. НО продакшн-back-control (`‹ Сегодня`) лесами НЕ является — это B5-нарушение. |

---

## 2. Эталоны хрома (один источник истины)

Значения-канон — за `tokens.css`/`components.css`/живой галереей; здесь — **форма/инвариант и сигнал дрейфа**. На них ссылаются проверки §3, а не повторяют. Источник истины формы хрома — `program/templates/today/index.html` (канон Today; бывший `daily/today/` — редирект); побайтное отклонение пути/токена — дефект.

| Элемент | Эталон-форма (инвариант) | Сигнал дрейфа |
|---|---|---|
| **Нав-таб «Сегодня»** | один контур-кружок `<circle cx=12 cy=12 r=4.6>`; активный `stroke=url(#navgrad)` sw 1.9, неактивный `currentColor` sw 1.75 | домик/солнце/иной глиф; залитый кружок; добавленная внутренняя точка (`<circle r=1.5 fill>` — прямой запрет B6); `sw` 1.9↔1.75 разнобой между файлами |
| **Набор+порядок табов** | Сегодня (кружок) · Программа (линия с 3 узлами) · Чат (пузырь с 3 точками) · Инструменты (сетка 2×2 `rect`). Ровно один `.on` = таб области | иной порядок/`path`/`viewBox`; лишний/недостающий таб; ноль или два `.on`; не тот активный таб |
| **Активный таб** | тот же контурный глиф, отличие ТОЛЬКО в цвете обводки (`url(#navgrad)` vs `currentColor`) | заливка `fill`; другая форма/мотив у активного |
| **Контейнер `.nav`** | `rgba(255,255,255,.94)`, `blur(12px)`, `border-top var(--line)`, `padding 9px 6px 16px`, неактивная подпись `var(--muted2)`, `padding-bottom:max(16px,env(safe-area-inset-bottom))` | `color:#6B7A8D` вместо токена у неактивной подписи; разный blur/padding/фон между файлами |
| **SOS = `qranchor`** | белый диск 44px (`#FFFFFF`, border `--line`, мягкая тень) + сердце-в-ладошках из ДВУХ `path`: сердце `d="M12 9.2c-1-1.7-3.5-1.9-4.6-.3-.9 1.3-.4 2.9.7 4l3.9 3.6 3.9-3.6c1.1-1.1 1.6-2.7.7-4-1.1-1.6-3.6-1.4-4.6.3Z"` + чаша-ладошки `d="M4 14.5a5.5 5.5 0 0 0 5 3.2h6a5.5 5.5 0 0 0 5-3.2"`, `stroke="var(--teal)" sw 1.75`; `right:16px; bottom` над нав-баром; `aria-label="Сейчас тяжело? Быстрая помощь"`; поведение — переход на `../crisis/…` (никакой шторки). Шторка `qr-sheet`/`qr-backdrop` + JS open/close УПРАЗДНЕНА (реш. DK 2026-07-10/11): любое появление на любой поверхности = дефект (CON-04) | символ ♥/❤; teal-tint/красный/градиент-диск; диск ≠ белый; иной stroke; дрейф `d`-путей (самая глубокая слепая зона); одиночный path без чаши-ладошек; `href="../sos/"` вместо перехода в crisis |
| **Аватар Sona** | `<span class="av">S</span>` — буква S, вес 700, белая, кружок `var(--grad)`. Голос Sona, НЕ бренд-марка (полный сонар-логотип — только иконка приложения / hero онбординга). Размеры `.av 38`/`.sav 22`/`.sav 20` согласованы по ролям | `<img>`/сонар-логотип вместо «S»; иной вес/цвет; сплошной teal вместо `--grad`; фиолетовый (Куратор); разнобой размеров между копиями |
| **Аватар Куратора** | фото Куратора в фиолетовой оправе-кольце (`img.gav`, оправа 2px `--curator`; реш. DK R30 2026-07-10); фолбэк без файла — плоский `#7C6CD6` (`--curator`) диск с инициалом (в прототипах — «А»), без градиента | градиент как у Sona; буква «S»; бирюза; фото без фиолетовой оправы; у инициала-фолбэка оправа-кольцо (сливается с заливкой) |
| **`#navgrad`** | `<linearGradient>` в `<defs>` со стопами `var(--teal)`/`var(--cyan)`, не литералом | `url(#navgrad)` есть, а `<defs>` нет → активная иконка чёрная/невидимая (DEAD-3); либо стопы захардкожены `#2BB4C6`/`#3ED1DB` |

**Барьер хрома.** Один слой на не-иммерсивном экране патиент-аппа = нижняя `.nav`. Никакого второго постоянного слоя: ни back-крошки/кнопки-возврата с `‹`/`❮`/`←` (ловить по смыслу — любой постоянный элемент возврата над контентом, независимо от имени класса; истор. классы `.backtoday`/`.back-c` устранены; `.crumb`/`.phead` живут только в Кабинете и навигаторе — иные поверхности), ни sticky-фильтра, ни верхнего таб-бара, ни sticky safety-баннера. Возврат — через подсвеченный таб или иммерсивный ✕. Якорь «‹ Сегодня» над контентом при активном табе «Сегодня» — **blocker** (дублирует и конфликтует с табом; истор. случай в `daily/calendar` устранён).

---

## 3. Каталог проверок

Единое место определения. Схема каждой строки: **ID · что проверяем · как обнаружить · сигнал/порог · sev**. Поверхность — по §1 (если не оговорено, дневная петля).

### 3.1 Минимализм и подача (CC-*, A1E, V3)

| ID | Что проверяем | Как обнаружить / сигнал | sev |
|---|---|---|---|
| **A1E-1/CC-02** | Под основным блоком (сетка/график/список/карточки) нет пояснительной сноски-легенды-дисклеймера, объясняющей, КАК читать показанное выше | каждый `.note`/`.dnote`/`.scalenote`/`.barsnote`/`mixcap` — на проверку (tools/profile `.scalenote`/`.barsnote`, sound-therapy `.dnote`/`mixcap`) | high |
| **CC-10** | Подписи к декоративным индикаторам / легенды цвета (`●Заходили`/`○Без занятий`) — цвет/форма должны читаться без словаря | конструкции «`‹цвет/значок›` — `‹значение›`» в любом источнике текста; `mixcap`; легенда под календарём/графиком (истор. `.callegend` устранён — ловить по конструкции, не по классу) | high |
| **CC-03** | Нет дисклеймера «чем экран НЕ является» (не оценивает/не сравнивает/только чтение) — лечить подачу, не подпись | «это не дашборд/оценка/диагноз», journal `.syscard` | high |
| **CC-15** | `aria-label`/`alt` графиков не дублируют видимую легенду (двойной канал) | aria TFI-линии/баров повторяет `.scalenote`/`.barsnote` | low |
| **CC-01** | Нет пояснительного зачина под H1, выводимого из карточек ниже; зачин допустим ТОЛЬКО как невыводимый ориентир (неделя/состояние/дата) | muted-параграф «Здесь ты видишь…»/«Это экран, где…» под `.pagetitle`/`.onbhead h1`/`.meta` | high |
| **CC-1F** | Один контентный H1 первым после статусбара; нет верхнего eyebrow/uppercase-бара над H1, дублирующего нав-таб; ровно один H1 | `.kicker`/`.eyebrow`/`.section-label` над `.pagetitle`/`<h1>`; два заголовочных слоя; `h1` как `div`. FP: онбординг-`.kicker`, `.upsell .eyebrow` (не петля). Связано с B5, A11Y-LANDMARK-HEADING-01 | high |
| **CC-05** | Нет надписей-статусов, дублирующих цвет/форму/иконку соседа; тест «несёт ли смысл, которого нет в иконке» | `.stxt b+span` (span повторяет b); `.res+.kind` («Стало легче» рядом с чипом) | medium |
| **CC-06** | Описательные подписи — только у основного блока; второстепенные списки (помощь/настройки/модули) — только заголовки | `.mlbl` над чипами модулей; подписи read-only аккаунта | medium |
| **CC-11** | Заголовок-ориентир не повторяется второй формулировкой (kicker→title→meta трижды о контексте) | journaling: `.step`+`.pagetitle`+`.meta` об одном | medium |
| **CC-14** | Нет повторяющихся «успокаивающих» строк-припевов установки проекта на одном экране | вторая строка-припев той же установки в любом источнике текста экрана (живой якорь — sound-therapy `.guardnote`; истор. дубли `.playerguard`/`.endnote` устранены); эхо строк экрана в specpanel | low |
| **CC-07** | Психообразование/«почему/как мозг привыкает» не на основном пути, раскрывается одним жестом; отличать от ориентира | любой «почему/как мозг привыкает» виден сразу на основном пути, вне раскрытия (`.whybody`/`.notewrap`/`.accbody`); истор. случай — sound-therapy `.principle`, устранён | high |
| **CC-12** | Внутри раскрытых панелей — ориентир-минимум, не второй экран легенд (тройное объяснение одного числа) | разворачивать КАЖДЫЙ аккордеон; `.acc-tfi` график+таблица+`.scalenote` | medium |
| **CC-08** | Нет избыточных инструкций-императивов при очевидном действии; клиническое ядро (mixing point) отделять от механической инструкции | `.hint` «можно выбрать несколько» (живёт в exercise/writing/identity/journaling); `qr-head p` | medium |
| **CC-09** | Каждая строка — одна мысль ≤12 слов, без вводных/канцелярита/двух предложений; считать буквально | многопредложные `.syscard`, `sonahero .say`+`.sub`, referral `.safety`; вводные «Просто спокойный след…» | medium |
| **CC-13** | Нет служебно-системных/мета-оговорок про прототип/плейсхолдер/модель данных в device-зоне | referral `.safety` «…готовится с врачом»; «плейсхолдер», коды сущностей в видимом UI | medium |
| **CC-16** | Контекстные подписи к состоянию (таймер/режим/ветка) — короткий ориентир, не объясняющая фраза; читать JS-строки `presets`/`timerlabel` | sound-therapy `timerlabel`; onbprog `.remain` | medium |
| **LEAK-DEV-01** | Ноль дев-заметок/плейсхолдеров в `.device`/`.scroll` (включая JS-строки и `data-*`) | грепать в device-зоне (вычтя `.specpanel`): `.clinph`/`.medph`/`.devph`/`.branchph`, dashed-боксы `→…`, `→Лёва`/`→Этап 4`/`→V1`/`→O2`/`→O6`/`→O7`, имена `Лёва`/`Артём`, флаги `F2`/`F3`/`F6`/`F9`/`O3`/`O6`/`O7`, `computeTfiScore`/`mapSeverity`, `translations/ru.json`, «плейсхолдер»/«в проде»/«founder-видео», коды сущностей | high |
| **LEAK-REVIEW-01** | Ноль ревью-сообщений/тоглов в device + их CSS/JS; обработчик не оставляет два `.active` (ломает B2) | «Ревью: показать состояние», серые плашки команде «Здесь—/Ниже—», «для ревью/вид прототипа/состояние N из M»; любой видимый ревью-тогл в device (истор. today `.vtoggle` ⤢ на `.fstep` устранён — не заводить заново; ревью-вариант живёт только query-параметром, напр. `?zachin=under` в today). Не трогать продуктовую реплику Sona за раскрытием | high |
| **CC-17** | Каждая проверка A1–A4 — по ВСЕМ источникам текста (HTML/JS-строки/`presets`/`SONA[]`/`buildDetail`/aria/alt/content/шаблоны), не первый кадр | подпись только в JS: today `SONA[]`, calendar `buildDetail` (текст дня целиком в JS), sound-therapy `presets.timerlabel` | high |
| **V3-1** | Антипаттерн криптоплиток: нет однословных ярлыков-ребусов и иконок без подписи вместо текста; тест понятности каждого элемента (определения — `v3-minimalism-guide.md`) | сетка плиток «навык·регулярность·путь·норма»; пиктограмма/тогл без пояснения | high |
| **V3-2** | Иерархия размером и воздухом, не рамками/разделителями/плашками; имя-якорь = `--fs-h2`, `--fs-display` только за главной мыслью | равновеликие блоки без доминанты; карточка-обёртка+разделители вокруг фактов; `--fs-display` рядовым именам. Образец `.facts`/`.fact` на 4 экранах онбординга — проверять остаток | medium |
| **V3-3** | Минимизация подачи сохранила смысл/аффорданс: не вычтены факты/ориентир/Tier-1, тап ≥44, бирюза точечно, один градиент-якорь | пустой экран; пропавший Tier-1-факт; flat-ловушка (тоггл без состояния); два градиента. Сверять с исходной версией: понятнее — или просто меньше? | high |

**Граничные исключения раздела (не флагать):** ориентир (неделя/день/дата) под H1; содержательный H2 секции («Мои вводные»); клиническое ядро инструкции (mixing point, за раскрытие); онбординг/Кабинет — иные поверхности; ревью-леса — вычитаются до прохода.

### 3.2 Хром и навигация (CMP-4, NAV-01..17)

| ID | Что проверяем | Как обнаружить / сигнал | sev |
|---|---|---|---|
| **CMP-4** | Хром строго один слой; ни back-хедера/крошки/системной шапки. Возврат — нав-бар/иммерсивный ✕ | грепнуть `‹ ❮ ← Назад` и `back*`/`crumb`; любой якорь «‹ Сегодня» при активном табе «Сегодня» (истор. `.backtoday` в daily/calendar устранён — ловить по тексту/форме, не по классу) | **blocker** |
| **NAV-01** | Нет текстовой back-ссылки как самостоятельного элемента над/внизу контента | grep по `‹/❮/←` и `back*`/`crumb` (не по `header`/`nav`) | high |
| **NAV-02** | Круглая кнопка-возврат `‹` = второй слой хрома (back-хедер) на петле/хабе; если сознательно — решение DK | одиночная круглая кнопка `‹` первым интерактивом сверху с href внутрь продукта (`../tools/` и т.п.); истор. класс `.back-c` устранён — ловить по форме/href | high |
| **NAV-03** | Отличать содержательный `<header class=intake__head>` H2 (контент, ок) от системной sticky/fixed шапки (запрет); судить по `position`, не по тегу | `position:fixed/sticky`+`z-index` шапка с логотипом/действиями; FP: `<header>` в карточке без позиционирования; `<div class=topbar>` sticky без тега | high |
| **NAV-04** | Ровно один слой хрома = `.nav`; нет второго persistent/fixed (верхний таб-бар/sub-nav/sticky-фильтр/sticky safety) | второй `position:sticky/fixed` с нав-ролью; `.btabs`, второй `.nav`. 3 sticky только в Кабинете (NAV-19) | high |
| **NAV-14** | Переходы между разделами только через нижний нав-бар; нет дублирующего входа в тот же раздел из хрома | два постоянных элемента в один раздел; крошка «‹ Сегодня» дублирует таб | medium |
| **CMP-5** | Контейнер нав-бара идентичен между экранами; бейдж — статичная точка без пульса/счётчика/красного; хитбоксы ≥44 | бейдж пульсирует/красный/со счётчиком на одном экране, статичен на другом; разный фон/blur/padding `.nav` | medium |
| **NAV-08** | `.nav` идентичен (`position`/фон/`blur(12px)`/`border-top`/padding `9px 6px 16px`/safe-area); неактивная подпись `var(--muted2)`; запрет хардкода `#6B7A8D` | дифф CSS `.nav`: `color:#6B7A8D` вместо токена; разный padding/blur; нет `padding-bottom:max(16px,env(...))` | medium |
| **CMP-1** | Нав-бар идентичен канону на всех экранах с хромом (Сегодня circle r=4.6 один контур, активный navgrad sw 1.9, неактивный currentColor sw 1.75) | footer-compare рисует «Сегодня» как circle+внутр.точка (`circle r=1.5 fill`) — запрет B6; залитый/иной активный; иной порядок | high |
| **NAV-05** | Набор глифов идентичен побайтно (Сегодня circle / Программа линия-узлы / Чат пузырь-3точки / Инструменты сетка 2×2 rect); порядок/`viewBox`/`path` | дифф SVG-строк таба между файлами: домик/солнце вместо кружка; иной path | high |
| **NAV-07/COL-07** | Подсвечен ровно таб области (today·calendar→Сегодня; tools/*→Инструменты; chat→Чат; program→Программа); ровно один `.on`; активная = градиент-обводка, не заливка | ноль/два `.on`; calendar подсвечивает «Программа»; tool-подэкран не подсвечивает «Инструменты»; сплошная заливка | high |
| **NAV-06** | Активный таб = тот же контурный глиф, отличие только цветом обводки; не залит, без внутренней точки; sw активного един между файлами | дифф SVG активного (`.on`) и неактивного: `fill`, другой path, внутренняя точка, дрейф sw 1.9↔1.75 | medium |
| **NAV-17** | A11y хрома согласован между экранами: `.nav role=navigation`+`aria-label`; SOS `aria-label`; декор-SVG `aria-hidden` | один экран с ролью, другой — голый `<div class=nav>` (today·calendar); SOS без `aria-label` | medium |

### 3.3 Структура, прогресс, геймификация, гейты (GAM-*, GATE-01, COL-06)

| ID | Что проверяем | Как обнаружить / сигнал | sev |
|---|---|---|---|
| **GAM-01** | Стоп-лист механик: streak/серия/баллы/значки/leaderboard/конфетти/награда/проценты прогресса/осталось N/штраф (источник перечня — DESIGN-GUIDE B4a; правки списка — только там, сюда зеркалить) | грепнуть: серия, подряд, дней, streak, 🔥, балл, очк, %, осталось, награда, конфетти, разрыв | **blocker** |
| **GAM-02** | Процент и «осталось N» — только онбординг День 0, не в петлю; прочие механики запрещены даже в онбординге | процент/«осталось N» на Today/calendar/tools; streak/баллы/конфетти внутри онбординга | high |
| **GAM-03** | Прогресс — только статичная позиция (неделя N·день M, полоска недели), один индикатор; тест «убери на 3 дня — меняется только позиция» | два индикатора (полоска+счётчик); накопительная величина («всего сессий»/«часов»); полоска заливается процентом | high |
| **GAM-04** | Завершение тихое (галочка, терминальный язык к практике), без «Поздравляем!»/streak; пропуск нейтрален/приглашающий, не красный/«вы пропустили» | финал с «Поздравляем!»/наградой/«серия продолжается»; красная метка пропуска в calendar | high |
| **GAM-05** | Бейдж непрочитанного — статичная бирюзовая точка по факту ответа; не число/красный/пульс | бейдж с числом; красная точка; `@keyframes`/`animation` на `::after`; горит всегда | medium |
| **COL-06** | В одной зоне ≤1 яркий/градиентный акцент; прочие шаги — тихие slate-плашки одной высоты; считать суммарно по зоне | две+ ярких карточки рядом; будущий шаг с яркой заливкой; активный шаг и CTA оба кричат градиентом | medium |
| **GATE-01** | Экраны с обязательными полями используют контракт `data-gate` + `gate.js` из ДС (гайд B9); кнопка продолжения всегда живая и фокусируемая, состояние пишет только контроллер (`data-gate-state`) | `disabled`/`pointer-events:none`/`aria-disabled` на CTA продолжения («мёртвый тап»); обязательные поля без `data-gate`; собственная копия гейт-логики в `<script>` вместо подключения `gate.js`; жёсткий стоп не через `data-hard-gate`. Эталон — `design-system/gate-contract.md`. FP: кнопка отправки пустого композера чата/Кабинета — не гейт-кейс B9 | high |
| **LEAK-2** | Ревью-аффордансы (hover-превью/`.vbadge`) помечены «только прототип»; JS не оставляет два `.fstep.active` | ревью-аффорданс как продуктовая фича; hover без пометки; переключение состояний оставляет два активных шага (истор. ревью-тогл `.vtoggle` устранён — не заводить заново) | medium |

### 3.4 Движение (MOTION-*)

| ID | Что проверяем | Как обнаружить / сигнал | sev |
|---|---|---|---|
| **MOTION-DURATION-01** | Каждая `transition`/`animation` ≤~0.3с | грепать длительности >300ms (`.4s` полоса онбординга `.onbprog .fill` в 20+ файлах; `.35s`) | medium |
| **MOTION-LOOP-01** | Нет бесконечных/циклических анимаций | `animation ...infinite`/`alternate`; `@keyframes` пульсации/мигания; спиннеры; «дышащая» иконка; «Куратор печатает» | high |
| **MOTION-REDUCED-01** | Присутствует `@media (prefers-reduced-motion:reduce){}`, отключающий декоративные переходы (канон системы) | отсутствие блока → все transition/`@keyframes` играют у пользователя с вестибулярными расстройствами | high |
| **MOTION-VESTIBULAR-01** | Нет крупных параллакс/slide/scale>1.1 на крупных блоках, fade целого экрана | `animation:fade .3s` на всём `.scroll` (phq9-bridge); scale на крупной карточке; резкий сдвиг layout при раскрытии | medium |
| **HOVER-01** | На мобильной поверхности продуктового `:hover` НЕТ вовсе (реш. DK 2026-07-12: прототипы мобильные, hover снят полностью — удалён, не обёрнут). Каждый интерактивный элемент несёт `:active` и `:focus-visible`. Детектор: любой `:hover` в мобильном файле, стилизующий продуктовый элемент = нарушение → ручная проверка на `.specpanel`/ревью-хром. Исключения (hover легитимен): `cabinet/*`, навигатор `index.html`, витрина `design-system/*` (кроме мобильных партиалов `_gal-pat-*` — зеркалят продукт, hover снят; `_gal-pat-cab-*` — десктоп, ок), `v3-guide.html`, спец-панели | грепать `:hover` в мобильных — любой продуктовый = дефект | high |

### 3.5 Цвет и токены (COL-*, TOK-*)

| ID | Что проверяем | Как обнаружить / сигнал | sev |
|---|---|---|---|
| **COL-02** | В зоне ровно один бирюза-градиент-якорь (`--grad`/`url(#navgrad)`) | пересчитать все `background:var(--grad)`/`linear-gradient(...#2BB4C6...)`/`stroke=url(#navgrad)`; считать суммарно по зоне | high |
| **COL-03** | Красный (`--safety #EF4444`) — исключительно Tier-1 safety/кризис | грепнуть `#EF4444`/`#DC2626`/`red`/`--safety`/`--danger` каждое вхождение: просрочка, бейдж, ошибка поля, удаление, громкость | **blocker** |
| **COL-04** | Цветные иконки — единый приглушённый teal-tint; нет какофонии разных насыщенных цветов на экране | звук синий/дневник зелёный/дыхание оранжевый; Material/emoji-палитра | medium |
| **COL-05** | Палитра прохладная (`--bg`/`--bg2`/`--surface` slate-white); ни бежевого/тёплого/серифа. Обратная ошибка — over-monochrome, убраны легитимные teal-tint иконки | бежевый фон, `serif`; либо всё обесцвечено в моно-slate | high |
| **COL-08** | Контраст пар контактов как пол (текст 4.5:1 / крупный 3:1 / safety 7:1); рассчитать каждую пару. Анти-пары: `--teal` как текст на белом — провал AA→нужен `--teal-ink`; `--muted2` на смысловой подписи — провал роли | светлый teal на белом <4.5:1; фиолетовый аватар-текст на тинте; safety <7:1 | medium |
| **COL-09** | `--sky-tint #F0F9FF` только фон «если захочешь», не якорь рядом с teal-градиентом; `--success #22C55E` только Кабинет/триаж/нейтральное завершение, не «прогресс» в петле | `--sky-tint`/`--success` как акцент в дневной петле | medium |
| **TOK-1** | Источник токенов — общая ДС: прототип подключает `design-system/tokens.css`+`components.css` (напрямую `<link …?v=>` или через `paths.js`/`DS_ROOT`); локальный `:root` допустим ТОЛЬКО как слой осознанных override с комментарием-обоснованием (образец — корневой навигатор `index.html`); новые значения не заводятся в обход `tokens.css`. Предохранитель — не вводить generic-фиолетовый из стоп-листа | прототип с полным самодостаточным `:root`-дублем канона (вместо линка на ДС); локальное переопределение канон-токена (`--teal`/`--grad`/`--curator`/`--safety`/`--muted`/`--muted2`/`--line`/`--bg`/`--bg2`/`--surface`/`--teal-ink`/`--teal-tint`) на неканон-значение; override без комментария. Стоп-лист: `#7C6BD9`/`#9B8BEA`/`#8B7FE8`/`#B79CF0` ≠ канон Куратора `#7C6CD6` | high |
| **COL-01** | Фиолетовый Куратора в петле/хабе ровно `#7C6CD6`; `#7C6BD9`/`#6D5BD0`/`#8B7AE0` ≠ Куратор (drift в одном hex-разряде) | грепнуть все фиолетовые hex (заливки аватара, тинты) | high |
| **TOK-2** | Нецветовые токены сверять с каноном (`tokens.css`): тени, радиусы, типошкала, длительности. Ключевое: `--fs-h1` вес **700**, НЕ 800/34px | имена: `--sh-card`/`--sh-cta`/`--sh-elevated`; `--r-card 20`/`--r-btn 14`/`--r-nested 16`/`--r-sm 11`/`--r-chip 999`; `--fs-h1`/`--fs-h2`/`--fs-body`; `--t-micro`/`--t-short`/`--t-medium`. Дрейф: `border-radius:18px`, `box-shadow` с иной альфой, `font-weight:800`/`34px` на H1 | medium |
| **TOK-3** | Hex-литерал, совпадающий с токеном, должен быть `var(--x)`. Исключение — inline-SVG `fill`/`stroke` где `var()` не работает (осознанный литерал, не баг) | `color:#64748B` вместо `var(--muted)`; `background:#E8F8FA` вместо `var(--teal-tint)` | low |
| **TOK-4/DEAD-3** | Каждый `var(--x)` разрешается: объявлен в подключённых `tokens.css`/`components.css` или в локальном override-`:root`; линки на CSS ДС несут `?v=` = текущему `DS_V` (канон — `program/paths.js`); объявленные локальные токены используются; каждый `<defs>` id (`#navgrad`/`#curatorgrad`) реферится; каждый `@keyframes` используется | `var(--sh-elevated)` использован, нигде не объявлен → падает на `initial`; прототип без линка на `tokens.css`; отставший или отсутствующий `?v=` на CSS-линке (дрейф версии ДС); `--r-sm` объявлен, не используется; `url(#navgrad)` без `<defs>` | high |
| **TOK-5** | Канон не отгружает декор, который экраны снимают оверрайдом (гайд D6) | экранные оверрайды `border:none`/`box-shadow:none`/обнуление `border-radius` на канон-классах ДС (`components.css`) — кандидат «впечь в канон», флаг DK (правка канона — решение системы, не экрана). FP: функциональные границы (рамка инпута, фокус-кольцо, safety-красный, тёмный плеер) и state-стили самого канона — не считать | medium |

**Анти-ложноположительные.**
- **TOK-2:** вес-800/34px/беж ловить только в `.device` — `.specpanel` (беж `#FAF6EE`, вес 800, 675× в скаффолде) легальны. Радиусы `∉{20,16,14,11,999}` — вне скаффолда (частые `18`/`22`/`24`).
- **TOK-1/COL-01:** в `#web`/`cabinet-*` легальны производные от `#7C6CD6` (`--curator-ink #5A48C0`, `--curator-tint #F0EDFB`, `--curator-line #D9D0F4`). Флагать только новый базовый `#7C6BD9`.
- **CON-02/CON-07 (позитивная):** на «Сегодня» зачин Sona первый; плита Куратора дословна: роль-строка «Анна · твой куратор» + реплика-заглушка «Я рядом. Пиши — отвечу в чате.» (+ тихий аффорданс «Написать ›») — зеркало к протечке наружу.

### 3.6 Три контакта (CON-*)

| ID | Что проверяем | Как обнаружить / сигнал | sev |
|---|---|---|---|
| **CON-01** | Где говорит Sona — аватар «S» в градиент-кружке; сонар-логотип только бренд-марка (иконка приложения / hero онбординга) | реплика/пузырь/зачин Sona с сонар-логотипом вместо «S»; или бренд-марка подменена аватаром «S» | high |
| **CON-02** | Блок-зачин Sona (аватар-S + «Sona · твой AI-проводник» teal-ink + teal-tint-пузырь; пульс-чек-ин слит в ЭТОТ ЖЕ блок — chromeless-merge реш. DK 2026-07-08: пузырь и точки-шкала на ОДНОЙ поверхности `.presence`, без отдельной карточки у пульса и без отдельного жирного h3) — первый элемент ТОЛЬКО на «Сегодня»; строка дословна; пузырь не тёмный | зачин на calendar/sound-therapy/tools/profile/log; перефраз («Sona — ваш гид»); тёмный/backdrop-пузырь коуча; пульс вне `.presence` рядом с пузырём как отдельная карточка/виджет (регресс к до-chromeless подаче) | high |
| **CON-03** | Аватар Куратора — фото в фиолетовой оправе-кольце (`img.gav`, оправа `--curator`; реш. DK R30 2026-07-10); фолбэк без файла — плоский `#7C6CD6` с инициалом (в прототипах — «А»), без градиента; отличается от Sona и SOS по всем осям | Куратор на градиенте/с «S»/на бирюзе; фото без оправы; Sona случайно фиолетовый | high |
| **CON-04** | SOS-глиф = канон `qranchor`: оба `d=` (сердце + чаша-ладошки) идентичны системе **побайтно** (сверять против системы, не попарным диффом — контракт «система владеет значениями»); поведение — переход в crisis; шторка `qr-sheet`/`qr-backdrop` УПРАЗДНЕНА (реш. DK 2026-07-10/11): канон SOS = переход на `program/templates/crisis`, любое появление `qr-sheet`/`qr-backdrop` = дефект | `♥` вместо path; диск teal-tint/красный; иной stroke; дрейф `d` — самая глубокая слепая зона | high |
| **CON-05** | SOS не в шапке, плавает внизу-справа в зоне большого пальца, не перекрывает главный шаг/нав-бар | прибит в верхний угол как header-action; `bottom` мал → налезает на нав-бар | medium |
| **CON-06** | SOS за 1 тап с каждого не-иммерсивного экрана с хромом; на иммерсивных нет SOS, но всегда ✕→«Сегодня»; отсутствие на не-иммерсивном — флагать DK, не добавлять | calendar/tools/profile/log без SOS-якоря; иммерсивный плеер с лишним SOS; плеер без ✕ | high |
| **CON-07** | Плита-присутствие Куратора (`.cpresence`, реш. DK R30 2026-07-10: плоская `--curator-tint`-плита без рамки/тени, фото в фиолетовой оправе, роль-строка «Анна · твой куратор», реплика-заглушка «Я рядом. Пиши — отвечу в чате.», тихий аффорданс «Написать ›» в углу; живое состояние unread — начало последнего сообщения Куратора + статичная фиолетовая точка-маркер, не бейдж-счётчик/не красный) — только на «Сегодня»; вся плита — одна тап-мишень в чат | дубль на calendar/tools/profile/log/sound-therapy; регресс к строке-визитке `.guide` на «Сегодня»; маркер-пульс/красный/счётчик | medium |
| **CON-08** | Три контакта разведены по всем 4 осям (аватар/цвет/место/срочность); перекрёстная матрица 3×4; совпадение по одной оси = дефект | Sona и SOS оба плавающие; Куратор и Sona в одном месте одного цвета; SOS и Sona оба «секунды» без разведения | medium |
| **CON-09** | Два регистра голоса Sona разнесены (T1 приветствие-верх, T2 отклик на пульс), каждый — одна фраза в пузыре, не абзац; не третий голос | Sona в трёх+ местах; T1+T2 слиты; реплика-абзац; одинаковый бодрый тон независимо от ответа | low |
| **GAM-06** | Замер — живой диалог точкой без дашборда симптома (ноль графиков/чисел истории звона/измерителя громкости/частоты); эффект ответа ≥2 места; копи: нет «убрать звук/вылечить/громкость-частота» | график динамики симптома; слайдер «громкость тиннитуса»; журнал-таблица замеров; прячется в `practice/journaling` | high |
| **CON-10** | Пузырь по говорящему (C6g): в чатах пациента входящий Куратора `--curator-tint` / Sona серо-бирюза, исходящий пользователя — тихий `--bg2` (единственный градиент экрана — кнопка отправки); в Кабинете исходящий Куратора `--curator-grad`; аватар Куратора всегда фиолетовый. Асинхронный канал честный (канон daily/chat, реш. DK R31 2026-07-10): шапка-контакт с фото (`img.gav`) + срок «обычно отвечает в течение суток» БЕЗ точки «онлайн», после отправки — тихая статус-строка у последнего исходящего (вместо «прочитано»), вход по непрочитанному — статичная линия «Новое»; кадры жизненного цикла `?first/?sent/?unread` | фиолетовый/градиентный исходящий в Чате пациента; teal-исходящий в Кабинете; фальшивое присутствие в async-чате: точка «онлайн», «прочитано», «Куратор печатает» | medium |
| **CON-11** | Адресат контакта = цель ссылки: элемент, говорящий голосом/аватаром Sona («S», серо-бирюзовая система), ведёт на поверхность Sona (`tools/ask-sona/`, `daily/chat-unguided/`); элемент Куратора (фото/фиолетовая система) — на чат Куратора (`daily/chat/`). Проверять href каждой контакт-строки/ноты/плиты против говорящего | нота с аватаром «S» ведёт в `daily/chat/` (реальный баг приёмки 2026-07-10 на daily/skills); плита Куратора ведёт к Sona | high |

### 3.7 Доступность (A11Y-*, C4-EFFECT)

| ID | Что проверяем | Как обнаружить / сигнал | sev |
|---|---|---|---|
| **A11Y-PULSE-01** | Шкала-замер `role=radiogroup`+`aria-label`; каждая точка `role=radio`+`aria-checked`+словесный `aria-label` («Совсем нет»…«Очень») | точки как голые `class=dot` без роли/aria. Канон-пример — `design-system/_gal-pat-pulse-scale.html` (в data-driven Today пульс появится с наполнением дня) — проверять экраны со шкалой | high |
| **A11Y-FOCUS-01** | Каждый `outline:none` имеет парный `:focus-visible{box-shadow:0 0 0 4px var(--teal-tint)}` | `outline:none` (~80 файлов) без видимого кольца-замены | high |
| **A11Y-MEDIA-01** | Видео — `<track kind=captions>` или видимый CC; аудио — связь с расшифровкой; фон-сцена `aria-hidden` | ни один прототип не содержит `<track>` | high |
| **A11Y-LANDMARK-HEADING-01** | Ровно один `<h1>`-ориентир (не `div`), иерархия без скачков, нав-бар=`<nav>`, основная зона=`<main>`; зачин Sona не `h1` | отсутствие `<main>`/нав-бар не `<nav>`; H1 как `div`; несколько `h1`. `<h1>` уже добавлен на today·tools/profile — проверять остальные | high |
| **COL-08** | (контраст пар контактов — см. §3.5) | — | medium |
| **C4-EFFECT-01** | После выбора точки JS меняет ≥2 области (реплика Sona+доза+тон ленты); зона-отклик `aria-live=polite` | эффект в одном месте; `innerHTML` без live-региона | medium |

### 3.8 Тёмная поверхность (DARK-*)

| ID | Что проверяем | Как обнаружить / сигнал | sev |
|---|---|---|---|
| **DARK-01** | Иммерсивный тёмный — роли перекрашены: фон `#1E293B`/`#243149`, текст `#E2E8F0`, бренд-акцент `#27A2B2` (не светлый `#2BB4C6`), teal-текст `#5CCBD7` | плеер (sound-therapy·audio-player·video-player) держит светлый `#2BB4C6` на тёмном — проверять каждый | medium |
| **DARK-02** | Тёмная подложка (`#1E293B`/`--backdrop` как фон экрана) запрещена вне иммерсии; Today/Программа/Чат/Инструменты/Кабинет светлые | тёмный фон протёк в петлю/хаб/Кабинет | high |

### 3.9 Кабинет (CAB-*)

| ID | Что проверяем | Как обнаружить / сигнал | sev |
|---|---|---|---|
| **CAB-01** | В Кабинете нет online-точки/колокольчика-счётчика/дневной кривой симптома/серий/%-заливки; красный только safety-триаж; GAM-стоп-лист применяется | любой online-индикатор/колокольчик/дневная кривая/серия/процент в `cabinet-*` | high |
| **CON-10** | (цвет пузыря Куратора по поверхности — см. §3.6) | — | medium |

### 3.10 Утечки dev/review (LEAK-*, CC-13)

LEAK-DEV-01, LEAK-REVIEW-01, CC-13 — определены в §3.1 (текстовые утечки в device-зону). LEAK-1/LEAK-2 — здесь (леса и палитра specpanel).

| ID | Что проверяем | Как обнаружить / сигнал | sev |
|---|---|---|---|
| **LEAK-1** | `.specpanel` не протекает в `.device`; бежевая палитра specpanel (`#FAF6EE`/`#6b5d44`/вес 800) не в продукте; `@media(max-width:520px){.specpanel{display:none}}` присутствует; `.role-med`/`.role-dev` не в `.device` | продуктовый селектор наследует беж specpanel; id/класс specpanel переиспользован продуктом; нет media-скрытия | high |
| **LEAK-2/A11Y-SCAFFOLD-LEAK-01** | Ревью-инструменты (hover-превью/`.vbadge`/`.back`«← К карте») помечены «только прототип», JS не создаёт продуктовых состояний. Отличать лес `.back`«← К карте» (href `../../`) от продуктовой кнопки-возврата `‹` с href внутрь продукта (B5-нарушение; истор. класс `.back-c` устранён — различать по href) | ревью-тогл как продуктовая фича (истор. `.vtoggle` устранён); `.vbadge` без media `display:none`; переключение оставляет два `.fstep.active`; леса раздувают a11y-счётчики | medium |

### 3.11 Целостность кода, ссылки, метки, язык (DEAD-*, LINK-1, COMMENT-1, VER-*, SLOP-RU, TERM-1)

| ID | Что проверяем | Как обнаружить / сигнал | sev |
|---|---|---|---|
| **DEAD-1** | Каждый CSS-класс-селектор есть в разметке или порождается JS; сироты `.coach`/`.av`/`.who`/`.bubble`/`.guide`/`.gav`/`.shortnote`/`.whybody` после удаления зачина не остаются | сверка селектор↔разметка: правило в `<style>` есть, класса нет в DOM, не добавляет `classList.add`/`innerHTML` | medium |
| **DEAD-2** | Каждый `getElementById`/`querySelector` находит узел; нет ссылок на удалённые id (`#whyToggle`); нет необъявленных/невызываемых функций | `getElementById('whyToggle').addEventListener`, а id удалён → рантайм-ошибка, скрипт под ней мертвеет | high |
| **DEAD-3** | Каждый `@keyframes` используется в `animation`; каждый `<defs>` id реферится; `@media` относится к существующим селекторам | `@keyframes tap` без `.dot.on{animation}`; `<linearGradient id=navgrad>` без `url(#navgrad)` (или наоборот) | high |
| **COMMENT-1** | Код-комментарии/метки-задачи описывают реальное состояние после правок (canon-комментарий ≠ противоречащему коду) | `/* H1 27, вес 700 — НЕ 800 */` над `font-weight:800`; `// тёмный пузырь коуча` над уже teal-tint `.bubble` | low |
| **VER-1** | `<meta sonaura-doc-version>` = screen-id, не версия; `.vbadge` = чистое имя без суффикса версии; версия дизайна `vX.Y` только в `.specpanel .tag`; суффиксы `-k2`/`-clean`/`-pilot` не в `.vbadge` | `.vbadge` несёт `Today · v2.1`; `.tag` тащит рабочую ветку как версию; `meta` подменён номером версии | low |
| **VER-2** | Видимые плейсхолдеры (`.clinph`/`is-placeholder`/демо-номера) явно помечены, не выглядят финальными; пометки веток не утекают пользователю | плейсхолдер без визуального признака «заглушка»; демо-текст звучит как утверждённый без `.clinph`-обёртки | medium |
| **LINK-1** | Каждый `href=../dir/` → существующая папка-прототип; `href=#id` → существующий якорь; глубина `../` корректна; нет `href="../sos/"` (страницы SOS нет by design) | ссылка на несуществующую папку; разнобой глубины `../` между соседними экранами | high |
| **TOK-3/TOK-4/DEAD-3** | (литерал→токен, полнота `:root`, осиротевшие defs/keyframes — см. §3.5) | — | low/high |
| **SLOP-RU** | Видимый текст device-зоны — чистый русский без рунглиша/калек/олицетворения систем/канцелярита/англицизмов (кроме названий/протоколов и санкционированных концептов вроде today-first); после правки — обязательный прогон `ru-text-editor` | смешанные русско-английские строки в репликах; дословная калька; неестественные коллокации; канцелярит | medium |
| **TERM-1** | Запрет слова «звон» (гайд A4b, реш. DK 2026-06-25): пользовательский текст называет тиннитус «шум» или «тиннитус» | грепнуть «звон» по всем источникам текста device-зоны (CC-17: HTML/JS-строки/aria/alt/placeholder). FP: код-комментарии и `.specpanel` — не пользовательский текст; однокоренные ложные («позвонить»/«звонок»/«созвон») — не нарушение | high |

---

## 4. Кросс-экранный барьер (Слой 2) — список ID для попарного диффа

Не переписывать проверки — указать, какие из §3 гонятся ещё и **попарно** между экранами одной поверхности. **Расхождение МЕЖДУ экранами — дефект сам по себе**, даже если каждый экран локально валиден. Реализация — diff SVG/CSS/JS-блоков, не визуальный осмотр.

**Порядок:** (1) определить поверхность каждого файла; (2) попарно сверить общие компоненты между экранами одной поверхности; (3) meta-проверки целостности кода по каждому файлу.

**Хром (попарно между экранами дневной петли):**
- **NAV-20** (high, ядро барьера): сравнить хром (нав-контейнер, набор глифов, активное состояние, SOS-компонент, a11y-атрибуты) попарно между всеми экранами поверхности.
- **CMP-1/NAV-05** — набор/порядок глифов идентичны побайтно.
- **NAV-06** — активный глиф отличается только цветом обводки; sw активного един между файлами.
- **NAV-07/COL-07** — подсвечен ровно таб области; ровно один `.on`.
- **CMP-5/NAV-08** — контейнер `.nav` идентичен; неактивная подпись `var(--muted2)` (не хардкод `#6B7A8D`); бейдж статичен.
- **CMP-2/NAV-10** — SOS = канон-компонент `qranchor` (диск + два path, переход в crisis) на всех не-иммерсивных; шторка `qr-sheet`/`qr-backdrop`+JS УПРАЗДНЕНА (реш. DK 2026-07-10/11): канон SOS = переход на `program/templates/crisis`, любое появление шторки на любой поверхности = дефект; плееры (sound-therapy·audio-player·video-player) не включать. Сигнал: SOS как `href="../sos/"`; любая `qr-sheet`/`qr-backdrop`.
- **CON-04** — `d=` сердца идентичен между всеми экранами И с каноном системы.
- **CMP-6/NAV-12** — позиция/размер `qranchor` согласованы (`right:16px`, `bottom` над нав-баром); иммерсивный ✕ ведёт на «Сегодня» (откуда SOS в 1 тап); плееры в дифф позиции не включать.
- **CMP-3/CON-01** — аватар Sona = `<span class=av>S</span>` (`var(--grad)`), размеры `.av 38`/`.sav 22`/`.sav 20` согласованы по ролям; не сонар-логотип, не фиолетовый.
- **CON-03** — аватар Куратора: фото в фиолетовой оправе-кольце (`img.gav`); фолбэк — плоский `#7C6CD6` с инициалом «А».
- **CON-08** — матрица 3×4 разведения контактов.
- **CON-02/CON-07** — зачин Sona и плита Куратора только на «Сегодня»; не дублируются.
- **NAV-17** — a11y-атрибуты хрома согласованы.
- **CMP-7** (low) — мотив-иконки шагов (`.sico` video/sound/pulse/note/close) идентичны между Today (разметка) и Calendar (JS `ICO{}`): те же path, `stroke var(--muted2)` sw 1.7, моно-slate; `viewBox` не расходится.

**Токены (между файлами; канон — общие `design-system/tokens.css`+`components.css`, единая версия `?v=` = `DS_V` из `program/paths.js`):**
- **TOK-1/COL-01** — локальный `:root` каждого файла — только осознанные override, сверить с каноном; нет полного `:root`-дубля вместо линка на ДС; предохранитель против второго фиолетового `#7C6BD9`.
- **TOK-2** — нецветовые токены (тени/радиусы/типошкала/длительности) сверить.
- **TOK-3** — литерал→`var(--x)` (кроме inline-SVG).
- **TOK-4/DEAD-3** — полнота объявлений (ДС-линк + override-`:root`), единый актуальный `?v=` между файлами, defs/keyframes.

---

## 5. Пост-проверка оркестратором (Слой 3)

После каждого роя оркестратор сам проверяет результат на коде, не пересказом агента.

| Шаг | Что делает | Инструмент |
|---|---|---|
| **3.1 Определить поверхности** | классифицировать каждый файл (петля / онбординг `.onbnav` / иммерсивный плеер / Кабинет `cabinet-*`+`.specpanel`+`.btabs`+3 sticky); B5/B6/C6f только к петле | grep по сигнатурам §1 |
| **3.2 Дифф хром-блоков** | попарно между экранами петли: `.nav`-контейнер (CMP-5), глифы (CMP-1), активное состояние (NAV-06/07), `qranchor`+path (CMP-2/CON-04), аватар Sona (CMP-3), a11y (NAV-17) | diff CSS/SVG/JS |
| **3.3 Сверка токенов** | override-`:root` каждого файла против канона (TOK-1/2); линки ДС и единый `?v=` = `DS_V`, полнота `var(--x)` (TOK-4); нет второго фиолетового вне Кабинета | grep по hex, `var(--` и `tokens.css?v=` |
| **3.4 Целостность кода** | мёртвый CSS (DEAD-1), висячие JS на удалённых id (DEAD-2), осиротевшие keyframes/defs (DEAD-3), битые ссылки/глубина `../` (LINK-1) | grep селектор↔разметка, `getElementById`↔DOM, проверка путей |
| **3.5 Леса и метки** | вычесть леса по сигнатуре; проверить непротечку (LEAK-1/2), пометку «прототип»; согласовать версии (VER-1/2) | grep по классам-лесам + `@media display:none` |
| **3.6 Язык** | перечитать изменённые строки; при правках русского — прогнать `ru-text-editor` (SLOP-RU) | чтение device-зоны + skill |
| **3.7 Флаги DK (не авто-фикс)** | зафиксировать: отсутствие SOS на не-иммерсивном (NAV-09/CON-06); круглые кнопки-возврата на хабах (NAV-02); снятие декора канона оверрайдом (TOK-5); расхождение Кабинета vs канон | список спорных решений |

**Принцип.** Оркестратор чинит ВСЕ безопасные дефекты, не спрашивая. Решения по поверхности и отсутствующие компоненты — DK списком. Каждый утверждённый экран → обновить DESIGN-GUIDE + разлить правку на все релевантные прототипы (не чинить одно по десять раз). Границы этапа жёсткие: deferred/skipped эскалируется DK, не тиражируется молча.

---

## 6. SPEC-PANEL — устройство панели и детектор журнала правок

`.specpanel` — служебные «леса ревью» слева от телефона, не часть продукта; объясняет команде интерфейс справа (`.device`): что за поверхность, какие джобы (JTBD) закрывает, кто за что отвечает, к каким сущностям данных привязан, где границы. Источник истины по номеру/имени/джобам/сущностям/границам — [`interface-map.md`](../../../.plans/2026-06-curator-cabinet-redesign/interface-map.md). Критерий: панель отвечает на «ЧТО это за интерфейс и чем устроен», НЕ на «что поменяли в этой итерации».

**Канонические секции (порядок обязателен; чистые эталоны — `tools/help`, `tools/ask-sona`):**
1. **Back-ссылка** `<a class=back href="../../">← К карте интерфейсов</a>` — всегда первая, `href` всегда `../../`, продуктового смысла не несёт.
2. **Тег** `.tag` — НОМЕР и ИМЯ интерфейса как в `interface-map.md` + статус-плашка приёмки (`.st-proto`/`.st-accepted`/`.st-shell`) + версия дизайна. Версия = маркер дизайна, не лог правок.
3. **Заголовок** `h2` — человекочитаемое имя экрана как у пользователя.
4. **«Что это и зачем»** — прозой ЧТО за поверхность и ЗАЧЕМ сюда приходят; джоб словами, не механика.
5. **«Что пользователь делает»** — `<ul class=acts>`, по одному действию-глаголу на буллет.
6. **«Для команды»** — `<ul class=team>`, каждый буллет с вшитой меткой роли-адресата (фикс-словарь): `role-watch` «На что смотреть» (инварианты/цвето-коды/ревью-аффордансы/чего НЕ должно быть); `role-med` «Медтрек · Лёва» (пороги/шкалы/формулировки); `role-dev` «Артёму/разработчику» (в какие сущности данных читает/пишет — `daily_check_in`/`ProgressEntry`/`Conversation`/`SafetyFlag`, трассировка к Data Model); `role-dk`/`role-stage` «DK / Этап» (продуктовые развилки). Сущности — в `<code>`, в контексте; голых ID нет.
7. **Границы / «Инвариант» / «Открытые вопросы»** (в простых экранах сворачивается) — жёсткие правила + чего на экране НЕТ и почему (вынесено за V1 / в другой интерфейс); `.blocker` (⛔) для развилок, где сущность не объявлена в каноне / нет destination в модели.
8. **«Связи»** — откуда вход на экран, куда ведёт, с чем не путать / парное состояние (guided↔unguided, Sona↔Куратор↔SOS); место интерфейса в общем графе.

**Минимальный обязательный набор:** секции 1–6 + «Связи» присутствуют ВСЕГДА; секция 7 сворачивается только в простых экранах (program, chat).
**Сквозная трассировка JTBD:** «Что это и зачем» (job словами) → «Что делает пользователь» (действия) → «Для команды / role-dev» (сущности Data Model) → «Связи» (место в графе) → «Границы» (чего job НЕ покрывает). Явные BJ-коды (BJ1…BJ8) — для насыщенных кабинетных панелей (`cabinet-patient`); телефонным экранам достаточно словесной трассировки.

**⛔ Анти-паттерн: журнал правок в `.specpanel` запрещён** — транзиент, ему место в git/`.plans`, не в интерфейс-документации. Сигналы-запреты:
- **Чейнджлог-секции:** `Что изменено`/`Что нового в v#`, списки фиксов, «пересборка под DESIGN-GUIDE», «убраны X, добавлен Y».
- **Заголовки-секции с гайд-кодами правок** (`A#/B#/C# — …` с тире) — лог работы под гайд, не джоб-секция.
- **Нарратив редактирования** («раньше … / переименован / расформирован / слит сюда», «было/стало» как самоцель). *Исключение:* сравнение допустимо ТОЛЬКО когда объясняет устройство ТЕКУЩЕГО интерфейса.
- **Версия как лог правок** («v2.1 — поправили подписи») — версия только маркером дизайна в `.tag`.
- **Статусы процесса приёмки прозой/списком** («принято под гайд», «промоут в v2») — статус = одна плашка `.st-*` в `.tag`.
- **Заметки о ходе работы агента** — ссылки на задачи/PR/коммиты, TODO, даты правок.
- **Маркетинговый/продающий тон** («революционный экран», «лучший UX») — язык лесов фактический.
- **Дублирование контента `.device`** (повтор текстов кнопок/реплик) — панель объясняет, не воспроизводит.
- **Голые ID сущностей** без объяснения (правило DK «не давать голые ID»).

| ID | Сигнал | Что значит | Чинить | sev |
|---|---|---|---|---|
| **SPEC-PANEL-CHANGELOG** | внутри `.specpanel`: `<h3>Что изменено</h3>` и/или «Пересборка … под DESIGN-GUIDE»/«правки по принципам гайда», и/или ≥1 заголовок-секция с гайд-кодом `A#/B#/C# — …` (с тире); джоб-секции отсутствуют | панель документирует процесс правки, не интерфейс | выбросить весь блок, пересобрать с нуля по канону (секции 1–6 + Связи); состав джобов — из `interface-map.md` | high |
| **SPEC-PANEL-CHANGELOG-INSET** | `<h*>Что нового в v#</h*>` с нарративом «раньше / переименован / расформирован / слит сюда» внутри в остальном канонической панели | история редактирования врезана в корректную джоб-документацию | вырезать/перенести один блок; остальная панель сохраняется | medium |

**Как грепать.** Найти `<aside\|div class="specpanel">` (секции — `.row`/`<section>` с `<h3>`/`<h4>`). (1) Грепать жёсткие сигналы заголовков ТОЛЬКО в теле `.specpanel`: `Что изменено`/`Что нового в v`/`пересборк`+`DESIGN-GUIDE`/`правки по принципам гайда`; гайд-коды `A#/B#/C# — …`; нарратив `раньше / переименован / расформирован / слит сюда`. **Совпадения внутри `.device` — ложные.** (2) Проверить наличие канона (джоб-секции + «Для команды» с метками + «Связи»): подменены логом — тяжёлое нарушение; чейнджлог врезан — лёгкое. (3) Сверить номер/имя/джобы/сущности с `interface-map.md` — не выдумывать. (4) Перед коммитом — `ru-text-editor` (английский только для имён сущностей в `<code>`, шкал TFI/PHQ-9, концептов today-first/guided-unguided).

---

## 7. Покрытие гайда: пункт DESIGN-GUIDE → ID проверок

Сверка полноты: каждый пункт чек-листа гайда ↔ чем ловится в этом реестре. «Нет (ручная приёмка)» = автоматической проверки нет, пункт закрывается глазами DK/ревьюера. Проверки вне пунктов гайда (гигиена кода и лесов: LEAK-*, DEAD-*, LINK-1, COMMENT-1, VER-*, SLOP-RU, DARK-*, CAB-01, SPEC-PANEL-*) — их источник — §1/§6 и конвенции репо, не чек-лист.

| Пункт гайда | ID проверок |
|---|---|
| **A1** (минимум текста, дубли-надписи; A1a–A1d) | CC-05, CC-06, CC-10, CC-15 |
| **A1e** (без пояснительного зачина) | CC-01, A1E-1/CC-02, CC-03, CC-11 |
| **A1f** (один H1, без eyebrow-бара) | CC-1F, A11Y-LANDMARK-HEADING-01 |
| **A2** (глубина по запросу) | CC-07, CC-12, CC-08, CC-16 |
| **A2a** (video-first) | нет (ручная приёмка) |
| **A3** (один экран — одно действие) | частично COL-02/COL-06 (один яркий якорь); прямой проверки нет (ручная приёмка) |
| **A4** (голос интерфейса, ≤12 слов) | CC-09, CC-13, SLOP-RU |
| **A4a** («ты»-регистр) | нет (ручная приёмка) |
| **A4b** (запрет «звон») | TERM-1 |
| **B1** (вертикальный поток) | нет (ручная приёмка) |
| **B2** (один яркий шаг) | COL-06, LEAK-REVIEW-01, LEAK-2 (два `.fstep.active`) |
| **B3** (тихое завершение, нейтральный прогресс) | GAM-03, GAM-04 |
| **B4** (ноль игровых механик) | GAM-01, GAM-02, GAM-05, CAB-01 |
| **B5** (calm tech, один слой хрома) | CMP-4, NAV-01/02/03/04/14, CON-05; барьер §2 |
| **B5a** (нет крестика-леса в рамке) | §1 (правило лесов: `wtop`/`.wclose` — дефект) |
| **B6** (нав-глифы, актив только цветом) | CMP-1, NAV-05, NAV-06, NAV-07/COL-07, NAV-08, CMP-5, NAV-20 (§4) |
| **B7** (анимация одноразовая) | MOTION-DURATION-01, MOTION-LOOP-01, MOTION-VESTIBULAR-01, GAM-05 |
| **B7a** (продуктовый hover под `@media(hover:hover)`, tap-отклик `:active`+`:focus-visible`) | HOVER-01 |
| **B8** (плотность, воздух ~20px) | нет (ручная приёмка; смежное — V3-2) |
| **B9** (гейт `data-gate`, кнопка живая) | GATE-01 |
| **B10** (реактивные сообщения зон не конфликтуют) | нет (ручная приёмка) |
| **C1** (семантика цвета; C1a–C1e) | COL-01/TOK-1, COL-02, COL-03, COL-04, COL-05, COL-08, COL-09 |
| **C1f–C1h** (двухтировая safety, реактивные ноты, саундвейв-герой) | частично COL-03 (красный только safety); остальное — нет (ручная приёмка) |
| **C2** (зачин Sona только на «Сегодня») | CON-02, CON-01, CMP-3/CON-01 (§4) |
| **C3** (два регистра голоса Sona) | CON-09 |
| **C4** (замер — живой диалог) | GAM-06, C4-EFFECT-01, A11Y-PULSE-01 |
| **C5** (совладание, не шум; копи-стоп-лист) | GAM-06, TERM-1 |
| **C6** (три контакта; C6a–C6g) | CON-01, CON-03..08, CON-10, CON-11, CMP-2/NAV-10, CMP-6/NAV-12 (§4) |
| **C7** (a11y-минимумы) | A11Y-FOCUS-01, A11Y-MEDIA-01, A11Y-LANDMARK-HEADING-01, A11Y-PULSE-01, COL-08, NAV-17, MOTION-REDUCED-01 |
| **C7a** (реактивные сообщения озвучены) | C4-EFFECT-01 (aria-live) |
| **D1** (подача, не смысл) | V3-3 |
| **D2** (иерархия воздухом) | V3-2 |
| **D3** (криптоплитки — стоп) | V3-1 |
| **D4** (тест понятности) | V3-1, V3-3 |
| **D5** (бирюза точечно; D5a) | COL-02, COL-06; D5a (потолок карточек) — нет (ручная приёмка) |
| **D6** (декор не снимается оверрайдом) | TOK-5 |

---

> **История версий** — в git/`.plans` (чейнджлог транзиентен, в теле рул-дока не держим). v2.7: реструктуризация под роль машинного чек-листа — единый плоский реестр §3, эталоны сведены в §2, дубли Слоя 1↔Слоя 2 свёрнуты в §4 (список ID), значения вынесены ссылками на `tokens.css`/`components.css`, идеология V3 — на `v3-minimalism-guide.md`, устройство specpanel — на `DESIGN.md`/`interface-map.md`. v2.8: оздоровление по аудиту 2026-07-09 — мёртвые классы заменены живыми аналогами или сняты (сигналы переформулированы по смыслу), TOK-1/TOK-4/§4 переписаны под общую ДС (`paths.js`/`DS_ROOT`/`DS_V`), добавлены GATE-01/TERM-1/TOK-5, добавлена секция §7 покрытия гайда.
