# AIR CLI Reference
Install with pip install -e . and the air command is on your PATH
(equivalently: python -m sdk.cli).
Global concept: the AIR home (--home <dir>) is your managed books
directory — meta, hash-chained ledger, content-addressed document archive,
exports, and the review inbox. Most commands take --home; --policies
defaults to the home's configured policy set.
# Lifecycle
| Command |
What it does |
air init --home books --policies alsl/policies/ca-qc-2026.yaml [--name x] |
Create a managed AIR home |
air status --home books |
Entries, chain validity, archives, exports |
air audit --home books |
Render + verify the hash-chained syscall audit log |
# Compile & post
| Command |
What it does |
air compile doc.yaml --home books |
Compile AIR events → post to the native ledger; archives the document |
air compile doc.yaml --home books --optimize |
Same, with duplicate detection, netting, and payment fusion |
air compile doc.yaml --home books --report trial-balance --format markdown |
Post, then print statements |
air compile doc.yaml --home books --backend csv |
Export a universal CSV journal instead |
air compile doc.yaml --home books --backend qbo-export |
QuickBooks-shaped JSON export — no QuickBooks account needed |
air verify doc.yaml --policies <set> |
Compile without posting; print diagnostics |
air recompile old.yaml new.yaml --home books |
Incremental: diff by content fingerprint, post reversal + replacement entries only |
# Statements
| Command |
What it does |
air report trial-balance --home books |
Also: general-ledger, income-statement, balance-sheet |
... --format text|markdown|csv|json |
Any statement, four formats |
# Ingestion (document → books)
| Command |
What it does |
air ingest invoice.txt --home books |
Extract events (offline mock extractor), validate against the AIR schema, route by confidence |
air ingest invoice.txt --home books --llm |
Use the Claude extractor (needs pip install anthropic + ANTHROPIC_API_KEY) |
air ingest ... --threshold 0.9 |
Auto-approve threshold (default 0.85); schema-invalid always goes to a human |
air inbox --home books |
List extractions awaiting review |
air approve inbox_00000 --home books --approver name |
Stamp approver + timestamp, compile, post |
air reject inbox_00000 --home books --reason "duplicate" |
Reject (archived, never deleted) |
# Bank reconciliation
| Command |
What it does |
air reconcile statement.xml --home books |
camt.053 / MT940 / CSV, auto-detected; exits 0 clean, 2 with differences |
... --cash-account 1000 --tolerance-days 3 |
Matching knobs |
# Agent surface (Python)
from sdk.syscalls import AirKernel
k = AirKernel("books", actor="agent:alice")
k.create_economic_event({...}) # schema-validated draft
k.validate(); k.compile() # dry runs
k.post() # deterministic compile -> books (idempotent)
k.merge() # post with netting + fusion
k.reverse("je_evt_x") # contra entry, never an edit
k.close_period("2026-01") # later posts into it are refused (AIR-E700)
k.reconcile("statement.mt940") # bank matching
k.generate_report("balance-sheet", "markdown")
# every call above — success or refusal — is one hash-chained audit record
# Demo
air init --home /tmp/demo --policies alsl/policies/ca-qc-2026.yaml
air compile tests/fixtures/demo_document.yaml --home /tmp/demo --report balance-sheet
python -m sdk.demo_agent --home /tmp/demo # scripted agent, syscalls only
air audit --home /tmp/demo