# How Munder Difflin Implements Persistent Memory for Agents: Architecture and Code Reference

> Discover how Munder Difflin achieves persistent memory for agents by storing notes in plain-text files and mining them into a searchable semantic index, MemPalace.

- Repository: [Chaitanya Giri/munder-difflin](https://github.com/chaitanyagiri/munder-difflin)
- Tags: architecture
- Published: 2026-08-22

---

**Munder Difflin stores agent notes in plain-text [`memory.md`](https://github.com/chaitanyagiri/munder-difflin/blob/main/memory.md) files under `hive/agents/<agent-id>/` and continuously mines them into a shared semantic index (MemPalace) every three minutes, enabling persistent, searchable long-term memory across sessions.**

Munder Difflin is an Electron-based multi-agent framework where **persistent memory for agents** is implemented through a dual-layer architecture combining local markdown files with a shared vector index. This article examines the source code implementation in `chaitanyagiri/munder-difflin`, detailing how the **MemoryManager** and **MemoryReflector** classes orchestrate durable knowledge storage and retrieval.

## The Dual-Layer Storage Architecture

Munder Difflin separates durable storage from searchable semantic memory. Each layer serves a distinct purpose in the persistence lifecycle.

### Local Agent Memory Files

Each agent maintains its own long-term notes in a plain-text [`memory.md`](https://github.com/chaitanyagiri/munder-difflin/blob/main/memory.md) file located at `hive/agents/<agent-id>/memory.md`. These files survive process restarts and serve as the **source of truth** for an agent’s accumulated knowledge. The system treats these as append-only logs that agents can read and write during their execution.

### The Shared MemPalace Index

To enable cross-agent semantic search, the application maintains a centralized vector database called the **MemPalace**. According to [`src/main/memory.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/memory.ts) lines 74-77, the `MemoryManager.palacePath()` method builds the palace location at `<harnessHome>/palace`, creating a shared "home" for the semantic index that all agents can query.

## The MemoryManager Class (src/main/memory.ts)

The `MemoryManager` runs in the main Electron process and acts as the bridge between local markdown files and the shared semantic index.

### CLI Discovery and Environment Injection

Before spawning agents, the manager resolves the external `mempalace` binary location. The `MemoryManager.bin()` method (lines 79-115) searches `$PATH` and common install locations—including `~/.local/bin/mempalace` on Linux/macOS and Windows `where mempalace`—to locate the CLI.

When an agent spawns, `MemoryManager.env()` (lines 39-44) injects two critical environment variables into the child process:

```typescript
{
  MEMPALACE_PALACE_PATH: <palace-path>,
  MEMPALACE_EMBEDDING_MODEL: <model>
}

```

This injection ensures that all CLI calls from the agent automatically target the correct shared palace without hardcoded paths.

### Continuous Mining Loop (Store)

Every three minutes (`MINE_INTERVAL_MS`), the manager scans `hive/agents/*/memory.md` for modification time changes. For any updated file, it executes the mining command via the `mineAgent` helper (lines 88-102 and 108-118):

```bash
mempalace mine <agentDir> --wing <agentId> --agent <agentId>

```

The mining process is **idempotent**; the CLI deduplicates entries, making re-mining safe. A ten-minute timeout protects against hung processes (lines 120-127). When the `MemoryReflector` updates a file, the changed `mtime` automatically triggers re-indexing on the next cycle.

### Semantic Search and Recall (Read)

The manager exposes two async helpers for retrieving information:

- **`search(query, {wing?, results?})`** – Executes `mempalace search` for semantic lookup across all agents (lines 80-85).
- **`wakeUp(wing?)`** – Executes `mempalace wake-up` to generate a short digest for session initialization (lines 87-92).

Both methods use the internal `runCli` helper (lines 46-71) to spawn the binary with the injected environment and enforce a 120-second timeout.

## Memory Maintenance and Condensing (src/main/reflect.ts)

Unbounded growth of [`memory.md`](https://github.com/chaitanyagiri/munder-difflin/blob/main/memory.md) files would eventually degrade performance. The **MemoryReflector** provides automatic compression to keep memory files manageable.

### The MemoryReflector Class

Running in the same main process as the `MemoryManager`, the `MemoryReflector` periodically parses each [`memory.md`](https://github.com/chaitanyagiri/munder-difflin/blob/main/memory.md), creates backups, and summarizes old sections using a headless Claude-Haiku call (lines 30-41). It then rewrites the file into a strict three-region format (lines 86-102):

1. **Pinned facts** – Critical information that must never be summarized.
2. **Condensed summary** – AI-generated compression of older sections.
3. **Recent verbatim sections** – The most recent entries kept in full.

### Automatic Re-indexing After Condensing

After the reflector writes the condensed file, the [`memory.md`](https://github.com/chaitanyagiri/munder-difflin/blob/main/memory.md) modification time updates. The `MemoryManager` mining loop detects this change on its next three-minute iteration and automatically re-indexes the updated content, ensuring the semantic search index remains synchronized with the compressed local storage.

## Lifecycle and Configuration

The persistence system initializes only when specific conditions are met. In [`src/main/index.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/index.ts) (lines 68-71), `MemoryManager.start()` verifies that:

- The `semanticMemory` user setting is enabled.
- The `mempalace` CLI binary is discoverable.
- The palace home directory exists.

The mining loop can be gracefully stopped with `memory.stop()`. User-tunable parameters—including `embeddingModel`, condensing intervals, and size triggers—reside in [`src/main/config.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/config.ts).

## Practical Implementation Examples

The following examples demonstrate how to interact with the persistent memory system programmatically.

### Creating an Agent with Persistent Memory

```typescript
import { spawn } from 'node:child_process';
import { MemoryManager } from './memory';

// Initialize with config-provided paths
const memory = new MemoryManager(
  () => config.harnessHome,
  () => ({ enabled: true, model: 'minilm' })
);
memory.start(); // Begins the 3-minute mining loop

// Spawn agent with palace environment injected
const proc = spawn('claude', ['--agent', 'my-agent'], {
  env: { ...process.env, ...memory.env() },
});

```

### Performing Semantic Lookups

```typescript
async function findRelevantNotes(query: string) {
  const result = await memory.search(query, { results: 10 });
  if (result.ok) {
    console.log('Search results:\n', result.output);
  } else {
    console.error('Search failed:', result.error);
  }
}

```

### Manual Memory Condensing

```typescript
import { MemoryReflector } from './reflect';

const reflector = new MemoryReflector(
  () => config.harnessHome,
  () => 'claude',
  () => memory.env(),
  () => ({
    enabled: true,
    intervalMs: 30_000,
    byteTriggerPct: 60,
    sectionTrigger: 40,
    recentKeep: 12,
    minBytes: 16_384,
  }),
  (e) => console.log('Reflector log:', e)
);

// Force immediate condensing for a specific agent
reflector.reflectNow('my-agent').then((res) => console.log(res));

```

## Summary

- **Munder Difflin** implements persistent memory for agents through a combination of local [`memory.md`](https://github.com/chaitanyagiri/munder-difflin/blob/main/memory.md) files and a shared **MemPalace** semantic index.
- The **MemoryManager** ([`src/main/memory.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/memory.ts)) orchestrates CLI discovery, environment injection, and a continuous mining loop that indexes changes every three minutes.
- Agents communicate with the palace via injected environment variables (`MEMPALACE_PALACE_PATH` and `MEMPALACE_EMBEDDING_MODEL`).
- The **MemoryReflector** ([`src/main/reflect.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/reflect.ts)) prevents unbounded file growth by condensing old entries into a three-region format and triggering automatic re-indexing.
- All search and recall operations use the external `mempalace` CLI with enforced timeouts for stability.

## Frequently Asked Questions

### Where does each agent store its persistent notes?

Each agent writes to a plain-text [`memory.md`](https://github.com/chaitanyagiri/munder-difflin/blob/main/memory.md) file located under `hive/agents/<agent-id>/memory.md` within the hive folder. This file serves as the durable, human-readable source of truth for the agent’s long-term knowledge.

### How often does Munder Difflin index new memory entries?

The `MemoryManager` scans for changes every three minutes (`MINE_INTERVAL_MS`). Any [`memory.md`](https://github.com/chaitanyagiri/munder-difflin/blob/main/memory.md) file with a modified timestamp since the last successful mine is re-indexed into the shared MemPalace using the `mempalace mine` command.

### What prevents the memory files from growing indefinitely?

The `MemoryReflector` class periodically compresses [`memory.md`](https://github.com/chaitanyagiri/munder-difflin/blob/main/memory.md) files by summarizing older sections via Claude-Haiku and rewriting the file into a structured format with pinned facts, condensed summaries, and recent verbatim entries. This condensing runs automatically based on configurable byte and section triggers.

### How do agents discover the shared semantic memory index?

When spawning an agent, the main process calls `MemoryManager.env()`, which injects the `MEMPALACE_PALACE_PATH` and `MEMPALACE_EMBEDDING_MODEL` environment variables into the child process. This ensures the agent’s CLI calls automatically target the correct shared palace location without requiring manual path configuration.