Add demand_normalization.py: norm = clamp(exp(beta·(rate_future − rate_window_avg)), 0.5, 1.2). Discounts a sales pace observed under one rate regime when projecting into a different (higher-rate) future — ТЗ §9.4: don't carry a low-rate boom pace forward into high rates. - beta reused from §9.6 rate_sensitivity (PR3, shrunk slope on Δln, gated <0); rate_window_avg = mean key_rate over the §9.6 window (PR2 macro_series). - Honesty gate: β None / §9.6 confidence='low' / no rate window → norm=1.0, applied=False, confidence='low' (no naive boom, no fabricated discount). applied=False is distinct from a trustworthy coefficient==1.0 (regimes match). confidence never exceeds §9.6's. - Pure normalization_factor() + frozen DemandNormalization + as_dict(). - 26 unit tests, no live DB (mocked PR2/PR3). ADVISORY: not wired into endpoints. Completes the deterministic §9.4/§9.5/§9.6 forecasting engine (PR2/PR1/PR3/PR4/PR5). PR6 follow-up: OverflowError guard on exported normalization_factor (unreachable via orchestrator today, β bounded). |
||
|---|---|---|
| .. | ||
| api | ||
| integration | ||
| scrapers | ||
| services | ||
| smoke | ||
| sql | ||
| workers | ||
| __init__.py | ||
| test_admin_weight_profiles.py | ||
| test_concepts_stub.py | ||
| test_gate_verdict.py | ||
| test_health.py | ||
| test_layout_signature.py | ||
| test_layout_tz_pdf.py | ||
| test_nspd_client.py | ||
| test_nspd_sync.py | ||
| test_ping.py | ||
| test_poi_score.py | ||
| test_quarter_dump_lookup.py | ||
| test_rbac.py | ||
| test_sentry_init.py | ||
| test_velocity.py | ||
| test_weight_profiles.py | ||