<?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>DEV Community: Nhường Phan</title>
    <description>The latest articles on DEV Community by Nhường Phan (@nhng_phan_d04dad6eece57).</description>
    <link>https://dev.to/nhng_phan_d04dad6eece57</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%2F3875135%2F312c5ef9-4591-45e0-9e3f-8a32923bb85c.png</url>
      <title>DEV Community: Nhường Phan</title>
      <link>https://dev.to/nhng_phan_d04dad6eece57</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nhng_phan_d04dad6eece57"/>
    <language>en</language>
    <item>
      <title>We've Been Thinking About AI Code Wrong. Code Isn't Flat — It's Layers.</title>
      <dc:creator>Nhường Phan</dc:creator>
      <pubDate>Sun, 12 Apr 2026 16:27:22 +0000</pubDate>
      <link>https://dev.to/nhng_phan_d04dad6eece57/weve-been-thinking-about-ai-code-wrong-code-isnt-flat-its-layers-39ph</link>
      <guid>https://dev.to/nhng_phan_d04dad6eece57/weve-been-thinking-about-ai-code-wrong-code-isnt-flat-its-layers-39ph</guid>
      <description>&lt;p&gt;I've been vibe coding almost every day for the past year. Claude, GPT, Copilot — they're all incredible. I can go from idea to working app in hours instead of weeks.&lt;/p&gt;

&lt;p&gt;But I keep hitting the same wall.&lt;/p&gt;

&lt;p&gt;And I think the wall isn't AI. &lt;strong&gt;The wall is code itself.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The $200 Bug
&lt;/h2&gt;

&lt;p&gt;Last month I was building a payment feature. Minute 1, I told AI:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Balance can never go negative."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI wrote the check. Clean code. Looked perfect.&lt;/p&gt;

&lt;p&gt;30 minutes later, I asked AI to add a bulk transfer feature. The context window was getting full. AI generated new code — and somewhere in that new code, it created a path where balance could go to -$200.&lt;/p&gt;

&lt;p&gt;AI didn't hallucinate. It didn't write bad code. It literally didn't have my constraint in context anymore. The constraint existed in my prompt from 30 minutes ago — which had already scrolled out of the window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The constraint lived in 1 line of English. Then it disappeared.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I fixed it. Added a test. Moved on. But it kept bugging me.&lt;/p&gt;

&lt;p&gt;Then I realized: this isn't an AI problem. This is a &lt;strong&gt;code&lt;/strong&gt; problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Code Is Broken (For AI)
&lt;/h2&gt;

&lt;p&gt;Think about how your brain works when someone says "build a money transfer feature":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Transfer money between two users"
  → ok, first validate, then transfer, then save
    → validate means: check users are active, check balance
      → check balance means: sender has enough money
        → that means: if sender.balance &amp;lt; amount, reject
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You think in &lt;strong&gt;layers&lt;/strong&gt;. From vague to specific. Each layer only has 3-5 concepts. Your brain naturally decomposes the problem.&lt;/p&gt;

&lt;p&gt;But when you write code? &lt;strong&gt;All layers collapse into one flat file.&lt;/strong&gt;&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="c1"&gt;# This is what your brain thought:
#   Layer 0: Transfer money safely
#   Layer 1: Validate → Execute → Save
#   Layer 2: Check sender active, check balance
#   Layer 3: if sender.balance &amp;lt; amount: raise Error
#
# This is what survived:
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;transfer_money&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;InvalidUserError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;InsufficientBalanceError&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
    &lt;span class="n"&gt;new_balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;
    &lt;span class="c1"&gt;# ... 50 more lines
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;why&lt;/strong&gt; disappeared. Only the &lt;strong&gt;how&lt;/strong&gt; survived.&lt;/p&gt;

&lt;p&gt;Layer 0 ("transfer money safely") became a function name.&lt;br&gt;
Layer 1 ("validate, then execute, then save") became... nothing. Maybe a comment if you're lucky.&lt;br&gt;
Layer 2 became the actual code.&lt;/p&gt;

&lt;p&gt;When AI works on line 50, it has no idea what you decided at "layer 0." The architectural intent is gone. The constraints are gone. The reasoning is gone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code is a lossy compression of thought.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What If the Layers Don't Disappear?
&lt;/h2&gt;

&lt;p&gt;This is the idea I can't stop thinking about.&lt;/p&gt;

&lt;p&gt;What if you write &lt;strong&gt;exactly how you think&lt;/strong&gt; — starting broad, getting more specific — and every layer IS the code?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Transfer money safely"

  "Validate both users"
    "Sender must be active, otherwise reject"
    "Balance must be sufficient, otherwise reject"

  "Execute the transfer"
    "New sender balance = sender balance minus amount"
    "New receiver balance = receiver balance plus amount"

  "Save and return result"
    "Atomically save both balances to database"
    "Return result with updated users"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read that again.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Line 1 is what a product owner writes in a ticket.&lt;/li&gt;
&lt;li&gt;Lines 3-4 are what a business analyst writes in a spec.&lt;/li&gt;
&lt;li&gt;Lines 7-8 are what a developer writes in code.&lt;/li&gt;
&lt;li&gt;Line 11 is what a DBA cares about.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Same file. Same syntax. Same language. Every line is English. Every line is code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The depth is unlimited. Simple feature? 2 layers. Banking compliance feature? 10 layers. Each layer only adds the detail that layer needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Key Insight: Constraints Flow Downward
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting.&lt;/p&gt;

&lt;p&gt;When you write &lt;code&gt;"Balance must be sufficient"&lt;/code&gt; at layer 1 — what happens to that constraint at layer 4? In normal code, it disappears. Someone has to remember it. AI has to have it in context.&lt;/p&gt;

&lt;p&gt;But what if the &lt;strong&gt;system&lt;/strong&gt; remembers it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Layer 0: "Transfer money safely"
         constraint: "balance must never be negative"     ← written once

Layer 1: "Execute the transfer"
         constraint: "balance must never be negative"     ← auto-inherited

Layer 2: "Calculate new sender balance"
         constraint: "balance must never be negative"     ← auto-inherited

Layer 3: new_balance = sender.balance - amount
         system check: can this violate "balance &amp;gt;= 0"?
         → YES, if sender.balance &amp;lt; amount
         → ERROR: "Constraint 'balance never negative' may be violated.
                   Counterexample: balance=100, amount=150 → new_balance=-50"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constraint flows DOWN through every layer automatically. The system catches violations mathematically — not through tests, not through AI memory, but through &lt;strong&gt;structural inheritance.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I call this &lt;strong&gt;Constraint Inheritance Chain (CIC)&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;DOWN:&lt;/strong&gt; Parent constraints automatically apply to ALL children at any depth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UP:&lt;/strong&gt; When a child step is verified correct, its result becomes a fact the parent can use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACROSS:&lt;/strong&gt; Output from step 1 is automatically available to step 2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DIAGONAL:&lt;/strong&gt; Type definitions inject constraints everywhere they're used&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last one is powerful. Watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"WalletBalance is a number that is never negative"    ← define once

"User has a balance (WalletBalance)"                  ← use the type

"Transfer money from sender (User)"                   ← use User
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system automatically knows: &lt;code&gt;sender.balance &amp;gt;= 0&lt;/code&gt;. Nobody wrote that constraint for &lt;code&gt;transfer_money&lt;/code&gt;. It was &lt;strong&gt;inferred&lt;/strong&gt; from the type definition, through the record field, into the function scope.&lt;/p&gt;

&lt;p&gt;In my prototype, &lt;strong&gt;developers write ~5 explicit constraints, and the system verifies ~16 total&lt;/strong&gt; — because 69% are auto-inferred from type definitions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Same Logic, Three Styles
&lt;/h2&gt;

&lt;p&gt;One thing I'm exploring: what if the same code can be written in multiple styles? Product owners, developers, and AI all think differently. But the underlying logic is the same.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Document style&lt;/strong&gt; (product owner writes this):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;transfer money safely
  given sender is a User, receiver is a User, amount is a PositiveAmount
  producing TransferResult or InsufficientBalanceError

  requires that sender is active
  requires that receiver is active
  must always satisfy balance is non-negative
  guarantees that sender balance decreases by exactly the amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code style&lt;/strong&gt; (developer writes this):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;do transfer money safely
  from sender:User, receiver:User, amount:PositiveAmount
  -&amp;gt; TransferResult or InsufficientBalanceError

  promise before: sender.status is "active"
  promise before: receiver.status is "active"
  promise always: sender.balance &amp;gt;= 0
  promise after: result.sender.balance is old(sender.balance) - amount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Same parse tree. Same verification. Same output.&lt;/strong&gt; The system doesn't care which style you use. AI tends to use document style naturally (because that's how language models think). Developers can use code style if they prefer.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Gets Generated
&lt;/h2&gt;

&lt;p&gt;When all layers are detailed enough, the system compiles to real, runnable code:&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="c1"&gt;# Auto-generated from the layered description above
&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;transfer_money_safely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;sender&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="n"&gt;receiver&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="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PositiveAmount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;TransferResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Transfer money safely between two users.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="c1"&gt;# --- contracts ---
&lt;/span&gt;    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sender must be active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;receiver must be active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;_old_sender_balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;

    &lt;span class="c1"&gt;# --- validate both users ---
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;InvalidUserError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;InsufficientBalanceError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;current_balance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;requested_amount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# --- execute the transfer ---
&lt;/span&gt;    &lt;span class="n"&gt;new_sender_balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;
    &lt;span class="n"&gt;new_receiver_balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;

    &lt;span class="c1"&gt;# --- save and return result ---
&lt;/span&gt;    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;user_repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;new_sender_balance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;user_repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;new_receiver_balance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TransferResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;new_sender_balance&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;new_receiver_balance&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;_old_sender_balance&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plus auto-generated tests:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_transfer_rejects_inactive_sender&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Violate: requires that sender is active&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;suspended&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raises&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InvalidUserError&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;transfer_money_safely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_transfer_rejects_insufficient_balance&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Violate: balance must be sufficient&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raises&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InsufficientBalanceError&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;transfer_money_safely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_transfer_happy_path&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Verify: sender balance decreases by amount&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;active&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;transfer_money_safely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;From layers → verified correct → Python + tests. Automatically.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters For AI Coding
&lt;/h2&gt;

&lt;p&gt;Current AI coding flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;idea → AI writes code → hope it's correct → test → find bugs → fix → repeat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;idea → describe in layers → system verifies consistency → generate code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI never sees more than 3-5 concepts per layer.&lt;/strong&gt; No context window overflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constraints are structural, not contextual.&lt;/strong&gt; System remembers them even when AI's context window is full.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verification happens before code generation.&lt;/strong&gt; Bugs caught at description time, not runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every layer is readable English.&lt;/strong&gt; Code review = reading a document.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Uncomfortable Question
&lt;/h2&gt;

&lt;p&gt;Here's what I keep coming back to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do we actually want to "write code"?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or do we want to &lt;strong&gt;describe behavior at increasing levels of detail&lt;/strong&gt; until it's precise enough to run?&lt;/p&gt;

&lt;p&gt;Because if it's the second one... then maybe the right tool isn't a better code editor, or a better AI model, or better prompting.&lt;/p&gt;

&lt;p&gt;Maybe the right tool is a &lt;strong&gt;language where description IS code.&lt;/strong&gt; Where the document you write first is the source of truth. Where layers don't collapse. Where constraints don't disappear. Where AI and humans work at whatever level of detail they need.&lt;/p&gt;

&lt;p&gt;I've been prototyping this — a language where you write structured English that decomposes layer by layer until it's precise enough to compile. Where the system mathematically verifies that every layer is consistent with every other layer. Where the generated code is guaranteed to match your description.&lt;/p&gt;

&lt;p&gt;The tagline I keep coming back to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Write a document. Run it as code. It can't be wrong.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Still early. Still rough. But every time I use it, I can't go back to flat code.&lt;/p&gt;

&lt;p&gt;Curious if this resonates — or if I'm overthinking it. Have you hit the "flat code" wall with AI? How do you deal with constraints disappearing mid-session?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you're interested in following this project, I'll be sharing updates as the prototype matures. Drop a comment or follow — I'd love to hear your experiences with AI coding pain points.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>discuss</category>
      <category>vibecoding</category>
    </item>
  </channel>
</rss>
