<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>heyimusa</title>
    <link>https://heyimusa.blog/</link>
    <description></description>
    <pubDate>Mon, 20 Jul 2026 07:05:20 +0000</pubDate>
    <item>
      <title>A rollout needs a return address</title>
      <link>https://heyimusa.blog/a-rollout-needs-a-return-address</link>
      <description>&lt;![CDATA[A small declarative rollout and rollback experiment&#xA;&#xA;Original diagram for this note. It describes a Docker-only simulated release flow, not a production deployment or benchmark.&#xA;&#xA;I do not trust a deployment plan until I can explain what happens when the new version is the problem.&#xA;&#xA;That sounds obvious. It is still easy to build a delivery process around the happy path: create an image, update a manifest, watch the rollout, call it done. The awkward part starts when a release looks healthy enough to leave the pipeline but is not healthy enough to keep.&#xA;&#xA;To keep this small, I ran a toy release flow in a disposable Docker container. There was no host change, cluster, registry, or real service. The container held a desired-state file for a fictional checkout service, plus a saved copy of the known-good release.&#xA;&#xA;apply: checkout:1.4.3&#xA;healthcheck: /readyz -  FAIL (simulated)&#xA;rollback: checkout:1.4.2&#xA;healthcheck: /readyz -  OK (simulated)&#xA;finaldesiredstate: image=checkout:1.4.2 replicas=3&#xA;&#xA;The experiment is intentionally boring. That is the point. A rollback should not require somebody to reconstruct the previous state from memory while a production graph turns red.&#xA;&#xA;The release needs a return address&#xA;&#xA;A deployment is a state transition. The candidate release is only one half of that transition; the other half is the state you can return to when the candidate fails.&#xA;&#xA;In the tiny experiment, that state was just a saved file:&#xA;&#xA;image=checkout:1.4.2&#xA;replicas=3&#xA;&#xA;Real systems are less neat. There may be configuration changes, schema compatibility, feature flags, asynchronous workers, or traffic shifts. But the basic question does not change: what exact state are we restoring, and can the deployment system express it?&#xA;&#xA;If the answer is &#34;we will figure it out,&#34; the rollback plan is not really a plan.&#xA;&#xA;Rollback is not an apology button&#xA;&#xA;People often talk about rollback as if it is the opposite of deployment. It is not. It is another deployment, with the same need for identity, evidence, and verification.&#xA;&#xA;A useful rollback path has at least three properties:&#xA;&#xA;The previous artifact or desired state is identifiable.&#xA;The path to apply it is known before the incident.&#xA;The system has a signal that says the restored version is actually healthy.&#xA;&#xA;The third item gets skipped surprisingly often. Reverting an image tag is not proof that the service recovered. It only proves that the deployment controller accepted another instruction.&#xA;&#xA;Why declarative state helps&#xA;&#xA;This is where GitOps and other declarative delivery patterns earn their keep. They make the intended state visible. They also make a reversal more concrete: restore a reviewed revision, reconcile it, and watch the same health signals that justified the rollout.&#xA;&#xA;That does not make every rollback safe. Database migrations can make a simple reversal impossible. A downstream dependency may have changed underneath you. A feature flag may be the safer first lever. Declarative state is not magic; it just removes one common source of panic: having to guess which version and configuration were running before the change.&#xA;&#xA;The part I would test next&#xA;&#xA;The toy flow did not cover the hard cases. It did not include a database, traffic management, or an actual Kubernetes controller. It only checked the shape of the idea: a failed health check should lead to a named previous state, then to a second health check.&#xA;&#xA;The next useful step is to run the same exercise against a non-critical service in an isolated environment:&#xA;&#xA;deploy a known candidate;&#xA;deliberately fail a readiness condition;&#xA;reconcile the previous revision;&#xA;verify the restored service through the same route and alert signal users depend on.&#xA;&#xA;If that feels cumbersome in a test environment, it will feel worse during an incident.&#xA;&#xA;---&#xA;&#xA;Test notes: This note is based on a disposable Docker container limited to 0.25 CPU and 128 MiB memory. It simulated a declarative checkout release changing from 1.4.2 to 1.4.3, a failed readiness check, and restoration to 1.4.2. No production infrastructure, repository, cluster, registry, or database was accessed.&#xA;&#xA;Related work: Turning deployments into a repeatable platform capability&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="/img/articles/rollbacks-need-a-place-to-land.svg" alt="A small declarative rollout and rollback experiment"></p>

<p><em>Original diagram for this note. It describes a Docker-only simulated release flow, not a production deployment or benchmark.</em></p>

<p>I do not trust a deployment plan until I can explain what happens when the new version is the problem.</p>

<p>That sounds obvious. It is still easy to build a delivery process around the happy path: create an image, update a manifest, watch the rollout, call it done. The awkward part starts when a release looks healthy enough to leave the pipeline but is not healthy enough to keep.</p>

<p>To keep this small, I ran a toy release flow in a disposable Docker container. There was no host change, cluster, registry, or real service. The container held a desired-state file for a fictional <code>checkout</code> service, plus a saved copy of the known-good release.</p>

<pre><code class="language-text">apply: checkout:1.4.3
healthcheck: /readyz -&gt; FAIL (simulated)
rollback: checkout:1.4.2
healthcheck: /readyz -&gt; OK (simulated)
final_desired_state: image=checkout:1.4.2 replicas=3
</code></pre>

<p>The experiment is intentionally boring. That is the point. A rollback should not require somebody to reconstruct the previous state from memory while a production graph turns red.</p>

<h2 id="the-release-needs-a-return-address">The release needs a return address</h2>

<p>A deployment is a state transition. The candidate release is only one half of that transition; the other half is the state you can return to when the candidate fails.</p>

<p>In the tiny experiment, that state was just a saved file:</p>

<pre><code class="language-text">image=checkout:1.4.2
replicas=3
</code></pre>

<p>Real systems are less neat. There may be configuration changes, schema compatibility, feature flags, asynchronous workers, or traffic shifts. But the basic question does not change: <strong>what exact state are we restoring, and can the deployment system express it?</strong></p>

<p>If the answer is “we will figure it out,” the rollback plan is not really a plan.</p>

<h2 id="rollback-is-not-an-apology-button">Rollback is not an apology button</h2>

<p>People often talk about rollback as if it is the opposite of deployment. It is not. It is another deployment, with the same need for identity, evidence, and verification.</p>

<p>A useful rollback path has at least three properties:</p>
<ul><li>The previous artifact or desired state is identifiable.</li>
<li>The path to apply it is known before the incident.</li>
<li>The system has a signal that says the restored version is actually healthy.</li></ul>

<p>The third item gets skipped surprisingly often. Reverting an image tag is not proof that the service recovered. It only proves that the deployment controller accepted another instruction.</p>

<h2 id="why-declarative-state-helps">Why declarative state helps</h2>

<p>This is where GitOps and other declarative delivery patterns earn their keep. They make the intended state visible. They also make a reversal more concrete: restore a reviewed revision, reconcile it, and watch the same health signals that justified the rollout.</p>

<p>That does not make every rollback safe. Database migrations can make a simple reversal impossible. A downstream dependency may have changed underneath you. A feature flag may be the safer first lever. Declarative state is not magic; it just removes one common source of panic: having to guess which version and configuration were running before the change.</p>

<h2 id="the-part-i-would-test-next">The part I would test next</h2>

<p>The toy flow did not cover the hard cases. It did not include a database, traffic management, or an actual Kubernetes controller. It only checked the shape of the idea: a failed health check should lead to a named previous state, then to a second health check.</p>

<p>The next useful step is to run the same exercise against a non-critical service in an isolated environment:</p>
<ol><li>deploy a known candidate;</li>
<li>deliberately fail a readiness condition;</li>
<li>reconcile the previous revision;</li>
<li>verify the restored service through the same route and alert signal users depend on.</li></ol>

<p>If that feels cumbersome in a test environment, it will feel worse during an incident.</p>

<hr>

<p><strong>Test notes:</strong> This note is based on a disposable Docker container limited to 0.25 CPU and 128 MiB memory. It simulated a declarative <code>checkout</code> release changing from <code>1.4.2</code> to <code>1.4.3</code>, a failed readiness check, and restoration to <code>1.4.2</code>. No production infrastructure, repository, cluster, registry, or database was accessed.</p>

<p><strong>Related work:</strong> <a href="/portfolio/work/#work">Turning deployments into a repeatable platform capability</a></p>
]]></content:encoded>
      <guid>https://heyimusa.blog/a-rollout-needs-a-return-address</guid>
      <pubDate>Sun, 19 Jul 2026 17:31:09 +0000</pubDate>
    </item>
    <item>
      <title>I tried code-review-graph in Docker. Useful, but don’t swallow the 528x number whole.</title>
      <link>https://heyimusa.blog/github-trending-context-engineering-ai-coding</link>
      <description>&lt;![CDATA[Diagram comparing whole-corpus reading with graph queries in the code-review-graph benchmark&#xA;&#xA;Diagram from code-review-graph, commit 6a1ee1c · MIT licensed · kept locally so this post does not depend on a hotlink.&#xA;&#xA;I saw code-review-graph climbing GitHub Trending and nearly wrote the usual post about why AI coding needs better context. Then I stopped. That sentence is true, but it is also a pretty easy way to avoid trying the tool.&#xA;&#xA;So I did a small smoke test first.&#xA;&#xA;I ran it inside a Docker container, not on the host. The container had one CPU and 1.5 GiB of memory. Inside it, I made a tiny Python repository: authentication, a login endpoint, and one test. Then I installed code-review-graph 2.3.7 and built the graph.&#xA;&#xA;Full build: 3 files, 6 nodes, 9 edges&#xA;Nodes: 6&#xA;Edges: 9&#xA;Files: 3&#xA;Languages: python&#xA;&#xA;Nothing dramatic happened, which was reassuring. The tool connected api.py, auth.py, and the test in the way I expected. That only proves it can build a graph for a tiny repository. It does not prove that it will make pull request reviews better on a real codebase. Still, the smallest claim held up without giving the tool access to the machine running the blog.&#xA;&#xA;What the tool is trying to do&#xA;&#xA;code-review-graph uses Tree-sitter to map a repository. The intended payoff is simple: when an agent reviews a change, it should not need to read an entire repository just to find the few files that matter.&#xA;&#xA;That sounds obvious until a change touches an API, a worker, a deployment chart, and an alert rule. At that point the problem is not a lack of context window. It is finding the context that is actually connected to the change.&#xA;&#xA;For a three-file repository, I would still open the files myself. There is no prize for adding a graph database to a problem that rg can solve in ten seconds. The case gets more interesting once the repository is large enough that a change has consequences outside the diff.&#xA;&#xA;About the 528x number&#xA;&#xA;The project README leads with an eye-catching result: up to 528x fewer tokens. That number is real, but it is the best case from the project&#39;s FastAPI benchmark.&#xA;&#xA;The more useful number is their reported median of roughly 82x per question across six repositories. Even that needs context. The comparison is whole-corpus reading versus a graph query. A good engineer does not normally paste an entire repository into an LLM and hope for the best, so this is an upper-bound baseline, not a normal day at work.&#xA;&#xA;I like that the README says as much. Too many AI tool pages put the caveat in a footnote, if they include one at all.&#xA;&#xA;What I liked&#xA;&#xA;The project does not try to make the model magically smarter. It tries to give the model less irrelevant material. That is a healthier problem to work on.&#xA;&#xA;It also has a plausible route into real workflows: a CLI, MCP support, incremental updates, and a GitHub Action. A graph that looks good in a demo is easy. Keeping one useful after a repository changes every day is the hard part.&#xA;&#xA;What I still do not know&#xA;&#xA;This smoke test was deliberately small. It did not answer the questions I would ask before adopting it on a serious repository:&#xA;&#xA;How long does the first build take on a monorepo?&#xA;How large does the graph database become?&#xA;Does retrieval surface the files an experienced reviewer would open anyway?&#xA;Does it save time, or does it add another moving part to maintain?&#xA;&#xA;I would not give a trending tool write access to a repository on the strength of a screenshot and a benchmark chart. A read-only container, a non-critical repository, and outputs that a human can inspect are enough for a first pass.&#xA;&#xA;If you want to try it&#xA;&#xA;Start with one repository you know well. Measure the first build and an incremental update. Then compare the suggested files with the files you would have opened during a normal review.&#xA;&#xA;If the answers line up, keep going. If they do not, you have still learned something useful and avoided adding another MCP server just because it was trending.&#xA;&#xA;---&#xA;&#xA;Test notes: code-review-graph 2.3.7 ran in an isolated Docker container with Python 3.12, one CPU, and 1.5 GiB of memory. This was a graph-build smoke test on a small Python repository. I did not independently reproduce the project&#39;s token benchmark.&#xA;&#xA;Sources: code-review-graph · benchmark methodology · GitHub Trending&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="/img/articles/code-review-graph-token-problem.png" alt="Diagram comparing whole-corpus reading with graph queries in the code-review-graph benchmark"></p>

<p><em>Diagram from <a href="https://github.com/tirth8205/code-review-graph">code-review-graph</a>, commit <code>6a1ee1c</code> · MIT licensed · kept locally so this post does not depend on a hotlink.</em></p>

<p>I saw <code>code-review-graph</code> climbing GitHub Trending and nearly wrote the usual post about why AI coding needs better context. Then I stopped. That sentence is true, but it is also a pretty easy way to avoid trying the tool.</p>

<p>So I did a small smoke test first.</p>

<p>I ran it inside a Docker container, not on the host. The container had one CPU and 1.5 GiB of memory. Inside it, I made a tiny Python repository: authentication, a login endpoint, and one test. Then I installed <code>code-review-graph 2.3.7</code> and built the graph.</p>

<pre><code class="language-text">Full build: 3 files, 6 nodes, 9 edges
Nodes: 6
Edges: 9
Files: 3
Languages: python
</code></pre>

<p>Nothing dramatic happened, which was reassuring. The tool connected <code>api.py</code>, <code>auth.py</code>, and the test in the way I expected. That only proves it can build a graph for a tiny repository. It does not prove that it will make pull request reviews better on a real codebase. Still, the smallest claim held up without giving the tool access to the machine running the blog.</p>

<h2 id="what-the-tool-is-trying-to-do">What the tool is trying to do</h2>

<p><code>code-review-graph</code> uses Tree-sitter to map a repository. The intended payoff is simple: when an agent reviews a change, it should not need to read an entire repository just to find the few files that matter.</p>

<p>That sounds obvious until a change touches an API, a worker, a deployment chart, and an alert rule. At that point the problem is not a lack of context window. It is finding the context that is actually connected to the change.</p>

<p>For a three-file repository, I would still open the files myself. There is no prize for adding a graph database to a problem that <code>rg</code> can solve in ten seconds. The case gets more interesting once the repository is large enough that a change has consequences outside the diff.</p>

<h2 id="about-the-528x-number">About the 528x number</h2>

<p>The project README leads with an eye-catching result: up to <strong>528x</strong> fewer tokens. That number is real, but it is the best case from the project&#39;s FastAPI benchmark.</p>

<p>The more useful number is their reported median of roughly <strong>82x</strong> per question across six repositories. Even that needs context. The comparison is whole-corpus reading versus a graph query. A good engineer does not normally paste an entire repository into an LLM and hope for the best, so this is an upper-bound baseline, not a normal day at work.</p>

<p>I like that the README says as much. Too many AI tool pages put the caveat in a footnote, if they include one at all.</p>

<h2 id="what-i-liked">What I liked</h2>

<p>The project does not try to make the model magically smarter. It tries to give the model less irrelevant material. That is a healthier problem to work on.</p>

<p>It also has a plausible route into real workflows: a CLI, MCP support, incremental updates, and a GitHub Action. A graph that looks good in a demo is easy. Keeping one useful after a repository changes every day is the hard part.</p>

<h2 id="what-i-still-do-not-know">What I still do not know</h2>

<p>This smoke test was deliberately small. It did not answer the questions I would ask before adopting it on a serious repository:</p>
<ul><li>How long does the first build take on a monorepo?</li>
<li>How large does the graph database become?</li>
<li>Does retrieval surface the files an experienced reviewer would open anyway?</li>
<li>Does it save time, or does it add another moving part to maintain?</li></ul>

<p>I would not give a trending tool write access to a repository on the strength of a screenshot and a benchmark chart. A read-only container, a non-critical repository, and outputs that a human can inspect are enough for a first pass.</p>

<h2 id="if-you-want-to-try-it">If you want to try it</h2>

<p>Start with one repository you know well. Measure the first build and an incremental update. Then compare the suggested files with the files you would have opened during a normal review.</p>

<p>If the answers line up, keep going. If they do not, you have still learned something useful and avoided adding another MCP server just because it was trending.</p>

<hr>

<p><strong>Test notes:</strong> <code>code-review-graph 2.3.7</code> ran in an isolated Docker container with Python 3.12, one CPU, and 1.5 GiB of memory. This was a graph-build smoke test on a small Python repository. I did not independently reproduce the project&#39;s token benchmark.</p>

<p><strong>Sources:</strong> <a href="https://github.com/tirth8205/code-review-graph">code-review-graph</a> · <a href="https://github.com/tirth8205/code-review-graph/blob/main/docs/REPRODUCING.md">benchmark methodology</a> · <a href="https://github.com/trending">GitHub Trending</a></p>
]]></content:encoded>
      <guid>https://heyimusa.blog/github-trending-context-engineering-ai-coding</guid>
      <pubDate>Sun, 19 Jul 2026 14:56:35 +0000</pubDate>
    </item>
  </channel>
</rss>