From 8983b13afddc5536449b7e59a93f4f399f239854 Mon Sep 17 00:00:00 2001 From: Caleb Gross Date: Fri, 20 Mar 2026 14:51:03 -0400 Subject: [PATCH] fix: pattern decay rates and watcher noise filtering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three fixes for signal quality issues found during agent audit: 1. Pattern decay rates increased — self-sustaining patterns now decay at 0.995/cycle (was 0.9999, ~30% monthly loss vs ~0.07%). Normal patterns 0.995 (was 0.998). Stale threshold reduced from 7 to 3 days. Stale decay rates increased across all tiers. 2. Hard-reject release tooling files — .release-please-manifest.json and CHANGELOG.md added to heuristic lockfile rejection list. These are deterministic files with zero semantic value. 3. Salience floor raised 0.0 → 0.5 in DefaultConfig — non-MCP memories below 0.5 salience (shallow config changes, desktop noise) are skipped during encoding. Co-Authored-By: Claude Opus 4.6 (1M context) --- internal/agent/consolidation/agent.go | 24 ++++++++++++------------ internal/agent/encoding/agent.go | 3 ++- internal/agent/perception/heuristic.go | 5 +++-- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/internal/agent/consolidation/agent.go b/internal/agent/consolidation/agent.go index 113f6eb1..875d8b9a 100644 --- a/internal/agent/consolidation/agent.go +++ b/internal/agent/consolidation/agent.go @@ -48,15 +48,15 @@ type ConsolidationConfig struct { StrongEvidenceMinCount int // evidence count to unlock strong ceiling (default 10) // Pattern decay tunables - PatternBaselineDecay float32 // per-cycle baseline decay (default 0.998) - StaleDecayHealthy float32 // decay when evidence ratio >= 0.5 (default 0.98) - StaleDecayModerate float32 // decay when evidence ratio >= 0.2 (default 0.95) - StaleDecayAggressive float32 // decay when evidence ratio < 0.2 (default 0.90) + PatternBaselineDecay float32 // per-cycle baseline decay (default 0.995) + StaleDecayHealthy float32 // decay when evidence ratio >= 0.5 (default 0.97) + StaleDecayModerate float32 // decay when evidence ratio >= 0.2 (default 0.93) + StaleDecayAggressive float32 // decay when evidence ratio < 0.2 (default 0.85) // Self-sustaining pattern tunables SelfSustainingMinEvidence int // evidence count to qualify (default 10) SelfSustainingMinStrength float32 // minimum strength to qualify (default 0.9) - SelfSustainingDecay float32 // reduced decay for qualifying patterns (default 0.9999) + SelfSustainingDecay float32 // reduced decay for qualifying patterns (default 0.995) // Never-recalled watcher memory archival NeverRecalledArchiveDays int // archive non-MCP memories with 0 access after this many days (default 30, 0=disabled) @@ -87,13 +87,13 @@ func DefaultConfig() ConsolidationConfig { PatternStrengthCeiling: 0.95, StrongEvidenceCeiling: 1.0, StrongEvidenceMinCount: 10, - PatternBaselineDecay: 0.998, - StaleDecayHealthy: 0.98, - StaleDecayModerate: 0.95, - StaleDecayAggressive: 0.90, + PatternBaselineDecay: 0.995, + StaleDecayHealthy: 0.97, + StaleDecayModerate: 0.93, + StaleDecayAggressive: 0.85, SelfSustainingMinEvidence: 10, SelfSustainingMinStrength: 0.9, - SelfSustainingDecay: 0.9999, + SelfSustainingDecay: 0.995, NeverRecalledArchiveDays: 30, } } @@ -1531,12 +1531,12 @@ func (ca *ConsolidationAgent) decayPatterns(ctx context.Context) (int, error) { p.Strength *= cfgFloat32(ca.config.PatternBaselineDecay, 0.998) } - // Additional evidence-based decay for patterns not accessed within 7 days + // Additional evidence-based decay for patterns not accessed within 3 days recency := p.LastAccessed if recency.IsZero() { recency = p.CreatedAt } - stale := recency.IsZero() || time.Since(recency).Hours() >= 168 + stale := recency.IsZero() || time.Since(recency).Hours() >= 72 if stale { totalEvidence := len(p.EvidenceIDs) diff --git a/internal/agent/encoding/agent.go b/internal/agent/encoding/agent.go index 1a95aed4..2b6118c5 100644 --- a/internal/agent/encoding/agent.go +++ b/internal/agent/encoding/agent.go @@ -74,7 +74,7 @@ type EncodingConfig struct { EmbedBatchSize int // max memories to batch-embed in one call (default 10) DeduplicationThreshold float32 // cosine sim above which new memory is a duplicate (default: 0.95) MCPDeduplicationThreshold float32 // higher threshold for MCP-sourced memories (default: 0.98) - SalienceFloor float32 // min salience to encode; non-MCP sources below this are skipped (default: 0.0) + SalienceFloor float32 // min salience to encode; non-MCP sources below this are skipped (default: 0.5) DisablePolling bool // if true, skip the polling loop (MCP processes should not poll) } @@ -129,6 +129,7 @@ func DefaultConfig() EncodingConfig { BatchSizePoll: 10, DeduplicationThreshold: 0.95, MCPDeduplicationThreshold: 0.98, + SalienceFloor: 0.5, } } diff --git a/internal/agent/perception/heuristic.go b/internal/agent/perception/heuristic.go index 6ba03008..60d9d0e8 100644 --- a/internal/agent/perception/heuristic.go +++ b/internal/agent/perception/heuristic.go @@ -269,9 +269,10 @@ func (h *HeuristicFilter) evaluateFilesystem(path, content string) (float32, str "venv/", ".venv/", "site-packages/", ".tox/", ".mypy_cache/", ".ruff_cache/", ".pytest_cache/", ".egg-info/", ".eggs/"} - // Hard-reject lockfiles and checksums — deterministic files with zero semantic value + // Hard-reject lockfiles, checksums, and release tooling — deterministic files with zero semantic value lockfileNames := []string{"go.sum", "package-lock.json", "yarn.lock", "Cargo.lock", - "poetry.lock", "pnpm-lock.yaml", "Gemfile.lock", "composer.lock"} + "poetry.lock", "pnpm-lock.yaml", "Gemfile.lock", "composer.lock", + ".release-please-manifest.json", "CHANGELOG.md"} baseName := path if idx := strings.LastIndex(baseName, "/"); idx >= 0 { baseName = baseName[idx+1:]