# Engineering governance ## Назначение Этот документ — единственный источник устойчивой инженерной policy WealthLedger. Он определяет, как планировать и проверять изменения, но не хранит требования, design или tasks конкретного change. Нормативные change-specific артефакты находятся только в canonical OpenSpec store `wealth-ledger-specs` (`specs/openspec`). ## Термины **Change Owner** — человек, который принимает текущий planning artifact и разрешает переход к следующему. Для продуктового поведения это Product Owner, для технического или процессного изменения — Engineering Owner. **Delivery Map** — решение по каждой области `frontend`, `backend`, `specs` и `docs`: `affected` с ожидаемым результатом либо `N/A` с конкретной проверяемой причиной. **Completion Evidence** — созданная после реализации и archive запись о фактической поставке: Delivery Map, archive path, commits изменённых репозиториев, точные verification commands с наблюдёнными результатами и итог independent read-only review. **Enforceable Engineering Invariant** — обязательное правило с детерминированной non-mutating локальной проверкой, нарушение которой блокирует завершение change. Непроверяемое предпочтение является guidance, а не hard guardrail. **Planning structural gate** — stage-aware проверка доступной формы и ссылочной целостности текущего planning artifact до запроса approval. Она не оценивает качество rationale и не является semantic approval. ## Последовательность SDD Каждый versioned change проходит один граф: ```text Proposal → Delta Specs → Design → Tasks → Apply → Verify → Archive ``` - Proposal формулирует намерение, границы и ожидаемый результат без технологий, API, файлов и зависимостей. - Delta Specs описывают изменение наблюдаемого поведения и инвариантов без изменений кода. - Design объясняет архитектурный способ реализации крупными частями, риски и альтернативы; он не является построчной инструкцией. - Tasks — implementation checklist, достаточный для выполнения Design и Specs. Каждый checkbox объявляет ровно одну area, `Covers` ссылается на native identity `capability path — exact Requirement heading` либо объясняет `N/A`, а `Verification` задаёт планируемую проверку. Tasks не содержат будущие результаты, commits или post-archive bookkeeping. AI-агент готовит только текущий разрешённый артефакт, показывает его Change Owner и останавливается. Downstream artifact создаётся только после явного approval. Если новая сессия не может подтвердить approval из доступного контекста, агент запрашивает его повторно. До запроса approval агент запускает доступный stage planning gate и сам исправляет технические ошибки формата. Полный change validation не объявляется успешным, пока downstream artifacts отсутствуют. Форматное исправление без изменения intent, behavior, decisions или task scope не требует reapproval; семантическое изменение возвращает workflow к самому раннему затронутому artifact. Изменение принятого upstream artifact инвалидирует approval зависимых артефактов: Proposal — Specs, Design и Tasks; Specs — Design и Tasks; Design — Tasks. Tasks не могут неявно расширять scope или менять поведение и архитектуру: работа возвращается к соответствующему upstream artifact. ## Delivery Map и multi-repository delivery Design каждого change оценивает все четыре области: - `specs` всегда `affected` для versioned SDD change; - `docs` всегда `affected` для поставленной пользовательской фичи; для технического изменения допустимо `N/A`, только если as-built документация действительно не меняется; - `frontend` и `backend` являются `affected`, когда меняются их поведение, контракт, реализация или обязательный local gate; - `N/A` требует конкретной причины; пустой commit не имитирует участие репозитория. Change остаётся active, пока каждая affected область не реализована и не прошла свой canonical gate. Design содержит Contract Gate Decision: `runtime-openapi` имеет статус `required`, когда изменение затрагивает frontend и backend стороны API contract, иначе `N/A` с конкретной причиной. Успех одного репозитория не компенсирует отсутствие или failure другого. Task owner выбирается только из `frontend`, `backend`, `specs`, `docs` и `workspace`. Repository owner нельзя использовать для area со статусом `N/A`; cross-repository implementation разбивается на отдельные tasks. `workspace` владеет только orchestration и verification, но не подменяет repository-owned implementation или canonical gates. ## Risk-based testing Автоматизированный тест обязателен, когда изменение затрагивает хотя бы один существенный риск: - security- или privacy-sensitive поведение; - денежные вычисления; - целостность или миграцию данных; - конкурентный доступ; - публичный контракт; - критический пользовательский journey; - подтверждённую регрессию. Уровень теста выбирается по наблюдаемому поведению и наиболее дешёвой надёжной границе. Тест не создаётся только потому, что появился или изменился файл. DTO без собственной логики, декларативная конфигурация, тонкий адаптер, прямолинейная оркестрация, hygiene script и поведение сторонней библиотеки проверяются существующим contract или integration gate без отдельного unit test, пока в проектном коде нет самостоятельного ветвления, преобразования, инварианта либо регрессии. Frontend coverage gate — anti-regression constraint. Он не является причиной писать малоценные тесты декларативных файлов. Для backend нет общего числового coverage threshold; новый threshold допустим только через отдельное утверждённое обоснование защищаемого риска. Проверка самого нового hard guardrail должна показать успешный compliant case и отказ на одном контролируемом репрезентативном нарушении. Это не превращает каждый вспомогательный script в объект unit testing. ## Build versus buy До утверждения Design обязательна оценка зрелых поддерживаемых решений, если change вводит или существенно заменяет: - авторизацию или иной security-механизм; - хранение данных; - внешнюю интеграцию; - observability; - caching или concurrency control; - общую инфраструктуру или tooling. Solution Assessment сравнивает применимые варианты по соответствию требованиям, зрелости, безопасности, эксплуатационной стоимости, ограничениям и стоимости миграции. Поддерживаемое совместимое решение используется либо Design конкретно объясняет, почему его совокупная стоимость или риск выше выбранной альтернативы. Собственная реализация допустима, только если подходящего решения нет или доказана существенная несовместимость. Тогда Design фиксирует проверенные варианты, конкретные gaps, принятые риски и trigger повторного рассмотрения. Для обратимого изменения вне перечисленных областей отдельная формальная оценка не создаётся ради процесса. ## Rollback contract Design фиксирует status `required`, trigger, actions, data safety и verification, если change меняет auth/security behavior, data integrity или migration, public contract либо другое существенно труднообратимое решение. Contract учитывает данные и compatibility, созданные после delivery, и не может зависеть от нового неутверждённого архитектурного решения. Для обратимого change вне этих рисков status `N/A` содержит конкретную причину. Отдельный rollback artifact не создаётся ради процесса. ## Single Source of Truth | Вид знания | Authoritative location | | --- | --- | | Намерение, требования, Design, Tasks, changes и archives | `specs/openspec` | | Исполняемое поведение | `frontend` и `backend` code и risk-based tests | | Публичный API contract | backend runtime OpenAPI и committed frontend snapshot | | Текущее устройство и поставленные возможности | `docs/architecture` и `docs/features` | | Устойчивые архитектурные решения и причины | `docs/adr` | | Инженерная policy и completion evidence | `docs/development` | | Canonical source project-owned agent commands и skills | `specs/agent-projection/opencode` | | Компактная маршрутизация AI-агентов | root и repository-local `AGENTS.md` | `docs` описывает только фактическое текущее состояние и не пересказывает Proposal, Delta Specs, Design или Tasks другим форматом. `AGENTS.md` не копирует архитектуру или feature documentation: он направляет к authority и перечисляет только применимые hard constraints и canonical commands. ## Guardrails и local gates CI пока отсутствует, поэтому обязательные gates выполняются локально одним и тем же способом человеком, AI-агентом и workspace verifier: | Область | Canonical gate | | --- | --- | | frontend | `npm run verify` в `frontend` | | backend | `npm run verify` в `backend` | | specs | `bash specs/scripts/verify-workspace-change.sh ` из workspace root | | docs | `npm run verify` в `docs` | Каждый gate non-mutating и fail-fast. Auto-fix commands выполняются отдельно и не служат доказательством корректности. Runtime preflight отклоняет неподдерживаемый Node до application checks; OpenSpec preflight аналогично отклоняет несовместимую CLI version до операций со store. Hard guardrail должен иметь исполняемую локальную проверку. Правило без надёжной проверки помечается как guidance и учитывается в review, но не выдаётся за автоматический запрет. Новые frameworks, checkers и thresholds добавляются только после оценки поддерживаемого решения, maintenance cost и реально защищаемого риска. Root `.opencode/commands` и `.opencode/skills` являются derived projection. Изменения вносятся в versioned source под `specs`, распространяются explicit atomic sync и проверяются exact file/content comparison; package manifests, dependencies и machine-local state не являются authority inputs. Текущая exact OpenSpec CLI version читается только из `specs/openspec/.cli-version`. Новая stable release не меняет contract автоматически. Upgrade выполняется отдельным SDD change после isolated проверки schema, agent projection, canonical store и positive/negative fixtures; историческое evidence сохраняет фактическую прежнюю version. ## Verify, archive и Completion Evidence Structural validation OpenSpec проверяет schema и форму артефактов, но не соответствие реализации. До archive обязательны: 1. успешные canonical gates всех affected areas; 2. semantic verification реализации против Proposal, Delta Specs, Design и Tasks; 3. independent read-only review без Critical и Important findings; 4. завершённый checklist без unchecked tasks. Archive не имеет confirmation override для этих blockers. После успешного archive применяется двухфазная фиксация: сначала commits поставленных изменений и archive/sync, затем Completion Evidence с уже существующими delivery commit IDs, после чего отдельный final docs commit сохраняет evidence. Evidence ссылается на предшествующий as-built docs commit, если docs affected; при `N/A` сохраняет причину и не выдумывает implementation commit. Собственный final evidence commit не может ссылаться сам на себя и сообщается итогом archive workflow. Только фактические commits, выполненные команды и наблюдённые результаты могут быть evidence; planned значения и предположения не считаются завершением.