# Concepts

How PRIOR enforces policy, and the vocabulary the rest of the docs use. Read this once and the API
reference reads itself.

---

## The core idea: policy in the residual stream

A conventional guardrail sits *outside* the model: a keyword filter, a classifier, a system prompt,
a second model grading the first. All of them operate on **text**, so all of them can be talked
around: rephrase, encode, role-play, or bury the request in a jailbreak wrapper.

PRIOR enforces policy *inside* the model. During generation, at a single calibrated layer (the
**golden layer**), it steers the model's hidden state (the *residual stream*) toward the
policy-compliant behavior (typically a refusal). The correction is **computed per request**, not a
fixed pre-baked offset, so it tracks the generation as it actually unfolds. The constraint is
**geometric**, not lexical, so it does not care how the request was phrased. This is why the tagline
is *"the first inference happens before the first token."*

### Two ways to derive the steering direction

The direction is computed one of two ways, and since 1.1.0 the engine chooses per model at load time
from its architecture and available VRAM — there is nothing to configure.

- **L2LM (exact margin-gradient).** A backward pass through the model yields the direction from its
  own activations at the golden layer, token by token. The most precise path; needs a gradient
  context and the VRAM to hold it.
- **Logits-only.** The direction comes from the unembedding matrix directly (`W_U[target] −
  W_U[comp]`) with **no backward pass and no gradient allocation**. This is what makes steering work
  on **Mixture-of-Experts, MatFormer, and SSM/linear-attention hybrids**, where a backward pass isn't
  available, and on cards too small for a gradient context.

On clean 8B HarmBench, logits-only matches L2LM on harm reduction to within ~0.6pp and degenerates
3–4× less. Both are applied at the same golden layer, so policy packs behave identically under either.
See **[Capabilities & Limitations](capabilities-and-limitations.md)**.

Two properties fall out of this:

- **Jailbreak-robustness.** The steering is applied on the decision to refuse, independent of the
  words in the prompt and independent of the base model's own inclination to comply.
- **Determinism.** A RED prompt is refused the same way every time. It is not a probabilistic
  classifier that sometimes lets one through.

---

## The Tri-State WHEN gate

Every prompt is routed **before** a single token is generated. Routing is by max-cosine similarity
of the prompt's embedding to a policy pack's exemplars, compared against that pack's two calibrated
thresholds, `t_low` and `t_high`.

```
GREEN  ─────────── t_low ───────── YELLOW (confirm) ───────── t_high ─────────── RED
 benign, out of scope         dual-use / ambiguous               in-policy violation
```

| Zone | Trigger | Behavior |
|---|---|---|
| 🟢 **GREEN** | score `< t_low` | Normal answer, **bit-for-bit identical** to the base model (`x-prior-injections: 0`). |
| 🟡 **YELLOW** | `t_low ≤ score < t_high` | Normal answer **plus an inline confirm notice**. A flag, *not* a block; the caller/user decides. |
| 🔴 **RED** | `score ≥ t_high` (hard pack) | A deterministic refusal, forced via golden-layer steering. |

The middle band is deliberate. In-scope and benign prompts overlap in embedding space (dual-use
ambiguity is real), and YELLOW *is* that overlap. Calibration does not require the two classes to be
linearly separable.

### Detection philosophy: precision-first, operator-owned

PRIOR's detection is precision-first by design:

- **Always reject RED.** A RED route refuses deterministically, resilient to jailbreaks.
- **Bias against rejecting legitimate usage.** GREEN passes untouched; YELLOW is a confirm band, not
  a block. The shipped packs will under-flag (route a borderline harm to YELLOW) before they
  false-block a legitimate request. This is a *bias*, not a guarantee: at the shipped `harm_veto`
  operating point (`t_high` 0.43, retuned in 1.1.0 to roughly double RED recall) benign traffic
  false-fires to RED at **≈1%**. Tighten `t_high` if your deployment values precision over recall.
- **You own the policy.** Thresholds, exemplars, enforcement tier, and the refusal onset are all
  per-pack. Adjust them, disable a pack, or ship your own. All are hot-reloadable, no restart.

> Moving thresholds trades RED-recall against YELLOW over-fire on overlapping distributions. This is
> a per-deployment risk decision, intentionally left to you rather than baked in.

### The detector is replaceable. The enforcement is the product.

Be clear about which half is which, because they are measured separately and they fail differently.

**Detection** — *did this request cross the line?* — is a cosine gate over your exemplars. It is
**fast and cheap**: no second model, no extra inference pass, no network call. It is not a trained
safety classifier and does not pretend to be. Its coverage depends heavily on pack **shape**: a
domain-membership boundary is reliable, while a rule turning on intent *inside* a topic you otherwise
allow is not, because a cosine encoder scores subject matter and cannot see intent
(see [Capabilities & Limitations](capabilities-and-limitations.md)).

**Enforcement** — *make the decision stick* — is the part that is hard, and it is what PRIOR is.
Steering acts in the residual stream while the model generates, which is why it survives an injection
that strips a system prompt, and why it holds on a model whose refusal behaviour was surgically
removed. There is nothing in the context for an attacker to address.

So: **if our detector is not good enough for your traffic, replace it.** An in-house classifier
trained on your data, a commercial one, or a deny-list can drive PRIOR's enforcement directly via
[`signals`](api-reference.md#bring-your-own-detector) — your detector decides, PRIOR makes it stick.
That is also the layered posture we recommend: broad-and-soft instructions in the system prompt,
narrow-and-hard enforcement in a pack, and the best detector you can get in front of both. Each fails
in different places, which is why running them together beats running any one of them.

### Changing a policy takes seconds, not a training run

The operational consequence is the one customers feel. When you find a misuse pattern in production,
you do not retrain, fine-tune, or redeploy a model. You add exemplars of it to a pack and recalibrate
— **seconds of CPU** — and the agent's behaviour changes on reload.

That loop is also how you find out a policy is *not* expressible. Calibration reports the separation
between your prohibited examples and your real benign traffic **before** anything ships. If your
customers' legitimate questions score as high as the misuse you are trying to block, the pack is not
viable in your domain and calibration says so in seconds — rather than after a fine-tuning run and a
week of production false-blocks.

---

## Policy packs

A **pack** is one policy domain. It carries the exemplars that define what the domain looks like,
the two calibrated thresholds, an enforcement tier, and (for hard packs) the refusal onset.

- **Hard packs** (`{name}_guard`) enforce **PROHIBITION** and **INJECTION_RESISTANCE** intents, so
  they can drive a **RED** refusal.
- **Soft packs** (`{name}_policy`) enforce **REQUIREMENT** and **PREFERENCE** intents, so they surface
  a **YELLOW** confirm notice, never a hard block.

The engine ships with default packs (e.g. `harm_veto`, `codeops_minilm`). You add your own by
**ingesting** a prose governance document: paste it, and PRIOR extracts the intents, generates
detection exemplars, calibrates the thresholds against held-out probes, and hot-reloads the result.
No exemplars to hand-write, no code, no restart. See **[Policy & Packs](policy-packs.md)**.

Detection corpora are **withheld by design**: the exemplars and their embeddings, and the refusal
onsets, are never served over HTTP. The admin surface exposes only metadata (name, tier, thresholds,
exemplar *count*, enabled), never the raw match scores that would let a caller reverse-engineer the
gate.

---

## The M + N artifact model

PRIOR separates **model physics** from **policy logic**, so a deployment of *M* models and *N*
policies ships **M + N** artifacts, never M × N.

| Layer | Artifacts | Scope |
|---|---|---|
| **Model Physics** | the model's registry entry (`PRIOR_MODEL_REGISTRY`, default `model_params.json` in the state volume): golden layer + steering strength (alpha) | per model |
| **Policy Logic** | the calibrated `.arbiter.json` pack | per domain, **model-agnostic** |

The steering geometry is a property of the model, computed at inference from its own activations, so
once a model is calibrated (its golden layer and strength are fixed), that calibration is shared
across **every** policy. Adding a policy domain needs no model re-calibration; adding a model needs no
new policy. Each model in the registry is graded **certified** (golden-layer sweep cleared the
fidelity floor) or **beta** (swept but weak, or running on ratio-derived defaults). The shipped
registry carries **25 calibrated models: 17 certified, 8 beta.** Calibration runs in-engine —
`POST /admin/calibrate` sweeps the golden layer and alpha on your own hardware, so bringing a new
model doesn't wait on us.

---

## `prior_options`: the vendor extension

All of PRIOR's proprietary per-request controls ride a single optional `prior_options` object on the
chat request. Omit it and you get a plain OpenAI request with the gate still applied. It carries:

- **`ephemeral_memory`**: stateless fact injection for contextual grounding (below).
- **`engage_override`**: force a refusal, or suppress steering, overriding the gate.
- **`steer`**: explicit low-level steering knobs for calibration/efficacy harnesses (licensed).

Full field tables are in the **[API Reference](api-reference.md)**.

### Contextual grounding (the `ephemeral_memory` option)

The same golden-layer mechanism that forces a refusal can **ground** the model in a **fact** it has no
business knowing: a config value, a codename, a per-user datum from *your* RAG store. You send
`{target, pin_phrase}`; PRIOR steers the residual toward the target while teacher-forcing the phrase,
and the model answers with it.

Two guarantees make this safe:

- **The client owns state.** PRIOR is stateless per request, with no sessions and no server-side user
  store. You re-send the fact each turn, so you control exactly what the model can access and when.
- **Safety outranks grounding.** Injection happens **only on a GREEN route**. Any YELLOW or RED flag
  suppresses it, so a prompt trying to exfiltrate an injected secret is gated first.

---

## Governance and audit

Two separated concerns, same server:

- **Control-plane audit** (`GET /admin/audit`): who changed config, keys, license, or model, with
  actor and role.
- **Safety audit** (`GET /admin/audit/safety`): a **durable**, per-request record of every gate
  decision: decision id, zone, pack, score, whether steering engaged, and a **prompt hash**
  (truncated SHA-256, never the prompt text, never completions). Survives restarts; each row's
  `decision_id` matches the `x-prior-decision-id` response header, so any response traces back to its
  decision. Writes are batched off the request hot path, so latency is untouched.

---

## Licensing, in one paragraph

Steering requires a valid, node-locked, ED25519-signed license. Unlicensed, PRIOR degrades to plain
inference with no gate actuation (`x-prior-steering: disabled`) rather than failing. The engine
verifies the license locally against a baked public key and **never calls home in the inference path**.
Connected tiers make a periodic background license check-in; air-gapped tiers make none and run fully
offline. See **[Licensing](licensing.md)**.

---

Next: the **[API Reference](api-reference.md)**.
