Skip to main content

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 for Arc<dyn Trait> DI
  • Manual mock implementations in #[cfg(test)] mod tests — no mockall
  • Error strategy: thiserror in libraries, anyhow in the binary, all wrapped via #[from]
  • Error code field on every CoreError variant (ADR-019) — wire-format contract locked at 41 codes

Image processing pipeline

Screen frames go through a 4-tier importance branching (maekon-vision::EdgeFrameProcessor):

ImportancePipeline
≥ 0.8Full + OCR
≥ 0.5Delta encoding
≥ 0.3Thumbnail
< 0.3Metadata 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

Next