DEV Community

Cover image for Correlation-Aware Memory Search: How I Taught OpenClaw to Remember What Matters
M. K.
M. K.

Posted on

Correlation-Aware Memory Search: How I Taught OpenClaw to Remember What Matters

OpenClaw Challenge Submission 🦞

This is a submission for the OpenClaw Challenge.

What I Built

I built a correlation-aware memory search plugin for OpenClaw — openclaw-correlation-plugin.

The problem: OpenClaw's memory returns keyword matches, but doesn't know that certain contexts always matter together. Search for "backup error" and you get hits on those words — but you also need "last backup time", "recovery procedures", and "recent changes". You have to think to ask for them.

The solution: A rule-based correlation layer. Define correlations once:
json
{
"id": "cr-error-001",
"trigger_context": "backup-operation",
"trigger_keywords": ["backup", "git push", "commit", "workspace"],
"must_also_fetch": ["last-backup-time", "backup-status", "recovery-procedures"],
"confidence": 0.9,
"relationship_type": "related_to",
"learned_from": "backup-verification-failed-silently"
}

When you search for a backup issue, the plugin matches this rule and suggests the additional searches automatically. Zero extra keystrokes.

How I Used OpenClaw

Plugin SDK: Simple but Tricky

The SDK makes tool registration easy — call api.registerTool() with your tools, parameters, and handlers. I built two tools:

  1. memory_search_with_correlation — Enriched memory search. Returns matches + suggested additional searches based on correlation rules.
  2. correlation_check — Debug tool. Test rule matches without performing searches.

Gotcha: The registration API requires { names: [...] } as the second argument, not just tool objects. Documented, but easy to miss.

Three Matching Modes

Mode Use for Tradeoff
auto (default) General use Keyword + context, normalizes hyphens/underscores
strict Zero false positives Word-boundary only, may miss valid matches
lenient Fallback Fuzzy when nothing else matches

The auto mode's normalization is small but powerful: "backup operation" matches backup-operation rules.

Rule Lifecycle: CI/CD Borrowing

proposal → testing → validated → promoted → retired

Rules follow a promotion pipeline. retired rules are kept but not matched — no data loss. This lesson came hard: I deleted rules that didn't work, losing their learned_from institutional memory. Now rules get retired, not trashed.

Confidence Scoring: Not "Higher is Better"

I set everything to 0.95 because "high confidence sounds better." Result: signal drowning. Every query returned the same high-confidence rules, burying context-specific correlations.

The production model:

  • 0.95–0.99: Catastrophic if missed (config changes, gateway restarts)
  • 0.85–0.90: Reliable patterns (backup operations, error debugging)
  • 0.70–0.80: Useful with some false-positive risk (session recovery, git ops)

Zero Runtime Dependencies

The plugin has zero runtime dependencies — only esbuild and vitest for dev. A memory plugin that reads local files has no business pulling in transitive deps. Code is read-only: no filesystem writes, no network, no credentials. Passed security audit in March 2026.

Heartbeat Integration: The Killer Feature

On-demand correlation search is fine. Proactive surfacing is better. Every 5 heartbeats, a script scans the current work context and surfaces related memories before the agent thinks to ask. This is the difference between a search tool and a decision-support system.

Demo

Query: "backup error" with memory_search_with_correlation
json
{
"query": "backup error",
"matched_rules": [
{
"id": "cr-error-001",
"context": "backup-operation",
"additional_searches": ["last-backup-time", "backup-status", "recovery-procedures"]
},
{
"id": "cr-session-001",
"context": "error-debugging",
"additional_searches": ["recovery-procedures", "recent-changes", "similar-errors"]
}
],
"suggested_additional_searches": [
"recovery-procedures", "recent-changes", "similar-errors",
"last-backup-time", "backup-status"
]
}

Same query. 5 extra contexts. Zero extra keystrokes.

What I Learned

1. Two half-solutions beat greenfield

This plugin merged two earlier experiments: proper SDK lifecycle + rich matching. The code still supports dual formats from both (must_also_fetch and correlations). Sometimes synthesis > from-scratch design.

2. Confidence scores tier, don't max

0.95 for everything = useless. Tiered confidence prevents signal drowning. Only catastrophic correlations sit at the top.

3. Rules are organizational memory

The learned_from field captures why a rule exists. Deleting rules burns institutional knowledge. Retire, don't trash.

4. Proactive > reactive

On-demand search is reactive. Heartbeat integration is proactive. Every 5 heartbeats is the sweet spot: useful without token burn.

5. Check ESM/CommonJS compatibility first

A dependency went ESM-only while the gateway uses CommonJS require(). Result: ERR_REQUIRE_ASYNC_MODULE, memory system disabled. Fix: local embeddings via Ollama. Always check module system before upgrading.

6. Know when NOT to correlate

Anti-patterns: 1:1 relationships (write a script instead), generic keywords like "help" or "status" (creates noise). Correlation rules are for probabilistic relationships — real but not guaranteed.


Repo: github.com/ether-btc/openclaw-correlation-plugin

License: MIT

OpenClaw Plugin Registry: correlation-memory (v2.1.0)

Top comments (0)