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:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: doc-consistency
|
||||
description: "Сверка документов канона между собой и с openspec: один факт, живущий в двух домах, прямое противоречие между документами (периметр, зависимости, обратимость), поведение системы, осевшее в architecture.md вместо спек, capability без обзора или с пересказом требований, число без провенанса в research, ADR без ссылки на архивный design.md и без парного статуса при замене, заглушка вместо честной строки в пустом слоте. Читает docs/ и openspec/, кода не читает. Отдаёт готовые формулировки и ничего не правит сам. Соответствие документов коду смотрит агент doc-code-drift, язык — doc-wording. Зовётся скиллом av-dev-docs:healthcheck — на весь канон разом; он же зовётся шагом adopt и шагом upgrade. На отдельной задаче и на синке документации не звать. Только чтение."
|
||||
description: "Сверка документов канона между собой и с openspec: один факт, живущий в двух домах, прямое противоречие между документами (периметр, зависимости, обратимость), поведение системы, осевшее в architecture.md вместо спек, capability без обзора или с пересказом требований, число без провенанса в research, ADR без ссылки на источник (архивный design.md либо записка разведки) и без парного статуса при замене, заглушка вместо честной строки в пустом слоте. Читает docs/ и openspec/, кода не читает. Отдаёт готовые формулировки и ничего не правит сам. Соответствие документов коду смотрит агент doc-code-drift, язык — doc-wording. Зовётся скиллом av-dev-docs:healthcheck — на весь канон разом; он же зовётся шагом adopt и шагом upgrade. На отдельной задаче и на синке документации не звать. Только чтение."
|
||||
tools: Read, Grep, Glob
|
||||
model: opus
|
||||
color: yellow
|
||||
@@ -23,7 +23,7 @@ color: yellow
|
||||
| Факт | Дом |
|
||||
| --- | --- |
|
||||
| поведение системы | `openspec/specs/<capability>/spec.md` |
|
||||
| почему решено так | `adr/`, источник — архивный `design.md` |
|
||||
| почему решено так | `adr/`, источник — архивный `design.md` либо записка разведки |
|
||||
| граница домена, «чем не является» | `passport.md` |
|
||||
| инвариант и его severity | `CLAUDE.md` |
|
||||
| что приложение умеет и чего не умеет; порядок работ | `tasks/ROADMAP.md` |
|
||||
@@ -50,7 +50,10 @@ color: yellow
|
||||
`docs/tasks/` на непереехавшем проекте), принадлежит другому плагину и ведётся
|
||||
своим скриптом; не открывай его ни в той форме, ни в другой. Плюс
|
||||
`openspec/changes/archive/`, когда проверяешь ADR: там лежат `design.md`, из
|
||||
которых записи промоутятся.
|
||||
которых записи промоутятся. **Источник у ADR бывает и второй — записка
|
||||
разведки**: решение, принятое без изменения (намеренный отказ, выбор подхода),
|
||||
`design.md` не имеет по построению. Запись без ссылки **на любой из двух** —
|
||||
находка; запись со ссылкой на записку — нет.
|
||||
|
||||
**Кода ты не читаешь.** Разошёлся ли документ с кодом — вопрос агента
|
||||
`doc-code-drift`, и у него для этого другой вход и другая цена.
|
||||
|
||||
@@ -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` |
|
||||
|
||||
@@ -20,6 +20,44 @@ upgrade` идёт по записям снизу вверх от версии п
|
||||
|
||||
---
|
||||
|
||||
## Версия 14 — 2026-08-11
|
||||
|
||||
У ADR стало два законных источника. Прежде запись цитировала только архивный
|
||||
`design.md`, то есть решение, принятое по ходу изменения. Решение, принятое
|
||||
**разведкой** — намеренный отказ, выбор подхода, «проверили и не делаем», — не
|
||||
имеет `design.md` по построению: change по нему не заводится никогда. Триггер
|
||||
канона такое решение ловит («намеренный отказ от очевидного подхода»), а дома у
|
||||
него не было, и оно оседало в записке разведки или в переписке.
|
||||
|
||||
**Что изменилось.** `adr/` принимает второй источник — записку разведки. Правило
|
||||
«промоут, а не второе сочинение» не тронуто: запись по-прежнему цитирует уже
|
||||
написанное и **называет источник**, изменилось только то, что источников два.
|
||||
Следом сказали то же самое: карта домов, разрез проверки `doc-consistency`, вход
|
||||
и устав самого агента, скелеты `docs/adr/README.md` и `docs/adr/template.md`.
|
||||
|
||||
**Почему это версия, а не правка текста.** Два следствия уезжают в репозиторий
|
||||
проекта. По карте домов судит агент согласованности — прежняя редакция читала ADR
|
||||
со ссылкой на записку разведки как нарушение; а скелеты `adr/` лежат в проекте
|
||||
файлами и говорят там от имени канона.
|
||||
|
||||
**Что сделать проекту.**
|
||||
|
||||
1. Ничего с существующими записями: прежние ADR ссылаются на `design.md`, и это
|
||||
по-прежнему верно.
|
||||
2. **Поднять шапку `docs/adr/README.md`**: «промоут поверх архивного `design.md`»
|
||||
→ «промоут поверх уже написанного», с обоими источниками. Точный текст — в
|
||||
[skeletons.md](skeletons.md), раздел `docs/adr/README.md`.
|
||||
3. **Поднять `docs/adr/template.md`**: строка `- **Источник:**` называет два
|
||||
возможных источника.
|
||||
4. `docs/.docs.json`: `"canon": 14`.
|
||||
|
||||
**Чего делать не надо.** Заводить ADR задним числом по старым разведкам. Запись
|
||||
заводится, когда решение принимается, а не когда о нём вспомнили: сочинённое
|
||||
через полгода обоснование — ровно то «второе сочинение», против которого правило
|
||||
и написано.
|
||||
|
||||
---
|
||||
|
||||
## Версия 13 — 2026-08-11
|
||||
|
||||
Служебный файл канона переименован: `docs/.pm.json` → `docs/.docs.json`. Имя
|
||||
|
||||
@@ -200,9 +200,10 @@
|
||||
```markdown
|
||||
# Журнал решений
|
||||
|
||||
Одна запись — одно решение. **ADR это промоут поверх архивного `design.md`**,
|
||||
а не второе сочинение: запись цитирует решение и ссылается на
|
||||
`openspec/changes/archive/<id>/design.md`.
|
||||
Одна запись — одно решение. **ADR это промоут поверх уже написанного**, а не
|
||||
второе сочинение: запись цитирует решение и ссылается на источник —
|
||||
`openspec/changes/archive/<id>/design.md`, а у решения, принятого разведкой без
|
||||
изменения, на её записку.
|
||||
|
||||
## Когда заводить
|
||||
|
||||
@@ -241,7 +242,8 @@
|
||||
# Краткий заголовок решения
|
||||
|
||||
- **Дата:** ГГГГ-ММ-ДД
|
||||
- **Источник:** openspec/changes/archive/<id>/design.md
|
||||
- **Источник:** openspec/changes/archive/<id>/design.md — либо записка разведки,
|
||||
если решение принято без изменения
|
||||
|
||||
Статус ставится тем же полем и только при пересмотре:
|
||||
`- **Статус:** заменено на ADR-…` либо `- **Статус:** устарело`.
|
||||
|
||||
@@ -25,7 +25,7 @@ from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
from typing import NoReturn
|
||||
|
||||
CANON_VERSION = 13
|
||||
CANON_VERSION = 14
|
||||
|
||||
OK, DRIFT, USAGE, ENV, INTERNAL = 0, 1, 2, 3, 4
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: docs
|
||||
description: Вести содержимое документов канона по ходу разработки — синк после сделанной задачи с построчным отчётом по каждому документу, заведение ADR промоутом из архивного design.md, запись наблюдения в research, запись дефекта и настройки конвейера в review.md, чистка architecture.md от поведения с маркерами долга. Использовать, когда задача сделана и надо обновить документацию, когда просят завести ADR или записать решение, занести находку о внешних данных, записать проскочивший дефект, разгрузить разросшуюся архитектуру. Раскладку и соответствие канону проверяет скилл canon.
|
||||
description: Вести содержимое документов канона по ходу разработки — синк после сделанной задачи с построчным отчётом по каждому документу, заведение ADR промоутом из архивного design.md или из записки разведки, запись наблюдения в research, запись дефекта и настройки конвейера в review.md, чистка architecture.md от поведения с маркерами долга. Использовать, когда задача сделана и надо обновить документацию, когда просят завести ADR или записать решение, занести находку о внешних данных, записать проскочивший дефект, разгрузить разросшуюся архитектуру. Раскладку и соответствие канону проверяет скилл canon.
|
||||
---
|
||||
|
||||
# Ведение содержимого канона
|
||||
@@ -97,6 +97,13 @@ description: Вести содержимое документов канона
|
||||
**ADR цитирует решение оттуда и ссылается на источник.** Не пересказывает и не
|
||||
сочиняет заново.
|
||||
|
||||
**Второй законный источник — записка разведки**, и приходит он от скилла
|
||||
`av-dev-code:research`: решение, принятое разведкой (намеренный отказ, выбор
|
||||
подхода, «проверили и не делаем»), `design.md` не имеет по построению — change по
|
||||
нему не будет никогда. Промоут при этом тот же: цитата и ссылка, но на записку.
|
||||
Перечень источников закрыт и живёт в [каноне](../canon/references/canon.md),
|
||||
раздел `adr/`.
|
||||
|
||||
**Триггер заведения, форма имени и правило замены — в
|
||||
[каноне](../canon/references/canon.md), раздел `adr/`.** Здесь они не
|
||||
повторяются: копия правила расходится с оригиналом на первой же смене версии
|
||||
@@ -106,9 +113,9 @@ description: Вести содержимое документов канона
|
||||
нет**. Строка «adr/ — не требуется: решение рутинное» и есть то, ради чего
|
||||
чек-лист существует; её отсутствие неотличимо от «забыл посмотреть».
|
||||
|
||||
Порядок работы: открой архивный `design.md` change, найди в `Decisions` то, что
|
||||
проходит триггер, процитируй решение и его причину, сошлись на источник, добавь
|
||||
строку в индекс `docs/adr/README.md` сверху.
|
||||
Порядок работы: открой источник — архивный `design.md` change либо записку
|
||||
разведки, — найди в нём решение, проходящее триггер, процитируй его и причину,
|
||||
сошлись на источник, добавь строку в индекс `docs/adr/README.md` сверху.
|
||||
|
||||
## Чистка `architecture.md`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user