1. **High — `src/jarvis_finance/services/household_classification.py:529-579` — salary detection can misclassify an unpaired internal transfer as income.** The transfer guard recognizes only narrow phrases such as `own account transfer`; afterward, any positive bank description containing the substring `lohn` becomes a salary proposal. A description such as `Übertrag von Lohnkonto` therefore bypasses the transfer guard and can be auto-materialized under an existing `Lohn` category. **Fix:** fail closed on generic transfer/`übertrag`/account-transfer wording before income-category rules unless a safe pair exists, and require bounded, explicit salary evidence such as `lohnzahlung`, `salary`, or `payroll` rather than substring matching. 2. **Important — `src/jarvis_finance/services/household_classification.py:432-469` — recurring matching does not enforce the claimed account/currency/cadence scope.** An active rule with no `account_id` matches every account; currency is not queried or compared; weekly/irregular rules have no date check; quarterly/yearly rules only compare day-of-month and ignore expected month/period. These matches become `proposal_ready` and clear `requires_review`, despite reporting `account_scope_checked`. **Fix:** require exact currency and, for automatic classification, a present exact account match; validate cadence for every supported automatic frequency, including expected month for quarterly/yearly. Leave accountless or insufficiently scheduled rules as `decision_needed`. 3. **Important — `frontend/src/pages/HouseholdImportsPage.vue:16,142-150` — four-file UI advertises a per-file 5 MB allowance although the backend limit is 5 MB total.** The UI validates each file independently against `max_file_bytes`, while `_validated_files()` rejects once aggregate UTF-8 content exceeds `MAX_IMPORT_BYTES`. Valid-looking multi-file selections can therefore only fail after submission. **Fix:** use `max_request_bytes` to calculate and enforce aggregate size, and change the copy to state the total request limit. 4. **Moderate — `frontend/src/pages/HouseholdImportsPage.vue:183-215` — a failed replacement read restores access to stale file contents.** Existing `csvText`/slot contents are retained while `file.text()` runs. If reading rejects, `finally` re-enables preview without clearing the old contents or reporting an error, so the user can unknowingly preview the prior file after selecting a replacement. **Fix:** clear the target’s previous content before awaiting `file.text()`, catch read errors, keep the preview invalidated, and require a successful new selection. - Reviewed only the current five-file diff against base `9786857c814a29015987681e2416acb23275f9e5`; `git diff --check` passed. - No files created or modified. - No private/runtime data was read.