# BAT-016 Design: Review decision persistence and reconciliation workbench ## Design Status - Status: completed - Owner: 가웨인 direct recovery path; Kanban prohibited by user. ## Architecture Summary BAT-016 adds a small review-state layer beside the existing ledger facts. Transactions, accounts, imports, categories, and reports remain the financial source of truth; `review_decisions` and `reconciliation_sessions` store operator workflow state only. MCP and Streamlit adapters use the existing `service.py` facade and page/domain gateways, so the new behavior is additive to current consumers. ## Changed Areas - SQLite schema/migrations: schema version `11`, new `review_decisions` and `reconciliation_sessions` tables plus indexes. - Application: new `review_decision_service.py` owns decision/session persistence, payload sanitization, operating indicators, and attachment helpers. - Existing services: cross-transfer queue, reconciliation report, and uncategorized workbench attach persisted review/session state with additive fields. - MCP: safe review decision/session tools registered through `tool_contracts.py` and `server.py`. - Streamlit: dashboard actions for review decisions and reconciliation sessions through existing gateways. - Docs/tests: data model/project structure/runtime flow baselines and pytest coverage. ## Key Decisions 1. **Schema** - `review_decisions`: common decision envelope with `target_type`, `target_id`, `status`, `decision_type`, `reason_code`, `memo`, `operator`, `decided_at`, `review_after`, `target_payload`, timestamps. - `reconciliation_sessions`: account/basis-date session records with expected/actual/difference, `status`, `closed_at`, source/memo/operator, timestamps. - Migrations are additive and idempotent using `CREATE TABLE IF NOT EXISTS` and `CREATE INDEX IF NOT EXISTS`. 2. **State model** - Review statuses: `pending`, `decided`, `held`, `needs_recheck`, `ignored`. - Decision types: `account_transfer`, `real_expense`, `real_income`, `investment_transfer`, `excluded_from_analysis`, `duplicate_or_cancel`, `unknown`. - Reconciliation statuses: `open`, `closed`, `needs_recheck`, `ignored`. 3. **Payload safety** - `target_payload` is minimal JSON text; known sensitive keys such as `raw_payload`, password/token/secret/file_path are dropped before persistence. 4. **Contracts** - Existing payloads remain compatible; new fields such as `review_status`, `review_decision`, and `reconciliation_session` are additive. - MCP adds non-destructive tools only; no delete/reset tool is exposed. 5. **Operating indicators** - The service computes pending review, held/recheck, unreconciled account count, last reconciliation close time, and uncategorized recommendation backlog from persisted state plus current ledger state. ## Edge Cases - Unknown/invalid status or decision type returns validation errors rather than writing inconsistent state. - Release/hold/recheck operations target the latest decision for a given target and preserve audit timestamps. - Reconciliation session `difference` can be supplied or derived from expected/actual values. - Empty or unparsable `target_payload` is reduced to `{}` or a short summary, never raw financial evidence expansion. ## Architecture Impact - `both`: project structure gains `application/review_decision_service.py`; runtime flows gain review-decision/reconciliation workbench flow. ## Reference Doc Update Plan - `docs/data-model.md`: add review/session entities, state values, and payload-minimization rules. - `docs/project-structure.md`: list `review_decision_service.py` ownership. - `docs/runtime-flows.md`: add review decision and reconciliation workbench runtime flow.