|
| 1 | +<!-- Sync Impact Report |
| 2 | + Version change: 0.0.0 → 1.0.0 |
| 3 | + Modified principles: N/A (initial ratification) |
| 4 | + Added sections: Core Principles (5), Security Model, Performance Standards, Development Workflow, Governance |
| 5 | + Removed sections: All template placeholders |
| 6 | + Templates requiring updates: |
| 7 | + - .specify/templates/plan-template.md ✅ (no changes needed, Constitution Check section is generic) |
| 8 | + - .specify/templates/spec-template.md ✅ (no changes needed, structure accommodates our principles) |
| 9 | + - .specify/templates/tasks-template.md ✅ (no changes needed, phase structure works) |
| 10 | + Follow-up TODOs: None |
| 11 | +--> |
| 12 | + |
| 13 | +# Exoclaw Constitution |
| 14 | + |
| 15 | +## Core Principles |
| 16 | + |
| 17 | +### I. Secure by Default |
| 18 | + |
| 19 | +Every external interaction — tools, channels, memory access, LLM calls — flows through a deny-by-default WASM capability boundary. Plugins cannot access the filesystem, network, host memory, or environment variables unless the host explicitly grants specific capabilities. |
| 20 | + |
| 21 | +- Untrusted code (skills, tools, channel adapters) MUST run in WASM sandbox |
| 22 | +- Capabilities MUST be granted per-plugin via config-driven allowlists (e.g., `http:api.telegram.org`) |
| 23 | +- The host manages all persistent connections (WebSocket, SSE, long-polling); plugins handle discrete events only |
| 24 | +- Token authentication MUST use constant-time comparison |
| 25 | +- No plugin can bypass host-level metering, budgets, or security enforcement |
| 26 | + |
| 27 | +### II. Cost-Aware by Architecture |
| 28 | + |
| 29 | +Token spend is controlled through architectural design, not bolted-on limits. The memory engine retrieves relevant context (graph traversal + vector similarity) instead of dumping entire conversation history. Token metering lives in the trusted host layer where plugins cannot circumvent it. |
| 30 | + |
| 31 | +- Context assembly MUST use selective retrieval (target 3-5K tokens per request, not 120K) |
| 32 | +- Token metering MUST be host-side, counting actual wire data to/from LLM APIs |
| 33 | +- Budgets MUST be configurable per-agent, per-session, per-day, per-month |
| 34 | +- No cron/heartbeat pattern that sends full context on a timer; scheduled tasks use specific, scoped prompts |
| 35 | +- LLM provider calls MUST be auditable (input tokens, output tokens, cost, timestamp logged) |
| 36 | + |
| 37 | +### III. Simple Configuration |
| 38 | + |
| 39 | +Configuration MUST be a single TOML file that a human can write from scratch in under 5 minutes for a basic setup. No config sprawl across multiple files, no wizard-only setup, no hidden state. |
| 40 | + |
| 41 | +- Single config file: `~/.exoclaw/config.toml` (or `EXOCLAW_CONFIG` env var) |
| 42 | +- Sane defaults: loopback bind, no auth required for local, default agent model |
| 43 | +- Zero-config local mode: `exoclaw gateway` MUST work with no config file for development |
| 44 | +- Every config option MUST have a sensible default; only API keys and channel tokens are mandatory |
| 45 | +- Config schema MUST be documented in `examples/config.toml` with comments |
| 46 | + |
| 47 | +### IV. WASM-First Plugin Model |
| 48 | + |
| 49 | +All extensibility — channel adapters, tools, skills — ships as WASM modules (.wasm files). Plugins are language-agnostic (Rust, Go, JS, Python via Component Model), sandboxed by specification, and distributed as single files. |
| 50 | + |
| 51 | +- Plugins MUST target `wasm32-unknown-unknown` or `wasm32-wasip2` |
| 52 | +- Plugin host is Extism (on Wasmtime); migration to raw Wasmtime Component Model when Extism adds support |
| 53 | +- Per-invocation plugin isolation: fresh WASM instance per call, no shared state between invocations |
| 54 | +- Host functions expose controlled APIs to plugins (session storage, HTTP proxy, etc.) |
| 55 | +- Plugin interfaces defined in the host; plugins implement `handle_message`, `handle_tool_call`, `describe` |
| 56 | + |
| 57 | +### V. Performance Without Compromise |
| 58 | + |
| 59 | +Exoclaw MUST be fast enough that users never wait on the runtime — only on LLM response time. Single static binary, sub-millisecond plugin instantiation, microsecond routing decisions, zero-copy where possible. |
| 60 | + |
| 61 | +- Gateway MUST handle 10K+ concurrent WebSocket connections on commodity hardware |
| 62 | +- Plugin instantiation MUST complete in under 1ms (WASM cold start) |
| 63 | +- Session routing MUST complete in under 100 microseconds |
| 64 | +- Release binary MUST be a single static binary under 25MB (LTO + strip) |
| 65 | +- Memory usage MUST stay under 100MB for 1000 active sessions (excluding WASM instance memory) |
| 66 | +- Startup to first request MUST complete in under 500ms |
| 67 | + |
| 68 | +## Security Model |
| 69 | + |
| 70 | +**Trust boundary**: The WASM membrane separates trusted host code (Rust) from untrusted plugin code (WASM). |
| 71 | + |
| 72 | +| Layer | Trust | Examples | |
| 73 | +|-------|-------|----------| |
| 74 | +| Host runtime | Trusted | Gateway, router, agent loop, memory engine, capability system | |
| 75 | +| WASM plugins | Untrusted | Channel adapters, tools, skills, community extensions | |
| 76 | +| LLM providers | External | Anthropic, OpenAI — host manages connections, plugins never see API keys | |
| 77 | +| User data | Protected | Conversation history, memory graph, config — host-only access | |
| 78 | + |
| 79 | +Plugins interact with protected resources ONLY through host functions registered at instantiation. A plugin requesting a host function that wasn't granted fails at instantiation, not at runtime. |
| 80 | + |
| 81 | +## Performance Standards |
| 82 | + |
| 83 | +| Metric | Target | Measurement | |
| 84 | +|--------|--------|-------------| |
| 85 | +| Concurrent connections | 10,000+ | `wrk` or `k6` benchmark | |
| 86 | +| Plugin cold start | < 1ms | `tracing` span timing | |
| 87 | +| Route resolution | < 100us | `criterion` benchmark | |
| 88 | +| Memory per 1K sessions | < 100MB | `heaptrack` or RSS measurement | |
| 89 | +| Binary size (release) | < 25MB | `ls -la target/release/exoclaw` | |
| 90 | +| Startup to ready | < 500ms | Time from exec to first accepted connection | |
| 91 | +| Context tokens per request | 3-5K typical | Token counter in agent loop | |
| 92 | + |
| 93 | +## Development Workflow |
| 94 | + |
| 95 | +- `cargo check` for fast feedback during development |
| 96 | +- `cargo clippy` MUST pass with zero warnings (dead-code warnings excepted during scaffold phase) |
| 97 | +- `cargo fmt --check` MUST pass — canonical rustfmt style, zero config |
| 98 | +- `cargo test` MUST pass before any commit to main |
| 99 | +- All new public APIs MUST have at least one unit test |
| 100 | +- Integration tests for the WebSocket protocol use `tokio-test` |
| 101 | +- WASM plugins are tested by building to `wasm32-unknown-unknown` and calling via `PluginHost` in tests |
| 102 | +- Rust edition 2024 for all crates (main + plugins) |
| 103 | + |
| 104 | +## Governance |
| 105 | + |
| 106 | +This constitution governs all development decisions for exoclaw. Amendments require: |
| 107 | + |
| 108 | +1. A written rationale explaining what changed and why |
| 109 | +2. Version bump following semver (MAJOR: principle removal/redefinition, MINOR: new principle/expansion, PATCH: clarification) |
| 110 | +3. Update to this file with the Sync Impact Report comment at top |
| 111 | +4. Propagation check across `.specify/templates/` for consistency |
| 112 | + |
| 113 | +The constitution supersedes informal practices. If a development decision contradicts a principle, either change the code or amend the constitution — never leave them in conflict. |
| 114 | + |
| 115 | +**Version**: 1.0.0 | **Ratified**: 2026-02-08 | **Last Amended**: 2026-02-08 |
0 commit comments