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:

  1. Sampling — selects a diverse set of beliefs from across domains, prioritizing under-connected regions and cross-domain bridge opportunities.
  2. Pairing — generates candidate belief pairs for synthesis, applying diversity constraints and cooldown rules to avoid redundant pairs.
  3. 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

engine.run_dreams(queue_mode=True) → dict
Runs one dream pass: samples beliefs, generates pairs, dispatches to LLM, triages results.
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

FieldTypeDescription
pairs_selectedintNumber of belief pairs evaluated
acceptedintNew synthesis beliefs accepted into the graph
rejectedintSynthesis results that failed quality gate
queuedintResults sent to manual approval queue
novel_edgesintNew edges created
reinforcing_edgesintExisting edges reinforced
bridges_formedintCross-domain bridge edges created

Triplet Dreams

engine.run_triplet_dreams() → dict
Runs triplet dream synthesis (A+B+C) for higher-order connections. Returns the same stats dict format as pair-wise dreams.
triplet_stats = engine.run_triplet_dreams()
print(f"Triplet accepted: {triplet_stats['accepted']}")

Full Consolidation

engine.run_consolidation() → dict
Full sleep consolidation: dreams + triplets + reflection. Returns combined stats.
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

engine.dream_sample_beliefs(beliefs, config, seed?) → list[int]
Domain-stratified sampling with bridge priority. Returns indices into the belief list.
beliefs = engine.search_beliefs(limit=200)
indices = engine.dream_sample_beliefs(beliefs, config={
    "sample_size": 40,
})

Pair Generation

engine.dream_generate_pairs(beliefs, indices, sims, config, context) → list[dict]
Scores and selects candidate pairs with diversity constraints. Returns pairs selected for synthesis.

Cooldown Management

After a pair is rejected, it enters a cooldown period to avoid being re-evaluated too soon.

engine.dream_tick_cooldowns() → None
Tick down all pair cooldowns. Call once per consolidation cycle.
engine.dream_add_pair_cooldown(a_id, b_id, duration?) → None
Add a cooldown after a pair is rejected.
engine.dream_record_domain_pairs(pairs) → None
Record domain-pair usage for diversity tracking across dream cycles.

Dream Result Processing Rust

engine.score_dream_pair(belief_a, belief_b, sim, rc, ctx) → float
Scores a candidate belief pair for dream synthesis potential. Returns a composite score.
engine.process_dream_result(dream_data) → dict
Processes a completed dream synthesis: creates the synthesis belief and up to 3 edges (parent A → synthesis, parent B → synthesis, and optionally a bridge edge).

Quality Gates

Every dream result passes through the triage state machine before being accepted into the graph. The triage checks for:

See the Security page for details on the triage state machine.

Consolidation Scheduling

Dreams run during consolidation cycles. The scheduler supports multiple trigger modes:

ModeDescription
Cycle-countRun after every N processing cycles
Time-intervalRun on a fixed time schedule
Event-drivenRun when triggered by significant graph changes
ManualRun 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.