ADR 0037: PFD — инварианты поверхности и проверка Roslyn (weight, input lock, каналы)¶
Статус: Proposed
Дата: 2026-04-12
Обновлено: 2026-04-16 — канон имён для строгой поверхности: [PfdStrict], PfdStrictControl. Подробности — § История.
Связанные ADR¶
| ADR | Роль |
|---|---|
| 0021 | зона PFD в модели внимания |
| 0036 | канал → CDS → композитор → поверхность |
| 0025 | capabilities и зоны |
| 0039 | формы навигации в зоне внимания |
Резюме¶
- PFD strict surface: инварианты weight/input lock; Roslyn-анализаторы.
- Канон
[PfdStrict]/PfdStrictControl— география зоны vs строгая поверхность (0021).
Вне ADR¶
| Документ | Роль |
|---|---|
CascadeIDE.ArchitectureAnalyzers/README.md |
CASCOPE*; расширение — по этому ADR |
Контекст¶
В авиационной метафоре PFD — первичный «прибор»: плотная, авторитетная картина контекста без охоты по вкладкам (0021). На уровне чистого кода Roslyn не знает, «лёгкий» ли виджет: тяжесть — это политика продукта, а не свойство IL.
Чтобы формализовать дисциплину PFD в коде, нужны явные контракты (атрибуты, базовые типы, узкие интерфейсы подписок на каналы). Тогда анализаторы становятся охранниками инвариантов, а не эвристикой по имени класса.
Уже зафиксировано: границы слоёв канал / CDS / композитор без Avalonia в Cockpit/Channels, Cds, Composition (0036, CASCOPE001/002). Этот ADR задаёт дополнительный слой — именно для компонентов, декларированных как строгая PFD-поверхность (см. раздел ниже: это не вся география региона PFD).
Зона внимания и строгая поверхность (0021 vs 0037)¶
Две оси, которые нельзя смешивать:
| Ось | Что это | Где зафиксировано |
|---|---|---|
| Зона внимания (география экрана) | Какой регион окна — якорь взгляда: лобовое, PFD, MFD, EICAS как канал и т.д. Что физически стоит слева/рядом с редактором по пресету. | 0021 («Архитектура зон», якоря vs attention flow). |
| Строгая PFD-поверхность (инженерный контракт) | Какой компонент кода добровольно берёт на себя роль «приборной части» первичного контура: только индикаторы, допустимый вес, допустимые каналы данных. | Этот ADR (§1–§3), явные маркеры в коде. |
Зачем разделять: авиационная строгость не должна превращать IDE в аскетичный терминал, где «в регионе PFD нельзя даже кликнуть по файлу». Навигация по решению — контекст «где я»; если выселить её только в MFD ради формального «PFD = read-only», вырастет налог на переключение взгляда и контекста (0021 — переключения как цена продуктивности).
Гибридная картина («слоёный пирог»): в одном регионе внимания PFD на экране могут сосуществовать:
- Интерактивная навигация (например обозреватель решения, «якорь» workspace): пользователь кликает, раскрывает узлы, выбирает файл — это остаётся навигационным контекстом, а не «вторым лобовым». На эти компоненты не вешается обязательный маркер строгой PFD-поверхности 0037; Roslyn-анализатор по этому ADR их не трогает (нет маркера — нет контракта §1–§3).
- Строгие PFD-surfaces — индикаторы критического контура: статус агента, EICAS/оповещения, компактное здоровье workspace и т.п. Их помечают атрибутом
[PfdStrict]и/или базовым типомPfdStrictControl(канон имени). Внутри таких типов анализатор запрещает произвольный ввод, WebView и иные нарушения Input Lock и Weight (§1–§2): «бьёт по рукам» за лишний интерактив и тяжёлые встраивания там, где политика требует только «авионики».
Итог одной фразой для контрибьюторов: зона внимания PFD может содержать интерактивные элементы навигации; компоненты, явно помеченные как строгая PFD-поверхность ([PfdStrict] или наследование от PfdStrictControl), обязаны соблюдать инварианты Input Lock и Weight Limit этого ADR. Анализатор действует только по маркеру, а не по факту «компонент нарисован слева».
Глоссарий (два смысла «PFD»)¶
| Термин | Одна строка |
|---|---|
| PFD как зона внимания | Регион экрана в пресете (0021): где лежит якорь «контекст полёта». Сама география не включает автоматически строгие инварианты 0037. |
| Строгая PFD-поверхность | Компонент в коде с явным маркером [PfdStrict] или базовым типом PfdStrictControl: на него распространяются §1–§3 и Roslyn. Это не синоним «всё, что нарисовано в колонке PFD». |
Связка для ссылок: «лежит в зоне PFD» ≠ «подпал под контракт 0037», пока тип не помечен как строгая поверхность.
Навигация «где я в коде»: в примерах выше фигурирует обозреватель решения как знакомый ориентир; это не требование единственной формы. Навигация по символам, иерархии типов, хлебным крошкам, структуре файла и т.п. может быть для части задач эффективнее классического дерева — и по-прежнему относится к якорю «где я» в смысле 0021, а не к «приборам» 0037, пока на виджет не повешен маркер строгой поверхности. Конкретный набор инструментов и пресетов — продуктовый выбор; этот ADR только фиксирует развод географии зоны и контракта по маркеру. Продуктовое направление «несколько представлений и связанные файлы» — 0039.
Решение¶
Инварианты PFD-поверхности задаём тремя классами правил. Конкретные идентификаторы диагностик, списки запрещённых типов и исключения вводятся при реализации (отдельные коммиты), но смысл инвариантов фиксируется здесь.
Канон имён для строгой поверхности (для кода в репозитории)¶
Принято для реализации:
| Элемент | Имя | Заметка |
|---|---|---|
| Атрибут (использование) | [PfdStrict] |
Полное имя типа в C#: PfdStrictAttribute, PascalCase; не [PFD_Strict] — так единообразнее с идиомой .NET и с остальными атрибутами в репо. |
| Базовый тип (опционально) | PfdStrictControl |
Базовый класс для Avalonia-Control, наследники которого считаются строгой PFD-поверхностью без дублирования атрибута на каждом подтипе (анализатор учитывает атрибут на типе или наследование от PfdStrictControl — семантика одна). |
| Не путать с | PfdSurface |
Слово «surface» в тексте ADR — про роль в UI; отдельного атрибута [PfdSurface] для «любой панели в зоне» не вводим: без маркера строгого контракта анализатор не применяется. |
Глоссарий в коде: XML-доки на PfdStrictAttribute и PfdStrictControl должны ссылаться на этот ADR и кратко повторять двойной смысл PFD (зона внимания ≠ автоматический контракт).
1. Контроль «веса» (Weight / dependency allowlist)¶
Правило: компонент или класс представления, явно помеченный как строгая PFD-поверхность (см. раздел выше; [PfdStrict] или базовый тип PfdStrictControl), не должен напрямую использовать заведомо тяжёлые контейнеры и встраивания: например таблицы с виртуализацией как замена смысла PFD, WebView, богатые ItemsControl с произвольными шаблонами там, где политика требует только примитивов.
Логика: PFD в продукте — плотный индикатор (текст, иконки, простые формы, компактные прогресс-индикаторы), а не вторичная рабочая область. Анализатор не оценивает FPS; он проверяет запрещённые типы/пространства имён в пределах помеченного типа и связанного AXAML (если подключается анализ .axaml / codegen).
Оговорка: универсальный Grid как layout часто необходим; запрет «всего Grid» не является целью — только конкретный список тяжёлых типов и сценариев, согласованный с командой (белый список разрешённых контролов — опционально во второй фазе).
2. Запрет ввода (Input lock / read-only display)¶
Правило: для строгой PFD-поверхности (по маркеру) в авиационной аналогии — дисплей для чтения в типичном сценарии; произвольный ввод и перехват фокуса в таком компоненте конкурирует с лобовым (редактор, терминал) и ломает модель внимания. (Навигация в регионе PFD без маркера — вне этого правила; см. выше.)
Для так помеченных компонентов анализатор должен диагностировать явные обработчики указателя, клавиатуры и фокуса (например подписки на события ввода Avalonia), за исключением явно перечисленных исключений в политике продукта (одна кнопка подтверждения, safety — по отдельному ADR/чеклисту).
Зачем: сохранить строгую PFD-поверхность индикатором, а не интерактивной панелью, которая отнимает ввод у первичной рабочей поверхности.
3. Ограничение графа данных (каналы / потоки)¶
Правило: строго помеченный PFD-компонент может подписываться только на разрешённые для первичного контура потоки данных (рабочие имена: например каналы состояния здоровья workspace, статуса агента, следующего шага — точный перечень типов и интерфейсов фиксируется в коде и в cds-contract-v0 по мере стабилизации).
Подписка на потоки вторичной насыщенности (условно: длинная история git, полное дерево решения как единственный источник данных прибора, полный дамп файловой системы как основной источник именно строгой PFD-поверхности) считается несоответствием роли прибора: это контент MFD / навигации без маркера / боковых панелей. (Отдельно: обозреватель решения в регионе PFD без маркера 0037 не обязан ограничиваться этим списком каналов — он не претендует на роль «прибора».)
Логика: анализатор проверяет типы вызовов подписки / конструкторов каналов в пределах помеченного компонента, если каналы выражены как стабильные compile-time API (интерфейсы, обобщённые фабрики). Строковые ключи DI, рефлексия и «общий» bus без типизации вне зоны этого ADR — там нужны обзорные тесты и ревью, а не Roslyn-only.
Последствия¶
- Разделение 0021 (география зоны) и 0037 (строгий контракт по маркеру) снимает ложное противоречие «PFD интерактивен vs PFD только read-only»: интерактив допустим в регионе внимания, строгость — только у явно помеченных «приборов».
- Появляется явная дисциплина «строгая PFD-поверхность в коде»: без маркера анализатор молчит — это осознанный контракт.
- Правила порционно переносятся в
CascadeIDE.ArchitectureAnalyzers(новые ID рядом с CASCOPE) и юнит-тесты* на диагностики по образцу существующего проекта тестов. - Конфликты с UX (например одна кнопка «OK» на PFD) разрешаются списком исключений или отдельным подтипом атрибута, не отменяя базовый инвариант.
Не цели¶
- Сертификация авионики или полное воспроизведение ARINC 661 / CDS железа.
- Замена человеческого ревью дизайна: анализатор ловит известные классы нарушений, не «красиво/некрасиво».
- Автоматический запрет
Gridбез исключений и без согласованного списка типов.
Открытые вопросы (до статуса Accepted)¶
- Минимальный allowlist разрешённых каналов для PFD v1 и маппинг на существующие
Cockpit/Channels. - Нужен ли отдельный анализ
.axamlили достаточно partial-класса и codegen.
Снято с повестки именования: канон — [PfdStrict] / PfdStrictAttribute и опционально PfdStrictControl; см. таблицу в том же разделе.
История изменений¶
| Дата | Изменение |
|---|---|
| — | глоссарий; навигация и 0039. |
| — | раздел «Зона внимания vs строгая поверхность» (0021). |
| 2026-04-16 | канон имён для строгой поверхности: [PfdStrict], PfdStrictControl. |