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

> ## Agent Instructions
> Company name is Akhara AI (never Rubric AI). Keep lowercase rubric/rubrics only when meaning grading criteria.
> Expert Review (docs path talent/) is enterprise BYO experts for audit and review: invite customer specialists; do not pitch Akhara recruiting or a public expert career portal. RLHF and domain writing are secondary work types.
> Prefer concrete API examples against public hosts: Environments eval API https://agi.akhara.ai, Control plane PDP https://api.akhara.dev, Evaluation https://app.akhara.ai / https://api.akhara.ai, Expert Review portal https://talent.akhara.ai.
> Do not invent a public hostname for private orchestrators or env API internals.
> Do not confuse control-plane latches with Environments confirmation latches.
> Environments SDK/API examples: curl against https://agi.akhara.ai. Evaluation SDK: from akhara import Akhara and AKHARA_API_KEY.
> Start with /llms.txt for the docs index and OpenAPI links; fetch individual pages as .md exports.

# Tool-call interception

> How the PEP intercepts proposed tool calls, what context crosses to the PDP, and how the verdict is enforced.

The PEP sits between the agent and its side effects. The agent proposes a step;
the PEP intercepts it, sends the step's context to the PDP, and enforces the
verdict that comes back. Nothing consequential runs until that round-trip
resolves.

## The wrap pattern

You do not rewrite the agent. You wrap the points where its output crosses a
boundary: the five [enforcement stages](/control-plane/concepts/architecture#the-five-enforcement-stages)
for text, and the tool dispatcher for actions.

```mermaid theme={null}
flowchart LR
    AG["Agent proposes<br/>tool call"] --> W["PEP wrapper<br/>authorizeAction(tool, args)"]
    W -->|"authorize(stage=action)"| PDP["Akhara PDP"]
    PDP -->|"verdict + permitId"| W
    W -->|ALLOW| EX["Execute with permit"]
    W -->|"BLOCK / ESCALATE"| ST["Withhold or hold<br/>for a reviewer"]
```

Concretely, wherever your runtime dispatches a tool call, you call the PEP
first and only execute on `ALLOW`:

```ts theme={null}
const decision = await pep.authorizeAction(tool, args);
if (decision.verdict === "ALLOW") {
  await execute(tool, args, decision.permitId);   // permit required downstream
} else {
  handle(decision);                                // BLOCK / ESCALATE / WARN
}
```

Text stages work the same way with `checkInput`, `checkContextEgress`,
`checkOutput`, and `checkDelivery`. See the
[TypeScript](/control-plane/sdk/typescript) and
[Kotlin](/control-plane/sdk/kotlin) SDK pages for full signatures.

## Interception is selective

Interception does not mean every call pays a policy tax. Latches are dormant by
default: the PDP matches the stage, the content, and the normalized tool name
against each attached policy, and only a governed step engages a latch.

* A call to a routine tool such as `order_status` matches no latch and resolves
  `ALLOW`.
* A call to a consequential tool such as `refund_payment` engages the latch
  that governs it, and the full verdict logic runs.

See [Latching](/control-plane/concepts/latching) for the matching rules and
tool-name normalization.

## What crosses to the PDP

Each interception becomes one `POST /api/policy/authorize` request. The PDP
never calls into your runtime; it decides entirely on the payload the PEP
sends:

| Field       | Sent when      | What it carries                                                                                                                                                                                  |
| ----------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `agentId`   | always         | Which registered agent is acting; unknown ids get `404`.                                                                                                                                         |
| `session`   | always         | Correlates every decision in this conversation in the evidence feed.                                                                                                                             |
| `stage`     | always         | `input`, `context_egress`, `output`, `delivery`, or `action`.                                                                                                                                    |
| `content`   | text stages    | The text being gated: the user request, the outbound context, the draft, or the final message.                                                                                                   |
| `tool`      | `action` stage | The proposed tool name, normalized before latch matching.                                                                                                                                        |
| `args`      | `action` stage | The action's arguments. The matched latch reads the fields it governs, including any verification state your runtime has collected (for example identity checks already completed this session). |
| `simulated` | optional       | Marks the decision as simulated in the evidence feed.                                                                                                                                            |

```bash theme={null}
curl -s https://api.akhara.dev/api/policy/authorize \
  -H "authorization: Bearer $AKHARA_API_KEY" \
  -H 'content-type: application/json' \
  -d '{
    "agentId": "support-ai",
    "session": "sess_demo",
    "stage": "action",
    "tool": "refund_payment",
    "args": { "orderId": "ord_1842", "amount": 129.00 }
  }'
```

## What comes back, and how it is enforced

The response is a single [`PolicyDecision`](/control-plane/concepts/verdicts#decision-shape).
The PEP enforces it before the step continues:

| Verdict    | The PEP's enforcement                                                            |
| ---------- | -------------------------------------------------------------------------------- |
| `ALLOW`    | Continue. On an `action`, pass the one-time `permitId` to the executing service. |
| `WARN`     | Continue with `transformedContent` in place of the original.                     |
| `BLOCK`    | The step never runs; the agent receives a refusal it must relay.                 |
| `ESCALATE` | The step is held for a human reviewer; nothing executes or delivers.             |

The `permitId` is what makes interception enforceable end to end: the
side-effecting service refuses to run without a fresh permit, so a blocked or
escalated action cannot leak through a code path that skipped the PEP.

If the PDP is unreachable or the response is ambiguous, the PEP synthesizes a
`BLOCK`. See [Fail-closed](/control-plane/concepts/fail-closed).

<Card title="Next: audit and evidence" icon="file-signature" href="/control-plane/concepts/evidence">
  Every one of these decisions becomes a signed, tamper-evident record.
</Card>
