Files
main/audits/2026-10-11/reports/12-dependencies-and-configuration-report.md
codex-bot d07fbfabb1 docs: archive technical audit 2026-10-11 in develop (#36)
Переносит архив `audits/2026-10-11/` (19 файлов) из codex/audit-remediation-2026-10-11 в develop и добавляет точечный allowlist в .gitignore.
2026-10-17 19:38:03 +03:00

58 KiB
Raw Permalink Blame History

Аудит 12 — Dependencies & Configuration

1. Audit metadata

  • Audit ID/name: 12 / Dependencies & Configuration.
  • Дата: 2026-10-11.
  • Режим: read-only для frontend, backend, specs, docs; единственный создаваемый workspace artifact — этот отчёт.
  • Scope: необходимость dependencies, direct/transitive/peer ownership, toolchain, compiler/test/build configuration, env authority, generated inputs и воспроизводимость локальной подготовки. CI timings, качество assertions, уязвимости и бизнес-контракты не аудировались.
  • Skill: установленный ponytail-audit прочитан через Skill tool и применён к complexity-pass. Correctness findings получены отдельно по протоколу аудита 12. Прочитан verification-before-completion для проверки итогового артефакта. Graphify skill прочитан; существующего graphify-out/graph.json в workspace нет, install/extraction не выполнялись ввиду read-only контракта.
  • Предыдущие материалы: technical-audit-2026-10-11.md прочитан как реестр гипотез; его выводы и измерения не приняты за доказательство. Отчёт 11 использован для разграничения ответственности, его timings/результаты не пересчитывались.

Workspace: /Users/ksv741/Project/vibe/WealthLedger. Найдены четыре самостоятельных checkout и отдельный root Git repo:

Repo Путь HEAD SHA Ветка Начальный status
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
root, вспомогательная область ./ dc030f84c979cedb2628ef4bd97c62d6c63a9256 release/0.2.1 clean

Отдельный deploy/ не исследовался. Root Compose рассматривается только как доступный development configuration consumer, не как доказательство текущего server deployment. Личные .env, базы, сертификаты и credentials не читались.

Выполненные проверки

  1. Read/Glob/Grep: repo instructions; manifests и верхние секции пяти lockfiles; выбранные lockfile nodes; compiler/build/test/lint/Storybook/Knip/dependency configs; env validators и consumers; generated-artifact callers; setup instructions.
  2. Во всех пяти Git repo: git status --short --branch, git rev-parse HEAD; в application repos также git ls-files -- <config/generated/lock patterns> для проверки tracking boundary.
  3. В frontend и backend после source "$HOME/.nvm/nvm.sh" && nvm use --silent: node --version, npm --version → v24.21.0 / 11.19.0; npm ls --depth=0 --ignore-scripts → exit 0.
  4. Там же npm ls --all --json --ignore-scripts с set -o pipefail и выводом problems/error через inline Node stdin reduction → оба exit 0, problems: [], error: null. Это проверка установленного dependency graph, не clean-install/build proof.
  5. Там же npm query '*' --package-lock-only --ignore-scripts с inline stdin reduction → inventory виртуального graph из lockfile, без install или записи нового lockfile. Метод и результаты ниже.
  6. Backend: npm explain better-sqlite3 source-map-support ts-loader --ignore-scripts → подтверждены consumers и цепочка optional/required peers. Команда ничего не удаляет.
  7. Context7: документация npm об allowScripts и Prisma о явной генерации client. Дополнительно прочитаны versioned Prisma v7 deployment/workflow docs. Unversioned workflow URL перенаправил на новую модель Prisma; эта страница не использована для рекомендаций к установленной 7.10.0.
  8. Итоговая проверка файла: чтение нового отчёта, whitespace-check относительно /dev/null, git diff --check, повторный status/HEAD пяти repos. Результат заключительной проверки записан в разделе 10.

Npm выводит предупреждение Unknown user config "//registry". Это user-level configuration за пределами checkout; её содержимое не читалось. Команды inventory завершились успешно. Предупреждение не объявлено дефектом project configuration.

Не запускались: install/prune/update, npm audit, codegen, migrations, application/CLI watch processes, tests, lint, build, full verify, Docker, OpenSpec validation, обращения к брокерским/банковским API, CI runs, commit/PR. Исполняемые audit tools не создавались. Изменений manifests, lockfiles, sources или generated artifacts нет. Runtime-воспроизведение fresh setup и экономия времени/размера — UNVERIFIED / not measured.

2. Executive verdict

  1. Факт / FIX, P2: самостоятельный backend quick start пропускает Prisma generation. npm ci → migrate deploy → start:dev не создаёт ignored generated/prisma, который импортирует приложение. CI, Docker и root setup явно готовят client, поэтому существующий тёплый checkout скрывает дефект подготовки. DEPS-001.
  2. Факт / DELETE, P2: backend использует штатный Nest tsc builder, но прямо устанавливает ts-loader. Его required peer приводит в graph Webpack и minimizer/Terser; optional peers Nest CLI сами по себе не требуют этой ветки. Прямая декларация source-map-support также не имеет project caller. DEPS-002.
  3. Факт / SIMPLIFY, P2: runtime Prisma adapter использует better-sqlite3@12.11.1, а smoke/durability SQL checks — прямой 13.0.3. В production dependency tree сохраняются обе версии. Прямой драйвер нужен, но выбранный major не согласован с runtime owner. DEPS-003.
  4. Факт / FIX, P3: start:debug не задаёт NODE_ENV=development, в отличие от start:dev. При env example и отсутствии внешнего NODE_ENV debugger получает выключенный Swagger и Secure-cookie policy, хотя startup log называет окружение development. Это небольшой setup drift, не подтверждённая уязвимость. DEPS-004.
  5. KEEP: peers без прямых imports, Prisma CLI в production, независимые lockfiles, OpenAPI snapshot/types, Node alignment и разделение JSDOM/Chromium обоснованы реальными consumers. Различие TypeScript frontend/backend и Sonar/application profiles не требует автоматического выравнивания.
  6. UNVERIFIED: clean installation на Linux/macOS, фактическое удаление транзитивной Webpack-ветки после будущего cleanup, размер image/bundle, Sonar server/analyzer version и настройка глобального OpenSpec CLI. Их нельзя вывести из зелёного npm ls.

Итог: четыре подтверждённых findings: три P2 и один P3; P0/P1 не установлены. Удаление двух direct dev declarations и согласование одного runtime driver полезнее введения общего cross-repo tooling или нового валидатора.

3. Inventory & coverage

3.1 Manifests, versions и lockfiles

Repo Production direct keys Dev direct keys Toolchain / назначение
frontend root 23, включая 3 local workspace dependencies 52 React 19.3.0, Vite 8.3.0, TS 5.9.3, Vitest 5.0.0, Storybook 10.6.0
backend 26 37 Nest 12.x, Prisma 7.10.0, TS 6.0.3, Jest 30.5.1 / ts-jest 29.4.12
specs 0 5 Commit/release tooling; OpenSpec отсутствует в local npm dependency contract
docs 0 7 Commit/release tooling + Markdown lint/relative-links
root 0 5 Commit/release tooling

Метод: подсчёт ключей dependencies и devDependencies прочитанных root manifests. Это число declarations, не уникальных packages во всём workspace. Дополнительно полностью прочитаны три frontend workspace manifests, то есть всего восемь manifests. Их peer/dev declarations не суммируются с root: одна и та же установка deduped, но contracts владельцев самостоятельны.

Все пять прочитанных lockfile headers — npm lockfileVersion 3; root names/versions/direct declarations в просмотренных header sections согласованы с соответствующими manifests. Другой tracked JS lockfile в выбранном application tracking inventory не обнаружен. Все пять .nvmrc содержат 24.21.0; application Dockerfiles используют node:24.21.0-bookworm-slim. Версии registry dependencies в direct manifests exact; file: links frontend намеренные.

3.2 Transitive / peer / optional / platform inventory

Метод: один npm query '*' --package-lock-only --ignore-scripts на application repo. Из JSON отброшены nodes с пустым location; посчитаны nodes и truthy поля dev, optional, peer, hasInstallScript, наличие os || cpu. Workspace nodes включены. Это npm virtual graph nodes, не объём диска, не только external names и не число реально установленных platform packages.

Метрика frontend backend
Nodes с непустым location 1294 1119
dev: true 1192 738
optional: true 191 43
peer: true 0 43
hasInstallScript: true 4 8
Есть os или cpu 178 34

Flags пересекаются и не образуют разбиение. peer: 0 у frontend не означает отсутствия peer contracts: прямо объявленный peer provider не обязан иметь этот installation flag. Например, Mantine charts → Recharts → react-is доказаны installed manifests. Platform entries в lockfile не означают, что на Darwin установлены все Linux/Windows binaries.

Lockfile-marked lifecycle nodes:

  • Frontend: esbuild@0.28.2, fsevents@2.3.3 (optional), msw@2.15.0, unrs-resolver@1.12.2.
  • Backend: @parcel/watcher@2.6.0, nested better-sqlite3@12.11.1, @prisma/engines@7.10.0, @scarf/scarf@1.4.0, bcrypt@6.0.0, prisma@7.10.0, protobufjs@7.6.5, unrs-resolver@1.12.2.

Frontend allowScripts разрешает esbuild/fsevents; backend разрешает актуальные native/Prisma/protobuf/resolver nodes и содержит разрешение для better-sqlite3@13.0.3, у которого install hook отсутствует. Это не два native build hooks: версия 13 поставляет prebuilds, версия 12 имеет prebuild-install || node-gyp rebuild. Неисполнение MSW/scarf и optional/fallback hooks не объявлено поломкой без proof необходимого поведения. Policy owner — root manifest каждого npm repo, не dependency/workspace manifest.

3.3 Dependency Decision Register

Полный перечень exact versions доступен в frontend/package.json:39–116, backend/package.json:40–105; ниже все direct declarations сгруппированы по реальным ролям. KEEP для группы означает установленную роль в stack/configuration, не semantic audit каждого её API.

Repo / class Dependencies Consumer / назначение Decision
frontend runtime UI react, react-dom, react-router, @mantine/core, @mantine/hooks, @mantine/notifications, motion App/providers/routes, form/view imports, RouteTransition KEEP
frontend runtime charts/dates @mantine/charts, recharts, react-is, @mantine/dates, dayjs DonutChart/AreaChart, DateInput/DatePickerInput, locale; Recharts/react-is — peers KEEP
frontend forms/i18n react-hook-form, @hookform/resolvers, zod, i18next, react-i18next AuthForm, BankCard/Operation forms и локализованные schemas KEEP
frontend runtime HTTP/cache @tanstack/react-query, openapi-fetch, openapi-react-query src/shared/api/client.ts:1–4, App QueryClient/provider KEEP; разные уровни одного typed flow
frontend local packages @wealthledger/icons, @wealthledger/tokens, @wealthledger/ui App и Storybook theme/assets/components; exports → dist/JSON KEEP
frontend build/type/PWA typescript, @types/node, @types/react, @types/react-dom, vite, @vitejs/plugin-react, @rolldown/plugin-babel, @babel/core, babel-plugin-react-compiler, vite-plugin-pwa TS configs, Vite React compiler preset/PWA; package library builds KEEP
frontend tests/catalog vitest, @vitest/coverage-v8, @vitest/browser-playwright, playwright, jsdom, @testing-library/react, @testing-library/jest-dom, msw, storybook, @storybook/react-vite, @storybook/addon-docs Vitest projects/setup/server, browser provider, .storybook/main.ts KEEP
frontend graph/unused dependency-cruiser, knip scripts и разные graph/unused-declaration policies KEEP
frontend lint core eslint, @eslint/js, typescript-eslint, globals, eslint-import-resolver-typescript, eslint-plugin-import-x eslint.config.mjs:1–21,133–164 KEEP
frontend lint plugins @eslint-react/eslint-plugin, @stylistic/eslint-plugin, @tanstack/eslint-plugin-query, @vitest/eslint-plugin, eslint-plugin-jest-dom, eslint-plugin-no-unsanitized, eslint-plugin-perfectionist, eslint-plugin-react-hooks, eslint-plugin-react-refresh, eslint-plugin-regexp, eslint-plugin-security, eslint-plugin-sonarjs, eslint-plugin-storybook, eslint-plugin-testing-library, eslint-plugin-unicorn Все импортированы/подключены flat config; production/test/story profiles различаются KEEP; полезность отдельных rules вне этого аудита
frontend hooks/release husky, lint-staged, @commitlint/cli, @commitlint/config-conventional, release-it, @release-it/conventional-changelog, conventional-changelog-conventionalcommits prepare/hooks/staged scripts, commitlint, release plugin/preset KEEP
backend HTTP/framework @nestjs/common, @nestjs/core, @nestjs/config, @nestjs/platform-express, @nestjs/swagger, class-transformer, class-validator, reflect-metadata, rxjs Nest modules/bootstrap/DTO validation; metadata/RxJS — framework peers KEEP
backend auth/cookies @nestjs/jwt, @nestjs/passport, passport, passport-jwt, bcrypt, cookie-parser AuthModule, JWT strategy/guard, password hashing, configureApp KEEP
backend DB/config @prisma/adapter-better-sqlite3, @prisma/client, prisma, better-sqlite3, dotenv PrismaService, compiled generated client, image migrations, smoke/durability SQL, prisma.config.ts KEEP direct contracts; driver alignment DEPS-003
backend integrations/logs @grpc/grpc-js, @grpc/proto-loader, cheerio, lru-cache, nestjs-pino, pino-http TbankClient RPC/TLS/proto, NCR HTML+bounded cache, typed loggingOptions KEEP
backend build/debug @nestjs/cli, @nestjs/schematics, typescript, ts-node, tsconfig-paths, ts-loader, source-map-support CLI collection/tsc; test:debug explicitly preloads ts-node/paths; Webpack route не выбран KEEP первых пяти; DELETE двух последних — DEPS-002
backend tests/types @nestjs/testing, jest, ts-jest, supertest; @types/bcrypt, @types/cookie-parser, @types/express, @types/jest, @types/node, @types/passport-jwt, @types/supertest configured unit/HTTP tests, Jest transformer, application/test TS KEEP
backend lint eslint, @eslint/js, typescript-eslint, globals, @darraghor/eslint-plugin-nestjs-typed, @stylistic/eslint-plugin, eslint-import-resolver-typescript, eslint-plugin-import-x, eslint-plugin-jest, eslint-plugin-n, eslint-plugin-perfectionist, eslint-plugin-regexp, eslint-plugin-security, eslint-plugin-sonarjs eslint.config.mjs:2–15,25–40,79–123 KEEP
backend/specs/docs/root release @commitlint/cli, @commitlint/config-conventional, release-it, @release-it/conventional-changelog, conventional-changelog-conventionalcommits Локальные scripts/configs каждого независимого repo KEEP; duplication across repos не дефект
docs validation markdownlint-cli, markdownlint-rule-relative-links manifest lint + .markdownlint-rule-relative-links.cjs:1 KEEP

Peer compatibility контрпроверена установленным graph. В частности, backend/node_modules/ts-jest/package.json:64–71 принимает Jest 29/30 и TS >=4.3 <7: различие major names не является конфликтом. Nest CLI локально требует TS ~6.0.2; frontend остаётся на TS 5.9.3 с отдельными browser/package configs. Общий compiler lockfile здесь не нужен.

3.4 Potential Unused (not proven)

Initial candidate Почему отсутствие project import недостаточно Решение / дешёвая следующая проверка
recharts, react-is Mantine charts peer recharts >=3.2.1; Recharts peer react-is (node_modules/@mantine/charts/package.json:37–42, node_modules/recharts/package.json:89–92) KEEP explicit providers, не перекладывать contract на transitives
Backend прямой better-sqlite3 Dynamic require в durability и JS string, исполняемой внутри container smoke KEEP direct package; согласовать version, не удалять consumer
reflect-metadata, rxjs, passport Framework/decorator/strategy integration и peer requirements KEEP; отсутствие import в отдельных business files не unused proof
@nestjs/schematics nest-cli.json:3 выбирает collection; CLI загружает её по строке KEEP
conventional-changelog-conventionalcommits Release preset задан строкой name: conventionalcommits; frontend Knip ignore осознанно отражает dynamic loading KEEP
@babel/core, babel-plugin-react-compiler Root Vite config вызывает reactCompilerPreset(); preset integration — consumer без прямого compiler-plugin import KEEP
unrs-resolver, fsevents, platform packages Transitive tooling/optional native resolution, platform-specific packaging Не переносить транзитивные packages в direct; не вычищать lock nodes вручную

ts-loader и прямая декларация source-map-support после проверки config/CLI consumers переведены из кандидатов в DEPS-002. Других доказанных unused direct dependencies не установлено. Массовый автоматический removal по текстовым imports не предлагается.

3.5 Configuration Authority Matrix

Значение / область Authoritative owner Consumers / дублирование Вывод
Node 24.21.0 .nvmrc каждого repo; manifest engine; соответствующий Docker base setup-node читает local .nvmrc; backend ESLint node version тоже 24.21.0 KEEP согласованность; npm 11.19.0 фактически проверен на host, версия внутри image не проверена
Direct versions / lifecycle permissions Local package.json + package-lock.json; allowScripts root npm project npm ci, Docker, scripts; independent Renovate configs KEEP локальную authority; не вводить соседний checkout как toolchain source
Backend required env/defaults src/config/env.validation.ts:21–33,102–114 ConfigModule → ConfigService → Prisma/auth/logging/TbankClient/main; example воспроизводит defaults Один runtime owner для PORT=3000, rate=5, endpoint, LOG_LEVEL=info; mismatch defaults не найден
Backend mode Explicit NODE_ENV launch context start:dev, Docker/Compose задают development/production; main/auth читают process.env напрямую DEPS-004: один debug entry point выбивается из того же launch contract
Development env .env.example каждого app и root .env.development.example Local manual setup; root development Compose Required backend: DB URL, frontend origin, JWT secret, encryption key; реальные secrets не исследованы
API base/proxy Frontend VITE_API_BASE_URL в client.ts:21–26; Vite API_PROXY_TARGET в vite.config.ts:54–60 Local example = absolute localhost; Docker = empty same-origin base + backend proxy Это browser/build-time base и dev-server target, а не два competing endpoints
Frontend TS language/alias tsconfig.base.json, tsconfig.app.json Vite/Vitest alias @ → src; packages имеют declaration configs Alias согласован; отдельные app/config module modes имеют разных consumers
Frontend graph resolution tsconfig.dependency-cruiser.json Package aliases указывают source для архитектурных edges вместо built dist KEEP deliberate analysis projection; runtime всё ещё использует package exports
Backend output/module resolution tsconfig.json + build/dev profiles, nest-cli.json dist/src/main.js, dist-dev; copied proto assets; Jest ts-jest и e2e .js mapper ESM Nest integration и CJS generated Prisma — явные contracts; drift failures не доказаны
Sonar TS projection sonar-project.properties:11–12, tsconfig.sonar.json каждого app CI использует отдельный profile для заявленного старого analyzer KEEP до проверки server analyzer; это не app typecheck и не основание слить configs
Tests/platforms vitest.config.ts, backend manifest Jest + test/jest-e2e.json JSDOM, Chromium narrow/wide; src unit vs test HTTP suites KEEP разные boundaries; одинаковые transform fragments не требуют общего runner
Browser/RPC deadlines frontend/src/shared/api/client.ts:15–18; backend/src/integrations/tbank/tbank.client.ts:49–54 HTTP transport и upstream RPC имеют собственные retry budgets Одинаковые 15 s не доказывают единую policy; budget composition — audit 07
Generated Prisma prisma/schema.prisma:1–5; package.json:12 build generated/prisma → PrismaService → TS build; ignored source DEPS-001 касается самостоятельного quick start; CI/Docker готовят client явно, standalone checks — отдельный audit 11
Public API artifacts Backend openapi/generator; явно доставленный frontend snapshot + local generator version openapi-fetch types, temporary byte comparison KEEP committed frontend snapshot/types, backend temporary output не коммитить автоматически
Specs native CLI specs/README.md:18–31, предоставленная установка OpenSpec Отдельная native validation; npm verify не запускает CLI INVESTIGATE только если clean setup этой workflow становится требованием; CLI version не проверялась

Широкого набора неиспользуемых production env flags не найдено: каждое поле Environment имеет validator/default и конкретного ConfigService consumer. NODE_ENV, CI, HUSKY и KNIP_DISABLE_RAW_TRANSFER — launch/tooling context, а не параметры финансовой модели. Корректность бизнес-политик, опций scheduler и закрытых external integrations не исследовалась.

3.6 Tool Overlap Matrix

Инструменты / configs Реальные зоны применения Verdict
ESLint + Stylistic; aliases format, lint:fix Одна ESLint flat-config execution, stylistic plugin форматирует тот же JS/TS KEEP; второго project formatter в direct manifests нет
ESLint import rules + dependency-cruiser + Knip Local import/type checks; graph cycles/layers/reachability; unused entries/exports/declarations KEEP разные доказательства; повторные triggers — audit 11
Vite/Rolldown + Babel React compiler Bundling/React transform против React compiler optimization preset KEEP; Babel не заменяет Vite
Nest tsc + ts-jest Production TS compilation против Jest transform KEEP
Nest tsc + ts-loader/Webpack Выбранный tsc builder против невыбранного Webpack builder DELETE unused direct Webpack entry — DEPS-002
Vitest JSDOM + browser-playwright + RTL/MSW Fast component/transport tests против actual Chromium layout; RTL/MSW дают interactions/network simulation KEEP; browser dependency не равна дублирующему test framework
Zod/RHF resolver + backend class-validator Browser form validation и server trust-boundary DTO validation в независимых repos KEEP; generic cross-repo schema layer не нужен
OpenAPI JSON + generated TS Явный provider artifact и derived consumer types KEEP; source JSON и type output не взаимозаменяемы
Markdown main/changelog profiles Общий lint и специальная повторяемость release headings, через extends KEEP
Application + Sonar tsconfigs Текущий compiler против старого external analyzer KEEP version-compatibility adapter; точная server version UNVERIFIED

3.7 Generated sources и reproducibility

  • git ls-files подтверждает tracking frontend src/shared/api/spec/openapi.json и src/shared/api/generated/schema.d.ts; workspace package dist не tracked. check-openapi.mjs:6–12,16–33,41–43 генерирует временный type artifact и сравнивает с committed, затем удаляет temp. Проверка во время аудита не запускалась.
  • Backend .gitignore:7–8,69–70 исключает generated Prisma и openapi.json. generate-openapi.cjs:4–15,23–35 задаёт disposable configuration, использует Nest preview и пишет provider artifact. Runtime correctness/свежесть artifact не выводятся из наличия файла на диске.
  • Backend build владеет Prisma generation; frontend package builds владеют JS/CSS/declarations. Требовать committed private outputs вместо этих build owners оснований нет.
  • longs: String, разные defaults: true/false gRPC loaders (tbank.client.ts:194–209,232–241) сохраняют precision/field-presence contracts. Их нельзя консолидировать только по одинаковым именам packages/options.

Coverage risk-based: inventory manifests/configs полный в перечисленных областях; semantic tracing сосредоточен на fresh setup, выбранном compiler, peers без imports, native runtime boundary и mode consumers. Не исследованы все APIs каждого пакета, вся browser support matrix, actual images, registry provenance, advisories и глобальные editor/user configs.

4. Findings

DEPS-001 — Backend quick start не подготавливает generated Prisma Client

  • Decision: FIX. Severity: P2. Confidence: High. Effort: S.
  • Evidence: backend/README.md:9–18; backend/package.json:11–18; backend/prisma/schema.prisma:1–5; backend/.gitignore:7–8; backend/src/prisma/prisma.service.ts:3–5,16–21; backend/node_modules/@prisma/client/package.json:264–275; контргарантии: backend/.gitea/workflows/verify.yml:83–85, backend/Dockerfile:7–10, README.md:97–104.
  • Claim: инструкция для самостоятельного свежего checkout заканчивается start:dev без шага, создающего импортируемый client. Это дефект prerequisites, не требование коммитить generated code.
  • Current mechanism: schema output — generated/prisma; install hooks client 7.10.0 не генерируют его; root project не содержит generation lifecycle. migrate deploy применяет SQL, не генерирует client. start:dev запускает Nest watch, не build и не prisma generate. PrismaService импортирует отсутствующий module.
  • Impact / actual cost: clean quick start не может успешно скомпилировать этот import; warm checkout с существующим ignored output работает и скрывает prerequisite. Impact unmeasured: fresh-checkout reproduction и потраченное setup time не измерены.
  • Why now: backend объявляет самостоятельный local setup; текущие Prisma generator/package scripts позволяют доказать отсутствующий preparation owner до будущего dependency update.
  • Minimum change: добавить перед migrate deploy в backend quick start существующий npm run build — он уже выполняет prisma generate && nest build, как root setup. Не добавлять generator wrapper, postinstall side effect или tracked private client. Если требуется self-contained запуск каждого watch script, отдельно выбрать generation перед start:dev/debug, не дублируя оба решения автоматически.
  • Guarantees at risk: generation должен остаться до TS consumers; схема, migration SQL и существующая база не должны изменяться при preparation. Build не заменяет migrate deploy.
  • Counterarguments / trade-offs: CI и Docker уже готовят client; root README содержит правильную последовательность. Это ограничивает failure до самостоятельного fresh setup, но не исправляет эту публичную инструкцию. Полный build чуть дороже standalone generate, зато использует existing owner без нового tooling.
  • Verification or rollback: при будущей правке выполнить документированный setup в отдельном disposable checkout с новой SQLite fixture, убедиться в наличии client и успешном старте; тестовые секреты/данные не из live .env. Для text-only правки сначала достаточно сверить command chain; runtime proof нужен перед заявлением fresh setup verified. Rollback — revert правки инструкции; generated outputs не коммитить.
  • Related finding IDs: DEPS-004. Related audit signal: audit 11 — owner подготовки standalone checks.

Prisma v7 reference явно отмечает отсутствие generation в migrate deploy: https://www.prisma.io/docs/orm/v7/prisma-migrate/workflows/development-and-production#production-and-testing-environments.

DEPS-002 — Неиспользуемый ts-loader удерживает альтернативную Webpack toolchain

  • Decision: DELETE. Severity: P2. Confidence: High. Effort: S.
  • Evidence: backend/package.json:12,15–18,98–104; backend/nest-cli.json:1–10; backend/package-lock.json:14287–14310,13998–14009; installed versioned mechanism: backend/node_modules/@nestjs/cli/lib/configuration/defaults.js:10–18, backend/node_modules/@nestjs/cli/lib/compiler/helpers/get-builder.js:9–15, backend/node_modules/@nestjs/cli/actions/build.action.js:87–110,153–176, backend/node_modules/@nestjs/cli/package.json:84–118.
  • Claim: прямые ts-loader@9.6.2 и source-map-support@0.5.21 не обслуживают configured project build/debug/test path. Главный лишний entry — ts-loader, который имеет required Webpack peer.
  • Current mechanism: Nest defaults = tsc, webpack=false; local config не выбирает builder/webpack, scripts не передают webpack option. CLI импортирует Webpack compiler динамически только для выбранного Webpack branch. npm explain подтверждает цепь root ts-loader → required Webpack → minimizer-webpack-plugin → Terser → source-map-support. Nest CLI отмечает эти bundler peers optional. Прямых project imports/preloads source-map-support нет; test:debug использует ts-node с собственным @cspotcode/source-map-support.
  • Impact / actual cost: поддерживается unused compiler route и его peer/transitive graph; обновления/compatibility review затрагивают packages, не участвующие в configured compilation. Impact unmeasured: размер, install time, audit surface и число исчезающих transitive nodes после re-resolution не измерены. Terser — известный transitive consumer, а не повод удалить его dependency файлы вручную.
  • Why now: установленный Nest 12 сделал Webpack optional/lazy; прежняя прямая dependency больше не требуется обычному tsc builder. Исходное намерение держать резервный compiler не найдено.
  • Minimum change: убрать только две direct dev declarations, штатно обновить lockfile в отдельной implementation task. Сохранить Nest CLI, TypeScript, ts-node, tsconfig-paths и любую dependency, которую новый resolved graph всё ещё требует. Не переписывать Nest build на bare tsc: CLI владеет proto assets/watch lifecycle.
  • Guarantees at risk: production dist layout, copied proto contracts, watch/debug и source-mapped Jest debugging. Debugger должен продолжать использовать существующий ts-node path.
  • Counterarguments / trade-offs: ручной nest build --webpack потребует отдельной установки; такого поддерживаемого режима в scripts/config/docs/CI не найдено. Optional peer consumer не равен active project consumer. Транзитивный source-map-support может остаться, если его потребует другой retained package.
  • Verification or rollback: после будущего удаления — clean npm ci, npm ls --all, npm explain webpack source-map-support, canonical backend verify + test:e2e, watch/debug на disposable configuration; проверить proto asset path. При сохранении Webpack найти новый retained consumer вместо обещания полного удаления. Rollback — вернуть две declarations и предыдущий lockfile вместе.
  • Related finding IDs: DEPS-001, DEPS-004.

DEPS-003 — Runtime и SQL-проверки используют разные major SQLite-драйвера

  • Decision: SIMPLIFY. Severity: P2. Confidence: High. Effort: M.
  • Evidence: backend/package.json:50–53,144–148; backend/package-lock.json:3762–3784,6284–6294; backend/src/prisma/prisma.service.ts:16–21; backend/test/bank-cards-durability.cjs:24,74–81; backend/test/container-smoke.cjs:34–38,58–64; backend/Dockerfile:21–22,31–35; backend/node_modules/better-sqlite3/package.json:24–36,48–54; backend/node_modules/@prisma/adapter-better-sqlite3/node_modules/better-sqlite3/package.json:18–23,40–46.
  • Claim: прямой better-sqlite3 нужен реальным checks, но версия 13.0.3 заставляет удерживать второй driver поверх adapter-owned 12.11.1. Это не unused package и не npm peer error.
  • Current mechanism: adapter 7.10.0 требует better-sqlite3 ^12.6.0 и получает nested 12.11.1; direct exact13 не удовлетворяет этому range. Prisma CLI принимает direct13 как optional peer >=9. Smoke/durability SQL читают root13, а PrismaService работает через nested12. Обе dependency paths production и сохраняются после omit-dev prune.
  • Impact / actual cost: две packaging/native compatibility boundaries; SQL-level проверка использует другой driver generation, чем application adapter. При этом smoke также реально запускает приложение, поэтому нельзя утверждать отсутствие runtime/native proof вообще. Impact unmeasured: disk/image bytes, затраты install и поведенческая разница bundled SQLite не измерены.
  • Why now: несовместимые major уже присутствуют в local lock и production manifest; update direct driver независимо от adapter продолжает закреплять лишнюю boundary.
  • Minimum change: сохранить direct dependency, но выбрать exact версию, удовлетворяющую adapter range — текущая runtime 12.11.1 является минимальным кандидатом для консолидации. После штатного lock update подтвердить deduplication. Если нужен именно v13, ждать/выбрать официально поддерживающий её adapter; не принуждать несовместимый adapter override. Разрешение install hook v12 сохраняется; stale разрешение v13 можно удалить только после согласования новой policy.
  • Guarantees at risk: SQLite persistence, integrity checks, transaction/rollback, native ABI compatibility, read-only image migrations и финансовая durability. Не менять storage format и migration history ради dependency cleanup.
  • Counterarguments / trade-offs: v13 поставляет готовые N-API prebuilds, v12 использует install hook и возможную сборку; это реальное различие, а не две одинаковые lifecycle команды. Но production adapter уже зависит от v12, поэтому direct13 не устраняет v12 install cost. Требование тестировать намеренно разные SQLite generations не найдено; future advisories проверяются отдельно перед version change.
  • Verification or rollback: будущая clean installation на целевых OS/architecture; подтвердить один resolved driver и adapter-compatible version; backend verify, SQLite/e2e, built-image smoke и существующий durability runner с disposable baseline. Не запускать durability на рабочей базе. Rollback — восстановить manifest/lock/policy совместно и пересобрать image; database rollback не требуется при чисто dependency/config change без миграций.
  • Related finding IDs: DEPS-002.

DEPS-004 — Debug entry point теряет development mode

  • Decision: FIX. Severity: P3. Confidence: High. Effort: S.
  • Evidence: backend/package.json:16–17; backend/.env.example:1–10; backend/src/config/swagger.config.ts:1–3; backend/src/main.ts:49–57; backend/src/modules/auth/presentation/auth.controller.ts:131–136; backend/src/config/env.validation.ts:9–19.
  • Claim: при отсутствии унаследованного NODE_ENV одинаковые dev/debug watch profiles включают разные mode-sensitive policies. Это подтверждённое различие конфигурации, не доказанный отказ auth в конкретном browser.
  • Current mechanism: start:dev задаёт NODE_ENV=development, start:debug только --debug --watch --path tsconfig.dev.json. Env example не содержит NODE_ENV; Environment validator не нормализует это поле. Swagger открывается только при точном development, cookie Secure выключается только при точном development, log fallback пишет development даже при undefined.
  • Impact / actual cost: debugger не воспроизводит development HTTP configuration; Swagger отсутствует, cookies получают иной flag. Поведение Secure cookies на localhost зависит от client, его отказ не заявляется. Impact unmeasured: runtime debugger/browser scenario не запускался.
  • Why now: исправляется одной строкой existing entry point без env framework и изменения production defaults.
  • Minimum change: добавить NODE_ENV=development в start:debug тем же способом, что уже используется в start:dev. Не задавать global permissive default и не ослаблять production cookie/Swagger policy.
  • Guarantees at risk: production Secure cookies и отключённый Swagger должны сохраниться; debug остаётся отдельным осознанным local launch.
  • Counterarguments / trade-offs: внешняя shell/.env может уже задавать NODE_ENV — тогда расхождения нет. Fresh documented env такого prerequisite не устанавливает. Настройка только launch script намеренно меньше, чем новая unified environment abstraction.
  • Verification or rollback: после будущей правки сравнить dev/debug launch configuration на disposable env, убедиться в development Swagger; существующая production-mode проверка должна сохранить закрытый Swagger/Secure cookie. Rollback — revert одной script value.
  • Related finding IDs: DEPS-001, DEPS-002.

5. DELETE / SIMPLIFY / KEEP / INVESTIGATE

Decision Объект Основание / сохраняемая гарантия
DELETE Direct ts-loader и source-map-support — DEPS-002 tsc builder остаётся; transitive packages удаляются только штатным dependency resolution
SIMPLIFY Две версии better-sqlite3 — DEPS-003 Сохранить прямой SQL consumer и adapter-supported native driver; consolidation после SQLite/image/durability proof
FIX Fresh quick start — DEPS-001 Explicit build/generate до import, без committed private outputs и install hooks
FIX Debug NODE_ENV — DEPS-004 Local development mode, без изменения fail-closed production policy
KEEP Prisma CLI production dependency Image и Compose migration запускают node_modules/prisma/build/index.js; перенос в dev сломает omit-dev image
KEEP Recharts/react-is, reflect-metadata/RxJS/passport peers Dynamic/framework consumers; отсутствие business import не доказательство ненужности
KEEP Bcrypt, native SQLite, proto loaders и TLS CA option Auth, persistence, precision/field presence, реальная сеть/сертификаты; stdlib replacement не доказан эквивалентным
KEEP OpenAPI snapshot и generated TS Независимый consumer repo с offline local contract/type check
KEEP Отдельные compiler/test/Sonar profiles Разные runtime/module/analyzer environments и fixtures, не искусственно дублирующий один compiler
KEEP Независимые lockfiles/release/commitlint configs Каждый repo устанавливается и выпускается без соседних checkout
KEEP Restrictive allowScripts и exact versions Не давать wildcard разрешения ради исчезновения lifecycle warnings
INVESTIGATE Specs OpenSpec CLI ownership README допускает внешнюю незакреплённую CLI; local npm ci не обещает её установку. Pin только при требовании reproducible native workflow
INVESTIGATE Native/image footprint и Sonar projection Фактические artifacts/server version не проверены; размер и ложные diagnostics нельзя выводить из количества packages

Complexity-pass в формате ponytail-audit

  • delete: убрать direct ts-loader, активирующий невыбранную Webpack-ветку; replacement: существующий Nest tsc builder. [backend/package.json:101, backend/nest-cli.json]
  • shrink: согласовать direct better-sqlite3 с adapter-supported runtime version; replacement: один совместимый driver для приложения и SQL checks. [backend/package.json:50–53, backend/package-lock.json:3762–3784]
  • delete: убрать direct source-map-support declaration; replacement: ничего в project code, необходимые transitive consumers сохраняет npm. [backend/package.json:98]

net: -2 manifest lines, -2 direct deps possible. Число относится только к двум предложенным direct declaration removals. Lockfile/transitive line savings не измерены. Consolidation driver может убрать одну version instance, но не сам required direct dependency; clean resolution и compatibility proof ещё нужны.

6. Cost & benefit

Действие Класс выгоды Фактическое измерение Обязательные границы
DEPS-001: explicit preparation Setup reliability, cognitive load/agent navigation Missing prerequisite доказан статически; setup minutes not measured Fresh client до TS import; безопасная disposable DB; не трогать существующие secrets
DEPS-002: remove unused compiler entries Dependency maintenance, потенциальные install/CI cost 2 direct entries; Webpack peer chain доказана; minutes/bytes/closure reduction not measured Nest tsc, assets, watch/debug, existing test transforms сохранить
DEPS-003: driver alignment Runtime packaging, native maintenance, consistent SQL verification 2 resolved versions установлены; image bytes/runtime improvement not measured SQLite integrity/durability/transactions, ABI и migration CLI сохранить
DEPS-004: debug mode Local troubleshooting/cognitive load Различие launch config доказано; recovery time not measured Production cookie/Swagger policy не ослаблять

Не обещаются проценты ускорения, bundle reduction или денежная экономия. Package count не равен bundle size: dev dependencies frontend отсутствуют в nginx runtime, а platform lock entries не все устанавливаются на одном host. Общие пакеты между repos не означают двойной runtime bundle.

7. Top actions и план безопасной консолидации

Quick wins

  1. DEPS-001: исправить самостоятельный backend quick start существующим preparation command; сверить его с tracked generator/import chain. Самая дешёвая правка с непосредственной setup value.
  2. DEPS-002: удалить direct ts-loader/source-map-support в отдельной dependency task; штатно обновить lockfile, затем clean-install/peer/compiler/assets checks. Не удалять вручную Webpack nodes из node_modules/lockfile.
  3. DEPS-004: согласовать debug launch с start:dev одной script value, сохранив production mode.

Решение, требующее тестового подтверждения

  1. DEPS-003: выбрать adapter-compatible SQLite driver version, clean resolve, затем SQLite/image/durability proof. Новая ADR нужна только если принято намеренно сохранять разные driver generations или менять runtime DB packaging; для обычного version alignment достаточно dependency diff и regression evidence.

Минимальная последовательность future implementation: один связанный manifest/config diff → canonical lockfile update штатным npm → чистая установка на нужной платформе → npm ls --all → соответствующие existing type/build/tests → image/durability только для native change. После dependency changes выполнить repo-required npm audit и отдельно triage, не принимать --force/--legacy-peer-deps. Эти операции не выполнялись в аудите.

Не предлагается миграция в monorepo, центральный dependency manifest, новый env parser, custom unused-dependency script, общий test runner или объединение ESLint/graph/contract validators.

8. Cross-audit signals

  • Audit 11: backend/package.json:34, .gitea/workflows/verify.yml:83–89 — preparation ownership standalone verify/CI; здесь зафиксирован fresh local setup, execution repetition не пересчитывался.
  • Audit 07: frontend/src/shared/api/client.ts:15–18, backend/src/integrations/tbank/tbank.client.ts:49–54 — согласование end-to-end timeout/retry budget; одинаковые значения не требуют shared constant автоматически.
  • Audit 07/15: frontend/src/app/ui/App.tsx:13–19 и .ai/conventions/data.md:70–74 — focus-refetch behavior отличается от описанной policy; не включено в dependency findings.
  • Audit 13: backend/package.json:107–121, frontend/package.json:118–126, docs/package.json:24–33, backend/.gitea/workflows/verify.yml:64–65 — overrides/advisory exception требуют отдельного security rationale; vuln scan не выполнялся.
  • Audit 15: specs/README.md:28–31, specs/package.json:15–21 — ownership/version of external OpenSpec CLI; SDD lifecycle и CLI installation state здесь не исследованы.

9. Open questions / verification plan

Вопрос, меняющий решение Самый дешёвый proof Что изменит
Есть ли поддерживаемый backend Webpack consumer вне tracked scripts/config/CI? Уточнить у owner конкретную command/config; project search не нашёл При реальном consumer сохранить ts-loader либо оформить его явный режим вместо DELETE
Почему direct SQLite v13 нужна при adapter v12? Проверить необходимость v13 API в двух SQL consumers и существующим image/durability proof на compatible v12 Если специфичный v13 contract нужен, DEPS-003 станет INVESTIGATE до официального adapter support
Сколько transitive nodes/bytes действительно исчезнет после DEPS-002/003? Сравнить новый штатный lock graph и image digest/artifact в будущей dependency task Уточнит benefit; не меняет доказанный unused route, не требует нового profiler
Работает ли самостоятельный свежий setup после исправления инструкции? Отдельный disposable checkout/SQLite fixture без inherited generated output Позволит заменить статический inference DEPS-001 на runtime-verified statement
Нужна ли воспроизводимая native OpenSpec workflow на clean host? Уточнить requirement и получить фактический openspec --version owner среды Только тогда решить local pin; application setup от этого не зависит
По-прежнему ли Sonar требует отдельный старый TS profile? Проверить version существующего server analyzer / один уже выполненный scan log При современном analyzer можно пересмотреть profile, сейчас KEEP

Открытые вопросы не являются блокерами read-only отчёта. Ни установка новых tools, ни runtime database access для завершения аудита не нужны.

10. Проверка итогового артефакта

Единственная запись — audit-results/12-dependencies-and-configuration-report.md, вне четырёх самостоятельных repos и вне root allowlist. Выполнена semantic сверка: scope, точные SHA/строки, все четыре finding fields, counterarguments, preserved invariants, отсутствие выдуманных измерений, четыре специальные matrices/registers и consolidation table.

  • Повторные git status --short --branch и git rev-parse HEAD пяти repos подтвердили чистые working trees и те же SHA, что в metadata.
  • В пяти repos git diff --check и git diff --cached --check завершились с exit 0 без diagnostics; staged/unstaged tracked изменений нет.
  • git diff --no-index --check /dev/null audit-results/12-dependencies-and-configuration-report.md завершился с exit 0 без diagnostics: проверен сам новый ignored отчёт, а не только пустой tracked diff.
  • git status --short --ignored -- audit-results/12-dependencies-and-configuration-report.md показал !! audit-results/: отчёт сохраняется локально и не добавлен в root tracking.
  • Application tests/build/clean install не выполнялись; успешная проверка артефакта не подменяет future regression proof рекомендаций.

Consolidation table

ID Decision Severity Confidence Repo Files One-line impact Effort Related IDs
DEPS-001 FIX P2 High backend README.md; package.json; prisma/schema.prisma; src/prisma/prisma.service.ts Самостоятельный fresh quick start пропускает generated client prerequisite S DEPS-004
DEPS-002 DELETE P2 High backend package.json; package-lock.json; nest-cli.json Неиспользуемый ts-loader удерживает Webpack peer chain и лишние direct declarations S DEPS-001, DEPS-004
DEPS-003 SIMPLIFY P2 High backend package.json; package-lock.json; test/container-smoke.cjs; test/bank-cards-durability.cjs Runtime и SQL checks удерживают две major-версии SQLite-драйвера M DEPS-002
DEPS-004 FIX P3 High backend package.json; .env.example; src/main.ts; src/config/swagger.config.ts; src/modules/auth/presentation/auth.controller.ts Debug launch без NODE_ENV development выбирает другую HTTP mode policy S DEPS-001, DEPS-002