1. One-page picture
EvoClaw is one binary plus an optional local HTTP daemon. It runs a self-evolving agent loop, scrubs secrets at the runtime boundary, and persists every byte of state under ~/.evoclaw/. This diagram shows every major module on the same canvas.
flowchart LR
classDef frontend fill:#2a1f4a,stroke:#a78bfa,color:#fff
classDef gateway fill:#1a2f4a,stroke:#5fb3ff,color:#fff
classDef loop fill:#0f3a44,stroke:#22d3ee,color:#fff
classDef cap fill:#0f3a2a,stroke:#34d399,color:#fff
classDef route fill:#3a2f0a,stroke:#facc15,color:#fff
classDef policy fill:#3a210a,stroke:#fb923c,color:#fff
classDef store fill:#3a1414,stroke:#f87171,color:#fff
classDef ext fill:#1a2f4a,stroke:#5fb3ff,color:#fff,stroke-dasharray:4 3
CLI[CLI evoclaw]:::frontend
REPL[Interactive REPL]:::frontend
GW[Local Gateway HTTP]:::gateway
LOOP[Agent Loop]:::loop
RED[Redactor Vault]:::policy
TOOL[Tool Registry]:::cap
SK[Skill Tree]:::cap
MEM[Memory L0..L5]:::cap
REF[Reflection + Distillation]:::cap
PROV[Provider Adapter]:::route
ACP[ACP Provider]:::route
MCP[MCP Tool Wrappers]:::route
POL[Permission Engine]:::policy
COST[Cost Engine]:::policy
AUD[JSONL Audit]:::policy
FS[(workspace + logs)]:::store
YAML[(skills/*.yaml)]:::store
VAULT[(secrets/vault.json)]:::store
AGENTS[(agents/*.toml)]:::store
MCPCFG[(mcp/*.toml)]:::store
MODEL((Model API)):::ext
EXTAGENT((External CLI)):::ext
EXTSRV((MCP Server)):::ext
CLI --> REPL
REPL --> RED
GW --> RED
RED --> LOOP
LOOP --> TOOL
LOOP --> SK
LOOP --> MEM
LOOP --> REF
TOOL --> PROV
TOOL --> MCP
LOOP --> ACP
PROV --> MODEL
ACP -.spawn stdio.-> EXTAGENT
MCP -.spawn stdio.-> EXTSRV
TOOL --> POL
PROV --> COST
LOOP --> AUD
TOOL --> AUD
POL --> AUD
REF --> SK
REF --> MEM
SK --> YAML
MEM --> FS
AUD --> FS
RED --> VAULT
ACP --> AGENTS
MCP --> MCPCFG
2. Layered view (horizontal lanes)
Each lane is one responsibility tier. Read from top to bottom. Inside each lane the boxes are siblings and lay out left-to-right — they don't depend on each other vertically. Cross-tier dependencies always flow downward.
L7 Frontends
evoclaw CLI
Interactive REPL
Web Channels
▼
L6 Gateway / Wizard
Local Gateway
Onboard Wizard
MCP Bootstrap
▼
L5 Agent Loop
ConversationRuntime
SummaryParser
Compression
Reflection · Distillation
▼
L4 Capabilities
Tool Registry
Skill Tree
Memory L0..L5
Session JSONL
▼
L3 Routing & Adapters
OpenAI-compat
Anthropic
Copilot OAuth
ACP Provider
MCP Wrappers
▼
L2 Policy / Cost / Redact
Permission Engine
Cost Engine
Vault + Redactor
Audit Bus
▼
L1 Persistence
JSONL
YAML
TOML
JSON
Filesystem
AcyclicEach lane fans out horizontally — no single-column towerReverse signalling only via Audit Bus events
3. Runtime: one task end-to-end (closed loop)
User input enters at the left, gets scrubbed by the redactor, runs the loop until the model stops calling tools, then closes with reflection + distillation + a JSONL End record. Every text field crossing the model boundary is scrubbed; the loop is provably closed by doctor closure.
flowchart LR
U[User input] --> RED1[Redactor scrub]
RED1 --> TASK[Append Task record]
TASK --> PLAN[Plan turn]
PLAN --> CACHE{Tool fingerprint cached?}
CACHE -- yes --> SKIP[Reuse short marker]
CACHE -- no --> FULL[Send full schema]
SKIP --> CALL[provider.stream]
FULL --> CALL
CALL --> ASSIST[Assistant text + tool calls]
ASSIST --> RED2[Redactor scrub]
RED2 --> TOOLS{Any tool calls?}
TOOLS -- yes --> EXEC[Run tools]
EXEC --> RED3[Redactor scrub result]
RED3 --> TURN[Append Turn record]
TURN --> PLAN
TOOLS -- no --> FINAL[Final text]
FINAL --> REF[Reflection round]
REF --> DIST[Distillation]
DIST --> SK[Skill upsert]
REF --> MEM[Memory L3 write]
REF --> END[Append End record]
END --> DOC[doctor closure audit]
4. Secret-redaction barrier
Two complementary defences. No raw key, password, or OAuth token ever leaves the machine via the model API.
flowchart LR
classDef vault fill:#3a1414,stroke:#f87171,color:#fff
classDef pat fill:#3a2f0a,stroke:#facc15,color:#fff
classDef pass fill:#0f3a2a,stroke:#34d399,color:#fff
IN[Inbound text] --> V{Vault hit?}
V -- yes --> SUB["dollar SECRET NAME placeholder"]:::vault
V -- no --> P{Pattern hit?}
P -- yes --> RED["REDACTED kind fp"]:::pat
P -- no --> THRU[unchanged]:::pass
SUB --> OUT[Model / JSONL / Memory]
RED --> OUT
THRU --> OUT
Patterns: sk-ant-*, sk-* (≥20 chars), ghp_/gho_/ghu_/ghs_/ghr_*, AKIA… (20 alnum), eyJ*.*.* JWT, plus any 32-char-plus string with Shannon entropy ≥ 4 bits/char. Fingerprint = first 8 hex chars of SHA-256.
5. Token economy (5 stacked tricks)
Each trick is unit-tested. Stack them and a long task lands at roughly one third of the naive spend.
flowchart LR
T1[Trick 1 schema fingerprint] --> G1[25 to 40 percent prompt]
T2[Trick 2 ephemeral cache] --> G2[60 to 70 percent effective]
T3[Trick 3 head plus tail truncation] --> G3[50 to 70 percent observation]
T4[Trick 4 summary working memory] --> G4[80 to 90 percent history]
T5[Trick 5 tag-level compression] --> G5[50 to 60 percent long task]
G1 --> SUM[long task spend at one third or less]
G2 --> SUM
G3 --> SUM
G4 --> SUM
G5 --> SUM
5.1 Per-turn budget (hard)
| Section | Cap (tokens) | Overflow handling |
| system prompt | 800 | split into reference, lazy file_read |
| tools schema (first send) | 2000 | tools ≤ 10, description ≤ 80 chars |
| tools schema (fingerprint reused) | 30 | single-line marker |
| history block | 1500 | summary + tag compression |
| user new + tool_results | 8000 | smart_format truncation |
| Total input | ≤ 12K | triggers budget feedback |
cache_hit_rate ≥ 60%compression_ratio ≥ 50%per-turn input ≤ 12K
6. ACP / MCP standard interop
Two open protocols, both JSON-RPC 2.0 over stdio. ACP delegates the loop to an upstream coding CLI; MCP brings third-party tools into the registry.
6.1 ACP — delegate the loop
flowchart LR
RT[ConversationRuntime] --> AP[AcpProvider]
AP -- spawn stdio --> CLI[claude or codex or cursor or gh copilot]
CLI -- session prompt --> AP
AP --> RT
6.2 MCP — bring your own tools
flowchart LR
REG[ToolRegistry] --> WRAP[McpToolWrapper]
WRAP -- tools call --> SRV[npx or uvx or custom MCP server]
SRV --> WRAP
WRAP --> REG
7. Deployment topology
MVP: local-only. Optional: local Gateway daemon. ACP / MCP children always live on the same machine.
flowchart TB
subgraph LM["Your laptop"]
direction LR
UI[CLI / REPL]
GD[evo-gateway daemon]
RT[ConversationRuntime]
BR[ACP child]
MS[MCP child]
DATA[(~/.evoclaw)]
UI --> RT
GD --> RT
RT -.spawn.-> BR
RT -.spawn.-> MS
RT --> DATA
end
EXT((Model API))
RT --> EXT
Vault, agents/*.toml, mcp/*.toml, logs/*.jsonl all live in ~/.evoclaw/ and never leave the machine.
8. Storage map (~/.evoclaw)
| Path | Format | Owner | Purpose |
config.toml | TOML | user | provider, model, budget, security |
logs/{task_id}.jsonl | JSONL | Session | append-only task log |
skills/*.yaml | YAML | Skill | learned skills |
skills/index.json | JSON | SkillTree | tree summary |
memory/{L0..L5}.jsonl | JSONL | Memory | layered memory |
cost.jsonl | JSONL | CostEngine | per-turn cost events |
secrets/<provider>.key | text | wizard | chmod 600 |
secrets/vault.json | JSON | Vault | chmod 600 — named secret store |
agents/*.toml | TOML | ACP catalog | external agent profiles |
mcp/*.toml | TOML | MCP catalog | MCP server profiles |