From 3fc108a25123dce4aa338a8fc8fd02a6331cd2aa Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Fri, 20 Mar 2026 12:29:32 -0400 Subject: [PATCH] agents: record visits eagerly to prevent concurrent collisions Move visit recording from after LLM completion to immediately after seed selection. With 15 concurrent agents, they all queried the same graph state and selected the same high-degree seeds (core-personality written 12x, irc-regulars 10x). Now the not-visited filter sees the claim before concurrent agents query. Narrows the race window from minutes (LLM call duration) to milliseconds (store load to visit write). Full elimination would require store refresh before query, but this handles the common case. Co-Authored-By: Claude Opus 4.6 (1M context) --- poc-memory/src/agents/knowledge.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/poc-memory/src/agents/knowledge.rs b/poc-memory/src/agents/knowledge.rs index 183ef97..64aad7e 100644 --- a/poc-memory/src/agents/knowledge.rs +++ b/poc-memory/src/agents/knowledge.rs @@ -73,6 +73,11 @@ pub fn run_one_agent_with_keys( all_keys.extend(extra_keys); let agent_batch = super::prompts::AgentBatch { prompt, node_keys: all_keys }; + // Record visits eagerly so concurrent agents pick different seeds + if !agent_batch.node_keys.is_empty() { + store.record_agent_visits(&agent_batch.node_keys, agent_name).ok(); + } + run_one_agent_inner(store, agent_name, &def, agent_batch, llm_tag, log, debug) } @@ -90,6 +95,12 @@ pub fn run_one_agent( log("building prompt"); let agent_batch = super::defs::run_agent(store, &def, batch_size)?; + // Eagerly record visits so concurrent agents pick different seeds. + // The not-visited query filter checks this timestamp. + if !agent_batch.node_keys.is_empty() { + store.record_agent_visits(&agent_batch.node_keys, agent_name).ok(); + } + run_one_agent_inner(store, agent_name, &def, agent_batch, llm_tag, log, debug) } @@ -132,11 +143,6 @@ fn run_one_agent_inner( if debug { print!("{}", response_section); } log(&format!("response {}KB", output.len() / 1024)); - // Record visits for processed nodes - if !agent_batch.node_keys.is_empty() { - store.record_agent_visits(&agent_batch.node_keys, agent_name).ok(); - } - Ok(AgentResult { output, node_keys: agent_batch.node_keys,