Перейти к содержанию

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)

  1. Минимальный allowlist разрешённых каналов для PFD v1 и маппинг на существующие Cockpit/Channels.
  2. Нужен ли отдельный анализ .axaml или достаточно partial-класса и codegen.

Снято с повестки именования: канон — [PfdStrict] / PfdStrictAttribute и опционально PfdStrictControl; см. таблицу в том же разделе.


История изменений

Дата Изменение
глоссарий; навигация и 0039.
раздел «Зона внимания vs строгая поверхность» (0021).
2026-04-16 канон имён для строгой поверхности: [PfdStrict], PfdStrictControl.