diff --git a/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/.openspec.yaml b/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/.openspec.yaml
new file mode 100644
index 0000000..f845845
--- /dev/null
+++ b/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/.openspec.yaml
@@ -0,0 +1,2 @@
+schema: wealth-ledger-sdd
+created: 2026-08-27
diff --git a/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/design.md b/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/design.md
new file mode 100644
index 0000000..c96866a
--- /dev/null
+++ b/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/design.md
@@ -0,0 +1,82 @@
+## Context
+
+Страница полного журнала `account-operations` уже фильтруется по периоду и категориям, но фильтры применяются немедленно на каждое изменение контрола. Текущее состояние — два нативных `` и строка чекбоксов для категорий, все в состоянии React. Backend API `/api/v1/brokerage-accounts/{accountId}/operations` уже поддерживает параметры `from`, `to`, `categories`, `cursor`, `limit` и нормализует категории (порядок и дубликаты не создают отдельную cache identity). Кэш страниц Account Ledger (Ledger Page Cache Key) уже определён глоссарием и не меняется.
+
+## Goals / Non-Goals
+
+**Goals:**
+- Сделать применение фильтров явным: черновик не влияет на запрос до подтверждения.
+- Сохранить существующий API-контракт, cursor-пагинацию и серверный дефолт периода.
+- Визуальное оформление полей в едином стиле продукта (Mantine-контролы, русская локаль календаря).
+- Пагинация продолжает работать по последнему применённому фильтру.
+
+**Non-Goals:**
+- Не менять backend API, параметры запроса или серверный дефолт.
+- Не синхронизировать фильтры с URL, не добавлять шаринг по ссылке.
+- Не добавлять новые измерения фильтров (только период и категории).
+- Не менять отображение записей журнала.
+
+## Decisions
+
+### Разделение draft и applied состояния
+Черновик хранится в `draftFrom`, `draftTo`, `draftCategories`; запрос `useBrokerageOperations` использует `appliedFrom`, `appliedTo`, `appliedCategories`. Применённое состояние = Ledger Page Cache Key identity (User, Brokerage Account, нормализованные период и категории, cursor, limit). Черновик — только UI.
+
+**Rationale:** минимальное изменение существующей VM-архитектуры; не требует нового слоя состояния за пределами компонента страницы. **Alternatives:** вынести фильтр в URL-параметры (отвергнуто: нет требования шаринга, усложняет пагинацию), глобальное состояние (отвергнуто: фильтр локален для страницы).
+
+### Два отдельных DateInput вместо range picker
+Два поля `DateInput` («С»/«По») с мин/макс-ограничением вместо одного `DatePickerInput type="range"`.
+
+**Rationale:** сохраняет существующую раскладку, i18n-ключи `ledger.from`/`ledger.to`, поддерживает частичные фильтры (только «от» или только «по») явно, минимальный diff. Range picker компактнее визуально, но сложнее в partial-состояниях и клавиатурном вводе.
+
+### MultiSelect для категорий
+Mantine `MultiSelect` с `clearable`, placeholder «Выберите категории», данные из `operationCategories`.
+
+**Rationale:** стандартный паттерн мультивыбора в Mantine, searchable out-of-the-box. **Alternatives:** Popover+Checkbox.Group (отвергнуто: дублирует существующую модель), Select multiple (отвергнуто: менее заметен выбор).
+
+### DatesProvider с русской локалью
+Глобальный `DatesProvider settings={{ locale: "ru" }}` в `App.tsx` + `import "dayjs/locale/ru"`.
+
+**Rationale:** календарь DateInput показывает русские названия месяцев/дней недели. Без этого — английская локаль dayjs по умолчанию.
+
+### Зависимости с точными версиями
+`@mantine/dates` и `dayjs` объявляются прямыми зависимостями с точными версиями (pin), как остальные пакеты в `package.json`.
+
+**Rationale:** конвенция репо — exact pins; Knip требует объявлять используемые пакеты.
+
+## Delivery Map
+
+| Area | Status | Architectural outcome or N/A reason |
+| --- | --- | --- |
+| frontend | `affected` | Draft/applied state в VM страницы; DateInput×2 + MultiSelect + «Применить»/«Сбросить» в view; DatesProvider ru; pinned deps; risk-based тесты |
+| backend | `N/A` | API-контракт, параметры запроса и серверный дефолт не меняются |
+| specs | `affected` | Delta spec добавляет Requirement «User can explicitly apply ledger filters» в `brokerage-account-ledger` |
+| docs | `affected` | `docs/features/brokerage-account-ledger.md` обновляет раздел о поведении фильтров |
+
+### Contract Gate Decision
+
+| Gate | Status | Reason |
+| --- | --- | --- |
+| runtime-openapi | `N/A` | Backend API-контракт не меняется; frontend OpenAPI snapshot остаётся прежним |
+
+## Risks / Trade-offs
+
+- **Биом-касты**: `value as Date | null` и `as OperationCategory[]` могут триггерить `no-unnecessary-type-assertion` — убрать при флаге линтера, проверить через `npm run verify`.
+- **Календарь без dayjs/ru**: без `DatesProvider` или `import "dayjs/locale/ru"` календарь англоязычный — критичный UX-дефект для RU-интерфейса.
+- **Тестовое покрытие**: текущий тест покрывает apply+reset пагинации, но не «черновик не шлёт запрос» и «Сбросить очищает»; добавить risk-based тесты.
+
+## Migration Plan
+
+Порядок:
+1. Specs: delta spec (уже создан).
+2. Frontend: deps → DatesProvider → view/vm полировка → тесты → gate verify.
+3. Docs: обновить as-built feature doc.
+4. Archive: после всех gates.
+
+Нет миграции данных, нет изменения контракта — односторонняя frontend-замена контролов.
+
+### Rollback Contract
+
+| Field | Decision |
+| --- | --- |
+| Status | `N/A` |
+| Reason | Нет необратимых решений: frontend-only change контролов, без API/данных/auth/security. Откат = revert commit. |
diff --git a/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/proposal.md b/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/proposal.md
new file mode 100644
index 0000000..c1bab46
--- /dev/null
+++ b/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/proposal.md
@@ -0,0 +1,51 @@
+## Why
+
+На странице «Журнал операций» фильтры применяются немедленно на каждое
+изменение контрола, выбор даты сделан нативными `` с
+браузерным оформлением, а категории выложены строкой из чекбоксов. Пользователь
+ожидает: понятный визуальный вид полей, выпадающий список с мультивыбором для
+категорий и явные действия «Применить»/«Сбросить», при которых запрос к
+серверу идёт только после подтверждения. Сейчас эти ожидания не выполняются.
+
+## What Changes
+
+Намерение: на странице «Журнал операций» заменить нативный выбор периода на
+контрол в едином визуальном стиле продукта, собрать категории в выпадающий
+список с мультивыбором и сделать применение фильтров явным: черновик в
+контролах не меняет видимый список до подтверждения, подтверждение применяет
+черновик и сбрасывает пагинацию на первую страницу, сброс фильтров очищает
+черновик и немедленно возвращает список к пустому фильтру (сохранив серверный
+дефолт периода «с 1 января текущего года»).
+
+Non-goals:
+- Не меняется API-контракт, параметры запроса, cursor-пагинация или
+ серверный дефолт периода.
+- Не вводится URL-синхронизация фильтров, шаринг по ссылке и back/forward
+ по значениям фильтров.
+- Не добавляются новые измерения фильтров (только период и категории из
+ существующих категорий: `trade`, `income`, `tax`, `fee`, `transfer`,
+ `other`).
+- Не изменяется отображение записей, подпись типа события или направление
+ денежного движения.
+
+## Capabilities
+
+### New Capabilities
+- _none_
+
+### Modified Capabilities
+- `brokerage-account-ledger`: новое requirement «User can explicitly apply
+ ledger filters» — явное применение черновика периода и категорий, сброс
+ фильтров и сохранение пагинации по применённому состоянию. Существующие
+ requirements о серверной фильтрации, cache identity и компактном
+ представлении записей остаются без изменений.
+
+## Impact
+
+- Пользователи страницы полного журнала брокерского счёта — визуальное
+ оформление фильтров и явное применение.
+- Frontend-страница `account-operations` — новые контролы и draft/applied
+ семантика.
+- Backend и API-контракт: не затрагиваются.
+- Кэш страниц Account Ledger: identity не меняется — нормализация
+ категорий, нормализованный период, cursor и limit сохраняются.
diff --git a/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/specs/brokerage-account-ledger/spec.md b/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/specs/brokerage-account-ledger/spec.md
new file mode 100644
index 0000000..fbf8a72
--- /dev/null
+++ b/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/specs/brokerage-account-ledger/spec.md
@@ -0,0 +1,20 @@
+## ADDED Requirements
+
+### Requirement: User can explicitly apply ledger filters
+Система MUST позволять User формировать черновик периода и категорий на странице полного журнала и применять его явным действием. Пока черновик изменён, но не применён, видимый список записей и его курсорная пагинация MUST оставаться основанными на последнем применённом состоянии. Явное применение MUST коммитить черновик в применимое состояние и сбрасывать курсорную пагинацию на первую страницу. Сброс фильтров MUST очищать черновик, немедленно применять пустой фильтр (период по умолчанию и все категории) и сбрасывать пагинацию.
+
+#### Scenario: Черновик изменён, но не применён
+- **WHEN** User изменил период или категории в контролах фильтров, но не нажал «Применить»
+- **THEN** видимый список записей остаётся основанным на последнем применённом фильтре, а новый запрос к серверу не выполняется
+
+#### Scenario: Применение черновика
+- **WHEN** User нажал «Применить» на фильтре журнала с изменённым черновиком
+- **THEN** черновик коммитится в применимое состояние, курсорная пагинация сбрасывается на первую страницу и выполняется новый запрос с применённым периодом и категориями
+
+#### Scenario: Сброс фильтров
+- **WHEN** User нажал «Сбросить» на фильтре журнала
+- **THEN** черновик очищается, немедленно применяется пустой фильтр (период по умолчанию и все категории) и курсорная пагинация сбрасывается на первую страницу
+
+#### Scenario: Пагинация по применённому фильтру
+- **WHEN** User переходит к следующей или предыдущей странице журнала при изменённом, но не применённом черновике
+- **THEN** пагинация выполняется по последнему применённому фильтру, а черновик в контролах сохраняется
diff --git a/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/tasks.md b/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/tasks.md
new file mode 100644
index 0000000..2f87f97
--- /dev/null
+++ b/openspec/changes/archive/2026-08-27-account-ledger-explicit-filters/tasks.md
@@ -0,0 +1,45 @@
+## 1. Frontend implementation
+
+- [x] 1.1 [frontend] Запинить `@mantine/dates` 9.5.1 и `dayjs` 1.11.23 в `package.json` без caret-префиксов; синхронизировать `package-lock.json`.
+ - **Covers:** `N/A` — техническая необходимость: репо использует exact pins, Knip требует объявленные зависимости.
+ - **Verification:** `cd frontend && npm ci` без изменений lockfile.
+
+- [x] 1.2 [frontend] Добавить `import "dayjs/locale/ru"` в `src/main.tsx` и обернуть `` внутри `` в `src/app/ui/App.tsx`.
+ - **Covers:** `N/A` — техническая необходимость: без этого календарь DateInput показывает английскую локаль.
+ - **Verification:** `npm run typecheck` проходит; ручная проверка попапа календаря показывает русские названия месяцев.
+
+- [x] 1.3 [frontend] Добавить i18n-ключ `ledger.categoriesPlaceholder: "Выберите категории"` в `src/shared/i18n/locales/ru.ts` и заменить placeholder у MultiSelect в `AccountOperationsPageLoaded.view.tsx`.
+ - **Covers:** `brokerage-account-ledger` — `User can explicitly apply ledger filters` (UI-полировка мультивыбора категорий).
+ - **Verification:** MultiSelect placeholder показывает «Выберите категории» вместо дубликата label.
+
+- [x] 1.4 [frontend] Проверить и убрать ненужные касты (`value as Date | null`, `as OperationCategory[]`) в `AccountOperationsPageLoaded.view.tsx`, если Biome/TS-линтер флагают `no-unnecessary-type-assertion`.
+ - **Covers:** `N/A` — техническая необходимость: gate `npm run lint` должен проходить.
+ - **Verification:** `npm run lint` без ошибок type assertion.
+
+- [x] 1.5 [frontend] Добавить risk-based тесты в `AccountOperationsPage.test.tsx`: (a) изменение черновика НЕ вызывает новый запрос до «Применить»; (b) «Сбросить» очищает категории и период и перезапрашивает без параметров.
+ - **Covers:** `brokerage-account-ledger` — `User can explicitly apply ledger filters` (сценарии «Черновик изменён, но не применён» и «Сброс фильтров»).
+ - **Verification:** `npm run test:run` — оба новых теста проходят.
+
+## 2. Docs update
+
+- [x] 2.1 [docs] Обновить `docs/features/brokerage-account-ledger.md` пункт 32: описать staged draft/applied семантику фильтров, явные «Применить»/«Сбросить», пагинацию по применённому фильтру.
+ - **Covers:** `brokerage-account-ledger` — `User can explicitly apply ledger filters` (as-built документация).
+ - **Verification:** `cd docs && npm run verify` проходит.
+
+## 3. Gates and archive
+
+- [x] 3.1 [frontend] Запустить canonical gate: `cd frontend && npm ci && npm run verify`.
+ - **Covers:** `N/A` — финальная проверка frontend-реализации.
+ - **Verification:** typecheck + lint + coverage-ratchet + knip + deps + build проходят.
+
+- [x] 3.2 [specs] Запустить `openspec validate account-ledger-explicit-filters --type change --strict --store wealth-ledger-specs` и `openspec validate --specs --strict --store wealth-ledger-specs`.
+ - **Covers:** `N/A` — structural validation change и main specs.
+ - **Verification:** Обе команды exit 0.
+
+- [x] 3.3 [workspace] Semantic verification реализации против утверждённых Proposal, Delta Specs, Design и Tasks; independent read-only review.
+ - **Covers:** `N/A` — оркестрация финальной проверки перед archive.
+ - **Verification:** Reviewer-confirmation без Critical/Important findings.
+
+- [x] 3.4 [specs] Отметить tasks выполненными и archive change через `openspec archive`.
+ - **Covers:** `N/A` — закрытие change lifecycle.
+ - **Verification:** `openspec status` показывает change archived; commits в affected repos (specs, frontend, docs) без пустых коммитов.
diff --git a/openspec/specs/brokerage-account-ledger/spec.md b/openspec/specs/brokerage-account-ledger/spec.md
index c837256..1cf98d8 100644
--- a/openspec/specs/brokerage-account-ledger/spec.md
+++ b/openspec/specs/brokerage-account-ledger/spec.md
@@ -108,3 +108,22 @@
#### Scenario: Просроченная страница не возвращается
- **WHEN** cached страница журнала старше 30 секунд
- **THEN** система не возвращает её как свежий результат и получает актуальную страницу из upstream
+
+### Requirement: User can explicitly apply ledger filters
+Система MUST позволять User формировать черновик периода и категорий на странице полного журнала и применять его явным действием. Пока черновик изменён, но не применён, видимый список записей и его курсорная пагинация MUST оставаться основанными на последнем применённом состоянии. Явное применение MUST коммитить черновик в применимое состояние и сбрасывать курсорную пагинацию на первую страницу. Сброс фильтров MUST очищать черновик, немедленно применять пустой фильтр (период по умолчанию и все категории) и сбрасывать пагинацию.
+
+#### Scenario: Черновик изменён, но не применён
+- **WHEN** User изменил период или категории в контролах фильтров, но не нажал «Применить»
+- **THEN** видимый список записей остаётся основанным на последнем применённом фильтре, а новый запрос к серверу не выполняется
+
+#### Scenario: Применение черновика
+- **WHEN** User нажал «Применить» на фильтре журнала с изменённым черновиком
+- **THEN** черновик коммитится в применимое состояние, курсорная пагинация сбрасывается на первую страницу и выполняется новый запрос с применённым периодом и категориями
+
+#### Scenario: Сброс фильтров
+- **WHEN** User нажал «Сбросить» на фильтре журнала
+- **THEN** черновик очищается, немедленно применяется пустой фильтр (период по умолчанию и все категории) и курсорная пагинация сбрасывается на первую страницу
+
+#### Scenario: Пагинация по применённому фильтру
+- **WHEN** User переходит к следующей или предыдущей странице журнала при изменённом, но не применённом черновике
+- **THEN** пагинация выполняется по последнему применённому фильтру, а черновик в контролах сохраняется