Dreams
Cross-domain synthesis, consolidation scheduling, and quality gates for knowledge graph growth.
Dreams are ANIMA's mechanism for discovering connections between beliefs across different domains. During a dream pass, the engine samples beliefs, pairs them, sends the pairs to an LLM for synthesis, and triages the results through a quality gate before adding new beliefs and edges to the graph.
What Dreams Do
Each dream pass performs three conceptual steps:
- Sampling — selects a diverse set of beliefs from across domains, prioritizing under-connected regions and cross-domain bridge opportunities.
- Pairing — generates candidate belief pairs for synthesis, applying diversity constraints and cooldown rules to avoid redundant pairs.
- Triage — the synthesized result passes through a quality gate that decides whether to accept, reject, or queue the new belief for manual review.
Cross-domain connections. Dreams specifically target beliefs from different knowledge domains. This is what produces novel insights — connections that wouldn't emerge from within a single topic.
Running Dreams
Pair-wise Dreams
dream_stats = engine.run_dreams(queue_mode=True)
# queue_mode=True: auto-accept/reject based on triage rules
# queue_mode=False: interactive terminal approval
print(f"Selected {dream_stats['pairs_selected']} pairs")
print(f"Accepted: {dream_stats['accepted']}")
print(f"Bridges formed: {dream_stats['bridges_formed']}")
Return Value
| Field | Type | Description |
|---|---|---|
pairs_selected | int | Number of belief pairs evaluated |
accepted | int | New synthesis beliefs accepted into the graph |
rejected | int | Synthesis results that failed quality gate |
queued | int | Results sent to manual approval queue |
novel_edges | int | New edges created |
reinforcing_edges | int | Existing edges reinforced |
bridges_formed | int | Cross-domain bridge edges created |
Triplet Dreams
triplet_stats = engine.run_triplet_dreams()
print(f"Triplet accepted: {triplet_stats['accepted']}")
Full Consolidation
consolidation = engine.run_consolidation()
print(f"Total accepted: {consolidation['accepted']}")
Dream Candidate Selection Rust
The Rust core owns candidate sampling and pair selection. Python provides belief data, embeddings, and link queries. The core enforces diversity constraints and cooldown rules.
Sampling
beliefs = engine.search_beliefs(limit=200)
indices = engine.dream_sample_beliefs(beliefs, config={
"sample_size": 40,
})
Pair Generation
Cooldown Management
After a pair is rejected, it enters a cooldown period to avoid being re-evaluated too soon.
Dream Result Processing Rust
Quality Gates
Every dream result passes through the triage state machine before being accepted into the graph. The triage checks for:
- Duplicates — semantic similarity against existing beliefs
- Contradictions — conflicts with high-confidence existing beliefs
- Quality — statement quality validation (specificity, actionability)
- Classification — mechanism vs. narrative vs. template classification
- Constraints — hypothesis constraint checks for research plugins
See the Security page for details on the triage state machine.
Consolidation Scheduling
Dreams run during consolidation cycles. The scheduler supports multiple trigger modes:
| Mode | Description |
|---|---|
| Cycle-count | Run after every N processing cycles |
| Time-interval | Run on a fixed time schedule |
| Event-driven | Run when triggered by significant graph changes |
| Manual | Run only when explicitly requested |
Configuration
Dream parameters are set in your plugin's config/settings.toml:
[reflection]
dreams_enabled = true
dream_similarity_min = 0.4 # minimum similarity for pairing
dream_similarity_max = 0.75 # maximum similarity (too similar = redundant)
max_dream_pairs = 10 # pairs per dream pass
Sweet spot. The similarity window (min to max) controls the novelty of dream connections. Too narrow and dreams find only obvious links. Too wide and the LLM cannot form meaningful connections.