Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A1rCLQeKBgnBo3oTgHuTMe
5.0 KiB
YOUR STEP: 6 — Paper telemetry, stats, lock (plan §21 step 6)
Steps 1–5 have landed: the full v2 ranking pipeline (hygiene → embeddings → signals → triage →
admission → deep assessment → utility → cluster-capped shortlist → Claude editor → editorial),
candidate_runs telemetry, explain, features, ratings. Read git log -10, then
src/pipeline.rs, src/report.rs, src/main.rs, src/curate/telemetry.rs, src/epub/chapters.rs
and src/epub/templates/, src/types.rs (Colophon), src/db.rs, README, config.example.toml.
Scope (plan §5 lock, §15.1 Behind the paper + In-this-issue, §15.3 stats, §15.4 report/log block,
§16 lock coverage, §19 startup logging, README/config docs):
- Behind the paper (§15.1): a new short chapter after the World Briefing and before the colophon
(
src/epub/templates/behind.xhtml,render_behind_the_paper) with exactly the content shape in the plan: the considered/eligible/triaged/read-closely/shortlisted/selected line; theAdmitted via:line; theLearned signals:line (rated-with-embeddings count and knn percentage, feed affinity state);Near misses— the 10 highest-utility non-selected articles as<title> — <feed> · quality X · fit Y · <stage/reason>; theModels:line with triage/assessment, editor/summaries and embeddings models; cost and generation time. Both editions (X4 gets the same text, no links). The data comes from the run'sRunReport/StageCountsand the run'scandidate_runsrows (add aBehindThePaperstruct totypes.rsfilled by the pipeline; keep templates pure). Chapter ids stable (behind). - In this issue page: verify each entry shows the
whyline under the summary (step 2 was asked to do this; complete it if missing). The colophon keeps its fields and shows per-provider cost lines and models (verify; complete if missing). stats(§15.3):daily-epub stats [--days 14]printing issues, articles published, explicit ratings by label, ratings per issue, up/down ratio per admitting retriever (admitted_by[0]of rated picks, fromcandidate_runsjoined torating_eventsvia the latest explicit event), exploration yield (exploration picks selected / admitted, and how many were rated positively), mean issue size, cost per day per provider (fromruns.provider_costs_json), mean generation time. Plain text, one fact per line, no tables wider than 80 columns.- Run report and log block (§15.4): make sure
StageCountshas every field listed —eligible,embedded,triaged,admitted,admitted_by(map),assessed,shortlisted,clusters,exploration_admitted,exploration_selected,verdicts_in_prompt,rated_with_embeddings, per-provider usage — and that stage timings includeembed,signals,triage,admit,assess,rank,editor,summaries,brief. Emit the four-line info block from §15.4 once per run (curation:,admission:,preference:,providers:).print_reportinmain.rsprints the same lines. src/lock.rs(§5):flock(LOCK_EX | LOCK_NB)on<database_path>.lock, taken inmainforgenerate,profile rebuild,features backfill, andbackfill-social; a second invocation exits withgenerate is already running(name the command that holds it if cheap, else the generic message).serve,explain,stats,ratings,db migrate,features prunedo not take it. Uselibc/rustixonly if already in the dependency tree (checkCargo.lock); otherwisestd::fs::File+ thefs2-free approach vialibc::flockis acceptable to add as a tiny dep — say which in the report. Twenty lines, no table, no TTL.- Docs: README rewritten where it describes the pipeline, feedback links, costs, prerequisites
(Anthropic and Voyage keys, dashboard spend limits as the real backstop, the server-side fallback
note), the CLI (
ratings,explain,stats,features,--rescore,--skip-embeddings,--max-articlesas ceiling), anddata/profile.md.config.example.tomlcarries every key from plan §19 with comments. Startup logs resolved models and per-provider enabled state (verify). systemd/daily-epub-generate.service: no change needed unless an env var name changed; note the two new env vars in the README's systemd section.
Tests (§20 "Lock", "Pipeline" behind-the-paper, stats): two processes/one wins (spawn the binary or
use two File handles from separate threads with try_lock semantics — no sleeping longer than a
second), a killed holder frees the lock, serve does not take it (parse-level or by checking no lock
file is created); the behind-the-paper chapter renders with the counts and near misses on the mocked
pipeline run and is parseable XHTML in both editions (extend tests/m4_epub.rs); stats runs on a
temp DB with a couple of runs, issues and rating events and prints every line; the info block appears
in the log (capture with tracing test subscriber or assert on the formatted strings).