Skip to main content

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.

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:
from brane import Decision

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

Decision Types

TypeStatusEffect
allowImplementedExecute the capability. The function runs normally.
denyImplementedBlock the capability. Raises CapabilityDeniedError.
approval_requiredPlannedPause the action until a human approves.
redactPlannedAllow execution but remove fields from output before returning it.
transform_inputPlannedMutate the input before executing.
transform_outputPlannedMutate the output after executing.
routePlannedRedirect the action to a different capability, model, or provider.
sandboxPlannedExecute with constrained access.
log_onlyPlannedAllow execution and record the action for review.

Fields

FieldTypeDescription
typestrThe decision type.
reason`strNone`Human-readable reason. Included in CapabilityDeniedError.reason.
decision_idstrUnique ID for this decision. Auto-generated.
action_id`strNone`The action this decision applies to.
policy_name`strNone`Name of the policy that produced this decision.
policy_version`strNone`Version of the policy that produced this decision.
mutations`dictNone`Mutation payload for transform/redact decisions. Planned.
approval`dictNone`Approval request payload. Planned.
audit`dictNone`Audit metadata to attach to the action record. Planned.
metadatadictArbitrary 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

Decision(type="allow")
Decision(
    type="deny",
    reason="Refund amount exceeds tenant limit of $100",
)
Decision(
    type="deny",
    reason="High-risk tool blocked in prod",
    policy_name="block_high_risk_prod",
    policy_version="1.2",
)
When using the @runtime.before_capability decorator, policy name and version are annotated onto the Decision automatically.

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.