Agent
Layer

AI agents operate through capability tokens, receive context bundles with citations, and propose changes through safe write workflows.

Capability model

Agents authenticate as principals but operate via capability tokens. Tokens are attenuable (macaroon-style) - each delegation can add restrictions, never remove them.

Capability token structure

CapabilityToken:
  cap_id            → unique token identifier
  principal_id      → authenticated identity
  allowed_tools[]   → query, fetch_artifact, propose_changeset, ...
  tenant_realm      → scope boundary

  caveats:
    time_window     → valid from/to
    max_bytes       → response size limit
    max_nodes       → expansion limit
    allowed_labels  → permitted record types
    citation_mode   → "verified_only" requires provenance

  signature_chain   → supports attenuation

Minimal disclosure

Every tool response is filtered to capability scope. No "oops, included extra" leaks. What you can't see, you don't get.

Attenuation only

Tokens can be delegated with additional caveats. You can never add permissions, only restrict further.

Short-lived

Tokens have explicit expiry. Long-running agents refresh tokens periodically. Revocation is immediate.

Context bundles

A context bundle is a portable object an agent can carry between tools without losing provenance. Every claim is cited; every citation is verifiable.

ContextBundle v1 (CB1)

ContextBundle:
  bundle_id              → unique identifier
  created_sys_time       → when bundle was created
  valid_time_context     → what valid-time the bundle represents
  capability_context     → hash of the capability that created it

  claims[]:
    claim_id             → unique within bundle
    content              → the actual claim/summary
    support[]            → list of citation IDs
    derivation           → pointer if computed from other claims

  citations[]:
    citation_id          → unique identifier
    artifact_ref         → multihash of source
    byte_ranges[]        → specific portions
    commit_ref           → system-time anchor

  redactions[]:
    stub                 → placeholder for redacted content
    reason               → why redacted

  verification[]:
    inclusion_proofs     → merkle proofs for commits

Bundle disclosure levels

L0: Full

All claims, all citations, full verification proofs

L1: Summary

Aggregated claims, citation counts, proof hashes only

L2: Minimal

Answer only, no supporting context, hash of bundle

Citation format

Every claim in a bundle traces to source artifacts. Citations are first-class, not afterthoughts.

Citation:
  citation_id: "cite_7f3a9b"
  artifact_ref: "sha256:a1b2c3d4..."  # content hash
  commit_ref: "commit_12345"           # when ingested
  byte_ranges:
    - start: 1024, end: 2048           # specific excerpt
  valid_time: "2025-12-15T10:00:00Z"   # when claim was true
  trust_tier: "verified"               # human-reviewed

Content-addressed

Artifact references are hashes. If the source changes, the hash changes, and the citation breaks (intentionally).

Byte-precise

Citations can point to specific byte ranges within an artifact. "This claim comes from lines 45-67 of that document."

Time-anchored

Both valid-time (when it was true) and system-time (when we knew) are captured. Full bitemporal provenance.

Safe write workflow

Agents don't write directly. They propose changes that go through review before application. Full audit trail, easy rollback.

1

Propose

Agent submits mutations with intent description and citations. System returns a diff showing what would change.

ProposeRequest:
  mutations[]     → what to change
  intent          → why this change
  citations[]     → supporting sources
2

Review

Human or policy reviews the proposal. See the diff, check citations, approve or reject.

ProposeResponse:
  proposal_id     → reference for review
  diff            → what would change
  affected[]      → impacted records
3

Apply

Approved proposals are applied atomically. Receipts generated. Rollback available via retraction if needed.

ApplyRequest:
  proposal_id     → which proposal
  approver        → who approved
  approval_ref    → evidence of approval

Why this matters: Agents can be wrong. Hallucinations happen. This workflow ensures human oversight for writes while letting agents work autonomously for reads.

Tool protocol

Agent tools follow the MCP (Model Context Protocol) pattern with Substrate-specific extensions for citations and capabilities.

Example: Query tool

Tool: substrate/query
Input:
  query: "MATCH (s:Service) WHERE s.owner = 'alice' RETURN s"
  as_of_valid: "2025-12-15T00:00:00Z"
  as_of_system: "HEAD()"
  capability_token: "cap_xxx..."

Output:
  records: [/* ... */]
  bundle: ContextBundle  # Full provenance
  receipt_id: "rcpt_yyy"

Example: Propose change tool

Tool: substrate/propose
Input:
  mutations:
    - op: "update"
      target: "service:payments"
      field: "owner"
      value: "bob"
  intent: "Transfer ownership per ticket JIRA-1234"
  citations:
    - artifact_ref: "sha256:..."  # The ticket
  capability_token: "cap_xxx..."

Output:
  proposal_id: "prop_zzz"
  diff: /* ... */
  requires_approval: true

Agent safety considerations

Prompt injection defense

Context bundles are structured data, not raw text. Agents receive parsed, validated content - not document dumps that could contain injected instructions.

Capability boundaries

An agent with "read engineering" capability can't suddenly access HR data. Scope is enforced at the storage layer, not by the agent.

Citation requirements

In "verified_only" mode, agents must cite sources for every claim. Unsupported assertions are flagged. No making things up.

Audit trail

Every agent access produces a receipt. What was requested, what was returned, what capability was used. Full reconstruction possible.

Continue reading