Curation v2 step 1: three-way feedback, rating events, reader profile
- Migration 0002: rating_events, article_embeddings, interest_embeddings, article_assessments, candidate_runs, runs.config_json/provider_costs_json, issue_articles.why; copies ratings into rating_events and drops ratings and feed_priors (scores stays until step 4). - Vote is Loved | Good | NotForMe; legacy `up` links still verify as Loved. - Footer offers Loved it / Good / Not for me; the confirmation page offers the other two so a mis-tap can be corrected. handle_rating appends one event. - db::current_ratings implements the latest-explicit-event rule with summaries and facets; `ratings list|set|clear` CLI appends source='cli' events. - data/profile.md replaces the hard-coded reader prose; the system prompt is rebuilt every run in the §8.4 order with a recent-verdicts block. - Weekly rebuild reads summaries, facets and notes; feed priors removed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A1rCLQeKBgnBo3oTgHuTMe
This commit is contained in:
@@ -283,7 +283,7 @@ async fn assemble_build_publish(
|
||||
)
|
||||
.expect("render chapters");
|
||||
let first = issue.lineup.picks[0].article.id;
|
||||
let expected = auth::rating_url(&cfg.server.public_url, SECRET, date(), first, Vote::Up);
|
||||
let expected = auth::rating_url(&cfg.server.public_url, SECRET, date(), first, Vote::Loved);
|
||||
let chapter = chapters
|
||||
.iter()
|
||||
.find(|c| c.id == format!("art-{}", issue.lineup.picks[0].article.best_entry_id))
|
||||
@@ -298,8 +298,8 @@ async fn assemble_build_publish(
|
||||
SECRET,
|
||||
date(),
|
||||
first,
|
||||
Vote::Up,
|
||||
&auth::rating_token(SECRET, date(), first, Vote::Up)
|
||||
Vote::Loved,
|
||||
&auth::rating_token(SECRET, date(), first, Vote::Loved)
|
||||
),
|
||||
"the server must accept the token the EPUB minted"
|
||||
);
|
||||
|
||||
+12
-1
@@ -190,7 +190,18 @@ fn scour_opml_still_yields_the_interest_list() {
|
||||
|
||||
// The assembled profile is what actually reaches DeepSeek as the system
|
||||
// prompt; it must mention the stated preferences and the interests (§3.6).
|
||||
let document = profile::build(&interests, profile::NO_LEARNED_ADJUSTMENTS);
|
||||
let profile_file = profile::load_profile(Path::new(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
"/data/profile.md"
|
||||
)))
|
||||
.expect("profile file");
|
||||
let document = profile::build(
|
||||
&profile_file.body,
|
||||
&interests,
|
||||
profile::NO_LEARNED_ADJUSTMENTS,
|
||||
&[],
|
||||
60,
|
||||
);
|
||||
assert!(document.contains("Rust"));
|
||||
assert!(document.len() > 1000, "the profile is suspiciously short");
|
||||
}
|
||||
|
||||
+14
-10
@@ -270,16 +270,20 @@ fn rating_links_carry_the_spec_token() {
|
||||
.expect("article chapter");
|
||||
|
||||
let date = issue.meta.date;
|
||||
let up = build::rating_token("integration-secret", date, 1, Vote::Up);
|
||||
let down = build::rating_token("integration-secret", date, 1, Vote::Down);
|
||||
assert_eq!(up.len(), 16);
|
||||
assert_ne!(up, down);
|
||||
assert!(chapter.xhtml.contains(&format!(
|
||||
"https://daily.hallada.net/r/2026-08-15/1/up?t={up}"
|
||||
)));
|
||||
assert!(chapter.xhtml.contains(&format!(
|
||||
"https://daily.hallada.net/r/2026-08-15/1/down?t={down}"
|
||||
)));
|
||||
let loved = build::rating_token("integration-secret", date, 1, Vote::Loved);
|
||||
let good = build::rating_token("integration-secret", date, 1, Vote::Good);
|
||||
let down = build::rating_token("integration-secret", date, 1, Vote::NotForMe);
|
||||
assert_eq!(loved.len(), 16);
|
||||
assert_ne!(loved, good);
|
||||
assert_ne!(good, down);
|
||||
for (segment, token) in [("loved", loved), ("good", good), ("down", down)] {
|
||||
assert!(chapter.xhtml.contains(&format!(
|
||||
"https://daily.hallada.net/r/2026-08-15/1/{segment}?t={token}"
|
||||
)));
|
||||
}
|
||||
assert!(chapter.xhtml.contains("[ Loved it ]"));
|
||||
assert!(chapter.xhtml.contains("[ Good ]"));
|
||||
assert!(chapter.xhtml.contains("[ Not for me ]"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user