6 Commits
Author SHA1 Message Date
ksv741 9e227a563d chore(release): 0.1.0
Conventional commits / commits (pull_request) Successful in 12s
Specs security / security (pull_request) Successful in 7s
Specs verify / verify (pull_request) Successful in 10s
Specs security / security (push) Successful in 8s
Specs verify / verify (push) Successful in 11s
Include the reviewed historical OpenAPI fixture fingerprint in the release candidate. Keep full-history scanning enabled.
2026-09-14 07:09:53 +03:00
ksv741 246c754257 chore(release): 0.1.0
Specs security / security (push) Failing after 5s
Specs verify / verify (push) Successful in 9s
Conventional commits / commits (pull_request) Successful in 12s
Specs security / security (pull_request) Failing after 6s
Specs verify / verify (pull_request) Successful in 11s
2026-09-14 07:04:04 +03:00
ksv741 3c7c646f13 chore: configure releases and develop workflow 2026-09-14 07:01:15 +03:00
ksv741 50658ea8be docs: update system documentation references 2026-09-14 05:52:11 +03:00
ksv741 05e314cebb docs(specs): remove runtime OpenAPI gate 2026-09-13 19:08:13 +03:00
ksv741 9590dedc01 docs: align runtime requirements with Node 24 LTS 2026-09-13 15:05:40 +03:00
22 changed files with 4032 additions and 58 deletions
+26
View File
@@ -0,0 +1,26 @@
name: Conventional commits
on:
pull_request:
types: [opened, synchronize, reopened, edited]
jobs:
commits:
runs-on: ubuntu-latest
steps:
- uses: https://github.com/actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- uses: https://github.com/actions/setup-node@v4
with:
node-version-file: .nvmrc
- run: npm ci --ignore-scripts
- name: Check PR title and commits
env:
PR_TITLE: ${{ github.event.pull_request.title }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
printf '%s\n' "$PR_TITLE" | npm run commitlint -- --strict
npm run commitlint -- --strict --from "$BASE_SHA" --to "$HEAD_SHA"
+31
View File
@@ -0,0 +1,31 @@
name: Specs security
on:
push:
branches:
- '**'
pull_request:
schedule:
- cron: '17 5 * * *'
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: https://github.com/actions/checkout@v4
with:
fetch-depth: 0
- name: Record checked revision
run: git rev-parse HEAD
- name: Scan history with Gitleaks 8.30.1
run: |
curl --fail --location --silent --show-error https://github.com/gitleaks/gitleaks/releases/download/v8.30.1/gitleaks_8.30.1_linux_x64.tar.gz -o /tmp/gitleaks.tar.gz
echo '551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb /tmp/gitleaks.tar.gz' | sha256sum --check
mkdir -p /tmp/gitleaks-bin
tar -xzf /tmp/gitleaks.tar.gz -C /tmp/gitleaks-bin gitleaks
/tmp/gitleaks-bin/gitleaks git --log-opts=--all --redact=100 --no-banner
- uses: https://github.com/actions/setup-node@v4
with:
node-version-file: .nvmrc
- name: Audit runtime and development dependencies
run: npm audit --include=dev --audit-level=low
+17
View File
@@ -0,0 +1,17 @@
name: Specs verify
on:
push:
branches: ['**']
pull_request:
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: https://github.com/actions/checkout@v4
- uses: https://github.com/actions/setup-node@v4
with:
node-version-file: .nvmrc
- run: npm ci
- run: npm run verify
+1
View File
@@ -0,0 +1 @@
node_modules/
+4
View File
@@ -0,0 +1,4 @@
# Reviewed historical false positive: the removed runtime OpenAPI check used
# base64 of 0123456789abcdef repeated twice for its disposable SQLite database.
# This fingerprint covers only that historical line; new commits remain scanned.
72444dbbb11ae267e349adbf35256bd7c5be1489:scripts/verify-runtime-openapi.sh:generic-api-key:57
+1
View File
@@ -0,0 +1 @@
24.21.0
+106
View File
@@ -0,0 +1,106 @@
{
"git": {
"requireBranch": "release/*",
"requireCleanWorkingDir": true,
"requireUpstream": false,
"requireCommits": true,
"commitMessage": "chore(release): ${version}",
"tagName": "v${version}",
"tag": false,
"push": false
},
"npm": {
"publish": false
},
"github": {
"release": false
},
"gitlab": {
"release": false
},
"hooks": {
"after:git:init": "node scripts/check-release.cjs"
},
"plugins": {
"@release-it/conventional-changelog": {
"infile": "CHANGELOG.md",
"preset": {
"name": "conventionalcommits",
"types": [
{
"type": "chore",
"scope": "release",
"effect": "hidden"
},
{
"type": "feat",
"section": "Features",
"effect": "bump"
},
{
"type": "fix",
"section": "Bug Fixes",
"effect": "bump"
},
{
"type": "perf",
"section": "Performance",
"effect": "bump"
},
{
"type": "docs",
"section": "Documentation",
"effect": "bump"
},
{
"type": "spec",
"section": "Specifications",
"effect": "bump"
},
{
"type": "refactor",
"section": "Refactoring",
"effect": "bump"
},
{
"type": "build",
"section": "Build",
"effect": "bump"
},
{
"type": "ci",
"section": "CI",
"effect": "bump"
},
{
"type": "test",
"section": "Tests",
"effect": "bump"
},
{
"type": "style",
"section": "Styles",
"effect": "bump"
},
{
"type": "chore",
"section": "Maintenance",
"effect": "bump"
},
{
"type": "revert",
"section": "Reverts",
"effect": "bump"
}
]
},
"context": {
"host": "https://git.personal.ksv741.ru",
"owner": "WealthLedger",
"repository": "specs",
"linkReferences": true,
"commit": "commit"
}
}
}
}
+11 -3
View File
@@ -7,12 +7,20 @@
Если нужна существующая behavioral spec, выбери точный target через Если нужна существующая behavioral spec, выбери точный target через
[AI_INDEX](AI_INDEX.md). Specs не являются вторым editable HTTP OpenAPI: [AI_INDEX](AI_INDEX.md). Specs не являются вторым editable HTTP OpenAPI:
его authority — backend runtime document; workflow находится в backend публикует контракт, а frontend доверяет предоставленному snapshot и
[docs](../docs/development/runtime-openapi-verification.md). локально проверяет generated types; flow описан в
[docs](../docs/architecture/http-api.md#источник-контракта).
Архивы и чужие active changes сохраняй. Для правки индекса проверь targets, Архивы и чужие active changes сохраняй. Для правки индекса проверь targets,
anchors и `git diff --check`; application gates принадлежат affected repos. anchors и `git diff --check`; application gates принадлежат affected repos.
Если явно запрошена работа через OpenSpec, следуй Если явно запрошена работа через OpenSpec, следуй
[optional lifecycle](../docs/development/openspec-authority-and-lifecycle.md) [локальным инструкциям OpenSpec](README.md#начало-работы)
и используй store `wealth-ledger-specs`. Перед Node-командами выбери frontend и используй store `wealth-ledger-specs`. Перед Node-командами выбери frontend
`.nvmrc` через `nvm use --silent`, если здесь нет своей. `.nvmrc` через `nvm use --silent`, если здесь нет своей.
## Ветки и релизы
Работа — в отдельной ветке от `develop`, затем PR в `develop`; в `main` напрямую
не пушить. Release/hotfix и синхронизация веток — по [root README](../README.md#релизы-и-ветки).
Commits и заголовки PR — Conventional Commits; для спецификаций допустим `spec:`.
Перед подготовкой релиза прочитай root README; версии вручную не повышать.
+3 -2
View File
@@ -7,8 +7,9 @@ As-built факты и принятие решений — через [docs inde
При конфликте с текущим поведением установи расхождение; не копируй устаревшее При конфликте с текущим поведением установи расхождение; не копируй устаревшее
правило или случайный код молча. правило или случайный код молча.
HTTP OpenAPI имеет единственный editable source в backend, а не здесь: HTTP OpenAPI имеет единственный editable source в backend, а не здесь.
[contract workflow](../docs/development/runtime-openapi-verification.md). Frontend доверяет предоставленному snapshot и локально проверяет generated
types: [Источник HTTP-контракта](../docs/architecture/http-api.md#источник-контракта).
| Тема / trigger | Existing spec | | Тема / trigger | Existing spec |
| --- | --- | | --- | --- |
+100
View File
@@ -0,0 +1,100 @@
# Changelog
## 0.1.0 (2026-09-14)
### Features
* add authorization ([b4515a2](https://git.personal.ksv741.ru/WealthLedger/specs/commit/b4515a201aa63a46754f11c6a9644da216efeaeb))
* add breadcrumbs ([113ad5e](https://git.personal.ksv741.ru/WealthLedger/specs/commit/113ad5e9a2ef4a0f5b7d626fe7d248f5b877bde9))
* add brocker account list ([e907542](https://git.personal.ksv741.ru/WealthLedger/specs/commit/e9075425df4f5871b7a818aeba809aa440284214))
* add future events ([d4851df](https://git.personal.ksv741.ru/WealthLedger/specs/commit/d4851dfdb7c4bab00e61efe7b778ddc377d769c3))
* add logging ([aac1b43](https://git.personal.ksv741.ru/WealthLedger/specs/commit/aac1b435af29efbe0c12428eda1d8f938bcb6ac3))
* add operations list ([e5517cc](https://git.personal.ksv741.ru/WealthLedger/specs/commit/e5517cceae2fc495a36335609b3173cada7a78f3))
* add portfolio ([e3cc3d5](https://git.personal.ksv741.ru/WealthLedger/specs/commit/e3cc3d540bdef00c700b955340dbb5ad2eeec0c3))
* harden OpenSpec agent resilience ([8462a3b](https://git.personal.ksv741.ru/WealthLedger/specs/commit/8462a3ba75d6dda491b9221699357c58d8f8e3cc))
* harden OpenSpec SDD workflow ([a8b2c4e](https://git.personal.ksv741.ru/WealthLedger/specs/commit/a8b2c4eed988f7e1a7b3d6b7188bbe6791f00e2a))
* little frontend structure refactor ([cdc5ae8](https://git.personal.ksv741.ru/WealthLedger/specs/commit/cdc5ae89951e2639ef5a635f785068bfa8d9f316))
* **portfolio-view:** sync delta spec and archive change ([678a671](https://git.personal.ksv741.ru/WealthLedger/specs/commit/678a671d23b3f3db1d2ad8989924ffb35a9687ee))
* redesign portfolio position cards ([6795ee6](https://git.personal.ksv741.ru/WealthLedger/specs/commit/6795ee6f96911fe9cd0ba12e630009ee707272e4))
### Bug Fixes
* **specs:** remove archived change duplicate ([9f68ae5](https://git.personal.ksv741.ru/WealthLedger/specs/commit/9f68ae52557409dacbae50284d9e3635dd0e031b))
### Documentation
* add baseline OpenSpec change ([2d17778](https://git.personal.ksv741.ru/WealthLedger/specs/commit/2d1777823b411846161f3c2c211e46b2e97ea1a2))
* add MVP change proposals ([e383e5f](https://git.personal.ksv741.ru/WealthLedger/specs/commit/e383e5fac6051722510f812b8787cd8c0317c216))
* add React component style change ([18a9487](https://git.personal.ksv741.ru/WealthLedger/specs/commit/18a94874325169e1e3e6fa4d4669b120c7886475))
* **agents:** link audit remediation registry ([6a38cf1](https://git.personal.ksv741.ru/WealthLedger/specs/commit/6a38cf1e25927805b5fa43b43378efff175441fd))
* **ai:** archive superseded context routing plan ([bcb10da](https://git.personal.ksv741.ru/WealthLedger/specs/commit/bcb10da21cc2e2efb5c6951dfcff89ea65ca7ab4))
* align runtime requirements with Node 24 LTS ([9590ded](https://git.personal.ksv741.ru/WealthLedger/specs/commit/9590dedc0122cc045d24ba01321bbf4715516405))
* archive baseline change ([68be476](https://git.personal.ksv741.ru/WealthLedger/specs/commit/68be4760ce1a360d61b6c8924d3ac4b597001da8))
* archive React component style change ([6898732](https://git.personal.ksv741.ru/WealthLedger/specs/commit/6898732dd8e933e9d6a587aef48ebe0eddaa0cf2))
* archive T-Bank connection change ([7edfcb9](https://git.personal.ksv741.ru/WealthLedger/specs/commit/7edfcb9dba35f75ce76f97e643c2e7492afdd82c))
* complete T-Bank connection change ([cc05b2b](https://git.personal.ksv741.ru/WealthLedger/specs/commit/cc05b2b69cf8f82ff7e76673990fb901168f88a8))
* link to unified documentation entry ([43a5577](https://git.personal.ksv741.ru/WealthLedger/specs/commit/43a5577e72ed6556f7db5d10689c2cc3cbdd60e3))
* record completed manual bank card change ([834f2d1](https://git.personal.ksv741.ru/WealthLedger/specs/commit/834f2d146cb99675be5901b40a4d32039d250210))
* **sdd:** add tbank access refactor change ([79faa29](https://git.personal.ksv741.ru/WealthLedger/specs/commit/79faa29ac07172a16de617cd09003b5e7186900e))
* **sdd:** archive tbank access refactor ([736885f](https://git.personal.ksv741.ru/WealthLedger/specs/commit/736885fe6555c09a2d68b35994692c4fafdac518))
* **specs:** add audit remediation workflow plan ([ea58797](https://git.personal.ksv741.ru/WealthLedger/specs/commit/ea587970ae6123bb5fe5289a138ef42878dbd7ab))
* **specs:** archive account-ledger-explicit-filters ([69d4e63](https://git.personal.ksv741.ru/WealthLedger/specs/commit/69d4e63a5110f744a2428dd9d40525bf025a2db8))
* **specs:** archive add-instrument-logos ([70a200e](https://git.personal.ksv741.ru/WealthLedger/specs/commit/70a200e1b41992c8909f6f2daae4264afc442b9d))
* **specs:** archive api contract resilience remediation ([800450d](https://git.personal.ksv741.ru/WealthLedger/specs/commit/800450d07549475d2c83665b58a69c143db5349c))
* **specs:** archive audit remediation workflow ([d093902](https://git.personal.ksv741.ru/WealthLedger/specs/commit/d0939026fbf5e40a55390688c58a8929f8a23927))
* **specs:** archive auth and cache remediation ([6e20cdf](https://git.personal.ksv741.ru/WealthLedger/specs/commit/6e20cdffaf2f57065f2c99c2d3dd7b66cb1d9903))
* **specs:** archive brokerage account list change ([6f47589](https://git.personal.ksv741.ru/WealthLedger/specs/commit/6f47589211afd2cfcecb77884189203038e82732))
* **specs:** archive consume-mantine-components change ([b5df309](https://git.personal.ksv741.ru/WealthLedger/specs/commit/b5df309728afd1b96f2012b0b5b4d8271ee182a3))
* **specs:** archive dependency hygiene remediation ([8897bd9](https://git.personal.ksv741.ru/WealthLedger/specs/commit/8897bd9585004b89e4347712c33bd91867c50015))
* **specs:** archive documentation entrypoints remediation ([5b7bc0f](https://git.personal.ksv741.ru/WealthLedger/specs/commit/5b7bc0fdaf8202acfc8ac1ef5510b3f3abad2bbc))
* **specs:** archive domain money contract change ([039b72e](https://git.personal.ksv741.ru/WealthLedger/specs/commit/039b72eed38b07e89e2f0234e7c12c202b6cf262))
* **specs:** archive frontend audit remediation ([ab231a6](https://git.personal.ksv741.ru/WealthLedger/specs/commit/ab231a6aac58f4e97377e4d4fb521e22d3f07fdb))
* **specs:** archive frontend auth query gating change ([6e2890f](https://git.personal.ksv741.ru/WealthLedger/specs/commit/6e2890f86f5316fdb821b043084461314eb8cf13))
* **specs:** archive frontend quality guardrails ([2029519](https://git.personal.ksv741.ru/WealthLedger/specs/commit/20295190ddb02cb279a6b404d40d944bde862c3d))
* **specs:** archive frontend query remediation ([b8a3f96](https://git.personal.ksv741.ru/WealthLedger/specs/commit/b8a3f9631696a0b50fab27922214a1d158577f31))
* **specs:** archive frontend view model boundary change ([5cc42f3](https://git.personal.ksv741.ru/WealthLedger/specs/commit/5cc42f30cab997a6d0889c124279d06d64fc8e07))
* **specs:** archive improved ledger event rows ([9a8687f](https://git.personal.ksv741.ru/WealthLedger/specs/commit/9a8687feda24edcc6ee6412313a844afce50f5eb))
* **specs:** archive income analytics change ([9ac04cd](https://git.personal.ksv741.ru/WealthLedger/specs/commit/9ac04cdb44cacdad51b60e157a0d8a2f98e3a16a))
* **specs:** archive ledger-entry-type-label change and sync main spec ([37c0133](https://git.personal.ksv741.ru/WealthLedger/specs/commit/37c0133e8baf15959a0c38e45e7b7ac320b8084f))
* **specs:** archive local verification remediation ([72444db](https://git.personal.ksv741.ru/WealthLedger/specs/commit/72444dbbb11ae267e349adbf35256bd7c5be1489))
* **specs:** archive OpenSpec resilience change ([779a1e1](https://git.personal.ksv741.ru/WealthLedger/specs/commit/779a1e1305f8c209a4f98fae7f87718e48d61b37))
* **specs:** archive session workflow changes ([216956e](https://git.personal.ksv741.ru/WealthLedger/specs/commit/216956e0c6868c75bce8390d36e90685922b2c3b))
* **specs:** archive stock card polish ([cf6bc17](https://git.personal.ksv741.ru/WealthLedger/specs/commit/cf6bc1761140f06f44ea29e2eee1a2b24d075e2a))
* **specs:** archive stock ticker change ([329f0a8](https://git.personal.ksv741.ru/WealthLedger/specs/commit/329f0a86a46b1358f83975714b0c378ebf795e7e))
* **specs:** archive T-Bank cache boundary change ([0386b6b](https://git.personal.ksv741.ru/WealthLedger/specs/commit/0386b6b26fa06014182736d1773eb2e48c0293dc))
* **specs:** archive verification simplification change ([15ce5b5](https://git.personal.ksv741.ru/WealthLedger/specs/commit/15ce5b586da20ec2cf441a59547da5257c316b78))
* **specs:** drop archived optimize change ([2c9d163](https://git.personal.ksv741.ru/WealthLedger/specs/commit/2c9d163d396e7a770bfa0be33bf7fd5e1c2860aa))
* **specs:** harden OpenSpec authority lifecycle ([51344d4](https://git.personal.ksv741.ru/WealthLedger/specs/commit/51344d498808be09bb65b5c255fc4393103d5d0d))
* **specs:** mark remediation workflow complete ([37ba133](https://git.personal.ksv741.ru/WealthLedger/specs/commit/37ba133464140925cdc72cdb745fa7e34adb041c))
* **specs:** plan bounded SDD workflow ([50a6721](https://git.personal.ksv741.ru/WealthLedger/specs/commit/50a6721a6037677d97b1650523b4ada40be9668f))
* **specs:** plan frontend query remediation ([bce16ac](https://git.personal.ksv741.ru/WealthLedger/specs/commit/bce16ac3d6638fc8a5e5ab60c8844fde27453eb7))
* **specs:** record frontend remediation progress ([ca7ceed](https://git.personal.ksv741.ru/WealthLedger/specs/commit/ca7ceedcc307319d058516c7c1b0c8c710e893cd))
* **specs:** remove runtime OpenAPI gate ([05e314c](https://git.personal.ksv741.ru/WealthLedger/specs/commit/05e314cebbcb697938d5ca1ff6e1eb226bc73963))
* **specs:** start token-efficient agent pilot ([0b48b50](https://git.personal.ksv741.ru/WealthLedger/specs/commit/0b48b50f4a0d098e42fea292807a96bcd419e212))
* **specs:** version audit snapshot in docs ([ead4834](https://git.personal.ksv741.ru/WealthLedger/specs/commit/ead48345de163870bd9f6e2cdd0f0ac9b3862dce))
* update system documentation references ([50658ea](https://git.personal.ksv741.ru/WealthLedger/specs/commit/50658ea8be85568995cc2b71568f9779452424b6))
### Specifications
* archive compact portfolio totals ([d5c1825](https://git.personal.ksv741.ru/WealthLedger/specs/commit/d5c18258c471afe80306161e5e17b59b04667190))
* archive income page simplification with evidence ([fbb7193](https://git.personal.ksv741.ru/WealthLedger/specs/commit/fbb7193e900534728a4ac1256cc1f76c0ab88eb9))
* archive loading skeleton change ([1d934e0](https://git.personal.ksv741.ru/WealthLedger/specs/commit/1d934e01d7b1ccbd2717d11e1440b6f00dcda47c))
* archive local design token simplification ([19a658e](https://git.personal.ksv741.ru/WealthLedger/specs/commit/19a658e31849083ece7a1f601baba67769dabf1a))
* archive portable design token delivery ([ca709b5](https://git.personal.ksv741.ru/WealthLedger/specs/commit/ca709b5ab9ef380f408dcd6d5bc2f5f0f265d144))
* define portable design token source ([e637a07](https://git.personal.ksv741.ru/WealthLedger/specs/commit/e637a07e6b2b1b6d5372255dc9899fe771ac08df))
* deliver compact portfolio totals package ([b06a35b](https://git.personal.ksv741.ru/WealthLedger/specs/commit/b06a35bbaab83700f3435b50a559614860e5c07c))
* record approved income page simplification ([4c905c1](https://git.personal.ksv741.ru/WealthLedger/specs/commit/4c905c143368d799c142dbbce3a97d74108d6d28))
* remove income analytics period limit ([0608d4d](https://git.personal.ksv741.ru/WealthLedger/specs/commit/0608d4dc23576c32875e3579c8fedeca92db32e7))
* simplify local design token validation contract ([f171b8b](https://git.personal.ksv741.ru/WealthLedger/specs/commit/f171b8bb4642dcaf0c9b4db8354eb6b8aaa4ea9d))
### Refactoring
* refactor future event list ([601a498](https://git.personal.ksv741.ru/WealthLedger/specs/commit/601a4989913fe5b0dbe8c8f612702012d56a7099))
### Maintenance
* configure releases and develop workflow ([3c7c646](https://git.personal.ksv741.ru/WealthLedger/specs/commit/3c7c646f1386ab0f5c1f7604da87f3933cb10afb))
* harden SDD governance workflow ([0006aea](https://git.personal.ksv741.ru/WealthLedger/specs/commit/0006aea56207ad2192c678ced562feabf1a21c45))
* remove agent projection authority ([6719160](https://git.personal.ksv741.ru/WealthLedger/specs/commit/6719160c13d1fba80b395a96b3389f86bfed87aa))
* **specs:** finish verification cleanup ([b6c141f](https://git.personal.ksv741.ru/WealthLedger/specs/commit/b6c141f4f3b5d95dbfcbd921959db910e8d1db66))
* use native OpenSpec validation ([2faf4eb](https://git.personal.ksv741.ru/WealthLedger/specs/commit/2faf4eb8f35be99c99b9711634a9dc4d9c083c07))
+10 -2
View File
@@ -4,7 +4,7 @@
## Начало работы ## Начало работы
Перед созданием change прочитайте [engineering governance](../docs/development/engineering-governance.md) и [OpenSpec lifecycle](../docs/development/openspec-authority-and-lifecycle.md). Proposal, Delta Specs, Design и Tasks создаются последовательно по одному после approval Change Owner. Для любой команды, читающей или изменяющей change, явно передавайте `--store wealth-ledger-specs`. OpenSpec применяется по явному запросу согласно [AGENTS](AGENTS.md). Proposal, Delta Specs, Design и Tasks создаются последовательно по одному после approval Change Owner. Для любой команды, читающей или изменяющей change, явно передавайте `--store wealth-ledger-specs`.
Design должен оценить `frontend`, `backend`, `specs`, `docs` в Delivery Map и при обязательном trigger включить Solution Assessment. Docs описывает as-built state и не становится параллельным store требований. Design должен оценить `frontend`, `backend`, `specs`, `docs` в Delivery Map и при обязательном trigger включить Solution Assessment. Docs описывает as-built state и не становится параллельным store требований.
@@ -18,4 +18,12 @@ openspec validate <change> --type change --strict --store wealth-ledger-specs
openspec validate --specs --strict --store wealth-ledger-specs openspec validate --specs --strict --store wealth-ledger-specs
``` ```
Structural validation не заменяет semantic verification и independent read-only review перед archive. Audit-derived работа маршрутизируется через [live remediation registry](../docs/development/audit-remediation.md). Structural validation не заменяет semantic verification и independent read-only review перед archive.
## Релизы
Node задаётся собственной `.nvmrc`; после `nvm use --silent` выполните `npm ci`.
`npm run verify` проверяет diff. Release tooling проверяется из root командой
`node test-release.cjs specs`. OpenSpec validation остаётся отдельной проверкой
при изменениях требований. [Ветки и выпуск](../README.md#релизы-и-ветки),
[история релизов](CHANGELOG.md).
+4
View File
@@ -0,0 +1,4 @@
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: { "type-enum": [2, "always", ["feat", "fix", "perf", "docs", "spec", "refactor", "build", "ci", "test", "style", "chore", "revert"]] },
};
+1 -1
View File
@@ -4,6 +4,6 @@ context: |
WealthLedger состоит из независимых frontend, backend, specs и docs Git-репозиториев. WealthLedger состоит из независимых frontend, backend, specs и docs Git-репозиториев.
Canonical OpenSpec authority — зарегистрированный store wealth-ledger-specs в specs/openspec. Canonical OpenSpec authority — зарегистрированный store wealth-ledger-specs в specs/openspec.
Docs описывает только фактическое as-built состояние; устойчивые process policies находятся в docs/development. Docs описывает только фактическое as-built состояние; устойчивые process policies находятся в docs/development.
Локальная разработка и verification выполняются под Node 22 без CI. Локальная разработка и verification выполняются под Node 24 без CI.
Project artifacts объясняют решения по-русски; exact OpenSpec headings, tokens, Project artifacts объясняют решения по-русски; exact OpenSpec headings, tokens,
commands и normative keywords SHALL/MUST сохраняются на английском. commands и normative keywords SHALL/MUST сохраняются на английском.
@@ -106,8 +106,6 @@ artifacts:
- **Delivery Map**: ровно `frontend`, `backend`, `specs`, `docs`; каждая - **Delivery Map**: ровно `frontend`, `backend`, `specs`, `docs`; каждая
area имеет `affected` outcome или конкретный `N/A` reason. `specs` всегда area имеет `affected` outcome или конкретный `N/A` reason. `specs` всегда
`affected`. `affected`.
- **Contract Gate Decision**: `runtime-openapi` = `required`, только когда
меняются обе стороны API contract; иначе конкретный `N/A`.
- **Risks / Trade-offs** и **Migration Plan**. - **Risks / Trade-offs** и **Migration Plan**.
- В Migration Plan — `### Rollback Contract`: `required` с Trigger, - В Migration Plan — `### Rollback Contract`: `required` с Trigger,
Actions, Data safety, Verification для auth/security, data integrity/ Actions, Data safety, Verification для auth/security, data integrity/
@@ -56,12 +56,6 @@
| specs | `affected` | <!-- normative result --> | | specs | `affected` | <!-- normative result --> |
| docs | `affected` or `N/A` | <!-- as-built documentation result or reason --> | | docs | `affected` or `N/A` | <!-- as-built documentation result or reason --> |
### Contract Gate Decision
| Gate | Status | Reason |
| --- | --- | --- |
| runtime-openapi | `required` or `N/A` | <!-- required only when both API contract sides change; otherwise concrete N/A reason --> |
## Solution Assessment ## Solution Assessment
<!-- Include only when the change crosses a mandatory build-vs-buy trigger. <!-- Include only when the change crosses a mandatory build-vs-buy trigger.
+18 -39
View File
@@ -2,7 +2,8 @@
## Purpose ## Purpose
Определяет единый, проверяемый контракт HTTP API между backend и frontend, исключающий ручное расхождение типов и маршрутов. Определяет направление HTTP API contract между backend и frontend, исключающее
ручное расхождение frontend snapshot и generated types.
## Requirements ## Requirements
@@ -13,23 +14,27 @@ Backend SHALL публиковать версионированный OpenAPI-д
- **WHEN** backend запущен в локальной среде разработки - **WHEN** backend запущен в локальной среде разработки
- **THEN** разработчик может получить OpenAPI-документ для генерации frontend-клиента - **THEN** разработчик может получить OpenAPI-документ для генерации frontend-клиента
### Requirement: Frontend использует сгенерированный API-клиент ### Requirement: Frontend использует предоставленный OpenAPI snapshot
Frontend SHALL хранить в репозитории версионируемый snapshot опубликованного OpenAPI-документа и генерировать transport types из этого snapshot. Команда синхронизации MUST получать документ из backend, а затем обновлять snapshot и сгенерированный результат только при успешном завершении всего процесса. Сгенерированный результат MUST храниться в frontend-репозитории. Frontend SHALL хранить в репозитории версионируемый snapshot предоставленного
актуального OpenAPI-документа и генерировать transport types из этого snapshot.
Команда генерации MUST читать frontend snapshot и обновлять сгенерированный
результат. Она MUST NOT читать файлы соседнего backend checkout, запускать
backend scripts или проверять backend runtime OpenAPI. Сгенерированный результат
MUST храниться в frontend-репозитории.
#### Scenario: API-контракт синхронизируется #### Scenario: Types генерируются из предоставленного snapshot
- **WHEN** разработчик запускает команду синхронизации при доступном backend с валидным OpenAPI-документом - **WHEN** разработчик запускает frontend-команду генерации
- **THEN** frontend обновляет versioned snapshot и сгенерированные transport types из опубликованного контракта - **THEN** frontend обновляет generated transport types из versioned snapshot
#### Scenario: API-контракт изменяется #### Scenario: API-контракт изменяется
- **WHEN** backend меняет опубликованный API-контракт - **WHEN** backend меняет опубликованный API-контракт и frontend получает новый snapshot
- **THEN** frontend может синхронизировать snapshot и повторно сгенерировать transport types до интеграции изменения - **THEN** frontend может повторно сгенерировать transport types до интеграции изменения
#### Scenario: Синхронизация контракта завершается ошибкой
- **WHEN** backend недоступен или публикует невалидный OpenAPI-документ
- **THEN** команда завершается с ошибкой и существующие snapshot и сгенерированные transport types не изменяются
### Requirement: Frontend не зависит от OpenAPI во время работы ### Requirement: Frontend не зависит от OpenAPI во время работы
Работающий frontend MUST использовать ранее сгенерированные transport types и MUST NOT требовать доступность Swagger или OpenAPI endpoint во время запуска, выполнения пользовательского сценария или локальной проверки актуальности generated artifact. Доступ к backend OpenAPI endpoint разрешён только команде синхронизации snapshot и отдельной read-only runtime-contract command. Работающий frontend MUST использовать ранее сгенерированные transport types и
MUST NOT требовать доступность Swagger или OpenAPI endpoint во время запуска,
выполнения пользовательского сценария, генерации types или локальной проверки
актуальности generated artifact.
#### Scenario: OpenAPI endpoint недоступен после сборки frontend #### Scenario: OpenAPI endpoint недоступен после сборки frontend
- **WHEN** frontend уже собран, а endpoint OpenAPI временно недоступен - **WHEN** frontend уже собран, а endpoint OpenAPI временно недоступен
@@ -39,32 +44,6 @@ Frontend SHALL хранить в репозитории версионируем
- **WHEN** разработчик запускает локальный frontend quality gate - **WHEN** разработчик запускает локальный frontend quality gate
- **THEN** проверка актуальности generated artifact использует сохранённый snapshot и не обращается к OpenAPI endpoint - **THEN** проверка актуальности generated artifact использует сохранённый snapshot и не обращается к OpenAPI endpoint
#### Scenario: Разработчик проверяет runtime-контракт
- **WHEN** разработчик запускает отдельную runtime-contract command
- **THEN** command может поднять изолированный local backend только для сравнения
его полного runtime OpenAPI document с committed frontend snapshot и не
обновляет ни один из артефактов
### Requirement: Отдельная команда обнаруживает runtime drift OpenAPI
Runtime-contract command MUST получать полный OpenAPI document от изолированного
local backend по `/api/docs-json`, рекурсивно canonicalize порядок JSON object
keys, сохраняя каждое field и array order, и сравнивать его SHA-256 с canonical
committed frontend snapshot. При любом content mismatch она MUST завершаться
ошибкой и показывать diff. Verification MUST NOT вызывать snapshot
synchronization command или записывать committed OpenAPI либо generated type
artifacts.
#### Scenario: Runtime success status отличается от committed snapshot
- **WHEN** backend runtime OpenAPI описывает response status, отличный от
committed frontend snapshot
- **THEN** runtime-contract command завершается ошибкой с diff и оставляет
snapshot и generated types без изменений
#### Scenario: Runtime OpenAPI совпадает с committed snapshot
- **WHEN** каждое field canonical runtime document совпадает с canonical
committed frontend snapshot
- **THEN** runtime-contract stage завершается успешно без изменения frontend files
### Requirement: Frontend обнаруживает дрейф сгенерированного контракта ### Requirement: Frontend обнаруживает дрейф сгенерированного контракта
Frontend SHALL проверять, что committed generated transport types соответствуют versioned OpenAPI snapshot, и MUST завершать quality gate с ошибкой при расхождении. Frontend SHALL проверять, что committed generated transport types соответствуют versioned OpenAPI snapshot, и MUST завершать quality gate с ошибкой при расхождении.
+1 -1
View File
@@ -170,7 +170,7 @@ Entry и Future Cash Event. Runtime/cache-термины MUST быть отде
### Requirement: README репозиториев являются компактными onboarding entrypoints ### Requirement: README репозиториев являются компактными onboarding entrypoints
Репозитории frontend и backend SHALL предоставлять русскоязычные README Репозитории frontend и backend SHALL предоставлять русскоязычные README
entrypoints, которые указывают Node 22, lockfile-safe bootstrap, локальные entrypoints, которые указывают Node 24, lockfile-safe bootstrap, локальные
non-mutating verification commands, требуемую локальную configuration и ссылки non-mutating verification commands, требуемую локальную configuration и ссылки
на authoritative или just-in-time documentation. README MUST различать deferred на authoritative или just-in-time documentation. README MUST различать deferred
check и passing verification gate, а detailed rationale deferred Prisma e2e и check и passing verification gate, а detailed rationale deferred Prisma e2e и
+2 -2
View File
@@ -31,7 +31,7 @@
delivery-plan файл как источник требований, порядка поставки или фактического delivery-plan файл как источник требований, порядка поставки или фактического
поведения. Требования SHALL оставаться в OpenSpec, а delivered system overview поведения. Требования SHALL оставаться в OpenSpec, а delivered system overview
и долговечные ограничения SHALL находиться в `docs`. Frontend и backend MUST и долговечные ограничения SHALL находиться в `docs`. Frontend и backend MUST
требовать Node 22 и документировать lockfile-safe bootstrap через `npm ci`. требовать Node 24 и документировать lockfile-safe bootstrap через `npm ci`.
#### Scenario: Агент определяет границы поставленной системы #### Scenario: Агент определяет границы поставленной системы
- **WHEN** агент начинает работу и ищет актуальные границы WealthLedger - **WHEN** агент начинает работу и ищет актуальные границы WealthLedger
@@ -40,7 +40,7 @@ delivery-plan файл как источник требований, поряд
#### Scenario: Агент bootstrap-ит application repository #### Scenario: Агент bootstrap-ит application repository
- **WHEN** агент начинает локальную проверку frontend или backend на чистой машине - **WHEN** агент начинает локальную проверку frontend или backend на чистой машине
- **THEN** он может определить Node 22 и выполнить `npm ci` без угадывания runtime policy - **THEN** он может определить Node 24 и выполнить `npm ci` без угадывания runtime policy
### Requirement: Frontend предоставляет минимальный каркас приложения ### Requirement: Frontend предоставляет минимальный каркас приложения
Frontend SHALL предоставлять русскоязычный адаптивный каркас приложения с маршрутами `/login`, `/register`, `/accounts`, `/accounts/:accountId` и `/settings`, светлой финансовой темой и навигацией для счетов и настроек. Каркас MUST содержать состояния загрузки, ошибки и пустых данных без реализации доменных сценариев. Frontend SHALL предоставлять русскоязычный адаптивный каркас приложения с маршрутами `/login`, `/register`, `/accounts`, `/accounts/:accountId` и `/settings`, светлой финансовой темой и навигацией для счетов и настроек. Каркас MUST содержать состояния загрузки, ошибки и пустых данных без реализации доменных сценариев.
+3634
View File
File diff suppressed because it is too large Load Diff
+21
View File
@@ -0,0 +1,21 @@
{
"name": "wealth-ledger-specs",
"version": "0.1.0",
"private": true,
"engines": {
"node": "24.21.0"
},
"scripts": {
"verify": "git diff --check",
"release:preview": "release-it --dry-run --ci",
"release:prepare": "release-it --ci",
"commitlint": "commitlint"
},
"devDependencies": {
"@commitlint/cli": "21.2.2",
"@commitlint/config-conventional": "21.2.2",
"@release-it/conventional-changelog": "12.0.0",
"conventional-changelog-conventionalcommits": "10.4.0",
"release-it": "21.0.2"
}
}
+31
View File
@@ -0,0 +1,31 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
":semanticCommitTypeAll(chore)"
],
"timezone": "Europe/Moscow",
"labels": [
"dependencies"
],
"dependencyDashboard": true,
"rangeStrategy": "pin",
"packageRules": [
{
"matchUpdateTypes": [
"minor",
"patch"
],
"groupName": "non-major dependencies"
},
{
"matchUpdateTypes": [
"major"
],
"dependencyDashboardApproval": true
}
],
"baseBranchPatterns": [
"develop"
]
}
+10
View File
@@ -0,0 +1,10 @@
const assert = require("node:assert/strict");
const { execFileSync } = require("node:child_process");
const { version } = require("../package.json");
const git = (...args) => execFileSync("git", args, { encoding: "utf8" }).trim();
assert.equal(git("status", "--porcelain"), "", "Commit all changes before preparing a release");
const tags = git("tag", "--merged", "HEAD", "--list", "v[0-9]*", "--sort=-version:refname")
.split("\n").filter(tag => /^v\d+\.\d+\.\d+$/.test(tag));
assert.equal(version, tags[0]?.slice(1) ?? "0.0.0",
"Version is already prepared or release tags are missing. Fetch tags; finish the existing release before preparing another.");