Skip to main content

zanii

Install from PyPI with pip install zanii. The Proof/runtime helpers below were added in 0.27.0. Base Python>=3.10 support remains. The optional CrewAI extra pulls in upstream packages (ChromaDB, and on Python 3.10 Pillow and filelock) with published advisories that had no compatible fixed release when checked; the base SDK does not depend on them. Docs: https://ledger.zanii.agency/docs.

For explicit lifetime management, agent.close(flush=False) stops new recording and new wrapped-tool invocations, waits for active SDK signing/persistence/delivery work, and leaves signed pending receipts in the caller-owned journal. Close the journal only after the agent closes. Select flush=True explicitly to initiate a final delivery attempt. An already-running wrapped tool keeps its original result/exception, but its later outcome cannot be recorded after shutdown; settle tools first when that evidence is required. Shutdown does not abort a provider, erase keys or delete recovery state.

Verifiable identity and proof-of-action for AI agents. Give every agent a cryptographic identity (did:key), scope what it's allowed to do with signed delegation certificates, and emit a tamper-proof, hash-chained receipt for every action it takes — anchored in an RFC 6962 Merkle transparency log. Anyone can verify what an agent did, offline, without trusting the server that stored it.

Full protocol parity with the TypeScript SDK (@zanii/core / @zanii/sdk) — cross-language test vectors guarantee byte-identical hashes and signatures. The only runtime dependency is cryptography.

pip install zanii

Quickstart

from zanii import ZaniiAgent, fetch_and_verify_proof
from zanii.core import generate_keypair, create_cert

# 1. Identities. The owner delegates a scoped, expiring capability to the agent.
owner = generate_keypair()
agent = generate_keypair()
cert = create_cert(
    issuer=owner.did,
    subject=agent.did,
    scopes=["crm.*"],                 # this agent may only act within crm.*
    exp="2027-01-01T00:00:00Z",
    issuer_private_key=owner.private_key,
)

# 2. Instrument the agent. Every action is signed and hash-chained locally,
#    then batched to the log.
zanii = ZaniiAgent(
    server_url="https://ledger.zanii.agency",
    agent_did=agent.did,
    agent_private_key=agent.private_key,
    delegation=[cert],
    # api_key="zk_live_...",          # required when the log enforces write auth
)
receipt, receipt_hash = zanii.record(target="crm.lookup", payload={"email": "a@b.co"})
zanii.flush()                         # ship queued receipts to the log

# 3. Anyone can verify that proof — offline, zero trust in the server.
proof = fetch_and_verify_proof("https://ledger.zanii.agency", receipt_hash)
assert proof.ok

wrap_tool instruments an existing function so every call (sync or async) is recorded automatically — result on success, error on failure:

lookup = zanii.wrap_tool("crm.lookup", crm.find)   # crm.find is your own function
lookup("a@b.co")                                    # transparently receipted

zanii.core — pure verification, no network

Import from zanii.core when you only build or verify proofs and never touch the network (an auditor, a third-party verifier, an offline signer). Everything there is deterministic and does no I/O; the network client lives on the top-level zanii package.

from zanii.core import verify_audit_bundle

# A self-contained audit bundle (GET /v1/export/{agent_did}) is verified with no
# trusted party: signatures, delegation scope, Merkle inclusion, the per-agent
# hash chain, and on-chain anchor consistency.
report = verify_audit_bundle(bundle)
assert report.ok, [c for c in report.checks if not c["ok"]]

Fully typed — ships py.typed (PEP 561), so your type-checker sees every signature.

MCP proxy

Front any MCP server so every tool call is receipted — no changes to the agent or the upstream server. Install the extra:

pip install "zanii[mcp]"

Wrap a connected upstream ClientSession with a ZaniiAgent; serve the result in place of the real server. Tool lists pass through unchanged; each call is recorded as mcp.<tool> — result on success, error on failure.

from zanii import ZaniiAgent
from zanii.mcp_proxy import create_zanii_proxy

proxy = create_zanii_proxy(upstream_session, ZaniiAgent(...))

Or run it standalone over stdio, wrapping an upstream stdio MCP server:

ZANII_SERVER=https://ledger.zanii.agency ZANII_IDENTITY=./identity.json \
    python -m zanii.mcp_proxy -- npx some-mcp-server --its-args

Two-way: TwoWayBridge forwards the upstream server's sampling, elicitation and roots requests to your client and records each with its answer (mcp.sampling, mcp.elicitation, mcp.roots). The stdio runner turns it on with ZANII_MCP_TWO_WAY=1.

from zanii.mcp_proxy import TwoWayBridge, create_zanii_proxy

bridge = TwoWayBridge(zanii)
async with ClientSession(read, write, **bridge.callbacks()) as upstream:
    await upstream.initialize()
    proxy = create_zanii_proxy(upstream, zanii, bridge=bridge)

Several upstream servers behind one proxy: create_multi_server_proxy({"crm": crm, "docs": docs}, zanii, guard=g) names tools and prompts <server>__<name> and records mcp.<server>.<tool>, mcp.<server>.resource and mcp.<server>.prompt. Resource URIs become mcp-router://<server>/<encoded uri> (the Python MCP SDK only accepts URL-shaped resource URIs). server_reliability(records) gives calls, errors, guard blocks and errorRate per server from the recorded {target, payload} pairs.

Agent runtime — deterministic rails

The SDK above records proofs. zanii.runtime (optional) is the layer that governs the action itself: the model proposes, tested code disposes. It enforces the accountability rules that sit above the ledger — scoped authority, "no external receipt → no claim of success", a fixed status vocabulary, manifest validation, and a human confirmation gate for irreversible actions.

pip install "zanii[runtime]"   # pure logic, no extra deps — ships with base zanii too
from zanii import ZaniiAgent
from zanii.runtime import Runtime, Tool, ToolResult

def send_email(to, subject):
    provider_id = mail.send(to, subject)          # your real integration
    return ToolResult(ok=True, receipt_id=provider_id)   # the provider's receipt

rt = Runtime(ZaniiAgent(...), [
    Tool("email.send", scope="email.*", run=send_email, irreversible=True),
])

d = rt.propose("email.send", {"to": "a@b.co", "subject": "Hi"}, intent="follow up")
# → irreversible ⇒ d.status == "awaiting_confirmation"; nothing sent yet
d = rt.confirm(d.confirmation_id)                 # owner says yes (bound to this exact action)
# → d.status == "sent" (a provider receipt was returned) and it's recorded on the ledger

Status is earned: no receipt_id ⇒ attempted (never sent); a matched read-back ⇒ confirmed; a thrown tool ⇒ failed. Out-of-scope or unknown tools are rejected before anything runs; low confidence returns clarify instead of guessing.

Co-signed interactions (A2A)

Two agents from different organisations sign one receipt (SPEC §9), with the same bytes as @zanii/sdk:

draft = initiator.a2a_draft("quote.request", {"sku": "A-1"})   # sent to the responder
accepted = responder.a2a_accept(draft)                          # {"body", "sig"}, sent back
receipt, hash_ = initiator.a2a_finalize(accepted)              # local key or `signer`
initiator.submit_interaction(receipt)                           # POST /v1/interactions, re-syncs the head
responder.sync_head()                                           # before the responder records again

Proof, delivery and optional recovery

preflight_signer(adapter, operation, expected_agent_id=..., expected_log_id=...) reports optional declared receipt/document/approval/witness/PQ capabilities. Old adapters remain unknown; no signing or local-key fallback occurs. Native SDK and daemon clients declare receipt-only support, and an undeclared log identity stays unknown. The adapter's declaration is separate from operation authorization or a live HSM check.

zanii.provenance.build_configuration_artifact creates a separate versioned signed configuration/content digest with explicit exclusions/provenance and a predecessor reference for changed resumed runs. Existing product fingerprints remain unchanged. The optional resolve_private_evidence authenticates a signed recipient/purpose/field grant and delegates current access/revocation to the customer's protected resolver; it returns only verified selected disclosures. Use zanii.proof_evidence.provider_reference(provider, action_id) for unambiguous provider IDs before committing them in private payload evidence.

The additive client helpers are record_and_confirm, get_delivery_status, fetch_and_verify_bundle, get_proof_details and wait_for_anchor. Confirmation matches the exact signed hash; accepted delivery, mathematical verification and independent chain settlement are separate results. Existing calls keep their defaults.

with ZaniiAgent(...) as agent: flushes and closes at scope exit; a delivery failure never hides an exception raised in the block (it is warned instead). Opt-in flush_interval= seconds ships the queue from a background thread (with the usual backoff), and flush_on_exit=True makes one delivery attempt at interpreter exit, bounded by exit_timeout= (default 5 s), and warns about anything still undelivered. Both only deliver: undelivered receipts stay queued and journaled.

zanii.aio provides AsyncZaniiAgent, the same agent for asyncio: record, flush, close, record_durably, recover_pending_receipts, record_and_confirm, get_delivery_status, sync_head and close_session are coroutines, wrap_tool returns a coroutine function, and async with flushes and closes. It runs the sync agent's own code in worker threads (asyncio.to_thread, stdlib only), so its receipts are byte-identical.

zanii.durable provides the optional encrypted FileReceiptJournal for solo receipts. Configure it when constructing the client, with a caller-managed encryption key and protected storage, before recording. Recover exact signed receipts with recover_pending_receipts; retrieve the retained nonce for private commitment checks. A second writer, wrong binding/key or conflicting log head fails closed. Journal mode rejects unsupported A2A signing before state changes; ordinary A2A remains available without a journal. Limits: losing the encryption key makes the journal unreadable; a crashed writer leaves a lock that an operator removes only after confirming that writer stopped; protected backups, rollback detection and (on Windows) directory durability and file permissions remain your responsibility. Memory-only recording is unchanged.

zanii.sql_journal provides SqlReceiptJournal(connection, agent_id=, server_url=, key=, dialect='sqlite'|'postgres', table='zanii_journal', takeover=False) over a DB-API 2.0 connection (sqlite3, or psycopg with dialect='postgres') and sql_journal_schema(dialect, table) for the DDL. Tables, sealing and single-owner fencing match @zanii/sdk/sql-journal; each write commits before returning. zanii.journal_testkit.run_journal_conformance(open_journal, corrupt=None) checks any custom journal against the guarantees FileReceiptJournal provides. fetch_and_verify_bundle_paged(server_url, agent_id, page_size=500, max_bytes=..., on_page=None) verifies a large export page by page against one pinned signed tree head.

verify_private_evidence, build_audit_pack and reconcile_capture compose existing verification and optional modules. Packs include only explicitly selected artifacts; unknown or unsigned inventory does not establish complete capture. Missing external settlement/witness policies remain not_checked.

zanii.runtime_execution supplies the coordination types and optional action stores used by the six helpers exported through zanii.runtime: validate_action, execute_with_evidence, execute_once, cancel_action, get_action_status and cancel_confirmation. Provider outcomes and evidence delivery remain separate. A recovered dispatched or uncertain action is never automatically invoked again. The file action store allows one writer per directory, a crashed writer's lock needs operator reconciliation, and network filesystems or multi-host coordination are not supported.

fetch_and_verify_proof("", "https://ledger.zanii.agency/verify/sha256:...", payload=..., nonce=...) checks a proof and its payload in one call: the target may be a bare hash, a /verify/<hash> path or URL (parse_proof_target), and report.payload["status"] is matches, mismatch (then ok is false) or not_checked. Pass the value given to record(), or bytes of the exact committed bytes; omit nonce for salt=False. get_proof_details(evidence, payload=..., nonce=...) does the same offline.

submit_revocation(server, create_revocation(cert, ts, owner_key), api_key=...) sends an owner-signed revocation (verified locally first, the answer must name this cert); check_revocation(server, cert_or_hash) and list_revocations(server) read the log's current list. CLI: zanii revoke ... --submit and zanii revocations [<cert.json>|<hash>].

ZaniiAgent(..., retry={"max_attempts": 8, "base_seconds": 0.5, "cap_seconds": 60, "jitter": 0.2}, on_delivered=..., on_retrying=..., on_failed=...) configures upload retries. Defaults keep the existing schedule (unlimited, 0.3 s doubling, 30 s cap, no jitter). After max_attempts consecutive failures receipts stay queued, on_failed fires and only an explicit flush() retries. A callback that raises is ignored.

Errors

zanii.errors gives every error the SDK raises a stable code. Each class also inherits the built-in type raised before (ZaniiValueError, ZaniiTypeError, ZaniiRuntimeError, ZaniiAssertionError; ZaniiHttpError is a RuntimeError with status and server_code; ZaniiNetworkError is a urllib.error.URLError with the same reason), and messages are unchanged, so existing except ValueError / except RuntimeError blocks keep working. Messages and details never carry API keys, payloads or private evidence.

from zanii.errors import ZaniiHttpError, is_zanii_error

try:
    agent.flush()
except ZaniiHttpError as e:
    print(e.status, e.server_code)
except RuntimeError as e:
    if not is_zanii_error(e, "QUEUE_FULL"):
        raise

ZANII_ERROR_CODES is identical to @zanii/sdk (shared fixture @zanii/conformance/error-codes-v1.json):

Code Meaning
INVALID_OPTIONS Constructor or call options are missing, malformed or inconsistent.
INVALID_ARGUMENT An argument value is malformed (proof target, hash, reference, window, payload context).
SIGNER_KEY_MISMATCH The signer public key is not the key in the agent DID.
AGENT_CLOSED The agent is closed or closing.
INVALID_STATE The call is not allowed in the current state of the agent or reader.
QUEUE_FULL The receipt queue is full; nothing was recorded.
NETWORK_FAILED The request failed without a usable HTTP answer.
TIMEOUT A deadline was reached; the remote side may still have acted.
CANCELLED The caller cancelled the operation.
HEAD_SYNC_FAILED The agent chain head could not be learned from the log; nothing was recorded.
HTTP_ERROR The log answered with a non-success HTTP status (see status and serverCode).
INVALID_RESPONSE The log answer was malformed or not correlated with the request.
REDIRECT_REFUSED A proof read was redirected to another origin and refused.
LIMIT_EXCEEDED Evidence or a response exceeded a byte or structural limit.
VERIFICATION_FAILED Evidence did not verify (bundle, proof or co-signed receipt).
SIGNATURE_INVALID A signer returned a signature that does not verify against the agent DID.
SIGNER_UNAVAILABLE The signing daemon could not be reached or did not answer in time.
SIGNER_REFUSED The signing daemon refused the request.
DELEGATION_REFUSED The delegation does not allow this receipt; the log would reject it.
JOURNAL_INVALID Journal data failed authentication, binding, integrity or validation.
JOURNAL_OWNED Another writer owns the journal; stale owners need operator recovery.
JOURNAL_STOPPED The journal is closed or stopped after an I/O failure or lost ownership.
JOURNAL_CONFLICT Conflicting journal entries, log head or delivery outcome.
JOURNAL_FULL The journal reached its entry or size limit.
JOURNAL_MISMATCH The journal does not match this agent (identity, log URL, attachment or mode).
JOURNAL_CONFORMANCE_FAILED A journal implementation failed the journal conformance kit.
REVOCATION_INVALID The revocation record is not signed by the cert issuer.
REVOCATION_REJECTED The log refused the revocation record (HTTP 422).

More optional modules

Everything below ships inside this one zanii package — no extra install unless a module needs a third-party dep (those are opt-in extras, shown as zanii[…]). Import only what a task needs.

Test, observe, receive:

  • zanii.webhooks — verify X-Zanii-Signature and dispatch typed webhook events: create_webhook_receiver(secret, on={...}). Stdlib only.
  • zanii.testing — fake_ledger() + make_identity / make_cert / make_receipt fixtures. Unit-test agents offline (no server, real Merkle proofs).
  • zanii.monitor — independent append-only + anchor watchdog. check_once(server), or the zanii-monitor CLI.
  • zanii.witness — independent co-signer: verify append-only, then counter-sign (create_witness(kp).cosign(sth, …), verify_cosignature). C2SP surface for regulators running a standard witness network: sth_to_checkpoint, parse_checkpoint, cosign_checkpoint (Ed25519 cosignature/v1), encode_vkey / parse_vkey, add_checkpoint_request, the pure handle_add_checkpoint (refuses rollbacks and inconsistent views) and verify_checkpoint_quorum(cp, lines, witnesses=[...], threshold=2).
  • zanii.residency transfer rules: check_transfers(touches, from_="DIFC") classifies each cross-border touch as allowed, needs_safeguard, refused or unknown against a shipped, dated rule table (UAE PDPL Arts. 22-23, DIFC DP Law 2020 Arts. 26-27, ADGM DPR 2021 ss. 41-44). Not legal advice: the rule tables need review by counsel before use.
  • zanii.otel (pip install "zanii[otel]") — with_tracing(agent) makes every record an OpenTelemetry span.

Agent-framework adapters (receipt a whole run via the framework's own hook):

  • zanii.langchain (zanii[langchain]) — zanii_callbacks(agent) receipts every tool call in a LangChain or LangGraph run; with_zanii_config(config, agent) adds it to a runnable config's callbacks and keeps the existing ones.
  • zanii.openai_agents (zanii[openai-agents]) — ZaniiRunHooks(agent) for the OpenAI Agents SDK.
  • zanii.crewai (zanii[crewai]) — instrument_crew(crew, agent) for CrewAI.
  • zanii.connectors — wrap_toolbox / run_tool_calls for raw OpenAI/Anthropic tool calls.

Compliance & privacy:

  • zanii.compliance — build_compliance_report(bundle, controls=…) → an auditor report.
  • zanii.retention — GDPR Art. 17 deletion attestations (build_retention_attestation) and the inverse build_retention_hold — a signed attestation that records were kept (UAE 5-yr rule).
  • zanii.redact — selective disclosure: commit / disclose / verify_disclosure.
  • zanii.consent — PDPL consent grant/withdrawal receipts (build_consent_receipt, verify_consent).
  • zanii.admissibility — court-ready bilingual (Arabic/English) evidence pack for UAE Electronic Transactions 46/2021 (build_evidence_pack, render_evidence_pack_markdown).
  • zanii.fta — FTA filing evidence (Meezan/Books): build_filing_prep_receipt (prepared, never filed), build_tax_agent_handoff, verify_filing_evidence, FTA_WALL.
  • zanii.walls — UAE vertical wall presets (SCA trading, RERA, TDRA, Legal, Consumer, DIFC/ADGM): WALLS, wall_policy, wall_manifest_hash, check_output, build_eval_receipt.

Discovery, payments & identity:

  • zanii.a2a_directory — resolve an agent DID to its verified history for A2A / agent cards. resolve_agent(did), resolve_and_verify(did) (pulls + verifies the audit bundle offline), agent_did_from_card.

  • zanii.x402 — bind a payment receipt to its on-chain settlement. verify_settlement, build_x402_payment, zero-dep json_rpc_tx_fetcher for any EVM chain.

  • zanii.erc8004 — build/resolve/verify ERC-8004 agent registration files wired to Zanii proof endpoints. build_registration_file, to_data_uri, resolve_registration, verify_resolved_agent.

  • zanii.memory — provable agent memory: hash-chained memory.write receipts (salted content commitments, tamper-evident links) so an auditor can prove "why did it decide that?". append_memory, build_memory_write, verify_memory, verify_memory_chain, commit_content.

  • zanii.kya — Know Your Agent: screen a counterparty against a deny-list / injected sanctions provider before transacting, and receipt it (kya.screening). screen_agent, resolve_and_screen, build_screening_receipt, verify_screening.

  • zanii.swarm — N-party (3+) co-signed receipts for agent teams: genuine M-of-N Ed25519 threshold signatures. Offline: build_swarm_body, sign_swarm, verify_swarm. On-ledger (SPEC §14, live at POST /v1/swarm): swarm_signer, build_swarm_receipt, and the authority-complete verify_swarm_receipt (delegation + scope + prev + revocation + distinct-owner segregation).

  • zanii.attest — bind which code ran to a receipt: an attestation claim + attestation_hash provenance field, quote verification delegated to an injected verifier. attestation_hash, attestation_field, verify_attestation.

  • zanii.subject — per-subject auditability: end users hold their own key and independently verify what agents did on their account (pseudonymous, platform-scoped subject_tag slice via GET /v1/subjects/{tag}). subject_tag, subject_identity, sign_subject_claim/verify_subject_claim, fetch_subject_history/fetch_my_history; stamp with agent.record(..., subject_tag=tag).

  • zanii.data_custody: prove what happened to the data an agent touched (every touch, where it went, when the original was destroyed). A custody record is an ordinary receipt whose subject_tag is the object's ref, with target data.<class>.<op>, so a read-scoped agent cannot record an export. derive_ref, purpose_allows, build_touch/verify_touch, verify_object_chain, custody_view. Proves what was recorded, not that no off-record copy exists (that needs zanii.attest). Not zanii.custody (physical supply chains). Parity with @zanii/data-custody.

  • zanii.sentinel — runtime behavioral monitoring ("antivirus for agents"): score drift between what an agent actually does and what it was made to do (declared scopes + learned habits) from the receipt stream; alerts are themselves sentinel.alert receipts (watcher ≠ watched). build_baseline, scan (novel-target, scope-edge, rate-spike, intent-gap, exfil sequence, off-hours, + operator-mode content hook), Watcher, escalation_rule, build_alert_receipt/verify_alert.

  • zanii.credentials — verifiable institutional credentials (diplomas, licences, certifications): offline-verifiable in ms, no call to the registrar. Four checks — signature, expiry, revocation (signed list with an explicit freshness window), and a domain-bound issuer root-of-trust (.well-known/zanii-issuer.json). build_credential, verify_credential, resolve_issuer, build_revocation_list, build_presentation/verify_presentation (possession, not a bearer token). Zanii verifies institutional identity; it is never the accreditor.

  • zanii.gov — public-sector algorithmic accountability (benefits, visas, fines, licences): a state decision with no governing rulebook cannot be constructed, and appeal_pack puts a bilingual, court-ready proof of what the algorithm did to you into the citizen's own hands. build_gov_decision, citizen_tag, appeal_pack, render_appeal_pack_markdown.

  • zanii.health — medical audit trails without leaking the pattern: per-episode unlinkable tags (the patient supplies the tag, never the seed), plus who accessed the record, which model recommended what under which protocol, and which named clinician took responsibility. Break-glass is loud, not impossible (pending_break_glass — the metric, not the mandate). episode_seed, episode_tag, build_access_receipt, build_recommendation, build_clinician_confirmation, build_break_glass, protocol_trail (not rule_consistency — individualised care is correct medicine), fetch_episodes.

Real-world provenance:

  • zanii.provenance — AI-content credentials: sign an artifact's hash with the creating agent's did:key, anchor as content.created, resolve the creator to their verified history. build_content_credential, verify_content_credential, credential_receipt, resolve_creator.
  • zanii.custody — supply-chain custody chains: co-signed handoffs (a2a) + N-party events (swarm)
    • pseudonymous item slices. item_tag, build_handoff, build_custody_event, verify_custody_chain (continuity: receiver of n = giver of n+1), custody_summary. Attestations, not atoms.
  • zanii.decisions — auditable algorithmic decisions for gig/creator workers: completeness + rule-consistency (manifest_hash required) + committed factors. build_decision_receipt, verify_decision, rule_consistency (interleaved rulebooks = the red flag).

Agent economy:

  • zanii.escrow — conditional payments as verifiable agreements, never held funds: co-signed terms, a deterministic release verdict (check_release — the receipt must be Merkle-proven in the log, a bare receipt is a claim, not a trigger), and settlement instructions authorized by whoever gives something up (payer → release, payee → refund, M-of-N arbiters → either). build_escrow_body, sign_escrow, verify_escrow, check_release, build_release, build_refund, verify_instruction.
  • zanii.insurance — machine-verifiable underwriting: risk facts from the ledger's un-inflatable aggregate, deliberately never a score; deterministic flags (THIN_HISTORY, STALE, WILDCARD_AUTHORITY, …); insurer+holder co-signed policies; claims assessed against Merkle-proven incident receipts. Ledger silence is unknown, not good. build_risk_profile, risk_profile, build_policy_body, verify_policy, build_claim_body, assess_claim.
  • zanii.federation — cross-ledger interop: log-signed witness policies (create_witness_policy, verify_federated_sth — M distinct recognised witnesses), split-view gossip (gossip_once), and the equivocation proof (build_equivocation_proof / verify_equivocation_proof) — two signed STHs, same log, same size, different roots: offline-checkable, no innocent explanation.

Lifecycle, agreements, governance, post-quantum:

  • zanii.succession — key rotation with signed continuity: the owner attests "B succeeds A" so reputation/CV history survives a rotation instead of dying with the key. A compromise succession requires compromised_at (brackets the trusted window); verify_lineage walks A→B→C (one owner per lineage — a sale is not a succession); combined_summary aggregates conservatively with explicit caveats. Continuity of authority, not identity of code.
  • zanii.sla — machine-verifiable service agreements: co-signed terms (scope, window, min/max actions, max_gap_ms uptime proxy), compliance computed from receipts — and the per-agent hash chain makes completeness provable (INCOMPLETE_RECORD when a prev-link seam shows: the provider cannot hide the bad hour). build_sla_body, verify_sla, assess_compliance.
  • zanii.constitution — behavioral rules as signed policy: forbid/require_approval/ allow over scope patterns, first-match-wins; the constitution hash IS the receipt's manifest_hash, so verify_governance yields provable verdicts (a stamped forbidden action is self-incriminating; a missing stamp is a visible ungoverned action) and governance_trail flags rulebooks changing mid-stream.
  • zanii.pq (pip install "zanii[pq]") — post-quantum migration rails: hybrid Ed25519 + ML-DSA-65 (FIPS 204) dual-signing where BOTH must verify (no silent fallback), a PQ key binding signed by both keys (possession proven), and an anchored transition record so the binding provably predates any future Ed25519 break. Cross-language verified against @zanii/pq. bind_pq_key, dual_sign, verify_dual, verify_transition.

Custody, interop, legal identity:

  • zanii.broker — the credential broker that closes the custody hole: the agent never holds raw API keys — the broker does, and it injects them ONLY into calls that produced a receipt first. Fail-closed (ledger unreachable = no call), credentials bound to exact https origins (no suffix masquerade) + segment-bounded path prefixes, secrets never in hash preimages, responses scrubbed. create_broker, Broker.execute. Run it in a separate process from the agent — and delete the keys from the agent's env.
  • zanii.vc — the W3C Verifiable Credentials 2.0 bridge: Zanii's did:key + Ed25519 + JCS IS the W3C eddsa-jcs-2022 cryptosuite, so to_vc/cv_to_vc emit spec-conformant VCs with genuine DataIntegrityProofs (forged inputs refused), and verify_vc verifies anyone's did:key eddsa-jcs-2022 VC. Byte-identical with @zanii/vc. Bridges the format, not the trust model — revocation and domain binding stay Zanii-side checks.
  • zanii.kyb — owner-to-legal-entity binding, deliberately two-way: the company serves .well-known/zanii-owner.json listing its owner DIDs + entity, AND the owner signs an attestation naming that domain/entity — one-sided claims are refused. build_owner_attestation, verify_owner_binding, fetch_and_verify_owner. Domain control ≠ corporate registration — a false claim becomes attributable forever, never certified.
  • zanii.jurisdiction: signed bindings of an owner or agent did:key to the regulator, jurisdiction, licence and sector it falls under (DFSA, CBUAE, ADGM-FSRA, SAMA, VARA, SCA, EU-<CC>-MSA), self-declared or regulator-attested, so a regulator can ask "which agents are mine?". build_jurisdiction, verify_jurisdiction, latest_binding, agents_under. Byte-identical with @zanii/jurisdiction. A self-declared binding is a claim, not a licence; the code list is a Zanii registry, not an official one.

Zanii L1 bridge:

  • zanii.chain_bridge (pip install "zanii[chain]") — one keypair, two products: a Zanii L1 (blockchain.zanii.agency) wallet's Ed25519 pubkey IS a ledger did:key, and the zan1… address derives from the same bytes. verify_chain_agent_binding proves a registered chain agent's claimed DID actually controls its wallet (a name-dropped DID fails); resolve_chain_agent finds on chain → verifies binding → pulls ledger reputation. The binding proves key identity — the rest of the metadata stays self-asserted.
  • zanii.x402 gained zanii_chain_tx_fetcher — verify ZAN settlements on the Zanii L1 with the same verify_settlement used for EVM chains (visible = final; amounts in integer zi).
  • zanii.payments knows ZAN (9 decimals): parse_money("1.5", "ZAN") → 1500000000 zi.

Keys, money, embeds, CLI:

  • zanii.kms — seal agent keys at rest (seal_identity / open_identity, scrypt + AES-256-GCM).
  • zanii.daemon — record without holding the private key: DaemonAgent signs through a local zanii-signerd daemon (npm @zanii/signerd), which owns the key, the timestamps and the chain head.
  • zanii.policy — pre-action allow/deny/require_approval (create_policy_engine).
  • zanii.payments — correct money for payment receipts (build_payment, integer minor units).
  • zanii.embed — "Verified by Zanii" badge builders (agent_badge, badge_svg, and claim_badge_svg(report, claim) for one declared, scoped check result).
  • zanii console script — the CLI: zanii keygen, zanii delegate, zanii verify <hash>, …

Industry modules (Python parity with the npm packages of the same name; stdlib + cryptography only):

  • zanii.zk — Privacy primitives with no extra dependency: Pedersen commitments on ristretto255 whose totals can be checked, hash-chain "value >= t" proofs, and set-membership proofs, byte-compatible with @zanii/zk. c = commit(42); verify_opening(c["commitment"], c["opening"])

  • zanii.robotics — Receipts for AI that moves things: an owner-signed device-to-agent binding, a safety envelope checked before a command is recorded, device-signed telemetry, emergency stops, and a hash-chained black box. command_receipt(device_did=d, actuator="arm", command="move", params={"speed_mps": 1}, envelope={"maxSpeed_mps": 1.5})

  • zanii.energy — Provable grid actions in integer Wh and W: meter-signed readings, demand-response delivery checks, EV charging sessions, and an origin-certificate registry that never counts the same energy twice. consumption([r1, r2])["Wh"]

  • zanii.trading — Accountable trading desks with integer minor-unit prices: pre-trade limit checks with a hash of the rules applied, best-execution evidence, signed clock-sync statements, and order history replay. order_receipt(order, {"maxQty": 1000, "venues": ["ADX"]}, reference_minor=1000)

  • zanii.elections — Accountability for election operations, never votes: two-signature custody handoffs, tabulation batches signed by several officials, and a disclosure-enforced registry of AI political content. verify_batch(signed_batch, min_signers=2)["ok"]

  • zanii.education — Pseudonymous student tags, AI-use declarations, on-time submissions, rubric-pinned grades with a change trail, and integrity reports. from zanii.education import student_tag; tag = student_tag("S123", institution_secret)

  • zanii.legal_ai — AI work receipts on legal matters (hashes only), a supervising lawyer's signed sign-off, citation checks against your own resolver, privilege-aware selective disclosure, conflict checks, and a court statement of AI use. s = sign_off({"matter": "M-1", "workProduct": h}, lawyer_key); verify_signoff(s, lawyer_did)

  • zanii.regulator: Scoped receipt feeds for supervisors (by agent, target, risk, time and, through jurisdiction bindings, jurisdiction, sector and regulator), provably random samples (seed committed first), incident-reporting clocks from a shipped rule table labelled law, guidance or proposal (EU AI Act, NIS2, DORA, GDPR, UAE PDPL, DIFC DP Law, DIFC Regulation 10 and its 2026 proposal, CBUAE AI guidance; assumed periods flagged), signed findings and log attestations, and periodic signed supervision attestations. deadlines = clock("difc-dpl", "2026-10-19T00:00:00Z"), s = attest_supervision({...}, key)

  • zanii.regulator — Scoped receipt feeds for supervisors, provably random samples (seed committed first), incident-reporting deadlines for the EU AI Act, NIS2, DORA and GDPR, and signed findings and log attestations. deadlines = incident_clock("nis2", "2026-10-19T00:00:00.000Z")

  • zanii.incident_report (parity with @zanii/incident-report): Signed incident evidence into the EU AI Act Art. 73 serious-incident report (Commission DRAFT template SB-10407 v1.0.0) and the OECD common reporting framework (non-binding, 29 criteria), each field from the evidence, the reporter or null with a reason, in a signed incident.report with inclusion proofs. r = create_incident_report(incident, {"sth": sth, "receipts": receipts}, issued_at, key); verify_incident_report(r, sth=sth)

  • zanii.post_market (parity with @zanii/post-market): EU AI Act Art. 72 post-market monitoring and Art. 12 / 19 / 26(6) log retention evidence: a signed post_market.report with per-agent receipt counts, retention proof over 6 months by default (gaps named), incident report hashes and caller metrics. verify_post_market(create_post_market(period, evidence, issued_at, key))

  • zanii.ai_register: a regulator's AI-system register from Ledger and Certify records (agent DIDs, owner, jurisdiction binding, Certify certificate, KYB attestation, descriptive fields), exported as EU AI Act Annex VIII A/B/C, UK ATRS 4.0 and Eurocities Algorithmic Transparency Standard 0.3.1 field maps with null-with-reason for anything the inputs do not support, plus a signed zanii.ai_register snapshot and CSV / JSON helpers. Parity with @zanii/ai-register. export_eu_ai_act(build_entry(system, as_of=t), "C")

  • zanii.status_feed: one signed, append-only, hash-chained status feed per jurisdiction (delegation revocations, Certify suspensions, revocations and reinstatements, incidents, jurisdiction bindings), each event with evidence hashes; verify chain, signers, time and gaps, read since a sequence number, render Atom or JSON Feed, anchor the head as a receipt. Parity with @zanii/status-feed. verify_feed(entries, signers=[operator_did])["ok"]

  • zanii.carbon — Per-call energy and emissions receipts (measured or declared, with the intensity source), and period reports for Scope 3 / CSRD, location- and market-based. r = call_receipt("m", {"power_W": 700, "duration_ms": 1000}, intensity)

  • zanii.agent_bank — Treasury accounts for agents: policy-checked spending, a balanced double-entry journal in integer minor units, and reconciliation against rail settlements. a = AgentAccount("agent-1", {"currency": "AED", "perTx_minor": 50_000}); a.spend(request)

  • zanii.guard — An inline guard that decides before each agent action (canary tools and tokens, tool pinning, exfiltration sequences, holds after untrusted content, rate limits; monitor or enforce), plus an evolution tracker and a sandboxed harness for your own red-team probes; decisions can be recorded as signed receipts. create_zanii_proxy(upstream, agent, guard=g) checks every MCP call. g = create_guard(mode="enforce", canaries=["admin.*"], recorder=agent)

  • zanii.ai — Make an existing Python agent provable in one line: wrap your tools (callables, or objects with execute/run/invoke) and every call becomes a signed receipt; helpers also receipt model calls, streams, prompt lineage, guardrails, cost, takeovers and MCP client calls. tools = with_zanii({"crm.lookup": lookup}, agent)

  • zanii.gateway — A drop-in HTTP proxy that receipts every API call an agent makes, with no code changes (a WSGI app; opt-in allow-list, rate limits, replay blocking, PII flags, cost, salted body commitments). Binds 127.0.0.1 by default. ZANII_SERVER=https://ledger.zanii.agency python -m zanii.gateway --upstream https://api.example.com --port 4800

  • zanii.custody_verdicts — The eight subject-page rows (purpose, self-sovereign, nobody read it, never trained on, no copy kept, residency, subprocessor, minimization), computed offline from a verified history; each row is proven, not covered, failed or cannot determine, with the reason. rows = compute_verdicts(history, {"jurisdiction": ["AE"]}, verify_region=my_geo_verifier)

  • zanii.conformance — Run the language-neutral @zanii/conformance vectors against the Python SDK or your own implementation, plus seeded fuzzing, differential runs, live-server checks and signed conformance certificates; validate_integration_evidence(record, version=...) checks a dated integration-evidence record. report = run_conformance("packages/conformance/vectors")

Changelog

  • 0.28.1: Docs only. zanii.broker now shows the record callable it needs: find this call's receipt by hash in the flush() results and raise unless its status is accepted or duplicate (the npm README example checked a field that does not exist; fixed in @zanii/broker 0.1.3). No code change.

  • 0.28.0: Regulator Hub modules, all additive and byte-identical to their npm twins: new zanii.jurisdiction (signed regulator / jurisdiction / sector bindings, latest_binding, agents_under), zanii.incident_report (EU AI Act Art. 73 draft template and OECD incident reports with ledger proofs), zanii.post_market (Art. 72 post-market and log retention evidence), zanii.ai_register (Annex VIII, UK ATRS and Eurocities register exports, signed snapshots) and zanii.status_feed (signed, hash-chained per-jurisdiction status feed, Atom / JSON Feed); zanii.regulator gains the labelled regime table and clock, jurisdiction-scoped feeds and signed supervision attestations (EU-DE matches EU-wide rules).

    • zanii.witness C2SP checkpoints, cosignature/v1 cosignatures, vkeys, a pure add-checkpoint handler and a quorum check (byte-identical to @zanii/witness 0.2.0); zanii.residency.check_transfers with the shipped transfer_rules_v1.json (same bytes as @zanii/residency 0.3.0; not legal advice, needs review by counsel). Additive.
  • 0.27.0: additive proof/delivery/private-evidence/capture helpers and optional encrypted receipt journals; runtime authority/approval/budget hardening and six execution helpers; optional signer preflight and separate signed configuration artifacts. Existing signed formats, legacy payload verification and ordinary queue defaults remain. Journal mode supports solo receipts and fails before unsupported A2A signing.

    • Python parity with TypeScript: ZaniiAgent.a2a_draft / a2a_accept / a2a_finalize / submit_interaction, zanii.embed.claim_badge_svg, zanii.conformance.validate_integration_evidence, zanii.mcp_proxy.create_multi_server_proxy / server_reliability, zanii.langchain.with_zanii_config, and zanii.__version__. Checked against TS output in packages/conformance/cross-product/python-parity-v1.json. Additive.
    • Also: submit_revocation, list_revocations and check_revocation, and zanii revoke --submit / zanii revocations in the CLI; fetch_and_verify_proof(..., payload=, nonce=) and parse_proof_target for /verify/<hash> links; a configurable retry= policy with on_delivered / on_retrying / on_failed; with ZaniiAgent(...), opt-in flush_interval= and flush_on_exit=; the asyncio client zanii.aio.AsyncZaniiAgent; zanii.sql_journal.SqlReceiptJournal and zanii.journal_testkit; fetch_and_verify_bundle_paged; and typed errors (zanii.errors) that still inherit the built-in exceptions raised before, with every message unchanged. Fix: salted_payload_hash(p, "") now commits unsalted, as TypeScript does (it used to draw a random nonce, so such receipts could not be verified).
  • 0.26.2: zanii.encoding.js_stringify now matches JSON.stringify for integers beyond 2^53 (written as the nearest double, as JavaScript does) and for number keys ({1: x} becomes {"1":x}); an unsupported key type raises TypeError. Found while integrating Zanii Blackbox.

  • 0.26.1 — zanii.guard: Python parity with @zanii/guard (inline guard, evolution tracker, red-team harness; same decisions and receipts as TypeScript), and an optional guard= on zanii.mcp_proxy.create_zanii_proxy. Additive.

  • 0.26.0 — Same bytes as TypeScript, everywhere. Older Python functions that encoded data differently from the npm packages now produce exactly what TypeScript produces, so a record made in either language reproduces and verifies in the other. Verifiers still accept records made by earlier Python versions and report "legacy": True where they say which form matched. What changes for the same input:

    • zanii.pq.transition_payload returns the RFC 8785 JCS bytes of the binding (was an insertion-order JSON string); verify_transition accepts both.
    • zanii.custody.build_handoff / build_custody_event / robot_handoff commit evidence as JSON.stringify does; new verify_evidence proves both forms.
    • zanii.decisions.build_decision_receipt commits factors as JSON.stringify does and also returns subjectTag and manifestHash (subject_tag is still returned); new verify_factors proves both forms.
    • zanii.admissibility.build_evidence_pack uses the same text as TypeScript, so pack_hash matches; custody, timestamp and notarisation checks accept pre-0.26 packs.
    • zanii.memory, zanii.cv, zanii.fta, zanii.bundle: optional fields that are not set are left out instead of written as null (memory agent/tags, CV owner, FTA filing_ref/manifest_hash, bundle check detail). Signed objects made earlier still verify.
    • zanii.embed badges match @zanii/embed byte for byte (JS rounding and number formatting, encodeURIComponent for DIDs).
    • ZaniiAgent.wrap_tool records {args, result|error} like wrapTool; kwargs appears only when keyword arguments were passed.
    • New zanii.encoding.js_stringify: JSON.stringify byte for byte, for commitments the npm packages make that way.
  • 0.25.5 — The rest of the npm packages in Python: zanii.ai (wrap Python tools so every call is a receipt), zanii.gateway (a receipting HTTP proxy, python -m zanii.gateway), zanii.custody_verdicts (the eight subject-page verdicts, identical to TypeScript on all 108 recorded cases), zanii.conformance (run the conformance vectors, fuzz, certify), nine more zanii CLI commands, zanii.daemon.kubernetes_sidecar, hybrid X25519 + ML-KEM-768 sealing in zanii.pq (opens TypeScript output and vice versa; pip install "zanii[pq]"), dual_sign_with_signer, and create_sth(signer=...). Existing functions are unchanged.

  • 0.25.4 — ZaniiAgent(signer=...) records with a key held in an HSM, cloud KMS or signing service instead of agent_private_key: any object with public_key and sign(message) -> bytes. Its public key must be the one in agent_did, and every signature is checked before use; a failed signature records nothing. create_receipt(signer=...) likewise. Code that passes agent_private_key is unchanged. Two-way MCP: zanii.mcp_proxy.TwoWayBridge forwards an upstream server's sampling, elicitation and roots requests to the client and receipts each with its answer. Python parity for the expansion: the functions added across the optional npm packages now exist in the matching zanii.* modules, byte-compatible wherever they sign or hash (checked against the TypeScript output), plus ten new modules (zanii.zk, robotics, energy, trading, elections, education, legal_ai, regulator, carbon, agent_bank) and sign_object / verify_signed_object. Existing functions are unchanged.

  • 0.25.3 — protocol 1.3: payloads (and protocol objects) may contain decimals, encoded byte-for-byte as @zanii/core encodes them (RFC 8785 number form, zanii.encoding.es_number); wrap_tool no longer skips calls whose arguments or results contain one. Whole numbers beyond ±(2^53−1) stay refused, including as floats.

  • 0.25.2 — protocol 1.2: record(risk=...) labels what is at stake (low, medium, high, critical); close_session() records a session close so a verifier can tell a finished run from a cut-off one, and audit bundles report it; zanii.daemon.DaemonAgent records through @zanii/signerd without holding the key. Fixed: an honest swarm co-signer's audit bundle now verifies; object keys beyond U+FFFF order by UTF-16 code units and integers beyond ±(2^53−1) are refused, so Python and TypeScript hash identical bytes for every payload. Passes all 85 @zanii/conformance vectors.

  • 0.25.1 — record() now commits the payload as RFC 8785 JCS bytes (payload_bytes), so a payload hashed in Python and verified in TypeScript finally matches. Previously each SDK used its own serialiser and verify_payload returned False across languages for honest data, always for non-ASCII (Arabic names, addresses). Floats are refused rather than silently hashed; new receipts carry payload_encoding: "jcs"; pre-JCS receipts are checked with verify_payload_legacy, which reports which old dialect matched. SPEC §3 now specifies the encoding that was undefined.

  • 0.24.3 · A receipt the log rejects no longer breaks the chain: record() refuses an out-of-scope target (or a ts past the delegation's expiry) before signing, and a rejection from the log is warned, drops the receipts chained on it, and re-chains on the log's head.

  • 0.24.2 · Receipts survive a ledger outage: failed uploads stay queued in order and retry with backoff instead of raising into record(), wrap_tool always returns the tool's real result or error, an error reply from /v1/head is never read as "no history", and a bounded max_queue (default 10,000) refuses rather than drops.

  • 0.24.0 — zanii.monitor no longer raises false "history rewritten" alarms on a log receiving writes (TOCTOU): consistency proofs are pinned to the monitor's own signed snapshot via the SPEC's ?first=m&second=n (now honored by the server and zanii.testing), with a safe fallback for older servers; anchors written mid-run defer to the next check; same-size/different-root anchors are flagged as equivocation.

  • 0.23.0 — security & parity audit across 9 modules, every fix mirrored in TS: zanii.delegation treats naive timestamps as UTC (no more TypeError from verify paths on a cert exp without a timezone); identity_bridge bindings are genuinely two-way (the token verifier must return bound_did); sentinel detects hash-chain gaps, catches exfil sequences after a stale window, and build_baseline refuses a failed delegation chain; retention rejects decoy-key shreds and bad salts; train proves absence from an empty set (byte-identical root); minimization commits UTF-8 bytes (ensure_ascii=False) so non-ASCII field sets match TS; all verify functions return verdicts instead of raising on malformed input.

  • 0.22.0 — the data-sovereignty suite: zanii.residency ("did my data leave the country?" — region-bound touches + border-crossing detection), zanii.subprocessor ("who else touched it?" — provable onward-transfer graph, undeclared-party detection, GDPR Art. 28), zanii.minimization ("did you take only what you needed?" — declared-minimum field-set proofs, Art. 5(1)(c); byte-identical commitments), zanii.age_assurance ("prove the age gate happened" — without storing the ID; UK OSA / EU / US state laws). All zero server changes.

  • 0.21.0 — data custody & training provenance (from the Custody scope): zanii.train (training-set manifests + offline subject-absence proofs — "never used to train a model" as a yes; byte-identical roots with @zanii/train), zanii.identity_bridge (bind Entra/SPIFFE agent identities to a did:key, two-way, injected verifier), zanii.retention crypto-shredding (build_key_destruction — provable key destruction, not byte deletion), and zanii.sentinel 0.2.0 (blast_radius could-reach vs did-reach; an unknown-window finding so watcher downtime reads as UNKNOWN, never "clean").

  • 0.20.0 — the Zanii L1 bridge: zanii.chain_bridge (one keypair, two products — prove a registered chain agent's DID controls its wallet, then pull its ledger history; extra zanii[chain]), zanii.x402 zanii_chain_tx_fetcher (verify ZAN settlements), ZAN (9 dp) in zanii.payments. Also pins zanii[mcp] to mcp<2 (mcp 2.x renamed the Server API).

  • 0.19.0 — custody, interop, legal identity: zanii.broker (receipt-or-nothing credential broker — the agent never holds raw keys; fail-closed, origin-bound), zanii.vc (W3C VC 2.0 bridge with genuine eddsa-jcs-2022 DataIntegrityProofs — byte-identical across languages), zanii.kyb (two-way owner↔domain legal-entity binding).

  • 0.18.0 — lifecycle, agreements, governance, post-quantum: zanii.succession (signed continuity across key rotation; compromise brackets the trusted window), zanii.sla (co-signed terms + deterministic compliance with hash-chain-proven completeness), zanii.constitution (signed rulebooks; the hash is the receipt's manifest_hash — provable governance + mid-stream change detection), zanii.pq (hybrid Ed25519+ML-DSA-65 dual-signing + anchored transition records; optional extra zanii[pq]).

  • 0.17.0 — the agent economy layer: zanii.escrow (conditional payments — co-signed terms, Merkle-proven release verdicts, authorized settlement instructions; never held funds), zanii.insurance (underwriting risk facts — never a score — and deterministic claim assessment), zanii.federation (witness policies, split-view gossip, the equivocation proof). Byte-identical hash parity with the TS packages.

  • 0.16.0 — zanii.cv: AgentCV — a signed, portable view over the ledger (the summary is the un-inflatable ledger aggregate; curated entries each point at a verifiable ref; proves the entries are real, never that the history is complete). A Python-signed CV verifies in TS.

  • 0.15.0 — zanii.health: medical audit trails without leaking the pattern (per-episode unlinkable tags; the four-party accountability question; break-glass that is loud, not impossible; protocol_trail deliberately passes no uniformity verdict).

  • 0.14.0 — institutional trust layer: zanii.credentials (institutional credentials + the domain-bound issuer root-of-trust — the four checks, with the fourth being the one that matters) and zanii.gov (public-sector accountability; appeal_pack — the state proves what its algorithm did to you, and you hold the proof).

  • 0.13.0 — zanii.sentinel: runtime behavioral monitoring (drift detection over the receipt stream, six detectors + operator content hook, injected responses, and tamper-evident sentinel.alert receipts). Baselines are float-free (integer milli-units) so their hash is byte-identical to @zanii/sentinel.

  • 0.12.0 — real-world provenance: zanii.provenance (content credentials — the thin anti-deepfake layer), zanii.custody (co-signed supply-chain custody chains: a2a handoffs, swarm N-party events, pseudonymous item slices), zanii.decisions (auditable algorithmic decisions: completeness + rule-consistency + committed factors).

  • 0.11.0 — per-subject auditability: zanii.subject (subject_tag — a pseudonymous, platform-scoped, signature-covered receipt field + fetch_subject_history offline verification of exactly one end user's slice via GET /v1/subjects/{tag}); record(..., subject_tag=...) in the SDK.

  • 0.10.0 — loophole packages: zanii.kya (screen a counterparty before transacting, injected sanctions provider), zanii.swarm (N-party M-of-N threshold co-signed receipts; now with the authority-complete verify_swarm_receipt + build_swarm_receipt/swarm_signer for SPEC §14 on-ledger ingest via POST /v1/swarm — sig + delegation + scope + prev + revocation + distinct owners), zanii.attest (bind which code ran via an attestation claim + injected quote verifier — honest by default: no verifier means quote NOT verified).

  • 0.9.0 — zanii.memory: provable agent memory — hash-chained memory.write receipts with salted content commitments and tamper-evident links (append_memory, verify_memory_chain); entry_hash is RFC 8785 canonical, so chains verify byte-identically against @zanii/memory (TS).

  • 0.8.0 — UAE compliance: zanii.retention.build_retention_hold (kept-records attestation, inverse of deletion), zanii.consent (PDPL consent receipts), zanii.admissibility (bilingual court evidence pack, 46/2021), zanii.fta (filing evidence + FTA_WALL), zanii.walls (SCA/RERA/TDRA/Legal/Consumer + DIFC/ADGM presets).

  • 0.7.0 — discovery & commerce: zanii.a2a_directory (resolve a DID to its verified history), zanii.x402 (verify a payment receipt's on-chain settlement), zanii.erc8004 (register/resolve/verify ERC-8004 agent identities).

  • 0.6.0 — accountability fixes: salted payload commitments by default (record() — privacy/PDPL; salted_payload_hash/verify_payload, opt out with salt=False); owner-signed confirmations (zanii.core.create_confirmation; Runtime(owner_did=…) requires a signed owner approval); receipt provenance (runtime_hash/model_id/manifest_hash) + Runtime(intent_receipts=True) two-phase; infrastructure co-signatures (create_cosignature, segregation of duties) and zanii.compliance.reconcile (omission catcher).

  • 0.5.1 — docs: this page now lists every bundled module + extra (no code change).

  • 0.5.0 — framework adapters zanii.langchain / zanii.openai_agents / zanii.crewai (extras zanii[langchain,openai-agents,crewai]), plus zanii.retention and zanii.redact.

  • 0.4.0 — zanii.cli (+ the zanii console script), zanii.compliance, zanii.kms, zanii.witness, zanii.policy, zanii.payments, zanii.embed, zanii.connectors, and zanii.otel (zanii[otel]).

  • 0.3.0 — added zanii.webhooks, zanii.testing, and zanii.monitor (+ zanii-monitor CLI).

  • 0.2.0 — added zanii.runtime (deterministic agent rails).

  • 0.1.0 — initial release: the client SDK, the pure zanii.core verification namespace, verify_audit_bundle, py.typed, and the zanii.mcp_proxy (pip install "zanii[mcp]").

License

Apache-2.0.

Metadata

Release files for zanii 0.28.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zanii 0.28.1
File Size Uploaded Provenance Actions
zanii-0.28.1.tar.gz 759.9 kB Without provenance Details for zanii-0.28.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for zanii 0.28.1
File Interpreter ABI Platform Actions
zanii-0.28.1-py3-none-any.whl Python 3 none any Details for zanii-0.28.1-py3-none-any.whl

Total release size: 1.3 MB

Release files / zanii-0.28.1.tar.gz

Download URL zanii-0.28.1.tar.gz
Size 759.9 kB
Tags Source
SHA-256 checksum
How to use checksums
9cba4840a5fcda645cf1bb5cd6fc5a76c8358320de4e11e9b1e4bd289e5fd601
BLAKE2b-256 checksum
How to use checksums
a3cd0f317dfd9d2377dbf08b0bc4da65331029573e742034feb4e350ac5aead9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / zanii-0.28.1-py3-none-any.whl

Download URL zanii-0.28.1-py3-none-any.whl
Size 517.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8093bb41a49df723565c428a79686cf3fd7468457f10cc622ed2cf9047ec4900
BLAKE2b-256 checksum
How to use checksums
80f9318f1f97012e1865b31157c29687d0372202d61ffe0cfd3171efd6d7589e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Security for zanii 0.28.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.28.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page