Agent Trust & Assurance · A visual story

The Life of a
Uderia Agent

An answer you can trust is not an accident. It is earned twice — once when the agent is signed, and again on every turn, as it is observed, enforced, proved — and then kept in check, as its own conduct feeds back into the badge. This is that story, told from the outside in.

Born Composed Signed Runs Observed Enforced Proved Kept in check
Read it like an onion. Every panel opens in plain language. Click peel → to reveal the mechanism, then peel deeper → for the full technical detail — the crypto, the files, the tables. Peel only as far as you care to.
Act I

Born, then trusted — signing an agent

Trust in Uderia is a badge on the agent, not a promise in a document. A signed agent is trusted exactly when its whole composition is — every part it is made of must itself be signed and intact. You build trust from the inside out; you read it from the outside in.

① THE BADGE — 🟢 trusted · verifiable ② COMPOSE — the bottom-up gate ③ VALIDATE — 10 signable kinds ④ SIGN — Ed25519, content-bound INGREDIENTS ontology · skills Click a ring to peel to its layer.

Signing runs core → out: validate & sign each ingredient, then the agent. You read it out → core: the badge you see, and everything true beneath it.

Mechanism

Unsigned

Nobody has attested it. The default state of everything — a byte-identical baseline. Sharing still works; trust is simply not yet claimed.

Trusted

Signed and its content still matches what was signed. For an agent, this also means every ingredient is trusted too.

Changed

Signed once, but the content has drifted since. Tamper-evident: any edit flips 🟢 → 🟠 automatically.

Badge, not gate. Trust is shown and verifiable; by default it informs rather than blocks. Sharing an agent stays completely open — the badge tells a consumer what they are getting; it does not lock the door.

Detail

Trust is computed, never re-derived. The state is resolved on read from two facts: does a valid signature exist, and does the live content hash still equal the signed one. There is no separate "trust database" to fall out of sync.

The whole capability ships inside the physically-isolatable Ontology Suite, governed by one switch (core/enterprise.py). With no attestations present, every artefact is ⚪ and nothing about the platform changes.

Full detail · guarantees
  • Byte-identical baseline — no attestations ⇒ every artefact ⚪; behaviour is unchanged.
  • Tamper-evident — any content edit flips 🟢 → 🟠 via hash mismatch, with no re-signing.
  • Offline-verifiable — an Ed25519 signature verifies with only the signer's public key, no server call.
  • Trust ≠ access — a signed artefact is validated, not authorized; secrets never travel with it.

Reference: TRUST_MEMBRANE_ARCHITECTURE · module core/trust/ · UI static/js/handlers/trustBadge.js.

Mechanism

An agent's ingredients are its active ontology (its knowledge graph) and its active skills. The sign gate refuses to seal the agent until every ingredient is already 🟢. If one is unsigned or changed, it appears in a "sign these first" list — the guided path that makes the composition legible.

So trust is genuinely compositional: a signed agent contains only signed parts. The consumer reads one badge on the agent; the catalog of parts hides behind it, each already vouched for.

Detail

The rule is a single pure function, agent_signable(ingredients), which returns the blocking list. The same rule composes one level up for agent packs: a pack is "an agent whose ingredients are its members", resolved by pack.member_refs → agent_signable. One idea, applied recursively.

Config artefacts — MCP servers, LLM configs, vector/graph backends — are not attestable by design. Their content is credentials, and trust ≠ access. They are senses and organs the agent is born with, not things to be vouched for.

Full detail · the compositional truth

Agent trust resolves as: 🟢 agent ⟺ its attestation is intact and every ingredient resolves 🟢 (resolve_agent_trust). The composition itself is fingerprinted with an id- and order-independent composition_hash, so re-ordering ingredients or remapping ids never changes the badge — only real content change does.

Modules: core/trust/composition.py (profile → ingredients → live AgentTrust) · core/trust/pack.py (pack composition) · core/trust/attestation.py (agent_signable, resolve_agent_trust).

Mechanism

Signing is never a rubber stamp. Each signable kind runs a validator that returns one of three bands: clean (signs freely), partial (signs with a caveat noted on the badge), or blocked (cannot be signed until fixed). An ontology that isn't conformant, a skill that carries a prompt-injection, a flow whose query is unsafe — each is caught here, before a signature exists.

Detail · the ten signable kinds

Every kind maps onto one closed archetype set — the two shipped poles (conformance, content-safety) plus code-safety, query-safety, integrity, and aggregate. Eight kinds have a per-kind validator registered by kind; the two aggregate kinds (agent, agent pack) are signed only when all their parts are. Each validator is pure and 0-token, so adding a new kind is one function with no forks.

ArtefactkindWhat is signedArchetype
Ontology (KG)ontologyentities + relationshipsconformance
Skillskillinstruction textcontent-safety
Agentagentcomposition over ingredientsaggregate
Extensionextensionhandler source + manifestcode + content
Knowledge repoknowledgesorted per-doc hash + embeddingintegrity + content
Planner repoplannersorted per-case hashintegrity + query-safety
Agent packagent_packcomposition over membersaggregate
Flowflownode/edge logic (positions excluded)code + query + content
Dashboarddashboardtile structure + data sourcequery-safety
Canvascanvasmarkupmarkup/XSS + content
Full detail · the scanners

Validators lean on shared deterministic 0-token scanners: content_safety_scan (prompt-injection), code_safety_scan (AST), sql_safety_scan, markup_safety_scan (XSS), combined by aggregate_verdict. A ScanResult splits findings into blocking vs caveats, which is exactly what maps to blocked vs partial.

The ontology validator is special: it wraps the Tier 4.3 conformance gate, so a non-conformant ontology is not signable and a partially-conformant one signs with a badge note. Files: core/trust/validators.py, core/trust/scanners.py, core/trust/content.py (the canonical per-kind content resolver).

Mechanism

To sign, the platform computes a content hash of the exact signable bytes and signs kind|version_hash with the platform's Ed25519 provenance key. Because the signature is over content and not over an id or a filename, it is portable and self-describing — and any later edit changes the hash, so the signature no longer matches and the badge flips to 🟠.

Detail

The store persists each attestation with its signer public key alongside the signature, so a consumer on a different Uderia instance can verify with the publisher's key — no shared secret, no phone-home. content.py is the one canonical place that defines "what bytes are signed" per kind, shared by sign-off, badge-state resolution, and marketplace portability, so they can never drift apart.

Full detail · one key, reused three times

The signer behind trust is not a new key. eval/online.py:sign_payload() — the platform provenance key — is reused verbatim by core/trust/store.py:sign(). So one Ed25519 key signs three things: the execution trajectory (the EPC), the evaluation verdict that grades it, and the trust badge that says the agent is made of validated ingredients. All three verify offline with the same committed verifier.

REST: POST /v1/trust/<kind>/<id>/sign-off, POST /v1/trust/verify, GET /v1/trust/agent/<id>. Table trust_attestations (self-applying). Reference: AGENT_OPS_EVAL_ARCHITECTURE §6.4.

Mechanism

When an agent (or KG, skill, pack) is published to the marketplace and later installed, its ids are remapped to the new instance — but because signatures are bound to content, the attestation survives the remap. A publisher's green badge can reappear on the consumer's copy… if and only if the copy's live hash matches what was signed. If anything changed in transit, the badge honestly shows ⚪/🟠 instead.

Detail

Every marketplace surface uses the same two calls: capture(kind, id) at publish and reinstate(kind, new_id, claim) at materialize, gated by the honesty gate. The claim carries the signer's public key, so cross-instance verification uses the publisher's key. Wired into KG, agent-pack (and per-member), skill, extension, and component-instance flows; collections inherit trust for free via the reference model.

Full detail

Live-verified end to end: a signed KG published → forked to a new kg-id → resolves 🟢 with verified:true (the id remap survived), while the honesty gate refuses to re-establish a signature on a mismatched composition. Module: core/trust/portability.py (capture / reinstate / claim_state + honesty gate). 132 assertions in test/test_trust_membrane.py cover the three-state truth, hashing, the compositional truth table, all ten validators, and cross-instance public-key round-trip.

The one line to keep

Signing proves an agent and its parts are intact and unchanged — it grants no permissions. A checked thing is not an authorised thing. Whether the agent may act, and on whose behalf, is a separate story — Act II.

Act II

Then it acts — observe → enforce → prove

A signed agent is trustworthy at rest. But an agent earns trust in motion, one turn at a time. Every turn passes through a pipeline of independent checks — and the same substrate that observes quality can enforce against drift on the request path, then prove the result with a signed, published benchmark.

in answer Inbound guard injection Authority who acts Grounding scope stamped engine runs ④ authority-enforced Outbound guard PII · toxicity Grounding withhold drift Eval scored Sealed signed everything grounds on ⓪ the ontology · the whole flow is watched in ⑩ observability

Order is the process. You cannot withhold an answer after it has streamed — so grounding and guardrails sit before the answer leaves the building.

OBSERVE — score every turn ENFORCE — act before harm PROVE signed · published One substrate, three jobs — they can never disagree.

Observe — the substrate

Mechanism

Every executed turn is scored against a profile-class-aware suite of deterministic scorers — did it complete, stay in cost, avoid tool loops, cite its sources, keep numbers faithful, stay in scope. This runs in code (CI-pure, 0 tokens), on by default, backgrounded so it can never block or slow a turn.

Only the open-ended residue — "is this answer actually supported?" — is handed to LLM judges, and only on a sample.

Detail · the moat

19 core scorers + 13 reliability/quality scorers, derived entirely from the trace already persisted. Metrics are 3-bandedhealthy / review / danger — where review passes the gate but is flagged ("warn, don't gate"). The philosophy: grade what matters, not the path — tool assertions use subset / must-not-call semantics, never an exact sequence.

Full detail

Files: eval/scorers/deterministic.py · eval/scorers/reliability.py. A scorer abstains (passed=None) rather than fabricate a verdict when its input is absent — abstention is first-class. Runs across all five agent classes; adding a metric is one class + one register_scorer call. Reference: AGENT_OPS_EVAL_ARCHITECTURE §5.2.

Mechanism

The open-ended dimensions — answer correctness, groundedness, instruction-following, synthesis quality, and semantic content safety — go to a panel of independent models that each score one dimension in isolation, cite evidence, and may answer "unknown". Consensus is a majority vote that ignores abstentions.

Because Uderia already speaks to ten LLM providers, a diverse-family panel is essentially free — and diversity is what mitigates a single judge's self-preference and correlated error.

Detail · calibration

A judge starts non-gating. It is only promoted to gate a release once it agrees with human SME labels at Cohen's κ ≥ 0.6 (substantial agreement). Human labels come from an annotation queue where reviewers agree/disagree with verdicts. Judges refine what a code grader can only approximate — they never replace the deterministic floor.

Full detail · the 8 decomposed judges
JudgeDimensionAbstains unless
answer_correctnessvs a referencereference present
groundednessFocus / RAGretrieved docs present
instruction_followingIdeateanswer present
tool_arg_optimalitytool classestool calls present
answer_groundednesstool classestool results present
scope_faithfulnesstool classesKG scope declared
synthesis_qualityCoordinateexperts invoked
content_safetyall classesanswer present

content_safety is the semantic complement to the deterministic outbound guardrail — it catches the residue only meaning can (sarcastic or coded abuse, harm-enabling instructions, indirect personal identification), advisory and never blocking the answer path.

Files: eval/judge.py, eval/scorers/judges.py, eval/calibration.py. Every judge run is a visible, reload-safe Live Status step and its token cost is allocated to the turn exactly like any other spend.

Mechanism

The market shows you a stream of traces; the buyer's real question is "is this agent regressing?" So the lead UX is an agent health roster — one card per agent, IFOC-coloured, worst-health-first, with honest "unevaluated" empty states rather than fake numbers.

Detail · 4-class health & pass^k

One banded scale everywhere: 🟢 Healthy (≥ 0.80) · 🟡 Review (0.50–0.79) · 🔴 Danger (< 0.50) · ⚪ Inactive. Offline reliability uses pass^k — the fraction of cases that pass on all k reps — which surfaces the long tail that single-shot accuracy hides. A regression gate turns this into a CI exit code.

Full detail

Two lenses over one substrate: Sessions (instance — "what happened in this run?") and Agents (entity — "is this agent good?"), bridged by a trajectory verdict overlay. Files: agentPerformanceHandler.js, eval/analysis.py, eval/runner.py, eval/gate.py. Coordinators expand into a master/slave trace tree; flows are graded as whole agents.

Enforce — on the request path

Mechanism

Grounding checks every answer against the scope the agent's knowledge model actually declared. It closes Uderia's own documented failure: an agent received a complete, scope-correct enrichment, ignored it, brute-forced 19 calls across unrelated databases, and produced a confident, wrong 230-day answer. In enforce mode that answer is now withheld.

observe

measure only, change nothing (default)

annotate

deliver with an honest note

review

withhold, but keep the original for a human

enforce

withhold a confirmed drift

Detail · tiered — cheap trigger, judged decision

A first benchmark disproved a naïve deterministic block: it over-blocked honest "not in my scope" refusals and missed prose-only drift. So enforcement is tiered: a cheap deterministic trigger does recall (flags any structural data reference not on the KG allowlist — never starving the judge), then the scope_faithfulness judge does precisiondrifted → withhold · faithful → deliver · unavailable → annotate. An honest refusal always survives.

Detail · two lanes, one gate — the knowledge lane too

The same gate now grounds answers built from retrieved knowledge, not only from SQL scope. A second trigger family checks the answer's numbers, verbatim quotes, and named identifiers against the chunks that were actually retrieved — and, before flagging anything, runs a second-chance targeted retrieval so a claim the first search missed but the corpus does support is cleared, not blamed. What survives escalates to the groundedness judge. In the answer itself, an unsupported span gets a dotted underline — "unsupported by the knowledge base" is drawn in place, and it never means "false". A companion honesty check stops the opposite failure: when retrieval finds almost nothing yet the answer asserts specifics, it says "the knowledge base does not cover this" instead of inventing.

Full detail · never breaks a turn

Observe/annotate/off never reach the judge → zero added latency or cost by default; only enforce pays a judge call, and only when the trigger fires. The path fails open (a gate error delivers the original answer) and in enforce fails safe to annotate on any judge unavailability. Crucially, the live gate's "out of scope" is the same primitives the off-path scope_adherence scorer uses — observe and enforce can never disagree. A confirmed withhold is written into the Ed25519 provenance chain. Files: agent/grounding/{primitives,corpus,gate,enforce,runtime,adapter}.py, agent/honesty/. One implementation for all five engines, SQL scope and retrieved knowledge alike.

Mechanism

Inbound: the incoming request is screened before the agent reads it; a prompt-injection is refused. Outbound: the drafted answer is screened; personal data is masked and toxic content withheld. Both are fast and free — deterministic, zero extra model calls — so they cost nothing to run on every turn.

Detail

Outbound events carry category labels only — never the raw personal-data value, so the audit trail itself never leaks. Guardrails are a request-path enforcement primitive (a sibling of grounding, not a component), default observe, and — like everything here — fail open so they can never break a turn. On enforce, a blocked inbound turn produces a self-contained refusal; the injected text never reaches the model.

Full detail

Deterministic 0-token detectors: prompt-injection, PII (email/SSN/Luhn-validated card/phone/keys/IBAN/IP) with redaction, closed-set toxicity, and exfiltration-shaped URLs — the classic RAG leak where a poisoned document plants https://evil/?q={secret} that exfiltrates on render. A URL that is both novel (not in the turn's own sources) and exfil-shaped is defanged — its text kept, the link made dead — never silently deleted. Master switch GUARDRAILS_ENABLED (default off); per-profile guardrailConfig mode ladder off/observe/annotate/review/enforce (review = enforce with retention — see Act III). Files: agent/guardrails/. Rendered as a Live Status card, live + reload, for all five engines.

Mechanism

A scheduled task, a sub-agent, a flow node — anything running unattended — must not run with your full permissions, unattributed. Instead it takes on a limited version of its owner: autonomy on/off, read-only, a denied-tool list, a connector allow-list, a per-run budget. Every attempted action is checked against that limit before it happens, and every autonomous action is attributed to the agent, not to you.

Detail · fail-closed at every chokepoint

The agent's authority is a strict subset of its owner's — never a grant. Enforcement is fail-closed: if the check itself errors, the action is denied. Autonomy is set per turn at the boundary via an async-task-local security context, so concurrent sessions stay isolated with no signature threading. An interactive user turn leaves it unset → baseline, no gating.

Full detail · honest scope

Three tool chokepoints read the ambient principal and deny before executing: MCP tools, component tools, connectors. This is the attainable form — capability scoping + audit + enforcement. The fuller form ("cannot query outside its data slice") is the OBDA future. Files: core/agent_authority.py, wired at agent/execution_service.py. Reference: AGENT_AUTHORITY_ARCHITECTURE.

Prove — evidence, not claims

Mechanism

Every turn already produces an Ed25519-signed Execution Provenance Chain — a hash-chained record of exactly what happened. When the turn is scored, the verdict digest is bound to that chain's tip and signed, so a quality claim can be audited alongside the exact trajectory it grades. Tamper the trace, and the signature no longer matches.

Detail · one key, three signatures

This is where Act I and Act II meet. The same Ed25519 provenance key signs three things:

  • the trajectory — what the agent did (the EPC);
  • the verdict — how good it was (the eval attestation);
  • the badge — that the agent is made of validated ingredients (the trust attestation).

All three verify offline with the same committed verifier and the signer's public key alone.

Full detail

eval/online.py:sign_payload() is the shared signer; core/trust/store.py:sign() reuses it verbatim. A reproducible signed-attestation sample + a standalone offline verifier ship as the A6 proof-pack (docs/proof-packs/samples/verify_attestation.py) — anyone can confirm digest match, key fingerprint, Ed25519 signature, and that a tampered payload is rejected, with no Uderia install.

Mechanism

The grounding system is turned into a published, reproducible proof — one benchmark per lane. The structured lane: 36 real turns, judge-labelled — 100% trigger recall, 0 false negatives, net drift 6% → 0%. The knowledge lane: 18 curated cases scored by the production trigger itself — 85.7% recall, 0% false positives, 100% second-chance recovery, reproducible offline at zero tokens. Both publish their misses by case id. Read the numbers →

Detail · the matrix
judge: driftedjudge: faithful
trigger fires → judgedTP (caught)FP (extra judge call, never a wrong verdict)
trigger passes → deliveredFN (the honest gap, shown)TN

Honest by construction: false negatives and false positives are published, not hidden. The recall-first trigger exists precisely to shrink the FN corner.

Full detail

A 36-case dataset (in-scope / out-of-scope / ambiguous); a pure scoring core (eval/benchmarks/grounding/report.py) is the single source of truth the harness and any in-platform view render from, so they can never diverge. The knowledge-lane twin (eval/benchmarks/corpus_grounding/) is fully deterministic — anyone with the repo reproduces the published numbers offline, and the numbers are pinned in CI so drift fails the build. Both, side by side, with limits stated: The Numbers. Reference: §6b.

Where the two acts meet

One Ed25519 key signs the trajectory, the verdict, and the badge. That is why Trust & Assurance is one system, not three products bolted together: the thing that proves what the agent is made of (Act I) and the thing that proves how it behaved (Act II) rest on a single cryptographic root — offline-verifiable by anyone, with nothing but a public key.

Act III

The loop closes — trust that responds

Observing and enforcing is not the end of the story. What the substrate measures feeds back: the badge on the agent breathes with its conduct, a human can be put in the loop, no indirect path stays silent, and you decide policy on evidence, not faith. Trust is a closed loop — measured behaviour changes the trust state, the trust state can change enforcement, and every step stays visible and verifiable.

Mechanism

The Behavioral Trust Score fuses the static integrity of the sign-off (🟢/🟠/⚪) with the agent's live track record — a recency-weighted pass rate, extra weight on the trust-critical checks (scope, groundedness, governed-data ratio) — into one composite state that moves: provisional → at-risk → watch → proven → trusted. Sustained good conduct earns trust; decline visibly withdraws it. Integrity can only cap conduct, never promote it — an unsigned agent can never read fully trusted, no matter how well it behaves.

Detail · the circuit breaker

When an agent's trailing conduct enters at-risk (volume-gated, so a couple of bad turns on a new agent can't trip it), an opt-in circuit breaker responds — notify the owner, or freeze autonomy: it sets the agent's Agent-Authority autonomous=false, suspending only its unattended use until a human reviews. Interactive use is never touched; the freeze is visible and reversible. This is the loop closing — a measurement changing an enforcement.

Full detail

Pure decision in eval/trust_behavior.py (integrity × track-record fusion, staleness decay, volume gates); the breaker runs at the end of the online-eval hook on the transition edge into at-risk (eval/online.py:_run_trust_breaker). Default off ⇒ read-side only, byte-identical baseline. On the roster the state renders as a seal + ring glyph — the seal is integrity, the ring fills with conduct. Reference: §6c.1–6c.2.

Mechanism

A fourth acting mode on both the grounding gate and the outbound guardrail: review. It withholds or redacts exactly like enforce, but parks the ORIGINAL answer for the owner to disposition — nothing lost, nothing silently delivered. Ideal for the scheduled and autonomous runs nobody was watching. It is the platform's human-oversight mechanism, not a promise.

Detail · append-only release

Approve = "I've seen the original and accept it"; uphold = the withholding stands. Either way the decision is recorded on the turn's trace. Release is append-only — the delivered conversation is never rewritten; an approved original surfaces in that answer's trust capsule, always labelled as a human decision. Parked items and incidents land in an Assurance Inbox that turns trust events into worked items instead of buried log lines.

Full detail

review is a runtime composite, not a config-ladder mode: the runtime detects the raw profile mode, substitutes enforce for evaluation, then parks the withheld original in core/review_queue.py and re-tags the event. REST: GET /v1/assurance/reviews, POST …/<id>/approve|reject. Trust incidents flow through core/trust_events.py. Reference: §6c.4.

Mechanism

Indirect injection is the lane the entry guard cannot see. Three firewalls close it: a poisoned memory write is quarantined (stored but never recalled — closing the persistent-compromise vector); a poisoned retrieved document is defused (kept, but wrapped in an untrusted-data label the model must not obey); and a poisoned tool result — a database row that says "ignore all previous instructions" — is flagged. All three ride the same guardrails master switch and cost zero tokens.

Detail

The memory and retrieval firewalls alter what the model reads (quarantine / label); the tool-result firewall is deliberately observe-only — it flags but never rewrites the row, so a false positive can never corrupt real data. Each records an Assurance-Inbox event (labels only, never the poisoned content) and broadcasts a live notice. Files: components/builtin/memory/store.py (screen_memory_content), knowledge_context handler, agent/guardrails/runtime.py (scan_tool_result). Reference: TIER_1.3 §5.

Full detail · and one lane earlier — at ingest

All three reuse the one deterministic detect_prompt_injection primitive the inbound guard uses, and all fail open. Earlier still, an ingest firewall screens every document as it enters a knowledge repository — injection patterns, personal-data categories (counts only, never the values), exfil URLs — recording the result without ever blocking an upload. "We screen what the model reads, not just what the user types" — the indirect-injection triad the edge guard alone cannot cover, now backed by screening at the source.

Mechanism

A knowledge repository can never be a signed data product — retrieval matches on meaning and synthesis is judgement, so it can't be a deterministic contract. What it can earn is honesty about its source. Every answer now shows where its knowledge came from: the corpus's integrity signature (🟢 signed · 🟠 changed · ⚪ unsigned — a guarantee about the source, never the answer), how stale that source is ("verified 94 days ago" / "sync off"), and its sensitivity. A repository's own signature was made earned: it can be signed only once it is fully screened and its critical findings resolved — either quarantined, or acknowledged with a recorded reason. A poisoned document is one click from quarantine: excluded from retrieval, still visible, reversible.

Detail · two signature meanings, never conflated

The corpus signature and a data-product signature mean different things and the interface keeps them visually distinct: one attests source integrity (this document set, this embedding model, unchanged), the other a deterministic consumption contract. The answer stays in the monitored lane and says so — the badge is a source guarantee, not a consumption one. Quarantining a document changes the corpus, so the signature honestly reads "changed" until re-signed: the ratchet working, not a bug.

Full detail · beyond parity

Three controls no filtering-or-reporting platform offers: retrieval-anomaly monitoring (a document retrieved across many unrelated queries is a suspicious embedding hub — flagged for your disposition, never auto-quarantined; honestly labelled statistical, not proven poisoning); sensitivity levels (a per-agent ceiling on which repositories it may read, and a note when an answer draws on a confidential one); and a source-consistency judge that surfaces when two retrieved documents disagree instead of silently picking one. Files: agent/grounding/corpus.py, agent/guardrails/corpus_screen.py, core/knowledge_provenance.py, eval/retrieval_anomaly.py, eval/scorers/{reliability,judges}.py.

Mechanism

The observe → enforce climb is an anxiety problem, so it's decided on evidence. Policy backtesting replays a proposed grounding/guardrail policy over your real, persisted history — deterministically, at zero token cost — and reports exactly what it would have blocked, masked, or escalated. Red-teaming probes an agent with an adversarial corpus and scores whether its guards held. And every answer carries a consumer-facing "Why trust this answer?" receipt — sources, the governed-vs-free-formed data lane, guard findings, and the signed provenance chain, exportable and verifiable offline.

Detail

Backtest guardrail projections are exact (the same policy engine on stored text); grounding projections are trigger-level and honestly do not simulate the judge (a flagged turn reads "would escalate", never a certain block). The deterministic red-team scores in-path detector recall for free; an opt-in, budget-capped live red-team drives real probe turns — including a corpus lane that plants a real poisoned document in a test collection, asks the question that retrieves it, scores whether the firewall and the answer held, and deletes the payload afterward (with the cleanup status reported, never silent). A signed audit pack bundles posture + eval + incidents + an EU AI Act / NIST / GDPR control map, Ed25519-signed and offline-verifiable.

Full detail

Files: eval/backtest.py, eval/redteam.py (deterministic self-test), eval/live_redteam.py (real probe turns), the answer capsule (static/js/handlers/answerCapsule.js). REST: POST /v1/evals/backtest, /v1/assurance/resilience-test, /live-redteam, /audit-pack. And a per-turn Trust Journey strip renders the whole pipeline — inbound guard → authority → scope → tools → outbound → grounding → seal — as one glanceable row. Reference: §6c.3–6c.5.

The differentiator

Most platforms sell trust as filtering (guardrails that block) or as reporting (dashboards that observe). Uderia sells it as closed-loop, verifiable trust: measured behaviour changes the trust state, the trust state can change enforcement, and every step of that loop — down to the individual answer's receipt — is cryptographically provable.

The membrane holds

Safe by default, rigorous by choice

Nothing here is imposed on you. Every capability ships off, or observe-only — a fresh deployment behaves exactly like an ungoverned one until you turn something on. You opt into rigor deliberately, one layer at a time, and you can always see and verify what each layer did.

Signed, so you know what it is made of. Observed, so decline is visible. Enforced, so drift never reaches the user. Proved, so the claim is checkable — offline, by anyone. And kept in check, so trust reflects how it actually behaves.

The whole story, in one breath

A Uderia agent is born from its configuration, composed of validated ingredients, signed into a trusted whole — and then, on every turn it runs, it is observed for quality, enforced against hallucination, out-of-scope drift, leakage, and borrowed authority, and proved with a signature anyone can check. And the loop closes: its measured conduct feeds back into the badge itself, a human can be put in the loop, and every answer carries a receipt. Trust, earned — and kept.