# `Pixir.Permissions.WritePolicy`
[🔗](https://github.com/Ranvier-Technologies/pixir/blob/main/lib/pixir/permissions/write_policy.ex#L1)

Bounded write policy for headless executor/delegate runs.

The policy is deliberately narrower than `:auto`: it only authorizes `write` and
`edit` against canonical workspace-relative paths, keeps unsafe shell disabled, and
fails closed when paths or rules are ambiguous. It is a runtime object carried in
`context.permission.policy`, not a replacement for the existing permission-mode atom.

# `allows_global?`

```elixir
@spec allows_global?(map() | nil) :: boolean()
```

Whether a policy explicitly allows the whole workspace.

# `authorize_tool`

```elixir
@spec authorize_tool(map() | nil, String.t(), map(), String.t()) ::
  :allow | {:deny, map()} | {:error, map()}
```

Authorize one tool call under a bounded write policy.

# `canonical_relative`

```elixir
@spec canonical_relative(String.t(), String.t()) ::
  {:ok, String.t()} | {:error, map()}
```

Canonical workspace-relative target for policy checks.

# `from_file`

```elixir
@spec from_file(String.t(), String.t()) :: {:ok, map()} | {:error, map()}
```

Load and normalize a bounded write policy JSON file.

# `from_metadata`

```elixir
@spec from_metadata(map() | nil) :: {:ok, map() | nil} | {:error, map()}
```

Rehydrate a runtime policy from safe metadata previously written to the Log.

The hash is recomputed from the canonical durable fields before the metadata is
trusted. A mismatch means the Log projection was altered or came from an incompatible
hash format and therefore fails closed.

# `metadata`

```elixir
@spec metadata(map() | nil) :: map() | nil
```

Machine-readable policy metadata safe for CLI/delegate JSON output.

# `narrow_to_write_set`

```elixir
@spec narrow_to_write_set(map(), [String.t()]) :: {:ok, map()} | {:error, map()}
```

Return a policy narrowed to the given write set.

# `normalize`

```elixir
@spec normalize(
  map(),
  keyword()
) :: {:ok, map()} | {:error, map()}
```

Normalize a bounded write policy map and compute stable metadata.

# `rules_cover_path?`

```elixir
@spec rules_cover_path?([String.t()], String.t()) :: boolean()
```

Whether a workspace-relative path is covered by one of the given allow-style
rules. Public single source for the policy glob semantics (#284 F2: the
workflow apply step's write_set bound delegates here instead of hand-rolling
a second matcher).

# `validate_path_rules`

```elixir
@spec validate_path_rules([String.t()], String.t()) :: :ok | {:error, map()}
```

Validate a list of allow/deny path rules against the policy glob grammar.

# `validate_write_set_within_policy`

```elixir
@spec validate_write_set_within_policy(map(), [String.t()]) :: :ok | {:error, map()}
```

Validate that every write_set rule is within a parent policy allow rule.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
