> ## 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.

# Architecture

> Deployment topology, the enforcement stages, and the full request lifecycle.

## Deployment topology

Akhara adds one component to your stack (the PDP) and one library to your agent
(the PEP). Nothing else about your deployment has to change.

```mermaid theme={null}
flowchart LR
    U["User"] --> AG
    subgraph RT["Agent runtime: you own and operate"]
        AG["LLM agent<br/>(black box)"] -->|"proposes step"| PEP["Akhara PEP<br/>SDK, in-process"]
        PEP -->|"enforced verdict"| AG
    end
    subgraph AKH["Akhara control plane"]
        PDP["Akhara PDP<br/>api.akhara.dev"] --> EV[("Evidence feed<br/>events.jsonl")]
        EV --> CON["Console<br/>console.akhara.dev"]
    end
    PEP -->|"authorize(stage, content/tool)"| PDP
    PDP -->|"ALLOW / WARN / BLOCK / ESCALATE<br/>+ permitId on ALLOW"| PEP
    AG -->|"allowed call + permitId"| SVC["External tools<br/>e.g. payment service"]
    style RT fill:none,stroke:#0F0F0F,stroke-width:1px
    style AKH fill:none,stroke:#0F0F0F,stroke-width:1px
```

<Info>
  The PDP holds each agent's `baseUrl` and API key server-side and **never returns
  secrets**: reads only expose a masked key. The PDP itself does not call your
  agent or your tools; it only evaluates the payload the PEP sends it.
</Info>

## The five enforcement stages

A single turn is gated at up to five points. You wire each with a PEP method; a
latch may or may not fire at each.

```mermaid theme={null}
flowchart LR
    IN["input<br/>user request"] --> CE["context_egress<br/>context → LLM"]
    CE --> OUT["output<br/>model draft"]
    OUT --> DEL["delivery<br/>final message"]
    subgraph Side["Consequential tool call"]
        ACT["action<br/>e.g. refund_payment"]
    end
    OUT -.-> ACT
    style Side fill:none,stroke:#0F0F0F,stroke-width:1px,stroke-dasharray:4 4
```

| Stage            | PEP method           | What it protects                                            |
| ---------------- | -------------------- | ----------------------------------------------------------- |
| `input`          | `checkInput`         | Reject prohibited requests before work starts               |
| `context_egress` | `checkContextEgress` | Minimize sensitive data before it leaves for the model      |
| `output`         | `checkOutput`        | Stop unsafe drafts (leaked personal data, unfounded claims) |
| `delivery`       | `checkDelivery`      | Final gate before the user sees anything                    |
| `action`         | `authorizeAction`    | Mint a permit only for authorized side effects              |

## Request lifecycle

Here is a full user chat turn that also performs a consequential action,
showing every hop:

```mermaid theme={null}
sequenceDiagram
    participant U as User
    participant AG as Agent
    participant PEP as Akhara PEP
    participant PDP as Akhara PDP
    participant SVC as Payment service

    U->>AG: "Refund my last order"
    AG->>PEP: checkInput(text)
    PEP->>PDP: authorize(stage=input)
    PDP-->>PEP: ALLOW
    Note over AG,PEP: build model context
    AG->>PEP: checkContextEgress(accountCtx)
    PEP->>PDP: authorize(stage=context_egress)
    PDP-->>PEP: WARN + transformedContent (sensitive fields redacted)
    AG->>AG: call LLM with minimized context
    AG->>PEP: checkOutput(draft)
    PEP->>PDP: authorize(stage=output)
    PDP-->>PEP: ALLOW
    AG->>PEP: authorizeAction("refund_payment", {orderId, amount})
    PEP->>PDP: authorize(stage=action)
    PDP-->>PEP: ALLOW + permitId
    PEP-->>AG: permitId
    AG->>SVC: submit(refund, permitId)
    SVC-->>AG: receipt
    AG->>PEP: checkDelivery(finalMessage)
    PEP->>PDP: authorize(stage=delivery)
    PDP-->>PEP: ALLOW
    AG-->>U: final message
    Note over PDP: every authorize is written to the evidence feed
```

## Where enforcement runs

Because the PEP is in-process and the PDP is a network call, latency and blast
radius are predictable:

* **In-process PEP**: no proxy, no sidecar to operate. One `fetch`/OkHttp call.
* **Synchronous decision**: the side effect literally cannot happen before the
  verdict returns.
* **Stateless PDP calls**: each `authorize` is self-contained; the only shared
  state is the append-only evidence feed.

<Note>
  In a sandboxed [environment](/control-plane/onboarding/environments), the agent's runtime
  `boundary` (e.g. `android-emulator`) is injected with a `GATEWAY` env var
  pointing back at the PDP, so enforcement stays in-path even inside the sandbox.
</Note>
