zanii
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)
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.
Links
- Docs & concepts — https://ledger.zanii.agency/docs
- Live transparency log — https://ledger.zanii.agency
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— verifyX-Zanii-Signatureand dispatch typed webhook events:create_webhook_receiver(secret, on={...}). Stdlib only.zanii.testing—fake_ledger()+make_identity/make_cert/make_receiptfixtures. Unit-test agents offline (no server, real Merkle proofs).zanii.monitor— independent append-only + anchor watchdog.check_once(server), or thezanii-monitorCLI.zanii.witness— independent co-signer: verify append-only, then counter-sign (create_witness(kp).cosign(sth, …),verify_cosignature).zanii.otel(pip install "zanii[otel]") —with_tracing(agent)makes everyrecordan 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.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_callsfor 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 inversebuild_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-depjson_rpc_tx_fetcherfor 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-chainedmemory.writereceipts (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 atPOST /v1/swarm):swarm_signer,build_swarm_receipt, and the authority-completeverify_swarm_receipt(delegation + scope + prev + revocation + distinct-owner segregation). -
zanii.attest— bind which code ran to a receipt: an attestation claim +attestation_hashprovenance 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-scopedsubject_tagslice viaGET /v1/subjects/{tag}).subject_tag,subject_identity,sign_subject_claim/verify_subject_claim,fetch_subject_history/fetch_my_history; stamp withagent.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 whosesubject_tagis the object'sref, with targetdata.<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 needszanii.attest). Notzanii.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 themselvessentinel.alertreceipts (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, andappeal_packputs 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(notrule_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 ascontent.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.
- pseudonymous item slices.
zanii.decisions— auditable algorithmic decisions for gig/creator workers: completeness + rule-consistency (manifest_hashrequired) + 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. Acompromisesuccession requirescompromised_at(brackets the trusted window);verify_lineagewalks A→B→C (one owner per lineage — a sale is not a succession);combined_summaryaggregates 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_msuptime proxy), compliance computed from receipts — and the per-agent hash chain makes completeness provable (INCOMPLETE_RECORDwhen 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/allowover scope patterns, first-match-wins; the constitution hash IS the receipt'smanifest_hash, soverify_governanceyields provable verdicts (a stamped forbidden action is self-incriminating; a missing stamp is a visible ungoverned action) andgovernance_trailflags 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 W3Ceddsa-jcs-2022cryptosuite, soto_vc/cv_to_vcemit spec-conformant VCs with genuineDataIntegrityProofs (forged inputs refused), andverify_vcverifies 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.jsonlisting 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 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 thezan1…address derives from the same bytes.verify_chain_agent_bindingproves a registered chain agent's claimed DID actually controls its wallet (a name-dropped DID fails);resolve_chain_agentfinds on chain → verifies binding → pulls ledger reputation. The binding proves key identity — the rest of the metadata stays self-asserted.zanii.x402gainedzanii_chain_tx_fetcher— verify ZAN settlements on the Zanii L1 with the sameverify_settlementused for EVM chains (visible = final; amounts in integer zi).zanii.paymentsknows ZAN (9 decimals):parse_money("1.5", "ZAN")→1500000000zi.
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:DaemonAgentsigns through a localzanii-signerddaemon (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).zaniiconsole 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, 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.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 4800zanii.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.report = run_conformance("packages/conformance/vectors")
Changelog
- 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 optionalguard=onzanii.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": Truewhere they say which form matched. What changes for the same input:zanii.pq.transition_payloadreturns the RFC 8785 JCS bytes of the binding (was an insertion-order JSON string);verify_transitionaccepts both.zanii.custody.build_handoff/build_custody_event/robot_handoffcommit evidence asJSON.stringifydoes; newverify_evidenceproves both forms.zanii.decisions.build_decision_receiptcommits factors asJSON.stringifydoes and also returnssubjectTagandmanifestHash(subject_tagis still returned); newverify_factorsproves both forms.zanii.admissibility.build_evidence_packuses the same text as TypeScript, sopack_hashmatches; 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 asnull(memoryagent/tags, CVowner, FTAfiling_ref/manifest_hash, bundle checkdetail). Signed objects made earlier still verify.zanii.embedbadges match@zanii/embedbyte for byte (JS rounding and number formatting,encodeURIComponentfor DIDs).ZaniiAgent.wrap_toolrecords{args, result|error}likewrapTool;kwargsappears only when keyword arguments were passed.- New
zanii.encoding.js_stringify:JSON.stringifybyte 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 morezaniiCLI commands,zanii.daemon.kubernetes_sidecar, hybrid X25519 + ML-KEM-768 sealing inzanii.pq(opens TypeScript output and vice versa;pip install "zanii[pq]"),dual_sign_with_signer, andcreate_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 ofagent_private_key: any object withpublic_keyandsign(message) -> bytes. Its public key must be the one inagent_did, and every signature is checked before use; a failed signature records nothing.create_receipt(signer=...)likewise. Code that passesagent_private_keyis unchanged. Two-way MCP:zanii.mcp_proxy.TwoWayBridgeforwards 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 matchingzanii.*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) andsign_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/coreencodes them (RFC 8785 number form,zanii.encoding.es_number);wrap_toolno 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.DaemonAgentrecords through@zanii/signerdwithout 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/conformancevectors. - 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 andverify_payloadreturned False across languages for honest data, always for non-ASCII (Arabic names, addresses). Floats are refused rather than silently hashed; new receipts carrypayload_encoding: "jcs"; pre-JCS receipts are checked withverify_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 atspast 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_toolalways returns the tool's real result or error, an error reply from/v1/headis never read as "no history", and a boundedmax_queue(default 10,000) refuses rather than drops. - 0.24.0 —
zanii.monitorno 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 andzanii.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.delegationtreats naive timestamps as UTC (no moreTypeErrorfrom verify paths on a certexpwithout a timezone);identity_bridgebindings are genuinely two-way (the token verifier must returnbound_did);sentineldetects hash-chain gaps, catches exfil sequences after a stale window, andbuild_baselinerefuses a failed delegation chain;retentionrejects decoy-key shreds and bad salts;trainproves absence from an empty set (byte-identical root);minimizationcommits 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.retentioncrypto-shredding (build_key_destruction— provable key destruction, not byte deletion), andzanii.sentinel0.2.0 (blast_radiuscould-reach vs did-reach; anunknown-windowfinding 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; extrazanii[chain]),zanii.x402zanii_chain_tx_fetcher(verify ZAN settlements), ZAN (9 dp) inzanii.payments. Also pinszanii[mcp]tomcp<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'smanifest_hash— provable governance + mid-stream change detection),zanii.pq(hybrid Ed25519+ML-DSA-65 dual-signing + anchored transition records; optional extrazanii[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_traildeliberately 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) andzanii.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-evidentsentinel.alertreceipts). 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_historyoffline verification of exactly one end user's slice viaGET /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-completeverify_swarm_receipt+build_swarm_receipt/swarm_signerfor SPEC §14 on-ledger ingest viaPOST /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-chainedmemory.writereceipts with salted content commitments and tamper-evident links (append_memory,verify_memory_chain);entry_hashis 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 withsalt=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) andzanii.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(extraszanii[langchain,openai-agents,crewai]), pluszanii.retentionandzanii.redact. - 0.4.0 —
zanii.cli(+ thezaniiconsole script),zanii.compliance,zanii.kms,zanii.witness,zanii.policy,zanii.payments,zanii.embed,zanii.connectors, andzanii.otel(zanii[otel]). - 0.3.0 — added
zanii.webhooks,zanii.testing, andzanii.monitor(+zanii-monitorCLI). - 0.2.0 — added
zanii.runtime(deterministic agent rails). - 0.1.0 — initial release: the client SDK, the pure
zanii.coreverification namespace,verify_audit_bundle,py.typed, and thezanii.mcp_proxy(pip install "zanii[mcp]").
License
Apache-2.0.
Metadata
Release files for zanii 0.26.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| zanii-0.26.1.tar.gz | 602.3 kB | Without provenance | Details for zanii-0.26.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| zanii-0.26.1-py3-none-any.whl | Python 3 | none | any | Details for zanii-0.26.1-py3-none-any.whl |
Total release size: 1.0 MB
Release files / zanii-0.26.1.tar.gz
| Download URL | zanii-0.26.1.tar.gz |
|---|---|
| Size | 602.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
051c0a7962a836c88643509a8f639e9bfebeeb4a2ea54619bbbe8b48e3950e75
|
|
BLAKE2b-256 checksum How to use checksums |
ba8a2dc4b1a937aa813876b119dd5fe26fa6e3604974c2201f8ee3b0d05b8379
|
| 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.26.1-py3-none-any.whl
| Download URL | zanii-0.26.1-py3-none-any.whl |
|---|---|
| Size | 412.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5d8910020428842df0ca7aee712eea29171bcae660264ec4455e4498006f9d36
|
|
BLAKE2b-256 checksum How to use checksums |
ca22b72706500699c45f21b40169439d7605b396e517c1245b84b611e1a8c18e
|
| 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.26.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.