resolve: два сценария вместо одной цепочки — разведка и решение

Разведка была прологом к коду: три шага, чекпоинт вариантов — и вливание в
общую ветку. Своего исхода у неё не было, поэтому и писать в документы проекта
ей было незачем: ответ оседал в design.md будущего change.

- у разведки появился исход: ответ уезжает в документы канона, задачи заводятся
  и уточняются, написанное коммитится, запись закрывается. Кода сценарий не
  пишет вовсе, OpenSpec ему не нужен
- точка входа осталась одна, и сценарий выбирает скилл, прочитав постановку:
  «есть ли очевидный способ решения» видно после чтения записи, и требовать
  этого суждения от вызывающего значит требовать его раньше, чем оно возможно
- оба сценария лежат справочниками и одинаково — solve.md и research.md, — а в
  SKILL.md остались вход, развилка и правила, не зависящие от сценария.
  Асимметрия читалась бы как старшинство: сценарий в теле скилла выглядит
  основным, а в справочнике — оговоркой
- переход между сценариями — событие с названным исходом: решение, упёршееся в
  незнание способа, останавливается; разведка, выбравшая способ, доводится до
  конца, а код идёт следующим прогоном, который запускает человек
- канон 14: у ADR два законных источника. У решения, принятого разведкой,
  design.md нет по построению, и такое решение либо не попадало в adr/ вовсе,
  либо попадало сочинённым заново

Правки по своему же ревью, до коммита:

- версия 14 была неполной — разрез проверки, вход и устав doc-consistency,
  скелеты adr/README.md и template.md по-прежнему требовали ссылку на
  design.md. Агент краснел бы на законной записи; скелеты уезжают в проекты,
  поэтому запись журнала называет их поимённо
- canon.md объявлял себя двенадцатым, пережив версию 13. Литерал был третьим
  домом числа при двух исправных — убран, а не поправлен
- сценарий разведки был недостижим там, где обещал работать: ready требует у
  research оба раздела, включая «Куда ляжет ответ», а сценарий брался назначить
  адрес сам. Адрес назначает автор записи; сценарий — только когда записи нет
- разведка коммитила без гейта, хотя правит документы канона и индексы задач
- при переносе выпало предупреждение про закрытие разведки без записанного
  ответа — возвращено
This commit is contained in:
av
2026-08-11 11:36:37 +03:00
parent 863769406f
commit b8120d3271
15 changed files with 1073 additions and 526 deletions
+19 -6
View File
@@ -1,6 +1,10 @@
# Канон документов проекта
**Версия 12.**
**Номер версии здесь не стоит намеренно.** Этот файл описывает канон таким, какой
он сейчас, а число живёт в двух домах, которые не расходятся: константа в
`docs.py` (её печатает `docs.py version`) и верхняя запись
[журнала](changelog.md). Литерал в шапке был третьим и отстал на первом же
повышении — версию 13 он пережил, объявляя канон двенадцатым.
Это **единственный дом определения канона**. Скиллы `init`, `canon` и `docs`
читают его, а не пересказывают: три описания одной раскладки разъедутся, и
@@ -141,7 +145,7 @@ openspec/
**Процессный документ — не документ второго сорта.** `adr/` и `research/`
проверяются наравне с остальными, но **сверкой документации**, а не прогоном
ревью: ADR без ссылки на архивный `design.md`, замена без парного статуса, число
ревью: ADR без ссылки на источник, замена без парного статуса, число
без провенанса — это работа агентов `doc-consistency` и `doc-code-drift`, и она
осталась там же, где была. Изменилось одно: прогон ревью не открывает их как
критерий и не судит по ним изменение.
@@ -291,8 +295,17 @@ kebab-case.** Причина не эстетическая: имя файла с
### `adr/`
**ADR — промоут поверх архивных `design.md`, а не второе сочинение.** Запись
цитирует решение и ссылается на `openspec/changes/archive/<id>/design.md`.
**ADR — промоут поверх уже написанного, а не второе сочинение.** Запись цитирует
решение и ссылается на источник. Источников два, и оба законны:
- **архивный `design.md`** — решение принято по ходу изменения:
`openspec/changes/archive/<id>/design.md`. Обычный случай;
- **записка разведки** — решение принято разведкой, и change по нему не будет
никогда: намеренный отказ, выбор подхода, «проверили и не делаем». У такой
работы нет `design.md` по построению, и без второго источника её решение либо
не попадало в `adr/` вовсе, либо попадало сочинённым заново.
Источник называется в записи всегда — по нему видно, чем решение подтверждено.
Заводится, когда верно одно из трёх:
@@ -458,7 +471,7 @@ kebab-case.** Причина не эстетическая: имя файла с
| Факт | Дом |
| --- | --- |
| поведение системы | `openspec/specs/<capability>/spec.md` |
| почему решено так | `adr/`, источник — архивный `design.md` |
| почему решено так | `adr/`, источник — архивный `design.md` либо записка разведки |
| граница домена, «чем не является» | `passport.md` |
| инвариант и его severity | `CLAUDE.md` |
| что приложение умеет и чего не умеет; порядок работ | `tasks/ROADMAP.md` |
@@ -513,7 +526,7 @@ kebab-case.** Причина не эстетическая: имя файла с
| имя файла не kebab-case латиницей; форма имени ADR | транслит в имени — сверх эвристики | `doc-wording` |
| битые относительные ссылки | прямое противоречие между документами | `doc-consistency` |
| версия канона и её отставание | достаточность честной строки в пустом слоте | `doc-consistency` |
| нетронутый плейсхолдер шаблона | ADR без ссылки на `design.md`, замена без парного статуса | `doc-consistency` |
| нетронутый плейсхолдер шаблона | ADR без ссылки на источник, замена без парного статуса | `doc-consistency` |
| маркеры долга — числом | **протухший факт, разошедшийся с кодом** | `doc-code-drift` |
| миграция изменена, а `database.md` нет | зависимость в манифесте, не названная в обзоре | `doc-code-drift` |
| capability без упоминания в `architecture.md` | второй способ там, где обзор обещал единственный | `doc-code-drift` |