From eff960c54620bfba47d40bc3792ba805dea3dab3 Mon Sep 17 00:00:00 2001 From: Sam Scholten Date: Sun, 30 Aug 2026 20:34:38 +1000 Subject: rss: provenance + score calibration in items Item titles gain a rune-capped source-feed suffix so list views (which only ever show the channel title) display provenance inline. Item bodies open with feed, model score, and the batch-wide score median; the median is computed over every scored entry at poll time and stored on the run row as a nil-safe pointer, so old rows render without it. /api/status exposes the median too. --- core/runs.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'core/runs.go') diff --git a/core/runs.go b/core/runs.go index 38e6710..0dd4a7f 100644 --- a/core/runs.go +++ b/core/runs.go @@ -47,7 +47,11 @@ type KeptItem struct { // RunRow is one poll batch: what was seen, what was kept, when, and how // old the model was. EntriesSeen counts every fetched entry including any -// skipped before scoring (see RecFeedSkipped). +// skipped before scoring (see RecFeedSkipped). ScoreMedian is the median +// score across every scored entry this poll — the batch's background +// calibration, rendered next to kept items' scores in the RSS body. It's +// a pointer so old rows (and empty polls) read as "absent", never as +// a misleading 0.00. type RunRow struct { RanAt time.Time `json:"ran_at"` EntriesSeen int `json:"entries_seen"` @@ -55,6 +59,7 @@ type RunRow struct { Kept []KeptItem `json:"kept"` DurationMs int64 `json:"duration_ms"` ModelCreatedAt time.Time `json:"model_created_at"` + ScoreMedian *float64 `json:"score_median,omitempty"` } // ReadRuns parses all of path strictly. A missing file is not an error — -- cgit v1.2.3