A persistent homelab operator that forgets is a goldfish. Brilliant for one turn, then blank. It investigates a disk alert beautifully, closes the ticket, and three weeks later it meets the same alert as a total stranger. No memory of the last time, no idea it already wrote a runbook for exactly this.
That was the problem I wanted to solve first. Long John (my AI engineer, the persona I introduced in Part 1) was always going to shell out to a capable agent harness. The harness can think. What it could not do, out of the box, was remember. So before I wired up the body (the alert webhook, the Telegram channel, the kill-switch), I built the brain.
This is not the only order you could do it in. Plenty of solid setups treat memory as a later optimisation, and that is a reasonable call. For my use, a long-running operator that I wanted to trust with my cluster, statelessness was the thing that would bite me, so memory was the piece I chose to get right first.
The need, in infra terms
Think about what a real on-call engineer carries around. Two things, roughly.
One is the runbook shelf. The written-down knowledge: how we do upgrades here, who to escalate to, what "normal" looks like on this node. Stable, curated, the stuff you onboard a new hire with.
The other is scar tissue. The undocumented memory of every 3am incident. The "oh, this again, it's always the Ceph rebalance" instinct. You cannot onboard someone into scar tissue. They earn it by being there when things broke.
A stateless agent has neither. Every session it shows up as a brilliant contractor on day one, no shelf and no scars. daimon-memory is my attempt to give Long John both, and to treat that as the system layer rather than a bolt-on you call when you remember to.
Three things memory holds
I split it into persona, protocols, and recall.
Persona is who Long John is. A senior DevOps engineer, opinionated, notify-first, allergic to cowboy changes. This gets injected at the start of every session so the agent does not drift into generic-assistant mode.
Protocols are the governance: how it works, when it escalates, what it touches read-only versus what needs a go-ahead from me. Also injected up front. This is the runbook shelf, the onboarding doc that never gets stale because it is loaded every single time.
Recall is the scar tissue. Past decisions, incidents, lessons, runbooks the agent itself distilled. This is the part that has to be searchable and relevant on demand, because you cannot inject a year of history into every prompt.
Why hybrid RAG, not just vectors
For recall I went with two retrieval paths fused together.
Postgres full-text search handles the literal stuff. If an incident mentions netplan or a specific node name like eregion, I want an exact keyword hit, not a vibes-based approximation. Full-text is precise and cheap and it does not hallucinate a near-match.
Qdrant handles the semantic side. "The node that won't come back after a clone" should surface the MAC-address incident even if none of those exact words match. Vectors are good at meaning, weaker at exact tokens.
Neither alone was enough for me. Keyword search misses paraphrase, pure vector search fumbles exact identifiers. So I fuse the two result sets and let the strong signals from each win. Belt and suspenders, which is about right for a memory you are going to act on.
At session start it injects persona plus protocols. Each turn it auto-recalls whatever past records are relevant to what is happening right now. The agent walks in already knowing who it is, how it operates, and what it has seen before.
Writes are a nudge, not a magic auto-save
Here is the part I got wrong before I got it right. I wanted writes to be automatic. Just save everything.
That gives you a junk drawer. Raw transcripts, no signal, retrieval that returns noise.
So curation is nudge-driven. Hooks remind the agent to save, and the agent writes distilled records: a decision with its reasoning, an incident with root cause, a lesson, a runbook. Short, structured, worth recalling later. The reminder is the mechanism. There is a session-end backstop, but I learned not to lean on it, because it only reminds, it does not write. The real backstop is the per-turn nudge while the context is still warm. Skip that and the lesson evaporates with the session.
The honest version: memory you can approach a dozen ways, and several would work fine. This shape, system layer, hybrid retrieval, curated nudge-driven writes, is the one that fit my constraints and the trust level I wanted.
With the brain in place, the next job was governance: how much access this engineer gets, and what catches it when my trust turns out to be misplaced. That is Part 3.