<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Aquil Abdullah</title>
    <description>The latest articles on Forem by Aquil Abdullah (@aabdullahbos).</description>
    <link>https://forem.com/aabdullahbos</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F158375%2Fba3863e1-e19b-47b0-a6f9-4c7aa92e60a6.jpeg</url>
      <title>Forem: Aquil Abdullah</title>
      <link>https://forem.com/aabdullahbos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/aabdullahbos"/>
    <language>en</language>
    <item>
      <title>Vibe Coding Needs Telemetry</title>
      <dc:creator>Aquil Abdullah</dc:creator>
      <pubDate>Thu, 26 Mar 2026 20:00:19 +0000</pubDate>
      <link>https://forem.com/aabdullahbos/vibe-coding-needs-telemetry-29mi</link>
      <guid>https://forem.com/aabdullahbos/vibe-coding-needs-telemetry-29mi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published at: &lt;a href="https://www.aquilabdullah.com/your-post-url" rel="noopener noreferrer"&gt;https://www.aquilabdullah.com/your-post-url&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;I recently noticed something strange in the backend telemetry of a code base that I was working on.&lt;/p&gt;

&lt;p&gt;A single API request was triggering more than twenty database calls.&lt;/p&gt;

&lt;p&gt;The code looked perfectly reasonable, but the telemetry told a very different story.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Simple Vibe Coding Exercise
&lt;/h2&gt;

&lt;p&gt;Imagine you're building a simple profile endpoint.&lt;/p&gt;

&lt;p&gt;You ask your AI assistant to create something that returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;user information
&lt;/li&gt;
&lt;li&gt;the sports they participate in
&lt;/li&gt;
&lt;li&gt;posts they've written
&lt;/li&gt;
&lt;li&gt;events they're attending
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A reasonable implementation might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_user_sports&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_user_posts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;events&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_user_events&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sports&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;posts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;events&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this looks great.&lt;/p&gt;

&lt;p&gt;Each function is small.&lt;br&gt;&lt;br&gt;
Each responsibility is clear.&lt;br&gt;&lt;br&gt;
The code is readable and easy to test.&lt;/p&gt;

&lt;p&gt;From the perspective of &lt;strong&gt;local code correctness&lt;/strong&gt;, this is good code.&lt;/p&gt;

&lt;p&gt;But from the perspective of &lt;strong&gt;system behavior&lt;/strong&gt;, something subtle may have just happened.&lt;/p&gt;


&lt;h2&gt;
  
  
  The N+1 Query Problem
&lt;/h2&gt;

&lt;p&gt;If each of those helper functions hits the database, this endpoint just turned into multiple queries.&lt;/p&gt;

&lt;p&gt;Instead of one database call, we now have several.&lt;/p&gt;

&lt;p&gt;This pattern is known as the &lt;strong&gt;N+1 query problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It usually appears when you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run 1 query to fetch a list
&lt;/li&gt;
&lt;li&gt;then run N additional queries to fetch related data
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;get_users&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;get_posts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you load 10 users, that becomes 11 queries.&lt;br&gt;&lt;br&gt;
If you load 100 users, that becomes 101 queries.&lt;/p&gt;

&lt;p&gt;Each individual query is fast.&lt;/p&gt;

&lt;p&gt;But together they create unnecessary load and extra round trips.&lt;/p&gt;

&lt;p&gt;What started as clean, modular code quietly turns into a &lt;strong&gt;query fan-out pattern&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  When Telemetry Tells a Different Story
&lt;/h2&gt;

&lt;p&gt;It took me a minute to realize what I was looking at.&lt;/p&gt;

&lt;p&gt;The endpoint didn’t look suspicious, but the telemetry did.&lt;/p&gt;

&lt;p&gt;During a single request, I saw repeated database calls like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;21:15:40 GET /sports
21:15:40 GET /users
21:15:40 GET /event_rsvps
21:15:41 GET /sports
21:15:41 GET /users
21:15:41 GET /event_rsvps
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same resources being requested over and over again.&lt;/p&gt;

&lt;p&gt;The code looked clean.&lt;/p&gt;

&lt;p&gt;But the system was doing far more work than I expected.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Happens More With AI
&lt;/h2&gt;

&lt;p&gt;AI coding tools are very good at generating &lt;strong&gt;locally correct code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They optimize for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;readability
&lt;/li&gt;
&lt;li&gt;modularity
&lt;/li&gt;
&lt;li&gt;clear abstractions
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But they don’t automatically reason about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;query fan-out
&lt;/li&gt;
&lt;li&gt;database round trips
&lt;/li&gt;
&lt;li&gt;system-level performance
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So you end up with code that looks right, but behaves differently than you expect at runtime.&lt;/p&gt;




&lt;h2&gt;
  
  
  Fixing the Query Fan-Out
&lt;/h2&gt;

&lt;p&gt;Once you notice an N+1 pattern, the solution is usually to move more work into the database.&lt;/p&gt;

&lt;p&gt;Common approaches include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JOIN queries
&lt;/li&gt;
&lt;li&gt;database views
&lt;/li&gt;
&lt;li&gt;materialized views
&lt;/li&gt;
&lt;li&gt;RPC functions
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this case, I used a &lt;strong&gt;database RPC function&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of making multiple application-level calls, the database assembles the full result in a single operation.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before:
API → many database calls

After:
API → single RPC → database assembles result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reduces round trips and makes the endpoint behavior predictable.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Observability Mindset
&lt;/h2&gt;

&lt;p&gt;What struck me most about this bug was that the code itself looked perfectly reasonable.&lt;/p&gt;

&lt;p&gt;Nothing obviously inefficient.&lt;/p&gt;

&lt;p&gt;But telemetry told a different story.&lt;/p&gt;

&lt;p&gt;That’s the shift that comes with AI-assisted development.&lt;/p&gt;

&lt;p&gt;We can generate systems faster than ever.&lt;/p&gt;

&lt;p&gt;But speed makes it easier to miss how those systems behave under the hood.&lt;/p&gt;

&lt;p&gt;Telemetry gives you visibility into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how many queries an endpoint triggers
&lt;/li&gt;
&lt;li&gt;how requests flow through your system
&lt;/li&gt;
&lt;li&gt;where load is actually happening
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without it, you're relying on what the code suggests.&lt;/p&gt;

&lt;p&gt;With it, you can see what the system is actually doing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Before and After
&lt;/h2&gt;

&lt;p&gt;Before the fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request → ~20 database queries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After moving the logic into an RPC function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request → 1 database call
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same endpoint.&lt;br&gt;&lt;br&gt;
Very different behavior.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing Thought
&lt;/h2&gt;

&lt;p&gt;AI can generate endpoints quickly.&lt;br&gt;&lt;br&gt;
Telemetry tells you what those endpoints are actually doing.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>ai</category>
      <category>observability</category>
      <category>performance</category>
    </item>
    <item>
      <title>Co-programming with GPT-4o: A Love Story Gone Recursive</title>
      <dc:creator>Aquil Abdullah</dc:creator>
      <pubDate>Fri, 16 May 2025 23:33:36 +0000</pubDate>
      <link>https://forem.com/aabdullahbos/co-programming-with-gpt-4o-a-love-story-gone-recursive-3pf7</link>
      <guid>https://forem.com/aabdullahbos/co-programming-with-gpt-4o-a-love-story-gone-recursive-3pf7</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgch13zkgsg4a1ck0ledx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgch13zkgsg4a1ck0ledx.jpg" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we get started, let’s get one thing straight: this article breaks no new ground!&lt;/p&gt;

&lt;p&gt;If you search Google, Bing, DuckDuckGo, or Perplexity for the phrase “Co-programming with GPT-4o,” you’ll find plenty of tales of woe about using GPT-4o as your pair programming partner.&lt;/p&gt;

&lt;p&gt;So why did I do it?&lt;/p&gt;

&lt;p&gt;Well, besides being a glutton for punishment, I asked GPT-4o,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“What is the best OpenAI model for co-programming?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And it replied:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“[GPT-4o] 🔥 Overall best for co-programming.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5a6g5zkpxmy27bw57ch7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5a6g5zkpxmy27bw57ch7.jpg" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So there you have it! ChatGPT-4o told me it was the &lt;strong&gt;&lt;em&gt;“Best of the best of the best…Sir!”&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  We Hit It Off Swell!
&lt;/h3&gt;

&lt;p&gt;Everything started out great. I had an idea, and GPT-4o chatted me up. It told me how amazing my idea was and promised to help turn it into an app.&lt;/p&gt;

&lt;p&gt;It provided me with a skeleton for the codebase and even gave me the exact statements I’d need to get started. We waxed philosophically about the merits of npm and yarn, and why it chose npm for this project.&lt;/p&gt;

&lt;p&gt;When I mentioned that I wanted to use TypeScript instead of JavaScript, GPT-4o kindly converted the code and pointed out which type definitions I needed to install.&lt;/p&gt;

&lt;p&gt;At this point, we were totally vibing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30751urk5q4bm1ayodpp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F30751urk5q4bm1ayodpp.jpg" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was poo-pooing everyone who had claimed GPT-4o couldn’t code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;YOU DOWN WITH GPT?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;YEAH YOU KNOW ME.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Code? What Code?
&lt;/h3&gt;

&lt;p&gt;A few days later, I came back to my prototype to make some frontend changes. GPT-4o walked me through the edits, asked if I wanted it to generate a new file, and I said yes.&lt;/p&gt;

&lt;p&gt;I first suspected something was off when I noticed the new file was 50 lines shorter. When I ran the app, the styling was completely different.&lt;/p&gt;

&lt;p&gt;I asked what went wrong. GPT-4o told me it had lost context. I offered to upload the current version, and it obliged — we were back on track.&lt;/p&gt;

&lt;p&gt;There were a few more moments like this — context loss during refactoring, odd choices I wouldn’t have made — but I wrote them off as the cost of doing business.&lt;/p&gt;

&lt;p&gt;I was still down with GPT.&lt;/p&gt;

&lt;p&gt;But was GPT-4o still down with me?&lt;/p&gt;

&lt;h3&gt;
  
  
  The Ides of March or Et tu GPT-4o
&lt;/h3&gt;

&lt;p&gt;The final blow came when I was refactoring some logging logic. My good friend GPT-4o suggested we DRY up the code. I was like:&lt;/p&gt;

&lt;p&gt;“OK, GPT-4o, I see you modularizing my code and making reusable components!”&lt;/p&gt;

&lt;p&gt;It took this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LOG_PATH&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../logs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;conversations.jsonl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And converted them into the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getLogFilePath&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;logDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LOG_DIR&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nf"&gt;getLogFileDir&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 🚨 infinite recursion!&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;logPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Path2D&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;conversations.jsonl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;logPath&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yep, you read that right: &lt;code&gt;Path2D.join(...)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I don’t know if that was hallucination or performance art, but either way, it wasn’t helpful. (And yes, I think it meant &lt;code&gt;path.join(...)&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;When I pointed out the infinite recursion, GPT-4o thanked me and recommended a fix.&lt;/p&gt;

&lt;p&gt;Still, I figured it was time to get to a stopping point and try a different model.&lt;/p&gt;

&lt;p&gt;So I asked GPT-4o to complete one last task: finish DRYing up a few more parts of the code.&lt;/p&gt;

&lt;p&gt;I uploaded the current file. Asked for a clean rewrite. GPT-4o gave me broken output.&lt;/p&gt;

&lt;p&gt;I tried again. And again. And again.&lt;/p&gt;

&lt;p&gt;Five uploads later, I finally figured out the issue: a newline character was being mishandled during patching.&lt;/p&gt;

&lt;p&gt;When I flagged it, GPT-4o jumped in and said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You’re spot on — the newline string is easy to break in patching logic because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;'\n' (Python-escaped newline) looks correct in code but often renders as 'n' or literal text if mishandled
&lt;/li&gt;
&lt;li&gt;This is a common gotcha in regex-based manipulation when we don’t parse the code structure semantically&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;I appreciated the honesty. But I also wanted working code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;There are things GPT-4o does really well. And to be fair, the model has already improved since this experiment. It was helpful with scaffolding, converting JavaScript to TypeScript, and even philosophical debates about dependency managers.&lt;/p&gt;

&lt;p&gt;But co-programming isn’t just about vibes. It’s about &lt;strong&gt;trust&lt;/strong&gt;, &lt;strong&gt;context&lt;/strong&gt;, and &lt;strong&gt;precision&lt;/strong&gt; — especially when you’re iterating on real-world code.&lt;/p&gt;

&lt;p&gt;If you decide to vibe-code with GPT-4o, make sure you’ve got version control, a good debugger, and a willingness to triple-check newline characters.&lt;/p&gt;

&lt;p&gt;As for whether GPT-4o is still “🔥 Overall best for co-programming”?&lt;/p&gt;

&lt;p&gt;Let’s just say… it's still under review.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>vibecoding</category>
      <category>debugging</category>
      <category>gpt4</category>
    </item>
  </channel>
</rss>
