Skip to content

[Repo Assist] feat: implement ExecApprovalV2PolicyHandler (PR7 coordinator)#261

Draft
github-actions[bot] wants to merge 1 commit intomasterfrom
repo-assist/feat-exec-v2-policy-handler-2026-05-02-577afdafa278a1d6
Draft

[Repo Assist] feat: implement ExecApprovalV2PolicyHandler (PR7 coordinator)#261
github-actions[bot] wants to merge 1 commit intomasterfrom
repo-assist/feat-exec-v2-policy-handler-2026-05-02-577afdafa278a1d6

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented May 2, 2026

🤖 This is an automated pull request from Repo Assist.

Summary

This implements ExecApprovalV2PolicyHandler — the V2 exec approval policy coordinator that existing code comments explicitly defer to "PR7/PR8". This makes the V2 approval rail functional for the first time: previously the V2 path in SystemCapability.HandleRunAsync always returned an error because no Allowed result code existed and the only handler (ExecApprovalV2NullHandler) always returned Unavailable.

The handler is intentionally not yet wired to production. A guard test (ProductionWiring_SetV2Handler_NotCalledInSrc) enforces this. The follow-on PR will install it in NodeService/App.xaml.cs once the resolution step from PR #260 lands.

Root Cause

The V2 exec approval architecture was built incrementally:

  • PR1: added routing seam + ExecApprovalV2NullHandler (always inert)
  • PR2–PR6: added input validation, normalization, resolution
  • PR7/PR8 (this PR): add the policy coordinator that evaluates ExecApprovalPolicy and returns an Allowed decision

Without an Allowed code in ExecApprovalV2Code, HandleRunAsync had no way to proceed to execution on the V2 path — the enum was structurally missing its success case.

Changes

ExecApprovalV2Result.cs

  • Added Allowed to ExecApprovalV2Code enum (7 codes total, up from 6)
  • Added ExecApprovalV2Result.Allowed() factory method

ExecApprovalV2PolicyHandler.cs (new)

Implements IExecApprovalV2Handler:

  1. Validates input via ExecApprovalV2InputValidator
  2. Evaluates ExecApprovalPolicy for the top-level command
  3. Expands shell wrappers via ExecShellWrapperParser.Expand() and re-evaluates each sub-command (prevents cmd /c dangerous-cmd from bypassing allow rules)
  4. Returns Allowed, SecurityDeny, or AllowlistMiss

SystemCapability.cs

  • HandleRunAsync V2 branch: proceeds to execution when result is Allowed
  • Extracted ExecuteRunRequestAsync / ParseRunRequest / RunCommandAsync as private helpers shared between the legacy path and the new V2 execution path
  • Added ParsedRunRequest inner class for argv/env/timeout parsing results

Tests

  • ExecApprovalV2RoutingTests.cs: 4 new tests covering the Allowed execution path end-to-end; guard test tightened to .SetV2Handler( call-site pattern; renamed test to reflect 7 codes
  • ExecApprovalV2PolicyHandlerTests.cs (new, 11 tests): covers Allow/Deny/Prompt rules, input validation failures, shell-wrapper inner-command evaluation, non-throw defensive test, integration tests

Trade-offs

  • The handler does not implement Prompt → UI interaction (that is a separate concern for a later PR). A Prompt rule from ExecApprovalPolicy causes the handler to return AllowlistMiss for now, preserving the existing fallback behavior.
  • RunCommandAsync is unchanged from the legacy path; the V2 path reuses it exactly, so execution semantics are identical.

Test Status

Suite Passed Failed Skipped
OpenClaw.Shared.Tests 1165 2 20
OpenClaw.Tray.Tests 407 0 0

The 2 Shared.Tests failures (CanvasCapabilityTests.A2UIPush_WithJsonlPath_ReadsFile, A2UICapabilitySecurityTests.A2UIPush_FileJsonl_OverCap_ReturnsError) are pre-existing and unrelated to this change — they test JSONL file reading in the Canvas/A2UI capability and fail due to test environment setup, not any code changed here.

Closes: n/a (this is forward progress on the V2 exec approval architecture)


Previous baseline: Shared 1152/1172 (20 skipped), Tray 407/407

Generated by 🌈 Repo Assist, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@97143ac59cb3a13ef2a77581f929f06719c7402a

Add the V2 exec approval policy coordinator that was deferred to
"PR7/PR8" in existing code comments. This makes the V2 approval rail
functional for the first time — previously the V2 path always returned
an error because no 'Allowed' result code existed.

Changes:
- ExecApprovalV2Result: add Allowed code + Allowed() factory method
- ExecApprovalV2PolicyHandler: new IExecApprovalV2Handler implementation
  that validates input, evaluates ExecApprovalPolicy, expands shell
  wrappers and re-evaluates each sub-command, then returns
  Allowed/SecurityDeny/AllowlistMiss
- SystemCapability.HandleRunAsync: execute command when V2 returns
  Allowed; extract ParseRunRequest/RunCommandAsync/ExecuteRunRequestAsync
  helpers shared between legacy and V2 paths
- ExecApprovalV2RoutingTests: 4 new Allowed-path routing tests; guard
  test tightened to .SetV2Handler( call-site pattern; renamed
  V2Result_AllCodesConstructible (6→7 codes)
- ExecApprovalV2PolicyHandlerTests: 11 new tests covering allow/deny/
  prompt rules, input validation, shell-wrapper expansion, integration

The handler is not yet wired to production (the guard test enforces
this); a follow-on PR will install it in NodeService/App.xaml.cs once
the resolution step from PR#260 lands.

Test status: Shared 1165 passed / 2 failed (pre-existing A2UI/Canvas
failures unrelated to this change) / 20 skipped. Tray 407 passed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants