exochain-avc 0.2.0-beta

EXOCHAIN Autonomous Volition Credential — portable signed credential for autonomous agent intent, authority, constraints, delegation, revocation, and trust receipts
Documentation

exo-avc — Autonomous Volition Credential

AVC is a portable, signed, machine-verifiable credential that defines what an autonomous actor is authorized to pursue under a human or organizational principal.

Identity proves who an actor is. Authority proves who delegated power. Consent proves what posture applies. AVC proves what autonomous intent is allowed before action occurs.

In this crate, volition strictly means delegated operational intent. It does not denote consciousness, sentience, emotion, or human-like free will.

Determinism contract

  • All collections in signed payloads are sorted and deduplicated.
  • All hashing is BLAKE3 over canonical CBOR — only ordered maps and sets (BTreeMap, BTreeSet), no platform-dependent integer widths, and no floating-point arithmetic.
  • Validation never reads system time; the caller passes now.
  • Validation is fail-closed: any unresolved key, missing required reference, malformed structural value, scope violation, expiration, or revocation produces an explicit Deny decision with reason codes describing why.

High-level API

use exo_avc::{
    AutonomyLevel, AuthorityScope, AvcConstraints, AvcDraft, AvcSubjectKind,
    DelegatedIntent, InMemoryAvcRegistry, AvcRegistryWrite, AvcValidationRequest,
    AvcDecision, issue_avc, validate_avc, AVC_SCHEMA_VERSION,
};
use exo_authority::permission::Permission;
use exo_core::{Did, Hash256, Timestamp};
use exo_core::crypto::KeyPair;

let issuer_keypair = KeyPair::from_secret_bytes([0x11; 32]).unwrap();
let issuer_did = Did::new("did:exo:issuer").unwrap();
let mut registry = InMemoryAvcRegistry::new();
registry.put_public_key(issuer_did.clone(), issuer_keypair.public);

let draft = AvcDraft {
    schema_version: AVC_SCHEMA_VERSION,
    issuer_did: issuer_did.clone(),
    principal_did: issuer_did.clone(),
    subject_did: Did::new("did:exo:agent").unwrap(),
    holder_did: None,
    subject_kind: AvcSubjectKind::AiAgent {
        model_id: "alpha".into(),
        agent_version: None,
    },
    created_at: Timestamp::new(1_000, 0),
    expires_at: Some(Timestamp::new(2_000, 0)),
    delegated_intent: DelegatedIntent {
        intent_id: Hash256::from_bytes([0xAA; 32]),
        purpose: "research".into(),
        allowed_objectives: vec!["primary".into()],
        prohibited_objectives: vec![],
        autonomy_level: AutonomyLevel::Draft,
        delegation_allowed: false,
    },
    authority_scope: AuthorityScope {
        permissions: vec![Permission::Read],
        tools: vec![],
        data_classes: vec![],
        counterparties: vec![],
        jurisdictions: vec!["US".into()],
    },
    constraints: AvcConstraints::permissive(),
    authority_chain: None,
    consent_refs: vec![],
    policy_refs: vec![],
    parent_avc_id: None,
};

let credential = issue_avc(draft, |bytes| issuer_keypair.sign(bytes)).unwrap();
let request = AvcValidationRequest {
    credential,
    action: None,
    now: Timestamp::new(1_500, 0),
};
let result = validate_avc(&request, &registry).unwrap();
assert_eq!(result.decision, AvcDecision::Allow);