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

# Guardrails and safety

> Four different jobs share one word. Separating them is what makes each one enforceable.

"Guardrails" usually means a box of prompt text that asks the model nicely. That is not what this is.

Four genuinely different problems hide under the word, with different failure modes and different fixes. Bundling them produces a control that sounds thorough and stops nothing.

<CardGroup cols={2}>
  <Card title="Not being tricked" icon="shield-alert">
    Prompt injection, jailbreaks, and instructions smuggled in through content the agent retrieves.
  </Card>

  <Card title="Not promising what isn't true" icon="triangle-alert">
    Refunds it cannot authorise, dates it cannot honour, entitlements the account does not have.
  </Card>

  <Card title="Staying on topic" icon="compass">
    Your AI agent must not become a free general-purpose assistant for anyone who finds it.
  </Card>

  <Card title="Keeping personal data in place" icon="lock">
    What the agent sees, what your operators see, and what reaches analytics are three different
    answers.
  </Card>
</CardGroup>

## Injection defence is structural before it is statistical

The classifier is the smaller half.

Most defences are a model asked to spot a malicious instruction. That reduces volume, and it will always miss some. The part that makes a successful injection **un-exploitable** is architectural:

<Steps>
  <Step title="Your policy lives in one trust context" icon="file-lock">
    It is not concatenated with anything a customer or a web page supplied.
  </Step>

  <Step title="The customer's turn is clearly-delimited untrusted data" icon="quote">
    Marked as data, never as instruction. It was never going to be treated as policy.
  </Step>

  <Step title="Tool authorization reads account entitlements only" icon="key">
    **Never conversation content.** No sentence anywhere in a transcript can grant a capability,
    because the authorization check does not read transcripts.
  </Step>
</Steps>

<Info>
  **That third point is the one that matters.** A customer who successfully convinces the model it is
  in developer mode still cannot make it call a tool the account is not entitled to — the tool was
  never loaded, and the authorization check never looks at what the model believes. The classifier
  reduces how often anyone tries. The structure decides what happens when someone succeeds.
</Info>

## Typed commitments, not free text

The highest-leverage control here is not bought from a vendor.

**A commitment is never free text.** A refund amount, a promised date, an entitlement, a discount — each is a **typed field the agent fills in**, which Tied validates against your real policy before anything reaches the customer.

The agent proposing a \$400 refund where your policy caps at \$200 does not produce a smaller refund, or an apology, or a retry. It produces a validation failure, and the agent escalates.

<Check>
  **This is the one control that makes a wrong model output harmless rather than merely less
  likely.** Everything else on this page reduces probability. This changes the consequence.
</Check>

## Staying on topic

An AI agent that will happily write someone's cover letter is a cost centre with no upside. Off-topic misuse is detected, refused, and — importantly — **never billed as a resolution**. You do not pay for someone discovering your agent will explain quantum mechanics.

## When it refuses to answer

Some questions retrieve perfectly well and still must not be answered by an agent. The knowledge base contains the general rule; applying it to *this* customer is a different act.

You define the refusal categories. They are written as tests on **what a correct answer would require**, not on how the customer phrased the question:

| The answer would require… | Example |
| - | - |
| **This customer's own record** | "Is my account past due?" |
| **A recommendation** | "Should I switch to the annual plan?" |
| **A prediction** | "Will my order arrive before Friday?" |
| **Acting on the account** | "Just cancel it for me." |
| **This customer's own position** under a regime you are regulated in | Your own category, written to your own rules |

<Warning>
  **Write the category as narrowly as the questions you actually want refused.** A category's *name*
  does more work than its definition — a broadly-named category quietly pulls in questions its
  description never claimed, and a narrowly-named one lets through cases you meant to catch. This is
  measured, not theoretical: renaming a category is a behaviour change, and Tied re-measures refusal
  behaviour after any change to one.
</Warning>

Note that the first two rows stop being refusals the moment the agent can *look them up*. "Is my account past due?" is unanswerable from documentation and trivially answerable with a connected billing system. Refusal categories and [tool scope](/agents/actions) move together.

## The gates, and the order they run in

Before the agent is allowed to answer, the turn passes a fixed sequence of gates. **The first one to fire ends the turn** and hands off — so a gate lower in the list is only ever reached because every gate above it declined.

<img src="https://mintcdn.com/tied/EKg57bTFCkV_E_Je/images/diagrams/escalation-order-light.svg?fit=max&auto=format&n=EKg57bTFCkV_E_Je&q=85&s=0507f6bbc35695b505b4128485c6874d" alt="The seven escalation gates in evaluation order, and the stage each one runs at." className="block dark:hidden w-full my-8" noZoom width="900" height="562" data-path="images/diagrams/escalation-order-light.svg" />

<img src="https://mintcdn.com/tied/EKg57bTFCkV_E_Je/images/diagrams/escalation-order-dark.svg?fit=max&auto=format&n=EKg57bTFCkV_E_Je&q=85&s=82aaa23fe9282cfb2698115590c5c060" alt="The seven escalation gates in evaluation order, and the stage each one runs at." className="hidden dark:block w-full my-8" noZoom width="900" height="562" data-path="images/diagrams/escalation-order-dark.svg" />

The order is not arrangement, it is the safety property. It is why a customer asking for a person gets one even while a model provider is down, and why a question that must be refused is recorded as a refusal rather than disappearing into a generic "didn't know".

| Gate | Runs | Fires when |
| - | - | - |
| **Human requested** | Before retrieval | The customer asked for a person |
| **Provider unavailable** | Before retrieval | No model provider is reachable |
| **Budget exhausted** | Before retrieval | This conversation hit its turn or cost ceiling |
| **No knowledge** | After retrieval | Retrieval returned nothing usable |
| **Must refuse** | After retrieval | The question fell into a refusal category |
| **Not grounded** | After retrieval | What retrieval found does not actually answer the question |
| **Low confidence** | After drafting | The draft was not confident enough to send |

The three that run **before retrieval** are deliberately deterministic and involve no network call at all. A floor that can only be honoured while a provider is reachable is not a floor.

<Info>
  **"Not grounded" is the gate that catches confident nonsense**, and it exists because nothing
  cheaper works. A retrieval score threshold does not separate the cases — questions the knowledge
  base cannot answer often score *higher*, because similarity measures topical adjacency rather than
  whether the answer is present. Nor does the model's own confidence: a model confabulating an
  answer is not uncertain about it, and some of the worst cases come back at maximum confidence.

  So this gate judges the **retrieved chunks**, asked of something that did not write the draft and
  never sees one. It is reported as *no knowledge*, because to the person reading the escalation log
  "retrieval found nothing" and "what it found does not answer this" are the same fact — the corpus
  did not cover it. The two stay separable in the detail, because an empty retrieval is an outage
  and a coverage gap is something to go and write.
</Info>

<Warning>
  **"The customer asked for a person" can never be switched off.** Not per account, not per inbox,
  not by a plan, not by a setting that does not exist. It is Tied policy and it is also an Apple
  Messages for Business channel requirement — an inbox where it could be disabled would put that
  channel out of compliance. It is matched against a phrase list rather than a model call, for two
  reasons: a check that depends on a network call fails exactly when the provider is down, which is
  precisely when someone asking for a human most needs one; and "prove you always honour this" is
  answerable for a phrase list and unanswerable for a model's judgement.
</Warning>

### Fail open on money, fail closed on speech

Two failure directions, and Tied picks them separately on purpose.

| When this is unavailable | Tied | Because |
| - | - | - |
| **The billing balance check** | **Fails open** — the agent engages anyway and billing reconciles afterwards | A billing outage must never degrade a customer's agent. The accepted cost is under-billing. |
| **A safety classifier** — the refusal check, the groundedness check | **Fails closed** — the agent escalates | The accepted cost is one escalation, which is free. The alternative is inventing an answer during an outage. |

A classifier failing closed is recorded as its own distinct reason, never folded into the gate it guards. A gate doing real work and a gate failing closed look identical in a transcript and mean opposite things to anyone tuning thresholds.

That human-request check deliberately over-fires. Someone writing *"I don't want to talk to a person, just tell me the fee"* will be escalated. That is the correct direction: a false positive costs one [free](/pricing/resolutions) escalation, a false negative costs a customer who asked for a human and did not get one.

Note also that **"refusal check unavailable" is a distinct ground from "must refuse"**, on purpose. A gate doing real work and a gate failing closed look identical in a transcript and mean opposite things when you are tuning thresholds.

## Ceilings

Every conversation carries two ceilings: a **turn ceiling** and a **per-resolution cost ceiling**. Both are per-account.

They are checked before a turn spends, which means the turn that crosses a ceiling still finishes and answers — the *next* turn is the one that finds the budget exhausted and escalates. That is ordinary budget behaviour, and it means a ceiling never cuts a customer off mid-answer.

## Two tiers of personal data

| Tier | What it is | Where it lives |
| - | - | - |
| **Tier A** | Raw, scoped to your account alone | In your data region, never pooled, never crossed with another account |
| **Tier B** | Anonymised and aggregated, personal data stripped | The only tier used for any cross-account purpose |

Pseudonymisation is deterministic, so the same person is the same token every time and analytics can actually join on it — but the key that makes it deterministic never leaves Tied's application layer and is scoped per account. One account's tokens are meaningless in another's.

See [Data residency](/admin/data-residency) for where each tier is held.

## What the agent can never do

Worth stating plainly, because these are absolute rather than configurable:

* **Authorize itself.** Every action is checked outside the model.
* **Exceed your tool scope.** A tool that was not loaded cannot be called.
* **Refuse to escalate when a customer asks for a person.**
* **Bill for a conversation a human joined.** See [What counts as a resolution](/pricing/resolutions).
* **Execute a compliance-classed action** without the executed instrument on your account.

## Next

<CardGroup cols={2}>
  <Card title="Actions and tools" icon="zap" href="/agents/actions">
    The tool floor, and the three checks each action passes.
  </Card>

  <Card title="Evaluation" icon="flask-conical" href="/agents/evaluation">
    How a guardrail is proved to work before it ships.
  </Card>

  <Card title="Operations" icon="activity" href="/agents/operations">
    Watching an escalation happen and correcting the cause.
  </Card>

  <Card title="Security" icon="lock" href="/admin/security">
    Account-level controls and what Tied holds.
  </Card>
</CardGroup>


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