fix(tradein/estimator): thin-market гейт IMV перестаёт быть витринным — рынок из 1 объявления больше не двигает headline и range_high #3336

Merged
bot-backend merged 3 commits from fix/3323-imv-thin-market-gate into main 2026-09-05 17:49:30 +00:00
Collaborator

Refs #3323 п.1 [medium] (сборник аудита; НЕ auto-close — в сборнике другие пункты). avito_imv_thin_market_threshold=10 рождал только warning; IMV с market_count=1 двигал headline (blend w=0.5) и растягивал range_high.

Где встал гейт

Обе ветки якоря (house_imv_evaluations и avito_imv_evaluations, включая repair-basis ×k #2677) сходятся в один вызов _apply_imv_blend — гейт там, сразу после null-guard, а не по веткам. При market_count < threshold: ни blend медианы, ни расширение range_high; IMV остаётся display-only в карточке. Поведение при market_count >= threshold не изменено (регресс-контроль тестом).

Warning стал честным: «IMV ОТБРОШЕН из денежного пути…», а не просто «тонкий рынок».

Бонус-дыра, закрытая по пути

market_count читался как if imv_anchor.get(...)0 превращался в None, и гейт с флагом thin_market молчали на самом тонком рынке. Теперь is not None в обеих точках сборки.

Сознательно НЕ тронуто

  • Guard-1b: imv_anchor_present продолжает гасить quarter-index (#764) и при тонком рынке — открыть его было бы вторым изменением денег вне тикета; вынесу вопрос владельцу отдельно, если нужно;
  • сегментный множитель #2293 (за флагом);
  • sources_used/display-карточка.

Тесты

test_estimator_imv_blend.py (+3 кейса: гейт по значению, регресс-контроль, граница threshold−1/threshold): 36 passed + смежные 49 passed. Фальсификация — снято ТОЛЬКО тело гейта (полный откат дал бы TypeError = «возможности нет», не «значение неверно»):

assert (75000000, 110000000) == (50000000, 60000000)  — вклад IMV вернулся
2 failed, 1 passed — регресс-контроль остался зелёным, как и должен

Прод-приёмка после деплоя

  • SELECT доли оценок с market_count < 10 среди имеющих IMV-якорь — сколько оценок реально перестанут блендиться (замер «сколько прежних изменилось»);
  • контрольная оценка на адресе с тонким IMV: headline без вклада IMV, карточка avito_imv на месте с флагом thin_market.
Refs #3323 п.1 [medium] (сборник аудита; НЕ auto-close — в сборнике другие пункты). `avito_imv_thin_market_threshold=10` рождал только warning; IMV с `market_count=1` двигал headline (blend w=0.5) и растягивал `range_high`. ## Где встал гейт Обе ветки якоря (`house_imv_evaluations` и `avito_imv_evaluations`, включая repair-basis ×k #2677) сходятся в один вызов `_apply_imv_blend` — гейт там, сразу после null-guard, а не по веткам. При `market_count < threshold`: ни blend медианы, ни расширение range_high; IMV остаётся display-only в карточке. Поведение при `market_count >= threshold` не изменено (регресс-контроль тестом). Warning стал честным: «IMV ОТБРОШЕН из денежного пути…», а не просто «тонкий рынок». ## Бонус-дыра, закрытая по пути `market_count` читался как `if imv_anchor.get(...)` — **0 превращался в None**, и гейт с флагом `thin_market` молчали на самом тонком рынке. Теперь `is not None` в обеих точках сборки. ## Сознательно НЕ тронуто - Guard-1b: `imv_anchor_present` продолжает гасить quarter-index (#764) и при тонком рынке — открыть его было бы вторым изменением денег вне тикета; вынесу вопрос владельцу отдельно, если нужно; - сегментный множитель #2293 (за флагом); - `sources_used`/display-карточка. ## Тесты `test_estimator_imv_blend.py` (+3 кейса: гейт по значению, регресс-контроль, граница threshold−1/threshold): `36 passed` + смежные `49 passed`. Фальсификация — снято ТОЛЬКО тело гейта (полный откат дал бы TypeError = «возможности нет», не «значение неверно»): ``` assert (75000000, 110000000) == (50000000, 60000000) — вклад IMV вернулся 2 failed, 1 passed — регресс-контроль остался зелёным, как и должен ``` ## Прод-приёмка после деплоя - SELECT доли оценок с `market_count < 10` среди имеющих IMV-якорь — сколько оценок реально перестанут блендиться (замер «сколько прежних изменилось»); - контрольная оценка на адресе с тонким IMV: headline без вклада IMV, карточка avito_imv на месте с флагом thin_market.
bot-backend added 1 commit 2026-09-02 12:37:19 +00:00
fix(tradein): thin-market IMV не двигает деньги (#3323)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 13s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 5m6s
148da3e5a7
avito_imv_thin_market_threshold рождал только warning: IMV с market_count=1
всё равно уходил в blend (w=0.5 при A > median*1.15) и растягивал range_high.
Гейт поставлен в _apply_imv_blend — единственной точке, через которую IMV
влияет на деньги (обе ветки якоря, imv_anchor и imv_eval, сходятся там):
market_count < threshold → no-op, якорь остаётся display-only в карточке.
market_count >= threshold и market_count=None (порог не передан) — поведение
прежнее. market_count=0 больше не читается как «неизвестно».
Warning теперь говорит, что IMV ОТБРОШЕН, а не просто «тонкий рынок».
Light1YT added 1 commit 2026-09-02 12:44:41 +00:00
fix(tradein): завершить thin-market гейт IMV — Guard-1b и GET-путь (#3323)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 10s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / changes (pull_request) Successful in 13s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 5m23s
4f4345e27c
MEDIUM-1: imv_anchor_present ставился по anchor_total МИМО гейта — на тонком
рынке якорь отброшен, а Guard-1b (#764) продолжал глушить квартальную поправку
«потому что якорь есть»: headline не получал ни одной поправки, отброшенный
якорь двигал деньги вычитанием. Теперь present = not thin_market.

MEDIUM-2: trade_in.py (GET ?id= — расшаренная ссылка/PDF) — третья точка
сборки карточки: market_count=0 читался как «неизвестно», thin_market не
передавался вовсе → одна оценка показывала thin_market=True в POST и False
при переоткрытии.
Light1YT added 1 commit 2026-09-05 17:41:10 +00:00
Merge remote-tracking branch 'origin/main' into HEAD
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 12s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 5m1s
aaf8119408
# Conflicts:
#	tradein-mvp/backend/app/services/estimator.py
bot-backend merged commit 87781ad53c into main 2026-09-05 17:49:30 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
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#3336
No description provided.