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).
Tier A (same building) dropped cian listings tagged listing_segment='novostroyki'
even in delivered buildings where that tag marks owner resales/переуступки
(sale_type=free). Gated relaxation of the #1186 guard, Tier A ONLY: include
novostroyki rows iff the same house has secondary (vtorichka/NULL) listings AND
secondary_count >= primary_count — secondary-dominant signal of a delivered house.
Prevents a lone vtorichka + clustered developer-priced novostroyki from anchoring
on застройщик prices after MAD-clip drops the rare secondary (~27% overvaluation).
Pure-primary / primary-dominated houses keep the #1186 guard. Behind
estimate_sb_tier_a_allow_primary_if_secondary_present (default True).
Dedup duplicate active rows by (source, source_id) primary key (codebase canon,
namespaced id/url tags, source_url fallback) — collapses rows whose source_url
differs only by trailing slash / query-param (e.g. cian source_id=330047129 ×2).
Tier C / radius / asking_to_sold_ratio paths untouched. 84 unit tests pass.
- Удалён параметр listing_segment: str | None = None из сигнатуры _fetch_anchor_comps
(guard хардкожен в SQL-блоках Tier A/C, параметр не использовался)
- Убраны seg_counts / target_segment в caller-блоке SAME-BUILDING ANCHOR (~L2174)
- Docstring Tier C обновлён: «вторичка-канон guard (#1186): NULL = legacy вторичка»
- test_segment_guard_1186.py: добавлены 4 негативных assert'а:
· no bare = 'vtorichka' без IS NULL OR
· no deprecated <> / != 'novostroyki' form
· _fetch_anchor_comps не содержит listing_segment в сигнатуре
· Tier C не использует CAST(:segment AS text) (параметрическую форму)