Skip to content

fix(core): strip ephemeral Image parts before persistence writes - #6307

Merged
bug-ops merged 1 commit into
mainfrom
feat/issue-6239/persistence-strip
Jul 14, 2026
Merged

fix(core): strip ephemeral Image parts before persistence writes#6307
bug-ops merged 1 commit into
mainfrom
feat/issue-6239/persistence-strip

Conversation

@bug-ops

@bug-ops bug-ops commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • Enforces invariant C1/M5 (specs/072-multimodal-mcp-passthrough/spec.md §4): MessagePart::Image must never reach SQLite parts_json, Qdrant embeddings, or the durable JSONL session log.
  • Agent::persist_message now computes a stripped copy of parts (Image-filtered) and passes it to both persistence writers, before any code path that can produce an MCP-sourced Image part lands. The in-memory Message (already pushed via push_message) keeps its Image parts for the current turn's provider request — only the two persistence writers get the stripped copy.
  • Also closes pre-existing persistence waste on the existing user-upload image path.

Closes #6239

Test plan

  • 4 new tests in crates/zeph-core/src/agent/persistence/tests.rs (mod image_persistence_strip): strip verified against SQLite parts_json round-trip, the Qdrant-embed-path message-count/round-trip, the session JSONL log (SessionEvent::AssistantMessage), and a test proving the in-memory Message is unaffected.
  • cargo +nightly fmt --check
  • cargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warnings
  • cargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins --no-fail-fast — 13722 passed, 0 failed (one pre-existing unrelated flaky test, debug_dump::tests::json_dump_request_includes_request_metadata, confirmed by isolated re-run and independently by the reviewer)
  • Rustdoc gate (RUSTFLAGS="-D warnings" RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --workspace --features "desktop,ide,server,chat,pdf,scheduler")
  • CHANGELOG.md updated under [Unreleased]

Follow-ups filed during review

Two adjacent gaps were identified but are out of this issue's literal scope (spec-072 §4/AC-5 name exactly SQLite/Qdrant/session-JSONL, bound to Agent::persist_message) and are tracked separately:

@github-actions github-actions Bot added documentation Improvements or additions to documentation rust Rust code changes core zeph-core crate bug Something isn't working size/L Large PR (201-500 lines) labels Jul 14, 2026
@bug-ops
bug-ops enabled auto-merge (squash) July 14, 2026 22:14
Enforces invariant C1/M5 (spec-072 4) -- MessagePart::Image must never
reach SQLite parts_json, Qdrant embeddings, or the durable JSONL
session log. Agent::persist_message now computes a stripped copy of
parts before both persistence writers; the in-memory Message retains
its Image parts for the current turn's provider request. Also closes
pre-existing persistence waste on the user-upload image path.
@bug-ops
bug-ops force-pushed the feat/issue-6239/persistence-strip branch from a84f927 to f01eca9 Compare July 14, 2026 22:21
@bug-ops
bug-ops merged commit c50c4a3 into main Jul 14, 2026
43 checks passed
@bug-ops
bug-ops deleted the feat/issue-6239/persistence-strip branch July 14, 2026 22:29
bug-ops added a commit that referenced this pull request Jul 16, 2026
TranscriptWriter::append serialized the full Message verbatim to the
sub-agent's JSONL transcript with no filtering. Sub-agents never call
Agent::persist_message, so their transcripts bypassed the
MessagePart::Image strip landed in #6307 for spec-072 C1 entirely.

Extract the strip logic into a shared MessagePart::strip_images helper
in zeph-llm and call it from both Agent::persist_message and
TranscriptWriter::append, closing the defense-in-depth gap before #6240
(MCP image emission in tool-result processing) can make it reachable.

Closes #6305
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/L Large PR (201-500 lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement: P1 ephemeral persistence strip for MCP image passthrough

1 participant