Skip to content

fix(sanitizer): classify memory_search tool output as MemoryRetrieval (#2057)#2065

Merged
bug-ops merged 2 commits intomainfrom
fix-2057
Mar 20, 2026
Merged

fix(sanitizer): classify memory_search tool output as MemoryRetrieval (#2057)#2065
bug-ops merged 2 commits intomainfrom
fix-2057

Conversation

@bug-ops
Copy link
Copy Markdown
Owner

@bug-ops bug-ops commented Mar 20, 2026

Summary

This PR fixes GitHub issue #2057: memory_search tool output was not covered by the MemorySourceHint false-positive suppression added in PR #2053.

Root Cause

PR #2053 fixed false-positive injection detection in the context assembly path (assembly.rs), but the tool execution path (tool_execution/mod.rs) for memory_search was missed.

When users recalled memory containing phrases like "system prompt", the sanitizer incorrectly flagged it as a potential injection pattern → Qdrant embedding was skipped for the entire turn → semantic recall quality degraded over time.

Fix

  • Detect tool_name == "memory_search" in sanitize_tool_output()
  • Classify as ContentSourceKind::MemoryRetrieval with MemorySourceHint::ConversationHistory
  • This activates the existing hint suppression logic in sanitizer/lib.rs:321-328
  • Aligns the tool execution path with assembly.rs:698 (context assembly path already uses the same classification)

Defense-in-Depth

All structural defenses remain active:

  • Truncation (max_content_size)
  • Control character stripping
  • Delimiter tag escaping (</external-data> cannot break out)
  • Spotlighting with <external-data> wrapper (ExternalUntrusted trust level)

Only injection pattern regex detection is suppressed (the source of the false positives).

Validation

  • Unit tests: 6093 passed (+3 new), zero regressions
  • Security review: Low risk, stricter trust level (MemoryRetrieval < ToolResult)
  • Performance: No impact, slight speedup (regex scanning skipped for memory_search)
  • Code review: All validators (tester, security, perf, impl-critic, reviewer) APPROVED

Files Changed

  • crates/zeph-core/src/agent/tool_execution/mod.rs — add memory_search branch (7 lines)
  • crates/zeph-core/src/agent/tool_execution/tests.rs — add 3 regression tests (45 lines)
  • CHANGELOG.md — add entry to [Unreleased] Fixed section

Closes #2057.

… (issue #2057)

PR #2053 added MemorySourceHint to suppress false-positive injection detection
for memory retrieval in the context assembly path (assembly.rs). However, the
tool_execution path for memory_search was not covered.

Memory_search returns recalled conversation turns from semantic memory (SQLite/Qdrant).
Without proper classification, benign recalled content (e.g., user discussing
"system prompt") triggered injection false positives → Qdrant embedding was
skipped for the entire turn.

This fix:
1. Adds memory_search detection in sanitize_tool_output() (tool_execution/mod.rs)
2. Classifies it as ContentSourceKind::MemoryRetrieval with ConversationHistory hint
3. This enables the MemorySourceHint suppression logic (sanitizer/lib.rs:321-328)
4. Aligns tool_execution path with assembly.rs:698 (context assembly path)

Defense-in-depth remains: truncation, control char stripping, delimiter escaping,
and spotlighting with <external-data> wrapper all remain active. Only injection
pattern regex detection is suppressed (which was the source of false positives).

Tested: 6093 unit tests pass (+3 new), zero regressions.
@github-actions github-actions bot added bug Something isn't working size/M Medium PR (51-200 lines) documentation Improvements or additions to documentation rust Rust code changes core zeph-core crate and removed size/M Medium PR (51-200 lines) labels Mar 20, 2026
@bug-ops bug-ops enabled auto-merge (squash) March 20, 2026 19:27
@github-actions github-actions bot added the size/M Medium PR (51-200 lines) label Mar 20, 2026
@bug-ops bug-ops merged commit fafb8e1 into main Mar 20, 2026
25 checks passed
@bug-ops bug-ops deleted the fix-2057 branch March 20, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working core zeph-core crate documentation Improvements or additions to documentation rust Rust code changes size/M Medium PR (51-200 lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(sanitizer): memory_search tool output path not covered by MemorySourceHint fix (#2053)

1 participant