1. Install
# requires Python 3.11+ # clone the verdra repo, then: pip install -e ./sdk/python/verdra-record
# with repo credentials configured: # repository URL provided per engagement pip install verdra-record
# PyPI release follows V0.1 schema freeze:
pip install verdra-record
// the TypeScript package tracks the Python schema; ETA Q3 2026 npm install @verdra/record // or: pnpm add @verdra/record · bun add @verdra/record
2. Quickstart, Python
Wrap any agent action with @record.capture(...). The SDK reads the runtime configuration at the call site, runs the four-strata capture, signs the package with your customer-held key, and writes it to your storage.
from verdra_record import Record from langgraph.graph import StateGraph # customer-held signing key + customer-controlled storage record = Record( principal="Orion Treasury Corp.", storage="s3://orion-evidence/verdra/", signing_key="./orion.ed25519.priv", # or raw 32-byte seed schema_version="verdra/v0.1", ) # Production engagements wire signing through KMS (AWS KMS, GCP KMS, # Azure Key Vault, or HSM); see /security for the integration pattern. @record.capture( strata=["a", "b", "c", "d"], configuration={"model": "claude-sonnet-4-5", "tools": ["pay"], "spend_cap": "5000 USDC/day"}, mandate={"delegation": "dlg_4b2e", "scope": ["pay", "ship"], "expires": "2026-12-31"}, ) def issue_payment(graph: StateGraph, mandate: dict) -> dict: # your existing agent logic, unchanged return graph.invoke(mandate) # every call produces a signed Evidence Package in your bucket result = issue_payment(graph, mandate={"to": "vendr-fulfill-2", "amount": "1847.20 USDC"}) # result["_verdra_package_id"] => "EP-..." (also retrievable via the SDK return)
3. Quickstart, TypeScript
import { Record } from "@verdra/record"; import { Agent, tool } from "@openai/agents"; const record = new Record({ principal: "Orion Treasury Corp.", storage: "s3://orion-evidence/verdra/", schemaVersion: "v0.1", }); const issuePayment = record.capture(async (mandate) => { const agent = new Agent({ name: "orion-procure-7" }); return await agent.run(mandate); }); // every call produces a signed Evidence Package in your bucket await issuePayment({ to: "vendr-fulfill-2", amount: "1847.20 USDC" });
4. Runtime adapters
The base @record.capture(...) decorator works against any callable today. The framework adapters below wrap idiomatic hook points in each runtime so you don’t have to thread the strata through manually; they ship behind the V0.1 schema freeze on the cadence noted in each card. Until then, use the base decorator with explicit configuration={...} and mandate={...}; see §2 above.
configuration={...} and mandate={...}; the SDK signs, persists, and verifies. Works against any callable, including in-house runtimes.
Today
Agent.run(). Captures tool inventory and instructions hash; native streaming preserved.
V1.0 roadmap
tool_use blocks in messages.create. Captures system prompt hash and tool schemas in S(b).
V1.0 roadmap
5. Evidence Package shape
Every captured action produces an Evidence Package conforming to the public Verdra Rules schema. Top-level fields:
| Field | Type | Description |
|---|---|---|
| id | string | Content address: EP- + first 32 hex chars (128 bits) of BLAKE3-256 over the canonical body, excluding id and signature. |
| schema | string | Schema version pin, e.g. verdra/v0.1. |
| principal | string | Customer-supplied principal identifier; informational, not validated by the schema. |
| captured_at | string | ISO 8601 / RFC 3339 UTC timestamp at millisecond precision. |
| strata.a | object | Transaction stratum: counterparty, payload, rail, reference, timestamp. |
| strata.b | object | Configuration stratum: prompt hash, tool inventory, model + version, spend caps at dispatch. |
| strata.c | object | Behavior stratum: counterfactual decision trace, tool calls, latencies. |
| strata.d | object | Mandate stratum: principal-signed delegation, scope, limits, expiry. |
| signed_with | object | Algorithm + public key, bound into the signed canonical body. Tampering with either changes the recomputed id and breaks the signature. {algorithm: "ed25519", public_key: "ed25519:<hex>"}. |
| timestamp | object | RFC 3161 timestamp token from an external authority. V0.1 records {mode: "deferred"} as a forward commitment per Rules P.5. |
| storage | object | Customer-controlled storage URI. Verdra has no write path. |
| signature | object | Customer Ed25519 signature over the canonical body. {value: "<128-hex>"}; algorithm and pubkey live in signed_with so they are part of the signed bytes. |
6. Verifying a package
# anyone with the public key can verify, offline: verdra-record verify ./EP-ed594af8f57ff7c6a5a290ea78b4ffc1.ep.json \ --pubkey ./orion.ed25519.pub # [OK] EP-... schema=verdra/v0.1 # signature_valid: True # content_address_matches:True # timestamp_valid: False (RFC 3161 deferred, forward commitment per Rules P.5)
from verdra_record import verify_package # adjudicators, counsel, auditors, or counterparties can verify offline # using only the public schema and the customer's pubkey. result = verify_package( "./EP-ed594af8f57ff7c6a5a290ea78b4ffc1.ep.json", pubkey="./orion.ed25519.pub", # raw 32 bytes, or "ed25519:<hex>" text form ) assert result.signature_valid assert result.content_address_matches # result.timestamp_valid is False in V0.1 (TSA deferred); see notes: for note in result.notes: print(note)
7. What the SDK does not do
- It does not change agent behavior. Capture is read-side; agent logic returns its normal value.
- It does not phone home with package contents. Packages stay in customer storage.
- It does not require a Verdra account at runtime. Verification is offline against the public schema.
- It does not couple to a specific DR venue. The same package routes to counsel, an insurer, a payment network, or any compliant DR forum.