docs(specs): archive dependency hygiene remediation
This commit is contained in:
+2
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-08-24
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
## Context
|
||||
|
||||
См. motivation в `proposal.md`. На старте change frontend напрямую использует
|
||||
`react-router@7.9.6`; backend получает `deepmerge-ts@7.1.5` транзитивно через
|
||||
`prisma@7.9.1 -> @prisma/config`. Frontend одновременно хранит одинаковые
|
||||
`.env` и `.env.example`, а backend хранит пустой tracked `dev.db`; текущий
|
||||
backend ignore rule покрывает только `prisma/*.db`.
|
||||
|
||||
Каждый application directory — отдельный Git repository с собственным
|
||||
lockfile. Prisma 7.9.1 также является причиной deferred WL-P2-05, поэтому
|
||||
dependency change не может считать e2e gate восстановленным без отдельного
|
||||
подтверждения его review trigger.
|
||||
|
||||
### Baseline 2026-08-24
|
||||
|
||||
| Область | Наблюдение |
|
||||
| --- | --- |
|
||||
| Frontend dependency | direct `react-router@7.9.6` |
|
||||
| Backend dependency path | `prisma@7.9.1 -> @prisma/config@7.9.1 -> deepmerge-ts@7.1.5`; `@prisma/client` и adapter также `7.9.1` |
|
||||
| Frontend environment | `.env` и `.env.example` tracked с одинаковым content; local `.env` не игнорируется |
|
||||
| Backend SQLite | пустой root `dev.db` tracked; ignore покрывает только `prisma/*.db` |
|
||||
| Local URLs | development template направляет DB в `prisma/dev.db`; e2e config направляет её в `/tmp/wealth-ledger-e2e.db` |
|
||||
|
||||
### Advisory assessment 2026-08-24
|
||||
|
||||
`npm audit --omit=dev` reproduces one high frontend finding and three high
|
||||
backend findings. The direct frontend path is `react-router@7.9.6`.
|
||||
GHSA-2w69-qvjg-hvjx affects React Router `>=7.0.0, <=7.11.0` and is patched
|
||||
in `7.12.0`; npm identifies `7.18.2` as the current non-major version that
|
||||
also resolves the broader audit result. WealthLedger uses only
|
||||
declarative `<BrowserRouter>`, static internal `Link` targets and local
|
||||
`navigate` calls. It has no loaders, actions, SSR, RSC, single-fetch or
|
||||
prerendering surface. This removes the known preconditions for
|
||||
GHSA-2w69-qvjg-hvjx, but does not justify retaining an old direct package:
|
||||
the supported fixed version is compatible with Node 22 and React 19 and will
|
||||
be adopted.
|
||||
|
||||
The backend findings resolve through
|
||||
`prisma@7.9.1 -> @prisma/config@7.9.1 -> deepmerge-ts@7.1.5`.
|
||||
GHSA-ggr8-5vv4-36mx affects deepmerge-ts `<8.0.0` and is patched in `8.0.0`.
|
||||
Source code does not import `@prisma/config` or `deepmerge-ts`; the former is
|
||||
used by the local Prisma CLI configuration, while runtime uses the generated
|
||||
Prisma client and SQLite adapter. The vulnerability requires two
|
||||
attacker-controlled recursive object graphs passed into deepmerge APIs, a path
|
||||
absent from the delivered HTTP service. npm offers only a Prisma 6.12.0 major
|
||||
downgrade and the published latest Prisma remains 7.9.1, so this change
|
||||
accepts the tooling-only residual risk rather than forcing an unsupported
|
||||
override.
|
||||
Review trigger: a vendor-supported Prisma release for the 7.x integration
|
||||
that resolves `deepmerge-ts@>=8`, or new evidence that public runtime input
|
||||
reaches a deepmerge API.
|
||||
|
||||
### Implemented dependency outcome
|
||||
|
||||
`react-router` is upgraded from `7.9.6` to `7.18.2`, its current
|
||||
non-major npm audit fix. The existing AppRoutes regression suite validates
|
||||
the delivered declarative routing contract after the update, and the frontend
|
||||
production dependency audit reports zero findings. The Prisma/deepmerge-ts
|
||||
finding is accepted as tooling-only residual risk under the review trigger
|
||||
above; no manifest, lockfile or runtime behavior is changed for it.
|
||||
|
||||
### Implemented hygiene outcome
|
||||
|
||||
Each application repository exposes a non-mutating `hygiene:check` command.
|
||||
The frontend check permits only tracked `.env.example`, requires local
|
||||
`.env*` files to be ignored, and is part of `npm run verify`. The backend
|
||||
check rejects tracked SQLite runtime files and verifies root/Prisma DB and
|
||||
sidecar patterns without treating text fixtures as databases. The redundant
|
||||
tracked frontend `.env` and empty backend root `dev.db` are removed; existing
|
||||
documented URLs still create development data under ignored `prisma/` and e2e
|
||||
data under `/tmp`.
|
||||
|
||||
### Application-gate evidence
|
||||
|
||||
Under Node `v22.21.0` and npm `10.9.4`, frontend `npm run verify` passes with
|
||||
17 test files / 55 tests after the Router update. Backend `npm ci`,
|
||||
`hygiene:check`, non-mutating lint, application/test typechecks and
|
||||
`npm test -- --runInBand` pass with 19 suites / 59 tests. `npm run test:e2e`
|
||||
still stops during `prisma migrate deploy` with the pre-existing empty
|
||||
`Schema engine error` before Jest starts. This is recorded as the WL-P2-05
|
||||
deferred outcome, not as a passing e2e result or evidence of a Prisma fix.
|
||||
|
||||
`npm audit --omit=dev` after the clean install reports zero frontend
|
||||
production findings. Backend still reports three high findings in the exact
|
||||
Prisma 7.9.1 path recorded above, with only a Prisma 6.12.0 major downgrade as
|
||||
an automatic fix. OpenSpec authority, strict change validation, all synced
|
||||
spec validation (16/16) and `git diff --check` in every affected repository
|
||||
pass.
|
||||
|
||||
The remediation registry is updated with terminal evidence only after archive.
|
||||
It is deliberately not a checkbox in `tasks.md`: the archive lifecycle
|
||||
requires every task to be complete before archive, so post-archive bookkeeping
|
||||
cannot also be an unfinished implementation task.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Получить evidence-based решение по каждому high advisory, а не скрыть его
|
||||
массовым обновлением.
|
||||
- Применить только минимальные поддерживаемые dependency updates и доказать
|
||||
их существующими non-mutating gates.
|
||||
- Сделать local environment и SQLite artifacts непригодными для случайного
|
||||
commit, не ломая documented bootstrap.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Автоматически обновлять все устаревшие packages, добавлять package manager
|
||||
или вводить blanket `overrides` без vendor-supported compatibility path.
|
||||
- Менять HTTP/OpenAPI contract, Prisma schema/migrations, production data,
|
||||
T-Bank integration или обходить deferred Prisma e2e gate.
|
||||
- Создавать CI/CD security scanner, secret-management service или хранить
|
||||
реальные секреты в versioned files.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Каждый advisory проходит assessment до изменения manifest
|
||||
|
||||
Для WL-P2-12 сначала фиксируются исходные advisory metadata, installed path,
|
||||
affected version range, runtime/build reachability и минимальный supported
|
||||
fixed candidate. Затем выбирается один из outcomes: coordinated upgrade,
|
||||
accepted risk или deferred risk с конкретным trigger. `npm audit fix --force`
|
||||
не используется: он смешивает unrelated upgrades и не создаёт evidence
|
||||
применимости.
|
||||
|
||||
Альтернатива — обновить все findings одной командой audit fix. Она отвергнута,
|
||||
потому что Prisma является источником отдельного e2e failure и semver-compatible
|
||||
разрешение не доказывает поведение Nest/Prisma integration.
|
||||
|
||||
### Transitive Prisma finding обновляется только согласованной цепочкой
|
||||
|
||||
Если assessment требует remediation deepmerge-ts, change обновляет Prisma
|
||||
packages только в vendor-supported, lockstep-compatible наборе и проверяет
|
||||
фактический resolved graph после чистой установки. Точечный npm override
|
||||
транзитивного package допустим только если Prisma официально поддерживает этот
|
||||
диапазон; иначе finding остаётся документированным accepted/deferred risk.
|
||||
|
||||
Альтернатива — принудительно override-ить `deepmerge-ts`. Она отвергнута по
|
||||
умолчанию, поскольку обходит ownership dependency chain и может скрыть
|
||||
несовместимость Prisma tooling.
|
||||
|
||||
### Templates versioned, рабочие значения local
|
||||
|
||||
Frontend сохраняет единственный versioned template `.env.example`; `.env` и
|
||||
варианты `.env.*` игнорируются, кроме явно разрешённого example. При удалении
|
||||
tracked `.env` его содержимое сначала сверяется с example, поэтому documented
|
||||
`cp .env.example .env` остаётся воспроизводимым. Backend `dev.db` удаляется
|
||||
только как пустой runtime artifact; ignore policy покрывает root и Prisma
|
||||
SQLite locations, не затрагивая будущие намеренно versioned fixtures.
|
||||
|
||||
Альтернатива — оставить безопасный сегодня `.env` tracked. Она отвергнута:
|
||||
Git policy должна предотвращать будущий commit с секретом, а не оценивать
|
||||
только текущее значение.
|
||||
|
||||
### Evidence собирается существующими gates
|
||||
|
||||
После каждой manifest/lockfile change выполняются `npm ci`, dependency graph и
|
||||
relevant audit command в затронутом repository, затем существующие frontend
|
||||
`npm run verify` и backend non-mutating lint/typecheck/unit-test gates. Любая
|
||||
Prisma-related проверка отдельно сообщает исход `migrate deploy`; её failure
|
||||
не маскируется и не переводит WL-P2-05/P2-13 в done.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Минимальный fixed release меняет router behavior или peer resolution] →
|
||||
выполнить targeted route/auth regression tests и полный frontend verify до
|
||||
принятия lockfile.
|
||||
- [Prisma update меняет schema-engine behavior или incompatibly разрешает
|
||||
adapter/client packages] → обновлять vendor-supported packages вместе,
|
||||
запускать generated/type/unit gates и сохранить фактический e2e outcome.
|
||||
- [Ignore rule слишком широка и скрывает fixture] → покрыть только runtime
|
||||
DB patterns, проверить tracked files и явно оставить fixtures вне policy.
|
||||
- [Удаление tracked `.env` оставляет разработчика без config] → template и
|
||||
documented copy command проверяются до удаления tracked файла.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Зафиксировать baseline assessments и выбрать outcome для каждого advisory.
|
||||
2. Выполнить согласованные dependency/lockfile updates или записать accepted/
|
||||
deferred decision с review trigger.
|
||||
3. Перевести frontend configuration на `.env.example` + ignore policy;
|
||||
удалить tracked runtime inputs из index, сохранив локально воспроизводимый
|
||||
file через template.
|
||||
4. Удалить пустой backend runtime DB artifact, расширить ignore policy и
|
||||
проверить temporary DB location без касания production schema.
|
||||
5. Выполнить required gates и, только после archive, добавить terminal
|
||||
evidence в remediation registry. Rollback — независимый Git revert в
|
||||
затронутом repository; DB migration или user-data recovery не требуются.
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
## Why
|
||||
|
||||
Аудит 20.08.2026 подтвердил high advisories в прямом frontend dependency и
|
||||
транзитивной Prisma-цепочке, а также две небезопасные практики с локальными
|
||||
runtime-артефактами: tracked frontend `.env` и tracked пустая SQLite DB. Пока
|
||||
не проверена применимость advisories и не закреплены безопасные repository
|
||||
boundaries, следующий локальный bootstrap или автоматическое обновление может
|
||||
создать security regression либо случайно закоммитить локальные данные.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Добавить воспроизводимый процесс оценки dependency advisory: зафиксировать
|
||||
затронутый package path, применимость к архитектуре WealthLedger, выбранное
|
||||
исправление либо принятое исключение и условие его пересмотра.
|
||||
- Обновить только подтверждённо безопасные зависимости и lockfiles; не
|
||||
применять `npm audit fix --force` и не обновлять Prisma вслепую.
|
||||
- **BREAKING** Убрать tracked `frontend/.env`, оставив versioned
|
||||
`.env.example`, и исключить рабочие frontend `.env*` из Git с явным
|
||||
исключением examples.
|
||||
- **BREAKING** Убрать tracked `backend/dev.db`, запретить runtime SQLite
|
||||
artifacts во всех поддерживаемых местоположениях и закрепить temporary DB
|
||||
policy для локальных тестов.
|
||||
- Обновить remediation registry: пока change активен, он является единственным
|
||||
active remediation для WL-P2-12, WL-P3-07 и WL-P3-08; completion evidence
|
||||
добавляется только после archive.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `workspace-artifact-hygiene`: безопасное обращение с dependency advisories,
|
||||
локальной configuration и runtime SQLite-артефактами в независимых
|
||||
frontend/backend Git-репозиториях.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
_Нет._
|
||||
|
||||
## Impact
|
||||
|
||||
- Frontend: `package.json`, `package-lock.json`, `.gitignore`, tracked
|
||||
configuration template и regression checks.
|
||||
- Backend: Prisma dependency graph при подтверждённом исправлении,
|
||||
`.gitignore`, tracked DB artifact и проверка расположения temporary DB.
|
||||
- Specs/docs: delta-spec, change design/tasks и актуальный remediation registry.
|
||||
|
||||
Не изменяются пользовательские HTTP routes, OpenAPI contract, persisted
|
||||
production schema, T-Bank integration или deferred Prisma e2e policy. Любое
|
||||
обновление Prisma обязано отдельно доказать, что не маскирует WL-P2-05 и не
|
||||
объявляет e2e gate восстановленным без выполнения его review trigger.
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
## Purpose
|
||||
|
||||
Определяет проверяемые границы для dependency advisories, локальной
|
||||
configuration и SQLite runtime-артефактов независимых репозиториев WealthLedger.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Dependency advisory получает проверяемое решение
|
||||
Для каждого audit-derived dependency advisory система SHALL хранить
|
||||
проверяемую запись с Audit ID, advisory identifier, затронутой package path и
|
||||
installed version, оценкой применимости к runtime или build surface и одним из
|
||||
результатов: исправлено, принято или отложено. Принятое или отложенное решение
|
||||
MUST содержать rationale и review trigger; исправленное решение MUST содержать
|
||||
выбранный поддерживаемый upgrade path и evidence воспроизводимой проверки.
|
||||
|
||||
#### Scenario: Advisory подтверждён в dependency graph
|
||||
- **WHEN** проверка находит advisory в direct или transitive package path
|
||||
- **THEN** remediation record позволяет определить его reachability,
|
||||
выбранный результат и evidence без применения массового автоматического
|
||||
обновления зависимостей
|
||||
|
||||
#### Scenario: Advisory не применим к delivered architecture
|
||||
- **WHEN** assessment устанавливает, что advisory не достижим из runtime или
|
||||
build surface WealthLedger
|
||||
- **THEN** record фиксирует принятие риска, конкретное rationale и условие
|
||||
повторной оценки вместо ошибочного заявления об исправлении
|
||||
|
||||
### Requirement: Рабочая frontend configuration не является versioned input
|
||||
Frontend SHALL поставлять versioned `.env.example`, достаточный для создания
|
||||
локального `.env`, но MUST NOT хранить рабочий `.env` или другой локальный
|
||||
`.env*` файл в source control. Ignore policy MUST исключать локальные frontend
|
||||
configuration files, сохраняя явно разрешённый example template.
|
||||
|
||||
#### Scenario: Участник создаёт local frontend configuration
|
||||
- **WHEN** участник копирует `.env.example` в `.env` для запуска frontend
|
||||
- **THEN** локальный файл доступен runtime, но не появляется среди tracked
|
||||
файлов Git
|
||||
|
||||
### Requirement: Runtime SQLite-данные не являются versioned artifact
|
||||
Backend MUST NOT хранить SQLite database files, созданные runtime или local
|
||||
development, в source control. Ignore policy SHALL покрывать поддерживаемые
|
||||
repository runtime locations, а локальные test/database workflows MUST
|
||||
направлять временные базы вне source tree и не считать их частью
|
||||
коммитируемого результата.
|
||||
|
||||
#### Scenario: Локальный backend создаёт runtime SQLite database
|
||||
- **WHEN** backend workflow создаёт SQLite file для development или test run
|
||||
- **THEN** database находится вне versioned source inputs либо исключена
|
||||
ignore policy и не появляется среди tracked файлов Git
|
||||
|
||||
#### Scenario: В репозитории обнаружен устаревший runtime DB artifact
|
||||
- **WHEN** tracked SQLite database больше не требуется как fixture или source
|
||||
input
|
||||
- **THEN** change удаляет его из source control и сохраняет воспроизводимый
|
||||
local bootstrap через configuration template и documented workflow
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
## 1. Зафиксировать active remediation scope
|
||||
|
||||
- [x] 1.1 Обновить `docs/development/audit-remediation.md`: пометить только
|
||||
WL-P2-12, WL-P3-07 и WL-P3-08 как `active` с
|
||||
`address-dependency-advisories-and-repo-hygiene`; не менять immutable audit
|
||||
snapshot и не добавлять terminal evidence до archive.
|
||||
- [x] 1.2 Подтвердить baseline независимых Git repositories: зафиксировать
|
||||
installed dependency paths, tracked `.env`/SQLite inputs и существующие
|
||||
ignore rules без удаления пользовательских local files.
|
||||
|
||||
## 2. Принять доказательное решение по dependency advisories
|
||||
|
||||
- [x] 2.1 Для React Router и Prisma/deepmerge-ts собрать текущие primary
|
||||
advisory metadata, affected/fixed ranges, `npm audit` result и reachability
|
||||
из delivered SPA/backend architecture; записать Audit ID, package path,
|
||||
runtime/build surface и candidate outcome в change evidence.
|
||||
- [x] 2.2 Выбрать для React Router минимальный поддерживаемый fixed release
|
||||
либо accepted/deferred decision с rationale и review trigger; при upgrade
|
||||
обновить только manifest/lockfile и добавить/скорректировать targeted route
|
||||
regression coverage, необходимую для обнаружения compatibility regression.
|
||||
- [x] 2.3 Выбрать для Prisma/deepmerge-ts vendor-supported coordinated upgrade
|
||||
либо accepted/deferred decision с rationale и review trigger; не применять
|
||||
blind transitive override или `npm audit fix --force`, а при upgrade сохранить
|
||||
совместимость `prisma`, `@prisma/client` и adapter packages.
|
||||
- [x] 2.4 После каждого выбранного upgrade выполнить clean install и
|
||||
подтвердить фактический resolved dependency graph; не объявлять WL-P2-05 или
|
||||
WL-P2-13 восстановленными, если их отдельный Prisma trigger не выполнен.
|
||||
|
||||
## 3. Защитить local configuration и SQLite artifacts
|
||||
|
||||
- [x] 3.1 Добавить frontend hygiene regression check, который допускает только
|
||||
versioned `.env.example`, подтверждает ignore для local `.env*` и падает,
|
||||
если рабочая configuration оказывается tracked.
|
||||
- [x] 3.2 Перевести frontend на `.env.example` как единственный versioned
|
||||
template: убедиться в эквивалентном bootstrap value, удалить tracked `.env`
|
||||
из source control и обновить `.gitignore` с явным исключением example.
|
||||
- [x] 3.3 Добавить backend hygiene regression check для tracked SQLite runtime
|
||||
artifacts и ignore patterns root/Prisma locations; check не должен скрывать
|
||||
намеренно versioned text fixtures.
|
||||
- [x] 3.4 Удалить пустой tracked `backend/dev.db`, расширить backend ignore
|
||||
policy для SQLite sidecar/runtime files и подтвердить, что documented
|
||||
development/test DB URLs остаются local или temporary и не требуют
|
||||
versioned database.
|
||||
|
||||
## 4. Верификация и completion evidence
|
||||
|
||||
- [x] 4.1 Выполнить affected frontend `npm run verify`, backend non-mutating
|
||||
`npm run lint`, `npm run typecheck:app`, `npm run typecheck:test` и unit
|
||||
tests под Node 22; отдельно записать actual Prisma e2e outcome без выдачи
|
||||
deferred gate за passing.
|
||||
- [x] 4.2 Выполнить `npm ci` и relevant audit/dependency graph checks в
|
||||
каждом затронутом application repository, `git diff --check`, strict change
|
||||
and synced-spec validation с `--store wealth-ledger-specs`, а также OpenSpec
|
||||
authority verifier; устранить каждый confirmed blocking result.
|
||||
- [x] 4.3 Провести independent read-only review advisory assessment,
|
||||
dependency/lockfile diff, hygiene checks, `.env`/SQLite migration и
|
||||
documentation scope; выполнить applicable `opsx-verify` procedure и
|
||||
устранить blocking findings до archive.
|
||||
|
||||
После archive remediation registry получает terminal evidence: archive path,
|
||||
commits, exact commands/results, статусы WL-P2-12, WL-P3-07 и WL-P3-08 и ровно
|
||||
одну следующую рекомендуемую задачу. Это обязательное post-archive действие, а
|
||||
не task checklist, чтобы archive никогда не содержал незавершённую работу.
|
||||
Reference in New Issue
Block a user