fix(research): the manifest belongs to the mission, and a brittle phrase must not mean silence
Two defects from the first on-topic run.
**1. The manifest could never be updated twice in a day.** It was written into
the VAULT at a per-DATE path, but it is per-RUN data. A second mission the same
day rewrites a file that already exists, and `auto_merge` correctly refused the
whole branch:
diff is not additive (1 non-add change(s), first:
M ContinuousResearch/2026-08-18/harvest.jsonl); left for a human
So `main` kept the FIRST run's manifest, the next mission cloned it, and the
agents analysed yesterday's papers while every log line reported a successful
harvest. The merge policy was right; the placement was wrong. The manifest now
goes into the mission's own checkout after `ensure_checkout`, which keeps the
vault additive and gives each mission exactly its own papers. The agents commit
it alongside their analysis through the normal delivery path.
**2. A quoted phrase that matches nothing looked like a quiet day.** Phrase
search is precise and brittle: "hybrid retrieval BM25 dense" is a reasonable
topic and appears verbatim in no paper on arXiv — measured, 0 hits — while the
same four terms unquoted return exactly the hybrid-retrieval evaluations the
topic asked for. Harvesting zero because of adjacency is indistinguishable from
a genuinely quiet field, which is the distinction `Harvest::healthy()` vs
`added_anything()` exists to preserve. `search` now retries unquoted when the
phrase finds nothing, and says so in the log.
Proven in one run, all three behaviours at once:
"approximate nearest neighbor search" -> 5 candidates, 5 already held, 0 shelved
"hybrid retrieval BM25 dense" -> no exact phrase match, retrying broad
-> 5 candidates, 0 already held, 5 shelved
"LLM as a judge evaluation" -> 5 candidates, 5 already held, 0 shelved
wrote 5 paper(s) to .../ContinuousResearch/2026-08-18/harvest.jsonl
The seen-set suppressing 10 of 15 is the whole point of a recurring mission, and
the 5 that landed are on topic for the first time: RAG architecture evaluation,
agent-controlled search over chat logs, compute-aware retrieval and reranking,
hybrid retrieval in hyperbolic space, sparse-dense fusion limits.
353 tests pass.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
2cd0872e50
commit
850f11838b
@@ -177,37 +177,7 @@ pub async fn run_to_vault(
|
||||
|
||||
git(&vault, &["checkout", "-B", &branch]).await?;
|
||||
|
||||
// The run manifest, beside the notes.
|
||||
//
|
||||
// `templates/teams/continuous_research.toml` has told its reader role to
|
||||
// start from `ContinuousResearch/<date>/harvest.jsonl` since it was
|
||||
// authored, and nothing wrote it — the agents were pointed at a file that
|
||||
// did not exist. This is the code producing what the prompt already
|
||||
// promises, so "nothing new today" is a fact the agent reads rather than a
|
||||
// conclusion it guesses from an empty folder.
|
||||
//
|
||||
// Written only when the run is attributed to a mission: a plain library run
|
||||
// has no agent waiting on it and does not need the extra file in the vault.
|
||||
let mut staged: Vec<&str> = vec!["60 Papers"];
|
||||
let manifest_rel = crate::continuous_research::manifest_path(&crate::continuous_research::today());
|
||||
if mission_id.is_some() {
|
||||
let manifest_abs = vault.join(&manifest_rel);
|
||||
if let Some(parent) = manifest_abs.parent() {
|
||||
std::fs::create_dir_all(parent)
|
||||
.map_err(|e| format!("create {}: {e}", parent.display()))?;
|
||||
}
|
||||
let body = crate::continuous_research::manifest_lines(
|
||||
&total.papers,
|
||||
&crate::continuous_research::today(),
|
||||
);
|
||||
std::fs::write(&manifest_abs, format!("{body}\n"))
|
||||
.map_err(|e| format!("write {}: {e}", manifest_abs.display()))?;
|
||||
staged.push("ContinuousResearch");
|
||||
}
|
||||
|
||||
let mut add: Vec<&str> = vec!["add", "--"];
|
||||
add.extend(staged);
|
||||
git(&vault, &add).await?;
|
||||
git(&vault, &["add", "--", "60 Papers"]).await?;
|
||||
let message = format!(
|
||||
"library: {} new paper(s)\n\n{}\n\nShelved in the blob store; this commit is the catalogue.",
|
||||
total.shelved.len(),
|
||||
|
||||
Reference in New Issue
Block a user