> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brane.membranelabs.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Decision

> A Decision is the output of policy evaluation.

The output of policy evaluation. What the runtime enforces.

## Definition

A Decision is what a policy returns. The runtime enforces it. There is no ambiguity: the Decision is the contract between policy and runtime.

Start with two types. That is enough to build the first control loop:

```python theme={null}
from brane import Decision

Decision(type="allow")
Decision(type="deny", reason="Only SELECT queries are allowed")
```

## Decision Types

| Type                | Status      | Effect                                                             |
| ------------------- | ----------- | ------------------------------------------------------------------ |
| `allow`             | Implemented | Execute the capability. The function runs normally.                |
| `deny`              | Implemented | Block the capability. Raises `CapabilityDeniedError`.              |
| `approval_required` | Planned     | Pause the action until a human approves.                           |
| `redact`            | Planned     | Allow execution but remove fields from output before returning it. |
| `transform_input`   | Planned     | Mutate the input before executing.                                 |
| `transform_output`  | Planned     | Mutate the output after executing.                                 |
| `route`             | Planned     | Redirect the action to a different capability, model, or provider. |
| `sandbox`           | Planned     | Execute with constrained access.                                   |
| `log_only`          | Planned     | Allow execution and record the action for review.                  |

## Fields

| Field            | Type   | Description                                  |                                                                    |
| ---------------- | ------ | -------------------------------------------- | ------------------------------------------------------------------ |
| `type`           | `str`  | The decision type.                           |                                                                    |
| `reason`         | \`str  | None\`                                       | Human-readable reason. Included in `CapabilityDeniedError.reason`. |
| `decision_id`    | `str`  | Unique ID for this decision. Auto-generated. |                                                                    |
| `action_id`      | \`str  | None\`                                       | The action this decision applies to.                               |
| `policy_name`    | \`str  | None\`                                       | Name of the policy that produced this decision.                    |
| `policy_version` | \`str  | None\`                                       | Version of the policy that produced this decision.                 |
| `mutations`      | \`dict | None\`                                       | Mutation payload for transform/redact decisions. Planned.          |
| `approval`       | \`dict | None\`                                       | Approval request payload. Planned.                                 |
| `audit`          | \`dict | None\`                                       | Audit metadata to attach to the action record. Planned.            |
| `metadata`       | `dict` | Arbitrary metadata.                          |                                                                    |

## Computed Properties

* `allowed`: `True` if `type == "allow"`
* `denied`: `True` if `type == "deny"`
* `requires_approval`: `True` if `type == "approval_required"`

## Composition Rules

When multiple policies match a capability, the engine composes their decisions:

1. No policies match: allow by default
2. Any matching policy denies: return that deny decision immediately
3. All matching policies allow: return the last allow decision by priority order

Only `allow` and `deny` participate in composition today.

## Examples

```python theme={null}
Decision(type="allow")
```

```python theme={null}
Decision(
    type="deny",
    reason="Refund amount exceeds tenant limit of $100",
)
```

```python theme={null}
Decision(
    type="deny",
    reason="High-risk tool blocked in prod",
    policy_name="block_high_risk_prod",
    policy_version="1.2",
)
```

<Note>
  When using the `@runtime.before_capability` decorator, policy name and version are annotated onto the Decision automatically.
</Note>

## Future Decision Space

The Decision type space is intentionally structured for expansion:

* `approval_required`: pause the action, send an ApprovalRequest, resume when a human approves, or deny when they reject
* `redact`: strip or mask sensitive fields from the output before returning it
* `transform_input`: mutate the input before execution
* `transform_output`: mutate the output after execution
* `route`: redirect to a different model, tool, or capability
* `sandbox`: execute with constrained network, filesystem, or time access
* `log_only`: allow but record for later review

The important property is that the decision is structured. A structured decision can be audited, composed, explained, and eventually served from a central policy system.
