Skip to content

fix(tools): DynExecutor::requires_confirmation does not delegate to inner ErasedToolExecutor #3646

@bug-ops

Description

@bug-ops

Description

DynExecutor implements ToolExecutor but does not override requires_confirmation, so it always returns the default false from ToolExecutor. Every other delegation method (is_tool_retryable, is_tool_speculatable, set_skill_env, set_effective_trust) correctly calls the corresponding _erased variant on the inner Arc<dyn ErasedToolExecutor> — but requires_confirmation is missing.

This inconsistency is currently unexploitable because the speculation engine holds Arc<dyn ErasedToolExecutor> directly and calls requires_confirmation_erased without going through DynExecutor. However, DynExecutor is a public composition primitive, and as usage grows the missing delegation will silently produce incorrect behavior.

Reproduction Steps

  1. Wrap an ErasedToolExecutor implementation that overrides requires_confirmation_erased to return true inside a DynExecutor
  2. Call dyn_executor.requires_confirmation(call) via the ToolExecutor trait
  3. Observe: returns false instead of delegating to the inner requires_confirmation_erased

Expected Behavior

DynExecutor::requires_confirmation should delegate to self.0.requires_confirmation_erased(call), consistent with all other delegation methods.

Recommended Fix

Add to DynExecutor's ToolExecutor impl:

fn requires_confirmation(&self, call: &ToolCall) -> bool {
    self.0.requires_confirmation_erased(call)
}

Files

  • crates/zeph-tools/src/executor.rsDynExecutor impl of ToolExecutor

Depends on

#3644 (merged) — introduced ToolExecutor::requires_confirmation

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