docs(specs): archive frontend audit remediation

This commit is contained in:
2026-09-06 19:49:17 +03:00
parent 50a6721a60
commit ab231a6aac
4 changed files with 354 additions and 0 deletions
@@ -0,0 +1,3 @@
schema: wealth-ledger-sdd
created: 2026-09-06
skip_specs: true
@@ -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<string, entries[]>` одним проходом, добавляя 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 не выявляют регрессий. |
@@ -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`.
@@ -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.