<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Debugging AI on Programmer.ie: Modern AI programming</title>
    <link>http://programmer.ie/books/debugging-ai/</link>
    <description>Recent content in Debugging AI on Programmer.ie: Modern AI programming</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Sun, 06 Sep 2026 21:00:00 +0000</lastBuildDate>
    <atom:link href="http://programmer.ie/books/debugging-ai/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>What Does It Mean to Debug?</title>
      <link>http://programmer.ie/books/debugging-ai/01-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/01-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part I — Debugging From First Principles&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-puzzle-two-fixes-one-bug&#34;&gt;The puzzle: two fixes, one bug&lt;/h2&gt;&#xA;&lt;p&gt;A team owns a small billing function. Invoices above €1,000 get a 10% discount. One Monday, a €1,200 invoice goes out at full price. Two developers investigate independently.&lt;/p&gt;&#xA;&lt;p&gt;Developer A reads the code, spots a suspicious comparison, flips &lt;code&gt;&amp;lt;&lt;/code&gt; to &lt;code&gt;&amp;lt;=&lt;/code&gt; somewhere that &amp;ldquo;looks wrong,&amp;rdquo; reruns the failing invoice, and sees €1,080. Fixed. She closes the ticket.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The First Divergence</title>
      <link>http://programmer.ie/books/debugging-ai/02-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/02-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part I — Debugging From First Principles&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-puzzle-the-report-is-wrong-but-where&#34;&gt;The puzzle: the report is wrong, but where?&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 1 defined debugging as constructing the smallest evidence-backed causal account that predicts the failure and its reversal — pursued, inside a pinned envelope, by finding the earliest transition surviving forward and reverse intervention — and split &amp;ldquo;earliest divergence&amp;rdquo; into three levels: first difference, first relevant difference, first causal divergence. This chapter makes the localization part executable — how you get to a candidate first divergence efficiently, before the hypothesis cycle promotes it to a cause.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Evidence Before Explanation</title>
      <link>http://programmer.ie/books/debugging-ai/03-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/03-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part I — Debugging From First Principles&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-puzzle-the-model-explains-fluently-and-is-wrong&#34;&gt;The puzzle: the model explains, fluently, and is wrong&lt;/h2&gt;&#xA;&lt;p&gt;Chapters 1 and 2 assumed your checkpoints record reality. This chapter removes that comfort.&lt;/p&gt;&#xA;&lt;p&gt;Scenario. A RAG assistant answers: &amp;ldquo;Your refund was processed on September 2; reference RB-8814.&amp;rdquo; Asked &lt;em&gt;how&lt;/em&gt; it knows, it replies: &amp;ldquo;I retrieved ticket #4471 and the refund ledger, which both confirm RB-8814.&amp;rdquo; Confident. Cited. Coherent.&lt;/p&gt;&#xA;&lt;p&gt;The ledger says no such thing. Ticket #4471 is about a different customer. Reference RB-8814 does not exist in any retrieved document. Every sentence of the explanation is fluent and false.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Debugging Stack</title>
      <link>http://programmer.ie/books/debugging-ai/04-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/04-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part I — Debugging From First Principles&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-puzzle-three-suspects-one-keyerror&#34;&gt;The puzzle: three suspects, one &lt;code&gt;KeyError&lt;/code&gt;&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 3 taught you to trust only frozen artifacts. This chapter tells you &lt;em&gt;where to look for them&lt;/em&gt; — in what order, and at which layer.&lt;/p&gt;&#xA;&lt;p&gt;Scenario. A batch job crashes:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;KeyError: &amp;#39;refund_id&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &amp;#34;report.py&amp;#34;, line 90, in build_row&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    row[&amp;#34;refund_id&amp;#34;] = order[&amp;#34;refund_id&amp;#34;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Three engineers propose three fixes within minutes:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Engineer A: &amp;ldquo;Line 90 assumes a key that &lt;code&gt;clean&lt;/code&gt; doesn&amp;rsquo;t guarantee. Guard with &lt;code&gt;.get()&lt;/code&gt;.&amp;rdquo; (Code layer.)&lt;/li&gt;&#xA;&lt;li&gt;Engineer B: &amp;ldquo;The upstream export dropped the column yesterday. Re-fetch the data.&amp;rdquo; (Data layer.)&lt;/li&gt;&#xA;&lt;li&gt;Engineer C: &amp;ldquo;Works on my machine — the job container pins &lt;code&gt;pandas 1.5&lt;/code&gt;, prod runs &lt;code&gt;2.x&lt;/code&gt;, and the CSV reader changed dtype inference.&amp;rdquo; (Environment layer.)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;OBSERVATION: &lt;code&gt;order&lt;/code&gt; lacks &lt;code&gt;refund_id&lt;/code&gt; at line 90 on this input, this code version, this container.&#xA;HYPOTHESES: H1 code-assumption, H2 data-regression, H3 environment-drift.&#xA;INFERENCE: none yet — all three predict the identical traceback.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reading Python Exceptions</title>
      <link>http://programmer.ie/books/debugging-ai/05-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/05-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part II — Debugging Deterministic Software&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-crash-that-names-the-wrong-culprit&#34;&gt;The crash that names the wrong culprit&lt;/h2&gt;&#xA;&lt;p&gt;A nightly invoice job dies at 02:14 with this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Traceback (most recent call last):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &amp;#34;jobs/run_invoices.py&amp;#34;, line 41, in &amp;lt;module&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    main()&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &amp;#34;jobs/run_invoices.py&amp;#34;, line 36, in main&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    totals = summarize(orders)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  File &amp;#34;billing/totals.py&amp;#34;, line 88, in summarize&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    row[&amp;#34;refund_id&amp;#34;] = order[&amp;#34;refund_id&amp;#34;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;KeyError: &amp;#39;refund_id&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The on-call engineer&amp;rsquo;s eyes lock onto line 88 of &lt;code&gt;totals.py&lt;/code&gt;. That is where the traceback ends, so that must be where the bug lives. She adds &lt;code&gt;.get(&amp;quot;refund_id&amp;quot;)&lt;/code&gt;, the job goes green, and three weeks later finance finds $41,000 in refunds silently missing from the report. The traceback told the truth. She read it backwards — or rather, she read only the last line and treated it as the diagnosis.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Inspect State, Don&#39;t Guess</title>
      <link>http://programmer.ie/books/debugging-ai/06-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/06-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part II — Debugging Deterministic Software&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-function-that-reads-correctly-and-runs-wrong&#34;&gt;The function that reads correctly and runs wrong&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 5 convicted the handoff. Now you open the convicted function, and it looks innocent:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# billing/discounts.py&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;apply_discount&lt;/span&gt;(order):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rate &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; RATE_TABLE[order[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;tier&amp;#34;&lt;/span&gt;]]       &lt;span style=&#34;color:#75715e&#34;&gt;# line 12&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    total &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; order[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;subtotal&amp;#34;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; rate) &lt;span style=&#34;color:#75715e&#34;&gt;# line 13&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; order&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;coupon&amp;#34;&lt;/span&gt;):                &lt;span style=&#34;color:#75715e&#34;&gt;# line 14&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        total &lt;span style=&#34;color:#f92672&#34;&gt;-=&lt;/span&gt; COUPONS[order[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;coupon&amp;#34;&lt;/span&gt;]]  &lt;span style=&#34;color:#75715e&#34;&gt;# line 15&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; round(total, &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;)                 &lt;span style=&#34;color:#75715e&#34;&gt;# line 16&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A premium-tier order for $200 with a $20 coupon returns $160 instead of the expected $140. Read the code: line 12 looks up the tier rate (0.2 for premium), line 13 computes $160, lines 14–15 subtract the coupon. The logic reads correctly. Two engineers stare at it for twenty minutes and conclude &amp;ldquo;the coupon table must be stale&amp;rdquo; — then spend an afternoon auditing &lt;code&gt;COUPONS&lt;/code&gt;, which is fine.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debug the Boundary</title>
      <link>http://programmer.ie/books/debugging-ai/07-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/07-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part II — Debugging Deterministic Software&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-suite-is-green-and-the-refunds-are-wrong&#34;&gt;The suite is green and the refunds are wrong&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 6 taught you to inspect live state on the failing input. This chapter asks why the failing input was never run.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;paginate&lt;/code&gt; helper ships with 47 passing tests:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# billing/pages.py&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;paginate&lt;/span&gt;(items, page_size):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;Split items into pages of page_size. Returns list of pages.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pages &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; []&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, len(items), page_size):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        pages&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(items[i:i &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; page_size])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; pages&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Every test uses comfortable middles: 100 items with page size 10, 25 items with page size 5. Production runs it on the refund queue — and one night the queue holds exactly 0 items, then a single-item queue, then a queue whose length equals the page size exactly. The shown &lt;code&gt;paginate&lt;/code&gt; itself returns &lt;code&gt;[]&lt;/code&gt; correctly for the empty input (its &lt;code&gt;range(0, 0, 10)&lt;/code&gt; never executes); the phantom page appears in the production path, where a &lt;code&gt;chunk_count&lt;/code&gt;-driven sibling (convicted below) allocates one page too many at every exact multiple — including zero — and downstream code then indexes a page that should not exist. The single-item run works. All 47 tests stay green through all of it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Assertions, Invariants, and Contracts</title>
      <link>http://programmer.ie/books/debugging-ai/08-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/08-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part II — Debugging Deterministic Software&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-corruption-nobody-heard&#34;&gt;The corruption nobody heard&lt;/h2&gt;&#xA;&lt;p&gt;Chapters 5–7 kept finding breaks at the same place: the handoff. Now watch what happens when the handoff has no guard.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;code&gt;clean → summarize&lt;/code&gt; pipeline from Chapter 4 runs green for a month. Then finance notices refund totals drifting downward — no crash, no traceback, no red badge. Reconstruction shows the &lt;code&gt;clean&lt;/code&gt; refactor (the one Chapter 4 convicted) had been dropping &lt;code&gt;refund_id&lt;/code&gt; for split-shipment children for four weeks. Chapter 5&amp;rsquo;s &lt;code&gt;.get()&lt;/code&gt; silence would have done the same even faster: every affected row computed a total without its refund, wrote it to the report, and moved on. The program never failed. It just lied, quietly, 12,000 rows per night.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Environment Bugs</title>
      <link>http://programmer.ie/books/debugging-ai/09-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/09-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part II — Debugging Deterministic Software&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;green-here-red-there-same-code-same-data&#34;&gt;Green here, red there, same code, same data&lt;/h2&gt;&#xA;&lt;p&gt;Every contract from Chapter 8 is in place. The suite passes on the engineer&amp;rsquo;s laptop. It fails in CI — same commit hash, same fixture file, same command. The failure is the old ghost from Chapter 4:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# laptop (passes)                    # CI (fails)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ python jobs/run_invoices.py        $ python jobs/run_invoices.py&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;report.csv written, 312 rows         Traceback (most recent call last):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                       File &amp;#34;billing/totals.py&amp;#34;, line 88, in summarize&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                         row[&amp;#34;refund_id&amp;#34;] = order[&amp;#34;refund_id&amp;#34;]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                                       KeyError: &amp;#39;refund_id&amp;#39;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;git rev-parse&lt;/code&gt; matches. &lt;code&gt;sha256sum fixtures/incident_input.csv&lt;/code&gt; matches. The engineer re-reads &lt;code&gt;totals.py&lt;/code&gt;, re-inspects state, re-runs the boundary table — all clean, because the code &lt;em&gt;is&lt;/em&gt; clean and the data &lt;em&gt;is&lt;/em&gt; clean. Chapters 5–8 have nothing left to convict. That is precisely the signal: when identical code plus identical data still diverges, the divergence lives underneath both.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Notebook Is Not the Program You See</title>
      <link>http://programmer.ie/books/debugging-ai/10-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/10-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part III — Debugging Interactive and Numerical AI&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-changes-in-part-iii&#34;&gt;What changes in Part III&lt;/h2&gt;&#xA;&lt;p&gt;Parts I and II debugged a program you could re-run: same code, same data, same container, same outcome — or a substrate diff that explained the difference. The object under inspection was small and local — a value at a line, a frame&amp;rsquo;s state, a handoff between two functions.&lt;/p&gt;&#xA;&lt;p&gt;Part III keeps the discipline and grows the object. Nothing about the loop changes — reproduce first, find the earliest divergence, move one variable, predict the result before you look, convert the fix to a contract. What changes is &lt;em&gt;what the loop points at&lt;/em&gt;, and how hard it is to hold still. The object moves outward, one chapter at a time:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hidden Notebook State</title>
      <link>http://programmer.ie/books/debugging-ai/11-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/11-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part III — Debugging Interactive and Numerical AI&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-variable-that-exists-nowhere&#34;&gt;The variable that exists nowhere&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 10 closed with a green, in-order Run All — gutter monotonic, cells top-to-bottom. The engineer reopens the same notebook a week later, runs the first six cells interactively, and types &lt;code&gt;threshold&lt;/code&gt; in cell 7:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# cell 7 (fresh session, only cells 1-6 executed)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print(threshold)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 0.9   &amp;lt;- where did this come from?&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;A search for &lt;code&gt;threshold&lt;/code&gt; across every visible cell returns nothing. No definition, no import, no magic. Yet the kernel answers &lt;code&gt;0.9&lt;/code&gt;. Restart &amp;amp; Run All from the top fails at cell 7 with &lt;code&gt;NameError: name &#39;threshold&#39; is not defined&lt;/code&gt; — while the warm kernel insists the variable is real.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reproducible Notebooks</title>
      <link>http://programmer.ie/books/debugging-ai/12-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/12-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part III — Debugging Interactive and Numerical AI&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;green-here-red-there-same-notebook&#34;&gt;Green here, red there, same notebook&lt;/h2&gt;&#xA;&lt;p&gt;Chapters 10 and 11 closed with a notebook that runs clean: order verified, namespace explained, Run All green. The engineer sends it to a colleague. Same file, same Run All — different number:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# author laptop (passes)                  # colleague laptop (fails)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Cell 18: val_accuracy = 0.91              Cell 18: val_accuracy = 0.84&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Run All: green                            Run All: green — but different answer&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# and on the author&amp;#39;s own machine, rerun: 0.88&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;No traceback. No ghost variable. Three executions, three answers, zero errors. Worse: re-running on the &lt;em&gt;same&lt;/em&gt; machine drifts too.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debug the Data Before the Model</title>
      <link>http://programmer.ie/books/debugging-ai/13-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/13-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part III — Debugging Interactive and Numerical AI&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-model-bug-that-was-never-in-the-model&#34;&gt;The model bug that was never in the model&lt;/h2&gt;&#xA;&lt;p&gt;The notebook reproduces (Chapter 12): pinned env, seeded runs, hashed data, green Run All on two machines. And the fraud classifier is a star — 0.99 validation AUC overnight. The engineer begins tuning the architecture for the last point of precision. Then someone deploys it on last week&amp;rsquo;s live transactions: 0.61. Coin-flip with confidence.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Shapes, Types, Devices, and Tensors</title>
      <link>http://programmer.ie/books/debugging-ai/14-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/14-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part III — Debugging Interactive and Numerical AI&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;same-error-two-diseases&#34;&gt;Same error, two diseases&lt;/h2&gt;&#xA;&lt;p&gt;The data is honest now (Chapter 13): clean split, quarantined columns, loader contracts. Training starts — and dies on the first batch:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The engineer moves the model to CUDA. Next run, a sibling error:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RuntimeError: mat1 and mat2 shapes cannot be multiplied (32x128 and 256x64)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Both are &lt;code&gt;RuntimeError&lt;/code&gt;s from the same training step. The team debates &amp;ldquo;a device/config problem&amp;rdquo; vs. &amp;ldquo;a layer-dimension problem&amp;rdquo; — and both sound right, because the traceback points at the &lt;code&gt;matmul&lt;/code&gt; line in both cases while the actual handoff broke frames earlier.&lt;/p&gt;</description>
    </item>
    <item>
      <title>When Training Goes Wrong</title>
      <link>http://programmer.ie/books/debugging-ai/15-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/15-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part III — Debugging Interactive and Numerical AI&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-loss-curve-that-says-nothing--three-times&#34;&gt;The loss curve that says nothing — three times&lt;/h2&gt;&#xA;&lt;p&gt;Tensors flow (Chapter 14): every handoff green, batches well-formed, loss computes. And the curve is dead:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;epoch 1: loss=2.303  epoch 5: loss=2.302  epoch 20: loss=2.302&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Flat at &lt;code&gt;ln(10) ≈ 2.303&lt;/code&gt; — chance-level for ten classes. The team has seen this before: &amp;ldquo;learning rate too low, crank it.&amp;rdquo; They crank it. Now:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;epoch 1: loss=2.301  epoch 2: loss=nan&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Three candidate explanations circulate: the optimizer step is wrong (LR/pathology), the data teaches nothing (labels shuffled or inputs normalized to constants), or &lt;em&gt;nothing is actually wrong&lt;/em&gt; — the logged number is not the optimized number (logging averages the wrong tensor, eval runs on an unaugmented copy, the curve plots a stale buffer).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debugging Evaluation</title>
      <link>http://programmer.ie/books/debugging-ai/16-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/16-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part III — Debugging Interactive and Numerical AI&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;097-and-broken&#34;&gt;0.97 and broken&lt;/h2&gt;&#xA;&lt;p&gt;Training is honest now (Chapter 15): gradients flow, the overfit gate passes, the curve descends on clean data through asserted handoffs. Validation accuracy: &lt;strong&gt;0.97&lt;/strong&gt;. The demo delights. Then the engineer tries ten hand-written cases reflecting actual intent — paraphrased requests, edge phrasings, the minority class the customer cares about:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;validation accuracy: 0.97 (MEASUREMENT, n=2000, seed 42)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;intent slice (hand-written, n=40): 0.55 (MEASUREMENT, same weights, same code)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The eval says pass. The intent says fail. Both numbers are real measurements of the same model.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debugging What You Cannot See</title>
      <link>http://programmer.ie/books/debugging-ai/17-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/17-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IV — Debugging Models&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-glass-wall&#34;&gt;The glass wall&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 16 ended with an honest instrument and an unanswered question. The repaired evaluation reports, repeatably: the model fails the intent slice — wrong refund answer on split shipments, confident, cited, and wrong. No leak explains it. No metric swap rescues it. No seed relitigates it.&lt;/p&gt;&#xA;&lt;p&gt;So the engineer does the natural thing. She opens the model and looks inside — and finds there is no inside to open. No stack frame at the wrong line. No variable holding the wrong value. No &lt;code&gt;refund_id&lt;/code&gt; key to watch go missing at a handoff. There is a weights file measured in gigabytes, an API endpoint, and a text answer. The failure is behind glass: observable only through inputs and outputs, never by inspection.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Is the Model Actually the Problem?</title>
      <link>http://programmer.ie/books/debugging-ai/18-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/18-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IV — Debugging Models&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;everybody-blames-the-weights&#34;&gt;Everybody blames the weights&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 17 closed with five suspects hiding behind the same glass: prompt, retrieval, context, parameters, weights. The team&amp;rsquo;s reflex is to blame the last one — &amp;ldquo;the model can&amp;rsquo;t do split shipments, we need a bigger model&amp;rdquo; — and the vendor&amp;rsquo;s reflex is to agree, helpfully, in the direction of a larger invoice.&lt;/p&gt;&#xA;&lt;p&gt;Concrete failure. The support bot answers a split-shipment refund wrong: it cites the general 30-day policy, ignores the section 4.2 exception sitting in the knowledge base, and computes the wrong amount. The ticket says &amp;ldquo;model failure.&amp;rdquo; That label is a HYPOTHESIS, not an OBSERVATION — and in this author&amp;rsquo;s experience it is wrong about half the time, because everything the weights did was downstream of everything the pipeline handed them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Inspect the Actual Model Input</title>
      <link>http://programmer.ie/books/debugging-ai/19-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/19-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IV — Debugging Models&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-you-sent-is-not-what-it-got&#34;&gt;What you sent is not what it got&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 18 convicted the pipeline for the split-shipment refund failure. The engineer now opens her prompt file — clean, correct, citing policy 4.2 — and concludes the context was fine. It was not. What she wrote never travels alone: a system prompt prepends it, a chat template wraps it in role markers, retrieval inserts (or fails to insert) documents, and a tokenizer re-cuts every word into ids the model actually reads. Memory of the prompt is not evidence of the input.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Context Windows and Truncation</title>
      <link>http://programmer.ie/books/debugging-ai/20-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/20-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IV — Debugging Models&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-case-of-the-vanishing-exception&#34;&gt;The case of the vanishing exception&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 19 certified the rendered bytes — section 4.2 present, ids round-tripped. Yet the refund failure persists on long cases: short split-shipment queries pass, the same question with a full ticket history fails. The bytes were complete at render time and incomplete at generation time. Between the two stands a silent editor: the context window.&lt;/p&gt;&#xA;&lt;p&gt;Concrete failure. A 14,000-token assembled context (system + six retrieved sections + two years of ticket history + the question) enters a pipeline whose effective limit is 8,000 tokens. The assembler truncates from the middle — history kept, question kept, the retrieved exception dropped without a log line. The short fixture never notices; production always does.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sampling Is Part of the Program</title>
      <link>http://programmer.ie/books/debugging-ai/21-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/21-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IV — Debugging Models&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-test-that-passes-on-tuesdays&#34;&gt;The test that passes on Tuesdays&lt;/h2&gt;&#xA;&lt;p&gt;Chapters 19–20 certified the input: bytes complete, ledger balanced, nothing cut. And the split-shipment fixture still flickers — 9/12 Monday, 5/12 Wednesday, same bundle, same revision. The engineer re-runs the failing case once, watches it pass, and closes the ticket. Friday it reopens. Nothing changed except the draw.&lt;/p&gt;&#xA;&lt;p&gt;Concrete failure. At temperature 0.7 the refund answer cites 4.2 in six of ten runs and the general policy in four — same bytes, same weights, four different wrong amounts shipped to four different customers. The single-run &amp;ldquo;repro&amp;rdquo; measured a sample, not the system. The debugging object was never one output; it is the distribution over outputs that this input plus these parameters define.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Internal Signals</title>
      <link>http://programmer.ie/books/debugging-ai/22-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/22-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IV — Debugging Models&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-dip-at-the-exact-wrong-word&#34;&gt;The dip at the exact wrong word&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 21 stabilized the distribution — deterministic params, measured pass@1, flicker gated. One residue remains: on the surviving failures, can anything &lt;em&gt;inside&lt;/em&gt; the run locate where the answer went wrong? The engineer opens the token logprobs. At the exact token where the citation flips from 4.2 to the general policy, the logprob dips hard — the model, in some narrow sense, &amp;ldquo;hesitated&amp;rdquo; there. Tempting to declare the dip the cause. It is not. It is a lead.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Representation and Behavioral Diffs</title>
      <link>http://programmer.ie/books/debugging-ai/23-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/23-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IV — Debugging Models&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-upgrade-that-fixed-everything-except-the-refunds&#34;&gt;The upgrade that fixed everything (except the refunds)&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 22 closed with a repaired veer on revision A. Then the upgrade lands: revision B, announced with higher scores, migrated over a weekend. Monday the refund fixture drops from 11/12 to 7/12 — different cases fail, the citation veers at a new token, support reopens tickets the team had closed. Nothing in the pipeline changed; the weights did. Nobody ran the old behaviors against the new weights before switching, because nobody had the old behaviors pinned as an asset.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AI as Builder, Designer, Researcher, and Reviewer</title>
      <link>http://programmer.ie/books/debugging-ai/24-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/24-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part V — Debugging AI-Assisted Development and Research&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;models-are-now-collaborators--debug-their-work-products&#34;&gt;Models are now collaborators — debug their work products&lt;/h2&gt;&#xA;&lt;p&gt;Part IV established behavior-first debugging of opaque models: swap probes that change one input property at a time, input inspection that verifies what the model actually received, and sampling discipline that refuses single-run verdicts. The model was the patient on the table.&lt;/p&gt;&#xA;&lt;p&gt;That relationship just changed. Models are now collaborators producing code, designs, and research — work products you will merge, ship, and cite. Debug their work products, not just their outputs. An eloquent answer that fails its acceptance criteria is not a curiosity; it is a defective artifact entering your system.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debugging Intent</title>
      <link>http://programmer.ie/books/debugging-ai/25-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/25-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part V — Debugging AI-Assisted Development and Research&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-output-is-wrong--or-the-intent-was-never-written&#34;&gt;The output is wrong — or the intent was never written&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 24 routed defective work products by role. Most routes converge here: the builder built the wrong thing correctly because the intent was a sentence where a specification should have been. The debugging target shifts from the artifact to the artifact&amp;rsquo;s missing contract.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;OBSERVATION: a prompt reading &amp;ldquo;add pagination to the user list&amp;rdquo; returns working code that the requester rejects — wrong page size, wrong sort, wrong error shape. The code runs; the intent was never specified.&#xA;HYPOTHESIS H1 (underspecified intent): the prompt admits ≥3 compliant implementations, and the model picked one the requester did not want. H2 (model capability failure): no reasonable reading of the prompt produces the rejected behavior.&#xA;INFERENCE: none yet — H1 and H2 are separable only by an intent artifact written before regeneration. Blaming the model before pinning intent is single-run inference.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debugging Context for Coding Agents</title>
      <link>http://programmer.ie/books/debugging-ai/26-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/26-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part V — Debugging AI-Assisted Development and Research&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-contract-was-clear--the-agent-never-saw-the-files&#34;&gt;The contract was clear — the agent never saw the files&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 25 pinned intent. Now the agent with a perfect contract edits the wrong module, reimplements an existing helper, and misses the migration the contract names by path. The intent artifact is innocent. The working set is the suspect.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;OBSERVATION: the agent&amp;rsquo;s session log shows 4 files read; the fix required 7, including the migration and the helper the agent duplicated.&#xA;HYPOTHESIS H1 (missing-file): the agent never received the decisive file — retrieval omitted it or the working set excluded it. H2 (misread-file): the file was in context but the agent&amp;rsquo;s edits contradict its content — present but unused. H3 (stale context): the file was read but an older revision — edits fit a version that no longer exists.&#xA;INFERENCE: none yet — H1/H2/H3 predict different working-set dumps and are separable only by one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debugging AI-Generated Designs</title>
      <link>http://programmer.ie/books/debugging-ai/27-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/27-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part V — Debugging AI-Assisted Development and Research&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-diagram-is-beautiful--and-over-budget-by-250-milliseconds&#34;&gt;The diagram is beautiful — and over budget by 250 milliseconds&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 26 verified the agent saw the files. Now it proposes a profile endpoint fanning out to three services per request, with a sequence diagram reviewers call &amp;ldquo;clean.&amp;rdquo; The p99 budget is 200 ms. The line items sum to 450. Eloquence is not a load test.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;OBSERVATION: the design document claims &amp;ldquo;meets latency goals&amp;rdquo; while listing per-hop latencies (auth 80 ms, profile 190 ms, recommendations 180 ms) that sum past the stated 200 ms budget before queueing.&#xA;HYPOTHESIS H1 (constraint violation): the design contradicts its own numbers — no implementation of this shape can meet budget. H2 (constraint underspecification): the budget was never pinned, so &amp;ldquo;meets goals&amp;rdquo; is unverifiable prose rather than a checkable claim. H3 (tradeoff blindness): a viable alternative (cached reads, collapsed hops) exists but was never generated or compared.&#xA;INFERENCE: none yet — H1/H2/H3 predict different rows in a constraint table and are separable only by one.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debugging AI Research</title>
      <link>http://programmer.ie/books/debugging-ai/28-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/28-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part V — Debugging AI-Assisted Development and Research&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-literature-review-reads-perfectly--and-one-paper-doesnt-exist&#34;&gt;The literature review reads perfectly — and one paper doesn&amp;rsquo;t exist&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 27 priced the design. Now its &amp;ldquo;related work&amp;rdquo; section summarizes three papers with DOIs, quotes, and confident synthesis — one citation resolves to an unrelated paper, one has no retrievable byte anywhere, and the third says the opposite of what is claimed. The prose is flawless. The provenance is fiction.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debugging Coding Agents</title>
      <link>http://programmer.ie/books/debugging-ai/29-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/29-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part V — Debugging AI-Assisted Development and Research&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-agent-worked-for-40-minutes--and-the-suite-is-still-red&#34;&gt;The agent worked for 40 minutes — and the suite is still red&lt;/h2&gt;&#xA;&lt;p&gt;Chapters 24–28 debugged the agent&amp;rsquo;s work products, intent, context, designs, and sources. Now the trajectory itself is the patient: a code agent loops plan → edit → test for 40 minutes, re-applies the same patch three times, re-runs the same failing test, and closes with &amp;ldquo;fixed and verified&amp;rdquo; on a red suite. The final diff looks almost right. The path getting there is the defect.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Treat Prompts as Programs</title>
      <link>http://programmer.ie/books/debugging-ai/30-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/30-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VI — Debugging Prompts, Retrieval, and Hallucinations&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-prompt-that-just-needed-a-tweak--and-took-down-the-refund-bot&#34;&gt;The prompt that &amp;ldquo;just needed a tweak&amp;rdquo; — and took down the refund bot&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 29 ended with the trajectory triaged and the loop convicted: the agent re-applies equivalent edits because nothing in its instructions forbids equivalent retries, requires exit-code gating, or defines progress. That &amp;ldquo;nothing&amp;rdquo; has a name. It is the prompt — a program with no repository, no version, no diff, and no test, edited by folklore until it breaks in production.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Minimize the Prompt</title>
      <link>http://programmer.ie/books/debugging-ai/31-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/31-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VI — Debugging Prompts, Retrieval, and Hallucinations&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-40-line-prompt-that-fails--and-nobody-knows-which-line&#34;&gt;The 40-line prompt that fails — and nobody knows which line&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 30 versioned the prompt. Now the version is long: fourteen months of appended instructions, three example blocks, two guardrail paragraphs, a formatting schema, and a &amp;ldquo;be concise but thorough&amp;rdquo; contradiction nobody remembers adding. It fails on refund reference RB-8814 — invents a number — and every proposed fix appends line 41.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Retrieval Is a Pipeline</title>
      <link>http://programmer.ie/books/debugging-ai/32-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/32-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VI — Debugging Prompts, Retrieval, and Hallucinations&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-ledger-chunk-exists--and-the-answer-says-it-does-not&#34;&gt;The ledger chunk exists — and the answer says it does not&lt;/h2&gt;&#xA;&lt;p&gt;Chapters 30–31 versioned and minimized the prompt. Now the minimal prompt still fails: asked about refund RB-8814, the assistant invents a &amp;ldquo;processed&amp;rdquo; status while the ledger line &amp;ldquo;refund PENDING, no reference issued&amp;rdquo; sits in the corpus. The prompt is exonerated. The words arrived; the evidence did not.&lt;/p&gt;&#xA;&lt;p&gt;Concrete failure. The retriever returns five chunks for &amp;ldquo;refund RB-8814 status.&amp;rdquo; The ledger chunk is not among them. The engineer re-embeds everything, the failure persists, and the team debates the embedding model — while the actual break sits one stage downstream, invisible because &amp;ldquo;retrieval&amp;rdquo; is treated as one box.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Retriever Failure or Generator Failure?</title>
      <link>http://programmer.ie/books/debugging-ai/33-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/33-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VI — Debugging Prompts, Retrieval, and Hallucinations&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;same-wrong-refund-answer-three-different-culprits&#34;&gt;Same wrong refund answer, three different culprits&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 3 previewed this triple in miniature; Chapter 32 staged the pipeline. Now the full attribution runs. The symptom is fixed: &amp;ldquo;Your refund was processed on September 2; reference RB-8814.&amp;rdquo; The corpus truth is fixed: ledger line &amp;ldquo;refund PENDING, no reference issued,&amp;rdquo; no RB-8814 anywhere. Three incidents in three weeks produced this identical sentence — and each had a different first divergence.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debugging Hallucinations</title>
      <link>http://programmer.ie/books/debugging-ai/34-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/34-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VI — Debugging Prompts, Retrieval, and Hallucinations&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-answer-is-half-right--which-half-do-you-act-on&#34;&gt;The answer is half right — which half do you act on?&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 33 convicted the generation boundary for incident C. Now the harder case arrives: an answer with four claims, three grounded and one invented, delivered in one fluent paragraph. &amp;ldquo;Your refund is pending (ledger confirms), no reference has been issued (ledger confirms), processing typically takes 3–5 days (policy doc confirms), and reference RB-8814 was assigned September 2 (nothing confirms).&amp;rdquo; Finance can act on the first three. The fourth, acted on, emails a customer a fiction.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Model&#39;s Explanation Is Not a Trace</title>
      <link>http://programmer.ie/books/debugging-ai/35-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/35-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VI — Debugging Prompts, Retrieval, and Hallucinations&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;i-retrieved-the-ledger-confirmed-rb-8814-and-answered--none-of-which-happened&#34;&gt;&amp;ldquo;I retrieved the ledger, confirmed RB-8814, and answered&amp;rdquo; — none of which happened&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 3 stated the rule; Chapters 30–34 built the machinery that makes it enforceable. Now the capstone case. After the invented RB-8814 answer, the engineer asks the model to explain itself. It replies with a crisp chain-of-thought: &amp;ldquo;First I retrieved ticket #4471 and the refund ledger; both confirmed RB-8814; therefore I answered processed.&amp;rdquo; Every step is fluent. The retrieval log shows no ledger chunk. Ticket #4471 is another customer&amp;rsquo;s. The explanation is a second fabrication about the first fabrication — and it arrives shaped exactly like a trace.&lt;/p&gt;</description>
    </item>
    <item>
      <title>An Agent Is a Trajectory</title>
      <link>http://programmer.ie/books/debugging-ai/36-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/36-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VII — Debugging Agents&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;single-generations-are-over--the-debugging-object-is-now-the-trajectory&#34;&gt;Single generations are over — the debugging object is now the trajectory&lt;/h2&gt;&#xA;&lt;p&gt;Part VI treated the prompt as a program and pinned every claim to either retrieval or generation. That discipline holds for one call. It breaks the moment the system makes five of them: a support agent looks up order 8841, checks the refund policy, calls &lt;code&gt;issue_refund&lt;/code&gt;, re-checks the balance, and apologizes — twice refunding the customer while its final message reads perfectly. The generation is clean. The trajectory is the defect.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Trace the Agent</title>
      <link>http://programmer.ie/books/debugging-ai/37-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/37-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VII — Debugging Agents&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-log-says-tool-ran--and-nothing-else&#34;&gt;The log says &amp;ldquo;tool ran&amp;rdquo; — and nothing else&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 36 promoted the failure to a trajectory. Now the practitioner opens the log and finds this: &lt;code&gt;step 5: search_orders — ok&lt;/code&gt;, &lt;code&gt;step 6: issue_refund — ok&lt;/code&gt;, &lt;code&gt;step 9: done&lt;/code&gt;. No arguments, no returns, no state hashes, no latencies, no truncation flags. The double-refund from Chapter 36 is back, and the trace cannot separate any of its three hypotheses — the observation that would convict one of them was never written down.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Agent Failure Taxonomy</title>
      <link>http://programmer.ie/books/debugging-ai/38-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/38-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VII — Debugging Agents&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;same-wrong-answer-four-different-diseases&#34;&gt;Same wrong answer, four different diseases&lt;/h2&gt;&#xA;&lt;p&gt;Chapters 36–37 made the trajectory readable. Now the practitioner faces the next trap: two refund-agent failures look identical — &amp;ldquo;refunded twice&amp;rdquo; — but the contracted traces convict different steps. Run A repeats &lt;code&gt;issue_refund&lt;/code&gt; because the plan listed two refunds before any tool ran. Run B plans one refund but re-issues after a timeout it never saw. Identical ledgers, opposite repairs: fixing the plan cures A and leaves B broken; adding timeout handling cures B and leaves A double-spending.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Loops, Thrashing, and Retry Storms</title>
      <link>http://programmer.ie/books/debugging-ai/39-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/39-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VII — Debugging Agents&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-agent-worked-for-90-steps--and-the-state-never-moved&#34;&gt;The agent worked for 90 steps — and the state never moved&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 38 classifies single divergences. Now the practitioner watches a research agent burn 90 steps and a full API budget: &lt;code&gt;search_papers&lt;/code&gt; → &lt;code&gt;fetch_pdf&lt;/code&gt; → &lt;code&gt;parse_failed&lt;/code&gt; → &lt;code&gt;search_papers&lt;/code&gt; (same query) → &lt;code&gt;fetch_pdf&lt;/code&gt; (same URL) → &lt;code&gt;parse_failed&lt;/code&gt; … The contracted trace is complete, every step classifies somewhere, and the run still fails — because the defect is not one wrong step but zero net movement across thirty of them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Time Travel, Replay, and Forking</title>
      <link>http://programmer.ie/books/debugging-ai/40-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/40-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VII — Debugging Agents&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-if-it-had-branched-at-step-12--now-answerable&#34;&gt;&amp;ldquo;What if it had branched at step 12?&amp;rdquo; — now answerable&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 39 halts loops without explaining them. The practitioner is left with the obvious unasked question: at step 12 the agent re-issued the failed &lt;code&gt;fetch_pdf&lt;/code&gt;; had it instead switched sources, would the run have succeeded? Re-running the whole task from scratch cannot answer that — a fresh run diverges everywhere, and any success is attributable to nothing. The counterfactual needs machinery: restore the exact state at step 12, intervene once, and run forward.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Causal Replay</title>
      <link>http://programmer.ie/books/debugging-ai/41-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/41-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VII — Debugging Agents&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-fork-worked--so-the-forked-step-caused-it-not-yet&#34;&gt;The fork worked — so the forked step caused it? Not yet&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 40&amp;rsquo;s fork F1 (HTML instead of PDF at step 12) succeeded in 3/3 trials. The practitioner is tempted to close the case: the PDF action caused the failure. But the forward runs also used a different source snapshot, ran at a different hour, and consumed a parse path with its own cache — any of which could carry the change. Sensitivity shows &lt;em&gt;that&lt;/em&gt; the downstream moved; it does not show &lt;em&gt;what&lt;/em&gt; moved it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Trajectory Diff</title>
      <link>http://programmer.ie/books/debugging-ai/42-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/42-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VII — Debugging Agents&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;two-runs-same-task-opposite-ledgers--diff-the-time-not-the-text&#34;&gt;Two runs, same task, opposite ledgers — diff the time, not the text&lt;/h2&gt;&#xA;&lt;p&gt;Chapters 40–41 test one run&amp;rsquo;s counterfactuals. Now the practitioner holds something more common: run P (passing — one refund, ledger clean) and run F (failing — two refunds) on the same task, same pins, same day. The final answers differ by one sentence. The tool logs differ everywhere — retries, latencies, paraphrases — and naive text-diffing buries the one step that matters under forty cosmetic ones.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Multi-Agent Systems</title>
      <link>http://programmer.ie/books/debugging-ai/43-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/43-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VII — Debugging Agents&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;three-agents-one-failure-zero-owners&#34;&gt;Three agents, one failure, zero owners&lt;/h2&gt;&#xA;&lt;p&gt;Chapters 36–42 debugged one agent&amp;rsquo;s trajectory. Now the practitioner inherits a support pipeline with three: a triage agent classifies the ticket, a researcher agent gathers policy evidence, a action agent issues the refund. The ledger shows the familiar double-refund — and each agent&amp;rsquo;s local trace looks clean. Triage passed the right category; research cited the right policy; action executed what it received. The defect lives in none of the trajectories and in all of the gaps between them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Can One AI Debug Another?</title>
      <link>http://programmer.ie/books/debugging-ai/44-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/44-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VIII — Building the AI Debugger&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-assistant-that-explained-everything-and-proved-nothing&#34;&gt;The assistant that explained everything and proved nothing&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 43 closed with a direct question: the trajectories are routable by human practitioners — but can any of that discipline be delegated to an AI system without inheriting the failure modes this book forbids? Here is the concrete version. A practitioner hands a failing agent trajectory to a capable assistant model: &amp;ldquo;find the bug.&amp;rdquo; Minutes later the assistant returns a fluent, confident report — root cause identified, three supporting quotes, a suggested fix. The practitioner applies the fix. The symptom disappears once, returns the next day, and nobody can say which of the assistant&amp;rsquo;s claims was ever evidence and which was narration.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The AI Crash Dump</title>
      <link>http://programmer.ie/books/debugging-ai/45-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/45-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VIII — Building the AI Debugger&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-failure-that-could-not-be-reopened&#34;&gt;The failure that could not be reopened&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 44 permitted the AI assistant to propose — but only from a frozen, hashed bundle. That bundle did not yet exist as a defined artifact. Here is why it must. A practitioner investigates a support chatbot that quoted a refund policy nobody can find. She screenshots the answer, copies the prompt from memory, and asks the team to reproduce it. Three days later nobody can: the model version has rolled forward, the retrieved documents have been re-indexed, the temperature was never recorded, and the &amp;ldquo;prompt&amp;rdquo; she saved differs by two sentences from what was actually sent. The failure is real, witnessed — and undebuggable.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Diagnostic AI Invariants</title>
      <link>http://programmer.ie/books/debugging-ai/46-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/46-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VIII — Building the AI Debugger&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-assistant-that-broke-every-rule-politely&#34;&gt;The assistant that broke every rule politely&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 45 froze the past; this chapter polices the consumer. A practitioner runs a well-bundled failure through a debugging assistant that returns a report violating, in one page, every rule Chapters 01–03 established: its &amp;ldquo;observations&amp;rdquo; are paraphrases, its single hypothesis arrives with no competitor, its conclusion cites the assistant&amp;rsquo;s own confidence and one passing run, and the fix ships to production without human review. The bundle was perfect. The discipline was absent — because nothing checked it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>From Symptom to Hypotheses</title>
      <link>http://programmer.ie/books/debugging-ai/47-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/47-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VIII — Building the AI Debugger&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-clever-hypothesis-that-missed-the-boring-cause&#34;&gt;The clever hypothesis that missed the boring cause&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 46 can reject single-story reports — but it needs a defined space of competitors to judge plurality against. Here is the failure that space prevents. A RAG answer fabricates a citation. The assistant proposes one elegant hypothesis — &amp;ldquo;the reranker demoted the gold chunk&amp;rdquo; — with a sophisticated test involving score analysis. The team spends a week on reranker tuning. The actual cause is mundane: a stale index snapshot meant the gold chunk was never retrieved at all. Nobody listed it because nobody enumerated; cleverness covered one branch while coverage would have covered all of them.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Discriminating Experiments</title>
      <link>http://programmer.ie/books/debugging-ai/48-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/48-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VIII — Building the AI Debugger&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;three-hypotheses-nine-runs-one-lesson&#34;&gt;Three hypotheses, nine runs, one lesson&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 47 mapped the space; this chapter prices the search. A practitioner holds three live hypotheses for a RAG fabrication — stale snapshot (H1), reranker demotion (H2), prompt override (H3) — and runs them naively: re-index (expensive, hours), retrain the reranker (days), rewrite the prompt five ways (scattershot). Nine runs later H1 is confirmed by accident — the re-index fixed it — but the prompt rewrites also &amp;ldquo;helped&amp;rdquo; once each, the reranker retrain changed scores without changing outcomes, and nobody can say which run proved what because two variables moved per run and predictions were written after seeing outputs.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Do You Know the Diagnosis Is Right?</title>
      <link>http://programmer.ie/books/debugging-ai/49-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/49-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VIII — Building the AI Debugger&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-diagnosis-that-survived-everything-except-verification&#34;&gt;The diagnosis that survived everything except verification&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 48 split the space to one survivor — but survival is not proof. A practitioner holds H1 (stale snapshot) as the last branch standing for the fabricated citation: the chunk was absent, expansion changed nothing, wording swaps changed nothing. She ships the re-index, the symptom disappears for a week, and the postmortem records &amp;ldquo;root cause: stale index.&amp;rdquo; A month later the fabrication returns with a fresh index. The original evidence never distinguished &amp;ldquo;stale snapshot caused it&amp;rdquo; from &amp;ldquo;stale snapshot accompanied it&amp;rdquo; — no prediction-match ledger, no independent verification evidence, no human sign-off on the causal claim. The branch survived; the diagnosis was never verified.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AIDebugBench</title>
      <link>http://programmer.ie/books/debugging-ai/50-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/50-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VIII — Building the AI Debugger&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-leaderboard-that-measured-nothing&#34;&gt;The leaderboard that measured nothing&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 49 verified single diagnoses; this chapter asks what would measure debugging skill itself. A team ships &amp;ldquo;DebugScore&amp;rdquo;: an assistant is given fifty broken AI setups, its fixes are graded by whether the symptom disappears, and the resulting number — 87% — is cited in planning docs as proof the debugger works. Nobody asks whether the tasks resemble the book&amp;rsquo;s failure modes, whether grading checked exoneration of alternatives or just relief, whether the assistant had seen the tasks in training, or whether one trial per task decided each score. The number is precise, reported, and evidentially empty.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debug the Debugger</title>
      <link>http://programmer.ie/books/debugging-ai/51-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/51-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part VIII — Building the AI Debugger&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-checker-that-passed-everything&#34;&gt;The checker that passed everything&lt;/h2&gt;&#xA;&lt;p&gt;Chapters 44–50 built an impressive machine: gated assistants, frozen bundles, invariant checkers, enumerated spaces, discriminating runs, verification ledgers, a benchmark design. Then a practitioner notices the invariant checker has passed every report for a month — including one she hand-verified as containing an unresolving citation. The cause is embarrassing: a bundle migration changed the hash algorithm, the checker&amp;rsquo;s resolver silently failed open, and every I-2 verdict since is theater. The debugging system debugged everything except itself.&lt;/p&gt;</description>
    </item>
    <item>
      <title>AI Observability</title>
      <link>http://programmer.ie/books/debugging-ai/52-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/52-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IX — Production Debugging and Prevention&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-refund-that-nobody-can-replay&#34;&gt;The refund that nobody can replay&lt;/h2&gt;&#xA;&lt;p&gt;Part VIII built machine-assisted debugging machinery: contracted traces, hypothesis generation under evidence rules, discriminating experiments checked by intervention outcomes. That machinery means nothing without production observability. A practitioner inherits exactly this: a support agent double-refunds one customer on Tuesday, the on-call engineer asks what the model saw, and the answer is a dashboard screenshot of the output text plus a log line reading &lt;code&gt;POST /chat 200 812ms&lt;/code&gt;. No prompt hash, no retrieved documents, no parameters, no seed. The incident is real, the evidence is gone, and every diagnosis from here on is storytelling.&lt;/p&gt;</description>
    </item>
    <item>
      <title>From Production Failure to Regression</title>
      <link>http://programmer.ie/books/debugging-ai/53-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/53-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IX — Production Debugging and Prevention&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-fix-that-fixed-nothing--twice&#34;&gt;The fix that fixed nothing — twice&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 52 ended with a replayable record: the double-refund request re-assembled bit-exact, reproduced 2-of-3 trials, guardrail verdict empty. The on-call engineer ships the obvious repair — a prompt sentence forbidding double authorization — and closes the incident. Six weeks later the same double-refund returns under a reworded ticket, and nobody can say whether the old fix failed or a new defect arrived: no bundle was frozen, no repro was pinned, no regression test exists. The team fixed forward twice and learned nothing once.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Runtime Invariants and Guardrails</title>
      <link>http://programmer.ie/books/debugging-ai/54-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/54-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IX — Production Debugging and Prevention&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-guardrail-that-watched-the-wrong-door&#34;&gt;The guardrail that watched the wrong door&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 53 ended with a contractual repair and a bidirectional test: scope-less tickets now reject-and-ask in CI. In production, the next scope-less ticket still double-spends. The postmortem reveals why: the guardrail checked citation &lt;em&gt;format&lt;/em&gt; at the output, while the defect lived at the &lt;em&gt;handoff&lt;/em&gt; between research and action — an unchecked edge the guardrail never evaluated. The team owned a passing test and an unguarded path. Validation without enforcement is a wish.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debugging Cost and Latency</title>
      <link>http://programmer.ie/books/debugging-ai/55-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/55-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IX — Production Debugging and Prevention&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-invoice-nobody-can-attribute&#34;&gt;The invoice nobody can attribute&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 54 ended with enforced checkpoints: known-bad acts refuse before they commit. Then finance forwards a $40,000 monthly inference bill — triple the forecast — alongside p99 latency at 90 seconds, and the team argues from vibes. &amp;ldquo;The model got expensive&amp;rdquo; blames the vendor; &amp;ldquo;users ask longer questions&amp;rdquo; blames the customers; &amp;ldquo;add caching&amp;rdquo; prescribes before attributing. The Chapter 52 records hold per-stage segments, but nobody has ever assembled them into a ledger. Spend and delay are debuggable quantities. The team is debugging them as weather.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Debugging in Production</title>
      <link>http://programmer.ie/books/debugging-ai/56-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/56-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part IX — Production Debugging and Prevention&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;0214-three-responders-zero-procedure&#34;&gt;02:14, three responders, zero procedure&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 55 ended with an attributed ledger and joint-verdict optimizations — peacetime instruments. At 02:14 the refund agent starts authorizing duplicates at volume, the page fires, and three responders improvise three different incidents: one restarts the service (destroying in-flight evidence), one edits the prompt in the dashboard (a multi-variable repair under fire), one announces &amp;ldquo;we&amp;rsquo;re investigating&amp;rdquo; in the status channel and then goes silent for forty minutes. By dawn the bleeding stopped — nobody knows which act stopped it, the bundle was never frozen, and the postmortem reconstructs courage instead of causation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Ten-Minute Debug</title>
      <link>http://programmer.ie/books/debugging-ai/57-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/57-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part X — The Debugging AI Playbook&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;ten-minutes-one-failing-request-no-permission-to-boil-the-ocean&#34;&gt;Ten minutes, one failing request, no permission to boil the ocean&lt;/h2&gt;&#xA;&lt;p&gt;Part IX closed with the full method under production load: emit, convey, enforce, book, respond in order. Now the practitioner gets reality: ten minutes before the deploy review, one user-flagged refusal that &amp;ldquo;worked yesterday,&amp;rdquo; and no authority to freeze slices or convene commanders. The temptation is full rigor in miniature — a five-stage conveyor, a calibration set, and a ledger before lunch. That fiction produces the worst outcome: ten minutes spent starting everything and finishing nothing, with a confident verdict announced to fill the silence.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The One-Hour Investigation</title>
      <link>http://programmer.ie/books/debugging-ai/58-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/58-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part X — The Debugging AI Playbook&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;one-hour-one-defect-pins-available&#34;&gt;One hour, one defect, pins available&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 57 ended with a routed handoff: the flagged refusal triaged, pins UNKNOWN, no verdict, hour queue. Now the practitioner sits down with sixty protected minutes, log access, pinned environment, and the handoff record. The failure is concrete: the research agent&amp;rsquo;s answers degraded after Tuesday&amp;rsquo;s index refresh — some queries cite stale policy, others refuse outright. One hour is the book&amp;rsquo;s standard depth: enough to isolate, not enough to certify.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Full AI Incident Investigation</title>
      <link>http://programmer.ie/books/debugging-ai/59-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/59-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part X — The Debugging AI Playbook&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-incident-that-owes-a-published-record&#34;&gt;The incident that owes a published record&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 58 ended with isolation and queued artifacts: one defect, one repair candidate, deeper questions deferred. Now the incident that defeats the hour: a weekend of duplicate refunds across hundreds of accounts, two services disagreeing on whose handoff dropped scope, a regulator asking what happened, and leadership asking what prevents recurrence. Triage routed it; the hour isolated one edge; neither suffices. This incident owes customers remediation, the team prevention, and the record an account — with named roles producing named artifacts on a visible schedule.&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Debugging AI Toolkit</title>
      <link>http://programmer.ie/books/debugging-ai/60-chapter/</link>
      <pubDate>Sun, 06 Sep 2026 21:00:00 +0000</pubDate>
      <guid>http://programmer.ie/books/debugging-ai/60-chapter/</guid>
      <description>&lt;p&gt;&lt;em&gt;Part X — The Debugging AI Playbook&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;sixty-chapters-one-workbench--and-the-question-of-what-it-proved&#34;&gt;Sixty chapters, one workbench — and the question of what it proved&lt;/h2&gt;&#xA;&lt;p&gt;Chapter 59 ended with the published packet: one incident fully accounted, generality bounded on the final page. Now the practitioner faces the opposite problem — not one incident with a full procedure but any symptom with sixty chapters behind it. Which instrument, in which order, for this failure? The failure is meta and concrete at once: a teammate asks &amp;ldquo;the agent is wrong and slow — where do I start?&amp;rdquo; and the answer cannot be &amp;ldquo;read the book again.&amp;rdquo; Sixty chapters that cannot be selected under pressure are sixty chapters shelved.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
