<?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: Serhan Asad</title>
    <description>The latest articles on Forem by Serhan Asad (@serhanasad).</description>
    <link>https://forem.com/serhanasad</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%2F3930257%2F039cdfaa-0d0e-4e77-9526-ad622307ade0.png</url>
      <title>Forem: Serhan Asad</title>
      <link>https://forem.com/serhanasad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/serhanasad"/>
    <language>en</language>
    <item>
      <title>Specification Drift: Why AI Coding Workflows Stop Converging</title>
      <dc:creator>Serhan Asad</dc:creator>
      <pubDate>Thu, 14 May 2026 00:39:24 +0000</pubDate>
      <link>https://forem.com/serhanasad/specification-drift-why-ai-coding-workflows-stop-converging-39nl</link>
      <guid>https://forem.com/serhanasad/specification-drift-why-ai-coding-workflows-stop-converging-39nl</guid>
      <description>&lt;p&gt;I built the same AI coding feature twice. One attempt produced 116 commits and ended in a hard reset. The other shipped. The difference was where the specification lived.&lt;/p&gt;

&lt;h1&gt;
  
  
  Specification Drift: Why AI Coding Workflows Stop Converging
&lt;/h1&gt;

&lt;p&gt;I built the same AI coding feature twice.&lt;/p&gt;

&lt;p&gt;The first attempt used a vibe-coding workflow with Claude Opus 4.6.&lt;/p&gt;

&lt;p&gt;It produced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;116 commits&lt;/li&gt;
&lt;li&gt;7 reverts&lt;/li&gt;
&lt;li&gt;no staging success&lt;/li&gt;
&lt;li&gt;a hard reset after 15 days&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second attempt used the same model, same developer, same core feature, and same repository, but with a prompt-driven workflow.&lt;/p&gt;

&lt;p&gt;It reached staging by day 5 and merged by day 9.&lt;/p&gt;

&lt;p&gt;The difference was not the model.&lt;/p&gt;

&lt;p&gt;It was where the specification lived.&lt;/p&gt;

&lt;h2&gt;
  
  
  The failure mode
&lt;/h2&gt;

&lt;p&gt;The failure mode I’m calling &lt;strong&gt;specification drift&lt;/strong&gt; is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Specification drift is the gap between intended behavior and what AI-rewritten code actually preserves.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the failed attempt, fixes mostly lived in generated code or chat history.&lt;/p&gt;

&lt;p&gt;That worked at first. The early changes were fast. Bugs were visible. Fixes were obvious. Each commit felt productive.&lt;/p&gt;

&lt;p&gt;But as the system grew more coupled, a pattern appeared:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
text
fix → regress → fix → regress

&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:7460484504202321920/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.licdn.com%2Fdms%2Fimage%2Fv2%2FD5622AQG-7NgPzT9PhQ%2Ffeedshare-image-high-res%2FB56Z4j3H.wGgAU-%2F0%2F1778718113985%3Fe%3D2147483647%26v%3Dbeta%26t%3DO4E0j3pkBiJ3yjBCiOzvLe3Fza7vLVxYVW0besQDC1E" height="1402" class="m-0" width="1122"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:7460484504202321920/" rel="noopener noreferrer" class="c-link"&gt;
            #aicoding #aiengineering #softwareengineering #promptdrivendevelopment #specificationdrift | Serhan Asad
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            I spent 15 days vibe coding one production feature.

116 commits.
75 fix commits.
7 reverts.
Thousands of messages with the same AI model.

And at the end?

I deleted the whole thing.

Not because the model was bad.
Not because I didn't write tests.
Not because I didn't try hard enough.

The problem was more subtle:

The code kept changing, but the specification kept disappearing.

The failure mode specification drift.

It happens when fixes live only in AI written code.

You solve a bug. Then the next AI pass rewrites the surrounding system. The fix gets weakened, contradicted, or lost.

At small scale, this feels fine.

At system scale, it becomes a loop:

fix the orchestrator -&amp;gt; break the webhook
fix the webhook -&amp;gt; break credentials
fix credentials -&amp;gt; re-break the orchestrator

Every commit feels productive.

But the system is not actually getting closer to shipping.

So I rebuilt the same feature a second time using Prompt-Driven Development.

Same developer.
Same core feature.
Same model.
Same repo.
Same cloud test environment.

The difference was where the truth lived.

In vibe coding, the code was the source of truth.

In PDD, the prompts and behavioral tests were the source of truth. Code became replaceable.

That attempt reached first end-to-end staging success in 5 days and merged to production in 9.

The lesson:

When AI-assisted development stops converging, don't just add more patches. Move the fix into the artifact that survives the next generation.

For simple scripts, prototypes, and isolated features, vibe coding can still be incredibly fast.

But once the system becomes coupled enough that every fix creates another regression, the durable artifact matters.

The future of AI coding might not be "better prompts in chat."

It might be treating the specification itself as the thing we build, test, version, and regenerate from.

Full case study in comments.

#AICoding #AIEngineering #SoftwareEngineering #PromptDrivenDevelopment #SpecificationDrift

          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstatic.licdn.com%2Faero-v1%2Fsc%2Fh%2Fal2o9zrvru7aqj8e1x2rzsrca" width="64" height="64"&gt;
          linkedin.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>softwareengineering</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
