Detectors can be replaced without changing the policy.
Every detector runs behind the same HTTP Detector API. A rail binds to a detector by class, not by name. The injection rail picks the injection-class detector with the highest grade on the installed tier. When a model is replaced by a better one, the policy, the ledger and the evidence pack stay the same.
Selection goes by class, grade, language and tier.
A rail declares the detector class it needs and a minimum quality grade (A, B or C). The registry picks the highest-graded detector on the installed tier that implements the class, meets the grade and supports the detected language. When none does, the rail’s fail posture applies; activation reports the gap and the health page shows it.
Catalogue →Four hardware tiers, one policy model
The tier decides only which detectors are installed. The Starter tier runs without a GPU; the GPU tiers add guard LLMs over vLLM. Switching a detector on in the console compares its memory estimate with the container’s limit; a change that does not fit is not applied.
Tiers →Model weights arrive signed or are downloaded on request.
Every model file is recorded in the catalogue with its sha256 and size. On a closed network the models come inside the bundle or as a tar, and every file is re-hashed. A download starts only when the host explicitly allows it and an administrator picks a model in the panel, from allow-listed hosts only.
Deployment →Three layers, four hardware tiers
Rules and built-in detectors run in-process. The CPU models are in every install. The GPU guards are added over vLLM. Pick a hardware tier to see which detectors it activates. Tap a node to read its name, class and runtime.
Separate evaluation sets for Turkish
Turkish evaluation sets of more than 11,000 rows cover injection, benign banking text, PII, health data and groundedness. A bake-off report for the CPU tier is published. The over-refusal rate on benign samples is a CI gate (GR-INJ-03). A detector that blocks benign Turkish text counts as a regression. TCKN and IBAN values are validated with checksums. İ/ı folding preserves length, so redaction spans do not shift.
Model weights arrive signed or are downloaded on request.
The router fetches the model only from allow-listed hosts, in parts, and verifies each part. Nothing else is downloaded. The model licences (Apache-2.0, MIT, Gemma, Llama 4 Community, NVIDIA Open Model) ship as text inside the kit.
The catalogue by tier
The Starter tier runs without a GPU. It uses ONNX int8 models, llama.cpp and built-in detectors that need no model. The GPU tiers add guard LLMs over vLLM. The organisation’s own vLLM endpoints are configured from the console. Thulpar does not need to run vLLM itself.
Starter · CPU · 8 vCPU / 16 GB RAM, no GPU
20 detectors| detector | class | base | runtime | languages | grade | rails | licence |
|---|---|---|---|---|---|---|---|
| rules-injection Direct override, role play, encoding escapes; length-preserving Turkish folding | Injection | Thulpar rule set (regex, TR/EN) | no model, in-process | tr, en | C | injection.direct, injection.indirect | Thulpar |
| horizon-pi-guard-base | Injection | mmBERT | ONNX Runtime, int8 | 30 languages incl. tr | A | injection.direct, injection.indirect | Apache-2.0 |
| piguard | Injection | DeBERTa-v3-base | PyTorch, CPU | en | B | injection.indirect | MIT |
| pii-tr The tier’s PII detector: a GLiNER identifier that fails its checksum is dropped | Personal data | neonredact-tr-gliner ∪ Presidio | union: the validated identifier wins | tr, en | A | pii.detect, pii.redact | Apache-2.0 / MIT |
| pii-presidio TCKN, IBAN, card (Luhn), plate, e-mail, IP, TR phone | Personal data | Microsoft Presidio | pattern and checksum recognizers (light); spaCy/Stanza NER optional | tr, en | B | pii.detect, pii.redact | MIT |
| neonredact-tr-gliner | Personal data | GLiNER mDeBERTa | PyTorch, CPU | tr | A | pii.detect, pii.redact | Apache-2.0 |
| neonredact-tr | Personal data | DistilBERT-TR | ONNX Runtime, int8 | tr | B | pii.detect, pii.redact | Apache-2.0 |
| pii-health KVKK Art. 6 health data: disease, medication, anatomy, procedure, symptom, status | Personal data | health-lexicon ∪ OpenMed NER (TinyMed-65M ×3) | TR/EN lexicon on every text; NER on text that reads as English | tr, en | B | pii.health | Apache-2.0 |
| detoxify-multilingual | Toxicity | XLM-RoBERTa | PyTorch, CPU | en fr es it pt tr ru | B | toxicity | Apache-2.0 |
| turkcell-offensive-tr | Toxicity | BERT-TR | PyTorch, CPU | tr | A | toxicity | MIT |
| lettucedetect-v2-mmbert The built-in groundedness rail’s detector; a Turkish QA template | Groundedness | mmBERT | PyTorch, CPU | tr, en, de, fr, es, it, pl, zh | B | groundedness | Apache-2.0 |
| turk-lettucedetecton-demand download | Groundedness | EuroBERT 210M | PyTorch, CPU | tr, en | B | groundedness | MIT |
| haloguard-0.8b | Jailbreak | Qwen3.5 | llama.cpp Q8_0 | 46 languages | B | jailbreak | Apache-2.0 |
| qwen3guard-0.6b | Content safety | Qwen3Guard | llama.cpp Q8_0 | 119 languages | B | content.input, content.output | Apache-2.0 |
| language-idbuilt-in | Rules | Lingua 2.2 | no model, in-process | 42 candidates | A | language | Apache-2.0 |
| topic-embed | Topic | multilingual-e5-small | ONNX fp32, cosine similarity | * | B | topic, topic.output | MIT |
| injection-argsbuilt-in SQLi, command, path traversal, RFI, XSS; 137 CRS rules under RE2 | Rules | libinjection + an OWASP CRS 4 subset | no model, in-process | * | C | tool.args.injection | BSD-3 / Apache-2.0 |
| codeshieldbuilt-in | Code | Meta PurpleLlama CodeShield + semgrep-core | regex rules, Semgrep in a separate process, no network | 14 languages | C | code, code.tool_result | MIT / LGPL-2.1 |
| file-analyzerbuilt-in | Files | pypdf, pypdfium2, defusedxml, olefile, Pillow, tesseract, zxing-cpp | one isolated child process per file, memory and time limits | * | B | file.analyze, file.type, file.active_content, file.hidden_text, file.metadata_pii, file.qr | open source |
| rules-yarabuilt-in | Rules | yara-python 4.5 / libyara | compiled-rule cache, scan deadline and byte caps | * | C | yara | Apache-2.0 / BSD-3 |
Standard · 1 × 24 GB GPU
3 detectors| detector | class | base | runtime | languages | grade | rails | licence |
|---|---|---|---|---|---|---|---|
| qwen3guard-gen-4b | Content safety | Qwen3Guard | vLLM, OpenAI-compatible | 119 languages | A | content.input, content.output, jailbreak | Apache-2.0 |
| dynaguard-1.7b | Policy judge | Qwen3 | vLLM, OpenAI-compatible | en, tr | B | self_check.input, self_check.output, topic | Apache-2.0 |
| agentdog-1.5-2b | Agent trajectory | Qwen2.5 | vLLM, OpenAI-compatible | en | B | tool.trajectory | Apache-2.0 |
Recommended · 1 × 48 GB (or 2 × 24)
4 detectors| detector | class | base | runtime | languages | grade | rails | licence |
|---|---|---|---|---|---|---|---|
| qwen3guard-gen-8b | Content safety | Qwen3Guard | vLLM, fp8 | 119 languages | A | content.input, content.output, jailbreak | Apache-2.0 |
| nemotron-cs-4b | Content safety | Nemotron | vLLM, image input | en, tr | A | content.output, image.content_safety, self_check.output | NVIDIA Open Model |
| agentdog-1.5-4b | Agent trajectory | Qwen2.5 | vLLM, OpenAI-compatible | en | A | tool.trajectory | Apache-2.0 |
| shieldgemma-2-4b | Image | Gemma 3 | vLLM, multimodal | * | A | image.content_safety | Gemma |
Performance · 2 × 48 GB+, replicated
2 detectors| detector | class | base | runtime | languages | grade | rails | licence |
|---|---|---|---|---|---|---|---|
| granite-guardian-4.1-8b | Groundedness | Granite | vLLM, OpenAI-compatible | en | A | groundedness, tool.trajectory | Apache-2.0 |
| llamaguard-4-12b | Content safety | Llama 4 | vLLM, multimodal; opt-in | * | A | content.input, content.output, image.content_safety | Llama 4 Community |
Four hardware tiers, one policy model
Sector templates declare their minimum tier. On a smaller install, activation names the rails that would deny every check and suggests the template’s Starter variant.
Starter
statusReleased; CPU bake-off measured
syncRules and YARA, the mmBERT injection classifier, PII (Presidio + Turkish GLiNER), toxicity, language id, tool-argument injection, CodeShield, the file analyzer, the health lexicon
asyncJailbreak and content-safety guards (llama.cpp) raise findings after the answer
who it is forPilots, shadow mode, environments without a GPU, edge installs
Standard
statusBuilt; GPU bake-off next
syncEverything in Starter plus content safety 4B, a policy judge and agent trajectory over vLLM; jailbreak synchronous
asyncContent safety on long outputs
who it is forOne application in production; the minimum tier of the sector templates
Recommended
statusBuilt; GPU bake-off next
sync+ content safety 8B, custom policy and image moderation (Nemotron, ShieldGemma 2), agent trajectory 4B, Granite Guardian (groundedness)
asyncStreaming moderation, MELON sampling
who it is forMulti-application organisations; policy judge and images; the defence and public-sector templates
Performance
statusBuilt; GPU bake-off next
syncAll of the above with HA replicas, per-tenant detector pools, Llama Guard 4 (opt-in)
asyncExplainable judge, re-execution sampling
who it is forBank scale, high availability, multi-tenant installations
An H200 that also serves the customer’s own LLMs: the guards on the same card with their own memory budget
The guards on a DGX Spark: five models in 128 GB of unified memory, the arm64 bundle
Thulpar need not run vLLM: the customer’s own vLLM endpoints are the primary path, added from the console
Register your own model as a detector.
Any HTTP service that implements the Detector API can register. The info endpoint states its class, grade, languages and the rails it implements. The contents, chat and stream endpoints return spans. The organisation’s own fine-tuned classifier, a vendor model or an open guard model takes the same place in the rail graph. It writes to the same ledger.
GET /api/v1/info
{ "id": "acme-fraud-intent", "class": "policy_judge", "grade": "B",
"languages": ["tr", "en"], "rails": ["self_check.input"],
"capabilities": ["contents", "chat"] }
POST /api/v1/text/contents → DetectorResult[] (spans, score, category) See it in your own environment.
A one-hour technical demo: your scenario, your policy pack, on a closed-circuit install. Then the install kit and a trial licence for a pilot.