Memory Federation

Your agents learn as a team: what one agent proves useful federates to the rest β€” automatically, signed, and gated on maturity. And agents remember proactively: state a durable preference mid-chat and the agent saves it, tells you so, and applies it from the next turn.

# a memory note, created by hand (agents create them for you mid-chat)
mur notes create reply-language -d "Reply language" --kind rule <<< "Always reply in zh-TW."

# see what an agent's snapshot delivered
mur agent snapshot show my-agent

# preview what WOULD federate under the current maturity floor
mur agent snapshot pull my-agent --dry-run

# review the notes your agents propose to share
mur session out

Proactive remember

Every agent carries a built-in remember tool. When you state a durable preference ("from now on…"), correct the agent a second time on the same thing, or reveal a lasting environment fact, the agent saves it as an agent-local Draft note β€” and announces it in one line, in your language, with /forget as the undo.

Hard rules, enforced by the tool and its prompt contract: never secrets, never one-off details, never anything sourced from tool output rather than your own words.

# ~/.mur/config.yaml
memory:
  capture: auto_announce   # ask | auto_announce (default) | off

ask makes the agent confirm before saving; off removes the tool entirely. A per-agent Deny rule on the tool always wins.

Inside mur agent cli (or murmur), memory is three slash commands:

CommandAction
/remember [--kind rule|fact] <text>Save an agent-local Draft note yourself
/memoriesEvery note this agent can see, labeled by where it lives
/forget <name>Delete a note by name

Note kinds and decay

Notes come in two kinds with matched decay curves:

kindmeaninghalf-life
rulebehavioral guidance β€” iterate fastΓ—0.5
factenvironment truth β€” stays trueΓ—2.0

Both ride the same maturity lifecycle as skills (Draft β†’ Emerging β†’ Stable β†’ Canonical), promoted by real usage and demoted by disuse. Factors are configurable under skill.lifecycle (note_rule_half_life_factor, note_fact_half_life_factor).

A reserved injection slot (retrieval.reserved_note_slots, default 1) keeps a fresh note from being permanently outbid by mature skills β€” "takes effect immediately" stays true.

Federation: visibility follows scope, propagation follows maturity

A new note is visible to the agent that captured it immediately. Reaching other agents requires maturity:

  1. Each agent's sleep cycle drops an Ed25519-signed snapshot request into the daemon's inbox β€” one small file, no subprocess, no direct central-store access.
  2. The daemon β€” outside every agent sandbox β€” verifies the signature against the agent's on-disk public key, then assembles the curated skills (lifecycle at or above federation_snapshot.min_lifecycle, default stable) into that agent's local knowledge_cache/.
  3. The agent's loader injects from the cache with precedence agent-local β†’ cache β†’ global.
# ~/.mur/config.yaml
federation_snapshot:
  poll_secs: 30              # daemon sweep interval
  request_max_age_secs: 600  # replay window
  min_lifecycle: stable      # maturity floor for federation

Requests are single-shot (consumed on success and rejection alike), freshness-windowed, and name-validated before any path is touched. The trust anchor is the agent's own public key: sandbox write-isolation means no agent can plant a key in another agent's home.

Sharing is a decision, not a default

Maturity is one route to other agents; the other is you. Every remember also files a proposal into your review lane β€” the note itself stays agent-local until you decide:

mur session out
# 1 memory proposal(s) from agents:
#   [coach] reply-in-zh-tw (rule, βœ“ signed) β€” Reply language
#   Share `reply-in-zh-tw`?  βœ“ Accept Β· ⏭ Skip Β· βœ— Dismiss

Accept makes the note global β€” every agent's loader sees it. Dismiss consumes the proposal while the agent keeps its private copy. Re-remembering the same note replaces its pending proposal instead of stacking duplicates. Nothing an agent inferred reaches other agents without usage-earned maturity or this explicit gate.

Signed both ways

The pull leg was always signed; the outbound leg is too. Evidence signals and memory proposals are signed with the agent's identity key at the moment they leave its home, and ingest verifies both who said it (signature against agents/<name>/identity.pub) and that it may say it there (scope check) before anything is applied. The review lane labels each proposal βœ“ signed, unsigned (legacy), or βœ— INVALID SIGNATURE β€” an invalid signature is never acceptable.

Unsigned drops from older versions are tolerated by default; set MUR_SIGNAL_REQUIRE_SIG=1 to enforce signatures everywhere.

Inspecting memory

mur notes list --maturity draft   # what's been captured lately
mur notes show reply-language     # body, kind, maturity (counts as a retrieval)
mur notes search "deploy steps"   # ranked, records usage for the lifecycle