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_shockare 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.0fixed 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_pctcalculated live from market data), but the rule (K_FLATconstant) 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). IfK_FLATtruly 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:
| Situation | Meaning | Handling |
|---|---|---|
Market Up (missed_up) | Missed the rally while holding cash | Anti-conservatism admonition, tagged kind=caution |
Market Down (avoided_down) | Avoided the decline by holding cash | Neutral, no penalty |
| Flat (no movement) | HOLD was truly correct | Hit, 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):
reliablepattern:hit_rate × 0.7 + sample_size × 0.3(more accurate directional judgment = more valuable)cautionpattern: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)
# ⚠️ 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
| Pitfall | Mitigation |
|---|---|
| Small sample size, unstable patterns | Threshold 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 files | Plan to add an "aging mechanism": archive if not triggered for N days; currently not implemented |
Overfitting K_FLAT and other thresholds | Currently 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