Dreaming is the background memory consolidation system in memory-core. It moves strong short-term signals into durable memory while keeping the process explainable and reviewable.
Dreaming is enabled by default. Set
plugins.entries.memory-core.config.dreaming.enabled: false to disable it.
When the cron scheduler is disabled (cron.enabled: false or
APUS_SKIP_CRON=1), dreaming defers automatic job creation and updates while
preserving existing jobs. Startup cleanup of historical dreaming artifacts waits
for each agent's pending database preparation before running, including managed
background cleanup after a restart or upgrade. Database preparation failures are
reported with repair guidance. Explicitly disabling dreaming removes jobs carrying
its canonical declaration key in the active cron store.
What dreaming writes
- Machine state in SQLite-backed plugin state (recall store, phase signals, ingestion checkpoints, locks).
- Rewrite preimages in SQLite-backed plugin state before an accepted
MEMORY.mdrewrite. - Human-readable output in
DREAMS.md(or an existingdreams.md) and optional phase report files undermemory/dreaming/<phase>/YYYY-MM-DD.md.
The built-in SQLite store reads only the selected workspace's state for lookups and cleanup. Corrupt JSON in another workspace does not block these operations; corrupt JSON in a live record in the selected workspace still reports a storage error.
Long-term promotion still writes only to MEMORY.md.
Deep reports summarize why ranked candidates were not promoted, using counts by
rejection category without copying rejected snippets or source identifiers.
These counts cover candidates that reached promotion; they do not describe
entries excluded during ranking. A candidate that changes during the final
apply check keeps a general change reason rather than an inferred cause.
An empty sweep records completion in plugin state without creating memory or
dreaming files, so it does not complete a new workspace's first-run setup.
Existing daily notes can still receive managed phase-block updates.
Each newly promoted entry carries trailing recall metadata derived from the
candidate: up to three concept tags in <!-- trigger: phrase one, phrase two -->
and a bounded <!-- importance: N --> value from 1 to 10. Consolidation keeps
existing annotated entries byte-for-byte unless it explicitly merges or
supersedes them.
Phase model
Dreaming runs three cooperative phases per sweep, in order: light -> REM -> deep. These are internal implementation phases, not separate user-configured modes.
| Phase | Purpose | Durable write |
|---|---|---|
| Light | Sort and stage recent short-term material | No |
| REM | Reflect on themes and recurring ideas | No |
| Deep | Score and promote durable candidates | Yes (MEMORY.md) |
Light phase
- Reads recent short-term recall state, daily memory files, and redacted session transcripts when available.
- Dedupes signals and stages candidate lines.
- Writes a managed `## Light Sleep` block when storage includes inline output.
- Records reinforcement signals for later deep ranking.
- Never writes to `MEMORY.md`.
REM phase
- Builds theme and reflection summaries from recent short-term traces.
- Writes a managed `## REM Sleep` block when storage includes inline output.
- Records REM reinforcement signals used by deep ranking.
- Never writes to `MEMORY.md`.
Deep phase
- Ranks candidates with weighted scoring and threshold gates (`minScore`, `minRecallCount`, `minUniqueQueries` must all pass).
- Rehydrates snippets from live daily files before writing, so stale/deleted snippets are skipped.
- Passes gated owner and agent-derived candidates to a tool-free completion that chooses additions, merges, and supersessions against the current `MEMORY.md`.
- Composes `MEMORY.md` from validated source evidence, preserving unrelated entries and candidate source references within the prior-entry loss limit and bootstrap budget.
- Falls back to the previous append-only promotion path when the model is unavailable or the rewrite fails validation.
- Writes a `## Deep Sleep` summary into `DREAMS.md` and optionally `memory/dreaming/deep/YYYY-MM-DD.md`.
Session transcript ingestion
Dreaming can ingest redacted session transcripts into the dreaming corpus. Only interactive sessions are eligible. Cron, heartbeat, subagent, and unknown sessions stay out of durable candidate ingestion. Personal and sensitive content is redacted before ingestion, and runtime-marked recalled context is removed so recalled snippets cannot be learned again as new memory.
Two operator controls exclude sessions from automatic ingestion, each with a recorded reason: the memory admission policy matches retained hook-source, channel, or chat-type metadata, and memory forget records selected session IDs as forgotten for future scans. Policy changes do not erase existing candidates or prevent direct file writes. Manual session backfill applies both controls in preview, REM, and apply modes, and preserves source-session origins when staging candidates.
Consolidation safety
The deterministic score, recall-count, and query-diversity thresholds remain the candidate gate. Consolidation runs only after those gates pass.
Before building the consolidation prompt, memory-core removes candidates
whose indexed provenance is untrusted or system. This is a structural
taint gate, not a score penalty. Eligible candidates include their origin,
session kind, observation time, optional supersession key, and daily-note
source reference.
The model returns operation decisions, not replacement memory prose. The memory writer applies those decisions to the existing file using each candidate's bounded, sourced entry. An accepted rewrite or append compaction must:
- preserve prior entries within
phases.deep.maxPriorEntryLossFraction - include every promoted candidate's
Source: path#Lx-Lyreference - stay within the
MEMORY.mdbootstrap-safe file budget - parse as the expected structured response
Before the file changes, the previous MEMORY.md is stored in SQLite-backed
plugin state. DREAMS.md receives added, merged, and superseded counts plus
short diff-style highlights. This makes each rewrite reviewable without
turning the Dream Diary into a promotion source.
Background consolidation is informed by sleep-time compute (arXiv:2504.13171). The provenance and reflection boundary follows the durable memory framing in the Generative Agents research.
Dream Diary
Dreaming keeps a narrative Dream Diary in DREAMS.md. After each phase has enough material, memory-core runs a tool-free background completion and appends a short diary entry, using the workspace agent's default model unless dreaming.model is configured. If the configured model is unavailable, the diary run retries once with that agent's default model. Trust or allowlist failures are not retried.
Diary and consolidation completions use fresh contexts without retaining conversation sessions or delivering chat replies. Failed or empty diary generation writes a local fallback entry and reports a degraded outcome, so missing model output leaves a visible trace.
Diary generation uses the existing agent run budget, agents.defaults.timeoutSeconds,
instead of a separate one-minute deadline. It inherits the same 48-hour default and
timer-safe unlimited setting as agent runs. The selected provider's
models.providers.<provider>.timeoutSeconds still bounds its model requests, so
keep both budgets long enough for slow local inference.
The diary is for human reading in the Dreams UI, not a promotion source. Diary/report artifacts are excluded from short-term promotion; only grounded memory snippets are eligible to promote into MEMORY.md.
There is also a grounded historical backfill lane for review and recovery work:
Backfill commands
- `apus memory rem-harness --path <path> --grounded` previews grounded diary output from historical `YYYY-MM-DD.md` notes.
- `apus memory rem-backfill --path <path>` writes reversible grounded diary entries into `DREAMS.md`.
- `apus memory rem-backfill --path <path> --stage-short-term` stages grounded durable candidates into the same short-term evidence store the normal deep phase uses.
- `apus memory rem-backfill --rollback` and `--rollback-short-term` remove those staged backfill artifacts without touching ordinary diary entries or live short-term recall.
- `apus memory session-backfill --agent <id>` previews trusted candidates from the agent's retained session history, oldest unprocessed day first.
- `apus memory session-backfill --agent <id> --apply` stages those candidates through the normal short-term store and writes reversible diary blocks without changing `MEMORY.md` or `USER.md`.
- `apus memory session-backfill --agent <id> --rem` writes a deterministic grounded preview per day to `DREAMS.md` without staging candidates or calling a model.
- `apus memory session-backfill --agent <id> --rollback` clears the shared grounded backfill candidates and diary blocks, including artifacts created by `rem-backfill`.
Session backfill uses canonical retained transcript identities, including
sessions preserved across rotation. Messages are bucketed in the configured
dreaming timezone and share live ingestion's tracked message hashes and signal
caps. Apply drains bounded batches to completion in one command. Rollback
removes generated artifacts plus the hashes and cursor progress owned by those
batches, allowing the same candidates to be staged again.
Foreign files supplied with --archive-files are treated conservatively. Their
embedded ownership fields are caller-controlled and therefore remain untrusted;
without an authenticated provenance contract, they cannot enter short-term
staging. Tool output, web content, and non-owner turns are excluded from the
canonical session path as well.
The Control UI exposes the same diary backfill/reset flow on the agent's Memory tab (Agents page) so you can inspect results in the dream scene before deciding whether grounded candidates deserve promotion. A distinct grounded Scene lane shows which staged short-term entries came from historical replay, which promoted items were grounded-led, and lets you clear only grounded-only staged entries without touching live short-term state.
Deep ranking signals
Deep ranking uses six weighted base signals plus phase reinforcement:
| Signal | Weight | Description |
|---|---|---|
| Relevance | 0.30 | Average retrieval quality for the entry |
| Frequency | 0.24 | How many short-term signals the entry accumulated |
| Query diversity | 0.15 | Distinct interactive recall queries that surfaced it |
| Recency | 0.15 | Time-decayed freshness score |
| Consolidation | 0.10 | Multi-day recurrence strength |
| Conceptual richness | 0.06 | Concept-tag density from snippet/path |
Light and REM phase hits recorded in SQLite-backed plugin state add a small recency-decayed boost.
Scheduling
When enabled, memory-core auto-manages one cron job for a full dreaming sweep, deduped across the primary runtime workspace and any configured agent workspaces so subagent workspace fan-out does not exclude the main agent's DREAMS.md and memory state.
Plugin reloads preserve the managed schedule. The previous instance stops its background callbacks and settles pending diary publication before its replacement takes over, so scheduled sweeps can continue without a Gateway restart.
Runtime reconciliation owns only jobs declared as
memory-core:memory-dreaming-promotion. It uses Doctor's read-only classifier
on the active jobs already listed to report historical rows. Recognized legacy
or phase jobs require Doctor repair before runtime creates or updates the managed
job. Declared jobs with retired payload formats also require Doctor repair.
Jobs with historical tags and authored
payloads remain untouched and produce a manual-review warning; they do not block
creation or updates of the declared dreaming job. Disabling dreaming still removes
only explicitly declared jobs and reports any remaining historical work.
Run apus doctor --fix to adopt
historical dreaming jobs identified by ownership metadata and known generated
payloads. A historical tag on a custom prompt produces a manual-review warning.
Doctor first saves a verified SQLite backup, then adopts one unified
job in each persisted cron store partition without changing its ID, ordering,
or runtime state. If only legacy light/REM jobs exist, it promotes the oldest
valid phase job in place. It removes recognized duplicates only after that
partition has a valid survivor. When dreaming is disabled, Doctor retires the
recognized managed rows instead. Jobs with a different declaration key and
unrelated operator jobs remain unchanged; malformed or ambiguous rows produce
a repair warning and remain in place.
Dreaming completions share the background work budget with Skill Workshop and other plugin completions: at most three runs in total, with up to three available to memory-core. The sweep coordinator does not consume a completion slot while it waits for phase work. System busyness shows these runs together in the background row.
An explicit multi-agent fleet needs an ambient system owner for this job. If logs report Agent-less cron job has no resolvable owner, choose an existing agent to own the sweep. For example, if that agent is ops:
apus config set agents.defaults.systemAgent.agentId ops
This selects the execution owner; it does not change any agent's workspace or limit the sweep to that agent's memory. A sole-agent installation resolves its owner automatically.
| Setting | Default |
|---|---|
dreaming.frequency |
0 3 * * * |
dreaming.model |
default model |
Quick start
Disable dreaming
```json
{
"plugins": {
"entries": {
"memory-core": {
"config": {
"dreaming": {
"enabled": false
}
}
}
}
}
}
```
Custom sweep cadence
```json
{
"plugins": {
"entries": {
"memory-core": {
"config": {
"dreaming": {
"enabled": true,
"timezone": "America/Los_Angeles",
"frequency": "0 */6 * * *"
}
}
}
}
}
}
```
Slash command
/dreaming status
/dreaming on
/dreaming off
/dreaming help
/dreaming on and /dreaming off require owner status for channel callers or operator.admin for Gateway clients. /dreaming status and /dreaming help are read-only.
CLI workflow
Promotion preview / apply
```bash
apus memory promote
apus memory promote --apply
apus memory promote --limit 5
apus memory status --deep
```
Manual `memory promote` uses deep-phase thresholds by default unless overridden with CLI flags.
Explain promotion
Explain why a specific candidate would or would not promote:
```bash
apus memory promote-explain "router vlan"
apus memory promote-explain "router vlan" --json
```
REM harness preview
Preview REM reflections, candidate truths, and deep promotion output without writing anything:
```bash
apus memory rem-harness
apus memory rem-harness --json
```
Key defaults
All settings live under plugins.entries.memory-core.config.dreaming.
enabled boolean
Enable or disable the dreaming sweep.
phases.deep.maxPriorEntryLossFraction number
Reject a consolidation rewrite or append compaction when it removes more than this fraction of prior entries. Append compaction only removes whole machine-generated promotion sections.
frequency string
Cron cadence for the full dreaming sweep.
model string
Optional Dream Diary completion model override. Use a canonical provider/model value when also setting a subagent allowedModels allowlist.
phases.deep.maxPromotedSnippetTokens number
Maximum estimated token count kept from each short-term recall snippet promoted into MEMORY.md. Ranking provenance remains visible.
dreaming.model requires plugins.entries.memory-core.subagent.allowModelOverride: true. To restrict it, also set plugins.entries.memory-core.subagent.allowedModels. The automatic retry only covers model-unavailable errors; trust or allowlist failures produce a fallback diary trace and a degraded outcome instead of silently switching models.
Most phase policy, thresholds, and storage behavior are internal implementation details. See Memory configuration reference for the full key list.
Dreams UI
When enabled, the Gateway Dreams tab shows:
- current dreaming enabled state
- phase-level status and managed-sweep presence
- short-term, grounded, signal, and promoted-today counts
- next scheduled run timing
- a distinct grounded Scene lane for staged historical replay entries
- an expandable Dream Diary reader backed by
doctor.memory.dreamDiary
When the bundled memory-wiki plugin is enabled, the
Diary view gains two more sub-tabs next to Dreams:
- Imported Insights: clustered insights surfaced by external-history
imports (for example
apus wiki chatgpt import), for review before any of it graduates into durable memory - Memory Wiki: the compiled wiki the memory system can search and reason over — synthesis, entity, and concept pages (plus sources and reports that carry claims, open questions, or contradictions) with per-page counts, a full-vault breakdown, and inline page previews
Both sub-tabs show an enable hint instead when memory-wiki is off.