Skip to content

feat(graph): ToolExecutor wrapper [W2.C.2]#57

Draft
TimothyVang wants to merge 2 commits into
feat/W2.C.1-deny-rule-wrapperfrom
feat/W2.C.2-tool-executor
Draft

feat(graph): ToolExecutor wrapper [W2.C.2]#57
TimothyVang wants to merge 2 commits into
feat/W2.C.1-deny-rule-wrapperfrom
feat/W2.C.2-tool-executor

Conversation

@TimothyVang

Copy link
Copy Markdown
Owner

Summary

  • Implements verdict/graph/wrappers/tool_executor.py — second wrapper in the executor_work composition.
  • Dispatches (tool_name, args) to registered ToolWrapper subclasses.
  • UnknownToolError with informative message (lists registered tools) for unregistered tools.
  • __call__ satisfies DenyRuleWrapper's Callable[[str, dict], Any] executor contract.
  • Duplicate tool_name at construction raises ValueError.
  • NotImplementedError from _execute() propagates (W2.B integration not landed yet).
  • 13 tests GREEN; ruff clean.

TDD trace

  • RED commit: f63be79 — test imports fail
  • GREEN commit: 2c41188 — implementation, all 13 tests pass

Test plan

  • pytest tests/graph/wrappers/test_tool_executor.py -v → 13 passed
  • ruff check verdict/graph/wrappers/tool_executor.py → All checks passed

TimothyVang added 2 commits May 2, 2026 08:37
…C.2]

Failing test: tests/graph/wrappers/test_tool_executor.py — import fails
because verdict/graph/wrappers/tool_executor.py does not exist yet.

Assertions:
- Dispatches tool_name to the correct registered ToolWrapper subclass.
- UnknownToolError raised with informative message for unregistered tools.
- Returns a correctly-formed ToolOutput with tool_name, tool_version,
  invocation_hash (64-char blake3 hex), parsed_artifacts, stdout_sha256.
- NotImplementedError from _execute propagates (W2.B not landed yet).
- Duplicate tool_name at construction raises ValueError.
- registered_tool_names property lists all registered tools.
ToolExecutor is the second wrapper in the DenyRuleWrapper → ToolExecutor →
LedgerEmitter composition (ARCHITECTURE.md §2).

- Registry: dict[tool_name → ToolWrapper] built at construction; duplicate
  tool_name raises ValueError; UnknownToolError on unregistered dispatch.
- registered_tool_names property returns frozenset for introspection.
- run() resolves the wrapper and calls _execute(args, evidence_path, work_dir).
  NotImplementedError from _execute propagates (W2.B integration not landed).
- __call__ makes the instance directly satisfy DenyRuleWrapper's
  Callable[[str, dict], Any] executor contract with no adapter shim.
- 13 tests GREEN; ruff clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant