[Fable 5][P3] best_layouts: supply-бакеты ('4+', euro-1/2) не стыкуются с velocity-бакетами objective ('4', '5+', '2') — supply=0/sold_pct искажены #1229

Closed
opened 2026-06-13 04:49:46 +00:00 by bot-backend · 0 comments
Collaborator

Из армейского ревью Claude Fable 5 (2026-06-11)

Confirmed by 2/2 адверсариальных верификатора, severity P3 (correctness), confidence 0.7.

Файл

backend/app/services/site_finder/best_layouts.py:163

Evidence (цитата кода)

            WHEN f.rooms = 2 AND f.total_area < 35 THEN 'euro-1'
            WHEN f.rooms = 2 AND f.total_area < 50 THEN 'euro-2'
            WHEN f.rooms IN (1, 2, 3) THEN f.rooms::text
            WHEN f.rooms >= 4 THEN '4+'
            ELSE '1'

Why bug

Velocity-сторона отдаёт room_bucket из objective-вокабуляра ('студия'→'studio', далее passthrough '1'..'4','5+' — схема 68), supply-сторона — 'studio','euro-1','euro-2','1','2','3','4+'. В supply_map.get((room_bucket, ab), 0) ключи ('4',ab)/('5+',ab) отсутствуют → для 4- и 5+-комнатных layout'ов всегда supply_units_in_radius=0, sold_pct=None при реальном стоке; euro-строки supply (2-комн <50м²) не матчатся с bucket '2' → знаменатель sold_pct двушек занижен, sold_pct/is_oversold завышены.

Suggested fix

Привести supply-CASE к velocity-вокабуляру ('4'/'5+' вместо '4+'; euro-биннинг только если его производит и velocity-сторона) либо нормализовать оба через общий helper перед матчем.

Verify notes

  • [real/P3] Схема 68 фиксирует словарь Объектива: студия/1/2/3/4/5+; ETL пишет raw, _INLINE_VELOCITY_SQL — passthrough кроме 'студия'. Supply CASE даёт studio/euro-1/euro-2/1/2/3/4+. Lookup supply_map.get(('4',ab)) и (('5+',ab)) всегда miss → supply_units=0, sold_pct=None, is_oversold=False при реальном стоке; 2-комн <50м² уходят в euro-* → знаменатель sold_pct бакета '2' занижен, sold_pct/is_oversold завышены. Ranking/mix/цены не затронуты (считаются от deals) → P3.
  • [real/P3] Половина опровергнута прод-данными: objective_corpus_room_month содержит ровно {студия,1,2,3,4+} (psql: '4+'=3745 строк; '4'/'5+' нет) — velocity '4+' стыкуется с supply '4+', supply=0 для 4+ НЕ происходит. Euro-часть реальна: velocity не отдаёт 'euro-1/2', эти supply-ключи недостижимы; двушки <50м² исключены из знаменателя ('2',ab), числитель — все 2-комн сделки → sold_pct/is_oversold двушек завышены. P3: метрика информационная, clamped.

Provenance

  • Finders: site-finder-A
  • Confidence: 0.7
  • Originally batched at: main@d796027
## Из армейского ревью Claude Fable 5 (2026-06-11) Confirmed by 2/2 адверсариальных верификатора, severity **P3** (correctness), confidence 0.7. ## Файл [`backend/app/services/site_finder/best_layouts.py:163`](backend/app/services/site_finder/best_layouts.py:163) ## Evidence (цитата кода) ``` WHEN f.rooms = 2 AND f.total_area < 35 THEN 'euro-1' WHEN f.rooms = 2 AND f.total_area < 50 THEN 'euro-2' WHEN f.rooms IN (1, 2, 3) THEN f.rooms::text WHEN f.rooms >= 4 THEN '4+' ELSE '1' ``` ## Why bug Velocity-сторона отдаёт room_bucket из objective-вокабуляра ('студия'→'studio', далее passthrough '1'..'4','5+' — схема 68), supply-сторона — 'studio','euro-1','euro-2','1','2','3','4+'. В supply_map.get((room_bucket, ab), 0) ключи ('4',ab)/('5+',ab) отсутствуют → для 4- и 5+-комнатных layout'ов всегда supply_units_in_radius=0, sold_pct=None при реальном стоке; euro-строки supply (2-комн <50м²) не матчатся с bucket '2' → знаменатель sold_pct двушек занижен, sold_pct/is_oversold завышены. ## Suggested fix Привести supply-CASE к velocity-вокабуляру ('4'/'5+' вместо '4+'; euro-биннинг только если его производит и velocity-сторона) либо нормализовать оба через общий helper перед матчем. ## Verify notes - [real/P3] Схема 68 фиксирует словарь Объектива: студия/1/2/3/4/5+; ETL пишет raw, _INLINE_VELOCITY_SQL — passthrough кроме 'студия'. Supply CASE даёт studio/euro-1/euro-2/1/2/3/4+. Lookup supply_map.get(('4',ab)) и (('5+',ab)) всегда miss → supply_units=0, sold_pct=None, is_oversold=False при реальном стоке; 2-комн <50м² уходят в euro-* → знаменатель sold_pct бакета '2' занижен, sold_pct/is_oversold завышены. Ranking/mix/цены не затронуты (считаются от deals) → P3. - [real/P3] Половина опровергнута прод-данными: objective_corpus_room_month содержит ровно {студия,1,2,3,4+} (psql: '4+'=3745 строк; '4'/'5+' нет) — velocity '4+' стыкуется с supply '4+', supply=0 для 4+ НЕ происходит. Euro-часть реальна: velocity не отдаёт 'euro-1/2', эти supply-ключи недостижимы; двушки <50м² исключены из знаменателя ('2',ab), числитель — все 2-комн сделки → sold_pct/is_oversold двушек завышены. P3: метрика информационная, clamped. ## Provenance - Finders: `site-finder-A` - Confidence: 0.7 - Originally batched at: main@d796027
bot-backend added the
Fable 5 ревью
label 2026-06-13 04:49:46 +00:00
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#1229
No description provided.