<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bertonha</title>
    <description>The latest articles on DEV Community by Bertonha (@geovanne_bertonha_ed5b251).</description>
    <link>https://dev.to/geovanne_bertonha_ed5b251</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2861731%2Ff93b4620-5c30-495d-ad90-b317f8cc4d6c.jpg</url>
      <title>DEV Community: Bertonha</title>
      <link>https://dev.to/geovanne_bertonha_ed5b251</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/geovanne_bertonha_ed5b251"/>
    <language>en</language>
    <item>
      <title>Why I chose plain Markdown over a database for AI agent memory</title>
      <dc:creator>Bertonha</dc:creator>
      <pubDate>Wed, 04 Nov 2026 01:35:58 +0000</pubDate>
      <link>https://dev.to/geovanne_bertonha_ed5b251/why-i-chose-plain-markdown-over-a-database-for-ai-agent-memory-ohf</link>
      <guid>https://dev.to/geovanne_bertonha_ed5b251/why-i-chose-plain-markdown-over-a-database-for-ai-agent-memory-ohf</guid>
      <description>&lt;p&gt;Every time I opened a new Claude Code session, I spent the first few minutes explaining my work again. Who the customer is. What we decided last week. How the weekly update should look. The agent was good at the task. It just knew nothing about the context around it.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://github.com/geovanneb/get-things-done" rel="noopener noreferrer"&gt;Get Things Done&lt;/a&gt;, an open-source, local-first work memory for Claude Code, Codex and GitHub Copilot. This post is about one design decision behind it: storing that memory as plain Markdown files instead of in a database.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "memory" means here
&lt;/h2&gt;

&lt;p&gt;Not model training. Not embeddings hidden behind an API. Memory here means &lt;strong&gt;reviewed context&lt;/strong&gt;: notes about your projects, the people you work with, past decisions and the formats you deliver, written down somewhere your agent can read before it starts a task.&lt;/p&gt;

&lt;h2&gt;
  
  
  The layout
&lt;/h2&gt;

&lt;p&gt;The whole workspace is a folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;work-memory/
├── profile/          Your working style and preferences
├── stakeholders/     People, organizations and expectations
├── context/          Projects, decisions, risks and terminology
├── context-updates/  Material and proposed memory changes
├── meetings/         Retained recordings and transcript versions
├── outputs/          Reusable deliverable templates
└── tasks/            Objectives, deliverables and execution logs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each file is Markdown with YAML frontmatter. Agents find it through files they already read: &lt;code&gt;CLAUDE.md&lt;/code&gt; for Claude Code, &lt;code&gt;AGENTS.md&lt;/code&gt; for Codex, &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; for Copilot. No MCP server, no proprietary memory API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Markdown
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Agents already read files well.&lt;/strong&gt; Coding agents are built to navigate a repository. A folder of well-named Markdown files is the shape of data they handle best, with no extra tool layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Humans can read and fix it.&lt;/strong&gt; If the agent has a wrong idea about a stakeholder, I open the file and correct it. No admin UI, no query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Git gives history for free.&lt;/strong&gt; Put the workspace in a private repo and every change to your context is a diff you can review or revert.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No lock-in.&lt;/strong&gt; If I switch from Claude Code to Codex tomorrow, the memory comes with me. It is just files.&lt;/p&gt;

&lt;h2&gt;
  
  
  The review step
&lt;/h2&gt;

&lt;p&gt;The most useful part turned out to be how memory gets updated. Meetings are the main input: you record or import one, it is transcribed locally (Whisper or SenseVoice, after a one-time model download), and an agent compares it with what the workspace already knows.&lt;/p&gt;

&lt;p&gt;The agent does not write to memory directly. It proposes changes, such as a new deadline, a changed decision or what a colleague expects, with the evidence from the transcript. You accept or reject each one. Only then does it become context for the next task.&lt;/p&gt;

&lt;p&gt;I did not want an agent quietly rewriting what it "knows" about my work. A review step keeps the memory something I trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hard parts
&lt;/h2&gt;

&lt;p&gt;Plain files are simple until two writers touch the same folder. Here the dashboard and the agent both edit the workspace, so a few things matter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Writes go through a temp file and a rename&lt;/strong&gt;, so a reader never sees a half-written file. This does not stop two writers from overwriting each other's changes, and the docs say so.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paths are validated at every service boundary&lt;/strong&gt;, including values from JSON request bodies, so a crafted name cannot escape the workspace folder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search uses an optional SQLite index derived from the files.&lt;/strong&gt; You can delete it at any time. The files stay the source of truth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The dashboard binds to 127.0.0.1.&lt;/strong&gt; Cloud agents still see what they read, which is worth being clear about.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Trade-offs
&lt;/h2&gt;

&lt;p&gt;Markdown is not free. Search across many files needs an index. Structured queries ("every decision about project X since September") are harder than in SQL. And there is no real locking between the agent and the dashboard.&lt;/p&gt;

&lt;p&gt;For a personal or small-team work memory, I think those costs are worth it. You own the data, you can read every byte of it, and any agent that can open a file can use it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @bertonha/getthingsdone
&lt;span class="nb"&gt;mkdir &lt;/span&gt;work-memory &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;work-memory
gtd init
gtd start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is also a desktop app for macOS and Windows on the &lt;a href="https://github.com/geovanneb/get-things-done/releases/latest" rel="noopener noreferrer"&gt;releases page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I would love feedback: what context do you still find yourself repeating to your agent? And if this approach is useful to you, a star on &lt;a href="https://github.com/geovanneb/get-things-done" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; helps other people find it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>productivity</category>
      <category>markdown</category>
    </item>
  </channel>
</rss>
