ADR 0108 — В режиме runner проект рождается при клике на "Navegar pasta...", а не только при подтверждении
- Статус: Принят
- Дата: 2026-08-22
- Контекст: закрывает пробел, который ADR 0107 уже объявил в собственном разделе Последствий
- Расширяет (не редактируя): ADR 0104, ADR 0107
Контекст
ADR 0107 поставил навигацию по локальной папке через Runner, но явно объявил
в разделе Последствий принятый архитектурный пробел: тикет канала Phoenix
(terminal:<projectId>) выдаётся НА ПРОЕКТ, а на экране создания
(NewProjectWizard.tsx) проект рождается только на шаге
подтверждения (handleConfirm) — поэтому кнопке "Navegar pasta..." на шаге
"Onde o código vai morar" не к чему было привязать тикет, и она всегда попадала в
объявленное состояние ("disponível depois que o projeto existir"). Сам ADR
0107 перечислил два возможных выхода: "(a) um modo de ticket/canal para o
Runner não ancorado em projeto, ou (b) o projeto ser criado mais cedo no
fluxo do assistente (antes da confirmação)" — и отложил выбор до "uma
entrega futura que o dono do produto priorizar".
Это та самая поставка, проверенная вживую владельцем продукта при создании реального проекта: не имея возможности перемещаться по папкам на экране создания, он был вынужден вводить путь по памяти — ровно то трение, которое ADR 0107 существовал, чтобы устранить, только пробел остался именно там, где навигация дала бы наибольшую разницу.
Выбран вариант (b), а не (a): режим тикета без проекта изменил бы
контракт канала (Engine.Runners.Registry, сегодня ключуемый по
projectId) для всей поверхности Runner — exec, PTY и навигации — лишь
ради решения случая использования, у которого уже есть более дешёвый выход: сам ADR 0104
уже устанавливает, что createProject в режиме runner — ЛЁГКАЯ операция (лишь
строка проекта — без удалённого репозитория, без bootstrap Gitflow) и что
workspacePath в этом режиме предварителен по замыслу: настоящий runner при
подключении ПЕРЕЗАПИСЫВАЕТ путь тем, что сообщает о хосте (RN-423). Раннее создание
проекта не вводит второго источника истины о
пути — runner остаётся единственным.
Решение
Область: только execution_mode = 'runner'. Режим mounted продолжает с
projectId: null на шаге workspace, нетронутым — там проверка диска
выполняется ВНУТРИ контейнера api в момент создания (RN-422/RN-170), и
раннее создание с ещё не введённым путём вернуло бы сообщение об отказе
(которое учит монтировать папку) в момент, когда пользователь ещё даже не начал
думать о пути. У runner этой проблемы нет: создание в этом режиме лишь
проверяет ЛЕКСИЧЕСКУЮ часть пути (ADR 0104, пункт 2), никогда не касается диска.
NewProjectWizard.tsxсоздаёт проект при клике на "Navegar pasta...", а не только при подтверждении, — но лишь когда режимrunner. Если поле пути ещё пусто, он использует лексически валидный и явно предварительный маркер (/workspace-a-confirmar) вместо блокировки клика — настоящий runner перезаписывает это значение при подключении (RN-423), поэтому маркер никогда не становится истиной о пути, лишь разблокирует навигацию.- Повторное использование по СНИМКУ идентичности, а не по "я уже создавал какой-то проект
раньше". Снимок хранит лишь
name/externalId/adotando— поля, решающие, КАКОЙ проект создаётся, — и никогдаcaminhoLocal, потому что вся цель навигации — именно УТОЧНИТЬ путь после того, как проект уже существует: его включение в снимок аннулировало бы повторное использование при каждом клике. Пока идентичность не меняется, второй клик по "Navegar pasta..." и финальное подтверждение ПОВТОРНО ИСПОЛЬЗУЮТ тот же проект; смена имени (или возврат и смена принятого репозитория) аннулирует снимок, и следующая навигация создаёт другой. handleConfirmповторно использует проект, созданный во время навигации, когда снимок ещё совпадает, — никогда не вызываетcreateProjectснова для того же клика по "Provisionar"/"Ver o plano". Две строки для одного проекта были бы дефектом, а не функциональностью.
Последствия
- Осиротевший "неподготовленный" проект, если мастер закрыт, не завершив. Клик по "Navegar pasta..." и закрытие мастера, не дойдя до "Provisionar", оставляет созданную строку без репозитория и без bootstrap. Это принятый побочный эффект, и причина его принятия в том, что это не НОВОЕ состояние: любое прерванное сегодня создание — вкладка, закрытая между подтверждением и загрузкой экрана подготовки, например, — уже даёт тот же результат. У продукта сегодня нет механизма очистки осиротевших проектов (даже для этого существующего случая), и этот ADR его не создаёт — лишь этот случай перестаёт быть более редким, потому что создание теперь происходит на более раннем шаге потока. Если механизм очистки появится, он решит оба случая одним правилом.
UpdateProjectDtoпо-прежнему безexecutionMode/workspacePath. Констатация ADR 0104 (что преобразование режима СУЩЕСТВУЮЩЕГО проекта — не тривиальный PATCH) здесь не меняется — эта поставка не вводит никакого редактирования, лишь переносит момент ПЕРВОЙ записи.FolderBrowserModalполучает вторую причину получать ненулевойprojectIdдо подтверждения, но контракт компонента не меняется: он по-прежнему не знает, ЯВЛЯЕТСЯ ЛИ полученный проект окончательным или предварительным, — решает это мастер, по снимку.- Этот ADR НЕ вновь открывает решение (a) ADR 0107 (тикет без проекта): его по-прежнему не существует, и оно по-прежнему не нужно — поверхность exec и PTY Runner продолжает требовать реальный проект, как всегда требовала.