System architecture
chitta-field Rust memory substrate, 8-phase resonance, Bayesian self-tuning, and tree-sitter code intelligence — in a single C++ daemon.
Status as of 2026-09-20 Canonical architecture.
System Overview
Three layers: hooks, MCP server, and daemon. Claude Code hooks and the MCP server communicate with the chittad daemon over a Unix domain socket. Inside, chitta-field (a statically-linked Rust library) is the sole storage substrate — orchestrating memory, embedding, resonance, and decay.
// chitta-field: Rust memory store FieldStore WAL-backed in-memory field, sparse codes, cortical index Sparse 64 of 16,384 features active per memory — 0.4% sparsity Ownership One daemon holds the instance lock; sessions share it over RPC Socket Unix domain socket IPC between Claude Code and daemon Scaling Auto-scaling thread pool (8-16) with watchdog for slow requests
Core Components
Core components. Each handles one concern; chitta-field (Rust) is the storage substrate that the C++ daemon links against.
| Class | File | Role |
|---|---|---|
| FieldStore | chitta-field/src/field.rs | Central memory substrate: WAL, sparse codes, cortical index, decay |
| FieldRpcHandler | rpc/field_handler.hpp | JSON-RPC dispatch, budgets and lock discipline; see generated tools |
| Embedder | mind/embedder.hpp | Embedding with LRU cache and circuit breaker |
| LlamaYantra | vak_llama.hpp | In-process GGUF embedding through llama.cpp. The default backend |
| OllamaYantra | vak_ollama.hpp | HTTP embedding backend, used when no local GGUF is found |
| Subconscious | mind/subconscious.hpp | Background thread: patterns, hygiene, demotion, embedding |
| NativeDistiller | native_distiller.hpp | In-daemon transcript distillation using the configured model endpoint |
| CodeIntel | code_intel.hpp | Tree-sitter symbol extraction (9 languages) |
| QueueProcessor | queue_processor.hpp | Background embedding and maintenance queue |
| ThreadPool | rpc/thread_pool.hpp | Auto-scaling worker pool with watchdog |
| ProvenanceSpine | provenance.hpp | Knowledge source tracking and trust scoring |
The Resonance Engine
The core of memory retrieval. full_resonate() runs 8 phases to find relevant memories — not search, but resonance. Each phase adds signal; post-processing refines it. Backed by chitta-field's cortical posting index for sub-millisecond retrieval.
Semantic Seeds
Vector similarity search using HNSW4 index. Returns top-k memories by cosine distance to the query embedding — the initial gravity wells of meaning.
BM25 Hybrid
Keyword-based search using BM2524 scoring complements semantic search for exact term matches. Results merge using weighted combination with confidence factor.
Tag Matching
Boost memories whose tags match terms in the query. A small additive signal that rewards explicit categorization.
Attractor Finding
Identify conceptual gravity wells — clusters of densely connected memories in the triplet graph. Attractors are cached with 5-minute TTL.
Spreading Activation
Starting from seed memories, activation spreads through the triplet graph. Connected memories receive activation proportional to edge weight, inversely proportional to distance.
Session Priming
Recent observations and active topics from the current session boost related memories. The context of the conversation shapes what surfaces.
Code Intelligence
For code-like queries (detected by heuristic: ::, ->, _, ., or single identifiers), BM25 and term-based search on symbol names and signatures.
Post-Processing
Attractor boost, lateral inhibition (similar memories compete), Hebbian26 learning (co-accessed memories strengthen connections), and credit assignment for the Bayesian bandit.
struct ResonanceConfig { float spread_strength = 0.5f; float spread_decay = 0.5f; int max_hops = 3; float hebbian_strength = 0.03f; int max_attractors = 10; float basin_boost = 1.15f; float similarity_threshold = 0.85f; float inhibition_strength = 0.7f; float epsilon_boost_alpha = 0.3f; float semantic_weight = 0.6f; float activation_weight = 0.4f; float code_symbol_weight = 0.5f; };
ScoringPipeline v5.11+
Rust scoring combines similarity with bounded factors configured in scoring.json. The kind_operational prior is 0.8 for verbatim distiller fragments. Independent-session replication weighting defaults to 0 (off); CHITTA_REPLICATION_MAX overrides its cap. See current knobs and admission rules.
| Factor | Source | Description |
|---|---|---|
| Relevance | Cosine similarity | Base semantic match score |
| ACT-R1 | Access history | Anderson & Schooler (1991) power-law decay over access timestamps |
| Strength | Memory strength | Reinforcement from repeated access |
| Confidence | Bayesian posterior | Beta posterior mean over observation history |
| Surprise | FEP §2.3 | Reconstruction error as surprise signal |
| Arousal | Affect dimensions | Flashbulb memory effect: high-arousal memories boosted |
| MoodCongruence | Query affect | Bower20 (1981): valence/arousal alignment between query and memory |
| FrustrationEscalation | Query affect | Negative valence + high arousal boosts corrections/preferences |
| Status | Demotion tier | Tier-based weight (hot > warm > cool > cold) |
| Epistemic | Node type | Type-based multiplier (corrections, preferences weighted higher) |
| Kind | Node kind | Fine-grained kind multiplier |
| RealmReliability | Realm stats | Per-realm reliability based on historical feedback |
| InterferenceDensity | Competitor crowding | Price of Meaning: penalty for local competitor density |
| SpacingBoost | Access spacing | Geometry of Forgetting: well-spaced accesses boost recall |
| PredictionBoost | Markov chain | Layer 3: predicted-next-needed memories boosted |
| SurpriseDomain | Surprise Memory | Layer 4: “actual” outcomes boosted; wrong “expected” suppressed |
| EpistemicDebt | Epistemic Debt | Layer 5: memories in uncertain domains get 1.1× boost |
| IntegrationWeight | Integration Kernel | Layer 6: learned recall source weight as multiplier [0–2] |
final_score = Σ (factor_weight × factor_score + factor_bias)
Storage Layer
chitta-field is an embedded Rust store linked into the daemon. An exclusive instance lock protects each store. Snapshot families and uncovered WAL recover state; ordinary WAL syncs run on a 200 ms timer and explicit durable operations force persistence. Parallel decode and matching sidecars reduce measured warm startup to about 9.5 s, with about 20 s on a first start after deployment. See storage phases and recovery.
segments/ // WAL segment files ({instance_id}_{seqno}.seg)
manifest.json // Instance registry and seqno tracking
In-Memory Structures
| Structure | Fields | Purpose |
|---|---|---|
| MemoryEntry | id, kind, content, embedding, confidence, decay_rate, realm, timestamps, tier | Core unit of storage. Bayesian confidence and demotion-tier decay. |
| TripletEntry | id, subject, predicate, object, weight, valid_from_ms, invalidated_at_ms | Temporal knowledge graph. Predicates: calls, contains, imports, inherits, corrects, relates_to. |
| SymbolEntry | id, name, kind, signature, file_path, line_start, line_end, repo_id, embedding, description | Code intelligence: functions, classes, methods extracted by tree-sitter. |
| call_graph | HashMap<SymbolId, HashSet<SymbolId>> | Call graph edges, populated by callsite resolution via AddSymCallEdge ops. |
| SparseCode | memory_id, feature_ids[64], activations[64] | Sparse associative encoding. Cortical posting index maps feature → memory list. |
// Every Op is appended before applying in-memory // Entry format: [len:u32][seqno:u64][op_type:u8][msgpack_payload][crc32:u32] // Segment rotation at 256 MB; each instance owns its own segment files Durability: flush to OS after every append Recovery: replay all segments on open (fast — in-memory rebuild) Multi-writer: each daemon instance writes to {instance_id}_{seqno}.seg Integrity: CRC32 per entry; corrupt entries abort replay
Embedding Engine (Vāk)
The embedding pipeline follows a Vedantic naming convention. Each stage transforms speech into meaning, mirroring the philosophical concept of Vāk — the power of articulated consciousness.
| Class | Sanskrit Meaning | Role |
|---|---|---|
| VakPatha | Path of speech | WordPiece tokenizer (vocab.txt) |
| Shabda | Sound-form | Tokenized input (input_ids + attention_mask) |
| Artha | Meaning | Embedding vector + certainty. 1024 dimensions on a public build |
| LlamaYantra | Inner instrument | In-process llama.cpp inference over a GGUF model |
| SmritiYantra | Memory machine | Caching wrapper (LRU, 10000 entries) |
| ShantaYantra | Silent machine | Zero-vector fallback |
Dimensions: 1024 — compile-time, -DCHITTA_EMBED_DIM Format: GGUF, loaded in-process Max sequence: 128 tokens Pooling: Mean pooling with L2 normalization Runtime: llama.cpp (CHITTA_WITH_LLAMA_CPP) Fallback: HTTP endpoint via OllamaYantra when no GGUF is found Batch size: Up to 32 texts per inference call LRU cache: 1000 entries, tracks hit/miss rate
The model filename is derived from the compiled embedding identity, so the binary can never load a model from a different vector space than the store was built with. Changing the dimension means a fresh build directory and a re-embed.
Circuit Breaker
Opens after 3 consecutive failures, enters 60-second cooldown, then half-open state for testing recovery.
Theme System (xMemory)
Inspired by the xMemory paper, themes provide hierarchical organization of memories. Each memory is assigned to a theme based on semantic similarity, with sparsity penalizing oversized themes.
Two-Stage Retrieval
Stage 1: Theme Matching
Find diverse theme representatives matching the query. Ensures breadth across conceptual areas.
Stage 2: Adaptive Expansion
Expand within matching themes for depth. Background maintenance splits, merges, and reassigns as needed.
Code Intelligence
Tree-sitter parsing extracts structural information from source code: symbols, callsites, imports, and type hierarchy. Callsites are resolved against known symbols to build the call graph.
Supported Languages
Search Modes
| Mode | Tool | Method |
|---|---|---|
| Name search | find_symbol | Exact/prefix match on symbol name |
| Semantic search | search_symbols | Embedding similarity on symbol metadata |
| BM25 search | (internal) | Full-text keyword match on name + signature |
| Call graph | symbol_callers / symbol_callees | Traversal of call_edge table |
Symbols Functions, classes, methods, structs, enums name, kind, signature, file_path, line_range, parent Callsites Call, MemberCall, Qualified, New, Ctor, Indirect, LambdaCall Imports File dependencies Hierarchy Inheritance relationships
Memory Types & Lifecycle
26 node types, each with distinct decay characteristics and quality gates. Confidence is Bayesian, not a simple scalar — it tracks mean, variance, observation count, and decay.
Node Types
Decay Rates
| Type | Rate | Visual | Rationale |
|---|---|---|---|
| Belief | 0.0 |
Never decays (core identity) | |
| Symbol | 0.0 |
Code structure doesn't decay | |
| Wisdom | 0.005 |
Proven patterns should persist | |
| Correction | 0.005 |
Important lessons persist | |
| Preference | 0.01 |
Slowly fades if not reinforced | |
| Episode | 0.03 |
Fades unless reinforced |
Bayesian Confidence Model
struct Confidence { float mu; // Mean confidence float sigma_sq; // Variance (uncertainty) int n; // Number of observations float tau; // Decay parameter void observe(float value); // Update with new evidence void decay(float rate); // Time-based decay }; // strengthen() calls observe(positive) — increases mu, reduces sigma // weaken() calls observe(negative) — decreases mu // decay() gradually reduces confidence based on decay_rate
Quality Gate
1. Minimum length: Content must be >= 10 characters 2. Deduplication: Cosine similarity check (threshold: 0.95) 3. Diversity sampling: Avoids storing too many similar memories in quick succession
Self-Tuning (Bayesian Bandits)
The ResonanceLearner uses Thompson sampling69 to automatically optimize resonance parameters. Feedback updates the parameter posteriors used by later retrieval calls.
Thompson Sampling
Each tunable parameter has a Bayesian prior. BetaPrior for bounded parameters (0–1), GaussianPrior for unbounded. On each full_resonate() call, parameters are sampled from their current posteriors, balancing exploration and exploitation.
Credit Assignment
When a user strengthens or weakens a memory, the learner attributes credit to the parameters active when that memory was surfaced. QueryContext features — query length, term count, technical terms, domain prefix — inform the bandit. State persists across daemon restarts.
Semantic weight vs. BM25 weight // Balance vector vs keyword Spread strength and Spread decay // Graph activation dynamics Hebbian rate // Co-access learning speed Tag boost // Categorical signal magnitude // QueryContext features: query_length, term_count, has_technical_terms has_domain_prefix, avg_term_frequency
References
- John R. Anderson and Lael J. Schooler. Reflections of the Environment in Memory. Psychological Science 2(6), 396–408 (1991). https://doi.org/10.1111/j.1467-9280.1991.tb00174.x
- Yu. A. Malkov and D. A. Yashunin. Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs. IEEE TPAMI 42(4), 824–836 (2020); arXiv:1603.09320 (2016). https://arxiv.org/abs/1603.09320 https://doi.org/10.1109/TPAMI.2018.2889473
- Gordon H. Bower. Mood and memory. American Psychologist 36(2), 129–148 (1981). https://doi.org/10.1037/0003-066X.36.2.129
- Stephen Robertson and Hugo Zaragoza. The Probabilistic Relevance Framework: BM25 and Beyond. Foundations and Trends in Information Retrieval 3(4), 333–389 (2009). https://doi.org/10.1561/1500000019
- Donald O. Hebb. The Organization of Behavior: A Neuropsychological Theory. Wiley (1949); Psychology Press reissue (2002). https://www.routledge.com/The-Organization-of-Behavior-A-Neuropsychological-Theory/Hebb/p/book/9780415654531
- William R. Thompson. On the likelihood that one unknown probability exceeds another in view of the evidence of two samples. Biometrika 25(3–4), 285–294 (1933). https://doi.org/10.1093/biomet/25.3-4.285