ZeroClaw
ZeroClaw Labs · github.com/zeroclaw-labs/zeroclaw
ZeroClaw is a local-first, MIT/Apache-licensed Rust agent runtime whose state lives entirely in an owner-held directory, with no project-operated service in the default path. It scores well on portability, provider independence and freedom from unilateral change. Its action record is pruned, unsigned and can fail silently, and several owner controls (emergency stop, approval gates, credential revocation, deletion) have gaps.
- All state local under ~/.zeroclaw with no project-held copy (P2, P5, T3)
- Runs without any ZeroClaw Labs service, with local models and text-based tool calling (P3, P4)
- SLSA provenance ties release binaries to source (V1)
- No auto-update or remote flags; owner adds and removes any tool (M3, M5)
- Action log pruned to 200 entries by default, best-effort and unsigned (A1, A2)
- No export/import command or documented restore (P1)
- Documented estop is not enforced by the runtime (C3)
- Hard-coded base prompt sections cannot be replaced (M1)
All 26 findings
v0.8.5, tag commit cb2b20a9fe59004b7ef03e123942d31f29236d15 (released 2026-09-05); Linux x86_64 prebuilt as the reference platform; desk review 2026-09-30 of source, docs book, release assets and zeroclaw.com. Hands-on tests (P3, P4, V1, C1, C3, C4) graded on inspectable evidence only.
Portable · Can you leave, take the whole agent with you, and keep it alive?
90%- P1Owner-usable round trip
Export is immediate and needs no approval: the ops docs say a tar of ~/.zeroclaw covers everything. There is no export/import or restore command (the only `migrate` imports from OpenClaw) and no documented restore procedure, so restoring means installing the binary and unpacking the archive by hand (one shortfall).
- Runtime state and persistence (backup section)
- Ops overview: backups
- CLI command definitions
- Agent backup tool (workspace-local)
› How it could pass
Suggestions. Any change that meets the test counts.
- Ship a matching `zeroclaw export` / `zeroclaw import` (or `restore`) pair that leaves the agent running.
- Document restoring onto a new host, including a different home path.
Partial - P2Complete export
Every class of state sits under the install root: config and encrypted secrets with the owner's key file, sessions, memory (SQLite with source text; embeddings off by default), cron jobs, SOP runs, skills, per-agent workspaces and identity files. OAuth logins use the model vendors' own public clients, not a ZeroClaw-registered broker, so integrations re-link without the project. There is no manifest.
Pass - P3Runs without the provider
The runtime is MIT OR Apache-2.0 and needs no key, account or activation. Every contact with a project endpoint is optional and owner-triggered: `zeroclaw update` (GitHub Releases), the plugin registry (overridable by env var), the skills registry (overridable URL), and locale fetch. The relay is self-hosted and off by default. Desk review only; the provider-blocked run is hands-on.
Pass - P4Model independence
Ollama is a first-party keyless provider. Models without native tool calling get tools through the runtime's text-based PromptGuided fallback, and embeddings, transcription (local Whisper) and web search all have non-vendor options. No approval is needed to switch models. No formal minimum-model contract is published. Desk review only; the model swap is hands-on.
Pass - P5Exit survives termination
The default install is local-first: all agent state is always in ~/.zeroclaw on the owner's machine. ZeroClaw Labs holds no account or copy, so termination or shutdown cannot remove access.
Pass
Transparent · Can you see everything the agent is, and everything shaping it?
75%- T1Readable without the provider
State is stored as TOML config, SQLite databases (memory, sessions, cron, control plane), JSONL logs and plain workspace/skill files. SQLite embeds its own schema and the DDL is in public source. Secrets use ChaCha20-Poly1305 with an owner-held local key. The docs book lists paths but not table schemas or the `enc2:` layout; those are documented only in open source.
Pass - T2What runs is what you see
`log_llm_request_payload = "full"` records the full provider-bound message list for main-loop calls, and `zeroclaw config list` shows effective values including env overrides. However, auxiliary model calls (memory consolidation, on by default via auto_save, and the channel reply-intent classifier) are not captured. Tool instructions appended in the provider layer for non-native-tool models are added after the capture point. These are visible only in source (one shortfall).
- Observability: request payload logging
- Capture point
- Provider-layer tool instruction injection
- Consolidation prompt
- Channel classifier
- config list env-override legend
› How it could pass
Suggestions. Any change that meets the test counts.
- Route every model call (consolidation, classifiers) through the same payload capture.
- Capture requests after the provider layer's final rewrite, including tool schemas.
Partial - T3No shadow data
The source has no telemetry, analytics or crash reporting, and no endpoint on a project domain; OTel export has no endpoint by default. ZeroClaw Labs operates no service that receives owner data in the default configuration.
Pass - T4No hidden steering
Quickstart's provider picker preselects its first entry, OpenRouter, from a hand-ordered list, and no reason or commercial relationship is disclosed. The default is replaceable, with about 40 providers. There are no sponsored tools or paid placement in prompts, but no binding no-steering commitment exists, so the pass is withheld (G12).
› How it could pass
Suggestions. Any change that meets the test counts.
- Disclose why OpenRouter is preselected, or use a neutral or local-first order.
- Publish a binding no-paid-placement commitment.
Partial
Auditable · Can you reconstruct exactly what the agent did, and trust the record?
17%- A1Complete action record
Tool calls are logged to data/state/runtime-trace.jsonl, but persistence defaults to Rolling with max_entries = 200, and cron run history is pruned to 50. When the queue is full, events are dropped with only a tracing warning (the log is documented as best-effort). The recording floor is `warn` for interactive `zeroclaw agent` and ACP sessions, so INFO tool-call events on those paths are not persisted. That is three shortfalls.
- Log persistence defaults
- Observability docs
- Dropped events
- Logging: best-effort
- Per-command log floor
- Tool call logging
- Cron run history
› How it could pass
Suggestions. Any change that meets the test counts.
- Keep the action record until the owner deletes it.
- Record at a persisted level on every entry path, including interactive and ACP.
- Tell the owner when a write fails, or do not perform the action.
Fail - A2Tamper-evident, owner-checkable
The action record (runtime-trace.jsonl) is plain JSONL with no hash chain or signature. The Merkle-chained audit.log covers only certificate events and has a constant genesis hash. Tool receipts use an ephemeral in-memory HMAC key and cannot be verified by a third party.
› How it could pass
Suggestions. Any change that meets the test counts.
- Hash-chain or sign every action-record entry.
- Anchor checkpoints with the owner or an independent witness.
- Ship a documented open verifier that works across rotation.
Fail - A3Agent cannot rewrite its record
The record sits outside the agent workspace, and the default policy (workspace_only, forbidden_paths) blocks file tools from it. But in the recommended Balanced preset (allowed_commands = ["*"]), the prebuilt binary falls back to a no-op sandbox when no backend is available. A script run through the shell can then reach the file, so protection rests on policy with one bypass path.
- Log path initialisation
- Default forbidden paths
- Balanced preset
- Sandbox fallback to no-op
- Cargo features
› How it could pass
Suggestions. Any change that meets the test counts.
- Write the record from a component the agent's tools cannot reach (separate process or append-only).
- Fail closed when no OS sandbox is available.
Partial
Verifiable · Can you prove what it runs, who it is, and what changed?
67%- V1Obtainable source, matching build
All components, including the dashboard and relay, are MIT OR Apache-2.0 in the repository. The v0.8.5 release ships Sigstore-signed SLSA v1 provenance bundles binding each artifact's SHA-256 (for example the default x86_64 Linux tarball) to commit cb2b20a, and documents how to verify them. install.sh itself checks only SHA256SUMS. Desk review only; build verification is hands-on.
Pass - V2Owner-rooted identity
The project issues no identity. The daemon mints its own local CA, the optional relay uses a locally held Ed25519 key, and an A2A card can be served under an owner URL but is unsigned and off by default. Outbound actions are not signed, so attribution is per channel only (one gap).
› How it could pass
Suggestions. Any change that meets the test counts.
- Create an owner-held agent keypair or DID.
- Sign outbound actions and the A2A card, and document how recipients verify them.
Partial - V3Change history and rollback
An opt-in memory audit records memory operations (operation, key, namespace, session), but not content, before/after values or actor type, and there is no restore. Config has no change history: the .bak is removed after a successful write, and the docs point to manual backup restore. Instructions and skills are not versioned.
› How it could pass
Suggestions. Any change that meets the test counts.
- Version all agent state (config, instructions, skills, memory) with attribution to owner, agent, tool, import or update.
- Offer one-step restore to a chosen earlier state.
Partial
Modifiable · Can you change anything, and can only you change it?
70%- M1Instructions and logic
Owner-layer files (AGENTS.md, SOUL.md, IDENTITY.md, etc.) and skills are editable files. Large parts of the base system prompt (tool honesty, safety, channel capabilities, calibration note) and the memory-consolidation prompt are hard-coded, and config cannot replace them.
› How it could pass
Suggestions. Any change that meets the test counts.
- Expose the hard-coded prompt sections and the consolidation prompt as owner-editable files or config.
Partial - M2Memory
The main memory store can be listed, read, upserted and deleted item by item from the CLI and dashboard. Session history, which the agent reuses, can be listed but only deleted or renamed as whole sessions; individual messages cannot be edited or deleted (one store not fully editable). The optional relationship-memory graph has no owner edit surface.
› How it could pass
Suggestions. Any change that meets the test counts.
- Per-message edit and delete for session history.
- An owner edit/delete surface for the knowledge graph.
Partial - M3Tools
Owners can add any MCP server, or define shell/http/script tools in skills, without review. Any built-in can be removed with the risk profile's excluded_tools/allowed_tools, applied to all paths in one filter.
Pass - M4Owner has the final say
Autonomy, workspace scoping, forbidden paths, the command guard, the sandbox, rate limits and leak detection can all be switched off in config. The path guards (`..`, encoded traversal, `~user`) and untrusted-content framing have no off switch.
› How it could pass
Suggestions. Any change that meets the test counts.
- Add documented switches, with a warning, for the path-string guards and untrusted-content framing.
Partial - M5No unilateral change
There is no auto-update or remote flag. `zeroclaw update` runs only when the owner starts it, can pin `--version`, and the dashboard upgrade is owner-triggered with release notes. The model is an owner-set string. The opt-in open_skills sync (off by default) pulls a third-party repo weekly.
Pass
Controllable · Is your word final?
50%- C1Boundaries
There are per-sender peer groups, per-domain allow/deny for HTTP/fetch/browser, a command allowlist, path rules and per-tool allow/exclude lists; file tools refuse to write config.toml. The product has no payment capability, so spend was treated as met under G11. Cron `delivery.to` accepts any recipient without checking peer groups (one bypass path). The default-registered model_routing_config tool can also rewrite the calling agent's own risk profile and tool list, held back only by the generic supervised approval prompt.
- Peer groups
- Sandboxing and scope
- file_write config protection
- model_routing_config self-upsert
- Cron delivery
› How it could pass
Suggestions. Any change that meets the test counts.
- Block configuration tools from changing the calling agent's own profile.
- Check cron delivery targets against an outbound recipient allowlist.
Partial - C2Approval gates
The owner can gate any tool with always_ask, and the runtime overwrites any model-supplied `approved` flag; channels and cron fail closed. However, bounded delegate sub-loops are built with `approval: None`, so their tool calls bypass the gate (one path).
› How it could pass
Suggestions. Any change that meets the test counts.
- Route bounded delegate tool calls through the parent's approval manager.
Partial - C3Immediate halt
The docs describe `zeroclaw estop` as halting all in-flight tool calls, but it is disabled by default. The code only writes a state file that no runtime component reads. The working stop is ending the daemon (`zeroclaw service stop` / SIGTERM). Separate CLI/agent processes need their own steps, and the enabled service plus persisted cron jobs resume at next login. There is no documented within-seconds guarantee.
› How it could pass
Suggestions. Any change that meets the test counts.
- Enforce estop state before every tool call and scheduler tick, and enable it by default.
- Document that one stop cancels in-flight turns, subagents, SOPs and cron, with explicit resume.
Partial - C4Data serves only the owner
There is no telemetry or analytics, update checks are manual, and model content goes only to the owner-selected provider. However, web_search is enabled by default with DuckDuckGo and auto-approved, so model-written queries go to a third party the owner did not specifically choose (it can be turned off). OpenRouter requests carry fixed, undocumented app-attribution headers. The docs' "no telemetry" statements are not binding terms, and no privacy policy exists.
- Web search default enabled
- Default search provider
- OpenRouter attribution headers
- Philosophy: you own it
- ZeroClaw website
› How it could pass
Suggestions. Any change that meets the test counts.
- Make web search opt-in or ask during setup which provider to use.
- Document every outbound flow (including attribution headers) and make each switchable.
- Publish a binding no-telemetry commitment.
Partial - C5Credential custody
Secrets are encrypted locally with an owner-held key and the project holds no copy. Credentials can be listed and revoked one by one across `config list --secrets`, `auth list/logout` and paired-device tokens. Revocation through CLI config writes takes effect only on the next load or reload of the running daemon.
› How it could pass
Suggestions. Any change that meets the test counts.
- Make revocation take effect immediately in the running daemon.
- Provide one credential inventory with a revoke control per item.
Partial - C6Full deletion
`install.sh --uninstall` removes the service and binary and, after an interactive prompt, deletes ~/.zeroclaw. The piped default install path keeps data non-interactively, other platforms need a manual rm, and no completion limit is stated. There are no project-side copies.
› How it could pass
Suggestions. Any change that meets the test counts.
- Add a single `zeroclaw uninstall --purge` on all platforms that confirms 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 ZeroClaw (https://github.com/zeroclaw-labs/zeroclaw).
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 17:13:30 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/zeroclaw.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.