refactor(agents): split before-tool-call policy pipeline#113885
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 25, 2026, 5:59 PM ET / 21:59 UTC. ClawSweeper reviewWhat this changesThis PR decomposes the agent pre-tool-call approval, policy, diagnostics, and execution flow into focused modules while keeping Merge readiness⛔ Blocked until real behavior proof from a real setup is added - 5 items remain Keep this PR open for maintainer review. It is a broad but focused refactor of the security-sensitive pre-tool execution boundary; the supplied diff preserves the public facade and centralizes the prepared-parameter/finalization contract, but the protected Priority: P3 Review scores
Verification
How this fits togetherBefore an agent executes a tool, OpenClaw prepares parameters, applies loop and security policies, obtains approvals, records diagnostics, and then runs the tool. This PR reorganizes that boundary without intending to change the decisions, parameter identity, or execution order that downstream tool adapters rely on. flowchart LR
A[Agent requests tool call] --> B[Prepare parameters]
B --> C[Ordered policy chain]
C --> D[Approval transport]
D --> E[Diagnostics and loop tracking]
E --> F[Finalize prepared parameters]
F --> G[Tool execution]
G --> H[Terminal diagnostics and replay state]
Decision needed
Why: This is a maintainer-labeled refactor of a security-sensitive control boundary; source-level checks alone cannot choose the acceptable risk level for preserving historical execution semantics. Before merge
Agent review detailsSecurityNone. PR surfaceSource +133, Generated 0, Other -1. Total +132 across 8 files. View PR surface stats
Review metrics
Stored data modelPersistent data-model change detected: Merge-risk optionsMaintainer options:
Copy recommended automerge instructionTechnical reviewBest possible solution: Retain the focused module split, then obtain owner review of the complete ordering and prepared-parameter identity contract plus redacted live evidence for both execution paths before merge. Do we have a high-confidence way to reproduce the issue? Not applicable: this PR is an internal refactor and does not report a user-facing bug. The relevant verification is behavioral parity across the existing wrapped and adapter execution paths. Is this the best way to solve the issue? Unclear: splitting the god file by approval, policy, diagnostics, and execution ownership is a maintainable direction, but this review cannot establish the required parity from test/build claims alone without live path evidence and owner confirmation. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against c0e4caae5589. LabelsLabel changes:
Label justifications:
EvidenceWhat I checked:
Likely related people:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
|
3f58d14 to
1e0a149
Compare
|
ClawSweeper status: review started. I am starting a fresh review of this pull request: refactor(agents): split before-tool-call policy pipeline This is item 1/1 in the current shard. Shard 0/1. This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking. Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted. |
|
Merged via squash.
|
…3885) * refactor(agents): split before-tool-call pipeline * refactor(agents): isolate before-tool call types * fix(agents): restore approval resolution type import
Additional instructions
MUST: Keep Allow edits from maintainers enabled for this PR so maintainers
can help update the branch when needed.
What Problem This Solves
The pre-tool execution boundary had grown to 2,143 lines while owning approval transport, ordered policy decisions, diagnostics and skill telemetry, loop bookkeeping, and wrapped execution. That made security-sensitive ordering and parameter-identity invariants hard to review and kept the file on the max-lines baseline.
This is a maintainer-requested god-file reduction. It is AI-assisted.
Why This Change Was Made
Split the implementation into approval transport, policy-chain orchestration, diagnostics/skill/loop handling, and wrapped execution/finalization modules, plus a type-only shared contract module that prevents facade back-edges. The original path remains a small facade. Every implementation module is below 700 lines, so the target baseline entry is removed.
The split preserves the exact policy sequence and both execution paths. A shared finalization helper keeps the original prepared argument object alive through reconciliation because exec preparation keys private state by that exact WeakMap identity. It also preserves the adapter and wrapped paths' distinct historical finalizer receiver/nullish-return semantics.
A high-severity pre-existing control bypass was found during this audit and is deliberately not fixed here: Skill Workshop is revalidated on final params, while client-voice confirmation still runs only on initial params before later permitted rewrites. The maintainer has confirmed and routed that behavior to a dedicated product/security fix. The related pre-existing loop-history mismatch and voice-denial attribution remain untouched too.
User Impact
No user-visible behavior change. This makes the pre-execution security boundary smaller and clearer to review without changing policy decisions, approval timing, parameter rewriting, diagnostics, or tool execution.
Beyond the Split
Removed the redundant local preparing-tool intersection because
AnyAgentToolalready owns the optional preparation and finalization callbacks. The initial Skill Workshop probe remains unchanged because its truthiness controls the fast return; no approval-path optimization was attempted.Ordering Verification
I re-traced source order after the split, independently for the policy chain and both execution paths:
preparedParams, then code-mode normalizes;The policy sequence is visible in
src/agents/agent-tools.before-tool-call.policy.ts:113,:178,:185,:235,:284,:306,:342,:368,:390, and:393. The two execution paths are visible insrc/agents/agent-tools.before-tool-call.wrapper.ts:348andsrc/agents/agent-tool-definition-adapter.ts:351. The two-object WeakMap contract and historical finalizer modes are centralized and documented atsrc/agents/agent-tools.before-tool-call.wrapper.ts:92.Evidence
Final rebased proof: Blacksmith Testbox
tbx_01kydn82ymsw1j5atn6fcj50ty: https://github.com/openclaw/openclaw/actions/runs/30177045792pnpm check:changed: passed on the final reviewed tree in 16m48s, including format, max-lines ratchet, SDK API baseline, core/core-test typechecks, all core lint shards, boundary guards, and zero runtime import cycles.Exact full-CI recovery lanes passed:
pnpm check:architecturereports zero runtime and madge cycles;pnpm deadcode:dependenciesandpnpm deadcode:exportsreport zero unused entries.Focused before-tool/adapter/runtime suites: 199 passed. Four current-main private diagnostic-content cases were excluded from the clean command; an archived
origin/mainrun independently reproduced the same three failures because those tests still use the retired per-fieldcaptureContentshape. This PR does not alter that behavior or those tests.pnpm build: passed in 1m30s; all 142 public Plugin SDK subpaths verified and no[INEFFECTIVE_DYNAMIC_IMPORT]warning appeared.Redacted real exec proof through both production paths: https://github.com/openclaw/openclaw/actions/runs/30177961708. The wrapped and unwrapped-adapter calls each executed
pwdin a disposable prepared workdir, returnedstatus=completed/exitCode=0, preserved the final adjusted workdir, and observed that workdir in real shell output:{"wrapped":{"status":"completed","exitCode":0,"adjustedWorkdirMatches":true,"outputContainsWorkspace":true},"adapter":{"status":"completed","exitCode":0,"adjustedWorkdirMatches":true,"outputContainsWorkspace":true}}Plugin SDK baseline regeneration changed only the
agent-harness-runtimesource-link hash; exported declarations remained identical.Final full-branch autoreview: clean, no accepted/actionable findings (
patch is correct, 0.98).Owner review: the maintainer/orchestrator explicitly accepted the ordering and prepared-state analysis, confirmed B17/B18/B19 are separate work, and directed this split through the full review-and-land workflow.