Перейти к основному содержимому

ADR 0078 — Рамка экрана, и реестр вкладок намеренно расходится с handoff

  • Статус: принят
  • Дата: 2026-08-15
  • Предшествующий контекст: RN-048 (ожидающее продвижение истории), RN-104 (Chat и Criativo как места, с ключом sessions), RN-121 (вкладка Исполнители, dev agent и QA вне смешанной «Команды агентов»), ADR 0075 (embeddings в контракте LLMProvider — фундамент без потребления)

Контекст​

Чек-лист «рамка экрана» из handoff дизайна (design_handoff_brabo/CHECKLIST-CONFRONTO.md, раздел 2) описывает полосу, обрамляющую каждый экран проекта: header высотой 60px, линейка вкладок прямо под ним, активная вкладка с box-shadow: inset 0 -2px 0 var(--accent), горизонтальная прокрутка на узких экранах и контейнер содержимого с максимальной шириной 960–1040px. В коде ProjectPage.tsx были все четыре дефекта: header с переменным padding вместо фиксированной высоты, активная вкладка с border-bottom (а не box-shadow), без объявленной горизонтальной прокрутки и без потолка ширины в контейнере содержимого.

Исправление всех четырёх — суть этого ADR, но часть, требующая решения, — а не только CSS, — другая: handoff перечисляет 7 вкладок (Visão geral, Criativo, Código, Chat RAG, Gastos, Aprovações, Configurações), а в реестре (apps/web/src/routes/project-tabs.ts) их 10. Три лишние — executores, backlog и insights.

Handoff относится к более ранней волне ПРОГРАММЫ 16–26. Между волной, которая его нарисовала, и сегодняшним днём произошли три вещи, которые он не мог предвидеть:

  1. Executores родилась в ФАЗЕ 27 (RN-121), когда сетка агентов ушла из Visão geral на собственную вкладку, — реальные данные (живой статус, привязанная модель, переключатель автономии), а не макет.
  2. Backlog имеет собственный счётчик историй, ожидающих продвижения пользователем, с Фазы 12c (RN-048) — ещё одна очередь решений, с бизнес-правилом и тестом, покрывающим, что и когда она сигнализирует.
  3. Insights показывает гипотезы Psicólogo, ожидающие принятия/отклонения, — третья очередь решений проекта, существующая ещё до написания handoff.

Ни одна из трёх не избыточна по отношению к 7 вкладкам handoff, и ни одна не украшение: у всех есть реальные данные, счётчик, выведенный из запроса, и как минимум одна собственная RN с тестом. Удалить их, чтобы «совпасть» с handoff, уничтожило бы информацию, которую продукт уже умел показывать.

Решение​

10 вкладок остаются. Handoff — это эталон ВИЗУАЛЬНОЙ точности — цвета, типографика, отступы, рисунок рамки, — а не потолок того, сколько вкладок может иметь продукт (RN-203). Он фиксирует, как каждый экран должен ВЫГЛЯДЕТЬ; он не замораживает перечень функций на день, когда был написан. Правило уже действовало неявно (ФАЗА 26 зарегистрировала вкладку Código без того, чтобы handoff предусматривал «Executores» или «Insights» как отдельные вкладки, и никто не думал их удалять из-за этого), — этот ADR лишь делает его явным, с тестом, который отклонит, если кто-то «наведёт порядок» в реестре по handoff, не прочитав это решение.

Ключ sessions по-прежнему подписан «Chat», никогда «Chat RAG» (RN-202). Handoff называет эту вкладку «Chat RAG» на самых свежих экранах (designs/Brabo Chat.dc.html), и очевидным соблазном было бы просто поменять строку метки. Отказ буквален: «Chat RAG» описывает ФУНКЦИОНАЛЬНОСТЬ — запрос через embeddings по проиндексированному репозиторию, с цитированием источника, — которой у продукта нет. ADR 0075 поместил embed в контракт LLMProvider (capability доказана только в Ollama), но ничто ещё не ПОТРЕБЛЯЕТ эту операцию: нет конвейера индексации, нет векторного индекса на проект, нет UI цитирования. Сегодняшняя вкладка sessions — обычный КОНСУЛЬТАТИВНЫЙ Chat (RN-104), — агент, отвечающий с контекстом сессии, как Criativo, только без производства backlog. Подписать её «Chat RAG» сегодня было бы той же ложью, от которой ADR 0042 отказывается для модели каталога: объявлять возможность до того, как она появится, только потому, что имя уже зарезервировано в дизайне.

Четыре буквальных исправления рамки, без объявленных исключений:

  1. Header как нижний предел, а не потолок. .headerTop (заголовок идентичности проекта — значок provider, имя, chip репозитория, ветка/усыновлён — и компактный TokenMeter) получил min-height: var(--header-h) (60px), а не height. Содержимое этой полосы богаче, чем общий заголовок, который handoff рисует на 6 внутренних экранах (заголовок 18/600 + моноширинный подзаголовок
    • chip + индикатор): одна лишь карточка TokenMeter с собственным внутренним padding уже даёт около 70px. Принудительные 60px обрезали бы предупреждение о бюджете — а RN-088 уже установила, что сбой/состояние никогда не становится невидимым; обрезать бюджет ради эстетики было бы ошибкой того же класса под другим именем. min-height чтит токен как НИЖНИЙ ПРЕДЕЛ — когда содержимое проще (без TokenMeter, например, при загрузке), полоса остаётся около 60px; когда нет, она растёт, видимо.
  2. Активная вкладка с box-shadow: inset 0 -2px 0 var(--accent), а не border-bottom, в Tabs.module.css. Визуальная разница между ними невелика, но border-bottom сдвигает раскладку на 2px при смене состояния (рамка занимает место даже при переходе прозрачная-vs-сплошная, если плохо реализована), а handoff явно указывает атрибут. Значения отступов (gap: 2px, padding: 11px 13px), которые жили как переопределение CSS потомка в ProjectPage.module.css, — объявленный хвост со времён ФАЗЫ 16 («когда её можно будет менять, это место там»), — переехали в примитив, потому что эта волна дала обоим файлам одного владельца.
  3. Горизонтальная прокрутка (overflow-x: auto в .list, flex-shrink: 0 и white-space: nowrap в .tab) — её не было; линейка переносила бы строку или сжимала бы метки на узких экранах.
  4. Максимальная ширина контейнера содержимого — .body получил max-width: 1040px; margin: 0 auto для вкладок в форме документа (Backlog, Aprovações, Insights, Gastos, Configurações, Criativo, Chat). По-прежнему без потолка на вкладках semRespiro (Visão geral, Código): у первой собственная боковая направляющая, а вторая — «самая дорогая вкладка программы», по словам самого handoff, — обе намеренно используют весь экран.

Метка «Code» стала «Código». Ни одно другое место кода не сравнивает по СТРОКЕ метки (поиск подтверждён grep); КЛЮЧ реестра и deep-link остаётся code, нетронутым.

Последствия​

Реестр вкладок намеренно остаётся больше исходного замысла handoff — и у каждого лишнего пункта есть собственные RN и тест, указанные в этом ADR. Кто прочитает только handoff и сравнит с кодом, увидит расхождение; кто прочитает этот ADR, поймёт, что оно выбрано, а не забыто.

Ни одна ФОРМА экспорта не изменилась. AbaDoProjeto сохраняет те же поля (key, label, component, count?, ordem, semRespiro?), а ABAS_DO_PROJETO остаётся упорядоченным массивом, который читают другие потребители (Направление B оболочки навигации, параллельно в этой же волне), чтобы перечислить вкладки проекта в боковой панели, — изменилось лишь ЗНАЧЕНИЕ метки code, а список ключей не потерял и не приобрёл ни одного.

«Chat RAG» остаётся зарезервированным, а не отменённым. Когда конвейер индексации и UI цитирования появятся, вкладка sessions этого реестра будет местом, куда придёт функциональность, — имя сменится в тот день, вместе с данными за ним. Переименовать раньше было бы ошибкой того же класса, которую ADR 0042 уже назвал для модели: «включить» видимость возможности без самой возможности.

Остаётся вне, объявлено: богатый выпадающий список веток вкладки Código, UI blame и список PR (ФАЗА 26b) не затрагиваются этим ADR — рамка касается КОНТУРА экранов, а не внутреннего содержимого каждого.