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

ADR 0083 — Вкладка Terminal получает реального потребителя жизненного цикла, а не терминал

Статус​

Принят. Пересматривает раздел "Nenhuma rota HTTP nova" ADR 0081, который намеренно откладывал этот маршрут до появления реального потребителя. Не пересматривает — и не может пересмотреть — ADR 0065 и FASE 25b (CLAUDE.md), которые по-прежнему объявляют интерактивный терминал отрезанным: этот документ не поднимает физическую стену контейнера, а лишь читает зарегистрированное состояние снаружи неё.

Контекст​

Исходный план этого направления (PROGRAMA 28, Волна 5, направление F2) был "интерактивный терминал" в предположении, что к этому времени у контейнера на проект уже будет реальный жизненный цикл — настоящая подготовка, с worktree агента, живущим внутри контейнера. Этого не произошло. Волна 4/направление F1 (ADR 0081) поставила project_containers — ТАБЛИЦУ состояния (provisioning/running/stopped/failed/removed) и два use case, которые пишут и читают эту таблицу, — но ни одного реального вызова Docker: ни один сервис не монтирует /var/run/docker.sock, ни один не работает privileged, а у RegistrarTransicaoDeContainerUseCase нет ни одного вызывающего вне собственных тестов. Нет реально работающего контейнера, чтобы открыть терминал ВНУТРИ него.

Реализовать терминал, который притворяется, что выполняет команды, или который выполняет в ТОМ ЖЕ контейнере, что монорепозиторий Brabo, — долг, который ADR 0055 уже описывает как политику, а не изоляцию, — значило бы выдумать несуществующую возможность. Это та же ошибка, которую ADR 0041/0042 уже отвергают для LLM-provider без доказательства и модели каталога без курирования: capability объявляется только при доказательстве.

ADR 0081 уже назвал это направление недостающим потребителем:

Nada na Onda 4 consome esta tabela por HTTP ainda — o terminal interativo (25b/Onda 5) é o candidato óbvio, e decidir a forma da rota antes de saber exatamente o que ele precisa ler seria adivinhar um contrato. — ADR 0081

Решение​

Вкладка Terminal не получает терминал. Она получает реального потребителя, которого ADR 0081 ожидал: GET /projects/:projectId/container/lifecycle (RN-267), маршрут только для чтения, role:viewer, который отражает ObterCicloDeVidaDoContainerUseCase, не добавляя логики, — null, когда проект никогда не подготавливался (сегодня обычный случай, потому что ничто в продакшене не переводит таблицу), или зарегистрированное состояние (status/imageVersion/resources/failureReason/statusChangedAt).

Под пояснительным текстом, существовавшим в CodeBottomPanel.tsx с FASE 26b ("o terminal interativo ainda não existe — FASE 25b"), вкладка начинает показывать это состояние с Badge, переведённым на pt-BR, и причиной сбоя, когда она есть. Запрос происходит только пока вкладка Terminal открыта (enabled: aba === 'terminal'), без фонового опроса, — та же дисциплина трафика, которую RN-107 уже применяет к gate образа.

Пояснительный текст FASE 25b не удаляется и не ослабляется: состояние жизненного цикла — дополнительная информация, а не замена объяснения того, почему самого терминала не существует. То, что проект может показывать running, не означает, что там есть что-то исполняемое, — это означает лишь, что кто-то (сегодня — тест или ручной вызов) зарегистрировал этот переход в таблице.

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

Что начинает существовать. Первое HTTP-раскрытие жизненного цикла контейнера и первый экран продукта, читающий project_containers, — до этого таблица была видна лишь тем, кто обращался к базе или к тестам напрямую.

Что остаётся ровно как было. Интерактивный терминал. FASE 25b остаётся отрезанной и объявленной — ни одна строка этого ADR не поднимает оркестратор, не монтирует сокет Docker и не направляет команду терминала внутрь контейнера. Находки Z и AD (allowlist глаголов не сходится) остаются открытыми по той же причине, что в ADR 0081: закрытие требует физической стены, а не экрана, читающего таблицу состояния.

Что остаётся честным по построению. Поскольку ничто в продакшене сегодня не переводит project_containers, самый частый ответ нового маршрута — null, и вкладка показывает это буквально ("ainda não foi provisionado") вместо выдумывания статуса. В тот день, когда настоящий оркестратор появится и начнёт действительно переводить таблицу, этот же экран начнёт отражать это состояние без необходимости меняться — он уже читает то, что говорит таблица, никогда не то, что нам хотелось бы, чтобы она говорила.

Ссылки​

  • ADR 0081 — таблица и два use case, которые этот документ наконец раскрывает по HTTP.
  • ADR 0065 — FASE 25b, которая остаётся отрезанной; этот документ её не открывает заново.
  • RN-105, RN-107, RN-243, RN-267, RN-268.
  • apps/api/src/interfaces/http/containers/containers.controller.ts, apps/web/src/routes/code/CodeBottomPanel.tsx.