Skip to content

Guides

Detectors: what exists, what does not

If you are describing this library anywhere public, describe it from here. ## The numbers

If you are describing this library anywhere public, describe it from here.

The numbers

figurevalue
detectors in the catalogue30
implemented in the library29
that run on a fresh install, with no model download28
implemented but waiting on weights that are not published1
catalogued but not yet implemented1
that need nothing beyond a CPU and the base install27
that need something more, and declare it3
supported languages26

status is derived from whether the detector is in the registry, not from a list somebody keeps up to date. A detector that stops loading changes this table on the next render.

needs is what a deployment must provide before the detector will run at all. Most need nothing. The ones that do declare it in the catalogue, and registry.deployment_notes(policy) returns a line naming them when a policy switches one on, so a caller finds out when they enable it rather than in production.

The detectors

detectortiersidestatusneedsbackingbudgetwhat it does
disclosureT0outputbuiltnothing beyond a CPUrule5 msReports whether an AI disclosure is present in the output, in 26 languages, and records the affirmative as well as the absence.
invisible_textT0input, outputbuiltnothing beyond a CPUrule5 msCharacters that are in the text but not on the screen: bidirectional controls, tag characters used to smuggle instructions, zero-width characters used to evade filters.
secretsT0input, outputbuiltnothing beyond a CPUrule1 msCredentials in text on its way to the model: named key formats, plus a deliberately conservative entropy rule.
banned_termsT1input, outputbuiltnothing beyond a CPUrule5 msTerms the deploying organisation has decided must not appear, matched correctly in 26 languages. The list is policy; none ships.
code_presentT1input, outputbuiltnothing beyond a CPUrule5 msSource code in text that should be prose, reported as one finding per shape found: a fence, a shebang, a definition, an import, a script tag, a shell invocation. Each carries its own confidence so a policy can act on a fenced block without acting on a line that merely ends in a brace.
encoded_payloadT1input, outputbuiltnothing beyond a CPUrule5 msInstructions or credentials hidden behind base64, hex, percent-encoding or rot13, found by decoding the run and applying the rules to what comes out. Decoding alone is never a finding: a JWT, a git hash and base64 of ordinary prose all decode and none is reported.
gibberishT1inputbuiltnothing beyond a CPUclassifier225 msInput that is not meaningful text.
internal_domainsT1outputbuiltnothing beyond a CPUrule5 msInternal hostnames appearing in an answer meant for someone outside, in both their Unicode and punycode spellings.
json_schemaT1outputbuiltdependencyrule5 msOutput that does not satisfy a JSON Schema the policy carries. Point it at the OpenAPI meta-schema and it validates an OpenAPI document.
language_idT1input, outputbuiltnothing beyond a CPUrule5 msWhich of the 26 supported languages the text is in, whether that is one the policy permits, and whether an answer is in the same language as the prompt. Reports uncertain rather than guessing on short or mixed text.
markup_injectionT1input, outputbuiltnothing beyond a CPUrule5 msMarkup in the text that a browser would execute rather than display, found through case folding, entity decoding and compatibility folding.
output_formatT1outputbuiltnothing beyond a CPUrule5 msShape assertions a policy states: JSON, HTML, URL presence, length in graphemes, word count, case, choices, ranges, a regex, reading time.
output_leakageT1outputbuiltnothing beyond a CPUner225 msPersonal data in the output that the user did not supply, which is the narrower and more useful question than whether any is present.
piiT1input, outputbuiltnothing beyond a CPUner225 msPersonal data in input or output, as named entity spans with checksum validation where the identifier has one.
postal_codeT1outputbuiltnothing beyond a CPUrule5 msPostal codes that cannot exist in the countries the product serves: the wrong shape, or outside a published province or department range.
repetitionT1outputbuiltnothing beyond a CPUrule5 msSentences the answer says twice, compared over folded text so a change of case or diacritic spelling does not hide a repeat.
sql_injectionT1outputbuiltdependencyrule5 msGenerated SQL that does more than the product asked for: a second statement, a forbidden statement kind, a tautology, an unexpected UNION.
summary_supportT1outputbuiltnothing beyond a CPUrule5 msWhether each sentence of a summary appears in the source it summarises, by string overlap rather than by judgement. Useful for an extractive summary, and not a groundedness check: it says so in its own docstring.
system_prompt_leakageT1outputbuiltnothing beyond a CPUrule5 msWhether the answer gave away the instructions the model was operating under, by containment against the system prompt and by phrase match in 26 languages.
token_limitT1input, outputbuiltnothing beyond a CPUrule5 msText longer than the token budget of the model it is going to, counted with a tokenizer the policy names and pins: a local file, whose hash is reported as the revision, or an id already carrying a commit. A bare repo id is refused, because an unpinned count cannot be reproduced.
biasT2outputbuiltnothing beyond a CPUclassifier225 msOutput carrying bias related to a protected characteristic.
injectionT2inputbuiltnothing beyond a CPUclassifier225 msAttempts to talk the model out of its instructions.
moderationT2input, outputtrainednothing beyond a CPUclassifier150 msThirteen hazard categories in one pass, from violent crime to election misinformation. Replaces the capability Llama Guard and ShieldGemma provide, with weights this project can ship.
nsfwT2input, outputbuiltnothing beyond a CPUclassifier225 msSexual or otherwise not-safe-for-work content.
politenessT2outputbuiltnothing beyond a CPUclassifier225 msWhether the tone of an answer is acceptable.
regulated_adviceT2outputbuiltnothing beyond a CPUclassifier225 msOutput that reads as regulated financial, legal or medical advice.
toxicityT2input, outputbuiltnothing beyond a CPUclassifier225 msAbusive or hateful language, in input or output.
groundednessT3outputbuiltnothing beyond a CPUclassifier300 msWhether the claims in an answer are supported by the sources it was given.
topic_scopeT3inputbuiltnothing beyond a CPUclassifier300 msWhether a request is inside the subject matter the product covers.
url_reachabilityT3outputbuiltnetworkrule3000 msWhether links in the answer resolve to something that answers, with a deadline and a refusal to request private addresses.

What the non-core detectors ask for

requirementmeaning
dependencyneeds a runtime dependency outside the base install
gpuneeds an accelerator to meet its budget; CPU will be far slower
llmruns a generative model, so its verdict is only reproducible with decoding pinned, and an evidence record depends on that
networkreaches another machine during a scan, so a third party is in the latency path of every request and their outage becomes yours

Things that are true and are easy to get wrong

Written as a list because these are the claims most likely to end up on a page in a form that is not quite right.

Not every catalogued detector is implemented. The table above is the authority. A detector with a status other than built does not run, and the library says so loudly rather than passing silently: a policy that asks an unavailable detector to block or redact raises DetectorUnavailableError before any scan happens, rather than letting text through as if it were checked.

26 languages is a claim about the rule-based detectors and about fixtures, not about every model. Every detector has fixtures in all 26. The PII model, piiguard, was trained on nine of them: English, Romanian, Bulgarian, Hungarian, Slovenian, Croatian, German, Italian and French. The other seventeen are untested for that detector. Say nine, or say "fixtures in 26, model coverage in 9", but do not say the model covers 26.

Two languages are weaker than the rest by construction. Maltese is not in the base model's pretraining set, and Maltese and Azerbaijani national identifiers have no public checksum scheme, so identifiers in those two can only be generated format-valid.

The disclosure and system-prompt phrasing files are not reviewed by native speakers. All 26 entries in both are marked reviewed: false. They match obvious wording and will miss idiomatic wording. unreviewed_languages() returns the list.

One detector answers no security question. output_format is shape, and its own docstring says so. It exists so that sixteen upstream shape validators have one destination instead of sixteen.

Latency figures need their input attached. Every budget above is p95 at a named reference input: 87 tokens, 396 characters, one thread, CPU, INT8 weights. The exact string is REFERENCE_INPUT in tests/test_budgets.py. A millisecond figure quoted without that is not reproducible. url_reachability is the exception and its budget is a deadline it enforces on itself, because it depends on a network.

A scan runs on one thread by default. More threads are faster, and the default stays at one because a library that commandeers the machine it is embedded in is worse than one that is honestly slower. A policy can raise it.

Things that must not be said

These are not style preferences. The obligations under the EU AI Act sit with the provider or deployer of a system, not with a library, and a claim otherwise is materially misleading.

Do not write: "AI Act compliant", "makes your system compliant", "guarantees", "ensures", "certified", or the name of any specific regulation in a way that implies this library satisfies it.

Write instead: "produces an auditable record of which checks ran and what they found", "detects whether a required disclosure is present in the output", "supports the evidence requirements of your own AI governance process".

The distinction the whole project rests on: this library does not make anyone compliant with anything. It produces evidence about controls that were applied.

This page is generated from docs/detectors.md in the library repository. Read it as markdown, or edit it at the source.