openclaw-memory-darwin
v0.1.0
Published
OpenClaw memory-slot plugin backed by darwin-memo's outcome-settled ledger
Maintainers
Readme
openclaw-memory-darwin
Outcome-settled agent memory for OpenClaw, backed by
darwin-memo's ledger. Instead of anyone curating which
lessons are good, every memory_recall answer opens a ticket in the ledger, and the ticket is
settled automatically from the run's measured outcome (agent_end success or failure). Lessons
that keep steering runs to success accumulate energy and survive; lessons that keep being recalled
into failing runs lose energy and die. Selection pressure replaces curation.
This plugin claims OpenClaw's exclusive memory slot (replacing the built-in
memory_search/memory_get tools and prompt section) and provides:
- Tools:
memory_recall(query),memory_store(question, answer, source?),memory_forget(entryId) - Hook:
agent_endsettles every open ticket for the ending session - Service: periodic
ledger tick(upkeep, deaths, consolidation, ticket expiry) - Prompt section: tells the agent to consult memory before risky/recurring decisions
Zero runtime npm dependencies; the raw TypeScript entry is loaded in-process by the OpenClaw
plugin loader (jiti). All ledger operations shell out to the darwin-memo CLI, which prints one
JSON object per call.
Requirements
- OpenClaw >= 2026.3.24
- The
darwin-memoCLI (the Python bridge). Either onPATHasdarwin-memoor configured viacommandwith an absolute path, e.g.~/darwin-memo-clibridge/.venv/bin/darwin-memo.
Install
Linked (development, recommended while iterating):
openclaw plugins install --link /path/to/openclaw-memory-darwinFrom npm (once published):
openclaw plugins install openclaw-memory-darwinInstalling a kind: "memory" plugin automatically claims the memory slot and disables the other
memory plugins (memory-core, memory-lancedb). Restart the gateway after install/config changes.
Configuration (~/.openclaw/openclaw.json)
{
"plugins": {
"slots": { "memory": "openclaw-memory-darwin" },
"entries": {
"openclaw-memory-darwin": {
"enabled": true,
"config": {
"command": "/Users/you/darwin-memo-clibridge/.venv/bin/darwin-memo",
"memoryPath": "/Users/you/.openclaw/memory/darwin/memory.json",
"resourceScale": 1.0,
"successDelta": 1.0,
"failureDelta": -1.0,
"tickIntervalHours": 24,
"commandTimeoutMs": 15000
}
}
}
}
}All config keys are optional; defaults below.
| Key | Default | Meaning |
| --- | --- | --- |
| command | "darwin-memo" | darwin-memo executable (PATH name or absolute path) |
| memoryPath | <stateDir>/memory/darwin/memory.json | Ledger file; created by darwin-memo on first use |
| resourceScale | 1.0 | resource_scale passed to every ledger call (scales settle deltas) |
| successDelta | 1.0 | Delta applied to each open ticket when the run succeeds |
| failureDelta | -1.0 | Delta applied to each open ticket when the run fails |
| tickIntervalHours | 24 | Hours between background ledger tick runs; <= 0 disables |
| commandTimeoutMs | 15000 | Timeout per darwin-memo invocation (ms) |
<stateDir> is ~/.openclaw (or $OPENCLAW_STATE_DIR). Open tickets are persisted to
<stateDir>/memory/darwin/tickets.json (atomic writes), so they survive gateway restarts.
How settlement works
- The agent calls
memory_recall("how should I deploy X?"). The plugin runsdarwin-memo ledger <memoryPath> --scale <resourceScale> decide "<query>". If memory has nothing relevant it says so (no ticket). Otherwise the answer comes back wrapped in an escaped, clearly-delimited untrusted block, and the returnedticket_idis recorded against the current session key. - When the run ends, the
agent_endhook fires with a measuredsuccessboolean. Every open ticket for that session is settled:ledger settle <ticket> <successDelta|failureDelta> --detail "agent_end success=... durationMs=... error=...". Tickets are removed from the local book regardless of the settle result (the CLI reports{"settled": false}for unknown/expired tickets, which is logged). - The periodic tick applies upkeep: entries pay to live, starved entries die (with an obituary), stale tickets expire.
Honest limits
- A success boolean is a weak conserved resource.
agent_end.successmeasures "the run did not error", not "the advice was good". A lesson recalled into a run that succeeded despite it still gets paid. The signal is statistical: over many runs, consistently harmful lessons get more failure settlements than success ones and die. Sharper outcome measures (tests passed, task-level reward) would need a sharper settler. - Every open ticket of the session gets the same delta. There is no per-recall credit assignment within a run.
- Deltas are configurable, so the economy is only as honest as your config. Large
successDeltawith tinyfailureDeltaproduces grade inflation; symmetric defaults are deliberate. - Lessons that keep being recalled into failing runs die — even if the failure was someone else's fault. That is the intended pressure: memory that hangs around failure is, at best, not helping.
- Memory failures never kill an agent run: tool errors come back as tool results, hook errors are logged warnings.
Development
npm test # unit tests (node:test, type-stripped TS, no deps)
npm run e2e # drives the real darwin-memo CLI through the plugin's shell-out modulesSee VERIFICATION.md for the verification log against a real OpenClaw install.
darwin-memo: https://github.com/rogermsc/darwin-memo
