{{ summary_line }}
{% if no_embedding_count > 0 %}{{ no_embedding_count }} rated articles have no embedding and cannot act as neighbours — run the features-backfill job (features backfill --rated-only).
LOVED | title | feed | summary). Only the rank matters here — a verdict never ages out of this block, it is pushed out by newer ones. Tune curation.feedback.verdicts_in_prompt.value × 0.5^(age / {{ how.half_life_days }} days), where loved = {{ how.loved }}, good = {{ how.good }}, not for me = {{ how.not_for_me }}; ratings older than {{ how.lookback_days }} days are not loaded. A candidate's signal is the weighted mean cosine to its {{ how.neighbour_k }} nearest positive examples minus {{ how.negative_coefficient }} × the same over its nearest negative ones. The signal's preliminary weight ({{ how.knn_weight }}) is scaled by a gate that opens above {{ how.knn_floor }} embedded verdicts and is fully open at {{ how.knn_full }}. Tune curation.ranking.rating_half_life_days, knn_floor, knn_full, neighbour_k and weights.preliminary.knn.(up + 1) / (up + down + 2) becomes a candidate's signal (the mean over its rated direct feeds). Its weight ({{ how.feed_weight }}) is gated between {{ how.feed_floor }} and {{ how.feed_full }} attributable ratings. Tune curation.ranking.feed_floor, feed_full and weights.preliminary.feed.Clearing a verdict removes it from all four paths without deleting history; ratings are append-only.
{{ pagination.total }} events, newest first. History is append-only; a later explicit event for the same article marks the earlier one superseded. Use the clear verdict to retract.
| Event | Verdict | Value | Article | Issue | When | Source | By | Note |
|---|---|---|---|---|---|---|---|---|
| #{{ event.id }}{% if event.kind != "explicit" %} {{ event.kind }}{% endif %}{% if event.superseded %} superseded{% endif %} | {{ event.verdict }} | {{ event.value }} | {{ event.title }} | {% if !event.issue_date.is_empty() %}{{ event.issue_date }}{% endif %} | {{ event.when }} | {{ event.source }} | {{ event.username }} | {{ event.note }} |
| No rating events match. | ||||||||
One row per rated article (its latest explicit event), newest first. {% match last_run %}{% when Some with (run) %}"Used last run" counts the candidates of run #{{ run.id }} ({{ run.date }}, {{ run.status }}) that listed the article among their nearest rated neighbours, and how many of those were selected.{% when None %}No run has happened yet, so "Used last run" is empty.{% endmatch %}
| Verdict | Article | When · by | Note | Age → decay | Neighbour weight | Feed credit | In prompt | In rebuild | Used last run |
|---|---|---|---|---|---|---|---|---|---|
| {{ row.verdict }}{% let widget = row.widget %}{% include "_rating_widget.html" %} | {{ row.title }} {{ row.feed_title }}{% if !row.issue_date.is_empty() %} · {{ row.issue_date }}{% endif %} |
{{ row.when }} {{ row.source }} · {{ row.username }} |
{{ row.note }} | {{ row.age_days }} d → {{ row.decay }} | {% if row.has_embedding && !row.neighbour_weight.is_empty() %}{{ row.neighbour_weight }}{% if row.beyond_lookback %} (beyond lookback){% endif %}{% else if row.badge == "cleared" %}—{% else %}no embedding{% endif %} | {% for credit in row.feed_credits %}{{ credit.title }} {{ credit.credit }}{% if !loop.last %} {% endif %}{% endfor %} |
{% if row.in_prompt %}✓{% endif %} | {% if row.in_rebuild %}✓{% endif %} | {% if row.used_total > 0 %}{{ row.used_total }} ({{ row.used_selected }} selected){% endif %} |
| No current verdicts match. | |||||||||