fix(tradein): confidence_explanation no longer contradicts counters (#695) #738

Merged
bot-reviewer merged 1 commit from fix/695-explanation-counts into main 2026-05-30 15:10:31 +00:00
2 changed files with 31 additions and 3 deletions

View file

@ -1808,10 +1808,16 @@ async def estimate_quality(
range_high = new_range_high
confidence = anchor["confidence"]
tier_label = "того же дома" if anchor_tier == "A" else "ближайшего окружения (≤500 м)"
explanation = (explanation or "") + (
f" Оценка построена по {anchor['n']} аналогам из {tier_label}"
# #695: когда якорь построил headline, explanation описывает ИМЕННО якорные
# комплы (anchor['n'] из tier_label). Радиусный base-текст («Найдено N из M
# разных адресов») и analog_tier tier_note относятся к ДРУГОЙ выборке и
# противоречат якорю (n_analogs≠anchor['n']; «разных адресов» vs «того же
# дома») — поэтому ЗАМЕНЯЕМ, а не конкатенируем. repair_note сохраняем
# (ортогонален — поправка на ремонт). confidence уже = anchor["confidence"].
explanation = (
f"Оценка построена по {anchor['n']} аналогам из {tier_label}"
f"{' (топ-уровень в доме)' if anchor['used_uplift'] else ''}."
)
) + repair_note
# ── #651: IMV / Yandex BLEND (killer accuracy fix) — SECONDARY, Tier D only ──
# Радиусная медиана системно занижает премиум/видовые квартиры (нет class/

View file

@ -925,3 +925,25 @@ def test_estimate_precise_geo_tier_c_not_downgraded() -> None:
# default geo = '…ул. Хохрякова, 48' → есть номер дома → не coarse
)
assert _APPROX_FLAG not in (est.confidence_explanation or "")
# ── #695: explanation согласован при сработавшем якоре (без радиус-противоречия) ──
def test_explanation_anchor_no_radius_contradiction() -> None:
"""#695: якорь дома построил headline → explanation описывает якорные комплы
(anchor['n']=3 из того же дома), БЕЗ противоречащего радиусного «Найдено N из M
разных адресов» и без analog_tier-note про «нет аналогов в том же доме»."""
est = _run_estimate(anchor_comps=_SB_COMPS_PREMIUM, anchor_tier="A")
exp = est.confidence_explanation or ""
assert "Оценка построена по 3 аналогам из того же дома" in exp
assert "Найдено" not in exp # радиусный base-текст не конкатенируется
assert "разных адресов" not in exp # нет противоречия «того же дома» vs «разных»
def test_explanation_radius_path_keeps_base_text() -> None:
"""#695 контроль: без якоря (radius-путь) base-текст «Найдено N…» сохраняется."""
est = _run_estimate(anchor_comps=[], anchor_tier=None)
exp = est.confidence_explanation or ""
assert "Найдено" in exp
assert "Оценка построена по" not in exp # якорной фразы нет на чистом радиусе