Agent Trust & Assurance / Trust Membrane ← The Life of a Uderia Agent

Architecture · Tier 5.2

Trust Membrane

Status: implemented and merged to main (2026-07-03). This is the architecture reference — how the shipped system works. The design rationale is docs/roadmap/TIER_5.2_TRUST_MEMBRANE.md; the per-artefact validator model is TIER_5.2_VALIDATORS.md; marketplace portability is TIER_5.2_PORTABILITY.md.


1. The idea in one paragraph

Trust is a visible, cryptographically-verifiable badge on an artefact, and the agent is the primary unit: a signed agent is trusted exactly when its whole composition is — its active ontology and skills must each be signed 🟢. Trust is computed, never re-derived; sharing stays fully open (badge, not gate). Three states: ⚪ unsigned, 🟢 trusted (signed & intact), 🟠 changed (signed, but content drifted since). Default (no attestations) = a byte-identical baseline — every artefact is ⚪.

2. Module map (src/trusted_data_agent/core/trust/)

Module Responsibility
attestation.py Pure core: TrustState, content_hash, id- & order-independent composition_hash, resolve_state, resolve_agent_trust, agent_signable (bottom-up rule), the validator registry, ValidationVerdict + SignBand (clean/partial/blocked). Zero I/O.
scanners.py Deterministic 0-token safety scanners: content_safety_scan (injection), code_safety_scan (AST), sql_safety_scan, markup_safety_scan (XSS), aggregate_verdict. ScanResult splits findings into blocking vs caveats.
validators.py The 8 per-kind validators (ontology · skill · extension · knowledge · planner · flow · dashboard · canvas), each returning a ValidationVerdict, registered by kind. The remaining 2 signable categories (agent, agent_pack) are the aggregate/composition path — signed only when all their parts are, with no per-kind register_validator. 8 per-kind + 2 aggregate = the 10 signable categories in §3.
content.py Canonical per-kind content + version_hash resolver (skill/ontology/extension/knowledge/planner/flow/dashboard/canvas). One definition, shared by sign-off, badge state, and portability.
composition.py A real profile → its ingredients (active KG + active skills) → live AgentTrust.
pack.py Agent-pack composition resolver — a pack is "an agent whose ingredients are its members".
store.py The trust_attestations table (self-applying), Ed25519 sign/verify reusing the platform provenance key, content-bound signatures + the signer public key carried for cross-instance verification.
portability.py Marketplace capture / reinstate / claim_state + the honesty gate.
validators registry register_validator(kind, fn) — new kind = one function, no forks.

REST seam: api/trust_routes.py (GET /v1/trust/agent/<id>, GET/POST /v1/trust/artifact(s), POST /v1/trust/<kind>/<id>/sign-off, POST /v1/trust/verify). UI: static/js/handlers/trustBadge.js.

3. The validator model (all 10 categories)

Every signable kind maps onto one closed archetype set — the two shipped poles (conformance, content-safety) plus code-safety, query-safety, provenance-integrity, and aggregate. Each validator is pure, deterministic, 0-token, and maps its result onto the harmonised band clean · partial · blocked.

Artefact kind Signable content Archetype
Ontology (KG) ontology entities + relationships conformance (Tier 4.3 gate)
Skill skill instruction text content-safety
Agent (profile) agent composition over ingredients aggregate
Extension extension handler source + manifest code + content-safety
Knowledge repo knowledge sorted(per-doc hash) + embedding integrity + content-safety
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: TIER_5.2_VALIDATORS.md §6. Config artefacts (MCP servers, LLM configs, vector/graph backends) are not-attestable by design — their content is credentials, and trust ≠ access.

4. The bottom-up sign gate

agent_signable(ingredients) refuses to sign an agent unless every ingredient is already 🟢; the blocking list drives the guided "sign these first" flow. The same rule composes for agent packs (pack.member_refsagent_signable). Verdicts are Ed25519-signed and bound to the exact content version (store.sign).

5. Badges + sign-off UX

trustBadge.js provides the reusable primitives: - mountArtifactBadges(root) — fills [data-trust-artifact-*] slots with a signer-aware seal (green intact · amber changed · faint "sign off" for signers on unsigned; nothing for non-signers). Wired across Skills, Extensions, KGs, Repos, Agent Packs, and Workspace instances (flow/dashboard/canvas). - mountAgentBadges(root) — the compositional agent shield on the profiles list. - openArtifactTrust(kind, id) — the trust popover: state · offline Verify · signer-only Sign off / Re-sign (surfaces an agent-pack's blocking members). - mountMarketplaceTrust(root) — read-only "publisher signed" seal on marketplace cards.

6. Marketplace portability

Trust travels with content, not ids: signatures are content-bound (kind|version_hash), so an attestation survives an id remap. Every marketplace surface uses the same two calls — capture(kind, id) at publish, reinstate(kind, new_id, claim) at materialize — and the honesty gate re-establishes a signature only if the copy's live hash equals what was signed. The claim carries the signer's public key, so a cross-instance consumer verifies with the publisher's key. Wired into KG · agent-pack (+ per-member) · skill · extension · component-instance; collections inherit trust free via the reference model. Full detail: TIER_5.2_PORTABILITY.md.

7. Packaging + isolation (the Ontology Suite)

The Trust Membrane ships bundled with the Platform Ontology UX as one physically-isolatable enterprise feature — the Ontology Suite — governed by a single switch (core/enterprise.py, ON for all tiers today; a one-line flip makes it Enterprise-only). Removal manifest + absence-tolerance contract: src/trusted_data_agent/core/trust/README.md. Canonical suite description: PLATFORM_ONTOLOGY_ARCHITECTURE.md §11.

8. Guarantees & scope

Downstream consumers (Jul 2026): the membrane's integrity state now feeds two live surfaces beyond the badge — (1) Behavioral Trust Score (AGENT_OPS_EVAL_ARCHITECTURE.md §6c): the composite per-agent trust state = live conduct capped by this integrity reading (unsigned caps at "proven", changed caps at "watch" — a signature never promotes bad conduct), rendered as a seal+ring glyph on the Agents roster; (2) trust-aware routing (coordinate_engine.py: genieConfig.requireTrustedExperts) — a coordinator can require its experts to resolve 🟢 at routing time, making compositional trust operative, not just visible. Both resolve via composition.resolve_profile_trust defensively (suite absent → unknown / loud fail-open warning), preserving the removability contract.

Remaining (minor): a cross-instance trusted-publisher policy (verification works; the allow-list is a config choice); Model B grounding (opt-in runtime enforcement that a turn only executes signed ingredients).

Tests: test/test_trust_membrane.py (132 assertions — three-state truth, hashing, compositional truth table, all 10 validators, scanners, bands, portability incl. cross-instance pubkey round-trip).