Files
dev-skills/av-dev-pipeline/skills/review-pipeline/references/project-facts.md
T
avandClaude Opus 5 00ddfb0dde av-dev-pm расколот на av-dev-docs и av-dev-tasks
Плагин владел двумя разными вещами сразу — документацией проекта и учётом работ,
— и это мешало обеим. Канон нельзя было поставить без задач, задачи без канона, а
язык проектных текстов лежал внутри скилла canon и потому принадлежал половине.
Теперь плагина два, каждый ставится сам по себе.

av-dev-docs: скиллы canon, docs, init; агенты doc-consistency, doc-code-drift,
doc-wording; скрипт docs.py. av-dev-tasks: скиллы tasks, session; агенты
task-form, task-wording; скрипт tasks.py.

Между собой они зовутся через пространство имён, а не по пути в чужое дерево.
Все относительные ссылки, пересекшие границу плагина, сняты: tasks больше не
указывает в canon, canon не указывает в tasks. Вместо ссылки — имя скилла и
оговорка, что вызов может не разрешиться, и это исход, а не поломка.

То, что нужно обоим дословно, стало вторым общим домом. Словарь «Сопровождение и
эксплуатация» назван в трёх местах трёх плагинов — секция роадмапа, раздел
«Эксплуатация» в architecture.md, тема ревью operations — и ни один из трёх им не
владеет; он уехал в shared/operations.md, а canon.md и скилл задач везут копии.
Три перечня «чем держат проект» уже разъезжались на «метриках и логах» против
«мониторинга», так что ссылка тут не годится: плагин, поставленный в одиночку,
получил бы указатель в никуда. Тем же способом язык: у av-dev-tasks появилась
своя копия language.md.

Копий стало 18 при 8 домах.

Переименования разведены по смыслу, а не заменой строки: где речь о каноне —
av-dev-docs, где об учёте задач — av-dev-tasks. В пайплайне таких мест
одиннадцать, и оба адресата там встречаются вперемешку.

Журналы (DECISIONS, TODO, HISTORY) намеренно не тронуты: они описывают состояние
на момент записи. По той же причине оставлена наблюдённая строка в комментарии
docs.py — она цитирует конфиг живого проекта, а не называет плагин.

Не входит в этот заход и названо отдельно: слияние canon и docs в один скилл,
разделение docs/.pm.json на два конфига и переезд openspec в пайплайн.

Гейт зелёный: копии, фронтматтеры, диаграммы, json. Оба скрипта прогнаны после
переезда — docs.py version и tasks.py check на фикстуре.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 14:06:26 +03:00

138 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Откуда проход берёт проектную конкретику
Конвейер общий, находки — проектные. Проход, не знающий, что в этом проекте
нельзя нарушать, чем краснеет гейт и сколько данных реально идёт через узел,
выдаёт правдоподобные общие места: их дорого опровергать и нечем подтверждать.
Отдельного файла-брифа **нет**. Проектная конкретика живёт в документах канона
`av-dev-docs`, и проход читает их напрямую: пути жёсткие, посредник не нужен, а
второй дом для тех же фактов разошёлся бы и выглядел актуальным.
Определение канона — в плагине `av-dev-docs`,
`skills/canon/references/canon.md`. Здесь только карта «тема → её дом → что
оттуда берётся».
## Карта тем
**Дом бывает файлом или каталогом**`docs/security.md` и `docs/security/`
называют одну и ту же тему. Форму дома называет план разметки задачи; проход её не
угадывает.
| Тема | Дом | Что оттуда берётся |
| --- | --- | --- |
| `requirements` | `openspec/specs/`, `openspec/changes/<id>/specs/` | нормативное поведение и дельты изменения |
| `autotests` | `CLAUDE.md`, семантика гейта | команда гейта, чем краснеет безусловно, чего в нём нет, кто гоняет дорогое |
| `conventions` | `docs/conventions.*` | конвенции прозой и **что уже механизировано** правилом |
| `architecture` | `docs/architecture.*` | компоненты и capability, единые точки проекта |
| | источник `docs/passport.*` | что система делает и **чего не делает**, граница домена |
| `security` | `docs/security.*` | периметр, недоверенный вход, из чего строятся пути и ключи, что вне модели |
| `operations` | `docs/architecture.*`, раздел эксплуатации | окружение, внешние зависимости поимённо, наблюдатель, характер потока |
| | источник `docs/database.*` | чем физически лежит запись, что при чтении и записи, настройки с числовым значением |
| *тема проекта* | её **свой** документ в `docs/` | то, что проект счёл нужным записать |
**`docs/adr.*` и `docs/research.*` в этой карте нет намеренно.** Они процессные
документы: прогон ревью их не открывает. Раньше первый питал тему `architecture`,
второй — `operations` и `requirements`; обе строки убраны, и цена этого названа в
`SKILL.md`, раздел «Честный предел».
**Дом темы зависит ещё и от метки.** На `small` темы `security`, `operations` и
`architecture` смотрятся не против домов из этой таблицы, а против **инвариантов
`CLAUDE.md`**, и закрывает их `code`. Таблица описывает полный дом темы; сколько
из него открыто на этом прогоне, говорит план разметки задачи.
Сквозное, не привязанное к теме:
| Что нужно проходу | Где лежит |
| --- | --- |
| инварианты **с severity рядом с формулировкой** | `CLAUDE.md``AGENTS.md`, если он рядом), раздел инвариантов |
| что запускать запрещено, с путями; `testdata`; куда писать временное; имя основной ветки | `CLAUDE.md` |
| типовые узлы, типовые ложноположительные, **вопросы по темам**, триггеры метки, недоступно проверке | `docs/review.*`, раздел настройки |
| прецеденты: воспроизведённые дефекты с оракулом | `docs/review.*`, журнал |
**Вопросы проекта привязаны к теме, а не к имени прохода.** Раньше блок в
`docs/review.md` адресовался поимённо (`ops: <вопрос>`), и когда проход уехал в
старшую метку, вопрос перестал задаваться молча. Тема переезд прохода
переживает.
## Сшивать обязаны проходы
Раньше эти факты лежали рядом в одном файле, и соседство работало само. Теперь
они разложены по домам, и **проход обязан собрать их сам** — иначе снимет верное
число и честно понизит находку до гипотезы, потому что сравнить будет не с чем.
Два обязательных стыка:
- **замер + настройка.** «Пик 768 МиБ» — аномалия только рядом со строкой
«запись лежит сжатой и распаковывается целиком»; «блокировка удерживалась
5.019 с» — гарантированный отказ соседа только рядом с известным таймаутом
занятости. **Число проход снимает сам, на этом прогоне**, настройки берёт из
`docs/database.md`, и сшивают их `ops` и `adversary`. Раньше числа брались из
`docs/research/`; теперь этот документ процессный, и замер неизвестной свежести
больше не выдаёт себя за оракул.
- **инвариант + обратимость.** severity берётся из `CLAUDE.md`; если её там
нет — она **выводится по обратимости последствия** и помечается «выведена по
обратимости», а не выдаётся за решение проекта.
**У `basics` стыков нет, и это не упущение.** Он не меряет, поэтому сшивать число
с настройкой ему нечего; единственное его основание для `critical` — инвариант из
`CLAUDE.md`, всё остальное он формулирует условиями и оставляет гипотезой. Его
вход намеренно узкий: дома тем из плана плюс инварианты и журнал. Широкий вход —
это метка `large`, и там он есть у `architecture`. Греп по базе ему разрешён
точечный — «есть ли второй вызывающий», — но обход всей базы и инвентарь
концепций не его работа.
**У `scope` стыков нет по другой причине: он не читает содержимого.** Его дело —
найти дома и раздать темы, а не пересказать написанное. Пересказ сделал бы его
посредником между документом и проходом, а посредник расходится с источником и при
этом выглядит актуальным.
## Деградация — поразрядная
Документа нет — деградирует то, что из него читалось, и **только оно**. Каждый
проход пишет **свою** строку в границы покрытия; триаж собирает их в один
список и **не сливает в одну строку**: разные пробелы чинятся разным — периметр
пишется руками за десять минут, а числа требуют замера.
**Кто какой документ читает — из документа не выводится, а назначается планом.**
Документ питает тему (это записано на стороне канона, таблица «Роли документов и
темы ревью»), а тему на этом прогоне закрывает тот, кого назвала разметка задачи; вся
раскладка «тема → проход → глубина» — в `SKILL.md` этого скилла и больше нигде.
**Списка читателей не ведёт никто, и это не пробел.** Он жил бы на стороне
канона, а документ живёт дольше, чем раскладка проходов: список разошёлся бы с
конвейером молча и при этом выглядел актуальным. Однажды уже разошёлся.
Ниже — только **последствие** отсутствия дома, и оно называет самое дорогое, а не
всех пострадавших.
| Нет дома | Что деградирует |
| --- | --- |
| `CLAUDE.md` без инвариантов | `critical` по основанию «нарушен инвариант проекта» не присваивается никем |
| `docs/security.*` | тема `security` остаётся без дома: вопросы задаются по коду, `critical` не ставится, периметр неизвестен |
| `docs/database.*` | замер не с чем сравнить: находка темы `operations` не поднимается выше гипотезы |
| `docs/passport.*` | тема `architecture` теряет границу домена и вырождается в общее мнение |
| `docs/review.*` | `triage` отсеивает вслепую: типовых ложноположительных нет; вопросы проекта по темам не задаются |
| `docs/conventions.*` | вторая половина `code` идёт вхолостую: записанных конвенций нет |
| `docs/architecture.*` | «не появился ли второй способ» не проверяется — единых точек не знает никто; тема `operations` теряет перечень внешних зависимостей |
Строка в границах покрытия обязана называть **причину**: «`docs/security.md` в
проекте нет» читается иначе, чем «есть, но периметр не назван». Без причины
строка неотличима от «мы просто не стали» и перестаёт читаться на третьей задаче.
**Документов канона нет вовсе** — проект не приведён к канону. Это не повод
работать вслепую: скажи об этом строкой и предложи `av-dev-docs:canon`. Одна
операция на проект против деградации на каждой задаче.
## Правило чтения
- **Читай в источнике, не по памяти.** Документы правятся по ходу работы, в том
числе этой же задачей.
- **Число без провенанса — условие, а не утверждение.** Число, чей источник по
ссылке не подтвердился, читается как условие и **называется расходящимся**, а
не подменяется догадкой.
- **Пустое, названное пустым, — это факт.** «Внешних зависимостей нет — смотри
на диск и на СУБД» экономит обязательный вопрос. Отсутствие строки — не факт,
а пробел, и его надо назвать в границах покрытия.
- **Свойство, ставшее правилом линтера, из конвенций удалено** и лежит в
перечне механизированного в `docs/conventions/README.md`. Проверять его
проходом — тратить внимание на уже проверенное.