Skip to content

fix(tools)!: remove permissive defaults on ToolExecutor/ErasedToolExecutor#6067

Merged
bug-ops merged 1 commit into
mainfrom
feat/issue-6019/toolexecutor-forwarding-fix
Jul 11, 2026
Merged

fix(tools)!: remove permissive defaults on ToolExecutor/ErasedToolExecutor#6067
bug-ops merged 1 commit into
mainfrom
feat/issue-6019/toolexecutor-forwarding-fix

Conversation

@bug-ops

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

Copy link
Copy Markdown
Owner

Summary

Closes the recurring ToolExecutor/ErasedToolExecutor wrapper-forwarding defect class: a decorator's own impl block silently omits an override for a cross-cutting method and falls back to the trait's permissive default instead of forwarding to self.inner. This has recurred five times in roughly two months (#5899/#5905/#5906, #5900/#5938/#5931, #5985, #6012, and a 5th recurrence inside the very commit that closed #6012), each fixed with a one-off manual patch that did not prevent the next occurrence.

Mechanism (Option B + macro assist, architecturally reviewed and approved across two rounds):

  • Removed the permissive default bodies for requires_confirmation, execute_tool_call_confirmed, checkpoint_undo/checkpoint_redo/checkpoint_list, and is_tool_speculatable on both ToolExecutor and ErasedToolExecutor (crates/zeph-tools/src/executor.rs). This makes them required, so the compiler forces an explicit choice at every impl site instead of allowing a silent fallback.
  • Added four macro_rules! helpers in the new crates/zeph-tools/src/executor_delegate.rs to absorb the resulting boilerplate: a forward macro and a no-inner-defaults macro for each trait.
  • Fixed three production ErasedToolExecutor wrappers on the subagent tool-dispatch path with live forwarding gaps, discovered during architecture review:
    • FilteredToolExecutor / PlanModeExecutor (crates/zeph-subagent/src/filter.rs) — now forward the checkpoint trio and is_tool_speculatable_erased; PlanModeExecutor also now forwards set_effective_trust, which was previously silently dropped.
    • MemoryAwareExecutor (crates/zeph-subagent/src/manager/spawn.rs) — its confirmed-call path now replicates the existing sandbox-violation-to-memory-executor fallback instead of bypassing it.
  • Real impl-site count ended up at 167 (150 static + 17 erased) — significantly more than the initial ~107 estimate, since the compiler also surfaced test-only mocks across src/, root tests/, and scattered #[cfg(test)] modules that a manual crates/-only enumeration missed. This is the intended behavior of the compile-time-guarantee approach.
  • Rejected the ambassador delegation-macro crate (RPITIT-incompatible with this trait's native-async-fn methods, and all-or-nothing per trait while most wrappers specialize execute) and pure macro-only forwarding (still relies on remembering to invoke the macro — same review-dependent gap).

Process

Two architecture review rounds: the first plan only covered ToolExecutor, and the critic caught that ErasedToolExecutor — the actual substrate the subagent system dispatches through — was left out with 13 direct impl sites including 3 production wrappers with live gaps. The revised plan folded both traits in and was approved. Implementation was independently validated by four parallel reviewers (tests, performance, security, adversarial critique) with no blocking findings, then went through one code-review round (a documentation-only correction: an invented method name set_effective_trust_erased in the CHANGELOG/playbook that doesn't exist on either trait) before approval.

Test plan

  • cargo +nightly fmt --check
  • cargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warnings
  • cargo clippy --profile ci --workspace --all-targets --features bench -- -D warnings (zeph-bench files touched)
  • cargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins — 12815 passed, 0 failed, 35 skipped (reproduced independently three times across the review chain)
  • cargo test --doc --workspace --features "desktop,ide,server,chat,pdf,scheduler" — all 34 crate doctest binaries, 0 failed
  • RUSTFLAGS="-D warnings" RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --workspace --features "desktop,ide,server,chat,pdf,scheduler"
  • New regression tests for the 3 fixed production erased wrappers (checkpoint forwarding, trust-cap propagation, confirmed-path sandbox fallback)
  • Live-testing playbook and coverage-status.md row added

Closes #6019

@github-actions github-actions Bot added documentation Improvements or additions to documentation rust Rust code changes core zeph-core crate tests Test-related changes bug Something isn't working size/XL Extra large PR (500+ lines) labels Jul 11, 2026
…cutor

Closes the recurring wrapper-forwarding defect class where a decorator's
impl block silently omits a cross-cutting method override and falls back
to the trait's permissive default instead of forwarding to its inner
executor. This has recurred five times in two months across separate,
independently-discovered issues, each fixed with a one-off manual patch
that did not prevent the next occurrence.

Removes the default bodies for requires_confirmation,
execute_tool_call_confirmed, checkpoint_undo/redo/list, and
is_tool_speculatable on both ToolExecutor and ErasedToolExecutor, making
them required at every impl site. Adds four macro_rules! helpers in the
new crates/zeph-tools/src/executor_delegate.rs to absorb the resulting
boilerplate: a forward macro and a no-inner-defaults macro for each
trait. Fixes three production ErasedToolExecutor wrappers with live
forwarding gaps on the subagent tool-dispatch path: FilteredExecutor and
PlanModeExecutor now forward the checkpoint trio, speculatable, and
trust-cap propagation; MemoryAwareExecutor's confirmed-call path
replicates its existing sandbox-violation fallback instead of silently
dropping it.

BREAKING CHANGE: ToolExecutor and ErasedToolExecutor no longer provide
default bodies for requires_confirmation, execute_tool_call_confirmed,
checkpoint_undo/redo/list, and is_tool_speculatable (and their _erased
counterparts). External implementors must provide explicit bodies for
all six methods.

Closes #6019
@bug-ops
bug-ops force-pushed the feat/issue-6019/toolexecutor-forwarding-fix branch from 3f1dba8 to 7d41a23 Compare July 11, 2026 18:02
@bug-ops
bug-ops enabled auto-merge (squash) July 11, 2026 18:02
@bug-ops
bug-ops merged commit b20b686 into main Jul 11, 2026
43 checks passed
@bug-ops
bug-ops deleted the feat/issue-6019/toolexecutor-forwarding-fix branch July 11, 2026 18:10
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) tests Test-related changes

Projects

None yet

1 participant