ZeroClaw
The Rust Microkernel Harness · Deep-Dive DD-16 · Course 1
60 minutes · The thin-by-philosophy, medium-by-implementation answer to OpenClaw. Trait-driven kernel, 6-layer safety, 25+ providers.
32,000+ stars. Apache-2.0. Rust single-binary. No telemetry, no SaaS, no license server. The defining decision: trait-driven extensibility (ADR-002) — adding anything is a trait impl, not a core patch.
Deep-Dives
The thesis — trait-driven kernel is the cleanest extensibility model
ADR-002: trait-driven extensibility
The kernel depends ONLY on zeroclaw-api traits (ModelProvider, Channel, Tool, Memory, Observer, RuntimeAdapter, Peripheral) — never on concrete impls.
6-layer safety as a cascade
Channel access control, autonomy level, workspace boundary, shell policy, OS sandbox, tool receipts. Each layer blocks a different attack class. The deepest safety surface in the thin-harness category.
The load-bearing claim: ZeroClaw's 6-layer safety model is the reference architecture for thin-harness security. Its tool-receipt system (HMAC-SHA256 over successful tool calls) is the only harness that directly addresses the fabricated-tool-claim attack (Module 11) at the protocol layer. The trait-driven kernel is what makes 25+ provider slots possible without core bloat.
The trait-driven kernel — how adding a provider works
| Step | What happens | Touches core? |
| 1. Implement trait | Write a ModelProvider impl for the new vendor | No |
| 2. Wire factory | Register the impl in the provider factory | No |
| 3. Feature-flag it | Add a Cargo feature so it only compiles when needed | No |
| 4. Use it | Reference by name in zeroclaw.toml | No |
The cleanest separation of concerns in the roster. No core patch, no provider-specific code in the kernel, no bloat. The same pattern applies to channels, tools, memory backends, and peripherals. This is why 25+ provider slots scale without the codebase collapsing.
The 6-layer safety cascade
LAYER 1
Channel pairing
allowed_users, allowed_chats, webhook IP allowlists. Enforced at the channel adapter BEFORE the runtime sees the event.
LAYER 2
Autonomy level
readonly / supervised / full. Tools risk-classified: low runs, medium asks operator, high blocks.
LAYER 3
Workspace boundary
workspace_only confines reads/writes. forbidden_paths blocks /etc, /sys, ~/.ssh.
LAYER 4
Shell command policy
allowed_commands strict allowlist. Pattern-matcher runs BEFORE the shell, not after.
LAYER 5
OS-level sandbox
Auto-detected: Landlock/Bubblewrap/Docker (Linux), Seatbelt (macOS), AppContainer (Windows).
LAYER 6
Tool receipts
HMAC-SHA256 over successful tool calls + results. Fed back to detect fabricated-tool-claim attacks.
Each layer is independently defeatable but the default ships all six on. This is Module 6's risk-tiering principle taken to its logical conclusion: not one gate, a cascade.
Where security runs in the loop
The placement is load-bearing. Security does NOT run as a pre-filter on input or a post-hoc audit. It runs BETWEEN the model emitting a tool call and the tool executing.
Channel.deliver_message
-> Provider.chat (stream)
-> model emits tool_call
-> Security.validate (6 LAYERS) <-- HERE
-> Tool.invoke <-- only if allowed
-> result back to Provider
-> reply to Channel
A block surfaces as ToolResult::Err the model can react to. NOT a silent failure. The model cannot bypass layer 4 (runs before exec) or layer 6 (receipts are computed by the harness, not the model).
Tool receipts vs the fabricated-tool-claim attack (Module 11)
The attack
The model claims "the file says X" or "the tool returned Y" — fabricating a tool result to justify a downstream action. Most harnesses have no in-context evidence to contradict this.
The defense
HMAC-SHA256 over every successful tool call + its result, fed back into the conversation. If the model claims a tool returned data but no receipt exists, the harness can flag the fabrication.
Honest limitation: receipts use ephemeral keys. They are an in-context integrity signal TODAY, not yet a chained/durable audit log. Treat them as a defense against fabrication, not a forensic record.
The thickness paradox — thin philosophy, medium implementation
Thin by philosophy
- Single binary
- No telemetry, no SaaS, no license server
- No hidden system prompts ("the model sees what you configure")
- Self-hostable, operator-owned
Medium-thick by implementation
- ~700-800k Rust LOC across 1,015 files
- ~26 MiB binary; config schema alone 1.3 MB
- 25+ provider slots, 30+ channel impls
- Hardware support: GPIO/I2C/SPI/USB
RFC #5574 (microkernel refactor) is closing the gap: shrinking zeroclaw-runtime so kernel = loop + policy, with everything else behind feature flags. Foundation reportedly builds with --no-default-features. Honest framing: thin by design, medium by implementation, in-flight refactor to re-thin.
Explicit-only memory — a security choice, not a missing feature
ZeroClaw: explicit-only
Prompt context, tool output, files, and logs are NOT durable memory by default. A turn becomes memory ONLY if the agent calls memory_store explicitly.
Security property: an indirect injection cannot silently persist itself.
Hermes (DD-08): free writes
Model-initiated free writes to memory. Enables compounding capability (self-evolving skills) but creates a larger poisoning surface.
The trade is capability vs. security. ZeroClaw trades compounding for a smaller poisoning surface. Both are defensible — the choice depends on whether the deployment values compounding or hardening more.
Score: 34/60 — wins on safety, loses on context
| Module | Score | Key decision |
| 6 Permission/Safety | 5 | 6-layer model — deepest in thin-harness category |
| 2 Tools | 4 | browser, HTTP, hardware probes; trait-extended |
| 5 Sandbox | 4 | auto-detected OS sandbox (Landlock/Seatbelt/AppContainer/Docker) |
| 12 Prompt | 4 | minimal-prompt philosophy; operator-owned |
| 3 Context | 2 | basic history trimming only; no context-budget system |
| 9 Verification | 2 | limited |
Highest on Module 6 (Permission/Safety): 5/5. The 6-layer safety model is the deepest in the thin-harness category. Loses on Module 3 (Context Management): 2/5 — no sophisticated context-budget system.
3 things it does better, 3 things to fix
Does better
- Trait-driven kernel — cleanest separation of concerns in the roster
- 6-layer safety — deepest safety surface in the thin-harness category
- Provider agnosticism — 25+ slots with routing, retry, key rotation, per-vendor OAuth
To fix
- Close the microkernel gap — ~700k LOC contradicts the thin philosophy; finish RFC #5574
- Durable audit log — tool receipts use ephemeral keys; make them chained and persistent
- Context management — basic history trimming is insufficient; add turn-boundary trimming + context-budget
What you can now do
- Explain ZeroClaw's trait-driven kernel (ADR-002) and why it is the cleanest separation of concerns in the roster.
- Recite the 6-layer safety model in order and explain how the layers compose as a cascade rather than a toggle.
- Analyze the thickness paradox: thin by philosophy, medium-thick by implementation, with RFC #5574 closing the gap.
- Evaluate the tool-receipt system as a defense against fabricated-tool-claim attacks, and name its limitation (ephemeral keys).
- Score ZeroClaw (34/60), explain the wins (Module 6: 5/5) and losses (Module 3: 2/5), and judge when to build on it.
The lab: build a minimal simulation of ZeroClaw's 6-layer safety cascade in Python — model each layer as a gate function, send a sequence of tool calls through the cascade, then implement the tool-receipt system and confirm it detects a fabricated claim.
Next: DD-17 — PicoClaw: The Go Thin Harness