<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Documentation - Tag - Tracy Atteberry</title><link>https://tracyatteberry.com/tags/documentation/</link><description>Documentation - Tag - Tracy Atteberry</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><managingEditor>tracy@magicbydesign.com (Tracy Atteberry)</managingEditor><webMaster>tracy@magicbydesign.com (Tracy Atteberry)</webMaster><lastBuildDate>Wed, 20 May 2026 00:00:00 +0000</lastBuildDate><image><url>https://tracyatteberry.com/images/feed-icon.jpg</url><title>Documentation - Tag - Tracy Atteberry</title><link>https://tracyatteberry.com/tags/documentation/</link></image><atom:link href="https://tracyatteberry.com/tags/documentation/" rel="self" type="application/rss+xml"/><item><title>Documentation next: Habits that survive AI-assisted development</title><link>https://tracyatteberry.com/posts/documentation_next/</link><pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate><author>Tracy Atteberry</author><guid>https://tracyatteberry.com/posts/documentation_next/</guid><description><![CDATA[<div class="featured-image">
                <img src="https://tracyatteberry.com/posts/documentation_next/hero.jpg" referrerpolicy="no-referrer">
            </div><p>AI lets you ship faster than ever. That&rsquo;s great. But six months later, you&rsquo;re
staring at your own codebase wondering who wrote this. Why is this service
doing that? Why did you pick this library over the obvious one? What were you
thinking?</p>
<p>The problem usually isn&rsquo;t the code. It&rsquo;s that AI accelerates the building
without capturing the thinking. You evaluate options, make tradeoffs, reject
approaches, and move on. The decision happens in a chat window and then it&rsquo;s
gone. What&rsquo;s left is code without context, and that debt (a form of cognitive
debt) compounds quietly until it becomes a real problem.</p>
<p>Though it might help, the best fix isn&rsquo;t to slow down. It&rsquo;s to build a few
lightweight documentation habits that will hold up in an AI-assisted workflow.</p>
<h2 id="the-new-documentation-problem">The new documentation problem</h2>
<p>Traditional documentation advice assumes you understand everything you&rsquo;re
writing. You wrote the code, you know why it works the way it does, you just
need to write it down. AI-assisted development changes that assumption in a
couple of ways.</p>
<p>First, you move faster. When you&rsquo;re evaluating three AI-generated
implementations in ten minutes instead of writing one over an hour, there&rsquo;s
almost no natural pause where documentation feels like the obvious next step.
The decision-making is compressed, and so is the documentation.</p>
<p>Second, git history gets less useful. It still tells you what changed, but it
doesn&rsquo;t tell you that you picked this background job library because the other
one had a deployment constraint you needed to avoid. It doesn&rsquo;t tell you which
of four Stripe webhook implementations the AI suggested, or why you picked that
one. It doesn&rsquo;t tell you that you almost went a completely different direction.</p>
<p>The gap is context. And that&rsquo;s exactly what these habits are designed to
capture.</p>
<h2 id="document-decisions-not-implementations">Document decisions, not implementations</h2>
<p>The highest-leverage documentation habit is writing down why, not what. Code
already shows what. What it can&rsquo;t show is the thinking that produced it.</p>
<p>Keep a <code>docs/decisions.md</code> file. No formal template required. No ADR ceremony.
Just a running list of decisions, what options you considered, what you ruled
out and why, and what you landed on. A few sentences per decision is enough.</p>
<p>Some examples of the kind of thing worth capturing:</p>
<ul>
<li>Why you chose Sidekiq over Solid Queue (maybe it was a deployment constraint,
maybe it was familiarity, maybe you tried Solid Queue and hit a weird edge case)</li>
<li>Which Stripe webhook implementation you kept after the AI suggested three
different approaches</li>
<li>Why the data model is shaped the way it is instead of the more obvious
structure you considered first</li>
</ul>
<p>This is especially useful in AI-assisted work because the evaluation often
happens fast. You look at a few options, pick one, and move on. Without a
quick note somewhere, that reasoning is gone the moment you close the chat.</p>
<h2 id="the-daily-scratchpad">The daily scratchpad</h2>
<p>A scratchpad is not a journal. It&rsquo;s not a changelog. It&rsquo;s a place to think out
loud while you&rsquo;re working.</p>
<p>Drop a file at <code>tmp/scratch.md</code> (some people call it <code>journal.md</code> or
<code>dev-journal.md</code>) and use it to capture rationale in the moment. What did you
try? What didn&rsquo;t work? How did you arrive at this solution? What were you
unsure about?</p>
<p>It doesn&rsquo;t need to be clean. It doesn&rsquo;t need to be organized. It just needs to
exist.</p>
<p>Git history will tell future you that something changed on a Tuesday in March.
The scratchpad will tell future you that you were choosing between two
approaches, that one of them had a subtle concurrency problem you figured out
mid-afternoon, and that the solution you landed on was a compromise you felt
okay about. That&rsquo;s the stuff that can really help when you return to a project
three months later and can&rsquo;t quite remember what you were even trying to do.</p>
<h2 id="let-ai-explain-what-it-built">Let AI explain what it built</h2>
<p>Sometimes you ship code you don&rsquo;t fully understand yet. That&rsquo;s not a great
position to be in, but it&rsquo;s a real one, especially when you&rsquo;re learning a new
language or framework alongside building something.</p>
<p>When that happens, ask the AI to explain what it just built.</p>
<p>Recently I was building a new SaaS product in Elixir while still actively
learning the language. The initial architecture involved OTP supervision trees,
GenServers, and some patterns that weren&rsquo;t immediately obvious (to me). Rather
than hoping the understanding would come later, asking the AI to write an
<code>explainer.md</code> for the architecture made the whole thing legible. Later, an
<code>explainer.html</code> with diagrams and a walkthrough made it even better.</p>
<p>You can do the same thing with an existing codebase you&rsquo;re jumping into for the
first time. Drop the relevant files into context and ask for an explainer. It&rsquo;s
faster than reverse-engineering the code yourself, and it gives you something
you can update and refer back to as your understanding deepens.</p>
<p>My explainers live in <code>docs/explainers/</code>. They&rsquo;re not precious documents. They
can be rough, they can be wrong in places, and they should be updated as you
learn more. But having them at all is the difference between a codebase that
feels like yours and one that always feels a little foreign.</p>
<h2 id="keep-your-readme-human">Keep your README human</h2>
<p>AI tooling has introduced a temptation to stuff READMEs with prompts, agent
instructions, and notes about which parts were AI-generated. Resist it.</p>
<p>The README is for humans. What is this project? How do I get it running? Where
is the rest of the documentation? How do I contribute?</p>
<p>AI-specific context belongs elsewhere. Agent instructions and project rules for
your AI assistant go in <code>AGENTS.md</code> (if you use Claude, a <code>CLAUDE.md</code> symlink
pointing to it is handy). Plans and specs go in <code>docs/plans/</code> and
<code>docs/specs/</code>. Decisions go in <code>docs/decisions.md</code>. Explainers go in
<code>docs/explainers/</code>.</p>
<p>The README is the front door. Keep it welcoming and keep it human.</p>
<h2 id="own-the-code-all-of-it">Own the code, all of it</h2>
<p>You don&rsquo;t need to mark which lines an AI wrote.</p>
<p>I know that might feel counterintuitive. There&rsquo;s a reasonable instinct to be
transparent about your process. But there&rsquo;s a difference between transparency
and hedging. Marking code as AI-generated is a subtle way of distancing
yourself from it, as if to say: if this breaks, that&rsquo;s not entirely on me. But
that&rsquo;s not how accountability works.</p>
<p>You are responsible for every line of code you ship, regardless of how it was
produced. If you don&rsquo;t understand the code, you shouldn&rsquo;t ship it. If you&rsquo;re
not sure you understand it, that&rsquo;s what explainers are for.</p>
<p>The middle ground is being transparent about your development process at a
high level. It&rsquo;s no secret that most developers use AI assistance now, and
saying so in your docs or your README is great. That&rsquo;s transparency. What&rsquo;s
different is using it as a hedge. The tool you used to write the code doesn&rsquo;t
change your responsibility for the result.</p>
<h2 id="the-loop">The loop</h2>
<p>Good documentation helps you understand your codebase. Understanding your
codebase means you can give the AI better context when you&rsquo;re building something
new. Better context (human and AI) produces code that really fits the existing
architecture. Code that fits is easier to explain and document. Round and
round.</p>
<p>None of these habits are heavy. A few sentences in <code>decisions.md</code>. A rough note
in <code>scratch.md</code>. An explainer file when you&rsquo;re in unfamiliar territory. A
README that stays focused on humans.</p>
<p>The payoff is that six months from now, when you come back to this project, it
feels like yours. You remember what you were thinking. You know why things are
the way they are. And you can keep building without spending the first week
just figuring out what past-you was up to.</p>
<h2 id="bonus-automate-it-with-a-post-merge-hook">Bonus: automate it with a post-merge hook</h2>
<p>All of these habits share a common enemy: you have to remember to do them.
Remembering is fine when you&rsquo;re focused, but documentation is usually the thing
that slips when you&rsquo;re rushing to ship.</p>
<p>Here&rsquo;s a way to take the remembering out of it. A git <code>post-merge</code> hook fires
automatically after every merge. You can use it to shell out to Claude Code in
non-interactive mode and ask it to review and update your docs in light of what
just changed.</p>
<p>The hook grabs the merge diff, hands it to Claude along with a focused prompt,
and lets Claude update <code>README.md</code>, <code>docs/decisions.md</code>, any relevant explainers,
and product docs. Changes are left unstaged so you can review them before
committing. Nothing gets force-pushed. Nothing gets auto-committed. You stay
in control.</p>
<p>Here&rsquo;s the script:</p>
<div class="code-block code-line-numbers" style="counter-reset: code-block 0">
    <div class="code-header language-bash">
        <span class="code-title"><i class="arrow fas fa-chevron-right fa-fw" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h fa-fw" aria-hidden="true"></i></span>
        <span class="copy" title="Copy to clipboard"><i class="far fa-copy fa-fw" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/usr/bin/env bash
</span></span></span><span class="line"><span class="cl"><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="c1"># .git/hooks/post-merge</span>
</span></span><span class="line"><span class="cl"><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="c1"># After merging to main, asks Claude Code to review and update documentation.</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Changes are left unstaged for your review.</span>
</span></span><span class="line"><span class="cl"><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Setup:</span>
</span></span><span class="line"><span class="cl"><span class="c1">#   cp post-merge .git/hooks/post-merge</span>
</span></span><span class="line"><span class="cl"><span class="c1">#   chmod +x .git/hooks/post-merge</span>
</span></span><span class="line"><span class="cl"><span class="c1">#</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Requires Claude Code CLI to be installed and authenticated.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Only run on main branch</span>
</span></span><span class="line"><span class="cl"><span class="nv">CURRENT_BRANCH</span><span class="o">=</span><span class="k">$(</span>git symbolic-ref --short HEAD<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$CURRENT_BRANCH</span><span class="s2">&#34;</span> !<span class="o">=</span> <span class="s2">&#34;main&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">exit</span> <span class="m">0</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;📝 Checking documentation after merge to main...&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Capture what changed in the merge so Claude has context</span>
</span></span><span class="line"><span class="cl"><span class="nv">DIFF</span><span class="o">=</span><span class="k">$(</span>git diff ORIG_HEAD..HEAD --stat<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Build the prompt</span>
</span></span><span class="line"><span class="cl"><span class="nv">PROMPT</span><span class="o">=</span><span class="s2">&#34;A feature branch was just merged to main. Here is a summary of what changed:
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="nv">$DIFF</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">Please review the following documentation and update anything that is out of date
</span></span></span><span class="line"><span class="cl"><span class="s2">or missing given the changes above:
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">- README.md
</span></span></span><span class="line"><span class="cl"><span class="s2">- docs/decisions.md (add an entry if a significant architectural decision was made)
</span></span></span><span class="line"><span class="cl"><span class="s2">- Any relevant files in docs/explainers/
</span></span></span><span class="line"><span class="cl"><span class="s2">- Any relevant product documentation in docs/
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">Do not modify AGENTS.md or any files in docs/plans/ or docs/specs/.
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">After making changes, print a brief summary of what you updated and why.
</span></span></span><span class="line"><span class="cl"><span class="s2">If nothing needed updating, say so.&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Run Claude Code in non-interactive mode with read/write permissions only</span>
</span></span><span class="line"><span class="cl">claude -p <span class="s2">&#34;</span><span class="nv">$PROMPT</span><span class="s2">&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  --allowedTools <span class="s2">&#34;Read&#34;</span> <span class="s2">&#34;Write&#34;</span> <span class="s2">&#34;Glob&#34;</span> <span class="s2">&#34;Grep&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  --max-turns <span class="m">10</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Show which files were changed (if any)</span>
</span></span><span class="line"><span class="cl"><span class="nv">DOC_CHANGES</span><span class="o">=</span><span class="k">$(</span>git diff --name-only -- README.md <span class="s1">&#39;docs/**&#39;</span> 2&gt;/dev/null <span class="o">||</span> <span class="nb">true</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> -n <span class="s2">&#34;</span><span class="nv">$DOC_CHANGES</span><span class="s2">&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;✅ Documentation updated. Review changes before committing:&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$DOC_CHANGES</span><span class="s2">&#34;</span> <span class="p">|</span> sed <span class="s1">&#39;s/^/   /&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;   Run &#39;git diff&#39; to review, then &#39;git add&#39; and &#39;git commit&#39; when ready.&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;✅ No documentation changes were necessary.&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span></span></span></code></pre></div></div>
<p>Download here: <a href="./post-merge" rel="">post-merge</a></p>
<p>To install it, copy the script to <code>.git/hooks/post-merge</code> and make it
executable with <code>chmod +x .git/hooks/post-merge</code>. Since <code>.git/</code> isn&rsquo;t tracked
by git, you might want to keep the canonical copy in a <code>hooks/</code> directory in
your repo and add a setup step to your README.</p>
<p>A few things worth noting about the script:</p>
<p>The <code>--allowedTools</code> flag scopes Claude to read and write only. It can&rsquo;t run
arbitrary bash commands, can&rsquo;t touch your git history, and can&rsquo;t do anything
outside the files you&rsquo;ve pointed it at. Keeping the tool surface small is good
hygiene for any automated Claude Code invocation.</p>
<p>The <code>--max-turns 10</code> flag is a circuit breaker. It caps how many agentic turns
Claude can take so a single post-merge hook can&rsquo;t spin forever if something
unexpected happens.</p>
<p>The prompt explicitly excludes <code>AGENTS.md</code>, <code>docs/plans/</code>, and <code>docs/specs/</code>.
You don&rsquo;t want a merge hook rewriting your agent instructions or your design
plans. Keep the scope tight.</p>
<p>The <code>--max-turns</code> flag is a circuit breaker, but may need to be tuned based on
how much the amount of work that needs to be done. If the circuit breaker is
hit, the hook will exit with an error and leave the finished changes unstaged
for manual review.</p>
<p>This is a starting point, not a finished product. Your project&rsquo;s doc structure
will differ, and you&rsquo;ll want to tune the prompt to match. But the pattern holds:
capture the diff, give Claude focused scope, leave changes unstaged, and let the
human decide what to commit.</p>
]]></description></item></channel></rss>