Back to Documentation
AdvancedUpdated 2026-04-02

Delegation Chains

Per-delegation trust scoping, trust attenuation, upward escalation model, max depth enforcement, and the DelegationService API.

Delegation Chains

When an agent encounters an action above its trust tier, it does not fail silently. It escalates upward to a qualified agent. The Vorion delegation system enforces a strict principle: the executing agent uses its own authority. Low-trust agents cannot borrow authority from high-trust ones.

Implemented in packages/a3i/src/delegation/.


The Escalation Model

Vorion uses upward escalation, not weakest-link. The distinction matters:

| Model | How It Works | Risk | |-------|-------------|------| | Weakest-link | Chain trust = min(all agents). A single low-trust link limits everyone. | Penalizes legitimate collaboration | | Upward escalation | Executing agent uses its own trust. Low-trust agents get results, not authority. | Requires careful handler selection |

When Agent A (T2, score 400) needs a HIGH-risk action (requires T4+), it escalates to Agent B (T5, score 820). Agent B evaluates the request, decides whether to execute, and runs the action at its own T5 authority. Agent A gets the result but never gains elevated permissions.

sequenceDiagram
    participant A as Agent A (T2, 400)
    participant DS as DelegationService
    participant B as Agent B (T5, 820)
    participant E as ENFORCE

    A->>DS: escalate(action, riskLevel: HIGH)
    DS->>DS: Find qualified handlers (tier >= T4)
    DS->>B: EscalationRequest
    B->>B: Evaluate: should I do this?
    B->>E: Execute at own authority (T5)
    E-->>B: ALLOW (820 >= 600 threshold)
    B-->>DS: APPROVED_AND_EXECUTED + result
    DS-->>A: Result (A's trust unchanged)

Delegation Chain Structure

A chain tracks every hop from originator to executor:

interface DelegationChain {
  chainId: string;          // Unique chain identifier
  originatorId: string;     // Agent that started the chain
  chain: DelegationLink[];  // Ordered list of delegations
  effectiveTrust: number;   // Executing agent's own trust
  effectiveTier: number;    // Tier derived from effectiveTrust
  depth: number;            // chain.length
  createdAt: Date;
  active: boolean;
}

interface DelegationLink {
  fromAgentId: string;       // Agent delegating
  toAgentId: string;         // Agent receiving delegation
  trustAtDelegation: number; // Delegator's trust at time of delegation
  delegateTrust: number;     // Delegate's trust at time of delegation
  delegatedAt: Date;
  reason?: string;
}

The effectiveTrust always equals the last delegate's own trust score. This is the escalation model in action -- the executor's authority determines what is allowed.


Using DelegationService

Creating a Delegation

import { createDelegationService } from '@vorionsys/a3i';

const delegationService = createDelegationService({
  maxDepth: 5,
  enablePenaltyPropagation: true,
  requireExplicitDelegation: true,
});

const trustScores = new Map([
  ['agent-a', 400],  // T2
  ['agent-b', 820],  // T5
]);

const chain = delegationService.delegate(
  'agent-a',   // from
  'agent-b',   // to
  trustScores,
  'Need HIGH-risk database migration',
);

console.log(chain.effectiveTrust);  // 820 (agent-b's trust)
console.log(chain.effectiveTier);   // 5 (T5)
console.log(chain.depth);           // 1

Extending a Chain

Chains can extend through multiple agents:

const trustScores = new Map([
  ['agent-a', 400],  // T2
  ['agent-b', 650],  // T4
  ['agent-c', 900],  // T6
]);

// A -> B
const chain1 = delegationService.delegate('agent-a', 'agent-b', trustScores);
// effectiveTrust: 650 (agent-b)

// A -> B -> C
const chain2 = delegationService.delegate(
  'agent-b', 'agent-c', trustScores,
  'B cannot handle CRITICAL risk, escalating to C',
  chain1,  // extend existing chain
);
// effectiveTrust: 900 (agent-c, the executor)
// depth: 2

Resolving Effective Trust

const { trust, tier } = delegationService.resolveEffectiveTrust(chain2);
// trust: 900, tier: 6 (T6)
// Always the last delegate's own trust

Safety Checks

The delegation service enforces three safety rules:

1. No Self-Delegation

delegationService.delegate('agent-a', 'agent-a', trustScores);
// Throws: "Delegation rejected: SELF_DELEGATION"

2. No Circular Delegation

const chain = delegationService.delegate('agent-a', 'agent-b', trustScores);
delegationService.delegate('agent-b', 'agent-a', trustScores, undefined, chain);
// Throws: "Delegation rejected: CIRCULAR_DELEGATION"

3. Max Depth Enforcement

const service = createDelegationService({ maxDepth: 3 });
// After 3 hops:
service.delegate('agent-d', 'agent-e', trustScores, undefined, deepChain);
// Throws: "Delegation rejected: DELEGATION_DEPTH_EXCEEDED"

Default max depth is 5. Configurable per deployment.

The permission check API is also available directly:

const permission = delegationService.canDelegate(
  'agent-a', 'agent-b', currentDepth, existingChain,
);

if (!permission.allowed) {
  console.log(permission.reason);   // 'CIRCULAR_DELEGATION'
  console.log(permission.message);  // Human-readable explanation
}

Penalty Propagation

When a delegated action fails, all agents in the chain receive a penalty. This creates accountability throughout the delegation graph.

const penalties = delegationService.propagatePenalty(chain, 8.57);
// Map {
//   'agent-a' => 8.57,  // Originator
//   'agent-b' => 8.57,  // Intermediary
//   'agent-c' => 8.57,  // Executor
// }

On success, only the executing agent earns trust. The originator and intermediaries do not gain trust from delegated actions -- they only bear risk.

| Outcome | Originator | Intermediary | Executor | |---------|-----------|--------------|----------| | Success | No gain | No gain | Gains trust | | Failure | Penalized | Penalized | Penalized |

This asymmetry discourages careless delegation. If you delegate to an unqualified agent, you share the penalty when it fails.

Penalty propagation can be disabled per deployment:

const service = createDelegationService({
  enablePenaltyPropagation: false,
});
// Only the final delegate is penalized on failure

Escalation System

The escalation API handles the full lifecycle of upward requests.

Registering Handlers

Higher-trust agents register as escalation targets:

delegationService.registerEscalationTarget({
  agentId: 'supervisor-bot',
  trustScore: 820,
  tier: 5,
  capabilities: ['database_admin', 'network_config'],
  maxConcurrent: 3,
  activeEscalations: 0,
});

Escalating an Action

const response = await delegationService.escalate(
  'worker-bot',     // requestorId
  400,              // requestorTrust
  'migrate_database', // action
  'HIGH',           // riskLevel
  4,                // requiredTier (T4+)
  'Production database needs schema migration',
  { targetDb: 'prod_customers', migrationId: 'mig-042' },
);

Escalation Decisions

type EscalationDecision =
  | 'APPROVED_AND_EXECUTED'       // Handler ran the action
  | 'APPROVED_WITH_CONSTRAINTS'   // Handler ran with restrictions
  | 'DENIED'                      // Handler refused
  | 'DELEGATED'                   // Handler passed to another agent
  | 'EXPIRED';                    // Request timed out (5 min TTL)

Multipath Resolution

The escalation system tries qualified handlers in descending trust order. If the highest-trust handler denies the request, the next handler is tried. This continues until one approves or all deny.

graph TD
    REQ[Escalation Request<br/>requires T4+] --> H1{Handler 1<br/>T6, score 900}
    H1 -->|DENIED| H2{Handler 2<br/>T5, score 850}
    H2 -->|APPROVED| RESULT[Action executed<br/>at T5 authority]
    H1 -->|APPROVED| RESULT2[Action executed<br/>at T6 authority]

Configuration

interface DelegationConfig {
  maxDepth: number;                  // Default: 5
  enablePenaltyPropagation: boolean; // Default: true
  requireExplicitDelegation: boolean; // Default: true
}

When requireExplicitDelegation is true, agents must set up delegation relationships before they can delegate. Implicit delegation (any agent can delegate to any other) is available but not recommended for production.


Next Steps