160 lines
16 KiB
Markdown
160 lines
16 KiB
Markdown
# 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` |
|
||
| Компактная маршрутизация AI-агентов и локальные entrypoints | root/repository-local `AGENTS.md` и workspace `.opencode` |
|
||
|
||
`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 <change>` из 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` являются локальными
|
||
non-authority entrypoints. Они должны соблюдать fixed store, version preflight,
|
||
one-artifact approvals и hard archive blockers, но не имеют отдельного
|
||
versioned projection source.
|
||
|
||
Текущая exact OpenSpec CLI version читается только из
|
||
`specs/openspec/.cli-version`. Новая stable release не меняет contract
|
||
автоматически. Upgrade выполняется отдельным SDD change после isolated проверки
|
||
schema, agent workflow, 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 значения и предположения не считаются завершением.
|