docs: simplify verification workflow
This commit is contained in:
@@ -21,7 +21,7 @@ npm ci
|
|||||||
npm run verify
|
npm run verify
|
||||||
```
|
```
|
||||||
|
|
||||||
Gate non-mutating и запускает runtime preflight, committed Markdown rules и `git diff --check`. Auto-fix и network/browser link checking в gate не входят; local links affected documentation проверяются scoped review.
|
Gate non-mutating запускает committed Markdown rules и `git diff --check`. Auto-fix и network/browser link checking в gate не входят; local links affected documentation проверяются scoped review.
|
||||||
Актуальные scripts проверять в `package.json`/`npm run`.
|
Актуальные scripts проверять в `package.json`/`npm run`.
|
||||||
|
|
||||||
## Boundaries
|
## Boundaries
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ Canonical gate не изменяет versioned-файлы:
|
|||||||
npm run verify
|
npm run verify
|
||||||
```
|
```
|
||||||
|
|
||||||
Он проверяет Node 22 до application stages и последовательно запускает hygiene,
|
Он последовательно запускает lint, application/test TypeScript, Jest и build. `npm run lint:fix` — явная
|
||||||
lint, application/test TypeScript, Jest и build. `npm run lint:fix` — явная
|
|
||||||
записывающая команда, а `npm run test:cov` — отдельная диагностика без общего
|
записывающая команда, а `npm run test:cov` — отдельная диагностика без общего
|
||||||
числового threshold. Runtime OpenAPI сверяется с frontend snapshot из workspace:
|
числового threshold. Runtime OpenAPI сверяется с frontend snapshot из workspace:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash specs/scripts/verify-runtime-openapi.sh
|
cd backend
|
||||||
|
npm run test:openapi-contract
|
||||||
```
|
```
|
||||||
|
|
||||||
`npm run test:e2e` временно не является passing gate: Prisma schema engine
|
`npm run test:e2e` временно не является passing gate: Prisma schema engine
|
||||||
|
|||||||
@@ -147,37 +147,34 @@ contract либо другое существенно труднообратим
|
|||||||
|
|
||||||
## Guardrails и local gates
|
## Guardrails и local gates
|
||||||
|
|
||||||
CI пока отсутствует, поэтому обязательные gates выполняются локально одним и тем же способом человеком, AI-агентом и workspace verifier:
|
CI пока отсутствует, поэтому обязательные gates выполняются локально человеком или AI-агентом:
|
||||||
|
|
||||||
| Область | Canonical gate |
|
| Область | Canonical gate |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| frontend | `npm run verify` в `frontend` |
|
| frontend | `npm run verify` в `frontend` |
|
||||||
| backend | `npm run verify` в `backend` |
|
| backend | `npm run verify` в `backend` |
|
||||||
| specs | `bash specs/scripts/verify-workspace-change.sh <change>` из workspace root |
|
| specs | native strict validation из canonical store |
|
||||||
| docs | `npm run verify` в `docs` |
|
| docs | `npm run verify` в `docs` |
|
||||||
|
|
||||||
Каждый gate non-mutating и fail-fast. Auto-fix commands выполняются отдельно и не служат доказательством корректности. Runtime preflight отклоняет неподдерживаемый Node до application checks; OpenSpec preflight аналогично отклоняет несовместимую CLI version до операций со store.
|
Каждый 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 и реально защищаемого риска.
|
Hard guardrail должен иметь исполняемую локальную проверку. Правило без надёжной проверки помечается как guidance и учитывается в review, но не выдаётся за автоматический запрет. Новые frameworks, checkers и thresholds добавляются только после оценки поддерживаемого решения, maintenance cost и реально защищаемого риска.
|
||||||
|
|
||||||
Root `.opencode/commands` и `.opencode/skills` являются локальными
|
Root `.opencode/commands` и `.opencode/skills` являются локальными
|
||||||
non-authority entrypoints. Они должны соблюдать fixed store, version preflight,
|
non-authority entrypoints. Они должны соблюдать fixed store, one-artifact
|
||||||
one-artifact approvals и hard archive blockers, но не имеют отдельного
|
approvals и hard archive blockers, но не имеют отдельного versioned projection
|
||||||
versioned projection source.
|
source.
|
||||||
|
|
||||||
Текущая exact OpenSpec CLI version читается только из
|
OpenSpec schema и changes валидируются native CLI с явным canonical store.
|
||||||
`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
|
## Verify, archive и Completion Evidence
|
||||||
|
|
||||||
Structural validation OpenSpec проверяет schema и форму артефактов, но не соответствие реализации. До archive обязательны:
|
Structural validation OpenSpec проверяет schema и форму артефактов, но не соответствие реализации. До archive обязательны:
|
||||||
|
|
||||||
1. успешные canonical gates всех affected areas;
|
1. успешные canonical gates всех affected areas;
|
||||||
2. semantic verification реализации против Proposal, Delta Specs, Design и Tasks;
|
2. native strict validation completed change и main specs из canonical store;
|
||||||
3. independent read-only review без Critical и Important findings;
|
3. semantic verification реализации против Proposal, Delta Specs, Design и Tasks;
|
||||||
4. завершённый checklist без unchecked tasks.
|
4. independent read-only review без Critical и Important findings;
|
||||||
|
5. завершённый 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 значения и предположения не считаются завершением.
|
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 значения и предположения не считаются завершением.
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ npm ci
|
|||||||
npm run verify
|
npm run verify
|
||||||
```
|
```
|
||||||
|
|
||||||
`verify` сначала отклоняет runtime вне Node 22, затем проверяет OpenAPI drift,
|
`verify` проверяет OpenAPI drift, TypeScript, Biome, один coverage-backed запуск Vitest,
|
||||||
repository hygiene, TypeScript, Biome, один coverage-backed запуск Vitest,
|
|
||||||
Knip, FSD dependency rules, production build и bundle budget. Он работает без
|
Knip, FSD dependency rules, production build и bundle budget. Он работает без
|
||||||
backend. Coverage остаётся anti-regression constraint; правила выбора тестов
|
backend. Coverage остаётся anti-regression constraint; правила выбора тестов
|
||||||
зафиксированы в [engineering governance](engineering-governance.md).
|
зафиксированы в [engineering governance](engineering-governance.md).
|
||||||
|
|||||||
@@ -12,17 +12,8 @@
|
|||||||
- Команда, читающая или изменяющая change, всегда получает `--store wealth-ledger-specs`; cwd и nearest-root discovery не выбирают authority проекта.
|
- Команда, читающая или изменяющая change, всегда получает `--store wealth-ledger-specs`; cwd и nearest-root discovery не выбирают authority проекта.
|
||||||
- Versioned framework-specific planning artifacts вне `specs/openspec`, включая `superpowers/plans`, запрещены. `references/**` остаётся read-only исключением.
|
- Versioned framework-specific planning artifacts вне `specs/openspec`, включая `superpowers/plans`, запрещены. `references/**` остаётся read-only исключением.
|
||||||
|
|
||||||
Exact поддерживаемая OpenSpec CLI version хранится в `specs/openspec/.cli-version`. Перед project-owned операциями выполняется:
|
Native OpenSpec CLI валидирует schema, changes и main specs с явным store;
|
||||||
|
historical archives не переписываются.
|
||||||
```bash
|
|
||||||
bash specs/scripts/verify-openspec-version.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Несовпадение version блокирует операцию до чтения или изменения store.
|
|
||||||
Публикация новой stable версии не меняет этот contract автоматически. Upgrade
|
|
||||||
выполняется отдельным SDD change после staged проверки schema, instructions,
|
|
||||||
agent workflow, store resolution и hard blockers; historical archives
|
|
||||||
не переписываются.
|
|
||||||
|
|
||||||
## Project-local schema
|
## Project-local schema
|
||||||
|
|
||||||
@@ -45,19 +36,8 @@ Delta Spec template является operation-neutral comment guide. Он пе
|
|||||||
`ADDED`, `MODIFIED`, `REMOVED` и `RENAMED`, но не создаёт активную operation
|
`ADDED`, `MODIFIED`, `REMOVED` и `RENAMED`, но не создаёт активную operation
|
||||||
section. Автор добавляет только применимые sections и не оставляет пустых.
|
section. Автор добавляет только применимые sections и не оставляет пустых.
|
||||||
|
|
||||||
До запроса approval выполняется доступная stage-aware проверка:
|
Structural validation выполняется native OpenSpec CLI с
|
||||||
|
`--store wealth-ledger-specs` и не означает approval.
|
||||||
```bash
|
|
||||||
bash specs/scripts/verify-openspec-planning.sh <change>
|
|
||||||
```
|
|
||||||
|
|
||||||
Proposal проверяется без ложного объявления полного change success; по мере
|
|
||||||
появления Specs, Design и Tasks добавляются strict validation, Delivery Map,
|
|
||||||
rollback, area ownership и exact Requirement coverage. Planning result имеет
|
|
||||||
три категории: `artifact-validation` (exit 1), `invocation` (exit 2) и
|
|
||||||
`environment` (exit 3). Только первая разрешает менять проверяемый planning
|
|
||||||
artifact; две остальные требуют исправить invocation или prerequisite.
|
|
||||||
Structural success не означает approval.
|
|
||||||
|
|
||||||
Project-local schema проверяется из `specs`:
|
Project-local schema проверяется из `specs`:
|
||||||
|
|
||||||
@@ -104,15 +84,13 @@ version preflight, permissive archive, conditional store selection и второ
|
|||||||
|
|
||||||
## Реализация и проверка change
|
## Реализация и проверка change
|
||||||
|
|
||||||
Design содержит Delivery Map для `frontend`, `backend`, `specs` и `docs`. Из workspace один non-mutating dispatcher проверяет карту и запускает canonical gates affected areas:
|
Design содержит Delivery Map для `frontend`, `backend`, `specs` и `docs`.
|
||||||
|
Перед archive canonical gates каждого affected repository выполняются по одному
|
||||||
|
разу. `specs` проверяется всегда native strict validation. При required
|
||||||
|
`runtime-openapi` запускают backend `npm run test:openapi-contract`; этот status
|
||||||
|
допустим лишь при affected frontend и backend.
|
||||||
|
|
||||||
```bash
|
Tasks имеют
|
||||||
bash specs/scripts/verify-workspace-change.sh <change>
|
|
||||||
```
|
|
||||||
|
|
||||||
`specs` проверяется всегда. Dispatcher читает явный Contract Gate Decision из Design и сравнивает backend runtime OpenAPI с committed frontend snapshot только при `runtime-openapi: required`; этот status допустим лишь при affected frontend и backend. Child failure блокирует общий результат; fallback и auto-fix отсутствуют.
|
|
||||||
|
|
||||||
Перед affected-area gates dispatcher повторяет planning verifier. Tasks имеют
|
|
||||||
формат `X.Y [area] action` и indented `Covers`/`Verification`; каждый Delta
|
формат `X.Y [area] action` и indented `Covers`/`Verification`; каждый Delta
|
||||||
Requirement покрывается точной ссылкой хотя бы один раз, а `workspace` остаётся
|
Requirement покрывается точной ссылкой хотя бы один раз, а `workspace` остаётся
|
||||||
только owner orchestration/verification. Для `N/A` verifier отклоняет пустой,
|
только owner orchestration/verification. Для `N/A` verifier отклоняет пустой,
|
||||||
@@ -126,14 +104,15 @@ affected areas. Второй context mapping не поддерживается.
|
|||||||
table alignment; Requirement, Scenario, architecture и planned Verification
|
table alignment; Requirement, Scenario, architecture и planned Verification
|
||||||
являются semantic changes.
|
являются semantic changes.
|
||||||
|
|
||||||
Перед archive отдельно подтверждаются structural и semantic gates:
|
Перед archive отдельно подтверждаются native structural и semantic gates:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash specs/scripts/verify-openspec-authority.sh
|
|
||||||
openspec validate <change> --type change --strict --store wealth-ledger-specs
|
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 success не доказывает соответствие реализации. Project-owned verify workflow сопоставляет реализацию с Proposal, Delta Specs, Design и Tasks, затем требует independent read-only review без Critical и Important findings.
|
Structural success не доказывает соответствие реализации. Semantic verification
|
||||||
|
сопоставляет реализацию с Proposal, Delta Specs, Design и Tasks, затем требуется
|
||||||
|
independent read-only review без Critical и Important findings.
|
||||||
|
|
||||||
Archive отклоняется при незавершённом artifact approval, unchecked task, failed affected-area gate, отсутствующей semantic verification или independent review. Confirmation override для этих условий отсутствует. Completion Evidence создаётся только после archive и delivery commits по двухфазному протоколу [Engineering governance](engineering-governance.md); final evidence commit не подменяется незакрытым task.
|
Archive отклоняется при незавершённом artifact approval, unchecked task, failed affected-area gate, отсутствующей semantic verification или independent review. Confirmation override для этих условий отсутствует. Completion Evidence создаётся только после archive и delivery commits по двухфазному протоколу [Engineering governance](engineering-governance.md); final evidence commit не подменяется незакрытым task.
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
## Назначение
|
## Назначение
|
||||||
|
|
||||||
`bash specs/scripts/verify-runtime-openapi.sh` сверяет полный OpenAPI document,
|
`npm run test:openapi-contract` в `backend/` строит configured Nest application,
|
||||||
который отдаёт локально запущенный backend по `/api/docs-json`, с committed
|
создаёт runtime OpenAPI document и сверяет его с committed snapshot
|
||||||
snapshot `frontend/src/shared/api/spec/openapi.json`.
|
`frontend/src/shared/api/spec/openapi.json` после детерминированной canonicalization.
|
||||||
|
|
||||||
Это отдельный контрактный gate, а не общий verifier всех репозиториев. Он нужен
|
Это отдельный контрактный gate, а не общий verifier всех репозиториев. Он нужен
|
||||||
перед изменениями backend API или frontend transport contract и не заменяет
|
перед изменениями backend API или frontend transport contract и не заменяет
|
||||||
@@ -15,23 +15,19 @@ snapshot `frontend/src/shared/api/spec/openapi.json`.
|
|||||||
Из корня workspace:
|
Из корня workspace:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
node --version # должна быть Node 22
|
cd backend
|
||||||
bash specs/scripts/verify-runtime-openapi.sh
|
npm run test:openapi-contract
|
||||||
```
|
```
|
||||||
|
|
||||||
Перед первым запуском в обоих application repositories выполняют `npm ci` под
|
Перед первым запуском в backend выполняют `npm ci` под Node 22.
|
||||||
Node 22. Команда определяет workspace из собственного пути, поэтому её можно
|
|
||||||
запустить и по абсолютному пути из другой текущей директории.
|
|
||||||
|
|
||||||
## Границы и результат
|
## Границы и результат
|
||||||
|
|
||||||
Команда:
|
Команда:
|
||||||
|
|
||||||
- временно компилирует backend, создаёт временную SQLite DB и запускает backend
|
- использует configured Nest application на integration boundary;
|
||||||
только на loopback-порту с детерминированными development values;
|
- рекурсивно сортирует только ключи JSON objects и сохраняет порядок arrays;
|
||||||
- рекурсивно сортирует только ключи JSON objects, сохраняет порядок arrays,
|
- не записывает snapshot или generated frontend types.
|
||||||
выводит SHA-256 обоих полных documents и unified diff при различии;
|
|
||||||
- всегда завершает дочерний backend и удаляет свои temporary resources.
|
|
||||||
|
|
||||||
Она не вызывает `npm run openapi:sync`, не записывает committed snapshot или
|
Она не вызывает `npm run openapi:sync`, не записывает committed snapshot или
|
||||||
generated frontend types и не обращается к T-Bank либо другому внешнему
|
generated frontend types и не обращается к T-Bank либо другому внешнему
|
||||||
|
|||||||
+1
-2
@@ -6,9 +6,8 @@
|
|||||||
"node": "22.x"
|
"node": "22.x"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"runtime:check": "node scripts/verify-node-version.mjs",
|
|
||||||
"lint": "markdownlint-cli2 \"**/*.md\" \"#node_modules\" \"#audits/2026-08-26-wealth-ledger-sdd/*-result.md\" \"#audits/2026-08-26-wealth-ledger-sdd-v2-review/*-audit.md\" \"#audits/codex-sessions-token-audit-2026-08-26.md\"",
|
"lint": "markdownlint-cli2 \"**/*.md\" \"#node_modules\" \"#audits/2026-08-26-wealth-ledger-sdd/*-result.md\" \"#audits/2026-08-26-wealth-ledger-sdd-v2-review/*-audit.md\" \"#audits/codex-sessions-token-audit-2026-08-26.md\"",
|
||||||
"verify": "npm run runtime:check && npm run lint && git diff --check"
|
"verify": "npm run lint && git diff --check"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"markdownlint-cli2": "0.23.2"
|
"markdownlint-cli2": "0.23.2"
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
import { readFileSync } from 'node:fs';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import { dirname, resolve } from 'node:path';
|
|
||||||
|
|
||||||
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
||||||
const packageJson = JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8'));
|
|
||||||
const nvmVersion = readFileSync(resolve(root, '.nvmrc'), 'utf8').trim();
|
|
||||||
const expectedMajor = nvmVersion.replace(/^v/, '').split('.')[0];
|
|
||||||
const expectedEngine = `${expectedMajor}.x`;
|
|
||||||
|
|
||||||
if (packageJson.engines?.node !== expectedEngine) {
|
|
||||||
throw new Error(
|
|
||||||
`Node runtime contracts disagree: .nvmrc=${nvmVersion}, package.json engines.node=${packageJson.engines?.node ?? 'missing'}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const actualVersion = process.versions.node;
|
|
||||||
const actualMajor = actualVersion.split('.')[0];
|
|
||||||
if (actualMajor !== expectedMajor) {
|
|
||||||
console.error(
|
|
||||||
`Unsupported Node.js runtime: expected ${expectedEngine}, actual ${actualVersion}. Activate .nvmrc before running repository checks.`,
|
|
||||||
);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Node.js runtime verified: ${actualVersion} (${expectedEngine})`);
|
|
||||||
Reference in New Issue
Block a user