From 9deca522b4d2e83faa18b5794f3541b9b06ff14b Mon Sep 17 00:00:00 2001 From: jay Date: Mon, 8 Jun 2026 15:47:51 -0400 Subject: [PATCH] Sources: accepted-duplicate % (curation-quality signal) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per Codex's optional note: alongside the ingest-wide duplicate_rate, expose accepted_dup_rate — of what a source got ACCEPTED, how much was a duplicate of already-served content (accepted_total − served). Nearly free (derived from existing counts); surfaced as a tooltip on the Dup column so the table stays uncluttered. Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/src/routes/admin/+page.svelte | 2 +- goodnews/queries.py | 6 +++++- tests/test_dashboard.py | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/frontend/src/routes/admin/+page.svelte b/frontend/src/routes/admin/+page.svelte index 7bd1e14..87f7b79 100644 --- a/frontend/src/routes/admin/+page.svelte +++ b/frontend/src/routes/admin/+page.svelte @@ -344,7 +344,7 @@ {s.served} {s.acceptance_rate != null ? s.acceptance_rate + '%' : '—'} - {s.duplicate_rate != null ? s.duplicate_rate + '%' : '—'} + {s.duplicate_rate != null ? s.duplicate_rate + '%' : '—'} {s.last_success_at ? fwhen(s.last_success_at) : '—'} {s.active ? fwhen(s.next_due_at) : '—'} {s.failures || ''} diff --git a/goodnews/queries.py b/goodnews/queries.py index 982d82a..5959bce 100644 --- a/goodnews/queries.py +++ b/goodnews/queries.py @@ -320,8 +320,12 @@ def source_health(conn: sqlite3.Connection) -> list[dict]: for r in rows: d = dict(r) total = d["total_articles"] or 0 - d["acceptance_rate"] = round(100 * d["accepted_total"] / total) if total else None + accepted = d["accepted_total"] or 0 + d["acceptance_rate"] = round(100 * accepted / total) if total else None d["duplicate_rate"] = round(100 * d["duplicates"] / total) if total else None + # Curation quality: of what this source got ACCEPTED, how much was a + # duplicate of content already served (accepted_total − served = accepted dupes). + d["accepted_dup_rate"] = round(100 * (accepted - d["served"]) / accepted) if accepted else None out.append(d) return out diff --git a/tests/test_dashboard.py b/tests/test_dashboard.py index c729ca0..1fb3ee7 100644 --- a/tests/test_dashboard.py +++ b/tests/test_dashboard.py @@ -47,6 +47,8 @@ def test_source_health_orders_failing_first_and_computes_next_due(tmp_path): assert flaky["next_due_at"] is not None good = next(s for s in sh if s["name"] == "Good") assert good["served"] == 1 and good["next_due_at"] is None # never attempted → due now + # source 1: 2 accepted (art 1, art 3) but art 3 is a duplicate → 50% of accepted were dupes + assert good["accepted_dup_rate"] == 50 def test_attention_flags_resting_flagged_and_brief():