--- name: docs description: Вести содержимое документов канона по ходу разработки — синк после сделанной задачи с построчным отчётом по каждому документу, заведение ADR промоутом из архивного design.md, запись наблюдения в research, запись дефекта и настройки конвейера в review.md, чистка architecture.md от поведения с маркерами долга. Использовать, когда задача сделана и надо обновить документацию, когда просят завести ADR или записать решение, занести находку о внешних данных, записать проскочивший дефект, разгрузить разросшуюся архитектуру. Раскладку и соответствие канону проверяет скилл canon. --- # Ведение содержимого канона Скилл владеет **содержимым** документов канона; раскладкой владеет `canon`. Определение канона и роли документов — [канон](../canon/references/canon.md), здесь не пересказывается. Главный вызывающий — **шаг синка документации в пайплайне задачи**. Пайплайн живёт в другом плагине и зовёт этот скилл по имени; проект без пайплайна ведёт документацию тем же скиллом вручную. ## Правило, из которого всё следует **Принуждённое отрицание.** Синк обязан назвать **каждый** документ канона: либо чем он обновлён, либо «не требуется, потому что…». Нетронутые группируются одной строкой с общей причиной. Причина, по которой правило именно такое, измерена: у ADR был список триггеров прозой — и он дал **6 записей на 43 изменения**. Прозаический триггер, который некому проверить, не срабатывает. Отличить «не написал» от «написал, что не требуется» можно только тогда, когда отрицание обязательно. Это тот же приём, что «границы покрытия» в отчёте ревью и «пустое называется пустым» в каноне. ## Чек-лист синка Идёт сверху вниз; каждая строка попадает в доклад. | Документ | Обновляется, когда | Проверка | | --- | --- | --- | | `openspec/specs/` | всегда при изменении поведения | вливает `opsx:archive` | | `database.md` | тронуты миграции | `docs.py check --base` | | `architecture.md` | новый компонент, граница, внешняя зависимость, изменилось окружение | `docs.py`: capability без упоминания | | `adr/` | дорогой откат, намеренный отказ, пересмотр прежнего | нет — только этот чек-лист | | `research/` | узнали новое о внешнем формате или данных | нет | | `security.md` | новый недоверенный вход, токен, путь наружу, сдвиг периметра | нет | | `conventions/` | находка принята и не специфична для одного места | промоут | | `review.md` | дефект воспроизведён; сузили или расширили проверку | нет | | `passport.md` | новый потребитель, сдвиг границы «чем не является» | нет | | `CLAUDE.md` | изменился инвариант, гейт, запрет, необратимое | нет | Пример доклада: ``` Синк документации: - architecture.md — добавлен воркер свёртки, ссылка на capability reindex - database.md — миграция 00006, таблица bucket - adr/ — заведён ADR-2026-08-03-queue-as-table: отказ от внешней очереди - research/ — новое о формате не узнано - passport, security, conventions, review — не требуется: изменение внутреннее ``` ## Сверка — не здесь, а на сессии Синк правит документы поодиночке, а расходятся они **между собой**: факт, дописанный в `architecture.md`, уже живёт в `CLAUDE.md`; периметр в `security.md` не знает про новый эндпоинт. Поймать это на своей же правке нельзя, и судит это агент `doc-consistency`. **Но синк его не зовёт.** Оба судьи документов — `doc-consistency` и `doc-code-drift` — зовутся раз в спринт, шагом сессии, на весь канон разом. Причина в цене: агент на `opus` по каждой сделанной задаче — самая дорогая церемония процесса. К тому же расхождение между двумя документами по определению требует двух документов, а на большинстве задач синк правит один. Что теряется: привязка находки к задаче, которая её породила. Что выигрывается, кроме денег: синк перестаёт отбирать пачку, и в неё попадают документы, которых работа не касалась, — расхождение, внесённое правкой в одном месте, там и живёт. ## ADR — промоут, а не второе сочинение Обоснование уже написано: `opsx:propose` кладёт `design.md` в каждый change, и после архивации он лежит в `openspec/changes/archive//design.md` с разделами `Context` / `Goals / Non-Goals` / `Decisions` / `Risks / Trade-offs`. **ADR цитирует решение оттуда и ссылается на источник.** Не пересказывает и не сочиняет заново. **Триггер заведения, форма имени и правило замены — в [каноне](../canon/references/canon.md), раздел `adr/`.** Здесь они не повторяются: копия правила расходится с оригиналом на первой же смене версии канона, а расходится незаметно. Твоя часть — **применить триггер к этой задаче и сказать вслух, сработал он или нет**. Строка «adr/ — не требуется: решение рутинное» и есть то, ради чего чек-лист существует; её отсутствие неотличимо от «забыл посмотреть». Порядок работы: открой архивный `design.md` change, найди в `Decisions` то, что проходит триггер, процитируй решение и его причину, сошлись на источник, добавь строку в индекс `docs/adr/README.md` сверху. ## Чистка `architecture.md` Обзор не держит поведение — его нормативный дом `openspec/specs/`. **Форма маркера долга и правило «гейт от них не краснеет» — в [каноне](../canon/references/canon.md), раздел `architecture.md`.** Разбирается порциями: раздел вычищает та задача, которая его касается. Содержимое не выбрасывается, а переезжает — требования в дельта-спеку change, обоснование в ADR, обзор остаётся строкой со ссылкой на capability. ## Запись в `research/` Наблюдение о внешнем мире: что реально шлёт источник, чем документация формата расходится с практикой. **Требование провенанса и правило про расходящееся число — в [каноне](../canon/references/canon.md), раздел `research/`.** Твоя часть — заметить, что по ходу задачи узналось новое о внешних данных, и не дать этому остаться в контексте. Признак: ты правил разбор, опираясь на то, чего нет ни в одном документе. ## Запись в `review.md` Файл держит два раздела с разными сроками жизни — журнал дефектов и настройку конвейера. **Что в каком и в какой форме — в [каноне](../canon/references/canon.md), раздел `review.md`**; подробности формы записи и выбор адреса, куда она ведёт, — у конвейера ревью проекта (при `av-dev-pipeline` — `Skill av-dev-pipeline:review-pipeline`, его `references/review-journal.md`). **Конвейера в проекте нет** — пиши по форме из скелета `review.md`, которую положил канон, и скажи в докладе, что подробностей формы взять негде. Твоя часть на синке: **дефект пишется сразу**, а не «потом, когда починим». Со временем теряется не факт, а то, почему дефект не поймали, — единственное, ради чего журнал есть. И решение сузить проверки (перестали звать проход, понизили профиль) обязано попасть в раздел настройки, а не остаться в отчёте ревью. ## Промоут в конвенции Находка → конвенция → правило линтера → **удаление из прозы**. Процедура целиком принадлежит конвейеру ревью проекта (при `av-dev-pipeline` — его `references/promote.md`, читается через `Skill av-dev-pipeline:review-pipeline`); роль каталога конвенций — в [каноне](../canon/references/canon.md). **Конвейера нет** — три шага всё равно твои, просто без его процедуры: сформулируй правило, поищи, чем оно механизируется, и вычеркни прозу, если механизировалось. Твоя часть — **третий шаг, который пропускают чаще всего**: правило заработало, а формулировка осталась в прозе, и проход продолжает проверять уже проверенное. На синке это отдельная строка: «conventions/ — правило X механизировано, формулировка удалена» либо «не требуется». ## Чего этот скилл не делает - **Не проверяет раскладку** — это `canon`. - **Не заводит недостающие документы** — их скелет кладёт `canon adopt` или `init`. - **Не сочиняет содержание.** Нечего записать — так и пишется, честной строкой. - **Не переоформляет документы «заодно»**: правится то, чего коснулась работа.