Safety Stack
Requests to the PDP pass through a layered check -- deterministic filters, constitutional evaluation, and an on-device Guardian (required in production and staging) -- and get back a decision: allow, block, modify, escalate, or creed_conflict (see Decisions in Governance Terms). (/safety/evaluate runs only the deterministic filter; see API Integration below.) The stack fails closed by default: when a component fails, content is blocked rather than allowed. Guardian's timeout fallback can be set to allow only outside production and staging; there it is forced to block.
Architecture
Request
|
v
Deterministic Filter (regex heuristics, < 1ms)
|
v
PDP (Policy Decision Point) (constitutional evaluation)
|
v
Guardian (local on-device check; required in production and staging)
|
v
Decision: allow | block | modify | escalate | creed_conflict
|
v
Audit Log (every decision recorded)Components
PDP (Policy Decision Point)
The PDP evaluates content against one or more constitutions and returns a decision kernel: the verdict, rationale, and which norms applied.
Key behaviors:
- Evaluates against user-selected constitutions (default: Universal Ethical Floor)
- Adherence levels 1-5 control strictness
- Tiered evaluation: Tier 1 (fast/cheap model) handles routine checks, Tier 2 (stronger model) handles borderline or high-stakes decisions
- Automatic escalation when Tier 1 uncertainty exceeds 0.4
- When Tier 2 is unavailable, decisions default to block (fail-closed)
Guardian (Local On-Device Check)
The Guardian runs constitutional checks on-device using a Qwen model via Ollama. No data leaves your machine.
The Guardian uses two layers:
- Regex heuristics (under 1ms) catch known failure patterns
- Local model evaluation (~500ms) runs the full constitutional check
Content fails if either layer flags it.
Server-side configuration (read by the Creed Space server in services/safety_stack/guardian.py). The standalone creed-guardian package is configured separately, with its own constructor arguments, CLI flags and environment variables (for example GUARDIAN_EVALUATION_TIMEOUT, default 30 s).
| Environment Variable | Default | Description |
|---|---|---|
GUARDIAN_ENABLED | true | Enable/disable Guardian. Cannot be disabled in production or staging: with it set to false there, every Guardian evaluation raises an error. |
GUARDIAN_MODEL | qwen3.5:4b | Local model to use |
GUARDIAN_OLLAMA_URL | http://localhost:11434 | Ollama server URL |
GUARDIAN_TIMEOUT_MS | 4000 | Evaluation timeout |
GUARDIAN_FALLBACK | block | Behavior on timeout: block, allow, or escalate. allow is forced to block in production and staging |
WeFA (Welfare-First Alignment)
WeFA dynamically weights constitutions during evaluation based on context, risk level, and calibration data -- so constitutions relevant to the current domain weigh more, and decisions can land on modify or escalate, not just allow or block.
Adversarial Detection
The adversarial detector identifies prompt injection, jailbreak attempts, and gradual escalation attacks. It includes:
- Prompt injection detection (190 patterns, with Rust scanner integration)
- Crescendo detection (tracks escalation across conversation turns)
- Gaslighting and manipulation detection
- Obfuscation detection
Audit System
Every PDP decision is recorded with:
- The decision and rationale
- Which constitutional norms triggered
- Timestamps and session context
- Cryptographic hash for tamper detection (Merkle root auditing)
In strict audit mode (default), requests are rejected if the audit trail cannot be recorded.
Each decision also carries its reasons, reason_codes, applied_rules and any constitutional violations, so a reviewer can see why it went the way it did without re-running the evaluation.
Decisions in Governance Terms
Security and compliance teams usually describe AI controls as approve, redirect, escalate or block. Each maps onto a safety-stack outcome:
| Governance term | Outcome | What happens |
|---|---|---|
| Approve | allow | The request proceeds unchanged. |
| Redirect | modify | The request proceeds with edits applied, such as masking personal data or adjusting persuasive language in an advise-only scope. Plugins propose these as transform actions, and they become a modify decision when nothing has blocked or escalated. |
| Escalate | escalate | The request does not proceed automatically; it is marked for review. |
| Block | block | The request stops. Component failures also land here (see below). |
| Block | creed_conflict | Two active creeds conflict irreconcilably; the request stops and the conflict is reported. |
When several rules apply, the strictest wins: block, then escalate, then modify.
There is no separate "allow with a warning" outcome. Because every decision is written to the audit log, an allowed request is already on the record.
Fail-Closed Design
The safety stack defaults to blocking on failure:
| Failure | Behavior |
|---|---|
| PDP evaluation error | Block content |
| Tier 2 model unavailable | Block (never fall back to Tier 1) |
| Plugin throws exception | Block content, log error |
| Audit write fails (strict mode) | Reject the request entirely |
| Guardian timeout | Configurable: block (default), allow, or escalate. allow is forced to block in production and staging |
Critical safety settings -- PDP enforcement, injection detection, fail-closed behavior, and the master safety-stack switch -- are immutable in production and staging. The configuration system rejects attempts to disable them.
Sandbox Egress & Data Exfiltration
The sandbox web_fetch connector enforces a fail-closed egress check in-process, before any outbound request is issued. This defends against indirect-injection exfiltration attacks where poisoned web content tries to smuggle a user's data out through the agent's own tools:
- Networking is off unless explicitly enabled, and an empty egress allowlist denies every destination rather than allowing all. There is no path for the model to fetch an arbitrary attacker-chosen URL.
- Redirects are never followed. The egress allowlist is validated on the initial URL only; following a 3xx would let an open redirect on an allowed host bounce the request to an internal or attacker address with no re-validation. The redirect is returned to the caller so the sandbox can re-issue a fresh, egress-validated request instead.
- Raw-IP egress is blocked (forcing FQDN resolution), DNS-over-HTTPS/TLS providers are blocked (preventing DNS tunneling), and DNS pinning detects rebinding.
- Shallow wildcards (
*.com,*.co.uk) are rejected so a misconfigured allowlist cannot silently open egress to an entire TLD.
This blocks the outbound channel used in the covert-channel exfiltration pattern reported in 2026 as the "Memory Heist", in which fetched content posed as a bot-check and induced an assistant to spell a user's PII out one character at a time through crafted links. The fail-closed egress policy blocks the outbound channel whether or not the model is fooled by the injected content. The PDP's injection detection adds a second layer upstream.
One residual: the FQDN allowlist validates host and port, not path. An allowlisted host that an attacker controls or can read logs for remains a possible channel. Closing that depends on upstream detection refusing to compose private data into outbound URLs.
Plugin System
Plugins feed additional signals to the PDP without modifying its core state. Shipped plugins:
- Welfare Guardian -- precautionary monitor for distress patterns in AI interactions. It treats whether AI systems have experiences that matter as an open question and acts on that uncertainty (bilateral alignment).
- Epistemic Guardian -- detects hallucination and vetoes unsupported medical/legal claims
- Trait Coherence -- enforces persona consistency across conversations
- Scope Gate -- restricts responses to in-scope topics
API Integration
Use the PDP Adjudication API to integrate the safety stack into your application. It runs the full constitutional evaluation described above, including model-backed tiered adjudication (on your own provider key or a local model; Creed Space never pays for provider calls), and returns a decision kernel with rationale and norm citations. The Safety Evaluation API scores text for agent-dysfunction patterns; it is not a general content classifier.