AI Agent Has Amnesia. Mine Keeps Receipts Alexander Panasenko released KYB v0.3.3 on October 27, 2026 (commit 06f63b5), an open-source Git-backed shared memory store for coding agents that keeps versioned records with active, archived and retracted lifecycle states instead of append-only Markdown notes. Panasenko built KYB after finding that Claude Code, OpenAI Codex and Google Antigravity sessions would rediscover older notes and spend hours pursuing approaches already rejected, and he states he has run no controlled benchmark comparing agents with and without KYB. The tool exposes the same records through a CLI, an HTTP API and Model Context Protocol support, and deliberately does not store hidden model reasoning or archive whole conversations. Your AI Agent Has Amnesia. Mine Keeps Receipts. Months of shared memory across Claude, Codex and Antigravity — versions, retractions, and why append-only notes keep failing TL;DR. Scattered Markdown notes kept sending my agents down paths we had already rejected. I built a shared Git-backed store KYB with versioned records and lifecycle states — active, archived, retracted. Query current state, history, or a time slice separately; replace wrong text instead of appending; separate finished work from wrong knowledge. Pinned to KYB v0.3.3, no controlled benchmarks — mechanisms and field notes below. Before KYB, my coding agents already had memory: Markdown files scattered across different places. The flaw showed up whenever another agent returned to a workspace, found an older note, and mistook it for the active plan. In my experience, an agent would sometimes spend hours pursuing an approach we had already investigated and rejected. The file still held a perfectly reasonable case for the old approach, while the decision to abandon it lived somewhere else. I am Alexander Panasenko, the author of KYB Know Your Business , so I have a stake in this story: it is my open-source project. This is an account of my engineering experience with Claude Code, OpenAI Codex, and Google Antigravity from summer through October 2026. The text, its translation, and the diagrams were prepared with AI assistance, based on my own experience, the public source code, and saved development records. A fresh session does not automatically inherit the conversation that just ended. A human had to step in and explain which file still mattered, why we changed course, and where the outcome was recorded. An obvious temptation is to write one more summary note, but that note needs remembering too: without updates, it goes stale like the rest. So here is the question this piece addresses: how do you preserve operational knowledge across sessions without letting an outdated note send the next agent down a path you already abandoned? My short answer is to save a little, with versions and lifecycle state, and keep three things apart: what is true now, what was recorded then, and how an attempt ended. The rest of this piece shows where each boundary came from. The mechanics below are pinned to the public KYB v0.3.3 https://github.com/alex09x/kyb/releases/tag/v0.3.3 release from October 27, 2026 commit 06f63b5 . The episodes below keep their dates: new features are not attributed to old versions, and the current main branch may differ. Our internal records are not public. I have not run a controlled comparison of agents with and without KYB, so the hours lost to stale notes are my personal recollection, not a measured saving after adoption. Why Files Were Not Enough In hindsight, the problem had three parts. First, there was no single shared entry point: notes lived in different places, and none was canonical across sessions. Second, a note had no explicit lifecycle state: a file describing a rejected plan looked just like one describing the active plan. Third, separate files do not by themselves establish which version of a decision is authoritative: even when notes are already tracked in Git, an agent reading a file in a working tree or a neighboring note cannot tell without a separate check whether that text superseded an earlier approach or was superseded later. My first real fix was simple: a shared service for operational facts, incidents, and tasks that every session could reach. Its first interface was a CLI on top of an HTTP API; agents know how to run commands, and that was enough to start. Later, the server gained Model Context Protocol MCP support so agents could call its tools directly. The CLI, HTTP API, and MCP all lead to the same records: three doors into one room, not three separate memories. What KYB did not become matters as much. It does not save hidden model reasoning or archive whole conversations. A record exists only when a human or agent explicitly saves it: knowledge under a stable key, an incident with detection and outcome, or a task with owner and status. Each record is a Markdown file in a Git repository. The search index is built on top and can be rebuilt; the repository stays canonical. I chose small, verifiable records over an automatic chat archive on purpose: an archive has everything, but finding the active conclusion in it is as hard as in a pile of files. One more distinction: the public repository holds the engine, while our working records live in a separate internal store. Installing KYB gives you your own store under your own access rules, with none of our notes. What to Record So Nobody Repeats a Rejected Path The shared server solved place, not content. Pour the same old notes into a database and search just finds stale text faster. So the next question was: what should survive a session? The most useful record usually answers a question source code cannot: why was it built this way? Code shows the chosen implementation, not which options were tried, where they fell short, or which constraint decided the outcome. Without that, the next agent may carefully rebuild a rejected design while sincerely believing it is an improvement—exactly my original problem. Material therefore falls into three kinds. Knowledge is a state or rule worth returning to: a service’s role, an interface agreement, a way to verify configuration. An incident is a problem that happened: symptom, impact, how to tell whether it continues, and how it ended. A task is work to be done, or the reason it was closed. The split keeps you from confusing an intention with a fact, or a finished attempt with an active recommendation. Take an example record about choosing a message queue. “We use option B” says too little. The next agent does not need to obey an old conclusion blindly; it needs to tell whether the conditions behind it still hold. I would write such a record roughly like this a template, not a real benchmark : Decision: Use option B for this workload. Reason: Option A failed requirement X under conditions Y. Verification: Link to test, configuration, or report with revision SHA. Revisit if: X or Y changes. Related: Task key where the options were compared. The “Revisit if” line turns an old decision from a prohibition into a condition: if X or Y has changed, revisiting is legitimate, and the agent does not have to guess whether the record expired. The same logic produced habits I now treat as part of the record. A claim without a source soon becomes one more text asking to be trusted, so note how and when a fact was checked: not “the API listens on 9090,” but “at revision X, checked the service-api listener, port 9090.” Before creating a record, search for an existing key; the same knowledge under two names recreates the old chaos inside the new system, and Git will not clean it up. Hunches and long logs of competing hypotheses belong in an open task or incident, not standing knowledge. Secrets do not belong in the store at all; a pointer to where an authorized person or tool can fetch them suffices. In v0.3.3, there is also a guard against silently losing tags: rewriting a task or incident keeps any tags the write omits. An explicitly empty list clears them. This is a narrow rule for metadata, not a partial update of any record: replacing the knowledge under an existing key still requires keeping the full current text. One Port, Different Questions Even a clean record serves different questions. In a toy example, Monday’s entry records that service-api listens on port 8080 . On Wednesday, the service moves to 9090 , and the record is updated under the same key. “Where should I connect right now?” and “What was recorded on Monday?” need different answers, and both are fair questions. Overwrite the row without history and Monday’s answer is gone. Return every version without dates or states and an agent may pick the wrong one. Git offers a third path: the key stays the same while its edits form a history. Still, history alone answers nothing until you say which slice you need. Each KYB query mode matches one question. A regular query searches current state: “where do I connect now.” --history searches matching text across all saved content versions, including the current one; kyb history