# Образец `openspec/config.yaml` Каталог `openspec/` заводится командой — `openspec init --tools claude`, — и она кладёт `config.yaml` с закомментированным примером внутри. Пример **заменяется целиком**: нетронутый файл выглядит настроенным, а работает как пустой. **Это маршрутизатор, а не второй дом фактов.** Сюда пишут ровно то, что нужно **в момент порождения артефакта** и чего в этот момент ещё никто не открыл: язык, правила именования capability, придирки валидатора и **адреса** документов канона. Пересказ паспорта, инвариантов, конвенций и правил ревью сюда не переносится: расходится он молча, а замечают это в уже написанном предложении. ```yaml schema: spec-driven context: | Language: Russian Пиши на русском, но: - Структурные заголовки оставляй на английском: ## ADDED/MODIFIED/REMOVED Requirements, ### Requirement:, #### Scenario: - Ключевые слова GIVEN/WHEN/THEN и RFC 2119 (SHALL/MUST/SHOULD) — на английском - Технические термины, пути и код — на английском Имена capabilities: - Capability — это ПОВЕДЕНИЕ или домен системы, а не пакет кода (совпадение с именем пакета допустимо, но не критерий). - Существительное, понятное без знания кода: ingest, parsing, storage, read-api. НЕ store/httpapi — это реализация. - Гранулярность по принципу «требования меняются вместе». Дробить, когда в одной спеке смешиваются разные заботы. Переименовать дёшево (RENAMED Requirements) — не дроби преждевременно в маленьком проекте. RFC 2119 — требование валидатора, не стиль: - Каждое ### Requirement ОБЯЗАНО содержать литерал SHALL или MUST, иначе `openspec validate` падает. Поэтому эти слова и WHEN/THEN не русифицируем. Что это за проект — читай перед предложением, а не отсюда: - docs/passport.md — цель, её граница (чем проект НЕ является), потребители, типовые сценарии, референсы; - CLAUDE.md — инварианты с severity и семантика гейта; - docs/architecture.md — устройство; docs/security.md — периметр; docs/adr/ — почему решено так; docs/research/ — что уже измерено. Пересказа этих документов здесь нет намеренно: второй дом факта расходится с первым молча, и заметно это становится в предложении, которое уже написано. Ревью: состав проходов и глубину тем здесь не пересказываем — их дом скилл av-dev:code-review, проектная настройка — docs/review.md. Конвенции кода: механизированное проверяет гейт, прозой остаётся docs/conventions/. Ни состав шагов гейта, ни перечень конвенций здесь не пересказываем: и то и другое растёт по ходу задач. Развилка или блокер — сперва prior art. Готовые решения смотрим в референсах паспорта, отвергаем — с названной причиной, и причина идёт в design.md этого же изменения. rules: proposal: - Capabilities называй по поведению или домену системы, не по пакету кода - "Why и What Changes — языком домена из docs/passport.md: без SHALL, без имён модулей и функций там, где вещь называется по-русски" design: - "Назови рассмотренные варианты и причину отказа от каждого — из них потом пишется ADR" - "Решение объясняется через то, что человек увидит иначе, а не через устройство кода" specs: # Кавычки обязательны: без них YAML обрежет строку на первом '#'. - "Каждое ### Requirement обязано содержать SHALL или MUST (иначе валидация падает)" - "Сценарий — ровно #### (четыре решётки); три или список молча теряются" - "SHALL/MUST должно стоять в ПЕРВОМ абзаце требования: валидатор смотрит только его" - "Заголовки и WHEN/THEN/GIVEN — на английском, остальной текст на русском" tasks: - "Критерии приёмки задачи — отдельным блоком и дословно: файл задачи закрытие удалит, критерии обязаны его пережить" - "Шаг плана формулируется проверяемо — по нему видно «сделано / не сделано» без суждения" ``` **Четыре правила для `specs` сняты отказами валидатора, а не выведены из документации** — потому и записаны дословно: без них каждое второе предложение узнаёт их падением `openspec validate --strict`. **Правила для `proposal` и `design` держат чекпоинт скилла `av-dev:code-resolve`.** Там работа останавливается и человеку объясняют, в чём проблема и как её решают, — а объяснение **собирается из этих двух артефактов**, а не сочиняется заново: третий пересказ одного и того же разошёлся бы с обоими. Требование поэтому стоит здесь, в момент порождения артефакта, а не в скилле, который спохватится позже. `design.md` при этом ещё и **сырьё для ADR** — отвергнутый вариант с названной причиной и есть половина будущей записи. **Правила для `tasks` держит тот же скилл, и по той же причине — момент порождения.** `tasks.md` — единственное, что переживает задачу: файл задачи закрытие удаляет, а приёмка потом судится по критериям, которые в него скопированы. Записанное в момент порождения не приходится вспоминать шагом позже, когда артефакт уже написан. Блок `context` проект дополняет своим (стек, разведка, особенности домена), но **адреса паспорта и `CLAUDE.md` обязательны** — отсутствие адреса к существующему документу `openspec.py check` называет отказом. **Ключи под `rules:` — имена артефактов схемы**, а не свободные слова: `proposal`, `specs`, `design`, `tasks`. Правило под чужим именем не применяется и об этом не сообщает, поэтому `rules.spec` вместо `rules.specs` даёт конфиг, выглядящий написанным и не работающий; `openspec.py check` такой ключ называет. Перечень артефактов задаёт OpenSpec, а не мы, — за его актуальностью следит `openspec.py form`.