102 lines
8.7 KiB
Markdown
102 lines
8.7 KiB
Markdown
# WealthLedger Specs
|
||
|
||
Этот репозиторий — единственный versioned SDD authority рабочей области. Canonical OpenSpec store `wealth-ledger-specs` расположен в `openspec/` (`specs/openspec` от workspace). Новые changes используют `wealth-ledger-sdd-v2`; существующие active changes с `schema: wealth-ledger-sdd` завершаются по legacy schema без автоматической миграции.
|
||
|
||
## Начало работы
|
||
|
||
OpenSpec применяется после явного решения Change Owner согласно [AGENTS](AGENTS.md). Для команд, читающих или изменяющих change, явно передавайте `--store wealth-ledger-specs`. Структурная готовность CLI не означает approval: перед каждым downstream artifact нужно явное решение Change Owner.
|
||
|
||
| Change | Lifecycle |
|
||
| --- | --- |
|
||
| Active `schema: wealth-ledger-sdd` | Proposal → Delta Specs → Design → Tasks → Apply; действующие approvals сохраняются. Legacy Design оценивает `frontend`, `backend`, `specs`, `docs` в Delivery Map. |
|
||
| New `schema: wealth-ledger-sdd-v2` | Proposal → Delta Specs → System Analysis → Design + QA Analysis → Docs Impact → Tasks → Apply. Design и QA Analysis готовы после System Analysis; Docs Impact ждёт обоих. |
|
||
|
||
Для changes без изменения observable behavior используется `skip_specs: true`. В v2 System Analysis/QA Analysis/Docs Impact всё равно фиксируют только применимое содержание и обоснованное N/A, а не фиктивные contracts или tests. `specs/openspec/specs/` хранит нормативное поведение, `docs/` — текущий AS-IS, backend-generated OpenAPI — текущий executable HTTP contract. Target contracts остаются в change до архива; docs обновляются только по согласованному Docs Impact через `[docs]` tasks. После завершения последнего legacy change эту переходную заметку можно удалить отдельным изменением.
|
||
|
||
## Проверка
|
||
|
||
Для native validation из этого репозитория:
|
||
|
||
```bash
|
||
npm run check:openspec
|
||
openspec schema validate wealth-ledger-sdd --verbose
|
||
openspec schema validate wealth-ledger-sdd-v2 --verbose
|
||
openspec status --change <change> --store wealth-ledger-specs
|
||
openspec validate <change> --type change --strict --store wealth-ledger-specs
|
||
openspec validate --specs --strict --store wealth-ledger-specs
|
||
```
|
||
|
||
OpenSpec CLI ставится глобально и не закрепляется в `package.json`: его транзитивная
|
||
зависимость `braces` имеет advisory без исправления в 3.x. Ожидаемая версия хранится
|
||
в `openspec/.cli-version`; `npm run check:openspec` проверяет Node из `.nvmrc`, версию
|
||
CLI и доступность store, и при расхождении выводит команду исправления. Structural
|
||
validation не заменяет semantic verification и independent read-only review перед archive.
|
||
|
||
Node задаётся собственной `.nvmrc`; после `nvm use --silent` выполните `npm ci`.
|
||
`npm run verify` локально проверяет whitespace в незакоммиченном diff; CI `verify`
|
||
выполняет тот же `git diff --check` по коммитам PR (merge-base→head) или push
|
||
(before→after, для новой ветки — последний коммит). Это структурная проверка
|
||
whitespace, не semantic spec validation. OpenSpec validation остаётся отдельной
|
||
проверкой при изменениях требований. История релизов — [CHANGELOG](CHANGELOG.md).
|
||
|
||
## Релизы
|
||
|
||
Репозиторий выпускается независимо. `develop` — интеграция, `main` — принятые
|
||
релизы. Обычная работа: issue-linked ветка от актуального `develop`, PR в
|
||
`develop`; общие правила — в Engineering Workflow по ссылке из AGENTS.
|
||
PR сливается squash или rebase-merge; merge-коммит не используется. `main`
|
||
обновляется только fast-forward из `develop`, поэтому история линейна:
|
||
|
||
```text
|
||
<type>/<issue>-<slug> --squash--> develop --ff-only--> main --> tag vX.Y.Z
|
||
```
|
||
|
||
Инвариант: `origin/main` всегда предок `origin/develop`. Проверка:
|
||
|
||
```bash
|
||
git fetch -q origin
|
||
git merge-base --is-ancestor origin/main origin/develop && echo ok || echo BROKEN
|
||
```
|
||
|
||
Commits и PR titles — Conventional Commits со ссылкой на Issue (кроме release),
|
||
включая `spec:`. Версии вручную не повышай.
|
||
|
||
1. Получи `main`, `develop` и теги: `git fetch origin --tags`. Проверь
|
||
инвариант. Создай `release/X.Y.Z` от проверенного `develop`;
|
||
`nvm use --silent`, `npm ci`.
|
||
2. На чистой ветке выполни `npm run release:preview`, просмотри версию/changelog,
|
||
затем `npm run release:prepare`. Команда создаёт `chore(release): X.Y.Z`,
|
||
обновляет manifest/lockfile/CHANGELOG; тег и push не выполняет. Не обходи
|
||
guards ветки, чистого дерева, отсутствующих тегов или уже подготовленной версии.
|
||
3. Проверь diff и штатные gates этого репозитория. Отправь только release-ветку,
|
||
открой PR в **`develop`** с заголовком `chore(release): X.Y.Z`. После зелёных
|
||
`verify`, `security`, `commits` выполни fast-forward-only merge. Если
|
||
`develop` изменился, обнови release-ветку и повтори проверки кандидата.
|
||
4. Открой PR `develop → main` с тем же заголовком и слей fast-forward-only.
|
||
5. Получи удалённый `main`, сравни его HEAD с проверенным release SHA и версией
|
||
manifest/lockfile. Создай аннотированный `vX.Y.Z` именно на этом SHA:
|
||
`git tag -a vX.Y.Z <release-sha> -m "Release X.Y.Z"`, затем отправь только
|
||
`git push origin refs/tags/vX.Y.Z`. Не запускай release-it повторно на `main`.
|
||
|
||
Обратная синхронизация не нужна: release-коммит попал в `develop` на шаге 3.
|
||
Опубликованные теги не перемещай. При сбое после merge создай отсутствующий тег
|
||
без нового bump; до merge исправь и проверь существующий кандидат без
|
||
повторного повышения версии.
|
||
|
||
Freeze релиза не поддерживается: пока открыт релизный PR, `develop` не двигают.
|
||
Срочный fix — обычная ветка `fix/*` от `develop` с последующим релизом;
|
||
пути от `main` нет, он сделал бы `main` не-предком `develop`. Исключение
|
||
требует явного решения: `release/hotfix-<name>` от `main`, PR в `main`, тег,
|
||
затем merge `main → develop` для восстановления инварианта.
|
||
|
||
`feat:` повышает minor, `fix:`/`perf:` и прочие разрешённые типы — patch;
|
||
`!`/`BREAKING CHANGE:` — major, включая версии до 1.0. `chore(release):`
|
||
исключён из рекомендации и changelog. Конфигурация — `.release-it.json`.
|
||
В Gitea для `main`/`develop` должны быть запрещены прямой/force push и обход
|
||
администратором, включена блокировка устаревшей ветки, обязательны `verify`,
|
||
`security`, `commits`; теги `v*` защищены. Линейность обеспечивают merge styles
|
||
репозитория: merge-коммиты и rebase `--no-ff` выключены, доступны squash,
|
||
rebase-merge и fast-forward-only; стиль по умолчанию — squash.
|
||
Workflow сам не включает эти настройки. Отдельное review approval для одного
|
||
владельца не требуется. Npm publishing, deploy и Gitea Releases не включены.
|