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

# Prose policies

> Compile YAML, JSON, or plain-English policy descriptions into the platform's policy IR.

The platform exposes `POST /api/v1/policies/compile` — a stateless adapter that turns YAML, JSON, Markdown, or English prose into a `PolicyCreate`-shaped object that the regular CRUD endpoints accept. Prose and Markdown are routed through Gemini (`gemini-2.5-flash`); YAML/JSON skip the LLM and validate directly.

The compiler **never raises** — every parse failure, schema mismatch, or missing field is returned as a structured `errors` array so the UI can render them inline.

## Endpoint

```http theme={null}
POST /api/v1/policies/compile
Content-Type: application/json

{
  "source": "Refunds over $200 must be approved by a manager. Block deletes on production tables.",
  "source_format": "prose"
}
```

`source_format` is one of `yaml`, `yml`, `json`, `prose`, `markdown`, `md`.

**Response:**

```json theme={null}
{
  "ok": true,
  "policy": {
    "name": "refund-approval-and-prod-deletes",
    "denied_actions": ["delete_production_database"],
    "require_approval": true,
    "approval_actions": ["issue_refund"],
    "approval_threshold_usd": 200.0
  },
  "warnings": [
    "policy compiled from prose by Gemini — review every field before activating"
  ],
  "errors": []
}
```

`ok` is `true` only when `errors` is empty. The returned `policy` slot is **not** persisted — POST it to `/api/v1/policies/` to save.

## YAML / JSON

Validated against the same Pydantic schema (`PolicyCreate`) used by the create/update endpoints, then re-serialized with sorted keys. Unknown top-level keys become warnings (so you can compile a partial extract from a larger document) and contradictions surface as soft warnings:

* `allowed_actions` and `denied_actions` overlap (deny wins at runtime).
* `approval_*` fields set with `require_approval=False` (approvals will not fire).

## Prose / Markdown

Calls Gemini with a system prompt that:

* Maps verbs to fields (`block`/`deny`/`forbid` → `denied_actions`; `only allow` → `allowed_actions`; `require approval` → `require_approval=True`).
* Converts amounts (`$500` → `500.0`).
* Maps prerequisites (`must look up before refunding`) into `evidence_requirements`.
* Refuses to invent action names not present in the source.

The model output is then run through the same `PolicyCreate` validator as YAML/JSON, so a hallucinated field cannot produce an invalid policy — it surfaces as a structured error.

**Environment:** the platform must have `GEMINI_API_KEY` (or `GOOGLE_API_KEY`) set. Without it, prose compiles return:

```json theme={null}
{ "ok": false, "errors": ["prose source_format requires GEMINI_API_KEY (or GOOGLE_API_KEY) to be set in the platform environment"] }
```

## Round-trip serialization

The companion helper `policy_to_yaml(policy)` (importable from `app.services.policy_compiler`) renders any policy dict back to canonical YAML — sorted keys, `None` stripped, block style. Useful for showing policies in the UI or exporting them.

## Console integration

The console policy editor calls this endpoint directly:

1. Author types/pastes prose, YAML, or JSON.
2. Editor POSTs to `/api/v1/policies/compile` on every paste/blur.
3. `errors` render as red squiggles inline; `warnings` show as yellow callouts.
4. On commit, the compiled `policy` is sent to `POST /api/v1/policies/`.

See [Console → Settings → Policies](/console/settings) for the UI-side workflow and [Concepts → Policies](/concepts/policies) for the underlying IR.

<Warning>
  Always review prose-compiled policies before activating them. Gemini occasionally invents fields the author did not request — the warning string above is your prompt to audit every key.
</Warning>

## See also

* [Concepts → Policies](/concepts/policies) — what a policy can express
* [Platform → Policies API](/platform/policies) — CRUD + sync endpoints
* [Console → Settings](/console/settings) — version history, diff, rollback
