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

# How it works

> The control plane, the two detection stages, what leaves your process, and how failures are handled.

## The pieces

<Steps>
  <Step title="Your application">
    Calls the SDK instead of, or around, your model client. The SDK builds a plain text
    view of the payload and remembers where each piece came from.
  </Step>

  <Step title="The control plane">
    Receives the text over HTTPS at `api.frostwolf.app`, inspects it, and returns a
    verdict with offsets into your own text. It never returns a rule or a pattern.
  </Step>

  <Step title="The SDK again">
    Acts on the verdict. It refuses the request, rewrites your payload from the
    offsets, or forwards it, and it does the rewriting itself.
  </Step>
</Steps>

## Two detection stages

Every payload takes two passes.

| Stage | What it is | Cost |
| - | - | - |
| Static | A compiled matcher over a curated signature set, with input normalisation | Microseconds, no network hop beyond the request |
| Semantic | A hosted model that reads the payload and names the strategy | Around 100 ms |

The semantic stage runs only when the static stage found nothing, so a payload the signatures already caught is not slowed down. Every plan runs the static stage without a limit. The semantic stage is the metered one.

See [Detection](/guard/detection) for the categories and how to read a verdict.

## What leaves your process

* The text of the payload, to the control plane, over TLS.
* With telemetry on (the default), a record per decision: the decision, severity, rule id, category, and character counts. No payload text.
* With capture on (off by default), the request and response bodies. See [Telemetry and capture](/operations/telemetry-and-capture).

## Rewriting happens on your side

The control plane returns offsets. The SDK cuts your own text at them, so a payload is never sent to FrostWolf to be rewritten. That keeps structure intact: images, provider parameters like `temperature` and `tools`, and message roles all pass through untouched, and only matched spans change.

## Failing closed

If the control plane cannot be reached, the SDK does not guess. By default a request is refused with `reason: "scan_unavailable"`, which is distinct from a detection so an outage is not mistaken for an attack. You can choose to fail open. See [Failure handling](/guard/failure-handling).

Cloak fails closed on its own account: a request it could not check for personal data is refused with `reason: "cloak_unavailable"`.

## Idempotent, non-blocking reporting

Telemetry and capture are fire-and-forget. A reporting failure goes to your `onError` callback and is never raised into the request path.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.