Architecture
Maekon follows Hexagonal Architecture (Ports & Adapters). The core (maekon-core) defines all traits and domain models; every other crate is an adapter implementing those ports.
Workspace layout
clients/maekon-client/
├── src-tauri/ # Tauri v2 main binary (package: maekon-app)
└── crates/
├── maekon-core # 95 port traits + 34 domain models + error codes
├── maekon-network # JWT auth, HTTP/SSE, gRPC, batch upload
├── maekon-storage # SQLite (WAL) + 31 migration versions
├── maekon-monitor # System metrics, active window, idle detection
├── maekon-vision # Screen capture, delta encoding, OCR, PII filter
├── maekon-suggestion # SSE/gRPC reception, priority queue, feedback
├── maekon-automation # Policy-based command execution + audit
├── maekon-analysis # LLM segment summarization, vector RAG
├── maekon-embedding # INT8 quantization, similarity search
├── maekon-audio # cpal capture + Whisper STT
├── maekon-web # Local Axum dashboard + React frontend
├── maekon-api-contracts # Shared API types
├── maekon-sandbox-worker # Out-of-process action executor
└── maekon-lint # Workspace lint tool (standalone)
The dependency rule
maekon-core ← every adapter (one-way)
Adapters never depend on each other. All cross-crate communication goes through traits defined in maekon-core. This is the core invariant — see ADR-001 §1.
Key invariants
- All port traits use
&self(not&mut self); implementations needing mutable state use interior mutability (Mutex,RwLock,parking_lot) #[async_trait]on every port — required forArc<dyn Trait>DI- Manual mock implementations in
#[cfg(test)] mod tests— nomockall - Error strategy:
thiserrorin libraries,anyhowin the binary, all wrapped via#[from] - Error code field on every
CoreErrorvariant (ADR-019) — wire-format contract locked at 41 codes
Image processing pipeline
Screen frames go through a 4-tier importance branching (maekon-vision::EdgeFrameProcessor):
| Importance | Pipeline |
|---|---|
| ≥ 0.8 | Full + OCR |
| ≥ 0.5 | Delta encoding |
| ≥ 0.3 | Thumbnail |
| < 0.3 | Metadata only |
PII filter runs before any image leaves the device — phone, API key, IP, email, credit card, SSN, file path masking with a 4-level cascade (Off / Basic / Standard / Strict).
Further reading
The full ADR series lives at docs/architecture/ in the public repo:
- ADR-001 Rust Client Architecture Patterns
- ADR-002 OS GUI Interaction Boundary
- ADR-003 Directory Module Pattern
- ADR-004 Tauri v2 Migration
- ADR-019 Error Code Infrastructure