## 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.