ADR 0087 — UX Designer входит как разговорный агент
- Статус: Принят
- Дата: 2026-08-17
- Контекст: явное решение владельца продукта, опережающее триггер
разделения, который
docs/fluxo.ymlуже объявлял для этой роли
Контекст
docs/fluxo.yml (ADR 0085) уже фиксировал ux-designer как роль целевой
модели команды, со status: proposto, hoje_absorvido_por: criativo (discovery) + design/ (design system como dado) и объективным критерием
разделения:
Когда у УПРАВЛЯЕМОГО проекта будет собственный интерфейс для проектирования — сегодня design system является статическим входом. Разделяется, когда прототип станет повторяющимся артефактом.
Этот триггер не сработал. Brabo пока не строит в продакшене проекты с
действительно собственным UI; design system (design/tokens.css,
design/COMPONENTS.md) остаётся статическим входом, к которому обращаются
Arquiteto и dev agents, а не живым проектом, нуждающимся в повторяющихся
решениях UX.
Владелец продукта всё же решил построить агента сейчас — СОЗНАТЕЛЬНОЕ решение
опередить, зафиксированное здесь, чтобы его не путали с ошибкой прочтения
критерия. История того, что вбирала роль, остаётся в docs/fluxo.yml, как
комментарий: прежний текст не стирается, лишь перестаёт быть действующим
состоянием.
Решение
UX Designer входит как пятый разговорный агент — Criativo, PO, Arquiteto,
Dev Lead и теперь UX Designer, — ОДИНОЧНЫЙ (без области, без субагентов),
зеркаля дизайн Engine.Agents.DevLeadServer.
Детали
Engine.Agents.UxDesignerServer(apps/engine/lib/engine/agents/ux_designer_server.ex) — GenServer на сессию, регидрация из event log, streaming, ограниченный цикл tool use с потолком 14 (того же калибра, что Arquiteto/Dev Lead: агент РАССУЖДЕНИЯ, а не лёгкого разговора, как Criativo/PO, у которых потолок 12). Активируется handoffaccepted, адресованным "ux-designer", — механизм ОБЩИЙ (ActivateAgentUseCase/canActivateAgentв api уже принимают любого агента с принятым handoff; там не изменилось ни строки), — а kickoff выполняется только при СВЕЖЕМ старте (перезапуск не регенерирует прототип).- Kickoff читает
artifact.product_brief, ту же «бизнес-потребность», которую производит Criativo, — без нового артефакта, тот же образец чтения, что уже делаетArquitetoServer.build_kickoff/1. - Система дизайна ОПИСАНА в идентичности
(
Engine.Harness.Agents, запись"ux-designer"), статический текст с токенами изdesign/tokens.css(семантические цвета, типографика, отступы, радиус) и соглашениями изdesign/COMPONENTS.md(варианты кнопок, стиль значков). У разговорных агентов НЕТ инструмента чтения файлов репозитория — переиспользовать было нечего, — а идентичность — единственный слой промпта, присутствующий в КАЖДОМ ходе, а не только в kickoff. propose_prototype(Engine.Agents.UxDesignerTools,apps/engine/lib/engine/agents/ux_designer_tools.ex) — ЕДИНСТВЕННЫЙ инструмент:personas,jornadas,prototipo(telas+anotacoes) иresumo. Записываетartifact.prototipo_navegavelи предлагает handoff "po" и "dev-lead" по ТОМУ ЖЕ артефакту.Engine.Agents.UxDesignerSupervisor— точная копия образцаDevLeadSupervisor; зарегистрирован вEngine.Applicationрядом с ним.EngineWeb.AgentCommandControllerполучил три клаузы (start,message,via_for), которые уже есть у четырёх других разговорных.apps/web/src/lib/agents.ts:'ux-designer'вAgentKey, запись сcolor: 'var(--accent)'. Ни один из пяти семантических токеновdesign/tokens.cssне был свободен от другого агента —--accentпереиспользован меньше всех (только Arquiteto), а правило design system запрещает новый hex.icon: PencilIcon— единственный значок каталога, семантически связанный с дизайном/редактированием и ещё не имеющий владельца.
artifact.prototipo_navegavel: без таблицы и без выделенного use case в api
Это решение, которому понадобилось исследование до написания кода, потому что
два прецедента «артефакта без таблицы» (artifact.project_image, ADR 0065;
artifact.c4_diagram, RN-149) используют ДРУГОЙ путь, чем
artifact.business_rule/artifact.product_brief, и два пути кажутся
взаимозаменяемыми, пока не посмотришь, ПОЧЕМУ.
У choose_project_image/create_c4_diagram есть СОБСТВЕННЫЙ use case в api
(DecidirImagemDoProjetoUseCase, CreateC4DiagramUseCase), потому что у
каждого есть структурная причина:
- уровень Container у C4 ВЫВОДИТСЯ из действующего
module_map— содержимое, которое модель не может перепечатать, не рискуя разойтись с реальным источником; - у решения об образе есть доменный отказ (явный тег, потолок ресурсов), который более одного потребителя должны соблюдать одинаково.
У propose_prototype нет ни одной из двух. Персоны, путешествия, экраны и
аннотации — САМОДОСТАТОЧНОЕ содержимое — пишет только сам UX Designer,
читает обратно только он, ничто не выводится из другого артефакта, и нет
второго общего доменного правила, ждущего переиспользования. Поэтому он идёт
путём business_rule/product_brief: проверка ФОРМЫ в ENGINE
(Engine.Harness.ArtifactSchemas, тип "prototipo_navegavel") и запись по
ОБЩЕМУ пути, который api уже выставляет для любого session_event
(EngineApiClient.append_event_returning/3, без нового маршрута). Открытие
CreatePrototipoUseCase повторило бы форму CreateC4DiagramUseCase без
обеих причин, которые её там оправдывают, — сложность без довода.
Один артефакт, два handoff — никогда два артефакта
docs/fluxo.yml перечисляет два выхода роли: prototipo (для PO) и
spec-visual (для Dev Lead). Очевидным соблазном был второй вызов
инструмента или второй артефакт для «spec-visual». Решение — НЕ дублировать:
прототип (экраны + аннотации поведения) И ЕСТЬ визуальная спецификация — PO
читает resumo/prototipo, чтобы спроектировать backlog, Dev Lead читает ТЕ
ЖЕ telas/anotacoes как эталон реализации. Две копии одного содержимого
разошлись бы при первом пересмотре, сделанном с одной стороны, — тот же
довод, что уже действует для C4, не перепечатывающего module_map.
Ход останавливается на первом успехе — урок Dev Lead, без его приостановки
UxDesignerServer переиспользует ту половину дизайна DevLeadServer, которая
выживает без ADR 0086: УСПЕШНЫЙ propose_prototype завершает ход, чтобы
модель не предложила снова и не произвела два прототипа с одним итогом
(реальный дефект, мотивировавший эту охрану у Dev Lead). ДРУГАЯ половина ADR
0086 — приостановка в ожидании proposed_action — здесь не применяется: у
propose_prototype нет никакого внешнего эффекта (это содержимое, а не
действие; нет параллели «расходу, за который взимает потолок RN-083»), поэтому
он рождается простым событием, как рождался execution.plan_proposed до 0086.
Последствия
За
- Роль входит активной с ТЕМ ЖЕ строгим подходом, что у остальных четырёх разговорных, — потолок итераций, регидрация, озвученный отказ с источником (RN-059/163), — а не растёт как ad-hoc функциональность внутри Criativo.
- Ноль новых маршрутов в api: механизма активации по handoff, общего
append_event_returningи общегоcreate_handoffуже хватало. Единственная новая поверхность в api — полеuxDesignerActiveв составе (RN-287), симметричное тому, что уже делалinfraActive. docs/fluxo.ymlперестаёт описывать роль, которой не было в коде, —status: active, реальные входы/выходы, без суффикса_alvo.
Против
- Триггер опережён, по явному решению. Исходный критерий разделения (собственный интерфейс в управляемом проекте) сам по себе не выдерживает как обоснование — принят, потому что владелец продукта попросил, понимая это.
teste-de-usabilidadeостаётся вне досягаемости. Требует реального человека, тестирующего интерфейс; ни один агент его не заменит. Не имитируется.metricas-de-usoостаётся объявленным пробелом. Зависит от ролиanalytics(ПРОДУКТОВАЯ метрика), которуюdocs/fluxo.ymlдержитproposto, — без неё у соответствующего входа UX Designer нет реального источника.- Карточка дашборда и панель команды вычисляют
uxDesignerActiveраздельно (RN-090) — то же дублирование, что уже было уinfraActive, принятое по той же причине: api отвечает ФАКТАМИ, представление — дело web.
Рассмотренные альтернативы
Ждать срабатывания триггера разделения. Это было буквальное прочтение
docs/fluxo.yml до этого изменения. Отвергнуто явным решением владельца
продукта — см. Контекст.
artifact.prototipo_navegavel с выделенным use case в api, по образцу
CreateC4DiagramUseCase. Отвергнуто: ни одна из двух причин,
оправдывающих тот образец (выводимое содержимое, общий доменный отказ), здесь
не применяется. Копирование формы без причины — сложность, которую следующему
читающему код пришлось бы оправдывать самому.
Второй вызов инструмента/артефакт для «spec-visual». Отвергнуто: прототип уже является визуальной спецификацией. Две копии одного содержимого (одна для PO, другая для Dev Lead) рисковали бы разойтись при первом пересмотре, сделанном с одной стороны.
UX Designer как субагент новой области. Отвергнуто: ничто в роли не требует внутреннего делегирования или нескольких параллельных исполнителей — это рассуждение ОДНОГО человека на сессию, как уже Criativo/PO/Arquiteto/Dev Lead.
Ссылки
docs/fluxo.yml— блокid: ux-designer, исходный триггер разделения- ADR 0085 —
docs/fluxo.ymlкак декларативный реестр ролей - ADR 0053 — создаёт Dev Lead, шаблон, который повторяет этот ADR
- ADR 0086 — почему
propose_prototypeНЕ приостанавливается (нет внешнего эффекта) - ADR 0065,
RN-149 — образец артефакта без
таблицы, которому следует
artifact.prototipo_navegavel, и почему ему НЕ нужен выделенный use case, который есть у двух других apps/engine/lib/engine/agents/ux_designer_server.ex,ux_designer_tools.ex,ux_designer_supervisor.exapps/engine/lib/engine/harness/agents.ex,artifact_schemas.exapps/web/src/lib/agents.ts,agent-status.ts