Trust Pipeline

Every connect() and sendByCapability() call flows through the trust pipeline—a multi-stage verification system that ensures agents are authentic, reachable, and trustworthy before any message is sent.

Overview

The trust pipeline is your first line of defense against:

  • Identity spoofing: Malicious agents claiming to be someone they’re not
  • Stale connections: Sending messages to offline or unresponsive agents
  • Untrusted agents: Interacting with low-reputation or unverified agents

The pipeline executes three verification stages in sequence:

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│  DID Resolution │ -> │ Liveness Check  │ -> │ Trust Score Gate│
└─────────────────┘    └─────────────────┘    └─────────────────┘

If any stage fails, the pipeline throws an error and the message is not sent.

import { AletheiaA2AClient } from "@a2aletheia/a2a";

const client = new AletheiaA2AClient({
  registryUrl: "https://registry.example.com",
  verifyIdentity: true,      // Stage 1: Enable DID verification
  requireLive: true,        // Stage 2: Require live agents
  minTrustScore: 50,        // Stage 3: Minimum trust threshold
});

// All calls go through the trust pipeline automatically
await client.connect("did:example:agent-123");
await client.sendByCapability("text-generation", "Hello!");

Stage 1: DID Resolution

The first stage verifies that the agent’s Decentralized Identifier (DID) resolves correctly in the registry. This confirms the agent’s identity is authentic and registered.

What It Checks

  • The DID exists in the registry
  • The DID document is well-formed and valid
  • The agent’s public keys can be retrieved for future signature verification
// DID resolution happens automatically during connect()
const agent = await client.connect("did:example:agent-123");
// If DID doesn't resolve, throws DIDResolutionError

Skipping DID Verification

In development or testing environments, you may want to skip DID verification:

const client = new AletheiaA2AClient({
  registryUrl: "https://registry.example.com",
  verifyIdentity: false,  // Skip DID resolution stage
});

Setting verifyIdentity: false disables identity verification entirely. Use only in trusted development environments.

Error: DIDResolutionError

When DID resolution fails, the pipeline throws a DIDResolutionError:

import { DIDResolutionError } from "@a2aletheia/a2a";

try {
  await client.connect("did:example:invalid-did");
} catch (error) {
  if (error instanceof DIDResolutionError) {
    console.error("DID verification failed:", error.message);
    console.error("Error code:", error.code); // "DID_RESOLUTION_FAILED"
    console.error("Cause:", error.cause);      // Original error from registry
  }
}

Stage 2: Liveness Check

The second stage confirms the agent is reachable and responding. This prevents sending messages to offline or unresponsive agents.

Two Modes of Liveness Checking

The pipeline supports two liveness checking modes:

Cached Mode (requireLive)

Uses the agent’s cached isLive status from the registry. Fast but may be stale.

const client = new AletheiaA2AClient({
  requireLive: true,  // Check cached isLive status (default: true)
});

When requireLive: true, the pipeline checks agent.isLive from the registry data. If false, throws AgentNotLiveError immediately.

Fresh Mode (livenessCheckBeforeSend)

Performs a real-time liveness probe before each message. More reliable but adds latency.

const client = new AletheiaA2AClient({
  livenessCheckBeforeSend: true,  // Probe agent before each send
});

This calls client.checkLiveness(agent.did) to verify the agent responds to a liveness probe.

Combining Both Modes

You can use both modes together for defense-in-depth:

const client = new AletheiaA2AClient({
  requireLive: true,              // Fail fast on cached offline status
  livenessCheckBeforeSend: true,  // Double-check before sending
});

Disabling Liveness Checks

For maximum flexibility (e.g., queue-based systems), disable both:

const client = new AletheiaA2AClient({
  requireLive: false,
  livenessCheckBeforeSend: false,
});

Error: AgentNotLiveError

When an agent fails the liveness check, the pipeline throws an AgentNotLiveError:

import { AgentNotLiveError } from "@a2aletheia/a2a";

try {
  await client.sendByCapability("text-generation", "Hello!");
} catch (error) {
  if (error instanceof AgentNotLiveError) {
    console.error("Agent not live:", error.message);
    console.error("Error code:", error.code); // "AGENT_NOT_LIVE"
  }
}

Stage 3: Trust Score Gate

The final stage ensures the agent meets a minimum trust score threshold. Trust scores are reputation metrics maintained by the registry.

How Trust Scores Work

Trust scores range from 0-100 and reflect an agent’s reputation:

Score Range Reputation Level
0-29 Untrusted
30-59 Limited Trust
60-79 Trusted
80-100 Highly Trusted

Scores are calculated from factors like:

  • Successful message deliveries
  • Response quality ratings
  • Uptime history
  • Community verification

Setting the Minimum Trust Score

Configure the threshold in your client:

const client = new AletheiaA2AClient({
  minTrustScore: 60,  // Only interact with "Trusted" agents or higher
});

Set to 0 (default) to disable the trust score gate entirely:

const client = new AletheiaA2AClient({
  minTrustScore: 0,  // No trust score filtering
});

Error: TrustScoreBelowThresholdError

When an agent’s trust score is below the threshold, the pipeline throws a TrustScoreBelowThresholdError:

import { TrustScoreBelowThresholdError } from "@a2aletheia/a2a";

try {
  await client.sendByCapability("text-generation", "Hello!");
} catch (error) {
  if (error instanceof TrustScoreBelowThresholdError) {
    console.error("Trust score too low:", error.trustScore);
    console.error("Required threshold:", error.threshold);
    console.error("Error code:", error.code); // "TRUST_SCORE_BELOW_THRESHOLD"
  }
}

TrustInfo Object

Every trusted operation returns a TrustInfo object containing the verification results:

interface TrustInfo {
  didVerified: boolean;        // DID was successfully resolved
  isLive: boolean;             // Agent is currently live
  trustScore: number | null;   // Agent's trust score (0-100)
  isBattleTested: boolean;     // Agent passed stress testing
  responseVerified: boolean | null;  // Response signature verified (future)
  verifiedAt: Date;            // When verification was performed
}

Accessing TrustInfo

const response = await client.sendByCapability("text-generation", "Hello!");

console.log("Trust verification:", response.trustInfo);
// {
//   didVerified: true,
//   isLive: true,
//   trustScore: 85,
//   isBattleTested: true,
//   responseVerified: null,
//   verifiedAt: 2026-02-15T10:30:00.000Z
// }

TrustInfo Properties

Property Type Description
didVerified boolean true if the agent’s DID was successfully resolved in Stage 1
isLive boolean true if the agent was confirmed live in Stage 2
trustScore number \| null Agent’s reputation score (0-100), or null if unknown
isBattleTested boolean true if the agent has passed stress testing and edge case validation
responseVerified boolean \| null Response cryptographic verification status (reserved for future phases)
verifiedAt Date Timestamp when the trust pipeline completed verification

Configuration Reference

All pipeline-related configuration options:

interface AletheiaA2AConfig {
  // Stage 1: DID Resolution
  verifyIdentity?: boolean;  // Default: true
                             // Set false to skip DID verification

  // Stage 2: Liveness Check
  requireLive?: boolean;                // Default: true
                                         // Check cached isLive status
  livenessCheckBeforeSend?: boolean;    // Default: false
                                         // Probe agent before each send

  // Stage 3: Trust Score Gate
  minTrustScore?: number;   // Default: 0
                            // Minimum trust score (0-100)
}

Default Configuration

const defaults = {
  verifyIdentity: true,
  requireLive: true,
  livenessCheckBeforeSend: false,
  minTrustScore: 0,
};

Configuration Examples

High-security production environment:

const client = new AletheiaA2AClient({
  verifyIdentity: true,
  requireLive: true,
  livenessCheckBeforeSend: true,
  minTrustScore: 80,
});

Development/testing environment:

const client = new AletheiaA2AClient({
  verifyIdentity: false,
  requireLive: false,
  livenessCheckBeforeSend: false,
  minTrustScore: 0,
});

Async queue-based processing:

const client = new AletheiaA2AClient({
  verifyIdentity: true,
  requireLive: false,           // Agent may be offline when queued
  livenessCheckBeforeSend: false,
  minTrustScore: 50,
});

When Trust Fails

Handle each error type appropriately in your application:

DIDResolutionError

import { DIDResolutionError } from "@a2aletheia/a2a";

try {
  await client.connect(agentDid);
} catch (error) {
  if (error instanceof DIDResolutionError) {
    // The agent's identity could not be verified
    // Possible causes:
    // - Invalid DID format
    // - DID not found in registry
    // - Registry unavailable
    // - Network connectivity issues
    
    if (error.cause?.message.includes("not found")) {
      console.error("Agent not registered:", agentDid);
    } else {
      console.error("Registry error, retry later");
    }
  }
}

AgentNotLiveError

import { AgentNotLiveError } from "@a2aletheia/a2a";

try {
  await client.sendByCapability("text-generation", message);
} catch (error) {
  if (error instanceof AgentNotLiveError) {
    // The agent is offline or unreachable
    // Options:
    // 1. Queue the message for retry
    // 2. Find an alternative agent
    // 3. Notify the user
    
    // Find alternative agent with same capability
    const alternatives = await client.findAgents({
      capability: "text-generation",
      requireLive: true,
    });
    
    if (alternatives.length > 0) {
      // Retry with alternative
      await client.sendToAgent(alternatives[0].did, message);
    } else {
      console.log("No live agents available, message queued");
    }
  }
}

TrustScoreBelowThresholdError

import { TrustScoreBelowThresholdError } from "@a2aletheia/a2a";

try {
  await client.sendByCapability("text-generation", message);
} catch (error) {
  if (error instanceof TrustScoreBelowThresholdError) {
    // The agent's reputation is below your threshold
    console.warn(`Agent score ${error.trustScore} < ${error.threshold}`);
    
    // Options:
    // 1. Lower threshold temporarily for less critical tasks
    // 2. Use a different agent
    // 3. Log and skip for non-essential operations
    
    const response = await client.sendByCapability("text-generation", message, {
      minTrustScore: error.trustScore ?? 0,  // Accept this agent
    });
  }
}

Catching All Trust Errors

import { AletheiaA2AError } from "@a2aletheia/a2a";

try {
  await client.sendByCapability("text-generation", message);
} catch (error) {
  if (error instanceof AletheiaA2AError) {
    console.error("Trust pipeline error:", error.code);
    console.error("Message:", error.message);
    
    // Handle by error code
    switch (error.code) {
      case "DID_RESOLUTION_FAILED":
        // Identity verification failed
        break;
      case "AGENT_NOT_LIVE":
        // Agent unreachable
        break;
      case "TRUST_SCORE_BELOW_THRESHOLD":
        // Reputation too low
        break;
    }
  }
}

Trust Verification Timing

Understanding when trust verification occurs helps optimize performance.

Connection Time

When you call connect(), the pipeline runs all stages:

// Trust pipeline runs during connect
const agent = await client.connect("did:example:agent-123");
// - DID is resolved and verified
// - Agent isLive status is checked (if requireLive: true)
// - Trust score is validated (if minTrustScore > 0)

The agent object returned contains the verification results:

console.log(agent.did);          // "did:example:agent-123"
console.log(agent.isLive);       // true/false
console.log(agent.trustScore);   // 0-100 or null

Per-Message Verification

When using livenessCheckBeforeSend: true, Stage 2 runs before each message:

const client = new AletheiaA2AClient({
  livenessCheckBeforeSend: true,  // Fresh liveness probe per message
});

// Liveness is probed before each send
await client.sendByCapability("text-generation", "Message 1");
await client.sendByCapability("text-generation", "Message 2");

This adds latency but ensures the agent is live at the moment of sending.

Optimization Strategies

Cache agent connections:

// Connect once, reuse for multiple sends
const agent = await client.connect("did:example:agent-123");

await client.sendToAgent(agent.did, "Message 1");
await client.sendToAgent(agent.did, "Message 2");

Trust once, verify liveness per message:

const client = new AletheiaA2AClient({
  verifyIdentity: true,         // Verify DID on connect
  requireLive: true,            // Check cached status on connect
  livenessCheckBeforeSend: true, // Fresh probe before each send
  minTrustScore: 50,            // Validate trust on connect
});

Relaxed trust for high-volume scenarios:

const client = new AletheiaA2AClient({
  verifyIdentity: true,
  requireLive: false,           // Skip cached check
  livenessCheckBeforeSend: false, // Skip fresh probe
  minTrustScore: 30,            // Lower threshold
});

This site uses Just the Docs, a documentation theme for Jekyll.