# `PhoenixAI.Guardrails.Pipeline`
[🔗](https://github.com/franciscpd/phoenix-ai/blob/main/lib/phoenix_ai/guardrails/pipeline.ex#L1)

Executes an ordered list of guardrail policies against a request.

Policies run sequentially. Each receives the (possibly modified)
request from the previous policy. The pipeline halts on the first
`{:halt, %PolicyViolation{}}`.

## Example

    policies = [
      {MyJailbreakPolicy, [threshold: 0.7]},
      {MyContentFilter, [pre: &sanitize/1]}
    ]

    case Pipeline.run(policies, request) do
      {:ok, request} -> AI.chat(request.messages, opts)
      {:error, violation} -> handle_violation(violation)
    end

# `policy_entry`

```elixir
@type policy_entry() :: {module(), keyword()}
```

# `from_config`

```elixir
@spec from_config(keyword()) ::
  {:ok, [policy_entry()]} | {:error, NimbleOptions.ValidationError.t()}
```

Builds a policy list from keyword configuration.

Validates options via NimbleOptions and resolves presets with
optional jailbreak overrides.

## Options

  * `:preset` — Named preset (:default, :strict, :permissive)
  * `:policies` — Explicit policy list (overrides preset)
  * `:jailbreak_threshold` — Override threshold
  * `:jailbreak_scope` — Override scope
  * `:jailbreak_detector` — Override detector module

## Examples

    {:ok, policies} = Pipeline.from_config(preset: :default)
    {:ok, policies} = Pipeline.from_config(preset: :strict, jailbreak_threshold: 0.5)

# `preset`

```elixir
@spec preset(:default | :strict | :permissive) :: [policy_entry()]
```

Returns a named preset policy list.

## Presets

  * `:default` — JailbreakDetection only (minimal safety)
  * `:strict` — All three policies (maximum protection)
  * `:permissive` — JailbreakDetection with high threshold (reduced false positives)

# `run`

```elixir
@spec run([policy_entry()], PhoenixAI.Guardrails.Request.t()) ::
  {:ok, PhoenixAI.Guardrails.Request.t()}
  | {:error, PhoenixAI.Guardrails.PolicyViolation.t()}
```

Runs an ordered list of policies against a request.

Returns `{:ok, request}` if all policies pass, or
`{:error, %PolicyViolation{}}` on the first halt.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
