From ab231a6aac58f4e97377e4d4fb521e22d3f07fdb Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Sun, 6 Sep 2026 19:49:17 +0300 Subject: [PATCH] docs(specs): archive frontend audit remediation --- .../.openspec.yaml | 3 + .../design.md | 209 ++++++++++++++++++ .../proposal.md | 65 ++++++ .../tasks.md | 77 +++++++ 4 files changed, 354 insertions(+) create mode 100644 openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/.openspec.yaml create mode 100644 openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/design.md create mode 100644 openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/proposal.md create mode 100644 openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/tasks.md diff --git a/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/.openspec.yaml b/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/.openspec.yaml new file mode 100644 index 0000000..20544f0 --- /dev/null +++ b/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/.openspec.yaml @@ -0,0 +1,3 @@ +schema: wealth-ledger-sdd +created: 2026-09-06 +skip_specs: true diff --git a/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/design.md b/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/design.md new file mode 100644 index 0000000..57261cc --- /dev/null +++ b/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/design.md @@ -0,0 +1,209 @@ +## Context + +Proposal утверждён Change Owner в текущей conversation. Change использует +`skip_specs: true`: пользовательское поведение уже определено Requirement +`brokerage-account-income-analytics — Instrument breakdown is traceable to exact Ledger Entries`. +Уточнение transport representation ниже реализует это требование, не меняя +правила расчёта дохода или выбранные пользователем возможности. + +IncomeAnalyticsService возвращает отдельные `instruments` и `entries`. +Backend группирует выплаты по приоритету UID, FIGI, ticker/type, operation ID +с добавлением валюты. Frontend повторяет эту формулу для поиска состава строки. +Формулы пока совпадают; отсутствие явной связи допускает их дальнейшее +расхождение без изменения самих денежных итогов. + +Frontend уже имеет page VM/view pattern, общую фабрику test QueryClient и +централизованный teardown. Остатки локальны: Events выбирает состояние и читает +данные в container; auth tests используют самостоятельные clients, один из +которых создаётся при render wrapper; T-Bank mutation tests повторяют client +configuration. Большинство остальных замечаний устранено ранее. + +## Goals / Non-Goals + +**Goals:** + +- Один владелец связи каждой выплаты с aggregate Instrument/currency row. +- Frontend получает состав breakdown без восстановления server identity. +- Events следует существующему VM/view pattern; тестовый cache lifetime + определяется одним test case и сохраняется при rerender. +- Audit status и документация опираются на фактически подтверждённую поставку. + +**Non-Goals:** + +- Изменение identity priority, денежных алгоритмов, source currencies, + pagination, временных границ или прав доступа. +- Изменение runtime auth/query/cache policy, общий cleanup приложения, + новый framework тестирования или универсальный provider harness. +- Изменение governance, исторических audit claims либо восстановление + отсутствующих approvals прежних commits по косвенным признакам. + +## Decisions + +### 1. Backend передаёт opaque membership key каждой income entry + +Income-specific transport type `IncomeAnalyticsEntryDto` расширяет существующий +`BrokerageOperationDto` обязательным строковым `instrumentKey`. +`IncomeAnalyticsDto.entries` использует этот subtype. Ledger endpoint и его +общий DTO не приобретают income-specific обязанностей. + +`instrumentKey` совпадает с `IncomeInstrumentDto.key` соответствующей строки. +После отбора подходящих выплат backend один раз вычисляет ключ каждой entry +по существующей формуле. Aggregation по инструментам использует уже +вычисленный `entry.instrumentKey`, а не повторный вызов формулы. Остальные +агрегаты продолжают работать с теми же выплатами и exact decimal helpers. + +Сохраняются состав и порядок top-level entries, порядок выплат внутри группы, +сортировка instruments, отрицательные значения и receipt counts. Не вводятся +дедупликация записей, новый идентификатор операции или зависимость от +уникальности ID, которой текущая коллекция дополнительно не проверяет. +Все entries выбранной аналитики имеют membership, даже если upstream не дал +UID, FIGI, ticker или instrument type; прежний fallback остаётся у backend. + +Frontend воспринимает значение как opaque string и не разбирает его формат. +Изменение backend identity representation впоследствии не требует второй +реализации правила в клиенте. + +Alternatives: + +- Только дополнить тесты одинаковой формулы: фиксирует текущие примеры, но + оставляет двух владельцев правила; не устраняет исходную причину drift. +- Добавить `entryIds` к instruments: компактно, но требует второй связи через + ID и дополнительных предположений при одинаковых ID; прямой ключ entry + выражает ровно нужное отношение без такого lookup. +- Вложить полные entries в каждую строку: устраняет сопоставление, но при + сохранении существующего top-level массива дублирует наиболее объёмную часть + ответа; удаление массива осложняет совместимость без необходимости. +- Shared frontend/backend package с формулой: добавляет межрепозиторную + зависимость и по-прежнему раскрывает клиенту server identity algorithm. + +### 2. Income VM собирает и проверяет только переданную связь + +Существующий response-to-display mapper остаётся у Income VM. Он строит +`Map` одним проходом, добавляя entries к bucket без +копирования ранее накопленного массива. Для каждой instrument row берётся +bucket её ключа; trend derivation остаётся там же, UI geometry — во view. +Клиентская `incomeEntryKey` удаляется. + +На этой границе проверяется целостность нового отношения: membership key +присутствует и является непустой строкой, instrument keys однозначны, каждой +entry соответствует существующая строка той же валюты, количество записей +каждой строки соответствует `receiptCount`. Для непустой строки отсутствие +entries не подменяется успешным пустым drill-down. Денежные суммы на frontend +повторно не рассчитываются. + +При нарушении связи mapper возвращает явный неуспешный результат, а VM выбирает +существующее локальное error/retry состояние аналитики. Это сохраняет уже +принятое поведение для неполного результата: не показывать его как полный и +не превращать ожидаемую ошибку данных в route crash. Нет fallback на прежнюю +формулу, пропуска неизвестных entries или исправления полученных данных. +Полностью пустой ответ с пустыми instruments и entries остаётся допустимым. + +Проверка ограничена новым membership seam; общий runtime DTO validator, +новые schema libraries и общий error protocol не вводятся. Backend service +tests фиксируют соответствие membership, counts и точных итогов для UID/FIGI/ +ticker/type/operation fallback, валют и отрицательных корректировок. Frontend +behavior tests используют opaque keys, не выводимые из identity fields, и +отдельно проверяют recoverable отказ при повреждённой связи. + +### 3. Events получает обычный page VM + +Page VM владеет account route input, существующим authenticated entity hook, +retry callback и discriminated state loading/error/empty/loaded. Container +вызывает один VM и выбирает уже существующие state views. Данные и callbacks +передаются props; новые layout wrappers и state-view files не нужны. + +Извлечение сохраняет текущий порядок выбора состояний, поведение при +отсутствующем account ID, UI событий и действия восстановления. Изменение +фонового refetch поведения не смешивается с переносом обязанностей. +Наблюдаемая граница проверки — страница и существующий entity seam. + +### 4. Остатки test clients используют существующую фабрику + +Auth и T-Bank test harnesses используют `createTestQueryClient`; при необходимости +query-only wrapper остаётся `createQueryWrapper`. Client создаётся до render +React wrapper, один раз на независимый test case, и доступен для cache assertions. +Существующий локальный выбор AuthProvider, Mantine, Router и initial entries +сохраняется; глобальный client или render-with-everything helper не появляются. + +Создание client внутри обычной функции `renderPage` или `renderRoutes`, которая +вызывается один раз на case, само по себе не является дефектом. Перенос нужен +там, где создание выполняется в React render wrapper или повторяет default +policy. Shared teardown сохраняет порядок cleanup, auth reset, MSW reset. +Общая инфраструктура не заменяется, используются уже установленные зависимости +и имеющиеся helpers; обязательный trigger Solution Assessment отсутствует. + +### 5. Audit evidence остаётся в существующих durable owners + +Три исходных audit reports сохраняются byte-for-byte как versioned snapshots +в docs с однозначным index. Исходные source files и прежние snapshots не +редактируются. Единственный live remediation registry получает нормализованное +сопоставление повторяющихся claims, текущий change и evidence: одинаковые +номера F из разных отчётов не считаются одинаковыми Audit IDs автоматически. + +Существующие исправления отмечаются как подтверждённое состояние с реальными +ссылками, без фиктивных implementation tasks. Незакрытые остатки относятся к +текущему change; все существенные claims получают disposition, чтобы состав +закрытия можно было восстановить из registry. T-Bank cache boundary ссылается +на уже существующую завершённую поставку. + +As-built docs обновляются до фактического результата реализации. Completion +Evidence принадлежит существующему двухфазному завершению после archive и +delivery commits. Новая запись различает прежние implementation commits и +собственные наблюдения текущей проверки, не объявляя прежние commits прошедшими +несуществовавший SDD lifecycle. Исторические statements о результатах остаются +историческими; `done` требует полного действующего evidence contract. + +## Delivery Map + +| Area | Status | Architectural outcome or N/A reason | +| --- | --- | --- | +| frontend | `affected` | Generated income membership contract, display mapping без identity formula, Events VM и стабильные test clients. | +| backend | `affected` | Income entry subtype с membership key, вычисляемым одним owner и используемым instrument aggregation. | +| specs | `affected` | Canonical Proposal/Design/Tasks и archive текущего change; main Requirements сохраняются, Delta Specs пропущены. | +| docs | `affected` | As-built income/frontend описание, неизменяемые audit sources, их нормализованные статусы и фактическое terminal evidence. | + +### Contract Gate Decision + +| Gate | Status | Reason | +| --- | --- | --- | +| runtime-openapi | `required` | Меняются backend income response representation и frontend snapshot/generated consumer; нужна проверка runtime document против committed snapshot. | + +## Risks / Trade-offs + +- Membership key повторяется у каждой entry и слегка увеличивает response. + Это меньше дублирования целых records и исключает formula ownership в UI. +- Новый frontend требует обновлённый backend. Совместимость обеспечивается + порядком поставки, без бессрочного fallback на старую формулу. +- Повреждённое отношение прекращает показ загруженной аналитики вместо тихой + потери строк. Проверки этого случая принадлежат public behavior seam. +- Существующие backend caches хранят Ledger pages, а analytics response + формируется заново; schema migration и новая cache generation не нужны. +- Не все предыдущие audit corrections имеют историческое terminal evidence. + Текущий change подтверждает наблюдаемое состояние, а не создаёт историю + approval задним числом. Непрошедший affected-area gate блокирует завершение. + +## Migration Plan + +Сначала backend начинает возвращать additive `instrumentKey`, сохраняя все +прежние поля и порядок. Старый frontend продолжает работать с таким ответом. +Backend OpenAPI остаётся source authority; frontend snapshot и generated types +обновляются существующим workflow, после чего переключается frontend consumer. + +При локальном переключении клиент перезагружается: прежние in-memory analytics +results и незавершённые запросы не переносятся в новый consumer. Новый frontend +не поставляется раньше backend. Events/test changes независимы от runtime +contract и не требуют данных для миграции. + +Проверки соответствия существующим требованиям и canonical affected-area gates +предшествуют независимому read-only review. Затем применяется действующий +archive/delivery/evidence порядок; Design не объявляет будущие результаты. + +### Rollback Contract + +| Field | Decision | +| --- | --- | +| Status | `required` | +| Trigger | Обнаружено неверное сопоставление выплат, нарушение совместимости income response или регрессия отображения после переключения. | +| Actions | Сначала вернуть предыдущий frontend consumer и соответствующие snapshot/types, перезагрузить клиент. Затем при необходимости вернуть backend representation; дополнительное поле совместимо со старым клиентом и может временно оставаться. Events/test changes откатываются независимо при регрессии их поведения. | +| Data safety | Изменяются только производные read-only response и клиентские представления; SQLite schema, credentials, Ledger storage и upstream operations не меняются. In-memory данные перечитываются; записи и денежные данные не удаляются. | +| Verification | В возвращённой паре consumer/provider income drill-down соответствует исходным Instrument/currency/period и signed totals; runtime OpenAPI совпадает со snapshot, generated types соответствуют ему, affected-area gates и semantic review не выявляют регрессий. | diff --git a/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/proposal.md b/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/proposal.md new file mode 100644 index 0000000..4bed291 --- /dev/null +++ b/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/proposal.md @@ -0,0 +1,65 @@ +## Why + +Повторная проверка трёх frontend audits показала, что большинство замечаний уже +исправлено, но остаются три связанных источника стоимости сопровождения: +согласованность связи доходов с инструментами зависит от повторения одного +правила в разных частях системы, экран событий не полностью следует принятому +разделению обязанностей, а подготовка части тестов остаётся неоднородной. + +Кроме того, наличие исправлений само по себе не подтверждает завершённость +remediation: результаты повторной проверки и состояние findings ещё не сведены +в актуальное evidence. Завершение этой работы сейчас позволит опираться на +проверенное состояние вместо повторного выполнения уже закрытых рекомендаций. + +Основание: остатки F-03 и F-06 structural maintainability audit, F3 repository +audit от 28 августа, а также отсутствие Completion Evidence для проверенных +исправлений от 6 сентября. Общий repository audit используется для сверки уже +реализованных замечаний и исключения повторной работы. + +## What Changes + +- Устранить зависимость достоверности расшифровки дохода от независимого + повторения правила сопоставления инструментов и выплат. Расшифровка остаётся + точным составом выбранной строки по инструменту, валюте и периоду, включая + отрицательные корректировки и случаи неполной идентификации инструмента. +- Завершить приведение экрана событий к принятому разделению ответственности + за данные, выбор состояния и отображение, сохранив текущее поведение. +- Завершить унификацию подготовки оставшихся тестов: время жизни их состояния + должно быть предсказуемым и не зависеть от повторного отображения обёртки. +- Свести относящиеся к продолжению audit claims и ранее реализованные + исправления в существующий процесс remediation. Подтвердить фактический + результат текущей поставки, отделив наличие кода от доказанного завершения. + +Ожидаемый результат — надёжная прослеживаемость состава дохода, согласованные +обязанности экрана событий и тестового окружения, а также однозначные текущие +статусы замечаний с проверяемым основанием. + +Non-goals: + +- Новые пользовательские возможности, изменение денежных расчётов, валютной + семантики, правил периода, сортировки или состава учитываемого дохода. +- Изменение поведения авторизации, повторная реализация исправленной границы + подключения T-Bank или общий рефакторинг всех экранов. +- Расширение набора проверок ради числового покрытия, внедрение новой общей + инфраструктуры либо изменение правил SDD и audit remediation. +- Возврат перенесённого workbench в приложение, переписывание исторических + аудитов или приписывание прежним исправлениям отсутствующих approvals и + результатов проверок. + +## Capabilities + +### New Capabilities + +### Modified Capabilities + +## Impact + +Затронуты поддержка аналитики дохода и экрана событий, сопровождение тестов и +процесс подтверждения устранения frontend audit findings. Пользовательские +возможности и действующие нормативные требования сохраняются. + +Работа реализует существующее требование +`brokerage-account-income-analytics — Instrument breakdown is traceable to exact Ledger Entries` +и действующие frontend conventions и audit-remediation policy. Изменения +Requirements не требуются; capabilities оставлены пустыми, change использует +`skip_specs: true`. diff --git a/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/tasks.md b/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/tasks.md new file mode 100644 index 0000000..d33f46a --- /dev/null +++ b/openspec/changes/archive/2026-09-06-complete-frontend-audit-remediation/tasks.md @@ -0,0 +1,77 @@ +## 1. Canonical change и источники remediation + +Перед Node-командами в каждой affected области активируется её `.nvmrc` через +`nvm use --silent`; для specs без `.nvmrc` используется `nvm use --silent 22`. +Ни одна task не меняет утверждённые behavior или architecture. Изменение их +смысла возвращает работу к соответствующему planning artifact. + +- [x] 1.1 [specs] Подготовить согласованный canonical комплект Proposal, Design, Tasks и metadata текущего change с `skip_specs: true`, без искусственных Delta Specs и изменения main Requirements. + - **Covers:** `N/A` — собственный результат specs area в Delivery Map: planning artifacts описывают исполнение существующих требований; нового observable behavior нет. + - **Verification:** Наличие ровно текущих Proposal/Design/Tasks и metadata в canonical change; native status показывает skipped specs; содержание соответствует решениям Change Owner в conversation. +- [x] 1.2 [docs] Сохранить три исходных frontend audit reports как неизменяемые versioned snapshots с однозначным index и ссылкой из общего audit index. + - **Covers:** `audit-remediation-workflow` — `Реестр remediation отделён от снимка аудита` + - **Verification:** Byte-for-byte сравнение каждого snapshot с соответствующим исходным report; все три источника доступны из index, прежние snapshots и source files не изменены. + +## 2. Backend income membership + +- [x] 2.1 [backend] Добавить income-specific entry subtype с обязательным `instrumentKey`; вычислять membership один раз после отбора выплат и группировать instruments по этому ключу, сохранив существующие DTO Ledger endpoint, суммы и порядок. + - **Covers:** `brokerage-account-income-analytics` — `Instrument breakdown is traceable to exact Ledger Entries`; `brokerage-account-income-analytics` — `Realized income uses exact executed coupon and dividend payments` + - **Verification:** Income response содержит связь каждой entry с её instrument row; прежние поля, порядок entries и сортировка instruments сохраняются; membership не требует дедупликации или нового ID; OpenAPI subtype наследует поля Ledger entry и объявляет строковый required key. +- [x] 2.2 [backend] Дополнить IncomeAnalyticsService tests проверками membership и согласованности состава групп с exact totals и receipt counts. + - **Covers:** `brokerage-account-income-analytics` — `Instrument breakdown is traceable to exact Ledger Entries`; `brokerage-account-income-analytics` — `Realized income uses exact executed coupon and dividend payments` + - **Verification:** `npm test -- --runInBand income-analytics.service.spec.ts`; cases покрывают UID priority над FIGI/ticker, FIGI fallback, ticker/type с частично отсутствующими данными, operation fallback без instrument identity, разделение валют, отрицательную корректировку и сохранение порядка/состава выплат. + +## 3. Frontend contract и ownership + +- [x] 3.1 [frontend] После backend representation обновить committed OpenAPI snapshot из backend Swagger document, регенерировать types штатным workflow и привести затронутые income fixtures к новому subtype. + - **Covers:** `N/A` — синхронизация generated transport boundary по Design decision 1; она технически необходима для typed consumer существующей аналитики и не вводит отдельного пользовательского поведения. + - **Verification:** `npm run openapi:generate` и `npm run openapi:check`; snapshot получен от backend, а не от ручного DTO редактирования; generated entry содержит обязательный `instrumentKey`, остальные поля Ledger доступны без ручного transport type. +- [x] 3.2 [frontend] Перевести Income display mapper на opaque membership key одним проходом, удалить клиентскую identity formula и вернуть явный неуспешный результат при повреждённой связи с переходом VM в существующее локальное error/retry состояние. + - **Covers:** `brokerage-account-income-analytics` — `Instrument breakdown is traceable to exact Ledger Entries`; `brokerage-account-income-analytics` — `Realized analytics never presents an incomplete result as complete` + - **Verification:** В mapper нет восстановления UID/FIGI/ticker/operation identity и пересчёта Money; проверяются непустой строковый membership, однозначность instrument keys, наличие instrument row, совпадение валюты и receiptCount. Полностью пустой ответ допустим; неизвестные entries не отбрасываются, неполный breakdown не подменяется пустым успешным результатом. +- [x] 3.3 [frontend] Дополнить income behavior tests проверками opaque membership, повреждённой связи и восстановления после retry, сохранив проверки trend и независимого forecast. + - **Covers:** `brokerage-account-income-analytics` — `Instrument breakdown is traceable to exact Ledger Entries`; `brokerage-account-income-analytics` — `Realized analytics never presents an incomplete result as complete`; `brokerage-account-income-analytics` — `Forecast is separate from realized income` + - **Verification:** `npm run test:run -- src/pages/account-income/ui/AccountIncomePage.test.tsx`; произвольные server keys работают независимо от identity fields; отсутствующий/пустой/нестроковый key, неизвестная группа, duplicate instrument key, несовпадение валюты и количества дают local error без route crash; после корректного ответа retry возвращает аналитику. Пустой ответ и signed entries отображаются корректно. +- [x] 3.4 [frontend] Выделить Events page VM для route input, entity query, выбора состояния и retry; оставить container с одним VM hook и существующими state views, дополнив только необходимые regression checks страницы. + - **Covers:** `N/A` — перенос обязанностей согласно Design decision 3 и текущей VM/view convention сохраняет пользовательское поведение Events и не меняет normative requirements. + - **Verification:** `npm run test:run -- src/pages/account-events/ui/AccountEventsPage.test.tsx src/entities/brokerage-event/api/useBrokerageEvents.test.tsx`; сохраняются loading/error/empty/loaded, retry, передача account route input, отсутствие запроса без account ID и текущий порядок выбора состояния. View не получает data/router hooks. +- [x] 3.5 [frontend] Перевести оставшиеся auth и T-Bank test clients на существующую фабрику, создавая client до React wrapper render и сохраняя доступ для cache assertions. + - **Covers:** `N/A` — завершение использования existing test infrastructure по Design decision 4; runtime auth и query policy не меняются, отдельного observable product behavior нет. + - **Verification:** `npm run test:run -- src/features/auth/model/auth.test.tsx src/features/tbank-connection/ui/TbankConnectionSection.test.tsx`; существующая auth/session/cache проверка сохраняет тот же client и seeded data при явном rerender. Новые случаи получают отдельные clients; feature-specific providers остаются локальными; production defaults и общий teardown не меняются. + +## 4. As-built documentation и live registry + +- [x] 4.1 [docs] Обновить фактическое описание income membership и frontend ownership, указав порядок backend-first обновления, перезагрузку клиента и согласованный rollback без изменения денежных правил. + - **Covers:** `N/A` — as-built результат docs area по Design и Migration Plan; документируется поставленная реализация существующих требований, а не новое поведение или параллельный planning authority. + - **Verification:** Описание соответствует реализованному response, mapper и Events VM; local links разрешаются; несовместимая пара new frontend/old backend не представлена поддерживаемой; rollback возвращает consumer раньше provider и не затрагивает сохранённые данные. +- [x] 4.2 [docs] Нормализовать claims трёх snapshots в существующем remediation registry, связать оставшиеся исправления с текущим change, а уже реализованные — с проверенными источниками и существующим evidence. + - **Covers:** `audit-remediation-workflow` — `Каждое audit claim получает доказательный disposition`; `audit-remediation-workflow` — `Registry задаёт однозначный статус и следующий change`; `audit-remediation-workflow` — `Terminal status подтверждён проверяемым evidence` + - **Verification:** Каждое из 22 source findings однозначно сопоставлено registry record; повторяющиеся underlying claims объединены со ссылками на все источники. Disposition отделён от remediation status, source-local F IDs не смешаны, текущий change — единственный active remediation; прежняя T-Bank cache поставка использует своё existing evidence. Ни один новый done не заявлен без полного terminal evidence. + +## 5. Affected-area gates после реализации + +Canonical gate каждой affected области выполняется один раз на итоговом +состоянии под Node 22; повтор нужен только после исправлений или нового failure. +Targeted checks выше служат разработке и не подменяют completion gates. + +- [x] 5.1 [backend] Выполнить canonical backend gate на итоговом состоянии реализации. + - **Covers:** `N/A` — обязательная проверка affected backend area по Delivery Map; gate подтверждает реализацию, а не вводит самостоятельное поведение. + - **Verification:** `npm run verify` из backend; сохранить exit status и relevant diagnostics всех составляющих, не подменяя failed step отдельным выборочным тестом. +- [x] 5.2 [frontend] Выполнить canonical frontend gate на итоговом состоянии реализации. + - **Covers:** `N/A` — обязательная проверка affected frontend area по Delivery Map, включая уже существующие audit corrections, без расширения runtime scope. + - **Verification:** `npm run verify` из frontend; сохранить outcome OpenAPI drift check, TypeScript, Biome, coverage-backed suite, Knip, dependency boundaries и build. +- [x] 5.3 [backend] Выполнить required runtime OpenAPI contract gate после синхронизации frontend snapshot. + - **Covers:** `N/A` — cross-area contract gate имеет backend owner и требуется Design Contract Gate Decision для согласованности provider/consumer representation. + - **Verification:** `npm run test:openapi-contract` из backend; runtime document сопоставляется с committed frontend snapshot, включая income subtype и ранее исправленный connectedAt contract. +- [x] 5.4 [docs] Выполнить canonical documentation gate после обновления as-built текста и registry. + - **Covers:** `N/A` — обязательный docs gate и scoped link review подтверждают пригодность durable документации из Delivery Map. + - **Verification:** `npm run verify` из docs; scoped review local links новых audit indexes, source mappings и изменённых feature/development документов. +- [x] 5.5 [specs] Выполнить native strict validation canonical change, main specs и project-local schema. + - **Covers:** `N/A` — обязательный structural gate specs area при skip_specs; проверяется canonical planning, без фиктивных изменений main Requirements. + - **Verification:** Из specs: `openspec schema validate wealth-ledger-sdd --verbose`; `openspec validate complete-frontend-audit-remediation --type change --strict --store wealth-ledger-specs`; `openspec validate --specs --strict --store wealth-ledger-specs`. + +## 6. Independent read-only Validation + +- [x] 6.1 [workspace] Независимо сопоставить итоговую реализацию с утверждёнными Proposal/Design/Tasks и применимыми main Requirements, выполнить standards review и проверить полноту audit mapping. + - **Covers:** `N/A` — только cross-repository semantic verification и independent review; workspace не владеет implementation и не создаёт конкурирующий spec или evidence store. + - **Verification:** Read-only review проверяет income membership и recoverable ошибки, сохранение денежных результатов и порядка, Events state ownership, test-client lifetime, backend-first compatibility/rollback и traceability всех material audit claims. Рассмотреть observed gates каждой area; отсутствие Critical/Important findings и semantic несоответствий необходимо для Validation PASS. Недостаток evidence или failure возвращает работу ответственному owner, а не маскируется unchecked-task override.