**NOT APPROVED — two P1 blockers remain.** 1. **P1 — Advertised duplicate action fails for legacy duplicates** - Synthetic legacy productive overlap was classified as `possible_legacy_duplicate`. - Review API advertised `supported_actions = ["expense", "duplicate", "ignore"]`. - Calling preview with `action="duplicate"` returned **HTTP 409**: `review action is not safe for this group`. - Cause: `get_household_review()` advertises `duplicate` for both logical and legacy duplicates (`household_import.py:1084–1085`), while `_supported_review_actions()` permits it only for `possible_logical_duplicate` (`household_import.py:1275–1276`). - This violates review capability parity and blocks the required safe duplicate resolution. 2. **P1 — A Migros money movement can be consumed by multiple receipts** - Synthetic probe: - Imported one CHF 10.00 Migros card movement. - Confirmed receipt A totaling CHF 10.00. - Previewed and confirmed distinct receipt B, same date and total. - Observed: - Second preview reported `status="linked"`. - Second confirm wrote another link and two more detail rows. - Database result: **2 linked receipts, 1 distinct money candidate, 4 line items**. - Cause: - `_existing_migros_money()` does not exclude movements already referenced by `household_migros_links` (`household_import.py:352–374`). - Matching selects the reused movement (`household_import.py:578–583`). - Schema enforces uniqueness only on `receipt_candidate_id`, not `money_candidate_id` or `money_transaction_id`. - This violates cross-batch one-to-one enrichment and creates ambiguous duplicate receipt lineage. **Non-blocking checks passed** - Generic `payment` text did not create a safe transfer. - Duplicate/reversal/pending-final ordering remained review-only and created no additional productive transaction. - Keyed HMAC identities changed with the key; public preview exposed only ordinal `file_1`/`row_1` tokens and no internal fingerprints. - Backend golden suite: **26 passed**. - Focused frontend suite: **7 passed**. - `git diff --check`: passed. - Candidate remained anchored at `7411df5ad88ab4b2bebd2ec5c7008aea18d4d7ca`; no repository files were modified.