paybondpaybond
Sign in

CLI contract

Shared command tree, flags, output shapes, exit codes, and redaction rules for the paybond CLI in TypeScript and Python.

This document is the canonical contract for the paybond CLI shipped by both kits:

  • TypeScript: @paybond/kit exposes the paybond binary.
  • Python: paybond-kit exposes the paybond binary.

Both implementations must expose the same command names, global flags, JSON output keys, exit codes, error categories, and redaction behavior. Parity tests compare --help, JSON schemas, and error handling across both kits.

Legacy entry points remain as thin wrappers over this tree:

Legacy aliasCanonical command
paybond-kit-loginpaybond login
paybond-init / paybond-kit-initpaybond init guardrail
paybond-mcp-serverpaybond mcp serve

Design rules

  • Tenant scope always comes from authenticated credentials (PAYBOND_API_KEY or the configured env file). Normal tenant-scoped commands must not accept tenant IDs from unauthenticated CLI arguments.
  • Human output defaults to safe, masked values suitable for terminals and CI logs.
  • Machine output uses --format json and returns stable, documented keys. JSON mode never omits required envelope fields.
  • Destructive or live-money actions require --yes and are still subject to server-side RBAC.
  • Secrets on disk use file mode 0600. Default .env.local targets are added to .gitignore when needed. Custom env-file paths inside a git repo must already be ignored.

Global flags

These flags are accepted on every subcommand unless a command explicitly documents an exception. Global flags may appear before or after the subcommand.

FlagDefaultDescription
--gateway <url>https://api.paybond.aiGateway base URL for authenticated API calls.
--env-file <path>.env.localLocal secrets file containing PAYBOND_API_KEY. Login writes here; other commands read from here unless the key is already in the process environment.
--format table|jsontableHuman table output or stable JSON envelope (see below).
--profile <name>(unset)Named credential profile stored in the Paybond CLI config file. When set, overrides --env-file for credential resolution.
--request-id <id>(generated)Correlation ID sent to Gateway on API calls and echoed in JSON output. When omitted, the CLI generates a ULID-style identifier.
--yesfalseSkip interactive confirmation for destructive or irreversible operations.
--no-openfalseDo not open a browser for device login or other browser-assisted flows.

Commands may define additional flags. Command-specific flags must not redefine global flag names with different semantics.

Output formats

Table (default)

  • Write human-readable lines to stdout.
  • Write errors to stderr.
  • Apply redaction rules to every field before printing.
  • Do not print raw API keys, capability tokens, signing seeds, or API bearer tokens.
  • Success lines should be concise and actionable (for example, masked key identity, resource IDs, and next steps).

JSON (--format json)

Every JSON response uses one envelope regardless of command:

{
  "ok": true,
  "command": "whoami",
  "data": {},
  "warnings": [],
  "request_id": "01JABY5EXAMPLE",
  "error": null
}

On failure:

{
  "ok": false,
  "command": "keys revoke",
  "data": null,
  "warnings": [],
  "request_id": "01JABY5EXAMPLE",
  "error": {
    "category": "forbidden",
    "code": "cli.rbac.denied",
    "message": "caller lacks keys:revoke permission",
    "details": {
      "gateway_status": 403,
      "gateway_code": "auth.forbidden"
    }
  }
}

Envelope fields:

FieldTypeDescription
okbooleantrue on success, false on failure.
commandstringCanonical command path (for example, login, whoami, audit exports list).
dataobject | nullCommand payload on success; null on failure.
warningsstring[]Non-fatal notices (for example, skipped browser open).
request_idstringCorrelation identifier for support and log correlation.
errorobject | nullPopulated on failure; null on success.

Error object fields:

FieldTypeDescription
categorystringStable error class (see error categories).
codestringStable machine-readable code (cli.* for local errors; Gateway error.code when proxied).
messagestringSafe, loggable summary without secrets.
detailsobjectOptional structured context (HTTP status, resource IDs, confirmation hints).

JSON mode writes the envelope to stdout only (including failures). Exit code still reflects success or failure.

Exit codes

CodeMeaning
0Success.
1General failure: usage error, validation error, business-state conflict, or unclassified CLI error.
2Authentication failure: missing, invalid, or expired credentials.
3Authorization failure: authenticated but RBAC or entitlement denied.
4Confirmation required: destructive command run without --yes.
5Gateway or upstream unavailable (503, network failure, timeout).
6Local environment failure: unreadable env file, git-ignore refusal, filesystem permission error.

When Gateway returns a structured error, the CLI maps HTTP status to exit code:

HTTP statusExit codeError category
400, 409, 422, 4281validation
4012auth
4033forbidden
4041not_found
4101gone
4295rate_limit
500, 502, 503, 5045gateway

Error categories

CategoryWhen used
usageUnknown command, invalid flag, or missing required argument.
authCredential missing, malformed, expired, or rejected by Gateway principal lookup.
forbiddenAuthenticated caller lacks the required role or entitlement.
validationRequest rejected because of invalid input or incompatible resource state.
not_foundResource absent in the authenticated tenant scope.
goneTemporary download or export no longer available.
confirmation_requiredDestructive command attempted without --yes.
rate_limitGateway rate limit exceeded.
gatewayUpstream Gateway or dependency error.
networkTransport failure before a structured Gateway response is received.
environmentLocal filesystem, git-ignore, or permission failure.
internalUnexpected CLI bug; should be rare.

Redaction rules

Apply these rules in table output and in any human-readable log lines. JSON data fields follow the per-command schema below; secret fields are omitted or replaced with masked placeholders unless the command explicitly documents a full-value JSON field for automation.

MaterialTable outputJSON data
API key (paybond_sk_*)Mask to paybond_sk_{env}_{first8}...{last4}; fallback paybond_sk_...key_masked in list/read responses; include one-time plaintext api_key only for keys create and keys rotate when the Gateway returns a new secret; never include the raw login secret in JSON (login uses key_written instead)
Capability tokenNever printcapability_token allowed only when the command creates or returns a new token for immediate use (for example, guardrails bootstrap); otherwise omit
Gateway bearer tokenNever printNever include
Signing seed / private key materialNever printNever include
Device codes during loginPrint user_code and verification URL (required for approval); never print device_codeInclude user_code and verification_uri; omit device_code
request_id from GatewayPrint when presentAlways echo in envelope and in proxied error details

Key masking algorithm (both kits must match):

  1. Split the key on _.
  2. When the shape is paybond_sk_{environment}_{key_id}_{secret}, emit paybond_sk_{environment}_{key_id[0:8]}...{key_id[-4:]} when len(key_id) > 12, otherwise paybond_sk_{environment}_redacted.
  3. Otherwise emit paybond_sk_....

Command tree

Top-level invocation:

paybond [--global-flags] <command> [<subcommand> ...] [args] [--command-flags]
paybond --help
paybond <command> --help

paybond login

Sandbox device login. Writes PAYBOND_API_KEY to the env file.

FlagDefaultNotes
--env sandboxsandboxOnly sandbox is supported. Live device login is rejected.
--forcefalseReplace an existing PAYBOND_API_KEY in the target env file.

Inherits global flags --gateway, --env-file, --no-open, --format.

Table output (success): verification URL, user code, env file path, masked key, target tenant, optional expiry notice.

login is the one command that intentionally performs a local secret write; it still never prints the raw key.

JSON data fields:

FieldType
env_filestring
key_maskedstring
key_writtenboolean
tenant_idstring
tenant_uuidstring
environmentstring
expires_atstring (RFC 3339, optional)
verification_uristring
user_codestring

These next four commands are post-login operator surfaces. They do not replace login, init, doctor, or dev loop for first success — use them after credentials exist to inspect state, script sticky context, or deep-link into Console for rare admin tasks.

paybond status

Summarize sandbox auth, the local policy file, last smoke/trace event, and the local trace dashboard URL. Tenant scope comes from authenticated credentials only — never from CLI tenant flags. Useful offline even when principal lookup fails (auth still reports key presence / next steps).

FlagDefaultNotes
--policy-file <path>paybond.policy.yamlLocal policy path to check for presence/mtime.

Inherits global --format, --gateway, --env-file, --profile.

JSON data fields:

FieldType
authobject — authenticated, source, env_file, gateway, optional key_masked, profile, tenant_id, tenant_uuid, environment, service_account_role, or principal_error / next when unresolved
policyobject — path, present, optional mtime, bytes
last_smokeobject | null — recorded_at, operation, authorized, run_id, intent_id, source (dev-trace | dev-audit)
traceobject — url, port, file meta, event_count
audit_logobject — file meta for .paybond/dev-audit.jsonl
happy_pathstring[] — canonical first-success command hints
next_commandsstring[]

Examples: paybond status, paybond status --format json. Suggested next: paybond control --once --format json.

paybond shell

Interactive REPL with sticky --gateway / --env-file / --profile context (Heroku-style). Nested shell or control inside the REPL is refused. Non-TTY, CI, and --format json must not hang — use --exec for one-shot.

FlagDefaultNotes
--exec "<command>"(unset)Run one sticky-context command line and exit (required in CI / non-TTY / JSON).

JSON data fields:

ModeFields
execmode, command, exit_code, sticky (gateway, env_file, profile) — or exited when the line was exit/quit
replmode, commands_run, sticky

Examples: paybond shell, paybond shell --exec "status", paybond shell --exec "whoami --format json".

paybond control

Live read-mostly control-plane TUI over gateway intents, agent receipts, local policy, spend decisions, and denials. TypeScript uses Ink; Python uses a terminal panel loop. Honors NO_COLOR and TTY detection. Tenant scope comes from authenticated credentials only.

FlagDefaultNotes
--oncefalsePrint a snapshot and exit (no TUI). Implied when --format json or non-interactive.
--policy-file <path>paybond.policy.yamlLocal policy panel source.
--limit <n>10Max rows per list panel (positive integer).

JSON / snapshot data fields: mode (snapshot | tui), active_panel, tenant_id, environment, gateway, trace_url, panels (intents, receipts, policy, spend, denials), generated_at, limitations[], and next_commands[] in snapshot mode.

Examples: paybond control, paybond control --once --format json, paybond control --once --limit 5.

paybond open

Explicit deep-link escape hatch to Console (or local trace / docs) for rare admin tasks. Not the default path for day-to-day Kit work — prefer status, control, and shell.

paybond open <resource> [<id>] [--port <n>] [--no-open]
ResourceTarget
console/console
billing/console/configuration/billing
sso/console/configuration/identity/sso
scim/console/configuration/identity/scim
compliance-exports/console/investigations/compliance-exports
intent <intent_id>Intent dossier in Console
export <job_id>Compliance export job in Console
trace [<run_id>]Local trace dashboard (http://127.0.0.1:9477, optional run deep link)
docsKit docs
FlagDefaultNotes
--port <n>9477Trace dashboard port (for open trace only).
--no-openfalsePrint the URL without launching a browser (also honors global --no-open).

Console origin: PAYBOND_CONSOLE_BASE_URL or PAYBOND_PUBLIC_BASE_URL, else http://127.0.0.1:3000. Docs origin: PAYBOND_DOCS_BASE_URL, else https://paybond.ai/docs.

JSON data fields: resource, url, purpose, opened, note.

Examples: paybond open console, paybond open billing --no-open, paybond open intent <uuid>, paybond open export job-123 --no-open, paybond open trace.

paybond init guardrail

Scaffold a sandbox paid-tool guardrail integration file.

FlagDefault
--preset paid-tool-guardpaid-tool-guard
--framework <name>provider-agnostic
--out <path>paybond-paid-tool-guard.ts or paybond_paid_tool_guard.py
--forcefalse

Allowed --framework values: generic, provider-agnostic, openai, claude, anthropic, gemini, google-ai, vercel-ai, langgraph, mcp.

JSON data fields: out, preset, framework, bytes_written.

paybond mcp

SubcommandDescription
serveStart the MCP server over stdio (default) or Streamable HTTP (--transport http; replaces paybond-mcp-server).
installWrite MCP host configuration for Claude, Codex, OpenAI, or generic stdio clients.
toolsList tools exposed by the local MCP server.

mcp install flags:

FlagDefault
--host claude|codex|openai|generic(required)
--scope local|project|userproject
--env-file <path>.env.local

Generated MCP configs must reference PAYBOND_ENV_FILE by default, not embed raw API keys.

JSON data fields (install): host, scope, config_path, server_command, printed. When printed is true (local scope) and --format json is set, payload contains the generated config text.

paybond doctor

Validate local runtime, package version, env file, key shape, principal lookup, and optional agent/MCP setup.

FlagDefault
--agentfalse — when set, also validate MCP server startup and tool listing.

JSON data fields: checks[] with { name, ok, message, details? }, summary (pass | fail).

With --agent, also runs agent middleware sandbox smoke when sandbox credentials are present.

paybond adyen

Read-only BYO Adyen Checkout settlement readiness against GET /v1/admin/settlement/config. Does not upsert API keys, HMAC secrets, or stored payment methods — use Console Settlement or POST /v1/admin/settlement/adyen/destination.

SubcommandDescription
readyChecklist: adyen_manual_capture enabled, destination, API key, HMAC, stored payment method, live URL prefix when live, paid-plan gate, rail readiness.
doctorExpands ready with webhook URL checklist (/webhooks/live/adyen and /webhooks/sandbox/adyen), sandbox/live mismatch hints, and Console destination pointer.

JSON data fields (ready): ready, checks[], summary, checklist_lines.

JSON data fields (doctor): checks[], summary, checklist_lines, next_steps.

Tenant walkthrough: Configure Adyen settlement. Shopify has a larger orchestration surface documented separately in Shopify CLI workflow.

paybond flutterwave

Read-only BYO Flutterwave Virtual Account settlement readiness against GET /v1/admin/settlement/config. Does not upsert secret keys or webhook secrets — use Console Settlement or POST /v1/admin/settlement/flutterwave/destination.

SubcommandDescription
readyChecklist: flutterwave_virtual_account enabled, destination, secret key, webhook secret, paid-plan gate, rail readiness.
doctorExpands ready with webhook URL checklist (/webhooks/live/flutterwave and /webhooks/sandbox/flutterwave), per-destination token URL when configured, sandbox/live mismatch hints, and Console destination pointer.

JSON data fields (ready): ready, checks[], summary, checklist_lines.

JSON data fields (doctor): checks[], summary, checklist_lines, next_steps.

Tenant walkthrough: Configure Flutterwave settlement.

paybond dev

Local sandbox developer workflows: travel smoke with checklist output, trace dashboard, optional WireMock Gateway (dev up), and a guided login → policy → validate → smoke loop.

SubcommandDescription
smokeWraps agent sandbox smoke with travel preset defaults; records a local trace event.
traceStarts a local HTTP trace dashboard (default port 9477) with a vertical timeline of recent smoke runs. Reads .paybond/dev-trace.jsonl from the current working directory.
loopGuided loop: login when needed → policy init --preset travelvalidate-tools --local-onlydev smoke.
upStart or stop a local WireMock Gateway (Docker required).

paybond dev smoke

FlagDefault
--preset <id>travel
--offlinefalse — in-process mock capability and simulated settlement; no PAYBOND_API_KEY required. Also stubs POST /harbor/intents/{id}/fund with an x402 402 → 202 → 200 state machine for local fund contract tests.
--format table|jsontable

JSON data fields (smoke): bind, execute, trace_url, audit_log, offline (when set). Timeline events are persisted under .paybond/dev-trace.jsonl.

paybond dev trace

FlagDefault
--port <n>9477

Serves a self-contained HTML dashboard at / and /runs/<run-id>. Polls /api/events for timeline data. Run from the same project directory as dev smoke / dev loop so .paybond/dev-trace.jsonl is found.

JSON data fields (trace): trace_url, port, events[] (each event may include trace_events[] with structured middleware records: tool_selected, spend_authorized, tool_executed, evidence_submitted, spend_finalized, plus steps[] for the vertical timeline UI).

paybond dev loop

FlagDefault
--policy-file <path>paybond.policy.yaml
--offlinefalse — skip login and use offline mock capability.
--no-loginfalse — skip the login step when credentials are already configured.
--format table|jsontable

JSON data fields (loop): steps[], smoke, trace_url, audit_log, banner_lines[], offline (when set).

paybond dev up

FlagDefault
--port <n>18089
--downfalse — stop the WireMock container instead of starting it.

Starts WireMock with bundled Gateway stubs under kit/dev/wiremock/mappings/ (also packaged in the Python wheel). Includes an x402 fund sequence for intent aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa: mappings 11-x402-fund-challenge.json (402 with payment-required), 12-x402-fund-pending.json (202), and 13-x402-fund-success.json (200 with capability_token). Use with paybond --gateway http://127.0.0.1:18089 intents fund ... or fundWithX402 / fund_with_x402 to rehearse the handshake without a remote sandbox API.

JSON data fields (up): gateway_url, port, wiremock_dir, container_name, status, next_commands[].

Dev smoke and loop append audit events to .paybond/dev-audit.jsonl under the working directory.

paybond config

SubcommandDescription
get <key>Read a config value (sensitive values are redacted using the same rules as list).
set <key> <value>Write a config value.
unset <key>Remove a config value.
listList all config entries (values redacted when sensitive).

Config is profile-scoped when --profile is set.

paybond whoami

Resolve the authenticated principal and tenant realm.

JSON data fields: tenant_id, tenant_uuid, environment, service_account_role, principal (Gateway principal payload, secrets stripped).

paybond keys

SubcommandDescriptionDestructive
listList service-account keys for the tenant.
createCreate a new key.
rotate <key_id>Rotate an existing key.yes — requires --yes
revoke <key_id>Revoke a key.yes — requires --yes

JSON data fields (list): keys[] with key_id, key_masked, role, created_at, expires_at, status.

JSON data fields (create, rotate): key_id, key_masked, plus one-time plaintext api_key when the Gateway returns a newly minted secret.

paybond intents

SubcommandDescription
listList intents (read-only Gateway operator route).
get <intent_id>Fetch one intent (read-only Gateway operator route).
createCreate an intent from pre-signed --body JSON via paybond.harbor.createIntent with a replay-safe recognition proof.
fund <intent_id>Fund an intent via paybond.harbor.fundIntent with a replay-safe recognition proof. Returns structured 200 / 202 / 402 results (including x402 paymentRequired challenges).
evidence <intent_id>Submit pre-signed evidence --body JSON via paybond.harbor.submitEvidence with a replay-safe recognition proof. Distinct from agent harbor evidence smoke, which Kit-signs payee evidence; this command accepts upstream-signed wire JSON.
settlement-confirm <intent_id>Confirm settlement via paybond.intents.confirmSettlement with a replay-safe recognition proof.

Read vs mutation paths: list and get call Gateway operator routes directly and do not require agent recognition. Intent mutation subcommands open a Paybond session (withPaybondCli / with_paybond_cli), sign a request-bound recognition proof over the wire body (or {} for fund), and delegate to the SDK Harbor surface.

Shared recognition flags (intent mutations):

FlagEnv fallback
--agent-recognition-key-id <id>APP_AGENT_RECOGNITION_KEY_ID
--agent-recognition-signing-seed-hex <hex>APP_AGENT_RECOGNITION_SEED_HEX
--idempotency-key <key>

create, fund, evidence, and settlement-confirm require these credentials when Gateway Harbor recognition enforcement is enabled.

paybond intents create

FlagRequired
--body <json-file> or --stdinyes — caller-supplied signed intent JSON forwarded verbatim to Harbor
--agent-recognition-key-id, --agent-recognition-signing-seed-hexyes when recognition is enforced (or APP_AGENT_* env)
--idempotency-keyno

paybond intents fund <intent_id>

FlagRequired
--payment-signature <sig>no — x402 retry header after signing paymentRequired
--body <json-file> or --stdinno — deprecated shim; reads payment_signature from JSON when --payment-signature is omitted (emits a stderr warning)
--agent-recognition-key-id, --agent-recognition-signing-seed-hexyes when recognition is enforced (or APP_AGENT_* env)
--idempotency-keyno

Harbor receives an empty POST body; the recognition proof binds to {}. On x402 rails, a 402 response includes payment-session metadata in the structured CLI JSON (statusCode, paymentRequired, etc.). Retry with a fresh recognition proof plus --payment-signature.

paybond intents evidence <intent_id>

FlagRequired
--body <json-file> or --stdinyes — caller-supplied signed evidence JSON forwarded verbatim to Harbor
--agent-recognition-key-id, --agent-recognition-signing-seed-hexyes when recognition is enforced (or APP_AGENT_* env)
--idempotency-keyno

The recognition proof binds to the exact wire body bytes Harbor verifies (same digest rule as agent harbor evidence smoke, but without Kit-side payee signing).

JSON data fields (evidence): intentId / intent_id, tenant, state, optional predicatePassed / predicate_passed.

paybond intents settlement-confirm <intent_id>

FlagRequired
--body <json-file> or --stdinno — defaults to {}
--agent-recognition-key-id, --agent-recognition-signing-seed-hexyes when recognition is enforced (or APP_AGENT_* env)
--idempotency-keyno

JSON data fields (fund): statusCode (or status_code in Python CLI output), intentId / intent_id, tenant, state, settlementRail / settlement_rail, currency, amountCents / amount_cents, funded, optional capabilityToken / capability_token, optional paymentRequired / payment_required, optional paymentResponse / payment_response, optional funding.

--request-id is forwarded as a correlation header on all subcommands. Responses redact capability_token / capabilityToken and other sensitive fields using the shared CLI redaction rules.

paybond guardrails

SubcommandDescription
bootstrapBootstrap a sandbox guardrail intent and capability. Request body must include completion_preset or evidence_schema, not both — see Agent policy.
evidenceSubmit sandbox guardrail evidence.

JSON data fields (bootstrap): tenant_id, intent_id, capability_token, operation, requested_spend_cents, sandbox_lifecycle_status.

paybond agent

Agent middleware commands wrap PaybondAgentRun and PaybondToolInterceptor. They default to sandbox-only unless --production is passed (live API keys require the explicit flag).

SubcommandDescription
run bindBind a run via sandbox bootstrap or production attach. Production attach requires --payee-did, --payee-signing-seed-hex, --agent-recognition-key-id, and --agent-recognition-signing-seed-hex (or APP_* env fallbacks). Persists context to .paybond/runs/<run_id>.json (mode 0600), including hex-encoded signing seeds for re-attach on tool execute.
run statusRead a persisted run binding from .paybond/runs/.
run traceShow middleware trace events for a bound run. Reads .paybond/runs/<run_id>.trace.json written during tool execute. Use --format json for trace_events[] / steps[] or --format table for a vertical checklist.
tool executeAuthorize, execute (via --result-body / --result-file), complete spend, and auto-submit evidence for a registered side-effecting tool. --result-body must match the bind completion_preset canonical evidence fields (CLI does not apply SDK evidenceMapper).
tool validateAuthorize-only dry run for a tool call (no execution or evidence).
registry validateValidate a local agent tool registry YAML/JSON file.
sandbox smokeOne-shot bind and execute for CI and coding agents. With --policy-file, bootstrap sends completion_preset from tool evidence_preset only — do not pair with a custom evidence_schema (Gateway rejects both). See Agent policy.

JSON data fields (run bind): run_id, tenant_id, intent_id, capability_token, operation, sandbox_lifecycle_status, allowed_tools[].

JSON data fields (run trace): run_id, intent_id, trace_events[] (tool_selected, spend_authorized, spend_denied, approval_required, tool_executed, evidence_submitted, spend_finalized), steps[], trace_url, trace_file, updated_at. Table mode prints trace_lines[] instead of the default key-value table.

JSON data fields (tool execute): authorization, tool_result, evidence (submitted, intent_state, predicate_passed, sandbox_lifecycle_status).

When evidence.submitted is false and the error category is gateway, check that --result-body matches the preset (for example cost_and_completion requires top-level status and cost_cents). Harbor predicate rejections are often surfaced as HTTP 502 harbor_evidence_failed through the Gateway.

JSON data fields (sandbox smoke): bind, execute (same shapes as above).

Use --format json for automation. --write-env on run bind appends PAYBOND_INTENT_ID, PAYBOND_CAPABILITY_TOKEN, and PAYBOND_RUN_ID to an env file.

paybond spend authorize

Authorize delegated spend for a tool call.

JSON data fields: authorized, intent_id, operation, requested_spend_cents, deny_reason (when not authorized).

paybond signal

SubcommandDescription
reputationRead reputation summaries.
portfolioRead portfolio summaries.
fraudRead fraud signals.

Each subcommand accepts resource selectors documented in the SDK references.

paybond receipts

SubcommandDescription
get <receipt_id>Fetch a receipt.
verify <receipt_id>Verify receipt signatures and binding.

paybond mandates

SubcommandDescription
verifyVerify a mandate artifact.
importImport a mandate into the tenant.

paybond a2a

SubcommandDescription
cardAgent card discovery and validation.
contractsContract listing and inspection.

paybond audit exports

Delegates to paybond.audit.exports on the Kit SDK (POST /v1/compliance/audit-exports and related routes). Tenant scope comes from authenticated credentials only — never pass a tenant id. Progress lines for create --wait go to stderr; use --format json for the envelope. Operator Console remains available for investigation UI (paybond open compliance-exports).

SubcommandDescriptionDestructive
createCreate a tenant-scoped compliance audit export pack.
listList compliance audit export jobs.
get <job_id>Fetch export job status; optional --issue-download / --output for bundle bytes.
verify <path>Verify a downloaded export bundle locally (Ed25519 manifest).
delete <job_id>Delete an export job.yes — requires --yes

paybond audit exports create flags: --time-start, --time-end (RFC 3339), --intent-id, --case-id, --operator-did, --includes a,b, --disclosure-tier standard\|extended, --retention-hours <n>, --wait, --output <path>, --timeout-seconds <n>.

JSON data fields (create): job, waited, output, bytes_written, next_commands[].

JSON data fields (list): exports[] with job_id, status, created_at, expires_at. Optional next_cursor when the Gateway paginates results.

SDK: paybond.audit.exports.create|list|get|delete|verify (TypeScript and Python) — same surface as the CLI. MCP readonly: paybond_list_audit_exports, paybond_get_audit_export when --tool-policy readonly (no create via MCP). Bundle verify stays SDK/CLI only.

Security invariants

Both kits must enforce:

  1. No live device login — reject --env live and hidden live flags.
  2. Git-ignore gate — refuse to write secret files that are not ignored inside a git repository (except when adding the default .env.local to .gitignore).
  3. 0600 secret files — env files containing API keys are written with owner-read/write only.
  4. No tenant override — reject --tenant-id and similar unauthenticated tenant selectors on normal commands.
  5. Confirmation gate — refuse destructive subcommands without --yes.
  6. Operator key expectation for login — reject device-login tokens whose role is not operator.

Parity and testing

Both kits must maintain:

  • Snapshot parity for paybond --help and each subcommand --help.
  • JSON shape parity for whoami, doctor, keys list, guardrails bootstrap, and representative error cases.
  • Identical exit codes and error categories for the same failure inputs.
  • Identical key masking output for the same raw key material.

Run kit tests from the repository root:

cd kit/ts && npm run test
cd kit/python && uv run pytest