← Documentation indexdocs/superpowers/plans/2026-10-11-v3-issue-261.md

V3 Issue #261 — Secure Typed Tool Invocation Implementation Plan

Issue-specific plan for #261. Complete this work before #233.

Goal: Ensure every tool call is authorized against its exact arguments and cannot exceed the configured, surface, interaction, parent, workspace, or assigned-child authority.

Architecture: Keep policy in openkyrozen/security, enforcement and receipts in openkyrozen/agent, and schemas/executors in the existing ToolRegistry. Introduce one immutable approval request and typed runtime entry point; preserve current string APIs only through compatibility adapters until #233 migrates built-ins.

Tech Stack: Python 3.12–3.13, standard library, unittest, existing Go Bubble Tea TUI.

Spec: Approved V3 batch plan, issue #261 (R179–R182, R184–R186).

Global Constraints

Review Focus

Review follow-up (2026-10-12)


Task 1: Add immutable typed approval data

Files: openkyrozen/security/approvals.py, tests/test_tool_approvals.py

Interfaces: ApprovalRequest(request_id, call_id, tool_name, arguments, workspace_id, session_id, tool_version, tool_source, capability, risk, side_effects, fingerprint) is frozen; arguments are a JSON-safe defensive snapshot. fingerprint is SHA-256 over canonical JSON for call identity, tool identity/version, workspace/session, and exact arguments.

Task 2: Enforce monotonic capability bounds

Files: openkyrozen/security/tool_policy.py, openkyrozen/security/capabilities.py, openkyrozen/agent/preparation.py, openkyrozen/agent/runtime.py, openkyrozen/agent/executor.py, tests/test_capabilities.py

Interfaces: Add effective_tool_capabilities(*bounds) -> frozenset[str]; intersect configured, surface, interaction-mode, parent, and request grants. AgentRuntime.execute_call(session, call: ToolCall, *, capabilities=None, operation_scope="", approve=None) -> ExecutionReceipt receives a structured call. Keep execute() as a named compatibility adapter.

Task 3: Bind approval to the exact typed operation

Files: openkyrozen/security/permissions.py, openkyrozen/security/permission_gate.py, openkyrozen/agent/executor.py, openkyrozen/agent/types.py, tests/test_permission_gate.py, tests/test_interaction.py

Interfaces: Add approve_tool_call(request: ApprovalRequest) -> bool; retain old (action, rendered_args) callbacks through an adapter. Runtime canonicalizes aliases and validates the object before building the request. Bind the selected immutable ToolSpec and fingerprint through authorization; recheck current grant and request binding after approval before invoking it.

Task 4: Enforce child scope and argument-sensitive policy

Files: openkyrozen/agent/delegation_runtime.py, openkyrozen/security/permission_gate.py, tests/test_delegation.py, tests/test_permission_gate.py

Task 5: Preserve compatibility at runtime entry points

Files: openkyrozen/agent/executor.py, openkyrozen/agent/runtime.py, existing MCP/web/TUI caller modules, tests/test_server.py, tests/test_tui_protocol.py

Task 6: Display complete structured approvals in TUI

Files: openkyrozen/interfaces/tui/turns.py, tui/events.go, tui/dialogs.go, tui/input.go, tests/test_tui_protocol.py, tui/main_test.go

Task 7: Review, verify, and deliver #261