From 4af0a9c05590d7d47135fc708719bf83d5dd3fb9 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Wed, 26 Aug 2026 23:14:09 +0300 Subject: [PATCH] docs: simplify verification workflow --- AGENTS.md | 2 +- development/backend-workflow.md | 6 +-- development/engineering-governance.md | 25 +++++----- development/frontend-workflow.md | 3 +- .../openspec-authority-and-lifecycle.md | 49 ++++++------------- development/runtime-openapi-verification.md | 22 ++++----- package.json | 3 +- scripts/verify-node-version.mjs | 26 ---------- 8 files changed, 40 insertions(+), 96 deletions(-) delete mode 100644 scripts/verify-node-version.mjs diff --git a/AGENTS.md b/AGENTS.md index 4b2efc5..b64d280 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,7 +21,7 @@ npm ci 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`. ## Boundaries diff --git a/development/backend-workflow.md b/development/backend-workflow.md index e20f69a..d1723ac 100644 --- a/development/backend-workflow.md +++ b/development/backend-workflow.md @@ -20,13 +20,13 @@ Canonical gate не изменяет versioned-файлы: 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` — отдельная диагностика без общего числового threshold. Runtime OpenAPI сверяется с frontend snapshot из workspace: ```bash -bash specs/scripts/verify-runtime-openapi.sh +cd backend +npm run test:openapi-contract ``` `npm run test:e2e` временно не является passing gate: Prisma schema engine diff --git a/development/engineering-governance.md b/development/engineering-governance.md index 350b346..b00bbb1 100644 --- a/development/engineering-governance.md +++ b/development/engineering-governance.md @@ -147,37 +147,34 @@ contract либо другое существенно труднообратим ## Guardrails и local gates -CI пока отсутствует, поэтому обязательные gates выполняются локально одним и тем же способом человеком, AI-агентом и workspace verifier: +CI пока отсутствует, поэтому обязательные gates выполняются локально человеком или AI-агентом: | Область | Canonical gate | | --- | --- | | frontend | `npm run verify` в `frontend` | | backend | `npm run verify` в `backend` | -| specs | `bash specs/scripts/verify-workspace-change.sh ` из workspace root | +| specs | native strict validation из canonical store | | 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 и реально защищаемого риска. Root `.opencode/commands` и `.opencode/skills` являются локальными -non-authority entrypoints. Они должны соблюдать fixed store, version preflight, -one-artifact approvals и hard archive blockers, но не имеют отдельного -versioned projection source. +non-authority entrypoints. Они должны соблюдать fixed store, one-artifact +approvals и hard archive blockers, но не имеют отдельного versioned projection +source. -Текущая exact OpenSpec CLI version читается только из -`specs/openspec/.cli-version`. Новая stable release не меняет contract -автоматически. Upgrade выполняется отдельным SDD change после isolated проверки -schema, agent workflow, canonical store и positive/negative fixtures; -историческое evidence сохраняет фактическую прежнюю version. +OpenSpec schema и changes валидируются native CLI с явным canonical store. ## Verify, archive и Completion Evidence Structural validation OpenSpec проверяет schema и форму артефактов, но не соответствие реализации. До archive обязательны: 1. успешные canonical gates всех affected areas; -2. semantic verification реализации против Proposal, Delta Specs, Design и Tasks; -3. independent read-only review без Critical и Important findings; -4. завершённый checklist без unchecked tasks. +2. native strict validation completed change и main specs из canonical store; +3. semantic verification реализации против Proposal, Delta Specs, Design и 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 значения и предположения не считаются завершением. diff --git a/development/frontend-workflow.md b/development/frontend-workflow.md index 937816d..88cc01c 100644 --- a/development/frontend-workflow.md +++ b/development/frontend-workflow.md @@ -7,8 +7,7 @@ npm ci npm run verify ``` -`verify` сначала отклоняет runtime вне Node 22, затем проверяет OpenAPI drift, -repository hygiene, TypeScript, Biome, один coverage-backed запуск Vitest, +`verify` проверяет OpenAPI drift, TypeScript, Biome, один coverage-backed запуск Vitest, Knip, FSD dependency rules, production build и bundle budget. Он работает без backend. Coverage остаётся anti-regression constraint; правила выбора тестов зафиксированы в [engineering governance](engineering-governance.md). diff --git a/development/openspec-authority-and-lifecycle.md b/development/openspec-authority-and-lifecycle.md index 59e3b26..9949dfd 100644 --- a/development/openspec-authority-and-lifecycle.md +++ b/development/openspec-authority-and-lifecycle.md @@ -12,17 +12,8 @@ - Команда, читающая или изменяющая change, всегда получает `--store wealth-ledger-specs`; cwd и nearest-root discovery не выбирают authority проекта. - Versioned framework-specific planning artifacts вне `specs/openspec`, включая `superpowers/plans`, запрещены. `references/**` остаётся read-only исключением. -Exact поддерживаемая OpenSpec CLI version хранится в `specs/openspec/.cli-version`. Перед project-owned операциями выполняется: - -```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 -не переписываются. +Native OpenSpec CLI валидирует schema, changes и main specs с явным store; +historical archives не переписываются. ## Project-local schema @@ -45,19 +36,8 @@ Delta Spec template является operation-neutral comment guide. Он пе `ADDED`, `MODIFIED`, `REMOVED` и `RENAMED`, но не создаёт активную operation section. Автор добавляет только применимые sections и не оставляет пустых. -До запроса approval выполняется доступная stage-aware проверка: - -```bash -bash specs/scripts/verify-openspec-planning.sh -``` - -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. +Structural validation выполняется native OpenSpec CLI с +`--store wealth-ledger-specs` и не означает approval. Project-local schema проверяется из `specs`: @@ -104,15 +84,13 @@ version preflight, permissive archive, conditional store selection и второ ## Реализация и проверка 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 -bash specs/scripts/verify-workspace-change.sh -``` - -`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 имеют +Tasks имеют формат `X.Y [area] action` и indented `Covers`/`Verification`; каждый Delta Requirement покрывается точной ссылкой хотя бы один раз, а `workspace` остаётся только owner orchestration/verification. Для `N/A` verifier отклоняет пустой, @@ -126,14 +104,15 @@ affected areas. Второй context mapping не поддерживается. table alignment; Requirement, Scenario, architecture и planned Verification являются semantic changes. -Перед archive отдельно подтверждаются structural и semantic gates: +Перед archive отдельно подтверждаются native structural и semantic gates: ```bash -bash specs/scripts/verify-openspec-authority.sh openspec validate --type change --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. diff --git a/development/runtime-openapi-verification.md b/development/runtime-openapi-verification.md index 8c2d7e8..5423c20 100644 --- a/development/runtime-openapi-verification.md +++ b/development/runtime-openapi-verification.md @@ -2,9 +2,9 @@ ## Назначение -`bash specs/scripts/verify-runtime-openapi.sh` сверяет полный OpenAPI document, -который отдаёт локально запущенный backend по `/api/docs-json`, с committed -snapshot `frontend/src/shared/api/spec/openapi.json`. +`npm run test:openapi-contract` в `backend/` строит configured Nest application, +создаёт runtime OpenAPI document и сверяет его с committed snapshot +`frontend/src/shared/api/spec/openapi.json` после детерминированной canonicalization. Это отдельный контрактный gate, а не общий verifier всех репозиториев. Он нужен перед изменениями backend API или frontend transport contract и не заменяет @@ -15,23 +15,19 @@ snapshot `frontend/src/shared/api/spec/openapi.json`. Из корня workspace: ```bash -node --version # должна быть Node 22 -bash specs/scripts/verify-runtime-openapi.sh +cd backend +npm run test:openapi-contract ``` -Перед первым запуском в обоих application repositories выполняют `npm ci` под -Node 22. Команда определяет workspace из собственного пути, поэтому её можно -запустить и по абсолютному пути из другой текущей директории. +Перед первым запуском в backend выполняют `npm ci` под Node 22. ## Границы и результат Команда: -- временно компилирует backend, создаёт временную SQLite DB и запускает backend - только на loopback-порту с детерминированными development values; -- рекурсивно сортирует только ключи JSON objects, сохраняет порядок arrays, - выводит SHA-256 обоих полных documents и unified diff при различии; -- всегда завершает дочерний backend и удаляет свои temporary resources. +- использует configured Nest application на integration boundary; +- рекурсивно сортирует только ключи JSON objects и сохраняет порядок arrays; +- не записывает snapshot или generated frontend types. Она не вызывает `npm run openapi:sync`, не записывает committed snapshot или generated frontend types и не обращается к T-Bank либо другому внешнему diff --git a/package.json b/package.json index 3e03529..14e75ed 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,8 @@ "node": "22.x" }, "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\"", - "verify": "npm run runtime:check && npm run lint && git diff --check" + "verify": "npm run lint && git diff --check" }, "devDependencies": { "markdownlint-cli2": "0.23.2" diff --git a/scripts/verify-node-version.mjs b/scripts/verify-node-version.mjs deleted file mode 100644 index d940889..0000000 --- a/scripts/verify-node-version.mjs +++ /dev/null @@ -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})`);