| name | spiritwriter |
| description | Local-first agent memory — content-addressed shards, encryption, entity resolution, provenance. No third-party services. Your intents and memories stay on your machine. |
| version | 0.1.0 |
| homepage | https://github.com/aaronmarkham/spiritwriter-core |
| user-invocable | false |
| metadata | {"openclaw":{"emoji":"🧠","os":["darwin","linux","win32"],"requires":{"anyBins":["python3"]},"install":[{"id":"spiritwriter","kind":"pip","label":"Install spiritwriter","package":"spiritwriter"},{"id":"spiritwriter-sealed","kind":"pip","label":"Install with sealed-box encryption (NaCl)","package":"spiritwriter[sealed]"},{"id":"spiritwriter-full","kind":"pip","label":"Install everything (sealed + IPFS network)","package":"spiritwriter[sealed,network]"}]}} |
spiritwriter — Agent Memory That Stays Local
spiritwriter was built because agent memory shouldn't cost $100/day in token burn, and your intents shouldn't flow through third-party services. It gives your agent structured, encrypted, content-addressed memory — stored locally, recalled efficiently, with a full provenance chain.
Battle-tested in production since February 2026 with OpenClaw agents.
Why This Exists
Most AI memory systems store raw conversation text and replay it into context. That's expensive (hundreds of tokens per recall) and sends your intents through external services. spiritwriter stores structured atoms — entity/key/value triples — so your agent recalls only what it needs. A 500-token conversation chunk becomes a 50-token shard with the same information.
No API keys. No cloud services. No telemetry. Your memory, your machine. IPFS distribution is opt-in for multi-agent sharing; core memory is always local.
Getting Started with OpenClaw
spiritwriter is a Python library, not a CLI tool. Your agent uses it via Python API calls — typically in hooks or agent code that runs alongside your OpenClaw session.
pip install spiritwriter
from spiritwriter.fabric.shard import MemoryShard, ShardAtom, AtomKind
from spiritwriter.fabric.store import ShardStore
store = ShardStore("~/.openclaw/shards")
spiritwriter works with whatever vector DB your OpenClaw agent already uses. If you also install MemPalace, spiritwriter auto-discovers it and adds semantic search over shards — see the mempalace integration skill.
What Your Agent Gets
Structured memory (not raw text dumps)
from spiritwriter.fabric.shard import MemoryShard, ShardAtom, AtomKind, DecayClass
from spiritwriter.fabric.store import ShardStore
store = ShardStore("~/.openclaw/shards")
shard = MemoryShard(
atoms=[
ShardAtom(text="Project uses FastAPI for the web layer",
kind=AtomKind.FACT, entity="myproject",
key="web_framework", value="FastAPI"),
ShardAtom(text="Never deploy on Fridays",
kind=AtomKind.CONVENTION, entity="team",
key="deploy_policy", value="no-friday-deploys"),
ShardAtom(text="Switched to PostgreSQL for ACID guarantees",
kind=AtomKind.DECISION, entity="myproject",
key="session_backend", value="postgresql"),
],
scope="project:myproject",
origin="my-agent",
decay_class=DecayClass.STABLE,
)
ref = store.put(shard)
Recall only what's needed (token efficiency)
context = shard.hydrate_context()
print(shard.token_estimate)
project_shards = store.by_scope("project:myproject")
store.set_ref("project-myproject", shard.shard_id)
latest = store.resolve_ref("project-myproject")
Encryption (your memory, not theirs)
from spiritwriter.fabric.crypto import generate_job_key
key = generate_job_key()
encrypted = store.encrypt_and_store(shard, key)
from spiritwriter.fabric.sealed import generate_owner_keypair, seal_shard
keypair = generate_owner_keypair()
sealed = seal_shard(shard, keypair.public_key)
Entity resolution — who is "Max"?
from spiritwriter.fabric.canonicalize import CanonicalRegistry, CanonicalSchema
schema = CanonicalSchema(
name="person",
ess_fields=["name", "relationship"],
fuzzy_fields={"name": 0.85},
)
with CanonicalRegistry("~/.openclaw/entities.db", schema) as registry:
result = registry.resolve({"name": "Max", "relationship": "son"})
registry.upsert({"name": "Max", "relationship": "son"},
result, source_name="chat", source_id="session-1")
result = registry.resolve({"name": "Max", "relationship": "son"})
Provenance (tamper-evident audit trail)
from spiritwriter.fabric.emitter import TraceEmitter, verify_chain
tracer = TraceEmitter(run_id="session-42", agent_id="my-agent",
out_path="~/.openclaw/trace.jsonl")
tracer.shard_created(shard.shard_id, shard.scope, len(shard.atoms))
assert verify_chain(tracer.get_events())
With MemPalace
If MemPalace is also installed, spiritwriter auto-discovers it and adds semantic search over your shards. MemPalace handles retrieval (vector search, BM25 reranking), spiritwriter handles trust (encryption, provenance, entity resolution). See the mempalace integration skill for details.
pip install spiritwriter[mempalace]
Decay Classes
Shards have a lifecycle — not everything lives forever:
| Class | TTL | Use for |
|---|
PERMANENT | Never | Identities, architecture decisions |
STABLE | 90 days | Project context, learned patterns |
ACTIVE | 14 days | Current tasks, active monitoring |
SESSION | 24 hours | Debugging context, temp state |
CHECKPOINT | 4 hours | Pre-flight state saves |
pruned = store.prune_expired()
License
Apache 2.0