feat(memory): implement TrajectoryRiskAccumulator and ImplicitConflictDetector#4386
Merged
Conversation
808947d to
8a62f5b
Compare
…tDetector Implements two security and memory quality improvements: TrajectoryRiskAccumulator (#4372): per-session shadow memory that accumulates safety signals (PolicyViolation, PromptInjectionPattern, ToolChainAnomaly, ConfidenceDrop) with exponential temporal decay and gates tool execution when trajectory risk exceeds the configured threshold. Based on MAGE (arXiv:2605.03228) — reduces tool-chain attack success from 100% to ≤10% with default config. Controlled via [memory.shadow_memory] with enabled=false default. ImplicitConflictDetector (#4373): write-time predicate similarity detection for APEX-MEM that stages implicit conflict candidates using Levenshtein distance, extends SYNAPSE ActivatedFact with is_implicit_conflict/conflict_candidate_id fields, and annotates recall results when pending candidates exist. Addresses the STALE benchmark gap (55.2% frontier model accuracy on implicit conflicts). Controlled via [memory.graph.implicit_conflict] with enabled=false default. Both features are additive and opt-in: disabled by default with zero-overhead noop paths. No changes to existing memory pipeline behavior when both are disabled. Closes #4372 Closes #4373
db6813d to
daf8c84
Compare
bug-ops
added a commit
that referenced
this pull request
May 18, 2026
- Rename migration 090 → 091 to avoid conflict with 090_implicit_conflict_candidates added in #4386 (TrajectoryRiskAccumulator) - Rename ConsolidationDaemonConfig (five-signal) → FiveSignalConsolidationConfig to avoid collision with existing spec 004-17 ConsolidationDaemonConfig - Keep shadow_memory field added by #4386 alongside five_signal in MemoryConfig
bug-ops
added a commit
that referenced
this pull request
May 18, 2026
- Rename migration 090 → 091 to avoid conflict with 090_implicit_conflict_candidates added in #4386 (TrajectoryRiskAccumulator) - Rename ConsolidationDaemonConfig (five-signal) → FiveSignalConsolidationConfig to avoid collision with existing spec 004-17 ConsolidationDaemonConfig - Keep shadow_memory field added by #4386 alongside five_signal in MemoryConfig
bug-ops
added a commit
that referenced
this pull request
May 18, 2026
- Rename migration 090 → 091 to avoid conflict with 090_implicit_conflict_candidates added in #4386 (TrajectoryRiskAccumulator) - Rename ConsolidationDaemonConfig (five-signal) → FiveSignalConsolidationConfig to avoid collision with existing spec 004-17 ConsolidationDaemonConfig - Keep shadow_memory field added by #4386 alongside five_signal in MemoryConfig
bug-ops
added a commit
that referenced
this pull request
May 18, 2026
…dation daemon (#4392) * release: prepare v0.21.2 - Bump workspace version 0.21.1 → 0.21.2 - Consolidate duplicate CHANGELOG.md section headers in [0.21.2] - Update splash snapshot for new version string - Update test badge count (9824) - Update specs to reflect changes since v0.21.1 * feat(memory): extend SYNAPSE to five-signal retrieval + async consolidation daemon Extends SYNAPSE recall in zeph-memory from two signals (recency + semantic relevance) to five by adding access frequency, causal distance, and novelty. Adds an optional async consolidation daemon via zeph-scheduler that promotes high-utility episodic facts to Qdrant and deprioritizes cold ones. New signals (all off by default — w_frequency=w_causal=w_novelty=0.0): - access_frequency: log(1+count) normalized, tracked in fact_access_log SQLite table; session-scoped via per-process UUID - causal_distance: BFS on MAGMA causal edges from current goal entity, bounded by causal_bfs_max_depth (default 10), cached per turn - novelty: exp(-λ × days_since_agent_init), pure arithmetic, zero I/O Weight normalization to 1.0 happens once at startup with WARN if config values diverge. The is_baseline() short-circuit preserves zero overhead for the two-signal default. Feature-gated consolidation daemon registered via zeph-scheduler under the `scheduler` feature. Migration 090 adds: fact_access_log table, messages.memory_tier, messages.qdrant_promoted columns. Research basis: MemTier (arXiv:2605.03675) — +33pp on LongMemEval-S; 14pp tool-execution degradation over 72h with flat retrieval. Closes #4374 Closes #3703 * fix(memory): resolve merge conflicts with main after rebase onto v0.21.2 - Rename migration 090 → 091 to avoid conflict with 090_implicit_conflict_candidates added in #4386 (TrajectoryRiskAccumulator) - Rename ConsolidationDaemonConfig (five-signal) → FiveSignalConsolidationConfig to avoid collision with existing spec 004-17 ConsolidationDaemonConfig - Keep shadow_memory field added by #4386 alongside five_signal in MemoryConfig
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
zeph-memory, feat(memory): implement TrajectoryRiskAccumulator — shadow memory safety guardrail #4372): per-session shadow memory stream that ingests per-turn audit signals with exponential temporal decay and gates tool execution when cumulative trajectory risk exceeds a configurable threshold. Addresses multi-turn attack vectors (tool-chain chaining, persistent indirect prompt injection) that per-turnContentSanitizercontrols cannot detect. Based on MAGE (arXiv:2605.03228).zeph-memory, feat(memory): implement ImplicitConflictDetector — write-time stale memory resolution #4373): write-time predicate similarity detection for APEX-MEM using Levenshtein distance, staging conflict candidates inimplicit_conflict_candidates(migration 090), and annotating SYNAPSEActivatedFactresults withis_implicit_conflict/conflict_candidate_id. Addresses the STALE benchmark gap (55.2% frontier model accuracy on implicit conflicts).Both features are opt-in with
enabled = falsedefault — zero overhead when disabled.Changes
crates/zeph-memory/src/shadow/mod.rs— new:TrajectoryRiskAccumulatorwith noop mode, decay, ring buffer,is_blocked()/should_escalate(), 8 unit testscrates/zeph-memory/src/graph/implicit_conflict.rs— new:ImplicitConflictDetector,normalized_levenshtein,detect_candidates,stage_candidates,annotate_conflicts, 12 unit tests including DB testscrates/zeph-db/migrations/sqlite/090_implicit_conflict_candidates.sql— new staging tablecrates/zeph-sanitizer/src/audit.rs— new:AuditSignalType,Severityenumscrates/zeph-config/src/memory.rs—TrajectoryRiskAccumulatorConfig+[memory.shadow_memory];ImplicitConflictConfig+[memory.graph.implicit_conflict]; non-negative weight validatorscrates/zeph-memory/src/graph/activation.rs—ActivatedFactextended withis_implicit_conflict: bool,conflict_candidate_id: Option<i64>crates/zeph-memory/src/graph/store/mod.rs—insert_or_supersede_with_conflict_detectionwrappercrates/zeph-tools/src/executor.rs—ToolError::TrajectoryRiskExceeded { score, top_signals }Test plan
cargo +nightly fmt --check— cleancargo clippy --workspace --features desktop,ide,server,chat,pdf,scheduler -- -D warnings— cleancargo nextest run --workspace --features desktop,ide,server,chat,pdf,scheduler --lib --bins— 10149 passedcargo test --doc --workspace --features desktop,ide,server,chat,pdf,scheduler— 19 passedRUSTFLAGS="-D warnings" cargo check --workspace --all-targets --features desktop,ide,server,chat,pdf,scheduler --locked— cleanhalflife_turns = 0clamped to 1 withtracing::warn!annotate_conflicts(chunks of 499)Closes #4372
Closes #4373