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

ADR 0202 — Индекс ADR по темам, с темой вне ADR

Статус​

Accepted. 2026-10-01 (AT-137, история HS-014, эпик EP-011, находка BRB-026, раунд 36; решение владельца от 01.10: «да, реорганизовать по темам, с темой ВНЕ ADR» — файл сопоставления ADR → тема рядом с индексом, проверяемый docs:check, и ни один принятый ADR не редактируется). Таксономия — список из 15 тем и тема каждого из 191 ADR — это ПРЕДЛОЖЕНИЕ этой lane, и владелец пересматривает её в PR: смена темы ADR или слияние двух тем — это изменение docs/adr/temas.yml, а не этого текста.

Контекст​

docs/adr/index.md был сгруппирован по ФАЗАМ. Это помогало, пока фазы были способом движения проекта; перестало помогать, когда фазы закончились и работа начала рождаться из kanban: по замеру 2026-10-01 из 191 строки индекса 148 жили под одним заголовком, ## Phase 12 — Post-dogfooding operability, с 0044 по 0197 — раздел, который был «остальным», стал индексом. Тому, кто ищет «что было решено о broker» или «почему ключ машины такой», не с чего начать, кроме как прочитать 148 строк.

AT-027 сделала половину подсчёта BRB-026 (индекс говорил 134 при 156 написанных) и письменно выделила эту половину, с вопросом, который её блокировал: была бы тема метаданными tema: во frontmatter каждого ADR — а добавление frontmatter к принятому ADR — это его редактирование, что соглашение индекса запрещает без исключений. Решение владельца решает вопрос с другой стороны: тема живёт ВНЕ ADR.

Что уже существовало и продолжает действовать: verificarIndiceAdr (scripts/docs/generate.mjs) отклоняет ADR без ссылки в индексе, а verificarContagensEmProsa проверяет подсчёт в description индекса и «the next one is NNNN». Ни один из них ничего не знает о группировке.

Решение​

1. Тема живёт в docs/adr/temas.yml, рядом с индексом. Два ключа: temas: — ЗАКРЫТЫЙ список, по порядку, у каждой id (kebab-case, якорь {#tema-<id>} и значение карты), titulo (заголовок раздела в индексе, на английском, как индекс) и descricao, — и adrs:, карта "NNNN": <id>. У каждого ADR ОДНА тема, основная: когда подходят две, действует та, в которой кто-то стал бы искать в первую очередь. Ни один принятый ADR не затрагивается.

2. Индекс ПРОВЕРЯЕТСЯ, а не генерируется. Каждая строка индекса — курируемая фраза об ADR, и ни один скрипт её не пишет (причина, которую verificarIndiceAdr уже фиксировал). Генерация индекса потребовала бы перенести 191 фразу в YAML — обменять читаемый Markdown на длинную строку YAML ради порядка, который проверка уже гарантирует. Индекс получает раздел ## <titulo> {#tema-<id>} на каждую тему, в порядке списка, с однострочной фразой из descricao и привычной таблицей, в числовом порядке.

3. scripts/docs/temas-de-adr.mjs проверяет, а docs:check отклоняет (verificarTemasDeAdr, родственник verificarIndiceAdr, вызываемый сразу после него): ADR в docs/adr/ без темы; тема в карте, которой нет в списке; запись в карте для несуществующего ADR; тема списка без единого ADR; список с повторяющимся id или заголовком; в индексе — отсутствующий, повторяющийся раздел темы, с заголовком, отличным от списка, вне порядка списка или несуществующей темы; и строка ADR под разделом другой темы, вне какого-либо раздела темы, повторяющаяся или вне числового порядка. Нечитаемый YAML, пустые список или карта, или индекс без единого раздела темы — это CEGO, и он отклоняется. Каждое правило доказано мутацией в scripts/docs/temas-de-adr.spec.ts, как и у других проверяющих.

4. В предложенной таксономии 15 тем. Она выведена из НАПРАВЛЕНИЙ продукта — тех же, что организуют CLAUDE.md и каталог agent-areas.ts, — а не из фаз или папок кода:

idтемаADR
gitGit, repository and branch policy11
agentesAgent harness, turns and sessions11
timeThe agent team — roles, areas and handoffs26
gatesGates, QA and security review12
execucaoExecution, terminal policy and approvals13
modosWhere the code lives — execution modes9
containerProject container and broker15
runnerThe local runner11
iamAuth, access and secrets13
llmLLM providers, models and spend16
conhecimentoRAG, knowledge graph and artifacts11
webWeb UI and design system12
operacaoOperation, deploy and installation15
engenhariaCI, release and supply chain10
docsDocumentation7

Почему ИМЕННО этот список, и неочевидные границы:

  • agentes × time. agentes — это КАК работает агент (контекст, цикл инструментов, ход, сессия, очередь сообщений, язык ответа); time — это КАКИЕ агенты существуют и что они кому поставляют (роли, области, делегирование, handoff, Psicólogo и Anamnese). Вместе дали бы 37 ADR — меньший «Phase 12». Разговорный Infra Lead (0175) попадает в agentes, потому что решает свой ход; Dev Lead (0053) — в time, потому что решает роль.
  • modos × container × runner. Три направления, которые соприкасаются в каждом ADR начиная с 0104, и поэтому разделены по ВОПРОСУ: где живёт папка (modos), кто поднимает контейнер и с каким сдерживанием (container), CLI на машине пользователя (runner). Runner, поднимающий контейнер (0137), — это container; git с учётными данными на хосте runner (0193) — это runner.
  • execucao × gates. execucao — политика, удерживающая агента, который ДЕЙСТВУЕТ (proposed_action, область пути, автоматический режим, абсолютные потолки); gates — вердикт о том, что сделано.
  • operacao объединяет deploy и установку. Оба отвечают на «как продукт работает на машине, которая не принадлежит его разработчику», и делят backup и compose установки; раздельно у установки было бы 7 ADR и 16-я тема.
  • engenharia берёт то, что принадлежит РЕПОЗИТОРИЮ, а не продукту: конвейер, опубликованные образы, подпись, Trivy, pin по digest, слои тестов и разделение схемы по агрегатам (0121) — единственный структурный рефакторинг api, который ни в какой другой теме не искали бы. Разделения SessionPage.tsx/ProjectSettingsTab.tsx остаются в web, где их ищет тот, кто трогает эти файлы.
  • Язык — не тема (о нём решает только 0177, и он в agentes); безопасность — не тема: она пересекает iam (CSP, CORS, envelope), execucao (потолки), container (сдерживание broker) и engenharia (цепочка поставок), а тема «безопасность» опустошила бы четыре, чтобы наполнить одну.

От десяти до пятнадцати — запрошенный интервал: меньше десяти объединило бы modos/container/ runner или agentes/time, а именно там провалился индекс по фазам; больше пятнадцати превратило бы тему в папку.

5. Кто решает тему нового ADR: тот, кто его пишет, в том же PR — одна строка в adrs: и строка индекса в разделе темы, в числовом порядке. Тот, кто ревьюит PR, подтверждает. НОВАЯ тема — это изменение списка в temas.yml, обоснованное в PR, который её создаёт; выход за 15 требует ADR, пересматривающего этот.

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

  • У индекса больше нет разделов по фазам, и вместе с ними уходят вступительные фразы каждой фазы. Повествование по фазам остаётся там, где оно всегда было полным, в docs/explanation/historico-de-fases.md; предупреждение об открытом критерии приёмки ADR 0020/0021 уходит вместе с ними в gates.
  • Новый ADR стоит на одну строку больше (temas.yml), и её забвение ОТКЛОНЯЕТ docs:check — та же цена и та же причина, что у verificarIndiceAdr.
  • Тема — это КЛАССИФИКАЦИЯ, и многие ADR служат двум. Индекс показывает каждый один раз, в основной; тот, кто ищет по другой теме, его там не найдёт. Это цена «одной темы на ADR», и альтернатива (вторичная тема) была рассмотрена и не вошла: она дублировала бы курируемую строку или оставила бы её в двух местах, которые стареют по отдельности.
  • Параллельные ADR: сопоставление покрывает ADR, существовавшие в origin/dev на 2026-10-01 (с 0001 по 0197, плюс этот). Тот, кто интегрирует ADR, родившийся в другой ветке, добавляет его строку — docs:check указывает, какой не хватает.
  • Перевод индекса на pt-BR (website/i18n/pt-BR/.../adr/index.md) остаётся по ФАЗАМ и уже отставал (103 из 191 строки); здесь он не реорганизуется. Правило traducao-pt-br в docmap предупреждает, в warn, как всегда.

Чего этот ADR НЕ делает​

  • Не редактирует ни одного ADR, даже чтобы исправить заголовок.
  • Не генерирует индекс: фразы по-прежнему курируются вручную.
  • Не создаёт RN: правило документационное, как и правило процедур runbook.