Skip to content

Fix dreaming replay, repair polluted artifacts, and gate wiki tabs#65138

Merged
Takhoffman merged 12 commits into
mainfrom
codex/fix-active-memory-mx-claw-64940
Apr 12, 2026
Merged

Fix dreaming replay, repair polluted artifacts, and gate wiki tabs#65138
Takhoffman merged 12 commits into
mainfrom
codex/fix-active-memory-mx-claw-64940

Conversation

@Takhoffman

@Takhoffman Takhoffman commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

What This PR Does

This PR fixes two user-visible memory problems and wires the recovery flow through the product surfaces that already expose dreaming state.

1. Active memory now keeps recall on the right channel

The branch fixes channel selection for active-memory recall runs so recall follows the resolved session/channel context instead of drifting to a weaker wrapper/provider hint.

Before this change, the recall path could flatten these inputs incorrectly:

explicit channel hint
session store channel
session origin provider
wrapper/provider fallback

Now the selection is ordered by trust and keeps parent-session context when it exists.

flowchart TD
    A["Explicit channel hint"] --> B
    S["Session store: lastChannel/channel"] --> B
    O["Session origin provider"] --> B
    W["Wrapper/provider fallback"] --> B
    B["Resolve recall run channel context"] --> C["Recall runs on the resolved channel"]
Loading

In practice, this means recall jobs stay attached to the channel the conversation actually belongs to instead of hopping to a weaker inferred provider value.

2. Managed dreaming no longer replays the same event and spiral-loops on itself

The branch fixes the main dreaming failure mode that produced the half-hourly spam.

There were two separate problems:

  1. A managed dreaming system event could be inspected by heartbeat and then replayed again instead of being consumed once.
  2. Dreaming could ingest its own narrative transcripts back into future dream runs.

Before:

flowchart LR
    A["Managed dreaming event queued once"] --> B["Heartbeat inspects event"]
    B --> C["Dreaming run writes diary + narrative transcript"]
    C --> D["Event not fully consumed or later replayed"]
    C --> E["Narrative transcript re-enters dream corpus"]
    D --> B
    E --> C
Loading

After:

flowchart LR
    A["Managed dreaming event queued once"] --> B["Heartbeat inspects exact queued entries"]
    B --> C["Successful dreaming run"]
    C --> D["Consume only inspected entries"]
    C --> E["Skip dreaming-generated transcripts during corpus ingestion"]
    D --> F["Later events remain queued for later heartbeats"]
    E --> G["No self-ingestion loop"]
Loading

Concretely, the runtime changes are:

  • src/infra/heartbeat-runner.ts now consumes inspected system events on success and on the no-tasks-due early-return path.
  • src/infra/system-events.ts now removes only the exact inspected queued entries instead of draining the whole session queue.
  • src/memory-host-sdk/host/session-files.ts and packages/memory-host-sdk/src/host/session-files.ts mark dreaming-generated transcripts, and extensions/memory-core/src/dreaming-phases.ts skips them during corpus ingestion.

This closes both the replay bug and the “dreaming about its own dreams” feedback loop.

3. Dreaming repair and diary cleanup are now explicit product actions

Once the runtime was fixed, the next problem was cleanup of already-polluted derived state. This PR adds one shared repair backend in memory-core and exposes it consistently.

flowchart TD
    A["Polluted dream artifacts"] --> B["memory-core repair API"]
    B --> C["CLI: openclaw memory status --fix"]
    B --> D["CLI: openclaw doctor --fix"]
    B --> E["Control UI: Repair Dream Cache"]
    B --> F["Control UI: Dedupe Diary"]
Loading

The repair model is intentionally conservative:

  • Repair Dream Cache archives and resets derived dream artifacts such as memory/.dreams/session-corpus and memory/.dreams/session-ingestion.json.
  • Dedupe Diary rewrites DREAMS.md, but only removes exact duplicate diary blocks.
  • DREAMS.md is not silently deleted by cache repair.

The dedupe rule is intentionally narrow:

fingerprint = normalizedTimestamp + "\n" + normalizedBody

That means we remove only exact same-timestamp / same-body duplicates, not fuzzy “similar” entries.

4. Diary rewrites are now serialized

The branch also fixes a write race on DREAMS.md.

Before, append/dedupe/backfill paths each did their own read-modify-write cycle. If two paths ran together, one could overwrite the other.

Now all diary mutations go through one locked update path in extensions/memory-core/src/dreaming-narrative.ts.

sequenceDiagram
    participant A as Append
    participant B as Dedupe
    participant L as Per-file async lock
    participant F as DREAMS.md
    A->>L: acquire
    A->>F: read/update/write
    A-->>L: release
    B->>L: acquire
    B->>F: read/update/write
    B-->>L: release
Loading

This preserves the existing behavior while preventing lost updates inside a single process.

5. Dreams UI now explains wiki-backed tabs instead of failing opaquely

Imported Insights and Memory Palace are provided by the bundled memory-wiki plugin, but the UI previously exposed those subtabs unconditionally.

This PR keeps the tabs visible, but when memory-wiki is disabled it shows a clear enablement state instead of a vague failure:

  • explains that the tabs come from memory-wiki
  • points at plugins.entries.memory-wiki.enabled = true
  • offers Open Config

It also adds better action feedback in Dreams -> Advanced for repair/dedupe:

  • confirmation before destructive-ish actions
  • inline success/error state
  • archive path surfaced after cache repair
  • Copy archive path button

Runtime Flow Summary

flowchart TD
    A["Conversation/session state"] --> B["Active-memory recall resolves strongest channel"]
    A --> C["Dreaming heartbeat consumes exact queued events once"]
    C --> D["Dream corpus built from normal session material"]
    D --> E["Dreaming-generated transcripts filtered out"]
    E --> F["Narrative diary writes serialized to DREAMS.md"]
    F --> G["Repair + dedupe available in CLI, doctor, and UI"]
    G --> H["Wiki tabs gated behind memory-wiki enablement"]
Loading

Main Files To Look At

  • extensions/active-memory/index.ts
  • src/infra/heartbeat-runner.ts
  • src/infra/system-events.ts
  • src/memory-host-sdk/host/session-files.ts
  • packages/memory-host-sdk/src/host/session-files.ts
  • extensions/memory-core/src/dreaming-phases.ts
  • extensions/memory-core/src/dreaming-repair.ts
  • extensions/memory-core/src/dreaming-narrative.ts
  • src/commands/doctor-memory-search.ts
  • src/gateway/server-methods/doctor.ts
  • ui/src/ui/controllers/dreaming.ts
  • ui/src/ui/views/dreaming.ts

Testing

  • pnpm vitest run --project infra src/infra/system-events.test.ts src/infra/heartbeat-runner.ghost-reminder.test.ts src/infra/heartbeat-runner.isolated-key-stability.test.ts
  • node scripts/run-vitest.mjs run --config vitest.config.ts extensions/memory-core/src/dreaming-repair.test.ts extensions/memory-core/src/dreaming-narrative.test.ts
  • pnpm vitest run --project extensions extensions/active-memory/config.test.ts extensions/active-memory/index.test.ts -t "modelFallback"
  • pnpm vitest run src/memory-host-sdk/host/session-files.test.ts
  • pnpm vitest run extensions/memory-core/src/dreaming-phases.test.ts
  • pnpm vitest run extensions/memory-core/src/cli.test.ts
  • pnpm vitest run src/commands/doctor-memory-search.test.ts
  • pnpm vitest run src/gateway/server-methods/doctor.test.ts
  • pnpm vitest run ui/src/ui/controllers/dreaming.test.ts
  • pnpm vitest run ui/src/ui/app-settings.test.ts
  • pnpm vitest run ui/src/ui/views/dreaming.test.ts

@aisle-research-bot

aisle-research-bot Bot commented Apr 12, 2026

Copy link
Copy Markdown

🔒 Aisle Security Analysis

We found 3 potential security issue(s) in this PR:

# Severity Title
1 🟠 High Symlink traversal in dreaming artifact repair archive destination allows arbitrary file move
2 🟡 Medium Arbitrary file write via unvalidated workspaceDir in dreaming narrative file updates
3 🔵 Low TOCTOU race in dreaming artifact archiver allows swapping path between lstat() and rename()
1. 🟠 Symlink traversal in dreaming artifact repair archive destination allows arbitrary file move
Property Value
Severity High
CWE CWE-59
Location extensions/memory-core/src/dreaming-repair.ts:119-123

Description

repairDreamingArtifacts() archives existing artifacts by renaming them into an archive directory under the workspace. While ensureArchivablePath() rejects symlinked source artifacts, the code does not prevent the archive directory path (or its parents) from being a symlink.

If an attacker can write within workspaceDir, they can create .openclaw-repair (or .openclaw-repair/dreaming) as a symlink to an arbitrary location. Because fs.mkdir(archiveDir, { recursive: true }) will traverse existing symlinks, subsequent fs.rename(targetPath, destination) may move memory/.dreams/session-corpus and memory/.dreams/session-ingestion.json to an attacker-chosen location outside the workspace.

Vulnerable flow:

  • Input: workspaceDir resolved from config/agent workspace directory.
  • Sink: fs.mkdir(archiveDir, { recursive: true }) + fs.rename(targetPath, destination) where destination is under archiveDir.
  • Missing validation: No lstat/realpath checks to ensure archiveDir stays within the real workspaceDir and contains no symlink components.

Vulnerable code:

await fs.mkdir(params.archiveDir, { recursive: true });
const destination = path.join(params.archiveDir, `${baseName}.${randomUUID()}`);
await fs.rename(params.targetPath, destination);

Recommendation

Harden archive destination creation against symlink traversal:

  1. Reject symlinks in the archive directory path (at minimum .openclaw-repair and .openclaw-repair/dreaming).
  2. Resolve real paths and enforce that the final archive directory is inside the real workspace directory.

Example approach:

async function assertNoSymlink(p: string) {
  const st = await fs.lstat(p);
  if (st.isSymbolicLink()) throw new Error(`Refusing symlink path component: ${p}`);
}

const workspaceReal = await fs.realpath(workspaceDir);
const repairRoot = path.join(workspaceDir, ".openclaw-repair");// Ensure existing components are not symlinks
for (const part of [repairRoot, path.join(repairRoot, "dreaming")]) {
  try { await assertNoSymlink(part); } catch (e: any) {
    if (e?.code !== "ENOENT") throw e;
  }
}

await fs.mkdir(path.join(repairRoot, "dreaming"), { recursive: true });
const archiveDir = path.join(repairRoot, "dreaming", buildArchiveTimestamp(new Date()));
await fs.mkdir(archiveDir, { recursive: false });

const archiveRealParent = await fs.realpath(path.dirname(archiveDir));
if (!archiveRealParent.startsWith(workspaceReal + path.sep)) {
  throw new Error("Archive directory escapes workspace");
}

Additionally consider creating the archive directory with fs.mkdtemp() under a validated, non-symlink parent directory to reduce race conditions.

2. 🟡 Arbitrary file write via unvalidated workspaceDir in dreaming narrative file updates
Property Value
Severity Medium
CWE CWE-22
Location extensions/memory-core/src/dreaming-narrative.ts:247-448

Description

The DREAMS diary update helpers write to a path derived from workspaceDir without ensuring it is an absolute, trusted workspace path.

  • updateDreamsFile() calls resolveDreamsPath(workspaceDir), which uses path.join(workspaceDir, "DREAMS.md").
  • No validation ensures workspaceDir is absolute or constrained to an approved root.
  • The resulting dreamsPath is created/written (fs.mkdir(path.dirname(dreamsPath)), then writeDreamsFileAtomic(...)).

If any consumer can call these exported APIs with attacker-controlled workspaceDir (e.g., via plugin facade usage or future gateway endpoints), this becomes an arbitrary file write primitive relative to the process working directory (for relative paths) or to any location the process can access (for absolute paths).

Recommendation

Validate and normalize workspaceDir before using it to build filesystem paths.

At minimum, require an absolute path and path.resolve() it (mirroring dreaming-repair.ts):

function requireAbsoluteWorkspaceDir(raw: string): string {
  const trimmed = raw.trim();
  if (!trimmed) throw new Error("workspaceDir is required");
  if (!path.isAbsolute(trimmed)) throw new Error("workspaceDir must be an absolute path");
  return path.resolve(trimmed);
}

async function updateDreamsFile<T>(params: { workspaceDir: string; ... }): Promise<T> {
  const workspaceDir = requireAbsoluteWorkspaceDir(params.workspaceDir);
  const dreamsPath = await resolveDreamsPath(workspaceDir);
  ...
}

If there is a known allowed workspace root, additionally enforce containment (e.g., resolved.startsWith(root + path.sep)) to prevent writing outside the workspace.

3. 🔵 TOCTOU race in dreaming artifact archiver allows swapping path between lstat() and rename()
Property Value
Severity Low
CWE CWE-367
Location extensions/memory-core/src/dreaming-repair.ts:92-105

Description

The dreaming repair archiver checks a path with lstat() to reject symlinks, then later archives it using fs.rename() by path. Because the check and use are separate filesystem operations, an attacker who can modify the workspace directory concurrently can race to replace targetPath after the lstat() check but before rename(), causing the code to move a different file/directory than the one that was checked.

  • Check: ensureArchivablePath() calls fs.lstat(targetPath) and rejects symlinks.
  • Use: moveToArchive() later calls fs.rename(targetPath, destination).
  • Impact: can be abused to archive/move an unintended workspace path (integrity/data loss), bypassing the intent of only archiving the expected artifacts.

Vulnerable code:

const kind = await ensureArchivablePath(params.targetPath);
...
await fs.rename(params.targetPath, destination);

Recommendation

Avoid path-based check-then-use flows for filesystem operations on attacker-modifiable directories.

Mitigations (pick what is feasible in your environment):

  1. Use file-descriptor-based operations by opening the path with flags that prevent symlink traversal and then operating on the opened handle (where supported).

  2. Re-validate immediately before rename and reduce the race window by checking again and failing if inode/device changed (best-effort):

const st1 = await fs.lstat(targetPath);
if (st1.isSymbolicLink()) throw new Error("Refusing symlink");// ... compute destination ...

const st2 = await fs.lstat(targetPath);
if (st2.ino !== st1.ino || st2.dev !== st1.dev) {
  throw new Error("Artifact changed during archival; aborting");
}
await fs.rename(targetPath, destination);
  1. Constrain operations within the workspace using a directory file descriptor (open workspace dir, then operate with openat-style APIs / native addon) or platform-specific syscalls such as renameat2 with RENAME_NOREPLACE + RESOLVE_NO_SYMLINKS equivalents (Node doesn't expose all of these directly).

Also consider documenting that the workspace must not be writable by untrusted users/processes during repair operations.


Analyzed PR: #65138 at commit 19a647f

Last updated on: 2026-04-12T05:09:47Z

@openclaw-barnacle openclaw-barnacle Bot added channel: msteams Channel integration: msteams app: web-ui App: web-ui gateway Gateway runtime extensions: memory-core Extension: memory-core commands Command implementations size: XL maintainer Maintainer-authored PR labels Apr 12, 2026
@greptile-apps

greptile-apps Bot commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR addresses three related dreaming subsystem issues: (1) heartbeat-triggered dreaming system events were peeked but never consumed, causing a single dreaming run to replay every 30 minutes — fixed by calling drainSystemEventEntries at each successful heartbeat exit path; (2) dreaming-narrative session transcripts were being ingested into the very session corpus they generate from — fixed by tagging those transcripts via bootstrap runId prefix detection and skipping them in collectSessionIngestionBatches; (3) the Imported Insights and Memory Palace diary subtabs had no guard against memory-wiki being disabled.

One minor write-efficiency concern in dedupeDreamDiaryEntries: the condition removed > 0 || existing.length > 0 rewrites the diary file on every call even when zero duplicates are found, updating the file's mtime unnecessarily and potentially triggering downstream ingestion re-scans. Suggest tightening to removed > 0.

Confidence Score: 5/5

Safe to merge; all remaining findings are P2 style suggestions that do not affect correctness.

The heartbeat drain fix is correct and well-guarded. Self-ingestion prevention is logically sound. Repair/dedupe flows follow existing patterns. The only issue flagged (unnecessary rewrite in dedupe) causes a harmless mtime update with identical content — not a data integrity problem.

extensions/memory-core/src/dreaming-narrative.ts — write condition in dedupeDreamDiaryEntries.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/memory-core/src/dreaming-narrative.ts
Line: 507-512

Comment:
**Unnecessary rewrite when no duplicates found**

The condition `removed > 0 || existing.length > 0` causes `writeDreamsFileAtomic` to run even when zero duplicates were removed, as long as the diary has any content. The roundtrip through `splitDiaryBlocks``joinDiaryBlocks` is lossless for well-formed diaries, so the byte content is preserved, but the file's mtime changes needlessly on every no-op `dedupeDiary` call. This can trigger spurious cache invalidations in downstream ingestion trackers that key on mtime. The guard should be `removed > 0`.

```suggestion
  if (removed > 0) {
    await fs.mkdir(path.dirname(dreamsPath), { recursive: true });
    await writeDreamsFileAtomic(
      dreamsPath,
      replaceDiaryContent(ensured, joinDiaryBlocks(keptBlocks)),
    );
  }
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Fix dreaming replay and recovery flows" | Re-trigger Greptile

Comment thread extensions/memory-core/src/dreaming-narrative.ts Outdated
@blacksmith-sh

blacksmith-sh Bot commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
gateway-watch-regression invalid local run: dirty watched source tree would force a reb
uild inside the watch window/
gateway-watch-regression invalid local run: dirty watched source tree would force a reb
uild inside the watch window
View Logs

Fix in Cursor

@Takhoffman

Copy link
Copy Markdown
Contributor Author

Merged current origin/main into this branch and resolved the CHANGELOG.md unreleased-fixes conflict by keeping both the new main entries and this PR's memory fix entry.

Also fixed the review-driven follow-ups that landed after the original dreaming changes:

  • tightened dedupeDreamDiaryEntries() so no-op dedupe does not rewrite DREAMS.md
  • validated workspaceDir at the dreaming repair boundary
  • made the per-file dream-diary lock registry self-cleaning instead of unbounded
  • hardened archive naming in dreaming repair to use unique destinations instead of probe-then-rename naming

The merge from main also needed three upstream test-type updates to satisfy the current repo checks:

  • extensions/discord/src/monitor/native-command.options.test.ts
  • extensions/telegram/src/exec-approval-resolver.test.ts
  • src/agents/pi-hooks/context-pruning/pruner.test.ts

The visible Greptile/Aisle comments are stale in a few places relative to the current head. Latest branch head is 19a647f470.

@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord channel: telegram Channel integration: telegram agents Agent runtime and tooling and removed channel: msteams Channel integration: msteams labels Apr 12, 2026
@Takhoffman
Takhoffman merged commit 847739d into main Apr 12, 2026
36 of 46 checks passed
@Takhoffman
Takhoffman deleted the codex/fix-active-memory-mx-claw-64940 branch April 12, 2026 05:25
trudbot pushed a commit to trudbot/openclaw that referenced this pull request Apr 12, 2026
…penclaw#65138)

* fix(active-memory): preserve parent channel context for recall runs

* fix(active-memory): keep recall runs on the resolved channel

* fix(active-memory): prefer resolved recall channel over wrapper hints

* fix(active-memory): trust explicit recall channel hints

* fix(active-memory): rank recall channel fallbacks by trust

* Fix dreaming replay and recovery flows

* fix: prevent dreaming event loss and diary write races

* chore: add changelog entry for memory fixes

* fix: harden dreaming repair and diary writes

* fix: harden dreaming artifact archive naming
TOMUIV pushed a commit to TOMUIV/openclaw that referenced this pull request Apr 14, 2026
…penclaw#65138)

* fix(active-memory): preserve parent channel context for recall runs

* fix(active-memory): keep recall runs on the resolved channel

* fix(active-memory): prefer resolved recall channel over wrapper hints

* fix(active-memory): trust explicit recall channel hints

* fix(active-memory): rank recall channel fallbacks by trust

* Fix dreaming replay and recovery flows

* fix: prevent dreaming event loss and diary write races

* chore: add changelog entry for memory fixes

* fix: harden dreaming repair and diary writes

* fix: harden dreaming artifact archive naming
@prtags

prtags Bot commented Apr 23, 2026

Copy link
Copy Markdown

Related work from PRtags group safe-marten-ot47

Title: Open PR candidate: Dream Diary duplicate/raw fallback cleanup

Number Title
#65138* Fix dreaming replay, repair polluted artifacts, and gate wiki tabs
#70332 fix(memory): harden dreaming diary pipeline
#70403 fix(memory-core): keep Dream Diary to one entry per sweep
#70523 fix(memory-core): suppress raw dreaming inline dumps on fallback (Fixes #70509)

* This PR

lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
…penclaw#65138)

* fix(active-memory): preserve parent channel context for recall runs

* fix(active-memory): keep recall runs on the resolved channel

* fix(active-memory): prefer resolved recall channel over wrapper hints

* fix(active-memory): trust explicit recall channel hints

* fix(active-memory): rank recall channel fallbacks by trust

* Fix dreaming replay and recovery flows

* fix: prevent dreaming event loss and diary write races

* chore: add changelog entry for memory fixes

* fix: harden dreaming repair and diary writes

* fix: harden dreaming artifact archive naming
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
…penclaw#65138)

* fix(active-memory): preserve parent channel context for recall runs

* fix(active-memory): keep recall runs on the resolved channel

* fix(active-memory): prefer resolved recall channel over wrapper hints

* fix(active-memory): trust explicit recall channel hints

* fix(active-memory): rank recall channel fallbacks by trust

* Fix dreaming replay and recovery flows

* fix: prevent dreaming event loss and diary write races

* chore: add changelog entry for memory fixes

* fix: harden dreaming repair and diary writes

* fix: harden dreaming artifact archive naming
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
…penclaw#65138)

* fix(active-memory): preserve parent channel context for recall runs

* fix(active-memory): keep recall runs on the resolved channel

* fix(active-memory): prefer resolved recall channel over wrapper hints

* fix(active-memory): trust explicit recall channel hints

* fix(active-memory): rank recall channel fallbacks by trust

* Fix dreaming replay and recovery flows

* fix: prevent dreaming event loss and diary write races

* chore: add changelog entry for memory fixes

* fix: harden dreaming repair and diary writes

* fix: harden dreaming artifact archive naming
globalcaos pushed a commit to globalcaos/tinkerclaw that referenced this pull request May 13, 2026
…penclaw#65138)

* fix(active-memory): preserve parent channel context for recall runs

* fix(active-memory): keep recall runs on the resolved channel

* fix(active-memory): prefer resolved recall channel over wrapper hints

* fix(active-memory): trust explicit recall channel hints

* fix(active-memory): rank recall channel fallbacks by trust

* Fix dreaming replay and recovery flows

* fix: prevent dreaming event loss and diary write races

* chore: add changelog entry for memory fixes

* fix: harden dreaming repair and diary writes

* fix: harden dreaming artifact archive naming
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
…penclaw#65138)

* fix(active-memory): preserve parent channel context for recall runs

* fix(active-memory): keep recall runs on the resolved channel

* fix(active-memory): prefer resolved recall channel over wrapper hints

* fix(active-memory): trust explicit recall channel hints

* fix(active-memory): rank recall channel fallbacks by trust

* Fix dreaming replay and recovery flows

* fix: prevent dreaming event loss and diary write races

* chore: add changelog entry for memory fixes

* fix: harden dreaming repair and diary writes

* fix: harden dreaming artifact archive naming
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
…penclaw#65138)

* fix(active-memory): preserve parent channel context for recall runs

* fix(active-memory): keep recall runs on the resolved channel

* fix(active-memory): prefer resolved recall channel over wrapper hints

* fix(active-memory): trust explicit recall channel hints

* fix(active-memory): rank recall channel fallbacks by trust

* Fix dreaming replay and recovery flows

* fix: prevent dreaming event loss and diary write races

* chore: add changelog entry for memory fixes

* fix: harden dreaming repair and diary writes

* fix: harden dreaming artifact archive naming
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: web-ui App: web-ui channel: discord Channel integration: discord channel: telegram Channel integration: telegram commands Command implementations extensions: memory-core Extension: memory-core gateway Gateway runtime maintainer Maintainer-authored PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant