Curation v2 step 5: deep assessment, utility, diversified shortlist

assess.rs replaces score.rs (DEEP_INSTRUCTIONS, representative sample
with [BEGINNING]/[MIDDLE]/[END], facets, cached deep rows with --rescore
bypass), rank.rs adds the utility blend over present signals with gate
ramps and the leader-clustered shortlist (cap 2 → 3 → uncapped, protected
top-N, exploration reserve), editor.rs replaces select.rs with the §13
rendering and utility-ordered fallbacks. ScoredArticle is gone; Candidate
is the only flow type. deep_batch_size replaces score_batch_size.

Started by Codex (cut off by its usage limit mid-verification) and
finished by a Claude agent from docs/plans/curation-v2-briefs/step5.md;
reviewed against plan §12–§13.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A1rCLQeKBgnBo3oTgHuTMe
This commit is contained in:
thalladaandClaude Fable 5.1 committed 2026-09-02 16:04:43 +00:00
1 parent 10f4afd091
commit 05a74a0dcf
22 files changed
+2710 -1298

No files matched your search

+13 -6
View File
@@ -195,22 +195,28 @@ pub fn build_brief_prompt(lineup: &Lineup, summaries: &BTreeMap<ArticleId, Strin
for section in &lineup.section_order {
let _ = writeln!(prompt, "\n## {section}");
for pick in lineup.section_picks(section) {
let score = pick
let quality = pick
.llm
.as_ref()
.map(|score| format!("{:.1}", score.score))
.unwrap_or_else(|| "unscored".into());
.map(|assessment| format!("{:.1}", assessment.quality))
.unwrap_or_else(|| "unassessed".into());
let fit = pick
.llm
.as_ref()
.map(|assessment| format!("{:.1}", assessment.fit))
.unwrap_or_else(|| "unassessed".into());
let summary = summaries
.get(&pick.article.id)
.cloned()
.unwrap_or_else(|| excerpt_summary(pick));
let _ = writeln!(
prompt,
"- {}\n feed: {}\n why: {}\n score: {}\n summary: {}",
"- {}\n feed: {}\n why: {}\n quality: {}\n fit: {}\n summary: {}",
pick.article.title.trim(),
pick.article.feed_title.trim(),
pick.why.as_deref().unwrap_or("not supplied"),
score,
quality,
fit,
summary
);
}
@@ -462,7 +468,8 @@ mod tests {
assert!(prompt.contains("- Migrating 40TB off Postgres"));
assert!(prompt.contains("why: the Migrating 40TB off Postgres piece you'd argue with"));
assert!(prompt.contains("summary: A migration story with numbers."));
assert!(prompt.contains("score: unscored"));
assert!(prompt.contains("quality: unassessed"));
assert!(prompt.contains("fit: unassessed"));
assert!(prompt.contains("2026-08-15"));
assert!(
!prompt.contains("section_intros"),