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

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), никогда не касается диска.

  1. NewProjectWizard.tsx создаёт проект при клике на "Navegar pasta...", а не только при подтверждении, — но лишь когда режим runner. Если поле пути ещё пусто, он использует лексически валидный и явно предварительный маркер (/workspace-a-confirmar) вместо блокировки клика — настоящий runner перезаписывает это значение при подключении (RN-423), поэтому маркер никогда не становится истиной о пути, лишь разблокирует навигацию.
  2. Повторное использование по СНИМКУ идентичности, а не по "я уже создавал какой-то проект раньше". Снимок хранит лишь name/externalId/adotando — поля, решающие, КАКОЙ проект создаётся, — и никогда caminhoLocal, потому что вся цель навигации — именно УТОЧНИТЬ путь после того, как проект уже существует: его включение в снимок аннулировало бы повторное использование при каждом клике. Пока идентичность не меняется, второй клик по "Navegar pasta..." и финальное подтверждение ПОВТОРНО ИСПОЛЬЗУЮТ тот же проект; смена имени (или возврат и смена принятого репозитория) аннулирует снимок, и следующая навигация создаёт другой.
  3. 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 продолжает требовать реальный проект, как всегда требовала.