ARF · Audit Record Foundry

Documentation &
Wild Examples

ARF is the Audit Record Foundry. Every example below produces a cryptographically signed, tamper-evident proof bundle. You aren't running agents; you're building a permanent record of every decision they made.

Quick Start

ARF requires PostgreSQL 16 with the pgvector extension for its task and provenance database. If you skip the database, ARF falls back to JSONL for offline use. Start that first, then install the ARF binary.

# Install ARF cargo install --path . --bin arf # or from crates.io when published: cargo install arf # Initialize governance config in your project arf config init # Creates .arf/config.toml in the current directory # Start the proxy (runs in the background) arf start --background # Proxy listening on localhost:4554 # Run any agent through governance arf run claude "implement the login feature" # Or just use the shell alias (auto-routes through ARF): claude "implement the login feature" # Open the TUI to watch what's happening arf tui

ARF requires: Rust 1.78+, git 2.40+. PostgreSQL is optional (JSONL fallback available). Supports macOS 13+ and Linux (kernel 5.15+). Windows support is planned.

Your First Governance Policy

ARF generates a default config on arf config init. The main config lives at .arf/config.toml. Customize it:

# .arf/config.toml [routing] default_runner = "claude" # claude | codex | gemini | antigravity default_engine = "anthropic" # anthropic | openai | gemini | ollama [governance] require_approval_for_tools = ["Write", "Bash"] blocked_commands = ["rm -rf", "curl * | sh"] blocked_paths = ["/etc", "~/.ssh"] [governance.sandbox] default_level = "sandbox" # jailed | sandbox | workspace | full project_dir = "." [circuit_breakers] consecutive_failures = 3 error_rate_threshold = 0.15 cooldown_seconds = 60 # Validate config before starting arf config validate # ✓ .arf/config.toml: config valid

Your First Governed Session

# Start the ARF proxy (runs in the background) arf start # Proxy listening on localhost:4554 # Launch the TUI to monitor (separate command) arf tui # In another terminal. Point your CLI at ARF and go. export ANTHROPIC_BASE_URL=http://localhost:4554 claude . # Check governance event log arf audit --last 10 # {"event_type":"runner_invoked","detail":{"engine":"claude","prompt_tokens":1024}} # Export the proof bundle when done arf provenance export --format json --out .arf/bundle.json # Verify bundle integrity arf provenance verify

Wild Example 1: Approve Reads, Block Network

Auto-approve all read operations. Require human sign-off on any network call. Block writes to files outside the src/ directory.

[governance] # Read operations are auto-approved; writes and shell require sign-off require_approval_for_tools = ["Write", "Bash"] # Block any command that touches external network resources blocked_commands = ["curl", "wget", "fetch", "axios"] blocked_paths = [".env", "config/production"] [governance.sandbox] default_level = "workspace" # agent confined to project dir project_dir = "."

The result: the agent can freely read and explore the codebase, but every write and shell command requires human approval, and any attempt to touch production config or .env files is blocked at the filesystem level. The approval decisions are visible in the proof chain.

Wild Example 2: 12 Agents in Parallel, Merge Only Passing Ones

Decompose a large refactor into 12 subtasks, run them in parallel using isolated git worktrees, and merge only branches that pass quality gates.

# Decompose the task and fan out to 12 parallel agents arf launch "Migrate the entire codebase from callbacks to async/await" \ --parallel 12 \ --worktree \ --profile standard # Each subtask runs in its own git worktree. # Conflict resolution: auto for clean merges, HITL for conflicts. # Watch progress in the TUI (separate terminal): arf tui # After merge, export the full multi-agent proof bundle arf provenance export --format json --out migration-proof.json

Wild Example 3: Fully Auditable AI-Assisted Code Review Pipeline

Run three agents in sequence: Producer writes code in an isolated worktree, Reviewer audits it, Archivist exports the proof. Every decision is in the provenance chain.

# Step 1: Producer writes the code (isolated worktree) arf launch "Implement rate limiting for the auth endpoints" \ --engine anthropic \ --worktree # Creates a git worktree, runs the agent, builds proof chain # Step 2: Reviewer audits the changes arf launch "Review the rate limiting implementation for security issues" \ --engine anthropic # Step 3: Export a full proof bundle for the review arf provenance export --format json --out code-review-proof.json # Every decision, every approval, every model response. One bundle. # Verify the bundle is intact and the chain is unbroken arf provenance verify # ✓ provenance chain valid (n entries, Ed25519 signatures intact) # Check governance grades for the session arf governance grade

Wild Example 4: Route by Task Type. Claude for Architecture, Ollama for Boilerplate

Expensive creative work goes to Claude. Mechanical transforms (boilerplate, format conversion, test generation from spec) route to a local Ollama model for free.

# .arf/config.toml. Configure named engine aliases. [providers.ollama] type = "chat_completions" base_url = "http://localhost:11434" models = ["qwen2.5:72b", "llama3.3:70b"] [routes.aliases] # Aliases let runners select engines by model name "claude-arch" = { backend = "anthropic", model = "claude-opus-4-7" } "local-fast" = { backend = "ollama", model = "qwen2.5:72b" } # Launch architecture work at Claude, boilerplate at Ollama arf launch "Design the new caching layer architecture" --engine claude-arch arf launch "Generate CRUD boilerplate for User, Post, Comment models" --engine local-fast # Free. Runs offline. No data leaves the machine.

Wild Example 5: Air-Gapped Session. Zero Cloud API Calls

Run an entire agent session with no network access to cloud APIs. Everything stays local. Still fully governed, still fully audited.

# .arf/config.toml. Route everything to a local Ollama instance. [providers.ollama] type = "chat_completions" base_url = "http://127.0.0.1:11434" models = ["qwen2.5:72b"] [routing] default_engine = "ollama" default_model = "qwen2.5:72b" [governance] blocked_paths = ["/etc"] # No ANTHROPIC_API_KEY or OPENAI_API_KEY required # All inference stays on 127.0.0.1. Nothing reaches the internet.

Configuration Reference

Config is discovered and merged in order: compiled defaults, then ~/.config/arf/config.toml, then .arf/config.toml in the project directory. Pass --config <path> to arf start to bypass auto-discovery and use only the specified file.

Engine vs. backend: engine is the user-facing term. It's what you pass to arf launch --engine and set in [routing] default_engine. backend is the config term used inside [routes.aliases] and [routes.default.*] to name the destination provider. Both refer to the same set of providers (anthropic, openai, ollama, etc.) but in different contexts.

[proxy]

[routing]

[routes.default.<facade>] and [routes.aliases]

Routes map incoming facades (the protocol a runner speaks) to a backend + model pair.

# When Claude Code connects (anthropic facade), route it to OpenAI [routes.default.anthropic] backend = "openai" model = "gpt-4.1" # Named aliases: use as model name in the runner to select a backend # e.g.: OPENAI_BASE_URL=http://localhost:4554 codex --model claude-heavy "prompt" [routes.aliases] "claude-heavy" = { backend = "anthropic", model = "claude-opus-4-7" } "local" = { backend = "ollama", model = "qwen2.5:72b" }

[providers.<name>]

Add additional backends (OAI-compatible endpoints, self-hosted, OpenRouter, etc.). The provider key becomes the backend name in routes and --engine.

[providers.ollama] type = "chat_completions" base_url = "http://localhost:11434" [providers.openrouter] type = "chat_completions" base_url = "https://openrouter.ai/api" api_key_env = "OPENROUTER_API_KEY"

[governance]

[governance.sandbox]

[circuit_breakers]

[task_db]

[[governance.rules]]: Rule Language

Custom rules live in .arf/governance/rules.toml. A rule with the same name as a built-in replaces it; new names extend the rule set.

[[governance.rules]] name = "no-prod-writes" # unique rule identifier description = "Block writes to production config" severity = "block" # block | warn | rewrite | modify trigger = "request" # request | stream_text_match match_patterns = [ "config/production/", "(?i)\\.env\\.prod", ] owasp_risks = ["1", "6"] # OWASP Top 10 risk tags (optional) # Rewrite: replace matched text in streamed output [[governance.rules]] name = "redact-tokens" severity = "rewrite" trigger = "stream_text_match" match_patterns = ["ghp_[A-Za-z0-9]{36,}"] replacement = "[REDACTED]" # Modify: clamp a model parameter to a safe value [[governance.rules]] name = "clamp-temperature" severity = "modify" trigger = "request" condition = "temperature > 1.0" modification = "clamp_temperature(1.0)" message = "Temperature clamped to 1.0"

Severity values: block rejects the request outright. warn logs and continues. rewrite mutates streamed output (requires replacement). modify patches request parameters (requires condition and modification).

Trigger values: request evaluates on the inbound request body. stream_text_match evaluates on each streamed text chunk from the model.

Run arf governance rules to list all active rules. Run arf config validate to verify your rules file before starting.

Governance Policy Reference

Governance rules live in .arf/governance/rules.toml. Each rule is a TOML array entry under [[rules]].

Rule Actions

Condition Types

Three Built-in Profiles

Shell Integration

ARF ships shell integration for bash, fish, and zsh. The integration creates aliases that auto-start the proxy and route the runner through ARF.

# Install shell integration (adds aliases to your shell rc) arf shell install # For fish: adds to ~/.config/fish/config.fish # For bash: adds to ~/.bashrc # For zsh: adds to ~/.zshrc # What the integration does: # 1. Creates aliases: claude, codex, gemini, agy # 2. Each alias auto-starts the ARF proxy if not running # 3. Sets ANTHROPIC_BASE_URL / OPENAI_BASE_URL to localhost:4554 # 4. Auto-stops the proxy when the last agent exits # 5. Injects governance env vars into the runner process # After installation, just use the runner as normal: claude "refactor the auth module" # Proxy starts, governance applies, audit chain records, proxy stops on exit. # Remove integration arf shell uninstall

The shell integration is idempotent. Running arf shell install twice doesn't duplicate entries. The proxy check uses a PID file at ~/.arf/proxy.pid.

MCP Integration

ARF exposes its governance, knowledge, and orchestration surface as an MCP server. Any MCP-aware client can connect.

# Start the MCP server (stdio JSON-RPC) arf mcp-server # Add to Claude Desktop config (~/.config/claude/claude_desktop_config.json): { "mcpServers": { "arf": { "command": "arf", "args": ["mcp-server"] } } } # Same pattern for Zed, Cursor, or any MCP-aware editor. # Key MCP tools exposed: # governance_check_action, governance_report_event, governance_rules # arf_task_list, arf_task_checkout_next, arf_task_checkin # arf_run_claude, arf_run_codex, arf_run_gemini, arf_subagent # knowledge_add, knowledge_query, knowledge_attest # provenance_show, provenance_verify # vault_checkout, vault_return

See the MCP page for the full tool list and usage examples.

IDE Integration

ARF has extensions for VS Code and JetBrains IDEs. Both connect to the proxy over HTTP and show governance status, allow approve/deny of HITL requests, and open the audit trail inline.

# VS Code: install from marketplace # Search for "ARF Agent Watchdog" in the Extensions panel # or: code --install-extension arf-io.arf-vscode # JetBrains: install from JetBrains Marketplace # Settings → Plugins → search "ARF Agent Watchdog" # Works in IntelliJ, PyCharm, GoLand, WebStorm, Rider

See the IDE Plugins page for full setup instructions.

Environment Variables

Keyboard Shortcuts Reference

See the full Terminal UI page for keyboard shortcuts. Quick reference:

Frequently Asked Questions

Yes. ARF itself requires no internet access. Configure any OAI-compatible local inference server (Ollama, DeepSeek, Qwen, llama.cpp) as your engine, set an empty network allowlist, and run entirely offline. Governance, auditing, and the TUI all function identically.
ARF reads API keys from environment variables (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.) and injects them just-in-time into outbound requests. The keys are never written to disk in plaintext and never visible in the TUI or logs. The vault subsystem (arf vault) manages session-scoped secrets that agents can check out and return during a task. That's separate from your own API keys.
With OS-level isolation enabled (Agent Relay Fence), no. The agent process sits in a network namespace that routes all traffic through the ARF proxy. There's no other route to the internet. Without OS isolation, an adversarial agent can use a hard-coded IP that bypasses DNS. That's why the Agent Relay Fence and network policy enforcement exist.
It depends on message sizes. A typical 4-hour session with 200 messages produces a compressed bundle of 2–8MB. The bundle contains all message content, so size scales with how much text the agents exchanged. Bundles are compressed with zstd.
ARF's architecture, threat model, and reference policies are documented at github.com/arf-io/arf and in this site's documentation. If you want to understand how a particular guarantee is enforced, the code paths and rule files are linked from the reference section above.
Yes. arf start runs headless by default; it backgrounds the proxy without opening a TUI. In CI, set your governance policy to auto-approve the actions the agent needs, then use arf launch <PROMPT> to drive the agent. Use arf provenance export at the end of the job to capture the full proof bundle as a build artifact.