Public documentation for governed AI labor
SDKs/Governance/Connectors
Arx / Docs / arxctl — ARX command-line tool

Documentation

arxctl — ARX command-line tool

Project-Agent / tools/arxctl/README.md

Project-Agent repo-root tools/arxctl/README.md

Two subcommands ship today; the package is structured so future subcommands slot in without changing call sites.

Subcommands

validate-manifests (Phase 2 / Workstream A.2)

Validates agent manifests against reference-agents/MANIFEST_FRAMEWORK.md v1.0.0.

```bash

Validate one manifest:

python -m tools.arxctl validate-manifests \ reference-agents/atlas-ceo-aide/manifests/job_description.yaml

Validate every shipped manifest (regression):

python -m tools.arxctl validate-manifests \ reference-agents/*/manifests/job_description.yaml

CI mode — treat warnings as errors:

python -m tools.arxctl validate-manifests --strict \ reference-agents/*/manifests/job_description.yaml ```

Exit codes: 0 on success, 1 on any validation failure or (in --strict) any warning, 2 on misuse.

The validator catches every framework violation: missing role.cell, wrong role.shape, missing termination_attestation_required: true, write actions without explicit approval rules, customer-private cells without a network_egress_policy deny-list, duplicate operation IDs, etc.

The 72-hour deployment runbook's Window 1 step T+0:25 calls this against every manifest in the customer's signed manifest set. Any failure halts the clock.

verify-chain (Phase 6 / Workstream E)

Customer-side audit chain verifier. Runs on the customer's auditor laptop. Reads NDJSON + manifest + signature artifacts from the customer's S3 bucket, re-walks the hash chain locally, runs kms:Verify per batch. No ARX trust required at any step — every endpoint touched is the customer's own infrastructure.

``bash python -m tools.arxctl verify-chain \ --bucket cisco-arx-audit \ --org-id <uuid> \ --kms-key-arn arn:aws:kms:us-east-1:CUST:key/abcd \ --region us-east-1 ``

For machine-readable output:

``bash python -m tools.arxctl verify-chain --json \ --bucket cisco-arx-audit --org-id <uuid> \ --kms-key-arn arn:aws:kms:us-east-1:CUST:key/abcd ``

Exit codes: 0 on full integrity, 1 on any tamper detected, 2 on misuse (missing boto3, etc.).

The verifier checks four properties per batch:

  1. NDJSON SHA matches manifest.ndjson.sha256 — catches payload

tampering.

  1. manifest_sha256 recomputes correctly — catches manifest

tampering.

  1. Chain links hold — re-walks every prev_hash

entry_hash link from the prior batch's tip.

  1. KMS Verify returns SignatureValid=True — confirms the

manifest was signed by the customer's KMS key.

Stops on the first failure (subsequent batches' expected_prev is wrong anyway).

Tests

```bash

Run all CLI tests:

python tools/arxctl/test_manifest_validator.py python tools/arxctl/test_verify_chain.py ```

Both test suites mock their dependencies (no real S3/KMS access required). The validator regression test test_all_repo_reference_manifests_pass walks every shipped reference-agent manifest and confirms framework conformance.

Architecture

The CLI loads the server-side app/core/audit_chain.py by file path so the verifier can ship as a standalone tool against any release tarball. The pure functions (canonical_event_json, compute_entry_hash, verify_chain_segment) produce byte-identical results on the server and on the customer's laptop — that's the whole point of canonicalization.

The package layout:

`` tools/arxctl/ __init__.py (empty marker) __main__.py (subcommand dispatcher) manifest_validator.py (validate-manifests library + CLI main) verify_chain.py (verify-chain library + CLI main) test_manifest_validator.py test_verify_chain.py README.md (this file) ``

Adding a new subcommand

  1. Add a module tools/arxctl/<name>.py with a top-level

main(argv: list[str] | None = None) -> int entry point.

  1. Register it in tools/arxctl/__main__.py:

```python from . import manifest_validator, verify_chain, your_new_thing

def main() -> int: sub = sys.argv[1] if sub in ("your-new-subcommand", "yns"): return your_new_thing.main(sys.argv[2:])

...existing dispatch

```

  1. Add a test file tools/arxctl/test_<name>.py.
  2. Add the subcommand to this README.