<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Documentation on Bradley Fidler</title>
    <link>https://brfid.github.io/tags/documentation/</link>
    <description>Recent content in Documentation on Bradley Fidler</description>
    <generator>Hugo -- 0.156.0</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 21 Feb 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://brfid.github.io/tags/documentation/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Using CHANGELOG.md as LLM session memory</title>
      <link>https://brfid.github.io/posts/changelog-as-llm-memory/</link>
      <pubDate>Sat, 21 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://brfid.github.io/posts/changelog-as-llm-memory/</guid>
      <description>&lt;p&gt;Most LLM assistants don&amp;rsquo;t maintain memory between sessions. The standard workaround — a large &lt;code&gt;CLAUDE.md&lt;/code&gt; or &lt;code&gt;AGENTS.md&lt;/code&gt; with everything in it — breaks down quickly. What&amp;rsquo;s more, it duplicates other content in your repo, growing the documentation maintenance surface without adding value.&lt;/p&gt;
&lt;p&gt;Lately I avoid this problem by treating &lt;code&gt;CHANGELOG.md&lt;/code&gt; as my LLM&amp;rsquo;s memory — specifically the &lt;code&gt;[Unreleased]&lt;/code&gt; section from the format standardized by &lt;a href=&#34;https://keepachangelog.com/&#34;&gt;Keep a Changelog&lt;/a&gt;, which becomes the primary mutable state document.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Most LLM assistants don&rsquo;t maintain memory between sessions. The standard workaround — a large <code>CLAUDE.md</code> or <code>AGENTS.md</code> with everything in it — breaks down quickly. What&rsquo;s more, it duplicates other content in your repo, growing the documentation maintenance surface without adding value.</p>
<p>Lately I avoid this problem by treating <code>CHANGELOG.md</code> as my LLM&rsquo;s memory — specifically the <code>[Unreleased]</code> section from the format standardized by <a href="https://keepachangelog.com/">Keep a Changelog</a>, which becomes the primary mutable state document.</p>
<h2 id="why-it-works">Why it works</h2>
<p><a href="https://keepachangelog.com/">Keep a Changelog</a> defines a format most LLMs recognize on sight: a fenced <code>[Unreleased]</code> block at the top, dated releases below. Most LLMs recognize the convention: <code>[Unreleased]</code> is active work, dated entries are history.</p>
<p>That maps directly onto what you need for session continuity:</p>
<ul>
<li><strong><code>[Unreleased]</code></strong> — mutable, updated every session. Current state, active priorities, blockers, decisions pending. The model reads this first.</li>
<li><strong>Dated entries</strong> — append-only history. Evidence that decisions happened and why. The model reads these to reconstruct context if it needs depth.</li>
</ul>
<p>The AGENTS.md (or CLAUDE.md) file becomes stable configuration: conventions, file paths, source-of-truth map. It changes rarely. The CHANGELOG takes on everything that does change.</p>
<h2 id="the-session-start-instruction">The session start instruction</h2>
<p>One line at the top of <code>AGENTS.md</code> is enough:</p>
<pre tabindex="0"><code>Read CHANGELOG.md [Unreleased] at session start.
</code></pre><p>From there the model knows where it is, what&rsquo;s in flight, and what to do next — without re-explanation.</p>
<h2 id="what-goes-in-unreleased">What goes in [Unreleased]</h2>
<p>I use explicit subsections:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="gu">## [Unreleased]
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Current State
</span></span></span><span class="line"><span class="cl">One-paragraph snapshot. Where things stand right now.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Active Priorities
</span></span></span><span class="line"><span class="cl">Ordered list of what needs to happen next.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### In Progress
</span></span></span><span class="line"><span class="cl">What the model started in the current session.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Blocked
</span></span></span><span class="line"><span class="cl">Anything waiting on external action.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Decisions Needed
</span></span></span><span class="line"><span class="cl">Open questions the model should surface, not resolve unilaterally.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### Recently Completed
</span></span></span><span class="line"><span class="cl">What just shipped. Moves to a dated entry on the next commit.
</span></span></code></pre></div><p>The model updates <code>[Unreleased]</code> at the end of each session. The next session reads it cold and picks up cleanly.</p>
<h2 id="what-this-is-not">What this is not</h2>
<p>This is not a replacement for good project documentation. Architectural decisions, integration details, and source-of-truth maps still belong in stable docs. The changelog is the <em>session state layer</em>, not the full context layer.</p>
<p>It also does not solve the problem of context window limits on large projects. It reduces the cost of context: the model loads a small, structured, current-state document instead of scanning a stale megafile.</p>
<h2 id="result">Result</h2>
<p>Sessions are shorter to start, more reliable to hand off, and easier to audit. The changelog does the work it was always supposed to do — track what changed and when — and the LLM does less redundant orientation work each time.</p>
<p>The format is well-understood, self-describing, and version-controlled. If you&rsquo;re already using Keep a Changelog, the only addition is a discipline: update <code>[Unreleased]</code> at the end of each session.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
