Skip to content

Dreaming Memory Consolidation ​

LLMs have no cross-session memory. Dreaming is OpenClaw's three-stage background consolidation, ensuring that today's CIO still knows about "the committee repeatedly HOLDing during a downtrend and missing the rally."

← 02-agents · Wiki Index · 04-execution-paths →


The Problem ​

Every time the committee runs, the 4 LLM roles are "born anew":

  • Quant doesn't know if the last signal given when RSI>70 was correct in hindsight.
  • Risk Officer doesn't know about the concentration warning from six months ago.
  • CIO doesn't know which verdicts have historically low hit rates or which types of decisions repeatedly miss opportunities.

Result: The same mistakes are repeated forever.

What We Learn: Committee's Own Verdicts vs. Ex-Post Market Action (Source Change 2026-05-26) ​

Important Change: Dreaming previously learned from actual user trades (portfolio_history.jsonl). However, single-user trade volume is too small (single digits to a dozen trades), making it nearly impossible to learn any statistically significant patterns from trades.

It now learns from the committee's own verdicts + subsequent market movements. The committee issues verdicts for each asset daily. Each verdict, combined with the subsequent 7d/30d market performance, forms a sample—regardless of whether the user trades or not. Sample size grows naturally with system operation.

The data source is memory/.dreams/verdict_review.jsonl produced by jobs/verdict_review.py. Each line is a post-hoc review of a verdict (already proxy-aware gold CNY/gram conversion + forward window maturity filtering applied, see 05-data-model).

Three-Stage Background Consolidation ​

Runs daily at 03:00 AM (jobs/dreaming.yml):

                              ┌─────────────────┐
   verdict_review.jsonl   →   │  Light Sleep    │  → short-term-recall.json
   + decision day regime      │  (Ingest Signals)│
                              └────────┬────────┘
                                       │
                              ┌────────▼────────┐
                              │  REM Sleep      │  → candidates.json
                              │  (Aggregate by   │
                              │   verdict×regime)│
                              └────────┬────────┘
                                       │
                              ┌────────▼────────┐
        Threshold Gate        │  Deep Sleep     │  → insights/*.md
        score≥0.8             │  (Solidify       │     + MEMORY.md index
        count≥3            →  │   Patterns)      │
                              └─────────────────┘
                                       │
                                       ▼
                          Next Committee CIO Context
                          Injects Insights (Including Admonitions)

Core Idea: The threshold gate ensures that only recurring patterns with sufficient evidence enter long-term memory, preventing the LLM from treating noise as signals. All numerical statistics are deterministically calculated; the LLM cannot modify them.


1. Light Sleep (Ingest Signals) ​

Source: jobs/dreaming.py:light_sleep

Reads verdict_review.jsonl. For each verdict, it appends the market regime on the decision day (using the committee's same core.regime.classify_regime, truncated to the decision day to prevent look-ahead bias). Only samples with matured outcomes (at least one window with a hit) are ingested.

Outputs .dreams/short-term-recall.json, with each signal shaped like: {decision_date, asset, verdict, regime, outcomes{7d,30d}, hits, macro_shock, source}.


2. REM Sleep (Aggregate by Verdict × Regime) ​

Source: jobs/dreaming.py:rem_sleep

Buckets by (asset, verdict, regime) and calculates the 7d/30d hit rate for each combination. For example:

  • "Committee TRIMs gold in a range_bound regime → 7d hit rate 80% (n=5)"
  • "Committee HOLDS Nasdaq in a downtrend regime → 30d actual change +12%, missed opportunity 100% (n=11)"

Two Disciplines:

  • Black Swan Exemption: Samples marked with macro_shock are excluded, preventing the committee from being penalized for unpredictable, sudden changes.
  • Only 7d/30d, Not 1d: Within 1 day, prices barely move; HOLD would be automatically judged a hit, creating a horizon illusion.

HOLD Opportunity Cost Perception (Key Design, 2026-05-26) ​

A HOLD's "hit" is determined using a volatility-aware threshold, not a fixed 3%:

"No movement" = K_FLAT × asset's atr_pct × √window_days, capped at 8% (K_FLAT=1.0 fixed constant)

Why not a fixed 3%: Gold's weekly volatility is ~1%, Nasdaq ~1.8%, Crypto ~3-5%. A uniform threshold would be too loose for gold and too tight for crypto. It's changed to "less than the asset's typical movement over this period" to count as a HOLD hit.

Key Principle (Prevent Reward Hacking): The system adapts to the measurement (atr_pct calculated live from market data), but the rule (K_FLAT constant) is fixed. The system must never be allowed to self-learn this "ruler for scoring itself"—otherwise, it has an incentive to lower the passing grade, counting missed HOLDs as hits, becoming increasingly conservative (Goodhart's Law). If K_FLAT truly needs adjustment, it can only be done in Phase 3 with a holdout set + sufficient samples via offline backtesting, with human sign-off.

When a HOLD is not a hit, it's further categorized by direction:

SituationMeaningHandling
Market Up (missed_up)Missed the rally while holding cashAnti-conservatism admonition, tagged kind=caution
Market Down (avoided_down)Avoided the decline by holding cashNeutral, no penalty
Flat (no movement)HOLD was truly correctHit, tagged kind=reliable

HOLD buckets where missed opportunities (missed_up_rate) are more frequent than hits → tagged caution, solidified into an admonition-type insight.

Output: .dreams/candidates.json


3. Deep Sleep (Solidify) ​

Source: jobs/dreaming.py:deep_sleep

Threshold Gate: score ≥ 0.8 AND count ≥ 3. Scoring (_score):

  • reliable pattern: hit_rate × 0.7 + sample_size × 0.3 (more accurate directional judgment = more valuable)
  • caution pattern: missed_opportunity_rate × 0.7 + sample_size × 0.3 (more frequent missed opportunities = more valuable admonition)

Patterns that pass the gate are written to memory/insights/*.md (one file per insight) + the MEMORY.md index is updated. Optionally, an LLM can verify (INVEST_DREAMING_LLM_VERIFY=1) to filter out spurious correlations.

Example of a Solidified Insight (caution) ​

markdown
# ⚠️ Admonition: HOLDing NDQ.AX in a downtrend frequently misses opportunities

## Statistics
- Sample Count: 11
- 30-day Hit Rate: 0.0%
- Average 30-day Actual Change: +12.02%
- Missed Opportunity Rate (HOLD but market rose): 100.0% / Avoided Decline Rate: 0.0%

## Interpretation
Historically, when the market is in a downtrend, the committee issued a HOLD for NDQ.AX. However, 30 days later, the market clearly rose in 100% of cases (average +12.02%, n=11)—cash was held, missing the rally.

> Action Suggestion: In this regime, the tendency to HOLD should be reduced, and BUY/ACCUMULATE should be considered more actively.

The CIO sees this insight via the MEMORY.md index during the next decision cycle → making it less likely to blindly HOLD in that regime. This is the specific mechanism for "the system learning" to combat excessive conservatism—not the LLM figuring it out, but statistics + a threshold gate solidifying the pattern.


4. How CIO / Risk Officer See It ​

core/runner/loaders.py:load_prior_insights reads memory/insights/*.md before running the committee and injects them into the prompt context (prior_insights). This is part of the Three-Path Single Source of Truth—all three paths (Skill / Web / Cron) go through run_committee_session for injection, ensuring nothing is missed.


5. Relationship with DSPy Posterior Training ​

Dreaming (behavioral insights) and DSPy oracle training (11-rl-training) are two injection points for the same "opportunity cost" philosophy:

  • Dreaming → Distills readable insights like "Is this type of committee judgment accurate or does it miss opportunities in regime X?" and injects them into the CIO prompt.
  • DSPy oracle → Calculates the "best verdict in hindsight" for each historical point in time, training a few-shot calibrator for the committee.

Both teach the committee "don't hold back when the market offers an opportunity," reinforcing each other.


6. GUI Perspective ​

/system → "Dreams" tab shows short-term-recall.json size + recent event stream; "Long-term Patterns" tab shows all solidified patterns in insights/*.md.


7. Failure Modes / Known Pitfalls ​

PitfallMitigation
Small sample size, unstable patternsThreshold gate count≥3 + black swan exemption; can expand samples with more committee runs/backtesting
Deep Sleep write concurrency (cron + manual run simultaneously)core/consolidation_lock.py provides exclusive lock
Accumulating insight filesPlan to add an "aging mechanism": archive if not triggered for N days; currently not implemented
Overfitting K_FLAT and other thresholdsCurrently fixed constants; any adjustment requires Phase 3 holdout + offline backtesting + human sign-off

Next Steps ​

→ 02-agents.md for the specific location of insights in the prompt → 11-rl-training.md for DSPy oracle posterior training → Paper-level background: OpenClaw Dreaming Guide