> ## Documentation Index
> Fetch the complete documentation index at: https://codexceed.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# avatar.permission

PermissionPolicy — the before-tool-call control gate (§11).

An *awaited control hook*, not an observation event (§13): the runner calls it
before every execution and acts on the `ToolPermission` it returns (allow /
block / ask). It can block and redirect control flow; the event emitter cannot.
Keeping it a direct call — never an emitter subscriber — is the whole point.

Tiers (§11): 0 reads (allow) · 1 edits — str\_replace/write\_file (allow iff every
target path resolves inside the workspace) · 2 commands (allow) · 3+ destructive / external
(blocked by default in the non-interactive MVP; `ask` lands with the Phase 3 REPL).

Tier 1 is allowed for every task kind, including `investigate` (ADR-0005): transient
instrumentation is legal there, and the verifier's net-zero-diff contract — not this
gate — enforces that the tree matches the pinned baseline at verification (detection
where prevention used to be). The sensitive-path denylist and workspace confinement
still apply to every kind.

## Classes

### `PermissionPolicy`

Evaluates a tool call against the §11 tier table before it runs.

Args:
sensitive\_path\_globs: The denylist enforced over every tool's declared paths.
Defaults to the built-in set (secure by default); the runner threads the
configured `HarnessConfig.sensitive_path_globs` through.

```python theme={null}
PermissionPolicy(sensitive_path_globs: Sequence[str] | None = None) -> None
```

#### `PermissionPolicy.check(self, tool: ToolDefinition, raw_input: dict, state: TaskState, ws: Workspace) -> ToolPermission`

Return the control decision for `tool` with `raw_input` (allow / block / ask).

Tier 1 (mutation) is allowed for every task kind: investigate tasks may
instrument transiently (ADR-0005), with the verifier's net-zero-diff contract
as the enforcement point.

Args:
tool: The tool definition, carrying its `permission_tier` and declared paths.
raw\_input: The proposed tool arguments.
state: The current task state (reserved for state-aware policies).
ws: The run-scoped workspace, used for path confinement.

Returns:
The `ToolPermission` the runner acts on.

### `ToolPermission`

The gate's decision for one tool call — the runner acts on this (§11).

```python theme={null}
ToolPermission(*, blocked: bool, reason: str = '', ask: bool = False) -> None
```

**Fields**

| Field     | Type   | Required |
| --------- | ------ | -------- |
| `blocked` | `bool` | yes      |
| `reason`  | `str`  | no       |
| `ask`     | `bool` | no       |
