<?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>Forem: Matthew</title>
    <description>The latest articles on Forem by Matthew (@matthewx999999).</description>
    <link>https://forem.com/matthewx999999</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3907352%2F1d5e6c81-837c-4728-9355-131955195bbb.jpg</url>
      <title>Forem: Matthew</title>
      <link>https://forem.com/matthewx999999</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/matthewx999999"/>
    <language>en</language>
    <item>
      <title>The git bisect run habit I should have learned ten years sooner</title>
      <dc:creator>Matthew</dc:creator>
      <pubDate>Mon, 04 May 2026 06:18:18 +0000</pubDate>
      <link>https://forem.com/matthewx999999/the-git-bisect-run-habit-i-should-have-learned-ten-years-sooner-3h07</link>
      <guid>https://forem.com/matthewx999999/the-git-bisect-run-habit-i-should-have-learned-ten-years-sooner-3h07</guid>
      <description>&lt;p&gt;Last Tuesday I lost about three hours to a regression in our checkout service. The cart total was off by a cent on certain promo combinations, and the only signal was a Slack ping from finance with a screenshot. No stack trace. No exception. Just wrong numbers.&lt;/p&gt;

&lt;p&gt;I did what I always do first. I opened the diff for the last deploy, scrolled, squinted, and tried to feel my way to the bug. Forty minutes in, I had a mental shortlist of suspects and zero proof. The code I was sure caused it had been merged a week earlier and was already reverted in a different branch for unrelated reasons. I was, as my old tech lead used to say, debugging the file I wanted the bug to be in.&lt;/p&gt;

&lt;p&gt;Then I remembered &lt;code&gt;git bisect run&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I keep relearning this tool. It's been around forever. I've recommended it to juniors more times than I can count. And yet whenever I'm in the thick of a real outage, I forget it exists for the first hour, because my brain wants to read the diff like a detective novel instead of running an experiment.&lt;/p&gt;

&lt;p&gt;Here's the workflow that finally stuck for me. I write a tiny script that exits 0 when the bug is absent and non-zero when it's present. For this regression, the script was twelve lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;
go build ./cmd/checkout
./checkout-test &lt;span class="nt"&gt;--promo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;BACK2SCHOOL &lt;span class="nt"&gt;--items&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/out
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s1"&gt;'"total":4297'&lt;/span&gt; /tmp/out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then &lt;code&gt;git bisect start HEAD v4.18.2&lt;/code&gt;, &lt;code&gt;git bisect run ./check.sh&lt;/code&gt;, and walk to the kitchen for coffee. By the time I came back, git had narrowed it to a single commit. Not the one I'd been staring at. Not even close. It was a four-line change to how we round per-line tax that someone had landed quietly two weeks ago, with a benign-looking commit message about "consistency."&lt;/p&gt;

&lt;p&gt;What surprised me wasn't the bug. The bug was small. What surprised me was how much faster the machine was at this than I was. I had been pattern-matching on author, recency, and which file looked spicy. Bisect doesn't care about any of that. It just keeps halving the search space until there's one commit left.&lt;/p&gt;

&lt;p&gt;A few things I've learned about making this a habit instead of a heroic last resort:&lt;/p&gt;

&lt;p&gt;The check script needs to be cheap. If your build is eight minutes, bisect across two hundred commits is a coffee break and a meeting and lunch. Mock the slow stuff. Build a smaller binary. I keep a &lt;code&gt;bisect/&lt;/code&gt; directory in some repos with pre-baked check scripts for known classes of bugs, so when something feels familiar I'm not writing the harness from scratch under pressure.&lt;/p&gt;

&lt;p&gt;Skip commits that don't build. &lt;code&gt;git bisect skip&lt;/code&gt; is your friend. You'll hit a few broken middle-of-refactor commits and that's fine; bisect handles them.&lt;/p&gt;

&lt;p&gt;Don't trust your gut on the "good" commit. I once spent forty minutes bisecting before realizing my "known good" reference also had the bug, just less visibly. Now I always run the check script against the supposedly-good commit first, before &lt;code&gt;bisect start&lt;/code&gt;. Two minutes of paranoia saves an hour of confusion.&lt;/p&gt;

&lt;p&gt;Bisect across squash-merged PRs and you might land on a commit that touches forty files. That's still useful. The PR title alone usually points you somewhere. I've also started linking PR numbers in commit bodies more aggressively for exactly this reason.&lt;/p&gt;

&lt;p&gt;The reason I keep forgetting this tool, I think, is that it feels like cheating. I want to understand the bug by reading the code, because that's the part that feels like real engineering. Bisect skips the understanding and goes straight to the answer. But the answer is what unblocks the team. Understanding can come after, in a calmer hour, with the offending commit already pinned to the wall.&lt;/p&gt;

&lt;p&gt;The Tuesday bug ended up being a one-line fix. The git bisect run took eleven minutes including the coffee. The forty minutes I'd spent reading the diff before remembering the tool existed is the part I want back.&lt;/p&gt;

&lt;p&gt;Next time I feel the urge to scroll through a deploy diff while a fire is burning, I'm going to write the check script first. Even if I'm sure I know where the bug is. Especially then.&lt;/p&gt;

</description>
      <category>git</category>
      <category>debugging</category>
      <category>productivity</category>
      <category>career</category>
    </item>
    <item>
      <title>20 years in, the agent stack finally feels like plumbing</title>
      <dc:creator>Matthew</dc:creator>
      <pubDate>Fri, 01 May 2026 14:34:31 +0000</pubDate>
      <link>https://forem.com/matthewx999999/20-years-in-the-agent-stack-finally-feels-like-plumbing-32i0</link>
      <guid>https://forem.com/matthewx999999/20-years-in-the-agent-stack-finally-feels-like-plumbing-32i0</guid>
      <description>&lt;p&gt;Twenty-something years ago I wrote my first SOAP client. The XML was nested four deep, the WSDL was wrong, the vendor's docs lied, and I still got paged at 2am when something a Java app I didn't write decided the namespace had moved. I think about that morning a lot whenever someone tries to sell me a new "agent framework."&lt;/p&gt;

&lt;p&gt;A year ago I'd have rolled my eyes at MCP too. Every cycle has Its Protocol. Most don't outlive their conference talk. But MCP crossed 97 million installs in March, the Linux Foundation just took it under open governance, and OpenAI's newest Responses API speaks it natively. Around when that happened I noticed something a little embarrassing. I'd quietly stopped writing one-off integration scripts. They just sort of fell off the to-do list.&lt;/p&gt;

&lt;p&gt;So what's it doing right that the last forty things didn't?&lt;/p&gt;

&lt;p&gt;It's boring. That's the whole answer.&lt;/p&gt;

&lt;p&gt;There's no clever DSL. No SDK lock-in. No "first-class agent abstractions" that turn out to mean three layers of decorator soup. A server exposes some tools, an agent calls them, the transport doesn't care which model you're paying this month. I run a Postgres MCP server, a Linear one, and a Playwright one. They have absolutely no idea about each other and they don't need to. It's the same dumb composability we got from pipes and from HTTP.&lt;/p&gt;

&lt;p&gt;The interesting bit isn't the install count. It's that OpenAI ships compatibility, Google ships compatibility, and now LF owns the spec. We're past the line where any one company can yank it. That is rare. The last protocol I can remember crossing it was OAuth 2.0, and that took years longer than people remember.&lt;/p&gt;

&lt;p&gt;A few things I'm still not sold on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auth gets reinvented per server and most of them get it wrong&lt;/li&gt;
&lt;li&gt;Discovery is hand-wavy. We're going to need something better than "paste this URL"&lt;/li&gt;
&lt;li&gt;Tool permissioning is closer to "the user clicks yes" than to anything you'd accept in production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that kills it. It just means the next two years probably look like 2010-era REST. Everyone agrees on the wire format and we slowly figure out the tooling around it. CORS will get reinvented. Someone will write a bad spec for tool versioning. We'll all live.&lt;/p&gt;

&lt;p&gt;If you've been on the fence, this is a good week to ship a small server. Pick one annoying internal tool you wish your editor knew about. Wrap it. Plug it in. The leverage is genuinely silly once you stop fighting the model into pretending to know things it never could.&lt;/p&gt;

&lt;p&gt;Curious what other graybeards on here are using MCP for day to day. The thing I'd most like to see: a battle-tested auth pattern that isn't "static bearer token in env."&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
  </channel>
</rss>
