ADF
Christian Balevski · github.com/christianbalevski/adf
ADF stores each agent as a documented SQLite file run by an MIT-licensed local runtime with no hosted service, so it is strong on portability, transparency and data handling. The action record has no tamper evidence and is pruned by default, agent state has no versioned rollback, and some owner limits (channel recipients, non-fetch egress) are not enforced on every path.
Disclosure: ADF was built to be an agent for humanity, so its design deliberately follows these criteria. Whether that is a good thing is for you to judge.
- Agent is a local, documented SQLite file with no provider account (P2, P5, T1)
- All injected context recorded in the file (T2)
- No telemetry; outbound flows disclosed with off switches (C4, T3)
- Owner-rooted did:key identity recoverable from a seed phrase (V2)
- No tamper evidence on the action record, which is pruned by default (A1, A2)
- No change history or rollback of agent state (V3)
- Channel and non-fetch egress limits not per-recipient or enforced on every path (C1)
- Startup migrations re-apply removed prompt sections (M1)
All 26 findings
Tag v0.7.5, commit 213640357fdc8a7799009bd3f46e7f03b2814bcc (release 2026-09-29), macOS/Windows/Linux desktop. Desk review of source, docs and spec in a local clone at that commit; no website, privacy policy or terms exist beyond the repository. G11: spend treated as met (no payment capability); provider-side automation treated as met (no hosted service).
Portable · Can you leave, take the whole agent with you, and keep it alive?
80%- P1Owner-usable round trip
Export is immediate (the agent is one .adf file; copying it and using Open is documented), but restoring a working agent on another machine takes several documented steps: import the owner seed phrase to unlock sealed keys, re-add a model provider key (app-level keys are not in the file), re-register app-level MCP servers, then review and accept the file. One shortfall (restore is not a single action).
- README highlights
- Security and identity guide (import identity)
- Settings guide (key-less provider copy)
- MCP integration (register missing servers)
- ADF spec: not guaranteed to transfer
› How it could pass
Suggestions. Any change that meets the test counts.
- Offer one import action that restores the file, unlocks identity and prompts for any missing provider key or MCP server in a single flow.
Partial - P2Complete export
The spec places config, instructions, memory, loops, timers, triggers, lambdas, files, messages, audit, logs, sealed identity keys and per-agent credentials in the .adf file; the project holds nothing. Items outside the file (app-level provider keys, app-scoped MCP credentials, WhatsApp session directory, runtime settings) can be re-linked by the owner without any ADF-registered client (MCP OAuth uses dynamic client registration; subscriptions use OpenAI/xAI client ids). A customised global base prompt is an app setting and does not travel; recorded, not counted, because the default install uses the shipped prompt.
Pass - P3Runs without the provider
The runtime is MIT-licensed with no licence check, account or ADF-run relay; the only ADF-project endpoints (GitHub update check, MCP registry, skill catalog, online docs) are optional, have off switches or bundled fallbacks, and are not needed to start or act. Mesh uses LAN, tailnet or owner-chosen addresses. Desk grade; a provider-blocked run is required at certification.
Pass - P4Model independence
Tool calling is the documented minimum and local open-weight models (Ollama, LM Studio, vLLM, llama.cpp) are first-class provider options; triggers, timers, lambdas and middleware run in the runtime. However, video input is implemented by injecting OpenAI-format video_url parts and is documented only for hosted providers (OpenRouter, Gemini), and no test against a local model is published, so under G12 at least one capability is not shown to survive a local model.
› How it could pass
Suggestions. Any change that meets the test counts.
- Document and test image, audio and video input (and computer use) against a named local open-weight model.
- Publish the minimum model contract with a tested local reference model.
Partial - P5Exit survives termination
State is local-first: the agent is a SQLite file on the owner's disk with no ADF account or hosted copy, so no termination, ban or shutdown by the project can remove access to it.
Pass
Transparent · Can you see everything the agent is, and everything shaping it?
100%- T1Readable without the provider
The whole agent is a SQLite file whose protected schema (schema v32) is specified table by table in the public spec; logic (lambdas, skills, hooks) is stored as source files; adf_audit blobs are documented Brotli-compressed JSON; secrets are sealed to the owner's seed-derived key and a per-install runtime key in the OS keychain. Minor gaps recorded: runtime_* meta keys are declared opaque (one integer cursor today) and the turn-checkpoint JSON shape is undocumented.
Pass - T2What runs is what you see
The spec requires and the executor implements recording every runtime-authored prompt text (system prompt snapshots, dynamic instructions, compaction summaries, loop_inject reminders) as rows in adf_loop; model id is stored per assistant row, tools and permissions in adf_config, and inherited app settings in an adf_effective_runtime snapshot. Edge gaps recorded, not counted: the snapshot omits side-loop and model_invoke model overrides (which are in the file config), and an owner-authored pre-LLM hook's rewritten request is not stored.
Pass - T3No shadow data
The project operates no service that receives agent content: crash upload is disabled, there is no telemetry SDK, and the update check sends a fixed staging id shared by all installs. The provider holds nothing (local operation).
Pass - T4No hidden steering
Source shows no paid placement: the MCP registry has no sponsor fields and no ADF-hosted model is offered. The only first-party preferences (base prompt pointing at ADF docs and the first-party skill catalog, which is the default catalog entry) are disclosed in NETWORK.md and the recorded system prompt and can be removed or replaced (Settings, include_base_prompt/bare_prompt). No binding no-steering commitment exists; pass rests on source.
Pass
Auditable · Can you reconstruct exactly what the agent did, and trust the record?
17%- A1Complete action record
The record spans adf_loop, adf_logs and adf_audit. Tool calls made from code (timers, triggers, lambdas, sys_code) are logged only on rejection or error, not on success; log writes swallow errors (catch non-fatal) and failed loop writes go only to the console and a memory buffer; adf_logs is a ring buffer trimmed to 10,000 rows by default and error messages are truncated. Three shortfalls.
- adf-call-handler best-effort log
- Lambda completion log
- LOGGING_DEFAULTS max_rows
- Log trimming
- Loop write fallback
› How it could pass
Suggestions. Any change that meets the test counts.
- Record every successful tool call from code paths with arguments and targets.
- Surface recording failures to the owner (or refuse the action).
- Stop pruning the action record by default.
Fail - A2Tamper-evident, owner-checkable
The record tables carry no hash, chain or signature, and no verifier ships. The sealed-epochs design is marked 'deferred. Not scheduled', and the spec notes the logs 'can be edited by whoever holds the file'.
› How it could pass
Suggestions. Any change that meets the test counts.
- Hash-chain or sign record entries and ship an open verifier.
- Anchor checkpoints with the owner or an independent witness.
Fail - A3Agent cannot rewrite its record
By default the agent cannot write adf_* tables (db_execute disabled and refuses adf_*; db_query is read-only; loop_clear and msg_delete disabled; sys_update_config for logging/audit is approval-gated; deleted loops are always archived). But sys_code/sys_lambda (on by default) run in a Node vm worker the docs say 'does not provide hard isolation', and the agent can evict adf_logs rows by flooding the 10,000-row ring buffer through normal calls.
› How it could pass
Suggestions. Any change that meets the test counts.
- Write the record from a component the agent's code cannot reach, with hard isolation.
- Keep the record from being evicted by agent-generated volume.
Partial
Verifiable · Can you prove what it runs, who it is, and what changed?
67%- V1Obtainable source, matching build
All source is MIT with open-source dependencies and releases are built in GitHub Actions, but the default Studio installers have no reproducible build, build attestation or provenance; only code signing and notarisation (the npm CLI, not the graded offering, gets npm provenance). A prebuilt resources/wasm/coreutils.wasm is committed without a build recipe.
› How it could pass
Suggestions. Any change that meets the test counts.
- Publish build provenance (e.g. GitHub attestations/SLSA) or reproducible builds for the Studio installers.
- Document how an owner verifies an installer against source.
- Ship the build recipe for committed binaries.
Partial - V2Owner-rooted identity
Agent and owner identities are did:key Ed25519, needing no resolver; the owner root is a locally generated 12-word BIP-39 seed recoverable on any machine without the provider, agent keys are sealed in the file and can be regenerated, and recipients verify signed ALF messages directly from the DID. Recorded caveats: no signed rotation attestation yet, and channel (Slack, email, etc.) actions are not DID-signed.
Pass - V3Change history and rollback
The loop transcript shows the agent's own tool calls, a config.changed event lists changed keys (in memory only, no values or author), and adf_audit keeps cleared loop segments by default; there is no versioning, attribution of owner or update changes, or restore for config, instructions, memory files, tools or model.
- Umbilical events: config.changed
- Umbilical is in-memory
- Memory management: audit defaults
- Sealed epochs (deferred)
› How it could pass
Suggestions. Any change that meets the test counts.
- Keep a durable, attributed change log for all agent state.
- Offer restore to a chosen earlier state.
Partial
Modifiable · Can you change anything, and can only you change it?
70%- M1Instructions and logic
The base prompt, tool-instruction sections and compaction prompt are editable in Settings and agents can suppress runtime prompt layers (bare_prompt). But a settings migration run at every start re-appends the {{soul.md}}/{{mind.md}} sections to a custom base prompt and the skills-catalog placeholder to a custom skills section (contrary to the settings guide), and built-in tool descriptions and runtime nudges are fixed in code.
› How it could pass
Suggestions. Any change that meets the test counts.
- Stop re-applying removed sections to owner-edited prompts.
- Make built-in tool descriptions and runtime notices owner-overridable.
Partial - M2Memory
Files, mind.md, the document and meta keys are viewable, editable and deletable in the UI, but the persistent loop (including compaction summaries reused across restarts) can only be cleared whole, and local_* tables the agent uses for contacts and structured memory can be listed and dropped but not edited row by row.
› How it could pass
Suggestions. Any change that meets the test counts.
- Add per-item edit and delete for loop entries and local_* rows.
- Expose every store the agent re-reads (including adf_audit) in the UI.
Partial - M3Tools
Owners can connect any MCP server or add lambdas without review, and every built-in tool has an enable switch in the agent config; no always-on tool was found.
Pass - M4Owner has the final say
Many protections are configurable (local-fetch guard, sandbox network, limits, logging and audit, host access), but some are hard-coded: cloud-metadata/link-local and daemon-port fetch blocks, a 300 s sandbox ceiling, the non-optional vm sandbox for code, and a forced idle after 4 consecutive tool-less replies.
› How it could pass
Suggestions. Any change that meets the test counts.
- Expose every remaining protection as an owner setting with a warning.
Partial - M5No unilateral change
App updates are opt-in: the app checks but downloads nothing until the owner clicks, and checks can be disabled, so the owner can stay on a version indefinitely; new agents have no preset model, and no remote flags were found. Recorded caveats: live catalogs from the repo's main branch (MCP registry on by default; skill catalog referenced by the default prompt) can change without a release but can be switched off or removed, and in-app notice is a release-notes link.
Pass
Controllable · Is your word final?
67%- C1Boundaries
Instruction sources are limited per DID and per sender, file tools are confined to the agent file, and the agent cannot change locked or restricted fields; spend is treated as met under G11 (no payment capability). But messages to channel adapters (email, Telegram, etc.) bypass outbox middleware and have no per-recipient limit, and egress by MCP servers, WebSockets and containers is not covered by per-domain limits (per-domain limits for sys_fetch require owner-written middleware code). Two shortfalls.
› How it could pass
Suggestions. Any change that meets the test counts.
- Add per-recipient and per-domain allow/deny lists as settings, applied to adapters, MCP, WebSockets and containers.
- Enforce limits on every action path.
Fail - C2Approval gates
Any tool, including MCP tools and code methods, can be marked restricted; model calls create tasks resolved only by the owner or owner-authorised code, unauthorised code calling a restricted tool is blocked, and inner loops strip gated tools.
Pass - C3Immediate halt
A single status-bar control ('Stop all agents and disable mesh') runs an emergency teardown that closes the runtime gate, aborts executors, stops timers and inner loops and tears down mesh, MCP, adapters, sandboxes and containers; restart needs an owner action. There is no provider-side work. Desk grade; confirm hands-on.
Pass - C4Data serves only the owner
No telemetry SDK and crash upload is off; the default-on flows (update check with a shared non-identifying id, provider checks to owner-chosen providers, catalog GETs with no content) are disclosed with off switches, and there is no hosted service, so no training, staff access or data terms apply.
Pass - C5Credential custody
The per-agent Identity panel lists credentials with reveal and delete, and provider keys and subscriptions are managed in Settings; but MCP OAuth sign-out clears only the app-level copy while agent-sealed copies remain usable, daemon access grants have no UI and revoke only after the file is re-opened, and some credentials (WhatsApp session, runtime keys) are not listed.
› How it could pass
Suggestions. Any change that meets the test counts.
- List every credential, including sealed MCP tokens and adapter sessions, with per-item immediate revocation.
Partial - C6Full deletion
Deleting an agent in the sidebar is one confirmed action that removes the .adf file and its WAL/SHM files, with no provider-side copies; but the adapter session directory, container workspace, app-level MCP/provider credentials and any .bak copies survive, so full deletion needs several steps and completion is not confirmed.
› How it could pass
Suggestions. Any change that meets the test counts.
- Make agent deletion remove adapter state, workspaces, backups and linked credentials, and confirm completion.
Partial
How this assessment was produced
One run, in a fresh container with stock Claude Code and no custom instructions, memory, hooks or plugins. The evaluator received only the prompt below.
Load the AFH sovereignty skill at https://agentsforhumanity.dev/skill.md and follow it to write a desk review of ADF (https://github.com/christianbalevski/adf).
During the run the skill was read from a local copy of this site with identical content; only the host in its URLs differed. The transcript records the exact prompt.
- Model
- claude-opus-5-5
- Harness
- Claude Code 2.1.285
- Ran
- 2026-09-30 13:59:33 UTC · 8 turns
- Criteria hash
- a9a46c32d9065380a3eeb09185cedd4734856fdc63b7ca509a15a1bbede75c6c
- Full transcript
- Download (JSONL, gzip) · every tool call, page read and reply
- Run protocol
- 2026-09-30-v1
Every agent evaluated once, each in its own fresh Podman container running stock Claude Code with Claude Opus 5.5. The container has no CLAUDE.md, AGENTS.md, memory, settings, hooks, plugins or MCP servers. The evaluator received only the one-line prompt and nothing else, and no published scores were available to compare against during the run.
- Human review
- pending
Load the AOH sovereignty skill at https://agentsofhumanity.ai/skill.md and follow it in verify mode for https://agentsofhumanity.ai/evaluations/adf.json.
Or grade it from scratch. See Check any score yourself.
Vendors and the public can dispute any finding with evidence. Disputes and their resolutions are published.