Collapse 14 Class-A boolean feature gates (all default True, never overridden in
prod) into their unconditional ON behavior: inline the ON-path, drop the guard +
any OFF branch, delete the config field, and remove/adjust OFF-path tests.
Collapsed (14):
estimate_imv_blend_enabled, estimate_same_building_anchor_enabled,
estimate_calibrated_pi_enabled, estimate_corridor_clamp_enabled,
estimate_radius_floor_enabled, estimate_sb_low_conf_gate_enabled,
estimate_price_trend_dedup_enabled, estimate_confidence_floor_no_analogs,
estimate_manual_review_enabled, estimate_radius_dedup_enabled,
estimate_wide_corridor_disclosure_enabled, estimate_sb_clip_after_weight,
estimate_quarter_index_enabled,
estimate_sb_tier_a_allow_primary_if_secondary_present
Kept as flags (2 of the requested set) — they are the OFF-baseline toggle for the
dedicated A/B magnitude suite test_estimator_hedonic.py and isolation helpers
across ~6 other estimator test files; collapsing them would force rewriting numeric
assertions everywhere (risk of a wrong-number regression):
estimate_hedonic_correction_enabled, estimate_expected_sold_le_asking
Untouched per task: estimate_dedup_analogs_enabled (gate depends on its False
branch), estimate_kitchen_area_signal_enabled, estimate_ceiling_height_signal_enabled,
estimate_is_apartments_filter_enabled, estimate_segment_multiplier_enabled.
Also removed the now-unconditional `enabled` param from _apply_corridor_clamp and
collapsed the same-building-anchor pre-fetch gate in scripts/backtest_estimator.py.
Regression gate (test_backtest_regression_gate.py) stays byte-green: all collapsed
flags defaulted True, so unconditional == prior prod behavior; the frozen 277-DKP
replay is byte-identical to the committed baseline. Full run: 458 passed (gate +
estimator suite) + 93 passed (same_building / 781 / tier_a / segment_guard).
estimate_dedup_analogs_enabled: False → True. Бэктест #1966 OFF vs ON
accuracy-идентичен (MAPE 13.89%, coverage 83.33%, bias −3.83%, median
width/cv без изменений) — включение меняет только user-visible n_analogs:
перестаёт быть раздутым кросс-постингом одного физлота на avito+cian+domklik
×3. Откат — ENV ESTIMATE_DEDUP_ANALOGS_ENABLED=false.
Тесты разведены default vs explicit (не ослаблены):
- test_estimator_dedup_cross_source_2087: добавлен test_dedup_default_is_on
(без monkeypatch — дедуп активен по умолчанию); test_dedup_flag_off_is_noop
оставляет ЯВНЫЙ OFF-override.
- test_backtest_regression_gate: пиним флаг OFF — гейт это байт-идентичный
replay frozen OFF-capture (recorded call-sequence фикстуры без дедупа); с
ON _dedup_cross_source триммит listings до quarter_indexes_lookup и
control-flow расходится с записью.
- test_estimator_n_analogs_priced (autouse) + test_radius_path_n_analogs_unchanged:
пиним OFF — инвариант «n_analogs = число priced-аналогов»/radius-passthrough
ортогонален дедупу, а синтетические аналоги делят адрес/этаж/площадь и
схлопнулись бы как кросс-посты.
Refs #2087, #2173
CLIENT-VISIBLE pricing (killer-factor, demo 2026-06-01). The same-building
anchor replaced headline median/range/confidence with an over-confident
premium on as few as 2 same-building asking comps. Human-chosen (Anton)
3-part safe-guard, all implemented:
1. min_comps 2 -> 4: anchor fires only with >=4 same-building comps.
2. confidence cap: at <5 anchor comps, confidence cannot be 'high' -> medium.
3. MAD-clip: drop price_per_m2 outliers among anchor comps before aggregation
(k=estimate_sb_mad_k=3.5); if <min_comps survive, anchor does NOT fire
(fallback to radius-median). Guards against price typos inflating anchor.
Anchor still REPLACES the headline (uplift-no-replace variant NOT chosen).
quarter-index/radius-tier/asking-sold untouched. 8 new unit tests; 61 anchor
tests pass, ruff clean.
MERGE-GATE (client-visible, like #764/#858): do NOT merge without a green
backtest #763 (held-out MAPE <= 18.7% + canonical A/B Малышева 125 /
Заводская 44а). Backtest needs live DB — pre-merge human/qa step.
Refs #755, #694