Переносит архив `audits/2026-10-11/` (19 файлов) из codex/audit-remediation-2026-10-11 в develop и добавляет точечный allowlist в .gitignore.
68 KiB
Аудит 11 — Validation & CI/CD Efficiency
1. Audit metadata
- Audit ID/name: 11 / Validation & CI/CD Efficiency.
- Дата: 2026-10-11.
- Режим: read-only для application/specs/docs repos; единственная запись — этот отчёт в родительском workspace.
- Область: execution DAG проверок, triggers, независимые CI guarantees, повторная подготовка, staged hooks, генерация контрактов и граница image publication. Алгоритмы самописных инструментов, assertions тестов, dependency security и поведение агента не аудировались.
- Skill: установленный
ponytail-auditпрочитан через Skill tool и применён к complexity-pass. Его ограничения сохранены: correctness findings ниже — результат протокола аудита 11, а не вывод skill. Дополнительно прочитанverification-before-completionдля контроля итогового артефакта. - Предыдущий аудит:
audit-results/technical-audit-2026-10-11.mdпрочитан как реестр гипотез. Его измерения dependency graph, совпадения OpenAPI и выводы о тестах не использованы как актуальное доказательство.
Workspace: /Users/ksv741/Project/vibe/WealthLedger. Это родительская папка самостоятельных Git-репозиториев:
| Repo | Найденный путь относительно workspace | HEAD SHA | Ветка | Начальный git status --short |
|---|---|---|---|---|
| frontend | frontend/ |
c8821200ce699dab1ce65360d1968d5877a2e78b |
codex/fix-stock-screener-race |
clean |
| backend | backend/ |
0ad84ff4f0b4712abc7e69dc299856f14af6eadd |
codex/add-stock-screener |
clean |
| specs | specs/ |
fcdc805f6c1b3be6a20a7e858e3e80cbd83a9121 |
codex/add-stock-screener |
clean |
| docs | docs/ |
e6fd4f64b81dd73b33959b845a1babcfac1891c8 |
codex/add-stock-screener |
clean |
| workspace root, вспомогательная область | ./ |
dc030f84c979cedb2628ef4bd97c62d6c63a9256 |
release/0.2.1 |
clean |
Также обнаружен отдельный deploy/.git; его исходники и pipeline не исследовались. Downstream deployment описан только по доступным root Compose и docs/architecture/deployment.md. Наличие локального checkout не доказывает production state.
Что выполнялось
- Статическое чтение repo instructions, manifests, workflows, hooks, compiler/test/build configs и вызываемых entry points; файловый inventory через Read/Glob/Grep.
- В каждом из четырёх repos и root:
git status --short --branch,git rev-parse HEAD. - В четырёх repos: read-only
git config --get core.hooksPath. Frontend:.husky/_; specs:.githooks; backend/docs: значение отсутствует, команда вернула 1 без вывода. Это отсутствие настройки, а не ошибка проверки приложения. - В specs:
git diff --check && git diff --stat && git diff --cached --stat— exit 0, вывода нет; проверены пустые локальные diffs, не PR content. - Через Context7 прочитана актуальная документация Gitea о PR activity types и head ref: Actions FAQ, webhook payload. Внешний источник подтверждает поддержку
edited; версия и настройки реального Gitea не запрашивались. - После записи отчёта: повторный read-only контроль Git status/HEAD всех пяти областей — SHA не изменились, working trees clean.
git diff --checkroot — без diagnostics. No-index whitespace-check отчёта относительно/dev/null— без diagnostics; exit 1 обозначает наличие нового содержимого относительно пустого файла. Rootgit status --short --ignored -- <report>показывает игнорируемыйaudit-results/, согласно allowlist; отчёт не добавлялся в tracking.
Не выполнялось: npm/Node/OpenSpec команды, install, lifecycle hooks, tests, lint, build, full verify, Prisma/OpenAPI codegen, Docker, migrations, обращения к брокерским/банковским API, npm audit, чтение secrets, commit/PR, изменение source/config/lockfiles/generated artifacts. CI runs/logs и branch protection settings не запрашивались. Тайминги отсутствуют; все оценки экономии — not measured.
2. Executive verdict
- Факт / FIX:
specs verifyв CI проверяет разницу working tree с index, а не проверяемые commits. В чистом checkout это пустая проверка, хотя её статус является задуманным required check. Самый дешёвый полезный gate — whitespace-check явного диапазона commits без Node installation в этом job.VERIFY-001. - Факт / риск: четыре repos исключают PR
editedиз triggers commitlint. Заголовок можно изменить после зелёного статуса без нового запуска; frontend/backend README обещают обратное.VERIFY-002. - Факт / SIMPLIFY: backend non-scheduled verify job содержит 3 явных Prisma generation и 2 Nest build. При этом standalone
verifyгенерирует client слишком поздно для чистого checkout. Нужен один owner подготовки до потребителей типов и reuse той же сборки в e2e, а не механическое удаление первого generate.VERIFY-003. - Факт / SIMPLIFY: frontend pre-commit после staged lint каждый раз собирает два private packages и сканирует весь dependency graph, даже для Markdown-only commit. Полный граф проверяется также в final verify и CI. Обязательные security/staged lint можно сохранить, а full graph оставить composed gates.
VERIFY-004. - KEEP: CI уже избегает дублирующего feature-branch push-run, имеет fail-fast цепочку
commits → security → verify, отмену устаревших ревизий и вынесенный тяжёлый performance benchmark. Unit/SQLite, JSDOM/Chromium и два dependency graphs имеют разные гарантии; объединять их по похожим именам нельзя. - UNVERIFIED: фактические CI minutes, npm/browser/build cache hits, версия Gitea, действующие required checks и защита устаревшего PR head от нового base не проверены. Это вопросы для короткого просмотра существующего run и настроек, а не основание отключать gates.
Итог: четыре подтверждённых P2 findings, без подтверждённых P0/P1. Основная экономия достигается сокращением повторной подготовки и правильным input scope дешёвых gates; расширение количества валидаторов не требуется.
3. Inventory & coverage
3.1 Изученные объекты и метод подсчёта
| Объект | Охват и метод | Результат |
|---|---|---|
| CI definitions | Полное чтение всех файлов в .gitea/workflows/ четырёх repos и root |
11 workflow files, 15 job definitions; сумма: frontend 2/4, backend 2/4, specs 3/3, docs 3/3, root 1/1 |
| CI platforms | Все перечисленные job definitions и .nvmrc |
Один label ubuntu-latest, нет OS/Node matrix; все .nvmrc — 24.21.0 |
| Local commands | Пять root manifests, три frontend workspace manifests | Раскрыты verify, standalone checks, build, generation, release entry points и root lifecycle |
| Git hooks | Tracked hook files, actual hooksPath, backend/docs .git/hooks, Husky launcher |
Frontend: pre-commit + commit-msg; specs: commit-msg; backend/docs: только .sample; активных pre-push checks не найдено |
| Backend e2e selection | Glob backend/test/*.e2e-spec.ts + test/sqlite.cjs:7–17 |
20 suite files; --all выбирает 19 functional suites, исключая один performance suite; это число файлов, не assertions |
| Browser selection | Glob *.browser.test.tsx в frontend src/packages + vitest.config.ts:36–64 |
2 файла, каждый включён для narrow/wide Chromium instances: 4 configured file-instance combinations без фактического запуска |
| Contracts | Backend generator + runtime integration suite; frontend check/generate | Прослежены источник, временный output, byte comparison, freshness и consumers |
| Downstream artifacts | Dockerfiles, image workflows, coverage/Sonar configs, docs deployment | Build provenance boundary и consumers покрыты статически; registry/deploy execution не проверены |
Counts относятся только к найденным локальным checkout, не к server-wide jobs/runners. Явные повторы команд считались разворачиванием manifest chains и workflow steps на успешном пути; lifecycle сторонних packages и cache-hit effects не выдаются за измеренную длительность.
Из installed manifests отдельно проверены backend/node_modules/@prisma/client/package.json:264–275 и backend/node_modules/prisma/package.json:194–205: у этой версии client нет postinstall generation, Prisma имеет preinstall. Это поддерживает гипотезу cold-checkout failure standalone verify; установленное дерево не заменяет воспроизведение fresh install.
3.2 Исследовательский порядок и исключённые гипотезы
- Inventory entry points → выбор рисков stale/no-op proof и повторной подготовки.
- Tracing workflow → package script → runner/generator/build outputs → consumer.
- Проверка альтернатив: отдельный front generate нужен до типов; standalone wrappers обеспечивают свежесть packages; graph modes отличаются; OpenAPI delivery явно ручная; image publication не равна server rollout.
- Сформированы четыре findings; без искусственного расширения до всех возможных оптимизаций.
Не аудировались assertions и качество coverage, алгоритмы custom scripts, advisories/overrides, OpenSpec schema/lifecycle design, глобальные editor/agent hooks и отдельный deploy repo. Исторические archives не использованы как proof текущих triggers.
4. Check Execution DAG
Ниже фактическая конфигурация. Обязательное локальное действие из conventions отмечено отдельно от автоматического trigger.
4.1 Edit/save и ручная проверка
developer / agent edits
├─ frontend npm run dev [только если процесс запущен]
│ └─ build:packages → Vite/HMR на изменениях
├─ frontend npm run dev:catalog [только если процесс запущен]
│ └─ build:packages → Storybook dev :6006
├─ frontend npm test [только если вручную выбран watch]
│ └─ build:packages → Vitest watch
├─ backend start:dev/debug [только если запущен]
│ └─ Nest watch → dist-dev; это не full test gate
└─ manual checks [решение автора]
├─ frontend targeted test / typecheck / lint / deps
│ └─ каждый standalone wrapper сначала build:packages
├─ backend targeted Jest / typecheck / isolated SQLite
└─ feature complete [локальное требование engineering:60–62]
├─ npm ci → root/dependency lifecycle
├─ frontend verify
└─ backend verify + risk-specific e2e/contract/durability
Автоматического full verify на каждый save в просмотренных application configs нет. Vite transform/HMR не доказывает typecheck, test coverage или production bundling. Backend dev compilation не заменяет configured HTTP/DB suites. Все global editor integrations остаются вне этого inventory.
4.2 Раскрытые gates
frontend verify [всё через &&, stop на первой ошибке]
build:packages
├─ icons: vite build → tsc declarations
└─ ui: vite build → tsc declarations
tokens: JSON export, build script отсутствует
→ openapi:check [temp generation + byte compare types]
→ tsc -b --noEmit
→ eslint . --max-warnings=0
→ test:lint [node:test]
→ vitest run --coverage [JSDOM + Chromium narrow/wide]
→ knip
→ depcruise base
→ depcruise Storybook, reachability/runtime graph
→ tsc -b
→ vite build [app/PWA dist]
→ storybook build [storybook-static]
backend verify [всё через &&]
lint → test:lint → typecheck:app → typecheck:test
→ test:cov --runInBand [Jest в src]
→ build [prisma generate → nest build]
backend test:e2e
build [prisma generate → nest build]
→ sqlite.cjs --all
для каждой functional suite последовательно:
temp DB → штатные migrate deploy → Jest --runInBand → cleanup
backend test:openapi-contract
build → sqlite.cjs openapi-contract.e2e-spec.ts
configured app schema ↔ generator from dist in temporary cwd
docs verify
Markdown lint + relative links/anchors
→ отдельный CHANGELOG lint profile → git diff --check
specs verify
git diff --check [working tree ↔ index, не PR range]
Sources: frontend/package.json:9–38, workspace manifests, backend/package.json:11–38,123–138, backend/test/sqlite.cjs:7–17,57–95, docs/package.json:8–13, specs/package.json:8–14.
4.3 Commit/push/PR
git commit frontend [actual hooksPath .husky/_]
Husky sh -e
→ staged Gitleaks, fail closed + redaction
→ lint-staged → ESLint --fix [selected staged JS/TS]
→ npm run deps → build:packages → full working-tree graph
→ commit-msg → commitlint
git commit specs
commit-msg → commitlint --strict
git commit backend/docs
application hooks отсутствуют в просмотренном checkout
git push feature branch
pre-push application checks отсутствуют
├─ без открытого PR: verify workflow не запускается
└─ с открытым PR: synchronize → PR workflow
PR opened / synchronize / reopened
frontend/backend:
commits [checkout head, npm ci --ignore-scripts, title + commit range]
→ security [full-history Gitleaks + npm audit]
→ verify [fresh npm ci; подготовка; full gates]
→ Sonar только для develop push, не PR
docs/specs:
commits ∥ security ∥ verify [независимые workflows]
root:
commits, включая edited [только root PR]
PR edited
root commits запускается
четыре repo commitlint workflows не подписаны
push develop/main
frontend/backend: commits skipped → security → verify
docs/specs: security ∥ verify; commits отсутствует
daily schedule
frontend/backend/specs/docs: security only
Frontend/backend PR branch не имеет отдельного push-run: это уже полезная защита от двойного CI для одного feature push. Push после merge проверяет новое состояние интеграционной ветки, а не автоматически бесполезно повторяет PR trust boundary.
В Gitea PR ref указывает на head, не на synthetic merge commit — это подтверждено Actions FAQ. Отсутствие merge preview нельзя компенсировать предположением, что зелёный PR автоматически проверен с новым base. Actual stale-branch protection — UNVERIFIED.
4.4 Build/publication/deploy
release:prepare [manual, release/*]
release-it guards + check-release
→ version/lock/changelog commit; tag/push disabled
manual release PR + protected merge + tag vX.Y.Z
→ component image.yml
version + HEAD/revision validation
→ npm ci → canonical verify [backend также e2e]
→ registry login → immutable tag absence check
→ Docker production build/push
→ pull exact digest → labels + container smoke
→ cleanup registry session [always]
→ explicit operator selection of component tags / deploy bundle
→ rollout [отдельный repo, здесь не проверялся]
Docker заново выполняет installation/build внутри packaging environment. Это другая гарантия: чистый Linux image с нужными native modules/assets, а не повтор host typecheck ради того же proof. Backend дополнительно имеет повтор генерации внутри Docker stages — VERIFY-003.
Container smoke сейчас идёт после push, поэтому его failure не отменяет publication. Это не automatic deploy: docs/architecture/deployment.md:76–85,132–135 явно требует отдельно проверить artifact и выбрать bundle, запрещает удалять tag ради retry. Backend workflow отказывается повторно публиковать существующий tag; frontend умеет проверить существующий digest. Без доказательства опасного rollout это не отдельный дефект аудита; immutable guards и operator smoke — KEEP.
5. Guarantee-to-Check Matrix
Для всех rows expected runtime = not measured. Timeout job — верхняя граница ожидания, а не measured runtime. R = read-only для versioned inputs; W = writes outputs/index/config. Даже R-check может иметь временные cache files.
| Check | Guarantee | Trigger / input scope | Read/write behavior | Downstream consumer |
|---|---|---|---|---|
npm ci |
Manifest/lock reproducible installation, не semantic proof | Conventions completion; CI install; все lockfile dependencies | W: node_modules; lifecycle, frontend Husky/specs hooks config | Все Node checks; Docker dependencies |
Frontend build:packages |
JS/CSS/declarations для package exports актуальны | Standalone wrappers, verify, dev/catalog/build; icons/ui целиком | W: package dist | TS, ESLint resolver, Vitest, app/Storybook |
Frontend openapi:check |
Committed schema.d.ts байтово соответствует генерации из принятого snapshot |
Full verify; snapshot + generator version + generated file | R tracked; W private temp + cleanup | Frontend typed API client |
Backend openapi:generate |
Artifact построен из текущего compiled backend | Manual delivery; current DTO/Swagger + dist | W: root ignored openapi.json; сначала build | Явно передаваемый consumer artifact |
| Backend OpenAPI integration | Generator output from current build равен schema configured current app; generator не открывает сеть | Contract change; CI e2e --all | W private DB/temp JSON; не versioned snapshot | Публичный generator и HTTP contract |
Frontend tsc -b, с/без CLI --noEmit |
Repo-wide strict TS configs и test/story/package compilation | typecheck, verify, app build; referenced projects | W buildinfo; app/node configs имеют noEmit | Локальный proof типов, bundle gates |
| Backend typecheck app/test | Production roots и test compilation | verify / manual; app subset и весь src+test | R, incremental:false/noEmit:true | Unit/e2e compilation confidence |
| Full ESLint + config tests | Configured rules, zero-warning policy, validation profile | verify/standalone; repo JS/TS | R для check; lint:fix отдельно W | Code review и next gates |
| lint-staged | Lint selected staged JS/TS + fixes | Frontend commit | W: selected content/index, возможный stash | Commit contents; не full-repo proof |
| Frontend Vitest coverage | Unit/transport/UI + actual layout checks; configured coverage floors | verify/coverage; full configured projects | W: coverage HTML/lcov и test artifacts | Merge gate, Sonar lcov |
| Backend Jest coverage | Colocated src unit suite проходит | verify/test:cov; src specs | W: coverage; общего threshold нет | Merge gate, Sonar lcov |
| SQLite functional runner | Configured HTTP/DB suites на isolated fresh migrations | test:e2e, CI; 19 выбранных suite files | W: temp DB only, cleanup | Authorization, transaction/CAS/replay/contract proof |
test:sqlite |
Auth/cards subset, не все HTTP suites | Manual risk-based iteration; default 2 suite files | W isolated DB; требует заранее generated client | Быстрая DB regression feedback |
| Base dependency-cruiser | Cycles, resolution, public API и layer boundaries | deps/verify/hook; весь src+packages, TS deps | R graph; wrapper W package build | Architecture gate |
| Storybook dependency-cruiser | Runtime reachability stories/preview не доходит до data/auth/routes | deps:storybook/verify; graph + preview, tsPreCompilationDeps:false | R graph; wrapper W package build | Независимость UI catalog |
| Knip | Unused exports/dependencies с repo entry point policy | verify/standalone; all workspaces | R analysis, wrapper W package build | Maintenance feedback |
| Vite/Storybook builds | App/PWA и catalog действительно bundle | verify/build; разные roots/plugins | W dist/storybook-static | Docker app output / UI catalog |
| Commitlint title + range | Заголовок и выбранные commits Conventional Commits | PR events; title + BASE/HEAD | R; job installation W | Required commits status; release history |
| Gitleaks | Staged/history secret scan + redaction/fail closed | Frontend commit index; CI full available history, daily | R inputs; CI downloads scanner; temp hook test | Commit/merge security boundary |
| npm audit | Registry advisory policy проходит для выбранных trees/levels | PR/push/daily security | Network read + возможные local logs; lock unchanged | Required security status |
| Docs Markdown | Syntax + local Markdown links/anchors, включая новые файлы | verify/CI; all Markdown + отдельный CHANGELOG | R | Docs consistency; не Mermaid/semantic proof |
Specs/docs git diff --check |
Whitespace errors в незакоммиченном working-tree diff | local verify, также current CI commands | R; untracked/index-only/committed changes не охвачены | Локальная проверка; в clean CI inputs пусты |
| Docker production build + smoke | Packaging, native runtime/assets/migrations и startup проходят | Release tag; image environment и pulled digest | W image/registry/disposable volumes | Explicit deployment selection |
| Sonar Quality Gate | Remote analyzer принял source и existing unit lcov | Только develop push после gates | W remote analysis | Develop push status, не PR proof |
| Durability / performance / runner regression | Migration/restart/backup proof либо load/runner behavior | Manual risk checks; не ordinary verify | W disposable outputs/DB; regression многократно запускает e2e | Schema-change proof / dedicated investigation |
OpenAPI: четыре разных утверждения
- Backend file equals frontend snapshot: сравнение двух сохранённых JSON доказало бы лишь их текущее совпадение. В этом аудите оно не выполнялось.
- Backend generator freshness:
test/openapi-contract.e2e-spec.ts:108–158вызывает generator from fresh dist в temporary cwd и сравнивает его JSON сcreateOpenApiDocument(app)current source/configured app. Это реально покрывается CI e2e. - Frontend type freshness:
scripts/check-openapi.mjs:10–38генерирует из frontend-local accepted snapshot и сравнивает bytesschema.d.ts; backend freshness из этого не следует. - Release compatibility / latest delivery: предыдущий release и предоставленный frontend artifact — другие inputs. Backend не имеет versioned JSON baseline (
backend/.gitignore:69–70), delivery описана явно (backend/README.md:218–228,frontend/README.md:201–204). Эти guarantees не были заявлены existing check и здесь остаются unverified.
KEEP: independent producer/consumer checks и offline generator guard. Не добавлять обязательный sibling checkout или второй editable contract source.
6. Duplicate Execution Matrix
6.1 Check × triggering context
Это configured occurrences на успешном пути, не частота реальных действий. F = один frontend full verify; B = один backend full verify. Host и Docker считаются раздельно.
| Check | Frontend targeted wrapper | F | Frontend pre-commit | Frontend CI verify job | Backend targeted contract | B | Backend CI verify job: pre-step + B + e2e | Release image job |
|---|---|---|---|---|---|---|---|---|
| Frontend package build | 1 для test/type/lint/deps/knip | 1 | 1 всегда после lint-staged | 1 | — | — | — | 1 host F + 1 Docker app build при cold build |
| Frontend repo tsc build mode | 0 или 1, по wrapper | 2 invocations | 0 | 2 | — | — | — | F + Docker type/build path |
| Frontend base depcruise | 0 или 1 | 1 | 1 | 1 | — | — | — | 1 host F |
| Storybook graph | 0 или 1 | 1 | 0 | 1 | — | — | — | 1 host F |
| Vitest target / full coverage | Targeted subset | 1 full | 0 | 1 full | — | — | — | 1 host full |
| Prisma generation, explicit | — | — | — | — | 1 | 1, поздно | 3 | 3 host + 2 Docker stage path при cold backend image build |
| Nest build | — | — | — | — | 1 | 1 | 2 | 2 host + 1 Docker |
| Backend unit coverage | — | — | — | — | 0 | 1 | 1 | 1 host |
| OpenAPI integration | — | — | — | — | 1 suite | 0 | 1 suite внутри --all | 1 suite внутри --all |
| Backend functional SQLite suites | — | — | — | — | 1 suite | 0 | 19 suite files | 19 host suite files |
Frontend два tsc invocations не равны двум полным recompilations: referenced configs уже noEmit, используются buildinfo. Ускорение от удаления второго не измерено. Backend app/test typecheck имеют перекрытие src, но разные program roots; удаление app-only proof без проверки ambient test effects не рекомендовано.
6.2 Матрица трёх событий
| Событие | Возможный локальный путь | Commit | Push / PR | Где повтор действительно лишний / где оправдан |
|---|---|---|---|---|
| (a) Одна UI правка в frontend | HMR, optional test:run -- <path> → по completion policy npm ci + F |
Staged Gitleaks + ESLint fixes + full deps с package build | Feature push: только PR synchronize, если PR открыт; CI fresh install + F | Targeted test и F дают разные scope/coverage; CI — independent boundary. Hook повторяет package build/base graph после F; для Markdown этот же hook не имеет relevant graph input |
| (b) Backend contract change | Targeted HTTP/contract; test:openapi-contract уже build+suite → B + relevant e2e; generator delivery отдельно |
Backend application hook нет | PR: commits → security → pre-generate + B + build/e2e | Отдельный contract command и --all могут повторить ту же suite; в одной неизменённой local revision повторный targeted run не нужен. В CI 3 generate/2 builds обслуживают одну revision и environment |
| (c) git push / PR | Push сам не вызывает local verify | pre-push checks нет | Feature без PR: pipeline нет. PR open/update: full gates. Merge push develop/main: integration gates. Release tag: image pipeline | PR/branch/tag stages имеют отдельные inputs и trust boundaries. Не удалять tag verification без same-SHA/lock/environment gated proof. Изменение только PR title сейчас не вызывает новый commits check |
UI изменение не запускает backend/specs/docs checks автоматически: это независимые repositories. Backend artifact change требует проверки frontend только при явном изменении принятого frontend input, а не обязательного просмотра соседнего repo для любой backend правки.
7. Findings
VERIFY-001 — Specs CI verify не проверяет проверяемый commit range
- Decision = FIX; Severity = P2; Confidence = High; Effort = S.
- Evidence:
specs/package.json:8–14;specs/.gitea/workflows/verify.yml:13–22;specs/README.md:33–35,52–55,68–70. Для сравнения настоящее content-check в docs:docs/package.json:8–10,docs/.gitea/workflows/verify.yml:23–25. - Claim: required-by-intent specs
verifyв clean CI checkout не проверяет whitespace committed PR/push content. Node setup/install обслуживает фактически пустой worktree diff. - Current mechanism: workflow checkout → setup-node → npm ci →
git diff --check; перед этой командой нет изменения tracked content и не передаются BASE/HEAD.prepareменяет hooksPath, не рабочие Markdown inputs. - Consumer: PR required
verifyиз README; локальный автор использует тот же script. Локально команда полезна для unstaged tracked diff, но не охватывает уже staged changes и новые untracked files. - Impact / actual cost: ошибки whitespace в committed change проходят этот job; ложная уверенность в проверке diff. Отдельные setup/install steps не дают content guarantee. Impact unmeasured: реальный пропущенный PR и CI minutes не наблюдались.
- Why now: это можно исправить существующим Git check, не вводя новую validation framework и не изменяя ответственность specs.
- Minimum change: оставить локальный script локальной проверкой либо явно охватить staged diff; в CI выбрать содержательный commit range и вызвать Git напрямую. Для PR обеспечить наличие base/head commits, проверить merge-base → head; для push — before → after, с явно определённым fallback для creation/zero SHA. Только после этого убрать setup-node/npm ci из verify job; commits/security остаются прежними.
- Guarantees at risk: корректность range и presence of history. Shallow checkout без нужного base даёт неполную проверку; просто удалить job при unchanged required-check settings нельзя.
- Counterarguments / trade-offs: specs README обещает лишь diff, не native OpenSpec validation. Finding не требует запускать schema/semantic validation на каждый push. Docs verify не является no-op: его Markdown lint действительно читает содержимое, хотя последующий worktree diff там также пустой.
- Verification or rollback: в будущем PR с trailing whitespace в committed Markdown должен fail, исправленный — pass; проверить staged/local и first-push fallback отдельно. Достаточен disposable test branch/repo, application suite не нужна. До proof оставить существующий required check и затем сохранить его имя. Rollback — вернуть workflow, не менять Git history.
- Related finding IDs: VERIFY-002; cross-audit 15 только по самостоятельной native OpenSpec policy.
VERIFY-002 — Commitlint не перезапускается при изменении заголовка PR
- Decision = FIX; Severity = P2; Confidence = High; Effort = S.
- Evidence:
frontend/.gitea/workflows/verify.yml:3–7,17–37;backend/.gitea/workflows/verify.yml:3–7,17–37;docs/.gitea/workflows/commits.yml:3–5,23–30;specs/.gitea/workflows/commits.yml:3–5,23–30; обещание —frontend/README.md:116–120,backend/README.md:80–85; работающий root precedent —.gitea/workflows/commits.yml:3–5,19–26. - Claim: все четыре repo workflows фильтруют
opened/synchronize/reopenedи не обрабатываютedited; title input может измениться без rerun validation, при том же HEAD. - Current mechanism: job читает event PR_TITLE и проверяет его вместе с commit range только на перечисленных events. Local commit-msg проверяет commit, а не будущий PR title, и не компенсирует отсутствие trigger.
- Consumer: required
commitsstatus, Conventional Commit policy для PR/release history. Gitea FAQ подтверждаетeditedactivity; отсутствие этого type — конфигурационное, а не отсутствие platform capability. - Impact / actual cost: green status относится к прежнему title; после invalid rename policy proof становится stale. Фактический merge с таким title не наблюдался; Impact unmeasured.
- Why now: несоответствие дешёвого check собственному input trigger устраняется малой правкой; не нужны новые rules.
- Minimum change: обеспечить commits/title check на
edited; docs/specs могут добавить type в отдельный commits workflow. Для frontend/backend сохранить selective dispatch: metadata-only event должен обновить commits proof без нового Chromium/Jest/build run. Не добавлятьeditedв full workflow без условия, если это просто умножит дорогие gates. - Guarantees at risk: текущие names required checks и отношение skipped jobs к имеющимся success statuses. При разделении workflow нельзя случайно сделать старый обязательный context недостижимым или заменить failed verification на skipped success.
- Counterarguments / trade-offs: title lint — выбранное самим проектом правило, не runtime-security boundary. Его можно отдельно пересмотреть как policy, но workflow сейчас обещает его enforce. Содержание PR body тоже может давать
edited; желательно проверять title-change payload, если платформа предоставляет нужные fields, без сложного custom classifier. - Verification or rollback: на existing successful PR изменить только title на invalid, убедиться в новом failed commits check; вернуть valid title и получить success без нового verify run. Проверить branch protection contexts и поведение skipped statuses на фактической Gitea. Rollback — trigger/job changes, contexts восстанавливаются согласованно.
- Related finding IDs: VERIFY-001; остальные guarantees independent.
VERIFY-003 — Backend preparation повторяется и не принадлежит standalone verify целиком
- Decision = SIMPLIFY; Severity = P2; Confidence = High; Effort = S.
- Evidence:
backend/.gitea/workflows/verify.yml:83–89;backend/.gitea/workflows/image.yml:30–33;backend/package.json:12–13,22–34;backend/.gitignore:7–8;backend/prisma/schema.prisma:1–5;backend/src/prisma/prisma.service.ts:1–5;backend/Dockerfile:8–10,12–22;backend/test/openapi-contract.e2e-spec.ts:139–156. - Claim: в одном обычном verify job explicit generation вызывается 3 раза, Nest build 2 раза. Одна revision проверяется без changes между этими шагами. Local standalone
verifyпри отсутствующем ignored client доходит до typechecks до собственной generation. - Current mechanism: (1) CI explicit prisma generate; (2) verify заканчивается build = generate + nest build; (3) test:e2e начинает тот же build. Root
verifyне имеет preparation перед typed lint/typecheck. Installed client manifest этой версии не имеет postinstall generation. Docker production path также наследует direct generate из dependencies stage, затем генерирует в package build ещё раз. - Consumer: typed source import generated Prisma, app/test typechecks и unit tests; runtime OpenAPI generator импортирует
dist/src/app.module.js. Последний требует свежую сборку, а не просто возможность Jest transpile source. - Impact / actual cost: подтверждён лишний запуск двух host generations и одного host Nest build; cold Docker path ещё одного generate. Потенциальный cold-local failure выводится из import/order, но fresh checkout runtime-воспроизведение не выполнялось. Impact unmeasured для latency/CPU; число explicit configured calls измерено статически.
- Why now: same job, same SHA и одно environment дают возможность reuse без ослабления независимой CI boundary.
- Minimum change: сделать standalone verify владельцем generation до typed consumers, оставить один Nest build; после successful verify вызвать существующий
node test/sqlite.cjs --allбез второй сборки. Удалить workflow pre-generate только после переноса подготовки в verify. Сохранить standalonebuildиtest:e2eself-contained. В Docker перенести direct generation в development target, если production build уже гарантирует её: development должен сохранить generated client. - Guarantees at risk: свежесть generated client для schema change; наличие current dist для OpenAPI; copied proto assets и native Linux modules; standalone command UX. Кеширование host-generated dist между разными environments не предложено.
- Counterarguments / trade-offs: первый CI generate необходим сейчас — его удаление само по себе ломает clean typechecks. Второй build необходим standalone
test:e2e, но избыточен в composed CI после verify. Build в Docker не удаляется: он доказывает packaging environment. Generation/internal build cache могут уменьшать стоимость повтора, но не устраняют лишний invocation. - Verification or rollback: один clean disposable checkout с approved install: standalone verify → existing SQLite --all; лог должен показать 1 explicit host generate и 1 Nest build при тех же 19 suites и runtime schema comparison. Schema change должен влиять на типы и generator. Development и production Docker targets проверить отдельно. Rollback — scripts/workflow/stage ordering; source/data migrations не нужны.
- Related finding IDs: VERIFY-004, только общая тема подготовки; не объединять repos общим tooling.
VERIFY-004 — Frontend pre-commit всегда делает package build и whole-repo graph
- Decision = SIMPLIFY; Severity = P2; Confidence = High; Effort = S.
- Evidence:
frontend/.husky/pre-commit:1–3; installed launcherfrontend/.husky/_/h:6,14–22;frontend/package.json:25–26,33,36–38;frontend/packages/icons/package.json:9–20;frontend/packages/ui/package.json:9–24;frontend/dependency-cruiser.cjs:24–29,78–86. - Claim: каждый successful frontend commit, включая Markdown-only, после staged lint запускает два package builds и full base graph. Команда не зависит от staged input relevance и не повторяет именно staged proof.
- Current mechanism: actual hooksPath → Husky
sh -e→ Gitleaks index → lint-staged →npm run deps→ build workspaces → depcruise src/packages working tree. Final verify/CI уже включают тот же base graph и отдельный Storybook graph. - Consumer: local commit readiness. Граф working tree может блокировать commit из-за незакоммиченного unrelated code; это отличается от selected staged ESLint input.
- Impact / actual cost: 2 workspace library builds + whole-repo dependency analysis на каждый такой commit, даже при отсутствии changed code/config inputs; после final verify — повтор в той же local revision, если код не менялся. Impact unmeasured: hook duration, частота commits и
--no-verifyне измерены и не утверждаются. - Why now: перенести existing whole-repo proof в existing final/CI boundary проще, чем писать новый staged graph builder.
- Minimum change: убрать
npm run depsиз mandatory pre-commit; сохранить full graph в final verify/CI. Сохранить fail-closed staged Gitleaks и staged lint. Если early graph feedback обязательно по принятому workflow, минимально ограничить existing command relevant source/package/TS/resolver/dependency config changes, не считать content-only import diff полноценным incremental graph proof. - Guarantees at risk: более поздняя обратная связь о cycles/import boundaries. CI guarantee не теряется при сохранении full graph и required verify; staged lint обязан получать актуальные package declarations при relevant package changes.
- Counterarguments / trade-offs: standalone deps prep нужна для fresh package exports, поэтому её нельзя убрать глобально из command. Local graph catches errors до отправки и полезен, если runtime мал. Без measured duration рекомендована минимальная смена layer, не сложная cache/fingerprint orchestration.
- Verification or rollback: будущий Markdown-only commit должен выполнять staged secret scan и commitlint, без package build/graph. Secret fixture должен по-прежнему fail до downstream commands; existing
scripts/test-pre-commit.mjsиспользовать при изменении hook. Import cycle должен fail в full verify/CI. Проверить relevant staged TS lint на clean/fresh declarations. Rollback — вернуть одну hook command. - Related finding IDs: VERIFY-003; cross-audit 10 — implementation quality custom hook test, здесь не исследовалась.
8. DELETE / SIMPLIFY / KEEP / INVESTIGATE
| Decision | Механизм | Основание и сохраняемая гарантия |
|---|---|---|
| DELETE, условно после FIX | Node setup/npm ci в specs verify job | После перехода на meaningful Git range Node не consumer; commits/security dependency checks остаются. VERIFY-001 |
| SIMPLIFY | Backend host generation/build DAG и Docker duplicate generate | Один свежий artifact в каждом environment; не удалять pre-type preparation. VERIFY-003 |
| SIMPLIFY | Mandatory full deps в frontend pre-commit | Whole-repo graph оставить final + required CI; staged Gitleaks/lint сохранить. VERIFY-004 |
| FIX | Specs CI input range; title edited triggers | Proof должен зависеть от actual checked input. VERIFY-001/002 |
| KEEP | Независимый CI после local checks | Local success не trusted proof для merge; install/checks повторяются на новой boundary обоснованно |
| KEEP | SQLite functional suites и temp DB guard | Unit mocks не заменяют authorization/CAS/transaction/replay proof; e2e-env отклоняет неisolated DB |
| KEEP | Current-build OpenAPI/runtime comparison и frontend byte check | Разные producer/consumer inputs; standalone offline generator guard сохраняется |
| KEEP | Base и Storybook dependency graphs | TS graph и runtime reachable graph имеют разные policy/inputs |
| KEEP | JSDOM и narrow/wide Chromium | DOM logic не доказывает реальную геометрию; viewports не OS matrix |
| KEEP | Full coverage в final/CI и Sonar lcov | Targeted tests без coverage — iteration feedback; не заменяют global coverage floor или report consumer |
| KEEP | Security before expensive verify; fail-closed exits | Cheap failures останавливают дорогую работу в пределах DAG; не превращать advisory/secret fail в green |
| KEEP | Feature PR-only verification, event-scoped cancellation, immutable image labels/tags | Уже уменьшает redundant runs и защищает artifact identity; фактическая server configuration остаётся unverified |
| KEEP | Performance/durability отдельными commands | Wall-clock shared-runner budget отдельно; schema-risk proof не отменять из-за того, что он вне ordinary verify |
| INVESTIGATE | npm/browser cache | В workflows не задан cache input/action; persistent runner cache может уже работать. До timing/hit proof не вводить новый cache layer |
| INVESTIGATE | Full app gate для Markdown-only application PR | Trigger сейчас whole-repo. Сначала определить affected paths и required-check semantics; не вводить path filters, оставляющие required status pending/skipped |
| INVESTIGATE | Второй frontend tsc, перекрытие backend app/test typecheck | Invocation overlap есть; cache и program-root differences не позволяют доказать ценность удаления без diagnostics comparison |
| INVESTIGATE | PR head freshness against updated base | Gitea не строит merge preview; actual branch protection не доступна в static checkout |
Complexity-pass по фактическому ponytail-audit
shrink:сократить повтор host generation/build в backend composed CI до одной подготовки; reuse existing SQLite runner. [backend/package.json:12,28,34;.gitea/workflows/verify.yml:83–89]delete:убрать mandatory whole-repo deps/build из frontend pre-commit; replacement — existing final/CI graph gate. [frontend/.husky/pre-commit:3]native:заменить пустой CI worktree diff + Node installation в specs на Git commit-range check. [specs/.gitea/workflows/verify.yml:18–22]
net: lines/dependencies reduction not measured, подтверждённых кандидатов на удаление dependency нет. Skill заканчивается оценкой net; числовой -N lines здесь не выдумывается, поскольку patch не готовился. Это не proposal удалить checks как таковые.
9. Cost & benefit
| Изменение | Ожидаемый класс benefit | Фактическое основание | Обязательный regression proof |
|---|---|---|---|
| Meaningful Git range без Node в specs job | CI minutes, maintenance, trust in gate | Один setup-node и один npm ci станут unnecessary для Git-only consumer; время not measured | Committed whitespace fail, safe range/fetch/fallback, preserved required context |
| Metadata-only title check | Reliability; avoidance of expensive metadata rerun | Сейчас edited не обрабатывается; новых минут/сокращения not measured |
Invalid title fail + valid pass без app rerun; no skipped-status bypass |
| Backend preparation once | CI CPU/minutes и local reproducibility | 3 explicit host generate → intended 1; 2 host build → intended 1 на composed path; время not measured | Cold checkout/types/schema/dist, same e2e selection, runtime OpenAPI equality |
| Lean frontend pre-commit | Developer waiting, cognitive load | Один unconditional package-build/full-graph chain можно снять с hook; время/частота not measured | Secrets remain fail closed, staged lint meaningful, cycle caught at required CI |
| Iteration without full coverage/build | Local runtime и feedback latency | Existing targeted commands уже есть; usage frequency/agent tokens not measured | Whole-repo final/CI и relevant risk tests остаются |
| Optional download caching | Potential network/CI minutes | Workflow cache config отсутствует; actual hit/miss state UNVERIFIED | Same npm ci + lock integrity; Linux native rebuild; Gitea cache compatibility |
Ни runtime savings приложения, ни процентов ускорения, ни сокращения agent tokens не измерено. Уменьшение числа explicit commands не равно пропорциональному уменьшению времени.
10. Recommended Tiered Verification Policy
Это рекомендация, не изменённые инструкции. Сейчас оба engineering-файла требуют npm ci и full verify при code/dependency completion; audit read-only не отменяет это правило задним числом.
| Layer | Frontend | Backend | Specs/docs/root | Guarantees retained |
|---|---|---|---|---|
edit |
HMR + relevant test:run -- <path> без coverage; targeted ESLint; package preparation при первом запуске/изменении packages |
Relevant Jest pattern; configured HTTP/SQLite subset при boundary changes; current generated client до typed checks | Изменённый текст/anchors; локальный diff, staged отдельно | Быстрый observable feedback; money/auth/CAS cases по затронутому риску |
feature complete |
Один full verify после последнего relevant input change; targeted visual/a11y proof | Один full verify с self-contained preparation + relevant HTTP/DB suites; contract proof при wire change; durability при schema/data change | Docs full Markdown/link gate; specs meaningful diff + native validation при requirements/schema change; root config/text checks | Full types/lint/coverage/architecture/bundle и risk-specific proof |
pre-commit |
Fail-closed staged secrets → staged lint/fix → commit-msg; full graph оставить final/CI | Existing policy без новых integration hooks | Specs commit-msg; root/docs не добавлять full app hook | Проверяется actual commit input; fix не выдаётся за read-only proof |
CI |
Fresh lock installation → full verify + Chromium; full graph и coverage floors; security и commits required | Fresh generated client → full verify → existing isolated SQLite --all без повторного build; commits/security required | Git-range specs check; full docs links; title on edited; root commitlint | Independent merge proof; whole-repo cross-consumer regressions; no ignored errors |
scheduled |
Existing daily security; deep suite только при обоснованном риске | Existing daily security; performance на dedicated/manual environment; runner-regression не каждый PR | Existing daily security; native/store checks по owned risk, не новый обязательный blanket process | Advisory drift ловится без edit; load noise не блокирует functional gate |
Installation локально следует привязать к manifest/lock/Node/install-state change, а не каждой source правке; в CI сохранить воспроизводимую installation. Это часть общей local/agent policy — см. cross-audit 14, без повторного отдельного finding.
Что можно проверять адресно, что нельзя считать полным proof
| Check | Safe targeted use | Что incremental selection пропускает |
|---|---|---|
| ESLint | Selected files с тем же typed config и fresh declarations | Новые config/rule effects на untouched files; import/type changes у consumers |
| Jest/Vitest | Relevant suite/pattern/project без coverage during iteration | Shared helper/provider/transport регрессии в других suites, global coverage floors |
| SQLite | Existing runner с explicit affected suite | Другие access/transaction consumers, shared migration/schema regressions; schema change требует broad DB proof |
| Typecheck | Existing project boundary, не случайный список changed .ts |
Reverse dependencies и public type consumers; production isolation при смешивании test roots |
| dependency-cruiser | Можно выбирать момент full scan по relevant input paths | Whole-graph cycles/reachability/resolver effects; changed files only не эквивалент full graph |
| Knip | Full at completion/CI, optional during iteration | Reverse references, config-discovered entries и dependency usage across workspaces |
| OpenAPI | Producer current-build proof; consumer provided snapshot proof | Breaking changes against old release и delivery freshness вне explicit input set |
| Markdown relative links | Changed source + incoming references при локальном переносе | Удаление target ломает unchanged incoming links; final docs full check сохраняется |
| App/Storybook/image build | Local selective build для affected artifact | Shared package/theme/plugins влияют на оба frontend consumers; image native/assets не доказаны host build |
Fail-fast, parallelism и resources
- Frontend/backend jobs действительно выстроены по
needs; failed commits/security не запускают expensive verify. Daily event не запускает verify. Внутри scripts&&останавливает downstream checks. - Frontend pre-commit использует
sh -e; explicit Gitleaks|| exit $?передаёт failure, а не маскирует его. Temporary OpenAPI checks и SQLite runner устанавливают ненулевой exit code при failure.continue-on-error/blanket|| trueв прочитанных workflows отсутствуют. - Docs/specs jobs независимы и могут занимать разные runners одновременно. Последовательность одного application DAG не ограничивает server-wide capacity; README указывает настройку
runner.capacity: 1вне repo. Actual capacity — unverified. - SQLite runner уже даёт каждой suite отдельный temp DB и запускает её
--runInBand; suites с explicit listen используют port 0. Это уменьшает DB/port collisions, но не доказывает безопасность полной параллелизации всех suites. Общий generated client/dist и CPU/memory остаются shared resources. - KEEP serial default: без timings не добавлять Jest/SQLite/Chromium параллельные jobs. Не выполнять одновременно повторные builds, которые перезаписывают одни outputs. Unit/static parallelism допустим только после single preparation и доказанного resource isolation, если measured critical path это оправдывает.
- Chromium install сейчас идёт до full verify, то есть до cheap type/lint failures. Возможен более ранний static stage, но новый составной gate/повтор package build требует cost proof; это не подтверждённый отдельный finding.
Explicit guarantees retained
- Денежная точность и boundary regressions остаются в existing meaningful unit/HTTP/DB checks; audit не предлагает заменить их coverage percentage.
- Real SQLite authorization, transactions/rollback, CAS, replay/idempotency и connection-isolation proof остаются CI functional suites; DB никогда не заменяется пользовательской.
- Generated client и current dist свежи до своих consumers; runtime contract сравнивается с current generator без внешней сети.
- Frontend accepted snapshot/type equality, full types и reverse-consumer proof остаются локальными и independent от sibling checkout.
- Full graph cycles/public API/reachability, Chromium layout и app/catalog packaging остаются final/CI checks.
- Staged secrets/history security не bypass; failures не становятся green; required contexts не ослабляются через skipped jobs.
- Release SHA/version identity, immutable tags, Linux native/assets, post-publication digest smoke и explicit rollout selection остаются.
- Durability при data/schema change и controlled lifecycle regression tests не исключаются из risk-based verification из-за их стоимости; содержательность assertions — отдельный аудит 08.
11. Top actions
Quick wins: подтверждённые механизмы, малый diff
| Rank | Действие | Value / risk / effort | Finding |
|---|---|---|---|
| 1 | Сделать specs CI whitespace-check явного commit range; затем убрать Node install из этого Git-only job | Убирает no-op proof и лишнюю installation; риск неверного range покрывается tiny fixture; S | VERIFY-001 |
| 2 | Добавить PR title edit coverage, сохранив selective metadata-only execution и проверив contexts | Исправляет stale check без full pipeline rerun; S | VERIFY-002 |
| 3 | Свести backend host preparation к одному generate/build на revision, сохранив clean standalone verify и existing e2e runner | Подтверждённый same-job повтор; cold-checkout/schema/dist proof обязателен; S | VERIFY-003 |
| 4 | Снять unconditional full graph/build с frontend pre-commit; оставить staged security/lint и required final/CI graph | Улучшает каждый commit path без нового tooling; риск только более поздней обратной связи; S | VERIFY-004 |
Решения, требующие тестового подтверждения
| Rank | Действие | Необходимое подтверждение | Finding |
|---|---|---|---|
| 5 | Устранить второй generate в backend production Docker path, оставив его development target | Обе Docker targets сохраняют current client, native modules/assets и runtime smoke | VERIFY-003 |
Новое ADR для перестановки уже существующих checks не требуется. Новая policy удаления обязательного gate или изменения public delivery/merge trust boundary потребует отдельного согласованного решения; такой migration здесь не предлагается. Cache tuning и удаление перекрывающихся typechecks не входят в confirmed top actions.
12. Cross-audit signals
- Audit 10 — custom tooling:
frontend/scripts/check-image-publication.cjs,scripts/test-pre-commit.mjs, backend runner-regression/durability entry points; отдельно проверить maintenance/consumer ownership, без ревью их алгоритмов здесь. - Audit 14 — agent/local workflow:
frontend/.ai/conventions/engineering.md:60–62,backend/.ai/conventions/engineering.md:60–62; mandatory npm ci + full completion gate и session повторяемость относятся к policy использования commands; реальные session counts здесь не измерены. - Audit 08 — test intent:
backend/test/openapi-contract.e2e-spec.ts, SQLite functional suites и frontend browser tests; этот аудит подтверждает selection/trigger, не достаточность assertions. - Audit 12 — dependency/security policy:
backend/.gitea/workflows/verify.yml:62–65; разные audit levels и advisory option требуют dependency-policy проверки, не переноса network audit на data edit. - Audit 15 — specs/docs:
specs/README.md:18–35,specs/.gitea/workflows/verify.yml; необходимость и version ownership native OpenSpec validation — отдельно от подтверждённого no-op Git range.
13. Open questions / verification plan
| Вопрос, меняющий решение | Статус | Самый дешёвый способ подтверждения |
|---|---|---|
| Required commits/security/verify contexts действительно обязательны? Проверяется ли outdated base/head? | UNVERIFIED: локальный workflow не задаёт server protection | Read-only Settings/branch protection export и один existing PR status; не запускать full suite |
| Фактическая Gitea версия поддерживает concurrency/edited/skipped status behavior как ожидает README? | UNVERIFIED для сервера; docs подтверждают edited/head semantics | Server version + существующий cancellation log; для VERIFY-002 metadata-only rename на disposable PR |
| Насколько дорогие npm ci, package build, Chromium install, повтор Nest build? Есть ли persistent cache? | not measured | Step timestamps одного успешного PR и image run, runner cache/hit logs; после changes сравнить те же steps; не запускать full pipeline ради аудита |
| Clean standalone backend verify действительно fails до generation? | Выводится из import/order; runtime fresh-install proof не выполнялся | При реализации VERIFY-003 один disposable clean checkout с normal approved install; проверить до/после. Не использовать локальный generated directory как baseline |
| Можно ли удалить второй frontend tsc или backend app-only typecheck без потери diagnostics? | INVESTIGATE, не top action | Compare configured compiler roots/diagnostics на real type regression; удалить только после equivalence proof, не ради invocation count |
| Нужен ли mandatory local graph до каждого commit, если final/CI его сохраняют? | Trade-off VERIFY-004 | Выбрать feedback layer у владельца; измерить один existing hook timing. Не писать новый graph-diff/cache инструмент |
| Есть ли гарантированное подтверждение принятого frontend artifact перед component rollout? | UNVERIFIED для deploy repo | Read-only release/deployment record с producer SHA/consumer snapshot provenance; separate deployment owner, без обращения к банковским API |
Вопросы о benchmark SLAs, существующих business assertions и advisory correctness намеренно не разворачиваются в этом аудите. Отсутствие run/log evidence не означает отсутствие защиты.
14. Машинно-считываемая таблица для консолидации
| ID | Decision | Severity | Confidence | Repo | Files | One-line impact | Effort | Related IDs |
|---|---|---|---|---|---|---|---|---|
| VERIFY-001 | FIX | P2 | High | specs | specs/package.json; specs/.gitea/workflows/verify.yml | Clean CI checks empty worktree diff, not committed changes; Node install gives no content proof | S | VERIFY-002 |
| VERIFY-002 | FIX | P2 | High | frontend,backend,specs,docs | frontend/.gitea/workflows/verify.yml; backend/.gitea/workflows/verify.yml; specs/.gitea/workflows/commits.yml; docs/.gitea/workflows/commits.yml | PR title edits leave previous Conventional Commit status stale | S | VERIFY-001 |
| VERIFY-003 | SIMPLIFY | P2 | High | backend | backend/package.json; backend/.gitea/workflows/verify.yml; backend/.gitea/workflows/image.yml; backend/Dockerfile | Same CI revision explicitly generates client 3 times and builds twice; standalone preparation occurs late | S | VERIFY-004 |
| VERIFY-004 | SIMPLIFY | P2 | High | frontend | frontend/.husky/pre-commit; frontend/package.json | Every commit runs package builds and full graph even without relevant staged code | S | VERIFY-003 |