# Data Architecture ## State Model The single source of truth is `AppStateRest` (`src/app/state/rest.rs`): ``` AppStateRest ├── session: SessionRuntime (hive_mind state, convergence flag) ├── runtime: RuntimeState (mode, provider status) ├── chat: ChatState (messages, scroll) ├── input: InputState (text, cursor, autocomplete) ├── settings: Settings (provider, model, temperature, concise_output) ├── config: AppConfig (endpoints, credentials) ├── scroll: ScrollState (per-panel offset) ├── diff: DiffState (edit review) ├── tools: Vec with outputs ├── statusline, sidebar, etc. └── toasts: pending notifications ``` **Mutation rules** (per CLAUDE.md): - Mutated in-place from exactly two locations: `actions/mod.rs` (apply_action) and `controller/input.rs` (key handlers) - Read-only from every other module - No generic update function — direct field mutation only ## Persistence ### SQLite Message Log (`src/model/msglog/`) | File | Purpose | |------|---------| | `schema.rs` | Table definitions (messages, sessions) | | `mod.rs` | CRUD operations | | `query.rs` | Query helpers (search, filter) | | `blobs.rs` | Large message blob storage | | `summary.rs` | Conversation summary cache | Schema uses `rusqlite` (bundled) with per-session isolation — each session gets its own database. ### Memory System (`src/model/memory.rs`) File-based memory stored under `~/.claude/projects//memory/`: - Each memory is one markdown file with frontmatter (name, description, type) - Types: `user`, `feedback`, `project`, `reference` - Memory index in MEMORY.md - Export/import for lesson sharing - PID-file session lock prevents concurrent access ### Settings & Config (`src/model/`) | File | Purpose | |------|---------| | `settings.rs` | Serialized user preferences (provider, model, theme) | | `app_config.rs` | Provider endpoints, API key resolution from env | | `session.rs` | Current session metadata | | `conversation.rs` | In-memory conversation state | | `editlog.rs` | Append-only JSONL edit audit trail | ### Edit Log `src/model/editlog.rs` records every file mutation: ```json {"ts": 123, "tool": "edit", "path": "src/main.rs", "reason": "fix bug", "content_sha256": "abc123", "bytes_delta": 15, "origin": "chat", "session_id": "sess-1"} ``` Max 5000 entries held in memory before pruning oldest. ## Context Management (`src/app/runtime/context/`) | Module | Purpose | |--------|---------| | `tokens.rs` | Token counting via `tiktoken-rs` | | `window.rs` | Token window resolution (fit within model context) | | `dedup.rs` | Deduplication of repeated tool outputs | | `squash.rs` | Compression of large JSON tool results | | `shaping.rs` | Message dropping when context exceeds limits | ## IPC Data Flow ``` Daemon State ──diff──▶ serialize ──frame──▶ socket ──▶ Client │ Client State ◀── apply_diff ◀── deserialize ◀──── socket ─┘ ```