How the agents remember, and where each kind of knowledge lives. Read this before writing any agent, because the single most common way an agent system fails in front of a customer is forgetting something it was already told.
Hermes' memory is 2,200 characters.
~/.hermes/memories/MEMORY.md is a flat file of §-separated entries, capped by
memory.memory_char_limit: 2200 (plus USER.md at 1375), flushed every ~6 turns. That is roughly
four to six facts.
It will evict, and it evicts silently. So:
Nothing the system depends on may live in Hermes memory. It is a hot scratchpad for the current task, never a source of truth. Everything durable lives in Postgres, a git repo, or the Operator KB, and is retrieved rather than remembered.
An agent that relies on Hermes memory to know what it promised a client will, eventually and unpredictably, forget.
| # | Store | Holds | Lives in | Lifetime |
|---|---|---|---|---|
| 1 | Hot context | what this agent is doing right now | ~/.hermes/memories/ (2.2KB) |
minutes; evicts |
| 2 | Client truth | the dossier | client git repo | forever; client keeps it |
| 3 | Job state | stage, attempts, spend, timings | Postgres jobs, runs |
forever |
| 4 | The conversation | every message either way | Postgres client_messages |
forever |
| 5 | Institutional learning | what works, what clients reject | Operator KB (pgvector) | forever, correctable |
| 6 | Doctrine | agent specs, terms, voice guide | these docs, indexed into the KB | versioned in git |
Use for: the job currently in flight, the client currently being answered. Nothing else. Never put a promise, a price, a deadline or a client fact here. Write those to store 3 or 4 and read them back.
Already specified in agents/02-dossier.md. One file, cited, in the
client's own repo. Every factual claim any agent makes must trace to it. Diffable, so a change to
a client's hours is visible in history.
jobs (stage, gate_level, amounts, timestamps) and runs (per-stage attempts, duration, spend).
Already built. This answers "where is it and what has it cost", never "what did we say to them".
Nothing in the design stored what was said to a client. The Account Manager records revisions "verbatim" — but to where? An agent that re-asks a question the client already answered, or re-offers something they already declined, reads as a machine and undoes the whole point of the voice work.
client_messages
id, job_id, business_id,
direction -- in | out
channel -- email | sms
body -- verbatim, never summarised
sentiment -- for the unhappiness trigger
agent -- which agent sent it
in_reply_to
sent_at
Rules:
agents/08 calls the most valuable dataset in the system.Do not build a second knowledge base. projects/operator-kb/ already provides exactly what
this needs: hybrid retrieval (full-text + vector + IDF + age decay, RRF-fused, LLM reranked) over
pgvector, and — the part that matters — contradiction-aware push-back.
| Tool | Use here |
|---|---|
kb_search |
"how have we written a plumber's services page before?" |
kb_challenge |
before acting — "we tried this angle in June and the client rejected it" |
kb_correct |
a belief proved wrong; supersedes rather than deletes |
kb_confirm |
a belief proved right; raises confidence |
kb_challenge is the reason to use this rather than a vector store: it is the inverse of search,
it surfaces the demoted graveyard and correction reasons, and it is calibrated to stay silent when a
plan matches current practice. Applied here, it stops the copy agent cheerfully repeating an angle
that has already failed twice.
A new connector (connectors/site-factory.mjs, alongside brain/granola/github) feeds it:
Every agent calls kb_challenge before a consequential decision — an angle, a voice choice, an
upsell — and kb_confirm/kb_correct after the outcome is known. That closing of the loop is what
makes the system compound instead of repeating itself.
The nine agent specs, website-build.mjs (the commercial terms), and the AiSearch voice guide.
Humans read them in git; agents retrieve them through the KB. website-build.mjs stays the only
source of prices — an agent quoting a price from the KB instead of the file is a bug, because the
file is what the agreement renders from.
| Agent | Reads | Writes |
|---|---|---|
| Orchestrator | 3 | 3 |
| Dossier | onboarding pack, GMB, NIGHTSHIFT businesses |
2 |
| Research | 2, NIGHTSHIFT competitors, KB (search, challenge) |
5 (angles that worked) |
| Copy | 2, research, 4 (revision comments), KB (challenge) |
copy files, 5 |
| Build | copy, assets, 2 (contact block) | site, build-report.json |
| Machine QA | site, 2 | qa-machine.json |
| Editorial QA | site, 2, research, KB (last 10 rejection reasons) | qa-editorial.json, 5 |
| Account Manager | 4 (always, first), 2, 3 | 4, 2 (new facts), 5 (complaints) |
| Customer Success | 4 (full history), 3, health, NIGHTSHIFT ratings | 4, 5, health.json |
kb_correct keeps the graveyard, and the graveyard is
what makes kb_challenge work.