Defined in approval_manager.py:31. See approval_manager/api.md for the canonical definition.
| Mode | Allows writes? | Plan required? | Approval prompts? |
|---|---|---|---|
READ_ONLY |
No | N/A | No |
WORKSPACE_WRITE |
Yes | Yes (default) | Yes |
PROMPT |
Yes | Optional | Yes |
ALLOW |
Yes | Optional | No |
DANGER_FULL_ACCESS |
Yes | No | No |
Location: governance/plan_gate.py:36
def assert_write_allowed(
*,
tool_name: str,
permission_mode: PermissionMode,
context: dict[str, Any],
require_plan: bool,
skip_plan_check: bool = False,
) -> NonePre-conditions:
tool_nameis a known write tool or arbitrary string (non-write tools always pass).contextis the current agent context dict.
Post-conditions:
- Returns
Noneif write is allowed. - Raises
ToolPermissionErrorwith an actionable message if blocked.
Gate logic:
if tool_name not in WRITE_TOOLS: return (pass)
if permission_mode not in _PLAN_MODES: return (pass — READ_ONLY blocks at higher level)
if skip_plan_check: return (explicit override)
if WORKSPACE_WRITE and not require_plan: raise (strict default)
if require_plan and not _has_plan_contract(context): raise
Constants:
WRITE_TOOLS = frozenset({
'workspace_write_file',
'workspace_apply_patch',
'workspace_edit_at_hash',
})Location: governance/audit_completeness.py
def check_audit_completeness(events: list[AuditEvent]) -> list[str]Returns list of missing required event type names. Empty list = complete.
Required event types: run_started, run_completed (or run_failed).
Location: governance/tool_lint.py
def lint_tool_registry(registry: ToolRegistry) -> list[str]Returns list of violation strings. Empty list = no violations.
Checks performed:
input_schemais a valid JSON Schemaobjecttype- No contradictory annotations (
read_only=True, destructive=True) - Tool names match
[a-z][a-z0-9_]*pattern
# Stored in agent context under context['plan_contract']
{
"content_hash": "sha256hex", # SHA-256 of plan content
"path": "/path/to/plan.md", # optional
"created_at": "ISO 8601", # optional
}