Dumb OMO commit
This commit is contained in:
@@ -188,3 +188,24 @@ _Auto-scaffolded by /start-work. Append new entries below - never overwrite._
|
||||
DB column — a direct hand-written match keeps the DB layer decoupled
|
||||
from `news_core`'s serde attribute and makes the two directions
|
||||
symmetric and easy to audit).
|
||||
|
||||
## F2/F3 final-wave fixes — cold-start percentile rule
|
||||
|
||||
- **Cold-start rule for trailing-window percentile ranks**: the draft specifies
|
||||
a cold-start fallback only for the relevance *score* (BM25-only until 20
|
||||
feedback samples; `.omo/drafts/news-triage.md:45`), not for percentile ranks.
|
||||
When `PercentileTracker::percentile_rank` returns `StoreError::InsufficientData`
|
||||
because the trailing 7-day window is empty, the scheduler maps it to `0.0`
|
||||
with a one-line `tracing::info!` log.
|
||||
- **Rationale**: conservative gate behavior. With percentile ranks at 0.0, no
|
||||
story can meet the notify threshold (relevance @ p90) or digest band
|
||||
[75, 90) until the window has data, preventing bogus batch-local
|
||||
percentiles from driving decisions. The breaking-news bypass lane
|
||||
(`source_count >= 2` or importance @ p99) is unaffected: corroboration bypass
|
||||
is percentile-independent, and the importance percentile uses its own
|
||||
distribution.
|
||||
- **JSON boundary for blocklist veto**: `StoryRow.relevance` is `Option<f64>`,
|
||||
mapped with `relevance.is_finite().then_some(relevance)`. This keeps the
|
||||
`f64::NEG_INFINITY` sentinel inside the backend scorer while serializing
|
||||
honestly as JSON `null` at the API boundary. `importance` remains `f64`
|
||||
because it is finite by construction (multi-hot arithmetic, no veto path).
|
||||
|
||||
Reference in New Issue
Block a user