feat: harden OpenSpec SDD workflow
This commit is contained in:
@@ -0,0 +1,276 @@
|
||||
## Context
|
||||
|
||||
WealthLedger использует project-local OpenSpec schema поверх CLI 1.10.0,
|
||||
canonical store в отдельном specs-репозитории и project-owned OpenCode
|
||||
entrypoints в unversioned workspace root. Schema уже задаёт последовательный
|
||||
artifact graph, а repository scripts защищают store authority, Delivery Map и
|
||||
terminal verification. Однако planning quality до Apply проверяется
|
||||
неравномерно, Tasks не имеют машиночитаемой связи с requirements и delivery
|
||||
areas, а root agent projection проверяется только как локально существующее
|
||||
состояние и не восстанавливается из четырёх Git-репозиториев.
|
||||
|
||||
Custom schema API остаётся experimental, поэтому совместимость нельзя безопасно
|
||||
выводить только из SemVer. Root workspace не является Git-репозиторием;
|
||||
versioned authority для новых guardrails и projection recovery должен
|
||||
принадлежать `specs`, а as-built policy, audit snapshots и dispositions —
|
||||
`docs`. Других active OpenSpec changes нет. Этот change создан по schema version
|
||||
1, поэтому его собственные Tasks должны вручную соответствовать утверждённому
|
||||
v2 contract до того, как Apply сделает этот contract default для будущих
|
||||
changes.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- сделать planning structure, task ownership и requirement coverage
|
||||
детерминированно проверяемыми до Apply;
|
||||
- восстановить project-owned agent workflow из versioned inputs и обнаруживать
|
||||
drift derived projection;
|
||||
- сохранить один exact supported CLI contract, пригодный для контролируемого
|
||||
будущего upgrade;
|
||||
- распределить guidance между schema, config, durable policy и verifiers без
|
||||
конкурирующих источников;
|
||||
- сохранить все source assessments и нормализовать их claims с доказательными
|
||||
dispositions;
|
||||
- сохранить пропорциональность workflow и существующие human approval gates.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- обновление OpenSpec CLI в этом change;
|
||||
- изменение frontend, backend, runtime API или deployment behavior;
|
||||
- универсальная схема для других проектов, Fast Track или второй lifecycle;
|
||||
- собственный workflow engine, identity/signature system для approvals или
|
||||
общий dependency scheduler для changes;
|
||||
- автоматическое доказательство смысловой полноты Proposal, Specs или Design;
|
||||
- новые review, completion, blocker, revision либо traceability artifacts.
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. Native schema v2 остаётся workflow engine
|
||||
|
||||
`wealth-ledger-sdd` повышается до version 2, сохраняя граф
|
||||
`Proposal → Delta Specs → Design → Tasks → Apply`. Изменяется contract
|
||||
существующих artifacts, а не их число. Schema и templates задают обязательную
|
||||
форму Tasks, условный rollback contract, stage validation guidance, полный
|
||||
feedback path и компактные примеры сложных delta operations. Minimal spec
|
||||
template остаётся ориентированным на `ADDED`; неиспользуемые delta sections не
|
||||
генерируются как пустые placeholders.
|
||||
|
||||
Artifact approval остаётся человеческим фактом разговора. File existence и
|
||||
CLI status продолжают означать только structural state. Форматное исправление,
|
||||
не меняющее approved semantics, повторяет structural checks без каскадного
|
||||
reapproval; любое изменение intent, behavior, architecture или task scope
|
||||
возвращает workflow к самому раннему затронутому artifact и инвалидирует его
|
||||
downstream approvals.
|
||||
|
||||
### 2. Guidance имеет явных владельцев
|
||||
|
||||
Ответственность разделяется так:
|
||||
|
||||
| Surface | Authority |
|
||||
| --- | --- |
|
||||
| schema instructions | artifact semantics, native syntax и workflow behavior |
|
||||
| templates | только форма создаваемого Markdown |
|
||||
| config context | стабильные факты workspace и язык project artifacts |
|
||||
| config rules | только краткие additive project constraints, отсутствующие в schema |
|
||||
| governance и ADR | durable rationale, ownership и upgrade policy |
|
||||
| non-mutating verifiers | Enforceable Engineering Invariants |
|
||||
|
||||
Текущие config rules, дословно повторяющие schema, удаляются или сокращаются;
|
||||
произвольный `_rules.md` не вводится. Project explanations пишутся по-русски,
|
||||
а OpenSpec tokens, headings, commands и normative keywords сохраняются в их
|
||||
точной английской форме.
|
||||
|
||||
### 3. Planning verifier отделён от full delivery dispatcher
|
||||
|
||||
`specs` получает один stage-aware non-mutating planning verifier. Он разрешает
|
||||
change через canonical store и применяет только доступные на текущем этапе
|
||||
checks:
|
||||
|
||||
- Proposal — metadata, обязательную структуру и разрешимость declared existing
|
||||
capability paths;
|
||||
- Delta Specs — strict change validation и соответствие capability set
|
||||
Proposal;
|
||||
- Design — Delivery Map, Contract Gate Decision и rollback decision;
|
||||
- Tasks — checkbox shape, area ownership, canonical gate coverage и точные
|
||||
requirement references, включая explicit `N/A` rationale.
|
||||
|
||||
Verifier не пытается машинно оценивать качество мотивации, архитектурного
|
||||
rationale или semantic correctness. Full workspace dispatcher вызывает его
|
||||
перед affected-area gates, а artifact entrypoints запускают доступный stage до
|
||||
запроса approval. Проверяемая логика получает compliant fixtures и
|
||||
representative failures для uncovered requirement, invalid area, malformed
|
||||
rollback decision и projection/version drift. Существующие parsers Delivery Map
|
||||
переиспользуются либо извлекаются, а не дублируются вторым несовместимым
|
||||
разбором.
|
||||
|
||||
### 4. Tasks используют area owner и встроенную coverage metadata
|
||||
|
||||
Каждый checkbox использует формат `X.Y [area] action`, где `area` — ровно одна
|
||||
из `frontend`, `backend`, `specs`, `docs`, `workspace`. Следующие indented
|
||||
metadata lines содержат:
|
||||
|
||||
- `Covers`: одна или несколько пар `capability path — exact Requirement
|
||||
heading` либо `N/A — concrete reason`;
|
||||
- `Verification`: planned command, observable check или delivered artifact.
|
||||
|
||||
OpenSpec продолжает отслеживать progress по checkbox line, а planning verifier
|
||||
связывает последующие metadata lines с ближайшим checkbox. Cross-repository
|
||||
implementation разбивается по repository owners; `workspace` используется
|
||||
только для orchestration и verification. Requirement heading остаётся native
|
||||
identity OpenSpec; дополнительный ID namespace не создаётся.
|
||||
|
||||
### 5. Root agent projection получает versioned canonical source
|
||||
|
||||
Текущие project-owned `commands` и `skills` импортируются как canonical source
|
||||
tree под `specs/agent-projection/opencode`. Package manifests, installed
|
||||
dependencies и machine-local runtime state не входят в source. Явная sync
|
||||
команда атомарно обновляет соответствующие каталоги root `.opencode`, а
|
||||
отдельный non-mutating verifier сравнивает required file set и contents с
|
||||
canonical source.
|
||||
|
||||
На upgrade новая upstream projection сначала создаётся в isolated staging.
|
||||
Upstream delta и минимальные WealthLedger overlays — fixed store,
|
||||
one-artifact-at-a-time approvals, feedback path и hard archive blockers —
|
||||
переносятся в canonical source, после чего sync обновляет root derived output.
|
||||
Authority verifier получает expected version из единственного version contract
|
||||
и проверяет совпадение каждого required generated marker. Concrete CLI version
|
||||
не закрепляется в verifier logic или fixtures независимо от contract.
|
||||
|
||||
Canonical source tree выбран вместо:
|
||||
|
||||
- patch set: меньше committed content, но patches хрупки к upstream text churn;
|
||||
- custom generator: устраняет дублирование, но создаёт новый transformation
|
||||
engine и повышает maintenance cost;
|
||||
- symlink: устраняет copy drift, но связывает agent discovery с filesystem и
|
||||
tool-specific symlink behavior;
|
||||
- manual staging only: сохраняет текущую простоту, но не обеспечивает recovery
|
||||
из clean checkouts.
|
||||
|
||||
### 6. Rollback contract является условной частью Design
|
||||
|
||||
Design template получает внутри Migration Plan структурированный rollback
|
||||
decision. Для auth/security, data integrity или migration, public contract и
|
||||
других труднообратимых решений status `required` раскрывает trigger, actions,
|
||||
data safety и verification. Для остальных changes status `N/A` требует
|
||||
конкретной причины. Отдельный rollback artifact не создаётся.
|
||||
|
||||
У этого change rollback contract имеет status `N/A`: application data,
|
||||
security behavior и public contracts не меняются, а committed specs/docs
|
||||
обратимы через Git. Initial projection cutover выполняется атомарно и сохраняет
|
||||
предыдущее local derived state до успешного verification, чтобы failed sync не
|
||||
оставил частично обновлённый workspace.
|
||||
|
||||
### 7. Multi-source assessment хранит raw evidence и отдельный triage
|
||||
|
||||
Пять исходных model reports переносятся byte-for-byte в один dated audit
|
||||
snapshot set под `docs/audits`; index обозначает их как external, non-authority
|
||||
claims и фиксирует checksums. После проверки совпадения исходная unversioned
|
||||
папка удаляется, чтобы не оставить competing copy.
|
||||
|
||||
Live registry получает нормализованные Audit IDs. Повторяющиеся claims имеют
|
||||
одну запись со ссылками на все sources. Triage disposition
|
||||
`confirmed | already-covered | rejected | deferred` хранится отдельно от
|
||||
remediation status. Confirmed findings этого scope связываются с текущим active
|
||||
change; already-covered получают existing evidence; rejected — rationale;
|
||||
deferred — review trigger. Следующим planned remediation после завершения этого
|
||||
change снова становится ранее выбранная auth platform assessment.
|
||||
|
||||
### 8. Version contract фиксирует совместимость, а не вечную версию
|
||||
|
||||
Текущая exact version остаётся неизменной. Появление новой stable версии не
|
||||
блокирует delivery и не меняет contract автоматически. Future upgrade является
|
||||
отдельным SDD change и проходит staged projection comparison, schema/status/
|
||||
instructions compatibility, canonical-store checks, disposable lifecycle и
|
||||
positive/negative authority fixtures. Historical archives и Completion Evidence
|
||||
сохраняют фактические версии своих запусков.
|
||||
|
||||
## Delivery Map
|
||||
|
||||
| Area | Status | Architectural outcome or N/A reason |
|
||||
| --- | --- | --- |
|
||||
| frontend | `N/A` | Change не меняет frontend behavior, source, contract или canonical gate. |
|
||||
| backend | `N/A` | Change не меняет backend behavior, source, contract или canonical gate. |
|
||||
| specs | `affected` | Schema v2, planning/projection guardrails, canonical agent source и нормативные lifecycle requirements образуют единый проверяемый SDD contract. |
|
||||
| docs | `affected` | Immutable multi-source audit, dispositions, governance, lifecycle documentation и ADR отражают поставленную SDD-систему. |
|
||||
|
||||
### Contract Gate Decision
|
||||
|
||||
| Gate | Status | Reason |
|
||||
| --- | --- | --- |
|
||||
| runtime-openapi | `N/A` | Change не затрагивает backend runtime API, frontend generated client или committed OpenAPI snapshot. |
|
||||
|
||||
## Solution Assessment
|
||||
|
||||
Change существенно меняет общую project tooling infrastructure, поэтому
|
||||
сравнение alternatives обязательно.
|
||||
|
||||
### Workflow enforcement
|
||||
|
||||
| Option | Fit и maturity | Security / operating cost | Constraints / migration cost | Decision |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Native OpenSpec schema/config + thin project verifiers | Полностью сохраняет canonical artifact graph; используемые extension points уже работают в 1.10, хотя schema API experimental | Local-only, без новых secrets/services; низкая стоимость поверх существующих gates | Требует exact compatibility contract и fixtures при upgrade; incremental migration | Selected |
|
||||
| Prompt/docs-only conventions | Markdown mature и дёшев, но не отклоняет нарушения | Низкая стоимость, высокий риск silent drift | Не выполняет требования machine validation и reproducibility | Rejected |
|
||||
| Собственный workflow engine | Максимальный theoretical fit, но custom maturity отсутствует | Новый privileged control surface и высокая постоянная стоимость | Дублирует OpenSpec lifecycle, требует migration всех entrypoints и state | Rejected |
|
||||
| Общая monorepo/CI platform | Зрелые продукты существуют, но workspace не имеет общего build/dependency graph и CI | Существенная installation и operating cost | Не решает approval semantics или audit traceability сама по себе | Rejected |
|
||||
|
||||
### Projection recovery
|
||||
|
||||
| Option | Fit и maturity | Operating cost | Main constraint | Decision |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Versioned canonical source tree + sync/check | Простая file projection с детерминированным сравнением | Низкая; около 115 KB source Markdown | Source и derived copy должны проверяться на drift | Selected |
|
||||
| Versioned overlay patches | Компактно | Средняя/высокая при каждом upstream text change | Patch fragility | Rejected |
|
||||
| Programmatic overlay generator | Гибко | Высокая; собственная transformation logic | Риск второго workflow engine | Rejected |
|
||||
| Symlink в specs-owned tree | Минимум duplication | Низкая локально | Tool/filesystem portability и смешение machine-local package state | Rejected |
|
||||
|
||||
Выбранный вариант не реализует OpenSpec behavior самостоятельно: native CLI
|
||||
остаётся engine, а project scripts только синхронизируют derived files и
|
||||
проверяют детерминированные инварианты.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- **Canonical source и derived projection дублируют Markdown.** Drift блокирует
|
||||
verifier; изменения вносятся только в source и распространяются explicit
|
||||
sync-командой.
|
||||
- **Markdown parser может стать хрупким.** Машиночитаемые prefixes и metadata
|
||||
намеренно узкие, fixture suite покрывает compliant и representative invalid
|
||||
inputs, а semantic review остаётся отдельным gate.
|
||||
- **Traceability создаёт ложное ощущение semantic coverage.** Verifier
|
||||
подтверждает наличие ссылок, но semantic verification и independent review
|
||||
продолжают проверять полноту реализации.
|
||||
- **Форматное исключение может скрыть semantic edit.** Оно ограничено ошибками,
|
||||
не меняющими intent, behavior, decisions или tasks; сомнение возвращает
|
||||
artifact на обычный reapproval path.
|
||||
- **Schema instructions могут разрастись.** Duplicate config rules удаляются,
|
||||
examples остаются короткими, а final instruction size сравнивается с
|
||||
baseline без жёсткого token threshold.
|
||||
- **Raw model reports могут выглядеть authoritative.** Snapshot index и registry
|
||||
явно разделяют source claims, triage evidence и project authority.
|
||||
- **Initial source-tree bootstrap не имеет прежней versioned baseline.** Sync
|
||||
сохраняет local pre-cutover state до успешного gate; после поставки все
|
||||
дальнейшие projection versions становятся восстановимыми через Git history.
|
||||
- **Future OpenSpec release может изменить experimental interfaces.** Exact
|
||||
contract блокирует silent adoption, а отдельный upgrade change выполняет
|
||||
staged compatibility assessment.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Ввести canonical projection source и non-mutating planning/projection checks,
|
||||
подтвердив compliant и controlled-invalid fixtures до переключения schema.
|
||||
2. Обновить schema, templates, config и canonical agent source до v2 contract;
|
||||
собственные Tasks этого change оформить уже в новом формате.
|
||||
3. Атомарно синхронизировать root derived projection и отклонить delivery при
|
||||
любом content/version drift.
|
||||
4. Перенести raw assessments в immutable indexed snapshot, проверить
|
||||
byte-for-byte equality, удалить unversioned copy и обновить live registry.
|
||||
5. Обновить governance, lifecycle docs и ADR до фактической архитектуры, затем
|
||||
выполнить specs/docs gates, semantic verification и independent review.
|
||||
|
||||
### Rollback Contract
|
||||
|
||||
| Field | Decision |
|
||||
| --- | --- |
|
||||
| Status | `N/A` |
|
||||
| Reason | Change не меняет application data, security behavior или public contracts; committed state обратим через Git, а projection является derived output с atomic cutover. |
|
||||
| Failed cutover handling | Sync восстанавливает сохранённое pre-cutover local state и не объявляет source/projection согласованными. |
|
||||
| Verification | Planning, projection, authority, strict OpenSpec и docs gates должны снова подтвердить выбранное состояние. |
|
||||
Reference in New Issue
Block a user