Skip to content

fix(tools): AdversarialPolicyGateExecutor.write_audit() does not propagate claim_source from ToolOutput #2535

@bug-ops

Description

@bug-ops

Summary

AdversarialPolicyGateExecutor.write_audit() in crates/zeph-tools/src/adversarial_gate.rs writes audit entries for all tool calls but hardcodes claim_source: None, even though the tool executor sets it in ToolOutput.

Root cause

write_audit() is called before or without access to the ToolOutput — it builds AuditEntry directly from ToolCall parameters with no reference to the execution result. Individual executors (shell, scrape, file, search_code) set claim_source in ToolOutput, but this is never copied into the adversarial gate's audit entry.

Observed in CI-355 (2026-03-31)

Audit entries for search_code and read always show no claim_source field:

{"tool": "search_code", "adversarial_policy_decision": "allow"}
{"tool": "read", "adversarial_policy_decision": "allow"}

Expected: "claim_source": "code_search" for search_code, "claim_source": "file_system" for read.

Fix sketch

Refactor write_audit() to be called after tool execution completes (or add a post-execution variant that accepts the ToolOutput) so it can copy claim_source from the result. For blocked/denied calls where no ToolOutput exists, claim_source remains None.

Note: ShellExecutor writes its own audit entries separately (via shell/mod.rs:674) and correctly sets claim_source: Some(ClaimSource::Shell). The adversarial gate entries would duplicate shell entries if both are active — consider deduplicating or merging them.

Related

Metadata

Metadata

Assignees

Labels

P3Research — medium-high complexitybugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions