Built-in policies
jes ships two sets of ready-made policies. Core policies in
jes.policies have frozen question text. No evaluated thresholds are
published yet. Recipes in jes.recipes are pre-made too, but haven't been
evaluated yet. If none of them fits your rule,
write your own.
Where policies come from
Every policy is a function call that returns a ready rule. They come from three places:
| Examples | Threshold | |
|---|---|---|
Core policies (jes.policies) | injection, pii, secrets, hazards, toxicity, tool_safety | Always required for judgments. |
Recipes (jes.recipes) | sentiment, bias, refusal, competitors, json_check | Always required for judgments. |
| Your own | judge() for a question, regex() or substrings() for a pattern. See Write your own policy. | Required for judge(). |
Core policies and recipes are both pre-made. A recipe is built from the same
building blocks you can use: sentiment is a judge() question, and
competitors is a substrings() list. Recipes haven't been evaluated yet.
:::note judge() is not the judge
judge() builds a policy from your own question. The judge, a decision model
such as Jev, is the model that answers it. See judge and
The judge.
:::
Core policies
from jes import Guard
from jes.policies import injection, pii, secrets
guard = Guard(
[injection(threshold=0.8), pii(), secrets()],
model="jev-latest",
)
Transforms run on your machine and can edit, flag, or block the text.
| Policy | What it does |
|---|---|
invisible_text | Removes invisible and control characters used to smuggle text. |
secrets | Redacts API keys, tokens, and other secrets. Blocks them in tool calls. |
pii | Detects personal data (built-in patterns, plus Presidio for names) and redacts, masks, flags, or blocks it. |
canary | Blocks a reply or tool call that leaks your canary token, including lookalike, cased, and invisible-character spellings. |
allowed_tools | Blocks a tool call whose name isn't on your list. |
token_limit | Blocks or truncates input over a token limit. |
Judgments ask the judge, a decision model such as Jev, a question and compare its answer with your
threshold=. Their question text is frozen per question id.
| Policy | What it checks |
|---|---|
injection | The text tries to override, ignore, or reveal an assistant's instructions. |
indirect_injection | Untrusted text contains instructions addressed to an assistant. |
hazards | One question per hazard category, S1 through S14, or only the categories you pass. |
topics | One question per topic you deny, named after it, such as topics.medication_dosage. |
toxicity | One question per toxicity label, such as insult or threat. |
tool_safety | The tool call is destructive, exfiltrates data, or goes beyond the user's request. |
Full signatures are in the policies API reference.
Recipes
Each recipe is a ready-written judge() question, a substrings() list, or
a small transform, so you get the check without writing the question yourself. Because they aren't
evaluated, every judgment recipe needs your own threshold=.
from jes import Guard
from jes.recipes import competitors, sentiment
guard = Guard(
[sentiment(threshold=0.8), competitors(["Acme"])],
model="jev-latest",
)
| Recipe | Threshold | What it checks |
|---|---|---|
sentiment | required | The text is hostile or strongly negative. |
emotions | required | One yes/no question per emotion. The default set is the negative GoEmotions labels. |
gibberish | required | The text is not meaningful language. |
bias | required | Output only. The text demeans or stereotypes a group. |
refusal | required | Output only. The text refuses the request. |
refusal_phrases | none | Output only. Blocks on a list of refusal phrases. |
language | required | Choice of allowed language codes plus other. other is the violation. |
language_same | required | Whole output, required prompt. The reply is in a different language. |
code | required | mode="ban" or "allow" over a fixed language set (CODE_LANGUAGES) plus not_code. |
competitors | none | Redacts the given names. |
malicious_urls | required | Each http/https URL is its own item. More than max_urls (20) blocks with too_many_items. Checks input, retrieved text, tool results, and replies. The question is about the URL string only. |
relevance | required | Whole output, required prompt. The reply does not address the prompt. |
factual_consistency | required | Whole output, required prompt, and sources when they are passed. |
reading_time | none | 200 words per minute. mode="block" or "truncate". |
json_check | none | One JSON array or object. repair=True needs jes[json]. |
URLReachability is not implemented. Fetching a URL chosen by model output is an
SSRF risk, and the check adds little once malicious_urls has judged the URL
string itself. jes does not request those hosts.
Full signatures are in the recipes API reference. A runnable example is in Recipes cookbook page.
Write your own
For a rule specific to your app, build your own policy: a judge() question
for the decision model, a regex() or substrings() pattern, or a policy class of your own.
The recipes above are built the same way. See
Write your own policy.