CLI reference¶
acx is the zero-dependency reference command-line tool for building, inspecting, verifying, stripping,
leveling, and safely sharing .acx Agent Cartridges — and for linting, signing, verifying, inspecting,
staffing, and submitting reusable ACX Workflows and Agent Graphs.
Running the tool¶
The reference implementation is pure ESM with no third-party dependencies: it uses only Node's built-in node:sqlite and node:crypto. Because node:sqlite is still gated behind a flag, every invocation must run under node --experimental-sqlite.
Node ≥ 22.5.0 and --experimental-sqlite are required
acx opens the cartridge with the built-in node:sqlite module. Without the flag the process aborts before any command runs.
The shebang in src/cli.mjs already encodes this (#!/usr/bin/env -S node --experimental-sqlite), so ./src/cli.mjs <command> works on a system where that env form is honored.
Running acx with no command (or help, -h, --help) prints usage:
acx — Agent Cartridge (.acx) command-line tool
Usage:
acx --version
acx export <agent-package-dir> <out.acx> --publisher <reverse-dns> [--include-field-learned]
acx inspect <file.acx>
acx verify <file.acx> [--registry <trust.json>]
acx strip <file.acx> <out.acx>
acx spec <file.acx>
acx check <file.acx> [--all-tools]
acx load <file.acx> [--host claude|codex|cursor]
acx workflow lint <workflow.cal.json> [--publish]
acx workflow sign <workflow.cal.json> --publisher <reverse-dns> [--key <pem>] [--out <file>]
acx workflow verify <workflow.cal.json> [--registry <trust.json>]
acx workflow inspect <workflow.cal.json>
acx workflow ready <workflow.cal.json> [--cartridges <dir>]
acx graph lint <graph.agent-graph.json> [--publish]
acx graph sign <graph.agent-graph.json> --publisher <reverse-dns> [--key <pem>] [--out <file>]
acx graph verify <graph.agent-graph.json> [--registry <trust.json>]
acx graph inspect <graph.agent-graph.json>
acx graph digest <graph.agent-graph.json>
acx share agent <file.acx> --slug <slug> [--registry <dir>] [--dry-run]
acx share workflow <workflow.cal.json> [--registry <dir>] [--dry-run]
acx share graph <graph.agent-graph.json> [--registry <dir>] [--dry-run]
acx level <file.acx>
| Command | One-liner | SPEC |
|---|---|---|
export |
Package an agent directory into a signed .acx |
§12 |
inspect |
Print meta, ROM objects, skills, capabilities, memory, attestations | §12 |
verify |
Evaluate the trust taxonomy (local/trusted/portable/legacy/tampered) |
§4.5, §12.6 |
workflow |
Validate, sign, verify, inspect, and staff portable agent-team workflows | §14 |
graph |
Validate, sign, verify, and inspect portable team information architectures | §16 |
share |
Verify and prepare one focused registry pull request | §17 |
strip |
Re-export SAVE-free and prove the ROM hash is unchanged | §3.4 |
level |
Earn a σ-gated, ROM-bound level credential from an independent verifier | §10 |
What is real vs. host-side here
The crypto, hashing, DSSE/in-toto signing, trust evaluation, scrub gate, TrueSkill gating, and credential verification are fully implemented. The level benchmark's reference solver is deterministic and pluggable — a production verifier plugs a real sandboxed agent run into the same gate. OCI push, DNS-TXT/OIDC namespace proofs, the host handshake runtime, and vec0 vector search are specified normatively but not part of this CLI.
share¶
Prepare a signed agent, workflow, or Agent Graph for the git registry. share performs no git, network,
push, or PR operation: it verifies the artifact, enforces safe canonical paths, copies only the public
artifact, and generates review metadata.
acx share agent agent.acx --slug research-designer --dry-run
acx share agent agent.acx --slug research-designer
acx share workflow research-council.cal.json --dry-run
acx share workflow research-council.cal.json
acx share graph product-delivery.agent-graph.json --dry-run
acx share graph product-delivery.agent-graph.json
| Flag | Meaning |
|---|---|
--registry <dir> |
Registry root; defaults to ./registry only when the current directory is a verified ACX checkout root. Required elsewhere, including npm-cache/global installs. |
--publisher <id> |
Require an exact match with the publisher bound into the signature |
--slug <slug> |
Required safe destination slug for an agent |
--dry-run |
Verify and print the planned paths/PR body without writing |
--force |
Re-run explicit preparation, but never replace different bytes at an immutable coordinate |
For agents, share requires a valid signed cartridge and clean acx.package-spec/1, then produces
registry/cartridges/<publisher>/<id>/<version>/cartridge.acx plus a generated README card. The requested
slug must match the ROM-bound artifact id. For workflows, it
requires the complete publication profile and valid JCS/DSSE/in-toto publisher binding, then produces
registry/cals/<publisher>/<id>/<version>.cal.json. For Agent Graphs, it applies the same signature and
publication gates, then produces
registry/graphs/<publisher>/<id>/<version>.agent-graph.json. It refuses legacy/unsigned artifacts,
tampering, publisher mismatches, unsafe identifiers, secret-like public metadata, and coordinate
replacement. Changed bytes require a new SemVer.
Continue with the deterministic index builder and tests:
node --experimental-sqlite tools/build-registry-index.mjs
npm test
git diff --check
git diff -- registry/
See Share ACX for the human path and the bundled
$acx-share-agent skill for agent-driven PR
preparation.
graph¶
Work with a standalone acx.agent-graph/1 information architecture without assigning or executing tasks.
The five public subcommands follow the workflow trust model while keeping organizational communication
separate from control flow.
| Subcommand | Purpose | Exit behavior |
|---|---|---|
graph lint <file> [--publish] |
Validate actor and knowledge references, routes and expected returns, loop bindings, convergence, direction invariants, and graph bounds; optionally validate public metadata | non-zero on any structural/publication issue |
graph sign <file> --publisher <id> [--key <pem>] [--out <file>] |
JCS-canonicalize the document, compute its SHA-256 digest, and add an Ed25519 DSSE/in-toto integrity block | non-zero if invalid or not publishable |
graph verify <file> [--registry <trust.json>] |
Recompute the digest and verify signature, graph id/version, publisher, key id, time, and trust-registry binding | non-zero when unsigned, invalid, or tampered |
graph inspect <file> |
Print a safe discovery card: actors, knowledge, route intents, connected loops, convergence, digest, and trust | read-only; never routes a message or dispatches a task |
graph digest <file> |
Print the SHA-256 digest of the unsigned JCS-canonical graph document | read-only; fails when the input is not a JSON object |
# Validate the public contract.
node --experimental-sqlite src/cli.mjs graph lint \
product-delivery.agent-graph.json --publish
# Sign. With no --key, a new private key is written beside the output.
node --experimental-sqlite src/cli.mjs graph sign \
product-delivery.agent-graph.json \
--publisher io.github.yourhandle \
--out product-delivery.signed.agent-graph.json
# Verify and inspect without executing anything.
node --experimental-sqlite src/cli.mjs graph verify \
product-delivery.signed.agent-graph.json
node --experimental-sqlite src/cli.mjs graph inspect \
product-delivery.signed.agent-graph.json
node --experimental-sqlite src/cli.mjs graph digest \
product-delivery.signed.agent-graph.json
lint accepts fuzzy prose and selectors but fails closed on hard invariants. Routes cannot point back to
their own source. Required direction cannot have conflicting owners or cycles. Expected returns must name
a real reverse route. Loop participant bindings cannot be ambiguous. Every convergence has at least two
distinct loop inputs and positive wait/round limits; graph-wide propagation and fan-out are bounded.
Publishable graphs add a stricter safety profile: discovery metadata must not look like credentials or private key material, and every referenced ACX Workflow is pinned by publisher id, workflow id, SemVer, and canonical digest. Knowledge modules contain descriptions, stewards, audiences, and optional metadata locators — never the knowledge payload itself.
graph digest removes only top-level integrity, canonicalizes with RFC 8785/JCS, and prints the sha256
digest used by registry identity, workflow dependency pins, and signed remix lineage.
An Agent Graph is not an authorization or dispatch engine
direct, approval, and other route fields describe team relationships. They never grant tool access,
budget, filesystem rights, or permission to act. lint, sign, verify, and inspect consume
declarative data only. A host that routes events remains responsible for policy, authorization, and all
declared propagation/convergence bounds.
See the visual Agent Graph guide for the Product Owner ↔ Developer reporting loop and the research + delivery convergence pattern.
workflow¶
Work with a standalone acx.cal/1 team workflow without executing it. The five subcommands deliberately
separate a portable artifact's validity and trust from one machine's ability to staff it.
| Subcommand | Purpose | Exit behavior |
|---|---|---|
workflow lint <file> [--publish] |
Validate closed conditions, references, completion contracts, reachability, termination, cycle bounds, and optionally public metadata | non-zero on any structural/publication issue |
workflow sign <file> --publisher <id> [--key <pem>] [--out <file>] |
JCS-canonicalize the document, compute its SHA-256 digest, and create an Ed25519 DSSE/in-toto integrity block | non-zero if invalid or not publishable |
workflow verify <file> [--registry <trust.json>] |
Recompute the digest and verify the signature, workflow id/version, publisher, key id, time, and trust-registry binding | non-zero when invalid or tampered |
workflow inspect <file> |
Print a discovery card: identity, team slots, required capabilities, digest, signature, and trust | read-only; never executes tasks |
workflow ready <file> [--cartridges <dir>] |
Recursively scan .acx files, staff slots by role/proven level/capability/stack, and check each task's skill/capability coverage |
non-zero when this roster cannot run it |
acx cal <file> [--cartridges <dir>] remains a backward-compatible alias for workflow ready.
Share a workflow¶
# 1. Portable validation: no local cartridges required.
node --experimental-sqlite src/cli.mjs workflow lint team.cal.json --publish
# 2. Sign. With no --key, a new private key is written beside the output.
node --experimental-sqlite src/cli.mjs workflow sign team.cal.json \
--publisher io.github.yourhandle --out team.signed.cal.json
# 3. Anyone can verify the exact shared graph before staffing or execution.
node --experimental-sqlite src/cli.mjs workflow verify team.signed.cal.json
# 4. The receiving studio checks whether its local roster can fill every slot.
node --experimental-sqlite src/cli.mjs workflow ready team.signed.cal.json \
--cartridges ./roster
Signing covers every top-level field except integrity using RFC 8785/JCS and binds the digest into an
in-toto Statement carried by DSSE. The generated private key stays outside the JSON and must never enter
git. A valid but unregistered signer is portable; a namespace-proven trust-registry entry upgrades it to
trusted; content or identity tampering is tampered.
Validation does not execute the workflow
lint, verify, inspect, and ready consume declarative data only. Actual dispatch, tool calls,
approvals, timers, variable updates, and branch advancement belong to a conformant host runtime.
Before execution, a host must enforce each task's sideEffects, approval, completion contract,
resource limits, and its own stricter policy.
export¶
Package an AGENTIBUS agent-package directory into a signed .acx cartridge.
Synopsis
node --experimental-sqlite src/cli.mjs export \
<agent-package-dir> <out.acx> \
--publisher <reverse-dns> [--include-field-learned]
Options
| Argument / flag | Required | Meaning |
|---|---|---|
<agent-package-dir> |
yes | Source AGENTIBUS agent-package directory. |
<out.acx> |
yes | Destination cartridge path. |
--publisher <reverse-dns> |
yes | Publisher id, e.g. io.github.agentibus (illustrative handle, not a real org). |
--include-field-learned |
no | Include quarantined field-learned SAVE memory. Default: off. |
What it does
- Generates a fresh ed25519 signing key and derives
keyid = "ed25519:" + hex(sha256(DER SPKI)). - Builds the ROM (skills, capabilities, meta), then signs a content-addressed ROM manifest recomputed from live bytes in a DSSE / in-toto envelope. See Signing & trust.
- Writes the cartridge, then writes the private key to
<out.acx>.key.pem(mode0600) OUTSIDE the cartridge.
The private key is written outside the cartridge — and must stay there
Per SPEC §4 the signing key is never stored inside the .acx. export emits it as a sibling file <out>.key.pem. Keep it secret; anyone with it can forge signatures under your keyid. The cartridge you distribute contains public key material only.
By default, field-learned memory is quarantined — the fail-closed scrub gate (SPEC §7.5) and the two-tier partition keep codebase-specific records out of what you ship unless you opt in with --include-field-learned. See Memory.
cartridge id: io.github.agentibus/scenario-research-designer@025edd67-cc60-47b8-a059-ddd839c29db5
rom hash: sha256:f479be021b8ea2e55cc6e3e33b95df9d151196548dfc854dedbe578be7120642
keyid: ed25519:17bb8c9290fd2a3d0c3a434ad0e99544d809dbff1540d64be0bab2274df14f66
signing key: /tmp/demo.acx.key.pem (private — keep secret, outside cartridge)
field-learned: quarantined (default)
wrote: /tmp/demo.acx
The rom hash printed here (sha256:f479be02…7120642) is the value that every later command binds to.
inspect¶
Print meta, ROM object counts, skills, capabilities, memory zone counts, and attestations for a cartridge. Read-only.
Synopsis
Options — a single positional <file.acx>; no flags.
What it does — opens the cartridge read-only and prints six sections: meta (all acx.* keys, sorted), the ROM object total grouped by kind, the acx_skill rows, the capabilities rows (with each capability's verified flag), memory counts grouped by zone, and any attestations.
== meta ==
acx.agent_name = Scenario Research Designer
acx.cartridge_id = io.github.agentibus/scenario-research-designer@025edd67-cc60-47b8-a059-ddd839c29db5
acx.created_at = 2026-04-03T13:35:46.190Z
acx.declared_level = 4
acx.embedding_engine = {"id":"local-hash-128","dim":128}
acx.model = gemini-2.5-pro
acx.provider = gemini
acx.publisher_id = io.github.agentibus
acx.role = designer
acx.rom_manifest_hash = sha256:f479be021b8ea2e55cc6e3e33b95df9d151196548dfc854dedbe578be7120642
acx.spec_version = 0.1
acx.vec0_format = 1
== ROM objects ==
total: 21 (memory:1, cartridge:9, sqlar:11)
== skills (acx_skill) ==
- expertise-designer: Specialized designer expertise on research, ux, benchmarking. Use when a task matches this agent's d
== capabilities ==
- implement-feature[pkg:generic/benchmarking+pkg:generic/research+pkg:generic/ux] verified=false
- build-dag[pkg:generic/snowflake+pkg:pypi/apache-airflow+pkg:pypi/dbt-core] verified=false
== memory (by zone) ==
rom: 1
== attestations ==
(none)
verified=false until a level attestation resolves
A capability's proficiency.verified is true only when a level attestation resolves against the ROM digest (SPEC §10). A freshly exported cartridge always reads verified=false; run level to change that. See Capabilities and Provable level.
declared_level is a claim, not a proof
acx.declared_level = 4 is what the publisher asserts. Only an independently issued, σ-gated credential makes a level provable.
verify¶
Evaluate the SPEC §4.5 trust taxonomy for a cartridge. Exits non-zero when the result is invalid or tampered.
Synopsis
Options
| Argument / flag | Required | Meaning |
|---|---|---|
<file.acx> |
yes | Cartridge to evaluate. |
--registry <trust.json> |
no | Public-keys-only trust registry. Loading a registry that contains private key material is refused (SPEC §12.4). |
What it does — recomputes the ROM manifest from live bytes, checks the DSSE signature, and maps the outcome onto the trust taxonomy:
| trust | meaning |
|---|---|
local |
signed by this instance's own key |
trusted |
valid signature, active registry key, valid namespace proof, and lifecycle checks pass |
portable |
valid signature, signer not in the registry |
legacy |
unsigned |
tampered |
ROM content diverges from the signed manifest |
With no --registry, an empty registry is used, so a validly-signed cartridge from an unknown signer resolves to portable with status: warning (a caution, not a failure — exit=0).
Tamper is detected, not just missing signatures
Rewriting signed sqlar content while leaving a stale objects.oid yields invalid / tampered — ROM content diverges from signed manifest (object hash mismatch) and exit=1. The full taxonomy walkthrough lives in Signing & trust.
strip¶
Copy a cartridge, remove the SAVE zone, and print the ROM hash-equality proof. Exits non-zero if the hashes differ.
Synopsis
Options — two positionals: the source <file.acx> and the SAVE-free destination <out.acx>; no flags.
What it does — copies the file, drops every SAVE-zone row, and re-derives the ROM manifest hash from the stripped result. Because the ROM was never mutated, the hash before and after stripping are byte-for-byte equal — a cryptographic demonstration that the mutable, field-learned SAVE memory was purely additive and the signed, immutable ROM core stands alone (SPEC §3.4).
Why this matters
strip is how a recipient proves a cartridge was never quietly mutated: strip it, and if the ROM hash
still matches the signed manifest, the shareable core is exactly what was signed. See the
Cartridge model for the ROM/SAVE split.
level¶
Run the demo benchmark with an independent verifier key, issue a level credential if the gate passes, and write the VC next to the cartridge.
Synopsis
Options — a single positional <file.acx>; no flags.
What it does
- Reads the cartridge's ROM digest and constructs a subject id
urn:acx:cartridge:<cartridge_id>. - Generates a separate verifier key/identity (
did:web:verifier.acx.dev) — never the publisher's key — and re-runs the pinned ROM against a benchmark with a sealed held-out slice. - Applies the TrueSkill σ-gate (
sigma < 1.5,gamesPlayed ≥ 30, conservativeR = mu − 3·sigma). Only on pass does it issue a W3C VC 2.0 + Open Badges 3.0 credential bound to the ROM digest. - Attaches the attestation to the cartridge (so
inspectsurfaces it) without mutating the signed ROM capability — the ROM signature is left intact — and writes the VC to<file>.level-attestation.json.
The reference competence=33 agent clears the gate and earns acxLevel 29, tier principal.
cartridge rom digest: sha256:f479be021b8ea2e55cc6e3e33b95df9d151196548dfc854dedbe578be7120642
benchmark: acx-bench-dag-de@2026.07.1 (160 tasks, held-out 96)
level: ISSUED
acxLevel: 29
tier: principal
rating: mu=32.85 sigma=1.191 games=90 pass@1=60% R=29.27
credential verify: VALID
capability build-dag -> resolvable as VERIFIED via attestation (ROM signature left intact)
wrote VC: /tmp/demo.level-attestation.json
exit=0
The credential is unfakeable by construction
No self-issuance (issuer ≠ subject), digest-bound to this exact ROM, σ-gated, earned on a sealed held-out slice, and revocable. This is the cryptographic form of the harness principle that "candidates are accepted only if they have no regression on both held-in and held-out data" (Lilian Weng, Harness Engineering for Self-Improvement, 2026-07-04). Full mechanics: Provable level.
This CLI's benchmark uses a deterministic reference solver
The level command exercises the entire crypto/gating/credential pipeline, but its solver is a deterministic, pluggable stand-in — a production verifier plugs a real sandboxed agent run into the same gate and issues the same kind of credential.
End-to-end¶
A cartridge is a self-contained, signed harness — the agent-OS image — that any host boots via the harness-requirements handshake. The CLI walks the full lifecycle:
flowchart LR
A["agent-package dir"] -->|export| B[".acx (signed ROM)"]
B -->|inspect| C["meta / skills / caps"]
B -->|verify| D["trust taxonomy"]
B -->|strip| E["ROM-only .acx<br/>hash EQUAL"]
B -->|level| F["σ-gated VC<br/>bound to ROM digest"]
See also: Proofs (reproducible scripts and assertions) · Conformance · Schemas · Signing & trust · Distribution.