type: vulnerability

name: OpenClaw NPM Update Wipes Memory Patches

description: Every time `npm update -g openclaw` or `npm install -g openclaw` is run on the Mac Mini, the extension directory at ~/.npm-global/lib/node_modules/openclaw/extensions/memory-lancedb/ is overwritten by the package manager. This wipes three critical customizations: (1) the LanceDB dimension patch in config.ts that changes text-embedding-3-small from 1536 to 768 dims to match nomic-embed-text via Ollama, (2) the enhanced index.ts with hybrid retrieval, smarter auto-capture, memory consolidation, and expanded recall, and (3) the node_modules/@lancedb/lancedb sub-package which npm prunes from extension directories. After an unpatched update, AIVA's memory plugin either fails to load entirely (missing @lancedb/lancedb) or silently creates a new 1536-dim LanceDB table, making all existing 768-dim memory vectors unreachable and causing a fresh-slate amnesia on next gateway start.

severity: high

impact: Complete loss of all patched enhancements. Memory plugin fails to start or silently creates wrong-dimension vector table. AIVA loses all recalled memories (768-dim vectors become incompatible with 1536-dim table). At scale with 1000+ SubAIVAs, a fleet-wide OpenClaw update without the patcher applied to each node causes fleet-wide memory loss across all customer SubAIVA instances.

mitigation: Run scripts/aiva_memory/openclaw_post_update.js immediately after every OpenClaw npm update, before restarting the gateway or testing any memory functionality. The script reinstalls @lancedb/lancedb, deploys enhanced_config.ts and enhanced_index.ts from ~/.openclaw/patches/, verifies the Ollama text-embedding-3-small alias, restarts the gateway, and health-checks the endpoint.

scale_risk: At 1000+ SubAIVA scale, OpenClaw updates CANNOT be individual npm calls — they must be orchestrated via fleet deployment pipeline (Ansible/SSH batch or Docker image rebuild). Without fleet management, a single `npm update` on one node is fine, but a mass update event (e.g., critical security patch) would simultaneously amnesiac all SubAIVAs. Fleet pipeline must: (1) pull new image to staging, (2) run patcher in staging, (3) verify memory round-trip, (4) roll out node-by-node with canary gating.


name: Auto-Recall Poisoning Bug — shouldCapture Skips <relevant-memories> Messages

description: OpenClaw's memory-lancedb plugin has an auto-recall/auto-capture interaction bug. When autoRecall is enabled, the plugin prepends a <relevant-memories>...</relevant-memories> XML block to the user message before it reaches the LLM. When autoCapture is also enabled, the plugin's shouldCapture() function subsequently sees the modified message (now starting with '<relevant-memories>') and silently skips it because the heuristic detects it is a system-injected context block, not genuine user content. The result: any message that triggers auto-recall will NEVER be auto-captured. The user's actual new statement (which follows the <relevant-memories> block) contains genuinely capturable information but is never stored because shouldCapture exits early on the XML prefix. This is a silent failure — no error, no warning, no Telegram alert. Over time, AIVA accumulates fewer and fewer new memories as more messages trigger recall, creating a feedback loop where recall gets richer (many existing memories) but capture dies off.

impact: AIVA memory system slowly stops learning new information in active conversations. Users who talk to AIVA frequently (high recall rate) are most affected. Memory appears to work (recall retrieves old facts) but no new facts are stored. Detected only by querying memory_stats and noticing capture_count stagnating while session_count rises.

mitigation: Enhanced index.ts addresses this by stripping <relevant-memories>...</relevant-memories> blocks from the message before passing to shouldCapture(). Must deploy enhanced_index.ts via the post-update patcher to activate fix. Also add memory_stats to AIVA's weekly cron report to catch stagnation early.

detection: Run `memory_stats` tool. If sessions > 10 and captures < sessions/3 and recall_count > sessions/2, the poisoning bug is likely active.


type: axiom

statement: After every OpenClaw npm update, run the post-update patcher before restarting the gateway or testing any memory functionality.

rationale: npm update overwrites extension source files and prunes extension-local node_modules. The LanceDB patch (768-dim), enhanced index.ts, and @lancedb/lancedb itself are all wiped. Running the gateway before patching either crashes (missing @lancedb/lancedb) or silently creates a 1536-dim table that makes all existing 768-dim memories unreachable.

evidence: Session 80 established the 1536->768 patch. MEMORY.md explicitly states 'LanceDB patches must be reapplied after any OpenClaw npm update.' OPENCLAW_MASTERY_RESEARCH.md §11.2 lists 5 patches that must survive every update.

applies_to: Mac Mini (AIVA host), any SubAIVA Docker node running OpenClaw with memory-lancedb


statement: At scale (1000+ SubAIVAs), OpenClaw updates must be managed via fleet deployment pipeline, not individual npm updates on each node.

rationale: At 1 SubAIVA: running the post-update patcher manually is a 2-minute operation. At 1000 SubAIVAs: manual patching is 33 hours of work. At fleet scale, a critical OpenClaw security patch creates a race condition — leaving nodes unpatched (security risk) vs patching without the memory patcher (amnesia risk). Only a fleet pipeline solves both simultaneously.

evidence: Research reports/OPENCLAW_MASTERY_RESEARCH.md §12.2 identifies 'OpenClaw updates breaking patches' as MEDIUM severity operational risk with mitigation 'Pin versions; test updates in staging'. KG entity ENT-openclaw-vuln-001 quantifies the scale risk.

required_architecture: Fleet pipeline: (1) Build new Docker image with OpenClaw + patches baked in, (2) Validate on staging SubAIVA (memory round-trip test), (3) Rolling deploy node-by-node with canary gate, (4) Health check each node before proceeding

implementation_target: Phase 3 (Marketplace) of HYPER_VERTICAL_AGENT_PARADIGM.md


statement: Plugin extensions that modify vendor source files are fragile — prefer configuration-based customization or wrapper patterns.

rationale: Modifying files inside node_modules (even via a post-update patcher) is inherently fragile because: (1) npm is designed to overwrite them, (2) the modification must be re-applied after every update, (3) the modified files may have merge conflicts with upstream changes, (4) there is no diff tracking unless vanilla backups are maintained. The post-update patcher is a necessary mitigation for the current OpenClaw architecture, but the long-term solution is to move customizations upstream.

better_patterns: Fork memory-lancedb extension into ~/.openclaw/custom-extensions/ and register it as the active extension (avoids npm overwrite entirely)

better_patterns: Submit enhanced_index.ts and enhanced_config.ts as PRs to the OpenClaw project — if merged, no patching needed

better_patterns: Use OpenClaw plugin config to inject dimension settings rather than source patching (if the plugin exposes a vectorDims config key in future versions)

better_patterns: Build a Docker image with OpenClaw pre-patched as the base image for all SubAIVAs — npm is never run inside containers in production

current_state: The post-update patcher in scripts/aiva_memory/openclaw_post_update.js is the correct SHORT-TERM mitigation. Long-term target is Option 1 (custom extension fork) or Option 4 (Docker base image with patches baked in).