arest-cli runs the engine on your machine. Point it at a directory of
FORML 2 readings; it compiles them, persists state to SQLite, and exposes
every SYSTEM call as a single command shape.
There is no separate "compile", "synthesize", or "forward-chain" subcommand.
Everything is SYSTEM:x = ⟨o, D'⟩, exposed as arest-cli <key> <input>.
- Rust nightly (the engine uses some unstable features for the WASM target; the CLI itself is stable but the workspace pins nightly):
curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly -y- For the SQLite backend: nothing extra (the
localfeature bundles SQLite viarusqlite).
git clone https://github.com/graphdl/arest
cd arest
cargo build --release --bin arest-cli --features local
# Binary at target/release/arest-cli (or .exe on Windows)Add it to your PATH, or symlink it:
ln -s "$PWD/target/release/arest-cli" /usr/local/bin/arest-cliarest-cli readings/ --db app.dbThis walks readings/, parses every *.md, runs the full Stage-1 + Stage-2
compile pipeline, and writes the resulting state to app.db. Pass multiple
directories to merge them:
arest-cli readings/core readings/myapp --db app.dbOnce app.db exists, every other invocation is <key> <input>:
# Create
arest-cli --db app.db "create:Order" "<<Order Id, ord-1>, <Customer, acme>>"
# Transition (state machine)
arest-cli --db app.db "transition:Order" "<ord-1, place>"
# Read with HATEOAS links
arest-cli --db app.db "get:Order" "ord-1"
# List
arest-cli --db app.db "list:Order" ""
# Query a fact type
arest-cli --db app.db "query:Order_was_placed_by_Customer" '{"Customer": "acme"}'
# Update
arest-cli --db app.db "update:Order" '{"id": "ord-1", "notes": "rush"}'
# Delete
arest-cli --db app.db "delete:Order" "ord-1"The output is JSON — pipe through jq for pretty printing.
# Run the full deontic + alethic check against the current state
arest-cli --db app.db "verify" ""
# Check arbitrary text (extracts facts, checks them against constraints)
arest-cli --db app.db "validate" "Alice placed ord-2 on 2026-04-26."
# Explain a single entity (which constraints apply, which fired)
arest-cli --db app.db "explain" '{"noun": "Order", "id": "ord-1"}'
# List legal next actions on a cell (Theorem 5 surface)
arest-cli --db app.db "actions" '{"noun": "Order", "id": "ord-1"}'# Re-compile in place; preserves the population
arest-cli readings/ --db app.db
# Or load a single reading at runtime (governed by the deontic gate)
arest-cli --db app.db "load_reading:my-app" "$(cat readings/myapp/orders.md)"cargo run --release --bin arest-cli --features local -- readings/ --db app.db
cargo run --release --bin arest-cli --features local -- --db app.db "list:Order" ""On first run, arest-cli generates a 32-byte tenant master key and writes
it to ~/.arest/tenant_master.bin (Unix) or %USERPROFILE%\.arest\tenant_master.bin
(Windows). On subsequent runs the same file is read; the bytes seed the
HKDF-SHA256 derivation of every per-cell ChaCha20-Poly1305 key (#659).
Two operator invariants:
- Loss = unrecoverable cells. Without these 32 bytes, every sealed cell
on disk (freeze blobs, kernel checkpoints, DO contents) becomes unreadable
ciphertext. Back up
~/.arest/tenant_master.binimmediately after the firstarest-clirun. - Migration = copy the file. Moving to a new machine? Copy
~/.arest/tenant_master.bin(preservechmod 0600on Unix). Same key on both sides means cells exchanged between them open identically.
The file is created with mode 0600 on Unix; on Windows it inherits the
default %USERPROFILE% ACL (owner-only). If arest-cli finds a master
file with a looser Unix mode (e.g. 0644 after a sloppy cp), it refuses
to load and prints a chmod 0600 hint — fix the mode and re-run.
OS-keystore integration (macOS Keychain, Windows Credential Manager, Linux libsecret) is out of scope for v1; file an issue if your environment needs it.
cargo test -p arest --lib # 940+ engine tests, ~30 s
cargo test -p arest --lib --features parallel # opt-in Rayon for α/Filter
cargo t # alias: dev-fast profile, no optsdocs/02-writing-readings.md— FORML 2 syntax referencedocs/03-constraints.md— UC / MC / RC / XO / XC / OR / SS / EQdocs/04-state-machines.md— transitions as derivationstutor/— 17 lessons across three difficulty tracksdocs/cloud.md— same engine, deployeddocs/mcp.md— expose the local DB to an AI agent