ADR 0194 — Одобрение плана Dev Lead активирует выполнение, а задача получает модуль, который он назначает
Статус
Accepted. 2026-10-01 (AT-263 и AT-274, эпик EP-030, раунд 36; решения
владельца от 01.10: "a ativação da execução passa a ser o APROVAR do plano do
Dev Lead; aceitar o handoff do Dev Lead só o traz para planejar" и "quem
atribui o módulo da tarefa é o Dev Lead, ao montar o plano de execução; só o
dev daquele módulo a pega"). Пересматривает, не редактируя их,
ADR 0069
(условное слияние принятия с активацией, RN-161) и ту часть
ADR 0086, которая
говорила, что у propose_execution_plan нет конвейера выполнения. Сохраняет
ADR 0165 (репозиторий
рождается при принятии к Arquiteto, принятие к Dev Lead — вторая дверь, а
execution/activate без репозитория — 409) и
ADR 0061
(execution.activated в консультативной сессии — 409).
Контекст
Измерено в dev (d89f777) до изменения:
- Кто выдаёт
execution.activated— толькоActivateExecutionUseCase, а он вызывается только маршрутомPOST .../execution/activate. Backend принятия (AcceptHandoffUseCase) никогда ничего не активировал: он подготавливает репозиторий, когда адресат —arquitetoилиdev-lead, и активирует АГЕНТА. "Активация при принятии" была на стороне WEB —handleAcceptHandoffсцеплялactivateExecution, когда адресатом былdev-lead, а роль workspace былаmaintainer/owner(RN-161). - У плана не было потребителя.
propose_execution_planявляетсяproposed_actionс ADR 0086, и Dev Lead приостанавливается в ожидании решения, но, будучи одобренным, он оставалсяapprovedнавсегда: уApproveActionUseCaseне было ветви для этого типа, а Dev Lead читал "plano aprovado e registrado". В реальном использовании 29.09 выполнение поднялось в 06:45:01, при принятии; план пришёл в 06:47:47 и осталсяpending. - У задачи не было модуля.
claimNextберёт следующую задачуtodoисторииready, чейmodule_ids(jsonb, несколько) содержит модуль dev. При истории с двумя модулямиdev-input-keyboardвзял "loop de queda automática da peça", аdev-board-engineвзял "mapear teclas" (сессия d7e9, seq 185/187). - Dev Lead не видел ни одного
task_id: kickoff перечислял лишь модули и истории, взятые из журнала собственной сессии.
Решение
- Принятие Dev Lead не активирует выполнение ни для какой роли.
handleAcceptHandoffтолько принимает;AcceptHandoffUseCaseне меняется (продолжает подготавливать как вторая дверь). Явная кнопка "Ativar execução" карточки (RN-137) и кнопка Visão Geral ОСТАЮТСЯ: это собственный жест того, кто решает пропустить план, а маршрутexecution/activateсохраняет все отказы. - Одобрение
propose_execution_planисполняет план в новом исполнителе в api —ExecuteExecutionPlanUseCase, в модуле выполнения, рядом сExecuteParallelizationUseCase, — вызываемом ручным одобрением и автоодобрением (тип остаётся ВНЕ абсолютных пределовdecide.ts, как решил ADR 0086). Он: перечитывает план против действующегоmodule_map; записывает модуль задач; и вызывает ТОТ ЖЕActivateExecutionUseCase, что и кнопка, с одобрившим (или, при автоодобрении, открывшим сессию) в качестве активирующего. БезoriginSessionId: сессия Dev Lead — это место, где он возобновляет и повествует. Исход —executed(sessaoDeExecucao,modulos,tarefasAtribuidas) илиfailed(motivo), сexecution.plan_applied/execution.plan_failedна временной шкале, и именно его Dev Lead читает при возобновлении. - Задача получает колонку
module(tasks.module text NULL, миграция0068_modulo_da_tarefa). План несётtarefas: [{ taskId, modulo }], валидируемый ЧИСТОЙ функцией (lerPlanoDeExecucao) против действующегоmodule_mapи задач проекта ДВАЖДЫ: при предложении (400plano_de_execucao_invalido, без создания действия — фраза возвращается Dev Lead как ошибка инструмента) и при одобрении (карта могла измениться; отказ становитсяfailedбез записи чего-либо). Kickoff Dev Lead перечисляет ожидающие задачи backlog ПРОЕКТА (list_backlog), сtask_idи модулями истории. - Задачу берёт только dev модуля.
claimNextиcountClaimableByModuleначинают использовать один предикат:t.module = $moduloИЛИ задача без модуля, чья история имеет ровно ОДИН модуль, и он —$modulo.
Последствия
- Активация начинает стоить одобрения валидного плана, а план
валиден, только если КАЖДАЯ упомянутая задача назначена модулю
module_map. Dev Lead, который не может собратьtarefas(пустой backlog, задачи в другом проекте), ничего не активирует новым путём; явная кнопка остаётся выходом и объявлена таковым. - Мост для задачи без модуля намеренный и узкий. Без него тот, кто активирует через Visão Geral без плана, не имел бы ни одной доступной задачи; с ним, ограниченным историей с ОДНИМ модулем, правило "только dev этого модуля" остаётся истинным, потому что другого там нет. Задача без модуля истории с несколькими модулями стоит до следующего плана — а PO не назначает модуль, так что задача, созданная ПОСЛЕ одобренного плана, попадает в этот случай. Закрыть это (PO назначает или автоматическое перепланирование) — отдельное решение.
- Уведомление
task.became_claimableпо-прежнему маршрутизируется по модулям ИСТОРИИ. Разбудить dev, который ничего не возьмёт, стоит одного запроса и никакого расхода модели; маршрутизация по модулю задачи потребовала бы трогать источники уведомления, вне области. agentesпо модулю остаётся информационным. Активация поднимает одного dev на модульmodule_map, как прежде; больше одного на модуль — черезparallelize(RN-083), с его пределом.- Вызов
propose_actionиз engine остаётся на default 15 с Req для этого типа. При автоодобрении api активирует выполнение внутри того же запроса (засевает инструкции и автономию, вызывает engine); случай, превышающий 15 с, не измерялся, и если превысит, исход всё равно придёт через временную шкалу, даже если tool-result сообщит об ошибке транспорта. - Экран не переходит к сессии выполнения после одобрения плана
(RN-634 делала это в кнопке): одобрение принадлежит
ApprovalCard, другому направлению. Dev Lead говорит, в какой сессии поднялось выполнение.