МЕРА/оценщик: FSD_K задаёт видимый диапазон цены, но его не ловит ни гейт, ни поведенческий тест; две ветки якоря недостижимы #3590

Open
opened 2026-09-17 13:07:16 +00:00 by bot-backend · 0 comments
Collaborator

Выделено из пост-мерж глубокого ревью #2381 (PR #3556), 17.09.2026. Поведение на проде не менялось — это долг покрытия и мёртвый код, существовавшие и до PR.

Мутационный прогон на реплее 1600 сделок

Мутация Изменилось сделок Гейт регрессии
FSD_K 1.5 / 2.0 857 / 931 (range_low/range_high) зелёный
SB_GUARDRAIL_TOL 0.0 / 0.10 0 / 0 зелёный
SB_GATE_MAX_FSD 0.10 / 0.30 0 / 0 зелёный
ANCHOR_TIER_C_CORRIDOR_MULT 1.2 4 (цена, expected_sold, диапазоны) зелёный

Находки

  1. FSD_K — живой порог без поведенческой защиты. Задаёт видимый клиенту диапазон range_low_rub/range_high_rub (estimator.py:3808), а гейт test_backtest_regression_gate.py в метриках видит только диапазон expected_sold. FSD_K=1.5 меняет 857 сделок при зелёном гейте. До любой калибровки FSD_K нужен тест: либо метрика диапазона по объявлениям в baseline, либо тест с заглушкой _compute_same_building_anchor с известным fsd и проверкой half = FSD_K*fsd.
  2. SB_GUARDRAIL_TOL — ветка недостижима (estimator.py:3802-3804): цена якоря — средняя/медиана/p70 того же пула, минимум которого и есть comp_min_ppm2, поэтому est_ppm2 ≥ comp_min×(1−tol) при любом tol ≥ 0. Решить: удалить или оставить с комментарием «недостижимо».
  3. gate_thin — мёртвый код (estimator.py:3762): требует n < 3, а якорь возвращается только при n ≥ SB_MIN_COMPS = 4; к тому же fsd > 0.20 и так даёт confidence=="low". Тест tests/test_estimator_audit_fixes.py:89-114 тавтологичен — строит min_comps=1 и копирует формулу в тело теста (стр. 107).
  4. Гейт на агрегатах поглощает точечные изменения: мутация Tier C mult=1.2 меняет 4 сделки, гейт зелёный. Имеет смысл хранить в baseline дайджест выгрузки по сделкам (скрипт реплея ревьюера: dump_replay_2381.py, 22 поля).
  5. Мелочь: tradein-mvp/frontend/src/app/mera-public/content.ts:373 — в комментарии осталось старое имя estimate_imv_blend_weight.

Приёмка

Мутация FSD_K краснит тест; решение по веткам 2–3 принято и записано (удалены или помечены недостижимыми с проверкой инварианта SB_MIN_COMPS ≥ SB_GATE_MIN_N); тавтологичный тест заменён или удалён.

Refs #2381, PR #3556, #1970.

Выделено из пост-мерж глубокого ревью #2381 (PR #3556), 17.09.2026. Поведение на проде не менялось — это долг покрытия и мёртвый код, существовавшие и до PR. ## Мутационный прогон на реплее 1600 сделок | Мутация | Изменилось сделок | Гейт регрессии | |---|---|---| | FSD_K 1.5 / 2.0 | 857 / 931 (`range_low`/`range_high`) | зелёный | | SB_GUARDRAIL_TOL 0.0 / 0.10 | 0 / 0 | зелёный | | SB_GATE_MAX_FSD 0.10 / 0.30 | 0 / 0 | зелёный | | ANCHOR_TIER_C_CORRIDOR_MULT 1.2 | 4 (цена, expected_sold, диапазоны) | зелёный | ## Находки 1. **FSD_K — живой порог без поведенческой защиты.** Задаёт видимый клиенту диапазон `range_low_rub`/`range_high_rub` (`estimator.py:3808`), а гейт `test_backtest_regression_gate.py` в метриках видит только диапазон expected_sold. FSD_K=1.5 меняет 857 сделок при зелёном гейте. До любой калибровки FSD_K нужен тест: либо метрика диапазона по объявлениям в baseline, либо тест с заглушкой `_compute_same_building_anchor` с известным `fsd` и проверкой `half = FSD_K*fsd`. 2. **SB_GUARDRAIL_TOL — ветка недостижима** (`estimator.py:3802-3804`): цена якоря — средняя/медиана/p70 того же пула, минимум которого и есть `comp_min_ppm2`, поэтому `est_ppm2 ≥ comp_min×(1−tol)` при любом tol ≥ 0. Решить: удалить или оставить с комментарием «недостижимо». 3. **`gate_thin` — мёртвый код** (`estimator.py:3762`): требует n < 3, а якорь возвращается только при n ≥ SB_MIN_COMPS = 4; к тому же fsd > 0.20 и так даёт `confidence=="low"`. Тест `tests/test_estimator_audit_fixes.py:89-114` тавтологичен — строит `min_comps=1` и копирует формулу в тело теста (стр. 107). 4. **Гейт на агрегатах поглощает точечные изменения**: мутация Tier C mult=1.2 меняет 4 сделки, гейт зелёный. Имеет смысл хранить в baseline дайджест выгрузки по сделкам (скрипт реплея ревьюера: `dump_replay_2381.py`, 22 поля). 5. Мелочь: `tradein-mvp/frontend/src/app/mera-public/content.ts:373` — в комментарии осталось старое имя `estimate_imv_blend_weight`. ## Приёмка Мутация FSD_K краснит тест; решение по веткам 2–3 принято и записано (удалены или помечены недостижимыми с проверкой инварианта `SB_MIN_COMPS ≥ SB_GATE_MIN_N`); тавтологичный тест заменён или удалён. Refs #2381, PR #3556, #1970.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#3590
No description provided.