From 6247c42182d458802c202139a6ea5899a06bba62 Mon Sep 17 00:00:00 2001 From: Lior Cohen Date: Fri, 10 Apr 2026 05:23:04 +0300 Subject: [PATCH 1/2] fix: revert accidental hebbian_boosts changes, keep only recency epsilon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove merged supersession-demotion changes (hebbian_boosts type change, demotion→superseded_count rename, multiplicative demotion) that belong on a separate branch - Keep only the recency tie-breaker epsilon (step 7c7) and google_result test fix from PR #13 Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/shrimpk-memory/src/echo.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/crates/shrimpk-memory/src/echo.rs b/crates/shrimpk-memory/src/echo.rs index 3164c77..25bc401 100644 --- a/crates/shrimpk-memory/src/echo.rs +++ b/crates/shrimpk-memory/src/echo.rs @@ -1624,6 +1624,15 @@ impl EchoEngine { } } + // 7c7. KS78: Recency tie-breaker (#13) — after all boosts and caps, add a + // negligible epsilon derived from created_at so newer memories win ties. + for result in &mut results { + if let Some(entry) = store.get(&result.memory_id) { + let recency_epsilon = (entry.created_at.timestamp_micros() as f64) * 1e-18; + result.final_score += recency_epsilon; + } + } + // 7d. Re-sort by final_score (similarity + hebbian boost) results.sort_by(|a, b| { b.final_score @@ -3616,9 +3625,12 @@ mod tests { assert!(results.len() >= 2, "Should have at least 2 results"); - // Find both memories in results + // Find both memories in results (the Meta memory also mentions "Google", + // so match the Google-only memory by excluding results that mention "Meta") let meta_result = results.iter().find(|r| r.content.contains("Meta")); - let google_result = results.iter().find(|r| r.content.contains("Google")); + let google_result = results + .iter() + .find(|r| r.content.contains("Google") && !r.content.contains("Meta")); assert!(meta_result.is_some(), "Meta memory should surface"); assert!(google_result.is_some(), "Google memory should surface"); From a46bac719c0c2164c8a36c54a382c514cc2153df Mon Sep 17 00:00:00 2001 From: Lior Cohen Date: Fri, 10 Apr 2026 16:24:04 +0300 Subject: [PATCH 2/2] fix: document recency epsilon cap bypass (Greptile P2) - Add comment at step 7c6 (inflation cap) noting that step 7c7's recency epsilon intentionally follows after and may exceed the cap by up to ~3e-5, which only breaks ties. Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/shrimpk-memory/src/echo.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/shrimpk-memory/src/echo.rs b/crates/shrimpk-memory/src/echo.rs index 25bc401..c396ea3 100644 --- a/crates/shrimpk-memory/src/echo.rs +++ b/crates/shrimpk-memory/src/echo.rs @@ -1617,6 +1617,9 @@ impl EchoEngine { // 7c6. Score inflation cap (KS69, KS76 Track 3): prevent unbounded boost stacking // Raised from 0.35 to 0.50 to give temporal + importance boosts headroom. + // NOTE: Step 7c7 (recency epsilon) follows this cap and may exceed it + // by up to ~3e-5. This is intentional — the epsilon only breaks ties, + // never meaningful score differences. for result in &mut results { let max_allowed = result.similarity as f64 + 0.50; if result.final_score > max_allowed {