integrity cli - XibalbaTechSol/integrity-core GitHub Wiki


title: integrity-cli created: 2026-07-07 updated: 2026-10-05 type: entity tags: [sdk, identity] confidence: high source_files:

  • integrity-cli/integrity_cli/main.py
  • integrity-cli/integrity_cli/identity.py
  • integrity-cli/integrity_cli/wallet.py
  • integrity-cli/integrity_cli/chain.py
  • integrity-cli/integrity_cli/bcc.py
  • integrity-cli/integrity_cli/config.py
  • integrity-cli/integrity_cli/vault.py
  • integrity-cli/integrity_cli/hooks.py
  • integrity-sdk/integrity_sdk/hook_runner.py
  • integrity-cli/tests/test_register_oracle_e2e.py
  • integrity-cli/tests/test_chain.py
  • integrity-cli/tests/test_hooks.py
  • integrity-cli/integrity_cli/verify.py
  • integrity-cli/tests/test_verify.py
  • integrity-cli/tests/test_verify_decision_trace.py

Table of contents

Overview

Developer CLI (Python/Typer) โ€” the human-driven counterpart to integrity-sdk, carrying its own copy of the identity/wallet/ chain logic (no sibling-import) but kept wire-compatible byte-for-byte.

integrity agent register runs the real self-sovereign on-chain sequence โ€” fund the agent's own EVM wallet โ†’ mint testnet $ITK โ†’ deploy SovereignAgent + StateAnchor โ†’ grant anchor role via execute โ†’ AgentPrimitivesFactory.registerPrimitives โ†’ POST to the oracle. It is a multi-transaction, multi-second command, not a single HTTP POST. See agent primitives.

Other commands: identity keygen/show (Ed25519 DID, full sha256(pubkey) fingerprint), agent show/ais (oracle lookups), and agent intercept --covered-entity (build a signed BCC commitment and POST it to the policy gate; exit 1 on a policy rejection, so it's scriptable).

vault command group, added 2026-07-30 (sync), bridging the CLI with the Trust Vault primitive-level persistent memory architecture (mirrors integrity_sdk/memory.py). Allows local tools to directly parse session facts (e.g. from transcript.jsonl) into the MemoryBackend (default: JSONLBackend), calculate a new cryptographic state root, and anchor it on-chain to the agent's StateAnchor contract.

xns command group, added 2026-07-11 (register/resolve/primary-handle/ set-primary/release), covering the new XibalbaNameService contract. All three writes route through SovereignAgent.execute โ€” calling XNS directly with the controller EOA as signer makes msg.sender the wrong address (XibalbaAgentRegistry.isRegisteredAgent only recognizes the SovereignAgent contract address), a real bug an early version of this work shipped and only caught via the real anvil end-to-end test in test_chain.py, not the Solidity-side unit tests (which correctly vm.prank the SovereignAgent address directly and so never exercised the CLI's own calling convention). register/set-primary/release resolve the caller's own SovereignAgent address via a GET /v1/agent/{did} oracle lookup first (that mapping isn't persisted locally by agent register). Superseded as the primary handle system as of 2026-09-26 (PRODUCTION_GAPS.md #71): these five subcommands still operate the on-chain XibalbaNameService singleton, now scoped to optional alias listing rather than an agent's primary identity โ€” see the two new subcommands below for the actual primary path.

xns available/xns claim, added 2026-09-26, cover the new Oracle-local xns_handles directory (see integrity-oracle's "XNS handle directory" section) โ€” no chain write, no gas, no wallet required. agent_register also gained a mandatory --handle option (auto-derived from --alias when omitted), validated client-side by _validate_xns_handle_format() before the oracle POST, since registration now claims a handle transactionally alongside primitive registration.

Security: no insecure default auth token (the old prototype's "mock_demo_token" is gone); placeholder tokens are refused outside ENVIRONMENT=local.

57 tests (pytest, incl. 1 opt-in ORACLE_E2E test): CliRunner + httpx-mock unit tests, a real anvil integration test (test_chain.py) that spins up a live chain, runs the real Deploy.s.sol, and exercises the CLI's on-chain code for real โ€” including, as of 2026-07-11, the new xns commands and a negative test proving isRegisteredAgent rejects a real-but-unindexed SovereignAgent โ€” plus test_register_oracle_e2e.py (opt-in via ORACLE_E2E=1, see below).

Resolved gap (found 2026-07-09, fixed 2026-07-09): main.py's agent register command hand-builds its own oracle POST body (it does not call integrity_sdk.registration.register_agent, per this page's "carrying its own copy" note above) โ€” it used to send {"agent_id": agent_did, "alias", "description", "did_document": doc, "primitives": registration.to_dict()}, the exact same schema drift integrity-sdk/integrity_sdk/registration.py had until 2026-07-09 (see integrity-sdk's fix note and docs/INTERFACE_CONTRACT.md ยง6.3's documented real schema): missing the required did field (sent as agent_id instead) and never sending eth_address_hex/ed25519_pubkey_hex, so integrity agent register without --skip-oracle 422/400'd against a real oracle the same way the SDK used to. Fixed the same day by rewriting the payload in main.py's agent_register to send {"did", "did_document", "primitives": {the 7 real fields, built explicitly rather than via registration.to_dict()}, "ed25519_pubkey_hex": "0x"+private_key.public_key().public_bytes_raw().hex(), "eth_address_hex": evm_account.address, "alias", "description"}โ€”alias/descriptionare kept as CLI-only metadata the oracle's struct has nodeny_unknown_fieldsfor, so it silently ignores them, same reasoningintegrity-sdkused. Verified for real against a live localcargo runoracle (fresh anvil +Deploy.s.sol/DeployMarkets.s.sol, ephemeral Postgres/Redis via Docker): integrity agent register --alias verify-cli-bot ...(no--skip-oracle) printed "Oracle accepted the registration", and a real GET /v1/agent/{did}on that same oracle returnedhas_ed25519_key: true, has_eth_address: truewith matching primitives, and the DID appeared in a realGET /v1/agents. New regression test integrity-cli/tests/test_register_oracle_e2e.py(opt-in viaORACLE_E2E=1, same gate name integrity-oracle/backend/tests/e2e.rsandintegrity-sdk/tests/test_registration_oracle_e2e.pyuse, mirroring that SDK test'soracle_backend` fixture pattern โ€” ephemeral Docker Postgres/Redis

  • real cargo run) drives the CLI's actual agent register Typer command via CliRunner, asserts success, and independently re-confirms via real GET /v1/agent/{did} + GET /v1/agents calls. Ran green standalone (ORACLE_E2E=1 uv run pytest tests/test_register_oracle_e2e.py) and as part of the full suite (skipped when ORACLE_E2E unset, as designed).

hooks install/hooks uninstall, added 2026-10-05 (B3): installs marker-tagged (# integrity-hooks:v1, carried in the command string itself, not a side-car manifest) PreToolUse/PostToolUse hook entries into a harness's settings.json, plus a public agent.did.json in the harness root with the private key stored outside it (integrity_sdk.did's harness-root layout). This is the one command in this package that imports integrity_sdk (did, and for --gate shield hook_runner.default_shield_socket_path; neither loads the connector stack) -- a deliberate, owner-approved exception to the "no sibling dependency" rule the rest of this file documents, because this command's whole job is to install the SDK's own identity layout (see hooks.py's module docstring for the full rationale). Installed hooks invoke python -m integrity_sdk.hook_runner out-of-process (--gate bcc: a real signed BCC commitment POSTed to bcc_middleware; --gate shield: a digest of the tool input sent to Shield's local gate daemon over a Unix socket โ€” accepted since 2026-10-06, and install then reports whether a daemon is actually listening and which DID to register with it, because the runner fails open when the daemon is unreachable and an unserved hook enforces nothing; --memory cortex: a redacted event POSTed to Cortex's /api/otel/batch). Idempotent (reinstall leaves settings.json JSON-equal); uninstall removes exactly the marked entries and never touches the DID file or key. 22 new tests across both packages (integrity-sdk/tests/unit/test_hook_runner.py, integrity-cli/tests/test_hooks.py).

integrity verify --decision-trace/--trace-evidence, added 2026-10-05 (B4): the existing verify command (main.py, verify.py -- signature/chain/checkpoint/ inclusion/anchor, independently reimplemented with no SDK import per the convention above) gained a second, explicitly SDK-backed path for B4's DecisionTrace evidence: integrity_sdk.core.verify_decision_trace_offline checks parent links and domain-separated Merkle inclusion, and any carried Jev advisory status is reported as its own advisory_status field (available/unavailable/rejected/not_present) that never fails the command by itself (C11: advisory, never authoritative). Also fixed a bug this session's bcc_middleware change exposed: --anchor-contract used to require the supplied root equal StateAnchor.latestRoot(), which only ever held for a per-agent anchor -- now relies on verifyLeaf's own isAnchoredRoot check, the real guarantee, so it works correctly against B4's shared evidence anchor too. tests/test_verify_decision_trace.py (5/5).

Related: integrity-sdk, agent primitives, BCC, DID.