Review-bot findings:
- CRITICAL: expected_sold_* were derived from PRE-blend median/range/ppm2, so
after the #651 blend raised median_price the UI showed asking (blended) vs
expected-sold (un-blended) → nonsensical discount. Moved the asking→sold
derivation to AFTER the blend block; INSERT + returned estimate now use the
post-blend values.
- IMV anchor had no rooms/area band → a studio-only IMV row could anchor a
3-room target and inflate via the x1.15 trigger. Added NULL-tolerant guard
(abs(Δrooms)<=1 AND area_m2 BETWEEN area*0.7..1.3) in _fetch_house_imv_anchor.
- Tests: expected_sold↔blended-median consistency, band rejection, weight clamp
[0,1], corridor count branch. ruff clean; 26 + 145 estimator regression pass.