Skip to content

fix(core,memory): correct write-time provenance and audit gating in MemGhost consent gate#6599

Merged
bug-ops merged 1 commit into
mainfrom
fix/6556-memghost-source-kind-mislabel
Jul 20, 2026
Merged

fix(core,memory): correct write-time provenance and audit gating in MemGhost consent gate#6599
bug-ops merged 1 commit into
mainfrom
fix/6556-memghost-source-kind-mislabel

Conversation

@bug-ops

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

Copy link
Copy Markdown
Owner

Summary

Three follow-up defects in the MemGhost write-time memory-consent gate (PR #6544 / issue #6490), all in the same zeph-core memory persistence path:

  • Agent::sanitize_tool_output computed the accurate ContentSourceKind per tool call but discarded it at the return boundary. The batched write path (tier_loop.rs) then re-derived source_kind from the aggregated trust tier alone via a lossy 2-bucket heuristic, mislabeling any batch containing MCP, A2A, memory-retrieval, or channel-message output as "web_scrape" in messages.source_kind, the Qdrant payload, and the memory_write audit-log entry. Live-reproduced in CI cycle ci-1440. Fixed by threading the real ContentSourceKind through process_one_tool_result (new batch_source_kind, tie-break: later call wins on equal trust tier) into the persisted write.
  • consent_gate.audit_all = false was honored on the background tool-output write path but not on the interactive memory_save path, so the documented "suppresses audit regardless of trust tier" contract only held for half of the write paths. MemoryToolExecutor gained an audit_all field wired through all 4 production entry points (runner.rs, acp.rs, daemon.rs, serve/agent_factory.rs).
  • The disclosure-note branch of persist_message_inner (in-turn channel note for autonomous untrusted writes) had no direct test coverage, unlike its sibling audit-log branch.

12 new regression tests added, including two adversarial-critique-driven additions: an audit_all=false case proving disclosure/audit independence, and an inverse call-order case proving the tie-break doesn't regress on reversed batch order.

Test plan

  • 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 — 14923 passed, 0 failed
  • Rustdoc gate (RUSTFLAGS="-D warnings" RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --workspace)
  • gitleaks protect --staged
  • .local/testing/playbooks/memory-consent.md updated with scenarios 11-12 covering these fixes
  • .local/testing/coverage-status.md row updated in place

Closes #6556
Closes #6559
Closes #6557

@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/XL Extra large PR (500+ lines) labels Jul 20, 2026
@bug-ops
bug-ops enabled auto-merge (squash) July 20, 2026 18:12
@bug-ops
bug-ops force-pushed the fix/6556-memghost-source-kind-mislabel branch from 4f7f3b3 to 32cadf3 Compare July 20, 2026 18:29
…emGhost consent gate

Batched tool-output writes recorded source_kind via a lossy heuristic
keyed only on aggregated trust level, mislabeling MCP, A2A,
memory-retrieval, and channel-message batches as web_scrape in the
audit log and messages.source_kind. sanitize_tool_output now returns
the real ContentSourceKind alongside trust level, and it is tracked
and persisted directly instead of re-derived.

consent_gate.audit_all was honored on the background tool-output
write path but not on the interactive memory_save path, so setting
it to false did not suppress interactive audit entries as documented.
MemoryToolExecutor now gates its audit block on audit_all consistently
with the background path, wired through all four entry points.

Also adds direct test coverage for the disclosure-note branch, which
previously had none.

Closes #6556
Closes #6559
Closes #6557
@bug-ops
bug-ops force-pushed the fix/6556-memghost-source-kind-mislabel branch from 32cadf3 to cb26f4e Compare July 20, 2026 18:32
@bug-ops
bug-ops merged commit 2780eca into main Jul 20, 2026
43 checks passed
@bug-ops
bug-ops deleted the fix/6556-memghost-source-kind-mislabel branch July 20, 2026 18:42
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/XL Extra large PR (500+ lines)

Projects

None yet

1 participant