corvus 0.3.1

Zero overhead. Zero compromise. 100% Rust. The fastest, smallest AI assistant.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
# Corvus ๐Ÿฆโ€โฌ›

Fast, small, and fully autonomous AI assistant infrastructure โ€” deploy anywhere, swap anything.

> [!IMPORTANT]
>
> ~3.4MB binary ยท <10ms startup ยท 1,017 tests ยท 22+ providers ยท 8 traits ยท Pluggable everything

### โœจ Features

- ๐ŸŽ๏ธ **Ultra-Lightweight:** <5MB Memory footprint โ€” 99% smaller than OpenClaw core.
- ๐Ÿ’ฐ **Minimal Cost:** Efficient enough to run on $10 Hardware โ€” 98% cheaper than a Mac mini.
- โšก **Lightning Fast:** 400X Faster startup time, boot in <10ms (under 1s even on 0.6GHz cores).
- ๐ŸŒ **True Portability:** Single self-contained binary across ARM, x86, and RISC-V.

### Why teams pick Corvus

- **Lean by default:** small Rust binary, fast startup, low memory footprint.
- **Secure by design:** pairing, strict sandboxing, explicit allowlists, workspace scoping.
- **Fully swappable:** core systems are traits (providers, channels, tools, memory, tunnels).
- **No lock-in:** OpenAI-compatible provider support + pluggable custom endpoints.

## Benchmark Snapshot (Corvus vs OpenClaw)

Local machine quick benchmark (macOS arm64, Feb 2026) normalized for 0.8GHz edge hardware.

|                           | OpenClaw      | NanoBot        | PicoClaw        | Corvus ๐Ÿฆ€            |
|---------------------------|---------------|----------------|-----------------|----------------------|
| **Language**              | TypeScript    | Python         | Go              | **Rust**             |
| **RAM**                   | > 1GB         | > 100MB        | < 10MB          | **< 5ร’MB**           |
| **Startup (0.8GHz core)** | > 500s        | > 30s          | < 1s            | **< 10ms**           |
| **Binary Size**           | ~28MB (dist)  | N/A (Scripts)  | ~8MB            | **3.4 MB**           |
| **Cost**                  | Mac Mini $599 | Linux SBC ~$50 | Linux Board $10 | **Any hardware $10** |

> Notes: Corvus results measured with `/usr/bin/time -l` on release builds. OpenClaw requires
> Node.js runtime (~390MB overhead). PicoClaw and Corvus are static binaries.

Reproduce Corvus numbers locally:

```bash
cargo build --release
ls -lh target/release/corvus

/usr/bin/time -l target/release/corvus --help
/usr/bin/time -l target/release/corvus status
```

## Quick Start

Use Corvus without compiling Rust locally:

```bash
npx @dallay/corvus --help
pnpm dlx @dallay/corvus status
yarn dlx @dallay/corvus agent -m "Hello, Corvus!"
bunx @dallay/corvus doctor
```

Or install globally via your package manager:

```bash
npm i -g @dallay/corvus
pnpm add -g @dallay/corvus
yarn global add @dallay/corvus
bun add -g @dallay/corvus
```

### Docker Compose (local-first dashboard)

```bash
# From clients/agent-runtime
cp docker-compose.yml docker-compose.local.yml

# Edit API_KEY (and optional provider/model) in your local compose/env

# Gateway only
docker compose -f docker-compose.local.yml up -d

# Gateway + dashboard
docker compose -f docker-compose.local.yml --profile dashboard up -d
```

Open:

- Gateway: `http://localhost:3000`
- Dashboard: `http://localhost:4324`

Then pair in dashboard via `/pair` and use the returned bearer token for admin config actions.

Build from source (Rust toolchain):

```bash
git clone https://github.com/dallay/corvus.git
cd corvus
cargo build --release
cargo install --path . --force

# Enable SurrealDB memory backend support
cargo build --release --features memory-surreal

# Quick setup (no prompts)
corvus onboard --api-key sk-... --provider openrouter

# Or interactive wizard
corvus onboard --interactive

# Or quickly repair channels/allowlists only
corvus onboard --channels-only

# Chat
corvus agent -m "Hello, Corvus!"

# Interactive mode
corvus agent

# Start the gateway (webhook server)
corvus gateway                # default: 127.0.0.1:8080
corvus gateway --port 0       # random port (security hardened)

# Start full autonomous runtime
corvus daemon

# Check status
corvus status

# Run system diagnostics
corvus doctor

# Check channel health
corvus channel doctor

# Get integration setup details
corvus integrations info Telegram

# Manage background service
corvus service install
corvus service install --linger on   # Linux: keep running after logout/reboot (user service + linger)
corvus service restart               # useful after binary updates
corvus service status

# Migrate memory from OpenClaw (safe preview first)
corvus migrate openclaw --dry-run
corvus migrate openclaw
```

Corvus also checks for newer releases in `agent`, `daemon`, and `status` commands.
Set `CORVUS_DISABLE_UPDATE_CHECK=1` to disable update notifications.

> **Dev fallback (no global install):** prefix commands with `cargo run --release --` (example:
`cargo run --release -- status`).

## Architecture

Every subsystem is a **trait** โ€” swap implementations with a config change, zero code changes.

<p align="center">
  <img src="../../assets/architecture.svg" alt="Corvus Architecture" width="900" />
</p>

| Subsystem         | Trait            | Ships with                                                                                                                                          | Extend                                                    |
|-------------------|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------|
| **AI Models**     | `Provider`       | 22+ providers (OpenRouter, Anthropic, OpenAI, Ollama, Venice, Groq, Mistral, xAI, DeepSeek, Together, Fireworks, Perplexity, Cohere, Bedrock, etc.) | `custom:https://your-api.com` โ€” any OpenAI-compatible API |
| **Channels**      | `Channel`        | CLI, Telegram, Discord, Slack, iMessage, Matrix, WhatsApp, Webhook                                                                                  | Any messaging API                                         |
| **Memory**        | `Memory`         | SQLite (hybrid search), SurrealDB (feature: `memory-surreal`), Markdown                                                                              | Any persistence backend                                   |
| **Tools**         | `Tool`           | shell, file_read, file_write, memory_store, memory_recall, memory_forget, browser_open (Brave + allowlist), composio (optional)                     | Any capability                                            |
| **Observability** | `Observer`       | Noop, Log, Multi                                                                                                                                    | Prometheus, OTel                                          |
| **Runtime**       | `RuntimeAdapter` | Native, Docker (sandboxed)                                                                                                                          | WASM (planned; unsupported kinds fail fast)               |
| **Security**      | `SecurityPolicy` | Gateway pairing, sandbox, allowlists, rate limits, filesystem scoping, encrypted secrets                                                            | โ€”                                                         |
| **Identity**      | `IdentityConfig` | OpenClaw (markdown), AIEOS v1.1 (JSON)                                                                                                              | Any identity format                                       |
| **Tunnel**        | `Tunnel`         | None, Cloudflare, Tailscale, ngrok, Custom                                                                                                          | Any tunnel binary                                         |
| **Heartbeat**     | Engine           | HEARTBEAT.md periodic tasks                                                                                                                         | โ€”                                                         |
| **Skills**        | Loader           | TOML manifests + SKILL.md instructions                                                                                                              | Community skill packs                                     |
| **Integrations**  | Registry         | 50+ integrations across 9 categories                                                                                                                | Plugin system                                             |

### Runtime support (current)

- โœ… Supported today: `runtime.kind = "native"` or `runtime.kind = "docker"`
- ๐Ÿšง Planned, not implemented yet: WASM / edge runtimes

When an unsupported `runtime.kind` is configured, Corvus now exits with a clear error instead of
silently falling back to native.

### Memory System (Full-Stack Search Engine)

All custom, zero external dependencies โ€” no Pinecone, no Elasticsearch, no LangChain:

| Layer              | Implementation                                                |
|--------------------|---------------------------------------------------------------|
| **Vector DB**      | Embeddings stored as BLOB in SQLite, cosine similarity search |
| **Keyword Search** | FTS5 virtual tables with BM25 scoring                         |
| **Hybrid Merge**   | Custom weighted merge function (`vector.rs`)                  |
| **Embeddings**     | `EmbeddingProvider` trait โ€” OpenAI, custom URL, or noop       |
| **Chunking**       | Line-based markdown chunker with heading preservation         |
| **Caching**        | SQLite `embedding_cache` table with LRU eviction              |
| **Safe Reindex**   | Rebuild FTS5 + re-embed missing vectors atomically            |

The agent automatically recalls, saves, and manages memory via tools.

```toml
[memory]
backend = "sqlite"          # "sqlite", "lucid", "surreal", "markdown", "none"
auto_save = true
embedding_provider = "openai"
vector_weight = 0.7
keyword_weight = 0.3

[memory.surreal]
url = "http://127.0.0.1:8000"
namespace = "corvus"
database = "memory"
allow_http_loopback = true
```

## Security

Corvus enforces security at **every layer** โ€” not just the sandbox. It passes all items from the
community security checklist.

### Security Checklist

| # | Item                             | Status | How                                                                                                                                                                                                                      |
|---|----------------------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 | **Gateway not publicly exposed** | โœ…      | Binds `127.0.0.1` by default. Refuses `0.0.0.0` without tunnel or explicit `allow_public_bind = true`.                                                                                                                   |
| 2 | **Pairing required**             | โœ…      | 6-digit one-time code on startup. Exchange via `POST /pair` for bearer token. All `/webhook` requests require `Authorization: Bearer <token>`.                                                                           |
| 3 | **Filesystem scoped (no /)**     | โœ…      | `workspace_only = true` by default. 14 system dirs + 4 sensitive dotfiles blocked. Null byte injection blocked. Symlink escape detection via canonicalization + resolved-path workspace checks in file read/write tools. |
| 4 | **Access via tunnel only**       | โœ…      | Gateway refuses public bind without active tunnel. Supports Tailscale, Cloudflare, ngrok, or any custom tunnel.                                                                                                          |

> **Run your own nmap:** `nmap -p 1-65535 <your-host>` โ€” Corvus binds to localhost only, so nothing
> is exposed unless you explicitly configure a tunnel.

### Channel allowlists (Telegram / Discord / Slack)

Inbound sender policy is now consistent:

- Empty allowlist = **deny all inbound messages**
- `"*"` = **allow all** (explicit opt-in)
- Otherwise = exact-match allowlist

This keeps accidental exposure low by default.

Recommended low-friction setup (secure + fast):

- **Telegram:** allowlist your own `@username` (without `@`) and/or your numeric Telegram user ID.
- **Discord:** allowlist your own Discord user ID.
- **Slack:** allowlist your own Slack member ID (usually starts with `U`).
- Use `"*"` only for temporary open testing.

If you're not sure which identity to use:

1. Start channels and send one message to your bot.
2. Read the warning log to see the exact sender identity.
3. Add that value to the allowlist and rerun channels-only setup.

If you hit authorization warnings in logs (for example: `ignoring message from unauthorized user`),
rerun channel setup only:

```bash
corvus onboard --channels-only
```

### WhatsApp Business Cloud API Setup

WhatsApp uses Meta's Cloud API with webhooks (push-based, not polling):

1. **Create a Meta Business App:**
  - Open the WhatsApp Business Platform page from Meta and create an app
  - Create a new app โ†’ Select "Business" type
  - Add the "WhatsApp" product

2. **Get your credentials:**
  - **Access Token:** From WhatsApp โ†’ API Setup โ†’ Generate token (or create a System User for
    permanent tokens)
  - **Phone Number ID:** From WhatsApp โ†’ API Setup โ†’ Phone number ID
  - **Verify Token:** You define this (any random string) โ€” Meta will send it back during webhook
    verification

3. **Configure Corvus:**
   ```toml
   [channels_config.whatsapp]
   access_token = "EAABx..."
   phone_number_id = "123456789012345"
   verify_token = "my-secret-verify-token"
   allowed_numbers = ["+1234567890"]  # E.164 format, or ["*"] for all
   ```

4. **Start the gateway with a tunnel:**
   ```bash
   corvus gateway --port 8080
   ```
   WhatsApp requires HTTPS, so use a tunnel (ngrok, Cloudflare, Tailscale Funnel).

5. **Configure Meta webhook:**
  - In Meta Developer Console โ†’ WhatsApp โ†’ Configuration โ†’ Webhook
  - **Callback URL:** `https://your-tunnel-url/whatsapp`
  - **Verify Token:** Same as your `verify_token` in config
  - Subscribe to `messages` field

6. **Test:** Send a message to your WhatsApp Business number โ€” Corvus will respond via the LLM.

## Configuration

Config: `~/.corvus/config.toml` (created by `onboard`; wizard now includes SurrealDB prompts when
available)

```toml
api_key = "sk-..."
default_provider = "openrouter"
default_model = "anthropic/claude-sonnet-4-20250514"
default_temperature = 0.7

[memory]
backend = "sqlite"              # "sqlite", "lucid", "surreal", "markdown", "none"
auto_save = true
embedding_provider = "openai"   # "openai", "noop"
vector_weight = 0.7
keyword_weight = 0.3

[memory.surreal]
url = "http://127.0.0.1:8000"
namespace = "corvus"
database = "memory"
# username = "corvus"
# password = "corvus-pass"
# token = "..."                  # preferred over username/password when set
allow_http_loopback = true

[gateway]
require_pairing = true          # require pairing code on first connect
allow_public_bind = false       # refuse 0.0.0.0 without tunnel

[autonomy]
level = "supervised"            # "readonly", "supervised", "full" (default: supervised)
workspace_only = true           # default: true โ€” scoped to workspace
allowed_commands = ["git", "npm", "cargo", "ls", "cat", "grep"]
forbidden_paths = ["/etc", "/root", "/proc", "/sys", "~/.ssh", "~/.gnupg", "~/.aws"]

[runtime]
kind = "native"                # "native" or "docker"

[runtime.docker]
image = "alpine:3.20"          # container image for shell execution
network = "none"               # docker network mode ("none", "bridge", etc.)
memory_limit_mb = 512          # optional memory limit in MB
cpu_limit = 1.0                # optional CPU limit
read_only_rootfs = true        # mount root filesystem as read-only
mount_workspace = true         # mount workspace into /workspace
allowed_workspace_roots = []   # optional allowlist for workspace mount validation

[heartbeat]
enabled = false
interval_minutes = 30

[tunnel]
provider = "none"               # "none", "cloudflare", "tailscale", "ngrok", "custom"

[secrets]
encrypt = true                  # API keys encrypted with local key file

[browser]
enabled = false                 # opt-in browser_open tool
allowed_domains = ["docs.rs"]  # required when browser is enabled

[composio]
enabled = false                 # opt-in: 1000+ OAuth apps via composio.dev

[identity]
format = "openclaw"             # "openclaw" (default, markdown files) or "aieos" (JSON)
# aieos_path = "identity.json"  # path to AIEOS JSON file (relative to workspace or absolute)
# aieos_inline = '{"identity":{"names":{"first":"Nova"}}}'  # inline AIEOS JSON
```

SurrealDB environment overrides (env-first):

```bash
export CORVUS_MEMORY_BACKEND=surreal
export CORVUS_SURREALDB_URL=http://127.0.0.1:8000
export CORVUS_SURREALDB_NAMESPACE=corvus
export CORVUS_SURREALDB_DATABASE=memory
export CORVUS_SURREALDB_USERNAME=corvus
export CORVUS_SURREALDB_PASSWORD=your-password-here
# optional:
export CORVUS_SURREALDB_TOKEN=...
```

## Identity System (AIEOS Support)

Corvus supports **identity-agnostic** AI personas through two formats:

### OpenClaw (Default)

Traditional markdown files in your workspace:

- `IDENTITY.md` โ€” Who the agent is
- `SOUL.md` โ€” Core personality and values
- `USER.md` โ€” Who the agent is helping
- `AGENTS.md` โ€” Behavior guidelines

### AIEOS (AI Entity Object Specification)

AIEOS is a standardization framework for portable AI identity. Corvus supports
AIEOS v1.1 JSON payloads, allowing you to:

- **Import identities** from the AIEOS ecosystem
- **Export identities** to other AIEOS-compatible systems
- **Maintain behavioral integrity** across different AI models

#### Enable AIEOS

```toml
[identity]
format = "aieos"
aieos_path = "identity.json"  # relative to workspace or absolute path
```

Or inline JSON:

```toml
[identity]
format = "aieos"
aieos_inline = '''
{
  "identity": {
    "names": { "first": "Nova", "nickname": "N" }
  },
  "psychology": {
    "neural_matrix": { "creativity": 0.9, "logic": 0.8 },
    "traits": { "mbti": "ENTP" },
    "moral_compass": { "alignment": "Chaotic Good" }
  },
  "linguistics": {
    "text_style": { "formality_level": 0.2, "slang_usage": true }
  },
  "motivations": {
    "core_drive": "Push boundaries and explore possibilities"
  }
}
'''
```

#### AIEOS Schema Sections

| Section        | Description                                                   |
|----------------|---------------------------------------------------------------|
| `identity`     | Names, bio, origin, residence                                 |
| `psychology`   | Neural matrix (cognitive weights), MBTI, OCEAN, moral compass |
| `linguistics`  | Text style, formality, catchphrases, forbidden words          |
| `motivations`  | Core drive, short/long-term goals, fears                      |
| `capabilities` | Skills and tools the agent can access                         |
| `physicality`  | Visual descriptors for image generation                       |
| `history`      | Origin story, education, occupation                           |
| `interests`    | Hobbies, favorites, lifestyle                                 |

See the AIEOS specification for the full schema and examples.

## Gateway API

| Endpoint    | Method | Auth                            | Description                                                           |
|-------------|--------|---------------------------------|-----------------------------------------------------------------------|
| `/health`   | GET    | None                            | Health check (always public, no secrets leaked)                       |
| `/pair`     | POST   | `X-Pairing-Code` header         | Exchange one-time code for bearer token                               |
| `/webhook`  | POST   | `Authorization: Bearer <token>` | Send message: `{"message": "your prompt"}`                            |
| `/whatsapp` | GET    | Query params                    | Meta webhook verification (hub.mode, hub.verify_token, hub.challenge) |
| `/whatsapp` | POST   | None (Meta signature)           | WhatsApp incoming message webhook                                     |

## Commands

| Command                                       | Description                                             |
|-----------------------------------------------|---------------------------------------------------------|
| `onboard`                                     | Quick setup (default)                                   |
| `onboard --interactive`                       | Full interactive 7-step wizard (includes memory backend + Surreal options) |
| `onboard --channels-only`                     | Reconfigure channels/allowlists only (fast repair flow) |
| `agent -m "..."`                              | Single message mode                                     |
| `agent`                                       | Interactive chat mode                                   |
| `gateway`                                     | Start webhook server (default: `127.0.0.1:8080`)        |
| `gateway --port 0`                            | Random port mode                                        |
| `daemon`                                      | Start long-running autonomous runtime                   |
| `service install/start/restart/stop/status/uninstall` | Manage background service lifecycle                 |
| `doctor`                                      | Diagnose daemon/scheduler/channel freshness             |
| `status`                                      | Show full system status                                 |
| `channel doctor`                              | Run health checks for configured channels               |
| `integrations info <name>`                    | Show setup/status details for one integration           |

## Development

```bash
cargo build              # Dev build
cargo build --release    # Release build (~3.4MB)
cargo test               # 1,017 tests
cargo clippy             # Lint (0 warnings)
cargo fmt                # Format

# Run the SQLite vs Markdown benchmark
cargo test --test memory_comparison -- --nocapture
```

### Pre-push hook

A git hook runs `cargo fmt --check`, `cargo clippy -- -D warnings`, and `cargo test` before every
push.

To skip the hook when you need a quick push during development:

```bash
git push --no-verify
```