<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Ai on Lack of Imagination</title>
    <link>https://lackofimagination.org/tags/ai/</link>
    <description>Recent content in Ai on Lack of Imagination</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 04 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://lackofimagination.org/tags/ai/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Letting AI Debug Production</title>
      <link>https://lackofimagination.org/2026/09/letting-ai-debug-production/</link>
      <pubDate>Fri, 04 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://lackofimagination.org/2026/09/letting-ai-debug-production/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s 2 in the morning, and you&amp;rsquo;re reading an incident channel: checkout is failing, orders are stuck, and support is starting to field angry messages from customers who can&amp;rsquo;t get past payment. After quite a bit of digging through the logs, you find the cause. It was a rejected payment call buried deep in thousands of entries. And you&amp;rsquo;re left thinking: this is exactly the kind of grunt work an AI agent should be able to take off your hands.&lt;/p&gt;
&lt;p&gt;For AI coding assistants, writing new code is the easy part. The hard part has always been maintenance. But you can&amp;rsquo;t just set an agent loose in production. It can easily corrupt the database, and all it can do afterwards is apologize and promise not to do it again.&lt;/p&gt;
&lt;p&gt;An agent debugging a codebase can read the code and guess, or execute the code and risk side effects. Test suites by themselves are not enough because a production incident is, by definition, a case the tests didn&amp;rsquo;t cover. What AI, or humans, for that matter, actually need is a way to run the failing scenario with the real data, without touching production.&lt;/p&gt;
&lt;p&gt;Deterministic replay solves exactly this problem. If every side effect the business logic performs is recorded as it happens, and the logic can later be rerun against those recordings, a production failure effectively becomes a sandbox.&lt;/p&gt;
&lt;p&gt;This is the core idea behind &lt;a href=&#34;https://github.com/aycangulez/pure-effect&#34;&gt;Pure Effect&lt;/a&gt;, a lightweight JavaScript/TypeScript library I&amp;rsquo;ve been developing for almost a year now. Business logic returns plain data describing the I/O it wants. Then an interpreter executes it. Because a flow is data until interpreted, a production run can be recorded into a trace: what every step returned or threw. And here&amp;rsquo;s the neat trick: that exact trace can be fed right back through the same flow later, completely offline without a database or network connection.&lt;/p&gt;
&lt;p&gt;This general approach isn&amp;rsquo;t new. Record/replay debugging has existed in various forms. What&amp;rsquo;s different here is that the business logic is expressed as plain data, and the library needs no infrastructure to run.&lt;/p&gt;
&lt;p&gt;Think of the trace as a flight recorder, and replay as the simulator loaded with it. During replay, your business logic runs for real, every branch, every decision, but each time it reaches a step that would talk to the outside world, it gets the recorded answer from the incident instead. The function that would call your payment provider never actually runs.&lt;/p&gt;

 
  
  
  
  
    
      
    
  
    
  


&lt;br&gt;
&lt;div class=&#34;figure center&#34; &gt;
  
    &lt;img class=&#34;fig-img&#34; src=&#34;https://lackofimagination.org/images/diagram-record-replay.svg&#34; &gt;
  
  
&lt;/div&gt;

  &lt;div style=&#34;clear:both;&#34;&gt;&lt;/div&gt;

&lt;p&gt;Giving an AI agent the failing trace allows it to rerun the incident as many times as it needs. If a change alters which steps execute, the replay says so. If the fix changes how the flow handles a recorded answer, the same recording now plays through to success. The worst thing an agent can do in this loop is be wrong, and being wrong costs some tokens, not a duplicate charge to a customer.&lt;/p&gt;
&lt;p&gt;One nice side effect is that the incident itself becomes a permanent part of the regression test suite, and since there&amp;rsquo;s no I/O, the test runs in microseconds.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s our deliberately buggy checkout flow. Each function returns either a plain result or a description of one I/O step. Nothing here directly executes any I/O.&lt;/p&gt;
&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-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;import&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;Success&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;Command&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;effectPipe&lt;/span&gt; } &lt;span style=&#34;color:#a6e22e&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;pure-effect&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&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;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;fetchCart&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;) =&amp;gt; {
&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;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;cmdFetchCart&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;db&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;getCart&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;cartId&lt;/span&gt;);
&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; &lt;span style=&#34;color:#a6e22e&#34;&gt;Command&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;cmdFetchCart&lt;/span&gt;, (&lt;span style=&#34;color:#a6e22e&#34;&gt;cart&lt;/span&gt;) =&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Success&lt;/span&gt;({ ...&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;cart&lt;/span&gt; }));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&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;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;applyPromo&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;) =&amp;gt; {
&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;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;cmdValidatePromo&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;promos&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;validate&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;promoCode&lt;/span&gt;);
&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; &lt;span style=&#34;color:#a6e22e&#34;&gt;Command&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;cmdValidatePromo&lt;/span&gt;, (&lt;span style=&#34;color:#a6e22e&#34;&gt;promo&lt;/span&gt;) =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;promo&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;valid&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;?&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Success&lt;/span&gt;({ ...&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;total&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;cart&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;total&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; &lt;span style=&#34;color:#a6e22e&#34;&gt;promo&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;discount&lt;/span&gt;) })
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Success&lt;/span&gt;({ ...&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;total&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;cart&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;total&lt;/span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    );
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&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;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;chargeCard&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;) =&amp;gt; {
&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;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;cmdChargeCard&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;payments&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;charge&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;customerId&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;total&lt;/span&gt;);
&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; &lt;span style=&#34;color:#a6e22e&#34;&gt;Command&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;cmdChargeCard&lt;/span&gt;, (&lt;span style=&#34;color:#a6e22e&#34;&gt;receipt&lt;/span&gt;) =&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Success&lt;/span&gt;({ ...&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;receipt&lt;/span&gt; }));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&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;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;checkoutFlow&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;) =&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;effectPipe&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;fetchCart&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;applyPromo&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;chargeCard&lt;/span&gt;)(&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Every step in &lt;code&gt;effectPipe&lt;/code&gt; receives the value the previous step produced, so the pipeline reads top-to-bottom as the flow of data. Each I/O step is wrapped in a &lt;code&gt;Command&lt;/code&gt;: a function that makes the I/O call, plus a &amp;ldquo;next&amp;rdquo; function that receives the answer and decides what happens next: a &lt;code&gt;Success&lt;/code&gt;, a &lt;code&gt;Failure&lt;/code&gt;, or another &lt;code&gt;Command&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;No one wrote the case where a promo discounts the cart to zero, so when a 100% VIP promo is used, &lt;code&gt;applyPromo&lt;/code&gt; computes a total of 0, &lt;code&gt;chargeCard&lt;/code&gt; dutifully asks the payment provider to charge nothing, and the provider rightfully refuses.&lt;/p&gt;
&lt;p&gt;In production, recording is a hook installed once at startup, so failure traces are captured without touching the existing code. We can record specific flows with &lt;code&gt;recordEffect&lt;/code&gt; as well:&lt;/p&gt;
&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-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;result&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;trace&lt;/span&gt; } &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;recordEffect&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;checkoutFlow&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;);
&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;// result.type === &amp;#39;Failure&amp;#39;, and trace is plain JSON
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The recording can be replayed without needing access to the production environment:&lt;/p&gt;
&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-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;timeTravel&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;checkoutFlow&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;trace&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&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;Replaying &amp;#39;flow&amp;#39; (3 recorded steps)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Initial input: { &amp;#34;cartId&amp;#34;: &amp;#34;cart_42&amp;#34;, &amp;#34;promoCode&amp;#34;: &amp;#34;FREE_YEAR_VIP&amp;#34;, ... }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Step 1: cmdFetchCart returned { &amp;#34;total&amp;#34;: 120 }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Step 2: cmdValidatePromo returned { &amp;#34;valid&amp;#34;: true, &amp;#34;discount&amp;#34;: 1 }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Step 3: cmdChargeCard threw { &amp;#34;message&amp;#34;: &amp;#34;Amount must be non-zero.&amp;#34;, &amp;#34;code&amp;#34;: &amp;#34;invalid_amount&amp;#34; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Replay finished with state: Failure
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Three lines make the whole flow visible: valid promo, full discount, zero-amount charge attempt. No log hunting or reproducing the customer&amp;rsquo;s cart in staging is necessary.&lt;/p&gt;

 
  
  
  
  
    
      
    
  
    
  


&lt;br&gt;
&lt;div class=&#34;figure center&#34; &gt;
  
    &lt;img class=&#34;fig-img&#34; src=&#34;https://lackofimagination.org/images/diagram-agent-loop.svg&#34; &gt;
  
  
&lt;/div&gt;

  &lt;div style=&#34;clear:both;&#34;&gt;&lt;/div&gt;

&lt;p&gt;With the trace at hand, an agent can replay the incident, spot the unconditional charge, and produce a fix:&lt;/p&gt;
&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-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;chargeCard&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; (&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;) =&amp;gt; {
&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; (&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;total&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Success&lt;/span&gt;({ ...&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;receipt&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;amount&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;waived&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt; } });
&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;const&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;cmdChargeCard&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;payments&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;charge&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;customerId&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;total&lt;/span&gt;);
&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; &lt;span style=&#34;color:#a6e22e&#34;&gt;Command&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;cmdChargeCard&lt;/span&gt;, (&lt;span style=&#34;color:#a6e22e&#34;&gt;receipt&lt;/span&gt;) =&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Success&lt;/span&gt;({ ...&lt;span style=&#34;color:#a6e22e&#34;&gt;order&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;receipt&lt;/span&gt; }));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For verification, the agent replays the same incident recording against the fixed flow:&lt;/p&gt;
&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-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;result&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;unreached&lt;/span&gt; } &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;replayEffect&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;checkoutFlow&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;trace&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;initialInput&lt;/span&gt;), &lt;span style=&#34;color:#a6e22e&#34;&gt;trace&lt;/span&gt;);
&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;// result.type === &amp;#39;Success&amp;#39;, result.value.receipt.waived === true
&lt;/span&gt;&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;// unreached.map((e) =&amp;gt; e.command) is [&amp;#39;cmdChargeCard&amp;#39;]: the charge was never issued
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The recording that used to end in a failure now plays through to success because the flow no longer asks the payment step to run. The final commit includes the incident as a permanent test:&lt;/p&gt;
&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-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;it&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;incident 42: a 100% promo checks out without a charge&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;async&lt;/span&gt; () =&amp;gt; {
&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;const&lt;/span&gt; { &lt;span style=&#34;color:#a6e22e&#34;&gt;result&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;unreached&lt;/span&gt; } &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;await&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;replayEffect&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;checkoutFlow&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;trace&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;initialInput&lt;/span&gt;), &lt;span style=&#34;color:#a6e22e&#34;&gt;trace&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;assert&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;equal&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;result&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;type&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Success&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;assert&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;equal&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;result&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;value&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;receipt&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;waived&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;assert&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;deepEqual&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;unreached&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;map&lt;/span&gt;((&lt;span style=&#34;color:#a6e22e&#34;&gt;e&lt;/span&gt;) =&amp;gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;e&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;command&lt;/span&gt;), [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;cmdChargeCard&amp;#39;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You&amp;rsquo;ve probably noticed that replay cannot confirm fixes that insert or reorder steps in the pipeline, so a fix that alters the step sequence causes replay to stop at that exact point. This is by design to ensure that the simulation never violates causality. Asking for a different step than the one recorded at that point halts with a literal &lt;code&gt;TimeParadox&lt;/code&gt; error.&lt;/p&gt;
&lt;p&gt;In practice, there is a 2-tier solution for this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tier 1 (Agent): Tries to fix the bug within the existing effect topology (fixing edge cases, null checks, etc.). Verifies via replay.&lt;/li&gt;
&lt;li&gt;Tier 2 (Human): If the fix requires architectural changes, new external I/O, or a change to what a failing step sends, the agent gives up and pages the engineer on call.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pure Effect doesn&amp;rsquo;t require a rewrite of everything you own. Structure the logic you actually care about as flows. Install recording once at startup, keep the failure traces, and run &lt;code&gt;redact&lt;/code&gt; over anything sensitive before a trace leaves the process. From there, the rules for your agent are simple: keep pipeline steps pure, push all non-determinism into Commands, and don&amp;rsquo;t alter the execution sequence.&lt;/p&gt;
&lt;p&gt;Granted, letting an agent auto-patch a live billing flow might be pushing it. Maybe someday we&amp;rsquo;ll trust them with that. But even today, an agent can verify a fix offline and open a pull request with an attached regression test before paging you.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href=&#34;https://github.com/aycangulez/pure-effect&#34;&gt;pure-effect&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
