Agentic Research

Cross-Channel Memory Hub: A Full Record of the Memory System Architecture Design for OpenClaw Agent

2026/05/1345 min readBryan Chan閱讀中文原文
TopicsOpenClawAgent ArchitectureMulti-Agent

Background: Why Does the Agent "Forget" Every Day?

At 4:00 a.m., the Auto-Dream Cron Job runs as scheduled. It checks the daily logs from the past three days, finds that all files have already been marked with <!-- consolidated -->, and then reports:

🌙 No new content today-skipped consolidation

But the fact is: that day the user had 35 conversations with the Agent on WeChat, covering email monitoring repairs, DBS bank searches, research on listed companies in new materials, search engine configuration, Cross Search plugin design, and many other tasks. All these conversations are fully preserved in the Session Log (185MB, 380+ files), but not a single one was written to the structured Daily Log.

This is not a single bug but a systemic architectural flaw. This article fully documents the process from discovering the problem to building a complete solution.


1. Problem Overview: Systemic Flaws at Three Levels

After a thorough investigation, we discovered three independent but compounding technical problems:

1.1 Architecture Level: Cross-Channel Session Isolation

OpenClaw uses the dmScope: "per-channel-peer" configuration, and each channel (Feishu, WeChat, WhatsApp) generates a completely independent Session:

WeChat Session (249c2bce)    Feishu Session (9780b3c4)    WhatsApp Session
      │                           │                        │
  Agent WeChat Clone              Agent Feishu Clone            Agent WA Clone
      │                           │                        │
   Only sees WeChat chats              Only sees Feishu chats            Only sees WA chats
      │                           │                        │
  ❌ Doesn't know what Feishu did        ❌ Doesn't know what WeChat did      ❌ Doesn't know any channel

Key finding: The sessions_list API can only return Sessions from the current channel. Even if WeChat has 101 historical Sessions, when the Feishu Agent calls the API it returns 0 WeChat Sessions.

1.2 Process Level: No Mandatory Mechanism for Daily Log Writes

Daily Log writing depends on the Agent voluntarily doing it. AGENTS.md has a "write after finishing" rule, but when the Agent focuses on actual tasks (writing code, deploying, analyzing data), the Context Window is filled with work content, and the Meta-Task of "writing the log" is naturally ignored.

The data proves this:

MetricSession LogDaily LogLoss Rate
Number of files380698.4%
Total size185MB~15KB99.99%
Daily content178 exchanges2 records98.9%

1.3 Implementation Level: Time Zone Boundary Bug

The Cron Job runs in the HKT time zone, and Session JSONL uses UTC timestamps. During HKT 00:00-08:00, the UTC date is still the previous day:

HKT:  May 12 22:00 ──────── May 13 00:00 ──────── May 13 08:00
UTC:  May 12 14:00 ──────── May 12 16:00 ──────── May 13 00:00
       │                      │
  User chats on WeChat          Cron runs, grep "2026-05-13"
  Session: "2026-05-12"   but Session is all "2026-05-12"
                          → 0 match → missed!

II. Memory Architecture Design: Three-Layer Model

To solve the above problems, we designed a three-layer memory model, where each layer has different storage formats, writing mechanisms, and safeguard strategies:

┌─────────────────────────────────────────────────┐
│ Layer 1: Session Log (system auto-saved)                │
│ agents/main/sessions/*.jsonl · 185MB · 380 files │
│ ✅ Every conversation is automatically saved, complete with no omissions                    │
│ ⚠️ Raw JSONL format, requires programmatic reading               │
├─────────────────────────────────────────────────┤
│ Layer 2: Daily Log (cross-channel manual/automatic integration)            │
│ memory/daily/YYYY-MM-DD.md · Markdown            │
│ ⚡ Three-layer protection: immediate task write → Session check → Cron fallback  │
│ 📝 Structured Markdown, human-readable                      │
├─────────────────────────────────────────────────┤
│ Layer 3: MEMORY.md (long-term memory integration)                   │
│ MEMORY.md · Automatically integrated at 4:00 AM                   │
│ 🧠 Only merges already consolidated daily logs             │
│ 🔴 If Layer 2 is blank → Layer 3 is also blank (fatal dependency)           │
└─────────────────────────────────────────────────┘

Key Design Decisions

Why not merge all channels into a single Session?

Removing per-channel-peer will cause contexts from different channels to mix. For example, work conversations on WeChat and technical discussions on Feishu will contaminate each other's Context Window, actually reducing efficiency.

Why not let Auto-Dream read the Session Log directly?

Session Log is raw JSONL (185MB), containing a lot of noise such as Tool Call, System Event, Model Change, etc. Extracting meaningful user conversations directly from it requires complex NLP processing; it is better to structure it when writing to the Daily Log.

3. Three-Layer Protection Mechanism

To ensure Daily Log (Layer 2) no longer misses anything, we designed three layers of protection, each with different trigger timing and reliability:

LayerTrigger TimingExecutorAdvantagesDisadvantages
1️⃣ Task-levelImmediately after completing each meaningful taskCurrent Session AgentHas context, most accurateDepends on Agent self-discipline
2️⃣ Session EndBefore replying to the last user messageCurrent Session AgentJust finished, fresh in memoryMay forget
3️⃣ Cron FallbackAutomatically runs every 2 hoursIndependent Isolated SessionAutomated, no omissionsNo context, can only extract text summaries

Trigger Rules: What Is a "Meaningful Task"?

✅ Must write:
- Deploy websites, fix bugs
- Write reports, analyze data
- Create/modify files, configure systems
- Search + organize information
- Install/configure tools, create Cron Jobs
- Any operation that consumes >2 Tool Calls

❌ No need to write:
- Simple Q&A ("Morning", "OK")
- Pure chit-chat

Design Principle: Defense in Depth

Task-Level Write (Layer 1) ──→ Missed?
Session Check (Layer 2) ──→ Missed again?
Cron Fallback (Layer 3) ──→ Never miss!

4. Cross-Channel Integration Pipeline

4.1 Why Can't We Use the API?

dmScope: "per-channel-peer" restricts the sessions_list API to returning only Sessions from the current channel. From Feishu, WeChat Sessions cannot be discovered.

4.2 Solution: Filesystem-Level Scanning

The Cron Job directly reads agents/main/sessions/*.jsonl files:

  • Uses find -mmin -240 to find Sessions modified in the last 4 hours
  • Uses pattern matching to identify the channel (check WeChat/WhatsApp first, and Feishu last to avoid misidentification)
  • Extracts user messages and writes them to the shared Daily Log

4.3 Channel Identification Strategy

ChannelIdentification PatternPriority
WeChatopenclaw-weixin or @tencent-weixinHighest
WhatsAppwhatsappMedium
Feishufeishu or ou_142d6f (exclude the above)Lowest

⚠️ Lesson Learned: You cannot directly use ou_142d6f... to identify Feishu, because the Delivery Config of WeChat Sessions also contains this ID (the Cron Job references it). You must match using an exclusive order.

4.4 Complete Pipeline Architecture

WeChat Agent          Feishu Agent          WhatsApp Agent
     │                    │                     │
     │  ① Write when done        │  ① Write when done         │  ① Write when done
     │                    │                     │
     └──────────┬─────────┴──────────┬──────────┘
                │                    │
          Shared Daily Log      ② Cron every 2h cross-channel scan
     (memory/daily/YYYY-MM-DD.md)  ← Read from filesystem
                │              All channels Session JSONL
          ③ 4:00 AM Auto-Dream
                │
            MEMORY.md (Long-term memory)

5. In-Depth Analysis of the Time Zone Boundary Problem

5.1 Reproducing the Problem

The Cron Job runs at 00:01 HKT and executes the following logic:

# Original source code (has Bug)
if grep -q "$(date +%Y-%m-%d)" "$SESSION_FILE"; then
  echo "ACTIVE"
fi

At this point:

  • date +%Y-%m-%d outputs 2026-05-13 (HKT)
  • The Session JSONL timestamp is 2026-05-12T14:34:00Z (UTC)
  • grep "2026-05-13" → 0 matches
  • Conclusion: "No active Session" → Miss!

5.2 Why the 8-Hour Window?

HKT is 8 hours ahead of UTC (UTC+8). This means that every day during 00:00-08:00 HKT, UTC is still on the previous day. Within this 8-hour window, all date-based Session matching will fail.

HKT 00:00 → UTC is still at the previous day 16:00
HKT 04:00 → UTC is still at the previous day 20:00
HKT 07:59 → UTC is still at the previous day 23:59
HKT 08:00 → UTC has finally reached today 00:00 ✅

5.3 Fix: Three-Date Matching

# Corrected code
HKT_TODAY=$(TZ='Asia/Hong_Kong' date +%Y-%m-%d)
UTC_TODAY=$(date -u +%Y-%m-%d)
UTC_YESTERDAY=$(date -u -v-1d +%Y-%m-%d)

if grep -qE "$HKT_TODAY|$UTC_TODAY|$UTC_YESTERDAY" "$SESSION_FILE"; then
  echo "ACTIVE"  # Cover all time zone boundary cases
fi

The OR matching of the three dates ensures that no matter when the Cron runs, at least one date can match a timestamp in the Session.

5.4 Additional Fix: find -newer Dependency Issue

The original find -newer memory/daily/$(date +%Y-%m-%d).md has nondeterministic behavior when the current day's Daily Log has not yet been created. Use instead:

find ... -mmin -240  # Files modified within the past 4 hours (no external dependencies)

6. Cron Pipeline Design

6.1 Division of Responsibilities Between the Two Cron Jobs

Cron JobFrequencyFunctionTimeout
daily-log-autocheckEvery 2 hoursCross-channel scan for Sessions → backfill Daily Log300s
auto-memory-dreamDaily at 04:00Consolidate from Daily Log → MEMORY.md + push report600s

6.2 Daily Run Timeline (HKT)

00:00 ─ autocheck
02:00 ─ autocheck
04:00 ─ autocheck + auto-memory-dream (double safeguard)
06:00 ─ autocheck
08:00 ─ autocheck
10:00 ─ autocheck
12:00 ─ autocheck
14:00 ─ autocheck
16:00 ─ autocheck
18:00 ─ autocheck
20:00 ─ autocheck
22:00 ─ autocheck

13 memory checks per day ensure that conversations within any 2-hour window are not missed.

6.3 Autocheck Execution Flow

Step 1: Calculate three dates (HKT_TODAY + UTC_TODAY + UTC_YESTERDAY)
    ↓
Step 2: find -mmin -240 to find Sessions active in the last 4 hours
    ↓
Step 3: grep filtering by three dates (timezone-safe)
    ↓
Step 4: Pattern Match to identify channel (exclusive order)
    ↓
Step 5: Extract user messages → append to Daily Log (append mode)
    ↓
Step 6: Exit silently (no report if there is no new content)

7. System Monitoring and Health Metrics

7.1 Health Check Items

MetricCheck MethodNormal Value
Daily Log existencels memory/daily/$(date +%Y-%m-%d).mdMust exist
Daily Log sizewc -c>500 bytes
Session coverageCompare Session count vs Daily Log entries>80%
Cron running statusopenclaw cron listlastRunStatus = ok
Dream Streakdream-log.mdConsecutive days

7.2 Current Status

After this repair is completed:

  • 📊 Memory store: ~370 records
  • 🏥 Health score: 75/100 (previously low due to missing Daily Log, will gradually recover)
  • 🔥 Dream Streak: 24 consecutive days
  • ⏱️ Memory latency: reduced from "complete omission" to <2 hours

8. Complete Pitfall Log

6 key issues encountered during the construction of this memory system:

#IssueSeverityRoot CauseFix
1No Checkpoint at session end causes complete amnesia🔴 FatalMeta-task has no automatic triggerThree-layer protection mechanism
2Misjudged WeChat Plugin status🔴 HighConfig warning ≠ actual statusCheck data before drawing conclusions
3sessions_list API cross-channel blind spot🔴 Highper-channel-peer isolationDirect file system read
4Channel Pattern misjudgment🟡 MediumMatch order is not exclusiveExclusive ordering
5UTC/HKT time zone boundary miss🔴 FatalSingle-date grepThree-date OR matching
6find -newer depends on non-existent file🟡 MediumExternal file dependency-mmin -240

Summary of Core Design Principles

PrincipleDescription
Defense in depthFailure of a single layer does not affect the whole (three-layer protection)
File system > APIWhen crossing channels, read files directly instead of relying on restricted APIs
Time range > date comparison-mmin -240 is more reliable than -newer
Multiple-date matchingCross-time-zone scenarios must be compatible with UTC and local time
Exclusive matchingPattern matching goes from specific to general to avoid misjudgment
Verify before concludingConfig warning ≠ actual status; check the data first

9. Collaboration with OpenClaw Auto-Dream

Memory Hub is the upstream assurance layer for Auto-Dream:

  • Memory Hub → Ensures the Daily Log is complete (multi-channel + cross-day boundaries)
  • Auto-Dream → Integrates the complete Daily Log into long-term memory
Memory Hub (Layer 2 Protection)         Auto-Dream (Layer 3 Integration)
┌──────────────────────┐       ┌──────────────────────┐
│ Cross-channel scan   │       │ Read Daily Log       │
│ Timezone safety      │  ──→  │ Extract key decisions│
│ Auto backfill        │       │ Update MEMORY.md     │
│ Guaranteed within 2h │       │Push integrated report│
└──────────────────────┘       └──────────────────────┘

The two work together to form a complete memory pipeline: from Session Log → Daily Log → MEMORY.md, from real-time logging to long-term memory, with safeguards at every layer.


Conclusion

The construction of Memory Hub this time stemmed from a seemingly simple question: "Why does the Agent forget every day?" After deeper investigation, we found that this was not a single bug, but the compounding of systemic issues at three levels: architecture design, process mechanisms, and time zone handling.

The core idea of the final solution is defense in depth: not relying on any single mechanism, but ensuring through three layers of protection, task-triggered writes, Session checks, and Cron fallback, that no matter which layer fails, the next layer will fill the gap.

More importantly, we learned to check the data first, and then draw conclusions. From a Config Warning causing a misjudgment of the WeChat Plugin status, to discovering the time zone boundary bug, every problem was solved by directly inspecting the raw data in the Session JSONL files, rather than relying on surface-level error messages.

This system is currently running on UltraClaw, performing 13 cross-channel automated integrations daily, and awaiting the test of time.