231 lines
20 KiB
Markdown
231 lines
20 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** — запись существующих delivery commits, фактической
|
||
Delivery Map, точных verification commands с observed results и independent
|
||
review. Finalization создаёт её внутри canonical change до archive; она
|
||
архивируется вместе с change.
|
||
|
||
**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.
|
||
|
||
### Роли и approvals
|
||
|
||
Сессия исполняет одну роль: Discovery, Specification, Implementation, Validation
|
||
или Finalization. Создание record и ожидание решения сами по себе не требуют
|
||
новой сессии той же роли. Переход к другой роли требует независимого контекста.
|
||
|
||
Specification поддерживает две bounded progression: `Proposal + Delta Specs`
|
||
и `Design + Tasks`. Перед каждым downstream artifact требуется отдельное явное
|
||
решение Change Owner:
|
||
|
||
| Approval неизменившегося artifact | Следующий разрешённый outcome |
|
||
| --- | --- |
|
||
| Proposal | Delta Specs в той же Specification-сессии |
|
||
| Delta Specs | Завершение первой пары; следующая Specification-сессия начинает Design |
|
||
| Design | Tasks в той же Specification-сессии |
|
||
| Tasks | Implementation в следующей роли |
|
||
|
||
Сохранённый observed approval повторно используется только при совпадении
|
||
identity и fingerprint. State не является самостоятельным доказательством
|
||
решения владельца. Отсутствующее либо legacy approval binding требует явного
|
||
решения; наличие файла не доказывает approval. Recovery и fingerprint procedure
|
||
определены в [context authority](agent-token-efficiency.md).
|
||
|
||
До запроса approval агент запускает доступный stage planning gate и сам
|
||
исправляет технические ошибки формата. Полный change validation не объявляется
|
||
успешным, пока downstream artifacts отсутствуют. Несовпадение fingerprint
|
||
утверждённого artifact сбрасывает его approval и downstream approvals;
|
||
изменение возвращается к самой ранней затронутой planning boundary. Отметки
|
||
выполнения Tasks не изменяют утверждённое содержание и нормализуются только
|
||
для approval fingerprint.
|
||
|
||
Изменение принятого upstream artifact инвалидирует approval зависимых артефактов: Proposal — Specs, Design и Tasks; Specs — Design и Tasks; Design — Tasks. Tasks не могут неявно расширять scope или менять поведение и архитектуру: работа возвращается к соответствующему upstream artifact.
|
||
|
||
### Implementation, Validation и Finalization
|
||
|
||
Implementation выполняет связный batch approved Tasks и отмечает только
|
||
фактически завершённую работу после релевантных checks. Если implementation-owned
|
||
работа остаётся, нормальный outcome — `CHECKPOINT` с продолжением Implementation;
|
||
это не blocker. `READY_FOR_VALIDATION` требует завершения всей такой работы и
|
||
успеха её проверок. Проблема intent направляется к Proposal, observable behavior
|
||
— к Delta Specs, архитектуры — к Design, декомпозиции — к Tasks.
|
||
|
||
Validation независимо проверяет affected gates, semantic и acceptance behavior,
|
||
применимые edge cases и выполняет independent read-only review. Она не меняет
|
||
production implementation, planning artifacts или Tasks. Эти проверки не
|
||
остаются implementation checkboxes. Результат `PASS`, `FAIL` или `SPEC_ISSUE`
|
||
привязан к проверенным planning/delivery inputs по
|
||
[context authority](agent-token-efficiency.md#fingerprints).
|
||
|
||
| Результат / blocker | Ответственная следующая роль |
|
||
| --- | --- |
|
||
| Validation PASS на актуальных inputs | Finalization |
|
||
| Implementation finding или unchecked implementation-owned Task | Implementation |
|
||
| Planning issue / SPEC_ISSUE | Specification, самая ранняя затронутая boundary |
|
||
| Отсутствующий либо устаревший PASS | Validation |
|
||
| Retryable archive/evidence/environment failure при корректных inputs | Finalization |
|
||
|
||
Finalization потребляет актуальный PASS и выполняет только completion mechanics.
|
||
Она не повторяет неизменившуюся Validation и не исправляет implementation или
|
||
planning. При blocker сохраняется observed cause и точный маршрут продолжения.
|
||
|
||
## Context authority
|
||
|
||
[Token-efficient agent workflow](agent-token-efficiency.md) единолично определяет
|
||
bounded reads, fingerprint bindings, handoff, evidence reuse и batching.
|
||
Обязательные safeguards этой policy действуют с любым agent runtime; skills,
|
||
commands и session adapters необязательны. Числовые token budgets и telemetry
|
||
не являются условием delivery.
|
||
|
||
## 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, Completion Evidence и archives | `specs/openspec` |
|
||
| Исполняемое поведение | `frontend` и `backend` code и risk-based tests |
|
||
| Публичный API contract | backend runtime OpenAPI и committed frontend snapshot |
|
||
| Текущее устройство и поставленные возможности | `docs/architecture` и `docs/features` |
|
||
| Устойчивые архитектурные решения и причины | `docs/adr` |
|
||
| Инженерная policy и context discipline | `docs/development` |
|
||
| Компактная маршрутизация и локальные boundaries | root/repository-local `AGENTS.md` |
|
||
| Необязательные runtime adapters и navigation | локальные skills, commands и session records |
|
||
|
||
`docs` описывает только фактическое текущее состояние и не пересказывает Proposal, Delta Specs, Design или Tasks другим форматом. `AGENTS.md` не копирует архитектуру или feature documentation: он направляет к authority и перечисляет только применимые hard constraints и canonical commands.
|
||
|
||
## Guardrails и local gates
|
||
|
||
CI пока отсутствует, поэтому обязательные gates выполняются локально человеком или AI-агентом:
|
||
|
||
| Область | Canonical gate |
|
||
| --- | --- |
|
||
| frontend | `npm run verify` в `frontend` |
|
||
| backend | `npm run verify` в `backend` |
|
||
| specs | native strict validation из canonical store |
|
||
| docs | `npm run verify` в `docs` |
|
||
|
||
Каждый gate non-mutating и fail-fast. Auto-fix commands выполняются отдельно и не служат доказательством корректности. Node 22 задан `.nvmrc` и `engines`; OpenSpec commands всегда используют canonical store.
|
||
|
||
Hard guardrail должен иметь исполняемую локальную проверку. Правило без надёжной проверки помечается как guidance и учитывается в review, но не выдаётся за автоматический запрет. Новые frameworks, checkers и thresholds добавляются только после оценки поддерживаемого решения, maintenance cost и реально защищаемого риска.
|
||
|
||
Native команды и completion procedure описаны в
|
||
[OpenSpec lifecycle](openspec-authority-and-lifecycle.md). Они не требуют
|
||
optional runtime adapters.
|
||
|
||
## Verify, archive и Completion Evidence
|
||
|
||
Structural validation OpenSpec проверяет schema и форму артефактов, но не соответствие реализации. До archive обязательны:
|
||
|
||
1. успешные canonical gates всех affected areas;
|
||
2. native strict validation completed change и main specs из canonical store;
|
||
3. semantic и acceptance verification против approved Proposal, Delta Specs,
|
||
Design и Tasks;
|
||
4. independent read-only review без Critical и Important findings;
|
||
5. завершённые implementation-owned Tasks и необходимая as-built документация;
|
||
6. актуальный input-bound PASS независимой Validation и существующие delivery
|
||
commits для каждой affected repository area.
|
||
|
||
Archive не имеет confirmation override для этих blockers. Completion Evidence
|
||
создаётся в `specs/openspec/changes/<change>/completion-evidence.md` после
|
||
существования всех перечисленных фактов и архивируется вместе с change.
|
||
Evidence содержит Delivery Map, существующие commit identifiers, exact
|
||
commands/observed results и независимый verdict с привязкой к inputs. Для
|
||
`N/A` сохраняется конкретная причина без фиктивного commit или gate.
|
||
|
||
Собственный evidence/archive commit не ссылается сам на себя: его идентификатор
|
||
сообщается после фиксации. Отсутствующие факты не заменяются placeholders,
|
||
unchecked Tasks или отдельным docs evidence store. При `docs: N/A` запись
|
||
Completion Evidence не требует docs-мутации. Registry хранит ссылку на
|
||
canonical archive и evidence; прежние датированные evidence и ссылки остаются
|
||
историческими и не переносятся задним числом.
|