<?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: Peng Cao</title>
    <description>The latest articles on DEV Community by Peng Cao (@peng_cao).</description>
    <link>https://dev.to/peng_cao</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%2F3713488%2Ff7c9def0-af88-4dd1-a084-e40bf3bcbcb5.jpg</url>
      <title>DEV Community: Peng Cao</title>
      <link>https://dev.to/peng_cao</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/peng_cao"/>
    <language>en</language>
    <item>
      <title>The Hidden Cost of Import Chains</title>
      <dc:creator>Peng Cao</dc:creator>
      <pubDate>Sat, 04 Apr 2026 12:55:43 +0000</pubDate>
      <link>https://dev.to/peng_cao/the-hidden-cost-of-import-chains-20jk</link>
      <guid>https://dev.to/peng_cao/the-hidden-cost-of-import-chains-20jk</guid>
      <description>&lt;p&gt;You open a seemingly simple file in your codebase:&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="c1"&gt;// src/api/user-profile.ts (52 lines)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validateUser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./validators&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;formatResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./formatters&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;logRequest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./logger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUserProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;validateUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;logRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;getUserProfile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;formatResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&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;Looks clean, right? Just 52 lines, three imports, straightforward logic. But when your AI assistant tries to understand this file, here's what actually gets loaded into its context window:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/api/user-profile.ts           52 lines    1,245 tokens
  └─ validators.ts                 89 lines    2,134 tokens
       └─ validation-rules.ts      156 lines   3,721 tokens
       └─ error-types.ts            41 lines     982 tokens
  └─ formatters.ts                 103 lines   2,456 tokens
       └─ format-utils.ts           78 lines    1,867 tokens
  └─ logger.ts                      67 lines    1,603 tokens
       └─ log-transport.ts          124 lines   2,967 tokens
       └─ log-formatter.ts          91 lines    2,178 tokens

Total: 801 lines, 19,153 tokens
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your 52-line file just became a &lt;strong&gt;19,153-token context load&lt;/strong&gt;. That's 366x more expensive than it appears. And your AI assistant has to load all of this to understand your simple function.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;hidden cost of import chains&lt;/strong&gt;—and it's one of the biggest reasons AI struggles with your codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Context Window Crisis
&lt;/h2&gt;

&lt;p&gt;Every import creates a &lt;strong&gt;cascading context cost&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Direct dependencies&lt;/strong&gt;: Files you import&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transitive dependencies&lt;/strong&gt;: Files your imports import&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type dependencies&lt;/strong&gt;: Interfaces and types needed for understanding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implementation depth&lt;/strong&gt;: How deep the chain goes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Modern AI models have context windows of 128K-1M tokens. Sounds like a lot, right? But in a real codebase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Average file&lt;/strong&gt;: 200-300 lines = 4,800-7,200 tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;With direct imports&lt;/strong&gt;: 800-1,200 lines = 19,200-28,800 tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;With deep chains&lt;/strong&gt;: 2,000+ lines = 48,000+ tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple related files&lt;/strong&gt;: Context exhaustion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suddenly that 128K context window doesn't feel so spacious. Add a few related files to analyze a feature, and your AI is already hitting limits—or worse, truncating critical context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Impact: The receiptclaimer Analysis
&lt;/h2&gt;

&lt;p&gt;When I ran &lt;code&gt;@aiready/context-analyzer&lt;/code&gt; on &lt;a href="https://receiptclaimer.com" rel="noopener noreferrer"&gt;receiptclaimer&lt;/a&gt;'s codebase, I discovered patterns that shocked me:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before Refactoring:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Average context budget per file: 12,450 tokens
Maximum depth: 7 levels
Fragmented domains: 4 (User, Receipt, Auth, Payment)
Low cohesion files: 23 (43% of analyzed files)

Top offenders:
- src/api/receipt-processor.ts: 47,821 tokens (cascade depth: 7)
- src/services/user-service.ts: 38,945 tokens (cascade depth: 6)
- src/api/payment-handler.ts: 35,102 tokens (cascade depth: 6)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After Refactoring:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Average context budget per file: 4,780 tokens (-62%)
Maximum depth: 4 levels
Fragmented domains: 2 (consolidated User+Auth, Receipt+Payment)
Low cohesion files: 5 (9% of analyzed files)

Top files (now optimized):
- src/api/receipt-processor.ts: 8,234 tokens (depth: 3)
- src/services/user-service.ts: 6,891 tokens (depth: 3)
- src/api/payment-handler.ts: 7,445 tokens (depth: 4)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Impact on AI Performance:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Response time: Avg 8.2s → 3.1s (62% faster)&lt;/li&gt;
&lt;li&gt;Context truncation errors: 34 → 2 (94% reduction)&lt;/li&gt;
&lt;li&gt;Suggestions quality: Subjectively much better, AI now references correct patterns&lt;/li&gt;
&lt;li&gt;Developer satisfaction: "AI finally gets what I'm trying to do"&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Four Dimensions of Context Cost
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;@aiready/context-analyzer&lt;/code&gt; measures four key metrics:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Import Depth (Cascade Levels)
&lt;/h3&gt;

&lt;p&gt;How many layers deep your dependencies go:&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="c1"&gt;// Depth 0: No imports&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&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;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Depth 1: Direct imports only&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./math&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Depth 3+: Deep chain (EXPENSIVE)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;processUser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user-processor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// imports 5 files&lt;/span&gt;
&lt;span class="c1"&gt;// └─ which imports './validators'             // imports 3 files&lt;/span&gt;
&lt;span class="c1"&gt;//     └─ which imports './validation-rules'   // imports 2 files&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rule of thumb:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Depth 0-2: ✅ Excellent (&amp;lt; 5,000 tokens)&lt;/li&gt;
&lt;li&gt;Depth 3-4: ⚠️ Acceptable (5,000-15,000 tokens)&lt;/li&gt;
&lt;li&gt;Depth 5+: ❌ Expensive (15,000+ tokens)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Context Budget (Total Tokens)
&lt;/h3&gt;

&lt;p&gt;The total number of tokens AI needs to understand your file:&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="c1"&gt;// Small budget (&amp;lt; 3,000 tokens)&lt;/span&gt;
&lt;span class="c1"&gt;// File: 120 lines, 1 import, shallow dependency&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;API_URL&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Large budget (&amp;gt; 20,000 tokens)&lt;/span&gt;
&lt;span class="c1"&gt;// File: 200 lines, 8 imports, deep dependencies&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validateInput&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./validators&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// +4,500 tokens&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;transformData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./transformers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// +6,200 tokens&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;enrichUser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./enrichment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// +8,100 tokens&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;formatResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./formatters&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// +3,800 tokens&lt;/span&gt;
&lt;span class="c1"&gt;// ... more imports ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Target zones:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;lt; 5,000 tokens: ✅ AI-friendly&lt;/li&gt;
&lt;li&gt;5,000-15,000 tokens: ⚠️ Monitor&lt;/li&gt;
&lt;li&gt;15,000+ tokens: ❌ Refactor needed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Domain Fragmentation
&lt;/h3&gt;

&lt;p&gt;How scattered your related logic is across files:&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="c1"&gt;// FRAGMENTED (user logic in 8 files)&lt;/span&gt;
&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;           &lt;span class="c1"&gt;// Authentication&lt;/span&gt;
&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;         &lt;span class="c1"&gt;// Profile management&lt;/span&gt;
&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;  &lt;span class="c1"&gt;// Validation&lt;/span&gt;
&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;     &lt;span class="c1"&gt;// Formatting&lt;/span&gt;
&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;        &lt;span class="c1"&gt;// Types&lt;/span&gt;
&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;       &lt;span class="c1"&gt;// Data access&lt;/span&gt;
&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;middleware&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;     &lt;span class="c1"&gt;// Auth middleware&lt;/span&gt;
&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;helpers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;       &lt;span class="c1"&gt;// Utilities&lt;/span&gt;

&lt;span class="c1"&gt;// CONSOLIDATED (user logic in 3 files)&lt;/span&gt;
&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
  &lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;            &lt;span class="c1"&gt;// Core business logic&lt;/span&gt;
  &lt;span class="err"&gt;├─&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;         &lt;span class="c1"&gt;// Data access&lt;/span&gt;
  &lt;span class="err"&gt;└─&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;              &lt;span class="c1"&gt;// Types and interfaces&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why fragmentation matters:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When AI tries to understand user-related features, it must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load 8 separate files (fragmented) vs 3 files (consolidated)&lt;/li&gt;
&lt;li&gt;Parse 3,200+ lines vs 800 lines&lt;/li&gt;
&lt;li&gt;Navigate 24+ imports vs 6 imports&lt;/li&gt;
&lt;li&gt;Build mental model across scattered context vs cohesive modules&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Cohesion Score
&lt;/h3&gt;

&lt;p&gt;How well a file focuses on one responsibility:&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="c1"&gt;// LOW COHESION (mixed concerns)&lt;/span&gt;
&lt;span class="c1"&gt;// user-service.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;validateEmail&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* validation logic */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;sendEmail&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* email sending logic */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;formatUserName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* formatting logic */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;logUserAction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* logging logic */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;encryptPassword&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* crypto logic */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;renderUserProfile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* rendering logic */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// HIGH COHESION (single responsibility)&lt;/span&gt;
&lt;span class="c1"&gt;// user-service.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* user creation */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;updateUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* user updates */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;deleteUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* user deletion */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;getUserById&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* user retrieval */&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;&lt;strong&gt;Cohesion calculation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The tool analyzes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Method names and their similarity&lt;/li&gt;
&lt;li&gt;Import types (business logic vs utilities vs external)&lt;/li&gt;
&lt;li&gt;File path and naming conventions&lt;/li&gt;
&lt;li&gt;Return types and parameter types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Scores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;80-100%: ✅ Highly cohesive (focused responsibility)&lt;/li&gt;
&lt;li&gt;60-79%: ⚠️ Moderate cohesion (some mixing)&lt;/li&gt;
&lt;li&gt;&amp;lt; 60%: ❌ Low cohesion (refactor into separate modules)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technical Deep Dive: How Context-Analyzer Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Build Dependency Graph
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Pseudo-code of the analysis&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;analyzeDependencies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entryFile&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DependencyGraph&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;traverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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="nx"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&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;ast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;imports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extractImports&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;for &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;imp&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;imports&lt;/span&gt;&lt;span class="p"&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;resolvedPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resolveImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolvedPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;MAX_DEPTH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;traverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolvedPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;traverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entryFile&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;graph&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;h3&gt;
  
  
  Step 2: Calculate Token Costs
&lt;/h3&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;calculateContextBudget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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="nx"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DependencyGraph&lt;/span&gt;&lt;span class="p"&gt;)&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;totalTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;countTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentFile&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentFile&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="nx"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentFile&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;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentFile&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;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;estimateTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ~24 tokens per 100 chars&lt;/span&gt;
    &lt;span class="nx"&gt;totalTokens&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Recursively count dependencies&lt;/span&gt;
    &lt;span class="k"&gt;for &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;dep&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDependencies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentFile&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;countTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dep&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;countTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;totalTokens&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;h3&gt;
  
  
  Step 3: Detect Fragmentation
&lt;/h3&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;detectFragmentation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;files&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;domains&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;for &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;file&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&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;domain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extractDomain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// e.g., "user", "receipt"&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;domains&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;domains&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;domains&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Flag domains split across many files&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;domains&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;fileCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;fragmentationScore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calculateFragmentation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;),&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;h3&gt;
  
  
  Step 4: Measure Cohesion
&lt;/h3&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;analyzeCohesion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extractExports&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ast&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;imports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extractImports&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Analyze semantic similarity of exports&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;similarities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="k"&gt;for &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;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &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;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&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;sim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculateSimilarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
      &lt;span class="nx"&gt;similarities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sim&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// High average similarity = high cohesion&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;avgSimilarity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;similarities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;similarities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Penalty for mixed import types&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;importTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;categorizeImports&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imports&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;mixedPenalty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;importTypes&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;avgSimilarity&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;mixedPenalty&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;h2&gt;
  
  
  Example: Refactoring receiptclaimer's Receipt Processing
&lt;/h2&gt;

&lt;p&gt;Let me show you a real refactoring that reduced context budget by 82%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before: Deep Import Chain (47,821 tokens)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/api/receipt-processor.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;validateReceipt&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../validators/receipt-validator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;parseReceiptImage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../services/ocr-service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;extractLineItems&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../parsers/line-item-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;calculateTotals&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../calculators/total-calculator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;enrichMerchantData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../enrichment/merchant-enricher&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;formatReceiptResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../formatters/receipt-formatter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;logProcessing&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../logging/process-logger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;notifyUser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../notifications/user-notifier&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;processReceipt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&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="nx"&gt;userId&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="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;logProcessing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userId&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;validation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validateReceipt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid receipt&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;ocrResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;parseReceiptImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&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;lineItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;extractLineItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ocrResult&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;totals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculateTotals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lineItems&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;enriched&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;enrichMerchantData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ocrResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;merchant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lineItems&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;notifyUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Receipt processed&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="nf"&gt;formatReceiptResponse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;lineItems&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;merchant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;enriched&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;&lt;strong&gt;Dependency tree:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;receipt-processor.ts (180 lines, 4,302 tokens)
  ├─ receipt-validator.ts (94 lines, 2,247 tokens)
  │   ├─ validation-rules.ts (156 lines, 3,721 tokens)
  │   └─ error-types.ts (41 lines, 982 tokens)
  ├─ ocr-service.ts (203 lines, 4,847 tokens)
  │   ├─ image-preprocessor.ts (145 lines, 3,461 tokens)
  │   ├─ ocr-client.ts (89 lines, 2,125 tokens)
  │   └─ text-extractor.ts (178 lines, 4,249 tokens)
  ├─ line-item-parser.ts (167 lines, 3,987 tokens)
  ├─ total-calculator.ts (78 lines, 1,862 tokens)
  ├─ merchant-enricher.ts (134 lines, 3,201 tokens)
  │   └─ merchant-api-client.ts (98 lines, 2,340 tokens)
  ├─ receipt-formatter.ts (103 lines, 2,458 tokens)
  ├─ process-logger.ts (67 lines, 1,601 tokens)
  │   └─ log-transport.ts (124 lines, 2,967 tokens)
  └─ user-notifier.ts (89 lines, 2,125 tokens)
      └─ notification-service.ts (156 lines, 3,724 tokens)

Total: 1,902 lines, 47,821 tokens
Depth: 7 levels
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  After: Consolidated Module (8,234 tokens)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/domain/receipt/receipt.service.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ReceiptRepository&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./receipt.repository&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;OCRProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./ocr.provider&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ReceiptTypes&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./receipt.types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReceiptService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReceiptRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;ocrProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OCRProvider&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;processReceipt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;imageUrl&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="nx"&gt;userId&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ReceiptTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ProcessedReceipt&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Validation (inline, simple)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isValidImageUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ReceiptTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ValidationError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid image URL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// OCR processing (delegated to focused provider)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ocrResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ocrProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Business logic (co-located)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;buildReceipt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ocrResult&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;lineItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseLineItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ocrResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&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;totals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calculateTotals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lineItems&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Enrichment (co-located)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;merchant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enrichMerchant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ocrResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;merchantName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Persistence&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;receipt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;lineItems&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;totals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;merchant&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&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;saved&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;isValidImageUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&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="nx"&gt;boolean&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;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.(&lt;/span&gt;&lt;span class="sr"&gt;jpg|jpeg|png|pdf&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;parseLineItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&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="nx"&gt;ReceiptTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Inline parsing logic (previously in separate file)&lt;/span&gt;
    &lt;span class="c1"&gt;// ~30 lines of focused parsing&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;calculateTotals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReceiptTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;ReceiptTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Totals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Inline calculation (previously in separate file)&lt;/span&gt;
    &lt;span class="c1"&gt;// ~15 lines of calculation&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;enrichMerchant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ReceiptTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Merchant&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Inline enrichment (previously in separate file + client)&lt;/span&gt;
    &lt;span class="c1"&gt;// ~20 lines of enrichment logic&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;buildReceipt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ocrResult&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;OCRResult&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ReceiptTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Receipt&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Mapping logic&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;&lt;strong&gt;New dependency tree:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;receipt.service.ts (245 lines, 5,856 tokens)
  ├─ receipt.repository.ts (87 lines, 2,078 tokens)
  ├─ ocr.provider.ts (45 lines, 1,072 tokens) [thin wrapper]
  └─ receipt.types.ts (38 lines, 908 tokens)

Total: 415 lines, 8,234 tokens
Depth: 3 levels
Reduction: 47,821 → 8,234 tokens (82.8% decrease)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;strong&gt;1. Consolidated scattered logic:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;8 separate files → 1 service file&lt;/li&gt;
&lt;li&gt;Related functions co-located&lt;/li&gt;
&lt;li&gt;Clear domain boundary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Inlined simple utilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;validateReceipt&lt;/code&gt;: 94 lines → 3 lines (simple inline check)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;calculateTotals&lt;/code&gt;: 78 lines → 15 lines (removed abstraction overhead)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;parseLineItems&lt;/code&gt;: 167 lines → 30 lines (removed generic parsers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Removed unnecessary abstractions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separate formatter → methods on service&lt;/li&gt;
&lt;li&gt;Separate logger → focused logging where needed&lt;/li&gt;
&lt;li&gt;Notification → moved to message queue trigger&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Created thin wrappers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OCR client: Fat client (203 lines) → thin provider (45 lines)&lt;/li&gt;
&lt;li&gt;Repository: Focused data access only&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Migration Strategy: How to Refactor Without Breaking Everything
&lt;/h2&gt;

&lt;p&gt;Refactoring deep import chains is scary. Here's how to do it safely:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Measure Current State
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate baseline report&lt;/span&gt;
npx @aiready/context-analyzer ./src &lt;span class="nt"&gt;--output&lt;/span&gt; baseline.json

&lt;span class="c"&gt;# Identify top offenders&lt;/span&gt;
npx @aiready/context-analyzer ./src &lt;span class="nt"&gt;--sort-by&lt;/span&gt; budget &lt;span class="nt"&gt;--limit&lt;/span&gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Prioritize Refactoring
&lt;/h3&gt;

&lt;p&gt;Focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High-traffic files&lt;/strong&gt;: API handlers, services, core business logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-budget files&lt;/strong&gt;: &amp;gt; 15,000 tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep chains&lt;/strong&gt;: Depth &amp;gt; 5&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low cohesion&lt;/strong&gt;: Score &amp;lt; 60%&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Create Domain Boundaries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before (scattered):
src/
  ├─ api/
  ├─ services/
  ├─ utils/
  ├─ formatters/
  ├─ validators/
  └─ helpers/

After (domain-driven):
src/
  ├─ domain/
  │   ├─ user/
  │   │   ├─ user.service.ts
  │   │   ├─ user.repository.ts
  │   │   └─ user.types.ts
  │   ├─ receipt/
  │   └─ payment/
  └─ infrastructure/
      ├─ api/
      └─ database/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Refactor Incrementally
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Week 1:&lt;/strong&gt; Consolidate one domain (e.g., User)&lt;br&gt;
&lt;strong&gt;Week 2:&lt;/strong&gt; Consolidate another domain (e.g., Receipt)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Week 3:&lt;/strong&gt; Update imports across codebase&lt;br&gt;
&lt;strong&gt;Week 4:&lt;/strong&gt; Remove old files, update tests&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Verify Improvements
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate new report&lt;/span&gt;
npx @aiready/context-analyzer ./src &lt;span class="nt"&gt;--output&lt;/span&gt; after.json

&lt;span class="c"&gt;# Compare&lt;/span&gt;
npx @aiready/cli compare baseline.json after.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Do:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Co-locate related logic&lt;/strong&gt;: Keep domain logic together&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inline simple utilities&lt;/strong&gt;: &amp;lt; 20 lines, used in one place&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use dependency injection&lt;/strong&gt;: Makes testing easier, reduces coupling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create thin adapters&lt;/strong&gt;: For external services, databases&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure regularly&lt;/strong&gt;: Track context budget over time&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ❌ Don't:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Over-abstract&lt;/strong&gt;: Not everything needs a separate file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create deep hierarchies&lt;/strong&gt;: Flat is better than nested&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Split prematurely&lt;/strong&gt;: Extract only when reused 3+ times&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignore cohesion&lt;/strong&gt;: Low cohesion = mixed concerns = high context cost&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refactor blindly&lt;/strong&gt;: Understand dependencies before moving code&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Integration with CI/CD
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GitHub Actions: Context Budget Check
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Context Budget Check&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;context-analysis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Analyze context budget&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx @aiready/context-analyzer ./src --threshold &lt;/span&gt;&lt;span class="m"&gt;15000&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check for regressions&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;npx @aiready/context-analyzer ./src --output current.json&lt;/span&gt;
          &lt;span class="s"&gt;npx @aiready/cli compare baseline.json current.json --fail-on-regression&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pre-commit Hook: Prevent Deep Chains
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="c"&gt;# .git/hooks/pre-commit&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Checking import depth..."&lt;/span&gt;
npx @aiready/context-analyzer ./src &lt;span class="nt"&gt;--max-depth&lt;/span&gt; 4 &lt;span class="nt"&gt;--quiet&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"❌ Import chains too deep. Refactor before committing."&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Import chains are &lt;strong&gt;invisible expensive&lt;/strong&gt;. Every import adds context cost that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slows down AI responses&lt;/li&gt;
&lt;li&gt;Increases token usage (costs money on paid APIs)&lt;/li&gt;
&lt;li&gt;Causes context truncation errors&lt;/li&gt;
&lt;li&gt;Makes AI suggestions less accurate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But unlike many optimization problems, this one has clear metrics and actionable fixes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Measure&lt;/strong&gt;: Run context-analyzer to see your current state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prioritize&lt;/strong&gt;: Focus on high-budget, deep-chain, low-cohesion files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refactor&lt;/strong&gt;: Consolidate domains, inline utilities, remove unnecessary abstractions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify&lt;/strong&gt;: Measure again, track improvements over time&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Analyze your codebase&lt;/span&gt;
npx @aiready/context-analyzer ./src

&lt;span class="c"&gt;# Check specific file&lt;/span&gt;
npx @aiready/context-analyzer ./src/api/handler.ts &lt;span class="nt"&gt;--detailed&lt;/span&gt;

&lt;span class="c"&gt;# Find files over budget&lt;/span&gt;
npx @aiready/context-analyzer ./src &lt;span class="nt"&gt;--threshold&lt;/span&gt; 15000

&lt;span class="c"&gt;# Export report&lt;/span&gt;
npx @aiready/context-analyzer ./src &lt;span class="nt"&gt;--output&lt;/span&gt; report.json

&lt;span class="c"&gt;# Unified CLI with all metrics&lt;/span&gt;
npx @aiready/cli scan &lt;span class="nt"&gt;--score&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Before you refactor:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measure your current context budget&lt;/li&gt;
&lt;li&gt;Identify top offenders (top 10 files by token cost)&lt;/li&gt;
&lt;li&gt;Pick one domain to consolidate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After you refactor:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measure again&lt;/li&gt;
&lt;li&gt;Calculate percentage improvement&lt;/li&gt;
&lt;li&gt;Share your results!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/getaiready/aiready-cli" rel="noopener noreferrer"&gt;github.com/getaiready/aiready-cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://getaiready.dev" rel="noopener noreferrer"&gt;getaiready.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Report issues: &lt;a href="https://github.com/getaiready/aiready-cli/issues" rel="noopener noreferrer"&gt;github.com/getaiready/aiready-cli/issues&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;What's your biggest context budget file?&lt;/strong&gt; Run the analyzer and share your findings—I'd love to see what you discover.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Peng Cao is the founder of &lt;a href="https://receiptclaimer.com" rel="noopener noreferrer"&gt;receiptclaimer&lt;/a&gt; and creator of &lt;a href="https://github.com/getaiready/aiready-cli" rel="noopener noreferrer"&gt;aiready&lt;/a&gt;, an open-source suite for measuring and optimizing codebases for AI adoption.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>Deep Dive: Semantic Duplicate Detection with AST Analysis - How AI Keeps Rewriting Your Logic</title>
      <dc:creator>Peng Cao</dc:creator>
      <pubDate>Sat, 04 Apr 2026 05:28:31 +0000</pubDate>
      <link>https://dev.to/peng_cao/deep-dive-semantic-duplicate-detection-with-ast-analysis-how-ai-keeps-rewriting-your-logic-3fa5</link>
      <guid>https://dev.to/peng_cao/deep-dive-semantic-duplicate-detection-with-ast-analysis-how-ai-keeps-rewriting-your-logic-3fa5</guid>
      <description>&lt;p&gt;You've just asked your AI assistant to add email validation to your new signup form. It writes 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;function&lt;/span&gt; &lt;span class="nf"&gt;validateEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&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="nx"&gt;boolean&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;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&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;Simple enough. But here's the problem: this exact logic—checking for '@' and '.'—already exists in four other places in your codebase, just written differently:&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="c1"&gt;// In src/utils/validators.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isValidEmail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// In src/api/auth.ts&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/@/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// In src/components/EmailForm.tsx&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkEmail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// In src/services/user-service.ts&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@&lt;/span&gt;&lt;span class="dl"&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="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your AI didn't see these patterns. Why? Because they look different syntactically, even though they're semantically identical. This is semantic duplication—and it's one of the biggest hidden costs in AI-assisted development.&lt;/p&gt;

&lt;p&gt;Semantic Duplicate Detection - How AI keeps rewriting the same logic in different ways&lt;br&gt;
How AI models miss semantic duplicates: same logic, different syntax, invisible to traditional analysis.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Problem: Syntax Blinds AI Models
Traditional duplicate detection tools look for exact or near-exact text matches. They catch copy-paste duplicates, but miss logic that's been rewritten with different:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Variable names (&lt;strong&gt;email&lt;/strong&gt; vs &lt;strong&gt;e&lt;/strong&gt; vs &lt;strong&gt;val&lt;/strong&gt;)&lt;br&gt;
Methods (&lt;strong&gt;includes&lt;/strong&gt;() vs &lt;strong&gt;indexOf&lt;/strong&gt;() vs &lt;strong&gt;match&lt;/strong&gt;() vs &lt;strong&gt;search&lt;/strong&gt;())&lt;br&gt;
Structure (inline vs function vs arrow function)&lt;br&gt;
AI models suffer from the same limitation. When they scan your codebase for context, they see these five implementations as completely unrelated. Each one consumes precious context window tokens, yet provides zero new information.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Real-World Impact: The receiptclaimer Story
When I ran @aiready/pattern-detect on receiptclaimer's codebase, I found 23 semantic duplicate patterns scattered across 47 files. Here's what that looked like:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;23 duplicate patterns (validation, formatting, error handling)&lt;br&gt;
8,450 wasted context tokens&lt;br&gt;
AI suggestions kept reinventing existing logic&lt;br&gt;
Code reviews: "Didn't we already have this somewhere?"&lt;br&gt;
&lt;strong&gt;After consolidation&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;3 remaining patterns (acceptable, different contexts)&lt;br&gt;
1,200 context tokens (85% reduction)&lt;br&gt;
AI now references existing patterns&lt;br&gt;
Faster code reviews, cleaner suggestions&lt;br&gt;
The math: Each duplicate pattern cost ~367 tokens on average. When AI assistants tried to understand feature areas, they had to load multiple variations of the same logic, quickly exhausting their context window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How It Works: Jaccard Similarity on AST Tokens
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;@aiready/pattern-detect uses a technique called Jaccard similarity on Abstract Syntax Tree (AST) tokens to detect semantic duplicates. Let me break that down.&lt;/p&gt;

&lt;p&gt;Step 1: Parse to AST&lt;br&gt;
First, we parse your code into an Abstract Syntax Tree—a structural representation that ignores syntax and focuses on meaning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Original code&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validateEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&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;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// AST tokens (simplified)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FunctionDeclaration&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Identifier:validateEmail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Identifier:email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ReturnStatement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LogicalExpression:&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CallExpression:includes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MemberExpression:email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StringLiteral:@&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CallExpression:includes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MemberExpression:email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StringLiteral:.&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;Step 2: Normalize&lt;br&gt;
We normalize these tokens by:&lt;/p&gt;

&lt;p&gt;Removing specific identifiers (variable/function names)&lt;br&gt;
Keeping operation types (CallExpression, LogicalExpression)&lt;br&gt;
Preserving structure (nesting, flow control)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Normalized tokens&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FunctionDeclaration&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ReturnStatement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LogicalExpression:&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CallExpression:includes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CallExpression:includes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StringLiteral&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;Step 3: Calculate Jaccard Similarity&lt;br&gt;
Jaccard similarity measures how similar two sets are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Jaccard(A, B) = |A ∩ B| / |A ∪ B|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where:&lt;/p&gt;

&lt;p&gt;A ∩ B = tokens in both sets (intersection)&lt;br&gt;
A ∪ B = tokens in either set (union)&lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Pattern A (normalized)&lt;/span&gt;
&lt;span class="nb"&gt;Set&lt;/span&gt; &lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FunctionDeclaration&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ReturnStatement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LogicalExpression:&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CallExpression:includes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;// Pattern B (normalized)&lt;/span&gt;
&lt;span class="nb"&gt;Set&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FunctionDeclaration&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ReturnStatement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LogicalExpression:&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CallExpression:indexOf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;// Intersection&lt;/span&gt;
&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="err"&gt;∩&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FunctionDeclaration&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ReturnStatement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LogicalExpression:&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="err"&gt;∩&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;

&lt;span class="c1"&gt;// Union&lt;/span&gt;
&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="err"&gt;∪&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FunctionDeclaration&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ReturnStatement&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LogicalExpression:&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CallExpression:includes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CallExpression:indexOf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;StringLiteral&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="err"&gt;∪&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;

&lt;span class="c1"&gt;// Jaccard similarity&lt;/span&gt;
&lt;span class="nc"&gt;Jaccard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.67&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, pattern-detect flags patterns with ≥70% similarity as duplicates. This catches most semantic duplicates while avoiding false positives.&lt;/p&gt;

&lt;p&gt;Pattern Classification&lt;br&gt;
The tool automatically classifies patterns into categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validators
Logic that checks conditions and returns boolean:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Pattern: Email validation&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validateEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&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;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;isValidEmail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Formatters
Logic that transforms input to output:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Pattern: Phone number formatting&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;formatPhone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&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;num&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\D&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&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;cleanPhone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&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="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;API Handlers
Request/response processing logic:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Pattern: Error response handling&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&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;errorResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Utilities
General helper functions:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// Pattern: Array deduplication&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&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;dedupe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ai</category>
      <category>codequality</category>
      <category>semantic</category>
      <category>programming</category>
    </item>
    <item>
      <title>AI Code Quality Metrics That Actually Matter: The 9 Dimensions of AI-Readiness</title>
      <dc:creator>Peng Cao</dc:creator>
      <pubDate>Sat, 04 Apr 2026 05:23:05 +0000</pubDate>
      <link>https://dev.to/peng_cao/ai-code-quality-metrics-that-actually-matter-the-9-dimensions-of-ai-readiness-b8h</link>
      <guid>https://dev.to/peng_cao/ai-code-quality-metrics-that-actually-matter-the-9-dimensions-of-ai-readiness-b8h</guid>
      <description>&lt;p&gt;Traditional code metrics like cyclomatic complexity and lines of code don't capture the real blockers for AI-assisted development teams. Here are the 9 dimensions that actually matter for AI-readiness.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The 9 Dimensions of AI-Readiness&lt;br&gt;
&lt;strong&gt;Semantic Consistency&lt;/strong&gt; - How consistently your codebase uses naming conventions and patterns&lt;br&gt;
&lt;strong&gt;Context Window Efficiency&lt;/strong&gt; - How much context AI needs to understand your code&lt;br&gt;
&lt;strong&gt;Import Chain Depth&lt;/strong&gt; - How deep your dependency chains go&lt;br&gt;
&lt;strong&gt;Domain Cohesion&lt;/strong&gt; - How well related logic is grouped together&lt;br&gt;
&lt;strong&gt;Pattern Recognition&lt;/strong&gt; - How easily AI can identify and reuse patterns&lt;br&gt;
&lt;strong&gt;Documentation Coverage&lt;/strong&gt; - How well-documented your code is&lt;br&gt;
&lt;strong&gt;Type Safety&lt;/strong&gt; - How well your types guide AI understanding&lt;br&gt;
&lt;strong&gt;Test Coverage&lt;/strong&gt; - How well your tests validate AI suggestions&lt;br&gt;
&lt;strong&gt;Architectural Clarity&lt;/strong&gt; - How clear your system's structure is&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Why Traditional Metrics Fall Short&lt;br&gt;
Traditional metrics were designed for human developers, not AI assistants. They measure code complexity from a human perspective, but AI has different strengths and weaknesses:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI excels at pattern recognition but struggles with inconsistent naming&lt;br&gt;
AI needs clear context windows but traditional metrics ignore them&lt;br&gt;
AI benefits from shallow import chains but complexity metrics don't measure depth&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Measuring What Matters
AIReady measures these 9 dimensions to give you a comprehensive picture of how well your codebase is optimized for AI assistance. Each dimension is scored independently, and the overall AI-Readiness Score combines them into a single metric.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Run AIReady analysis
&lt;span class="go"&gt;npx @aiready/cli scan . --score

&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Output:
&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;AI-Readiness Score: 78/100
&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Strengths:
&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;✓ Semantic Consistency: 85%
&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;✓ Type Safety: 90%
&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Areas &lt;span class="k"&gt;for &lt;/span&gt;Improvement:
&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;⚠ Context Window Efficiency: 65%
&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;⚠ Import Chain Depth: 70%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Getting Started
Ready to measure your codebase's AI-readiness? Run the analysis and see how your code scores across these 9 dimensions.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Install AIReady CLI
&lt;span class="go"&gt;npm install -g @aiready/cli

&lt;/span&gt;&lt;span class="gp"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Analyze your codebase
&lt;span class="go"&gt;npx @aiready/cli scan . --score
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ai</category>
      <category>codequality</category>
      <category>llm</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Why Your Codebase is Invisible to AI (And What to Do About It)</title>
      <dc:creator>Peng Cao</dc:creator>
      <pubDate>Sun, 01 Feb 2026 05:53:12 +0000</pubDate>
      <link>https://dev.to/peng_cao/why-your-codebase-is-invisible-to-ai-and-what-to-do-about-it-4ge0</link>
      <guid>https://dev.to/peng_cao/why-your-codebase-is-invisible-to-ai-and-what-to-do-about-it-4ge0</guid>
      <description>&lt;p&gt;Part 2 of 7: The AI Code Debt Tsunami Series&lt;/p&gt;

&lt;p&gt;I watched GitHub Copilot suggest the same validation logic three times in one week. Different syntax. Different variable names. Same exact purpose.&lt;/p&gt;

&lt;p&gt;The AI wasn’t broken. My codebase was invisible.&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%2Fwv4nfjfd9r7qe8wf08m7.png" 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%2Fwv4nfjfd9r7qe8wf08m7.png" alt=" " width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the problem: AI can write code, but it can’t see your patterns. Not the way humans do. When you have the same logic scattered across different files with different names, AI treats each one as unique. It doesn’t know you’ve already solved this problem. So it solves it again. And again.&lt;/p&gt;

&lt;p&gt;This isn’t just annoying. It’s expensive.&lt;/p&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;h2&gt;
  
  
  The Context Window Crisis
&lt;/h2&gt;

&lt;p&gt;Every time your AI assistant helps with code, it needs context. It reads your file, follows imports, understands dependencies. All of this costs tokens. The more fragmented your code, the more tokens you burn.&lt;/p&gt;

&lt;p&gt;Let me show you a real example from building ReceiptClaimer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1: User Validation — The Hard Way
&lt;/h3&gt;

&lt;p&gt;I had user validation logic spread across 8 files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api/auth/validate-email.ts
api/auth/validate-password.ts
api/users/check-email-exists.ts
api/users/validate-username.ts
lib/validators/email.ts
lib/validators/password-strength.ts
utils/auth/email-format.ts
utils/validation/user-fields.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each file: 80–150 lines. Different patterns. Different error handling. Different import chains.&lt;/p&gt;

&lt;p&gt;When AI needed to help with user validation, it had to:&lt;/p&gt;

&lt;p&gt;Read the current file (200 tokens)&lt;br&gt;
Follow imports to understand the pattern (3,200 tokens)&lt;br&gt;
Pull in dependencies to match types (5,800 tokens)&lt;br&gt;
Scan similar files to understand conventions (3,250 tokens)&lt;br&gt;
Total context cost: 12,450 tokens per request.&lt;/p&gt;

&lt;p&gt;At GPT-4 pricing (~0.03/1K tokens), that’s &lt;strong&gt;0.37 per code suggestion&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example 2: User Validation — The Smart Way
&lt;/h3&gt;

&lt;p&gt;After refactoring, I consolidated to 2 files:&lt;/p&gt;

&lt;p&gt;lib/user-validation/index.ts - All validation logic&lt;br&gt;
lib/user-validation/types.ts - Shared types&lt;br&gt;
Each file: 200–250 lines. Single pattern. Clear error handling. Minimal imports.&lt;/p&gt;

&lt;p&gt;Same AI assistance, new cost:&lt;/p&gt;

&lt;p&gt;Read the current file (200 tokens)&lt;br&gt;
Read the validation module (900 tokens)&lt;br&gt;
Read type definitions (1,000 tokens)&lt;br&gt;
Total context cost: 2,100 tokens per request.&lt;/p&gt;

&lt;p&gt;That’s an 83% reduction. From 0.37 to 0.06 per suggestion.&lt;/p&gt;

&lt;p&gt;If your team makes 50 AI-assisted edits per day, that’s:&lt;/p&gt;

&lt;p&gt;Before: 18.50/day = 555/month = $6,660/year&lt;br&gt;
After: 3/day = 90/month = $1,080/year&lt;br&gt;
Savings: $5,580/year. Just from organizing user validation.&lt;/p&gt;

&lt;p&gt;And that’s one domain. What about error handling? Database queries? API endpoints? File uploads?&lt;/p&gt;
&lt;h2&gt;
  
  
  Three Ways Your Code Becomes Invisible
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Semantic Duplicates: Same Logic, Different Disguise
&lt;/h3&gt;

&lt;p&gt;Traditional linters catch copy-paste duplication. They’re useless for semantic duplicates.&lt;/p&gt;

&lt;p&gt;Here’s what I mean. Both functions do the exact same thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: api/receipts/validate.ts
function checkReceiptData(data: any): boolean {
  if (!data.merchant) return false;
  if (!data.amount) return false;
  if (data.amount &amp;lt;= 0) return false;
  if (!data.date) return false;
  return true;
}
// File: lib/validators/receipt-validator.ts
export function isValidReceipt(receipt: ReceiptInput): boolean {
  const hasRequiredFields = receipt.merchant &amp;amp;&amp;amp; 
                           receipt.amount &amp;amp;&amp;amp; 
                           receipt.date;
  const hasPositiveAmount = receipt.amount &amp;gt; 0;
  return hasRequiredFields &amp;amp;&amp;amp; hasPositiveAmount;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ESLint won’t catch this. SonarQube won’t catch this. They look different.&lt;/p&gt;

&lt;p&gt;But to an AI reading your codebase? These are two competing patterns. Should it use the imperative style with early returns? Or the declarative style with boolean composition?&lt;/p&gt;

&lt;p&gt;It doesn’t know. So it picks randomly. Or invents a third way.&lt;/p&gt;

&lt;p&gt;I found 23 of these in ReceiptClaimer before I measured. Receipt validation, user authentication, file upload checks, date parsing, currency formatting.&lt;/p&gt;

&lt;p&gt;Each one was a signal to AI: “We don’t have a standard way of doing this.”&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Domain Fragmentation: Scattered Logic That Bleeds Tokens
&lt;/h3&gt;

&lt;p&gt;Every time you split a single responsibility across multiple files, you fragment your domain. AI has to load more context. Burn more tokens. Make more mistakes.&lt;/p&gt;

&lt;p&gt;Here’s what fragmentation looked like in my codebase:&lt;/p&gt;

&lt;p&gt;Receipt Processing (fragmented):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
  api/
    receipts/
      upload.ts          # Handles file upload
      extract.ts         # Calls OCR service
      parse.ts           # Parses OCR response
  lib/
    ocr/
      google-vision.ts   # Google Vision integration
      openai-vision.ts   # OpenAI Vision integration
    parsers/
      receipt-parser.ts  # Parsing logic
  services/
    receipt-service.ts   # Business logic
  utils/
    file-upload.ts       # S3 upload helper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8 files. 7 different import paths. To understand receipt processing, AI needs to load all of them.&lt;/p&gt;

&lt;p&gt;Receipt Processing (consolidated):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
  domains/
    receipt-processing/
      index.ts           # Public API
      ocr-service.ts     # OCR abstraction
      parser.ts          # Parsing logic
      storage.ts         # S3 operations
      types.ts           # Shared types
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5 files. Single import path. Clear boundaries. AI can understand the entire domain from one import.&lt;/p&gt;

&lt;p&gt;The result: Import depth dropped from 7 levels to 3 levels. Context budget per file dropped 62%.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Low Cohesion: Mixed Concerns That Confuse Everyone
&lt;/h3&gt;

&lt;p&gt;This is the “God file” problem, but inverted.&lt;/p&gt;

&lt;p&gt;Instead of one file doing everything, you have files that do unrelated things. AI can’t figure out what the file is for.&lt;/p&gt;

&lt;p&gt;Example from my early codebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// lib/utils/helpers.ts (820 lines)
export function formatCurrency(amount: number): string { ... }
export function parseDate(dateStr: string): Date { ... }
export function uploadToS3(file: Buffer): Promise&amp;lt;string&amp;gt; { ... }
export function validateEmail(email: string): boolean { ... }
export function generateToken(): string { ... }
export function calculateGST(amount: number): number { ... }
export function hashPassword(pwd: string): Promise&amp;lt;string&amp;gt; { ... }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What is this file? Currency formatting? Date parsing? Authentication? File uploads? Tax calculation?&lt;/p&gt;

&lt;p&gt;All of them. None of them.&lt;/p&gt;

&lt;p&gt;When AI tries to help, it doesn’t know which pattern to follow. The file has no cohesive theme. So AI makes guesses. Often wrong guesses.&lt;/p&gt;

&lt;p&gt;After measuring cohesion scores (more on this below), I split this into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
lib/formatting/currency.ts - Currency &amp;amp; GST
lib/formatting/date.ts - Date parsing
lib/auth/tokens.ts - Token &amp;amp; password handling
lib/storage/s3.ts - File uploads
lib/validation/email.ts - Email validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cohesion score went from 0.23 (terrible) to 0.89 (excellent).&lt;/p&gt;

&lt;p&gt;AI suggestions became relevant. Copilot started importing the right modules. Code reviews got faster because humans could find things too.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Measure Invisibility
&lt;/h2&gt;

&lt;p&gt;You can’t fix what you can’t measure. So I built tools to measure these three dimensions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Measuring Semantic Duplicates
&lt;/h3&gt;

&lt;p&gt;Traditional tools use line-by-line comparison. They fail on semantic duplicates.&lt;/p&gt;

&lt;p&gt;I built @aiready/pattern-detect using a different approach:&lt;/p&gt;

&lt;p&gt;Parse code into AST (Abstract Syntax Trees)&lt;br&gt;
Extract semantic tokens (variable names → generic placeholders)&lt;br&gt;
Calculate Jaccard similarity (set-based comparison)&lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Function A
function validateUser(user) {
  if (!user.email) return false;
  if (!user.password) return false;
  return true;
}
// Function B  
function checkUserValid(data) {
  const hasEmail = !!data.email;
  const hasPassword = !!data.password;
  return hasEmail &amp;amp;&amp;amp; hasPassword;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After normalization:&lt;/p&gt;

&lt;p&gt;Function A tokens: [if, not, property, return, false, return, true]&lt;br&gt;
Function B tokens: [const, property, return, and]&lt;br&gt;
Jaccard similarity: 0.78 (78% similar)&lt;/p&gt;

&lt;p&gt;Become a member&lt;br&gt;
Anything above 0.70? Probably a semantic duplicate worth reviewing.&lt;/p&gt;

&lt;p&gt;Tool: &lt;code&gt;npx @aiready/pattern-detect&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Measuring Fragmentation
&lt;/h3&gt;

&lt;p&gt;Context budget tells you how many tokens AI needs to understand a file.&lt;/p&gt;

&lt;p&gt;I built @aiready/context-analyzer to measure:&lt;/p&gt;

&lt;p&gt;Import depth — How many levels deep do imports go?&lt;br&gt;
Context budget — Total tokens needed to understand this file&lt;br&gt;
Cohesion score — Are imports related to each other?&lt;br&gt;
Fragmentation score — Is this domain split across files?&lt;br&gt;
Example output:&lt;/p&gt;

&lt;p&gt;src/api/receipts/upload.ts&lt;br&gt;
  Import depth: 7 levels&lt;br&gt;
  Context budget: 12,450 tokens&lt;br&gt;
  Cohesion: 0.34 (low - mixed concerns)&lt;br&gt;
  Fragmentation: 0.78 (high - scattered domain)&lt;br&gt;
High fragmentation + low cohesion = AI will struggle.&lt;/p&gt;

&lt;p&gt;Tool: &lt;code&gt;npx @aiready/context-analyzer&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Measuring Consistency
&lt;/h3&gt;

&lt;p&gt;The third dimension: pattern consistency.&lt;/p&gt;

&lt;p&gt;Do you handle errors the same way everywhere? Use the same naming conventions? Follow the same async patterns?&lt;/p&gt;

&lt;p&gt;I’m building @aiready/consistency to detect:&lt;/p&gt;

&lt;p&gt;Mixed error handling patterns (try-catch vs callbacks vs promises)&lt;br&gt;
Inconsistent naming (camelCase vs snake_case)&lt;br&gt;
Import style drift (ES modules vs require)&lt;br&gt;
Async pattern mixing (async/await vs .then())&lt;br&gt;
Status: Beta release next week.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;a href="https://receiptclaimer.com.au/" rel="noopener noreferrer"&gt;ReceiptClaimer&lt;/a&gt; Results
&lt;/h2&gt;

&lt;p&gt;I ran these tools on my own codebase — ReceiptClaimer, an AI-powered receipt tracker for Australian taxpayers. Here’s what I found:&lt;/p&gt;

&lt;h3&gt;
  
  
  Before Measurement
&lt;/h3&gt;

&lt;p&gt;Semantic duplicates: 23 patterns repeated 87 times&lt;br&gt;
Average import depth: 5.8 levels&lt;br&gt;
Average context budget: 8,200 tokens per file&lt;br&gt;
Cohesion score: 0.42 (poor)&lt;br&gt;
Monthly AI costs: ~$380 (estimated)&lt;/p&gt;

&lt;h3&gt;
  
  
  After Refactoring (4 weeks)
&lt;/h3&gt;

&lt;p&gt;Semantic duplicates: 3 patterns repeated 8 times (-87%)&lt;br&gt;
Average import depth: 2.9 levels (-50%)&lt;br&gt;
Average context budget: 2,100 tokens per file (-74%)&lt;br&gt;
Cohesion score: 0.89 (excellent)&lt;br&gt;
Monthly AI costs: ~$95 (estimated)&lt;br&gt;
Time invested: 40 hours over 4 weeks Annual savings: $3,420 in AI costs ROI: 12.6 months (probably faster due to velocity gains)&lt;/p&gt;

&lt;p&gt;But the real win wasn’t the money.&lt;/p&gt;

&lt;p&gt;AI suggestions became useful. Copilot started suggesting the right patterns. Code reviews got faster. New features shipped with fewer bugs. Onboarding new developers became easier.&lt;/p&gt;

&lt;p&gt;Making my code visible to AI made it better for humans too.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Can Do Today
&lt;/h2&gt;

&lt;p&gt;You don’t need to refactor everything. Start with measurement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Measure Your Semantic Duplicates
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;npx @aiready/pattern-detect&lt;/code&gt;&lt;br&gt;
Look for:&lt;/p&gt;

&lt;p&gt;Similarity scores &amp;gt; 70%&lt;br&gt;
Patterns repeated 3+ times&lt;br&gt;
Core domains (auth, validation, API handlers)&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Measure Your Fragmentation
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;npx @aiready/context-analyzer&lt;/code&gt;&lt;br&gt;
Look for:&lt;/p&gt;

&lt;p&gt;Import depth &amp;gt; 5 levels&lt;br&gt;
Context budget &amp;gt; 8,000 tokens&lt;br&gt;
Cohesion score &amp;lt; 0.50&lt;br&gt;
Files with fragmentation &amp;gt; 0.70&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Pick ONE Domain to Fix
&lt;/h3&gt;

&lt;p&gt;Don’t refactor everything. Pick your most painful domain:&lt;/p&gt;

&lt;p&gt;The one where AI suggestions are worst&lt;br&gt;
The one where code reviews take longest&lt;br&gt;
The one where new developers get confused&lt;br&gt;
Focus there. Consolidate files. Extract common patterns. Measure again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Track Improvements
&lt;/h3&gt;

&lt;p&gt;Run the tools weekly. Watch the metrics improve. Share results with your team.&lt;/p&gt;

&lt;p&gt;The goal isn’t perfect code. It’s visible code.&lt;/p&gt;

&lt;p&gt;Code that AI can understand. Code that humans can maintain. Code that doesn’t waste tokens on fragmentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next in This Series
&lt;/h2&gt;

&lt;p&gt;In Part 3, I’ll dive deep into the technical details: “Building AIReady: Metrics That Actually Matter”&lt;/p&gt;

&lt;p&gt;We’ll explore:&lt;/p&gt;

&lt;p&gt;Why traditional metrics (cyclomatic complexity, code coverage) miss AI problems&lt;br&gt;
How Jaccard similarity works on AST tokens (with diagrams)&lt;br&gt;
The three dimensions of AI-readiness and how they interact&lt;br&gt;
Design decisions: Why I built a hub-and-spoke architecture&lt;br&gt;
Open source philosophy: Free forever, configurable by design&lt;br&gt;
Until then, run the tools. Measure your codebase. See how invisible it really is.&lt;/p&gt;

&lt;p&gt;Try it yourself:&lt;/p&gt;

&lt;p&gt;&lt;a href="//aiready.dev"&gt;Home page&lt;/a&gt;&lt;br&gt;
&lt;a href="//github.com/caopengau/aiready-cli"&gt;GitHub&lt;/a&gt;&lt;br&gt;
Want to support this work?&lt;/p&gt;

&lt;p&gt;⭐ Star the repo&lt;br&gt;
🐛 Report issues you find&lt;br&gt;
💬 Share your results (I read every comment)&lt;br&gt;
Peng Cao is building open source tools for AI-ready development. He’s also the creator of ReceiptClaimer, an AI-powered receipt tracker for Australian taxpayers. Follow along as he builds in public.&lt;/p&gt;

&lt;p&gt;Read the series:&lt;/p&gt;

&lt;p&gt;Part 1: The AI Code Debt Tsunami is Here&lt;br&gt;
Part 2: Why Your Codebase is Invisible to AI ← You are here&lt;br&gt;
Part 3: Building AIReady — Metrics That Actually Matter (coming Next)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>coding</category>
      <category>agents</category>
      <category>software</category>
    </item>
    <item>
      <title>The AI Code Debt Tsunami is Here (And We’re Not Ready)</title>
      <dc:creator>Peng Cao</dc:creator>
      <pubDate>Thu, 15 Jan 2026 22:50:07 +0000</pubDate>
      <link>https://dev.to/peng_cao/the-ai-code-debt-tsunami-is-here-and-were-not-ready-36jl</link>
      <guid>https://dev.to/peng_cao/the-ai-code-debt-tsunami-is-here-and-were-not-ready-36jl</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Part 1 of “The AI Code Debt Tsunami” series&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Six months ago, GitHub Copilot helped me write a user validation function in 30 seconds. Yesterday, it wrote the same function again. And again. Five different versions across my codebase, each slightly different, none aware of the others.&lt;/p&gt;

&lt;p&gt;This isn’t a bug in the AI. This is the new normal. The probabilistic nature is the characteristics of the LLM coding agents and the limited context for each interaction.&lt;/p&gt;

&lt;p&gt;We’re witnessing the fastest productivity boost in software development history. AI coding assistants have made us 5x-10x faster at writing individual functions. But there’s a dark side we’re only beginning to understand: AI-generated code creates tech debt at an unprecedented scale and speed.&lt;/p&gt;

&lt;p&gt;Traditional tech debt accumulates exponentially by number of team member multiplied by the number of coding agent each one uses — messy code compounds over months into years. AI code debt accumulates exponentially. What used to take 18 months to become unmaintainable now happens in 6 weeks.&lt;/p&gt;

&lt;p&gt;The tsunami is here. Most teams don’t even see the wave.&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%2F7ooh9f7fukgy5t5m74t6.png" 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%2F7ooh9f7fukgy5t5m74t6.png" alt=" " width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Paradox: Going Fast While Falling Behind
&lt;/h2&gt;

&lt;p&gt;Here’s what I observed while building &lt;a href="https://receiptclaimer.com.au/" rel="noopener noreferrer"&gt;receiptclaimer&lt;/a&gt;, a receipt processing SaaS&lt;br&gt;
:&lt;/p&gt;

&lt;p&gt;Week 1–2: 🚀 Amazing! We’re shipping features daily. Copilot writes boilerplate, Claude helps with complex logic, ChatGPT generates tests. We’re moving 3x faster than any team I’ve been on.&lt;/p&gt;

&lt;p&gt;Week 3–4: 🤔 Hmm. Our AI assistants keep suggesting we create utilities that… already exist? They’re also suggesting 3 different patterns for the same API endpoint. Which one is “right”?&lt;/p&gt;

&lt;p&gt;Week 5–6: 😰 Wait. Our codebase has 23 nearly-identical handler functions. Our import chains are 8 levels deep. AI tools are now giving worse suggestions because they can’t fit our context into their windows. We’ve gone from 10x faster to 5x faster, probably drop quicker as time passes.&lt;/p&gt;

&lt;p&gt;The math: 1 months of 10x productivity = 12 months of traditional work. But we also accumulated what feels like 24 months of tech debt. Net result? We need to shift the focus to maintain that high multiplier.&lt;/p&gt;

&lt;p&gt;This is the AI code debt paradox: The faster AI helps you write code, the faster you accumulate debt you can’t see. Eventually, it becomes a codebase only for AI but not for human.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Four Horsemen of AI Code Debt
&lt;/h2&gt;

&lt;p&gt;After analyzing dozens of AI-assisted projects (including my own), I’ve identified four distinct problems that traditional metrics completely miss:&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%2Fbndv1cg2spy4db937bkz.png" 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%2Fbndv1cg2spy4db937bkz.png" alt=" " width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Knowledge Cutoff Gaps (The Outdated Pattern Problem)
&lt;/h3&gt;

&lt;p&gt;AI models have training cutoffs. GPT-4’s knowledge ends in April 2023. Claude’s is a bit later. But your best practices evolved last month.&lt;/p&gt;

&lt;p&gt;The result: AI confidently suggests patterns that were deprecated in your codebase months ago. It recommends libraries you’ve already migrated away from. It writes code that technically works but violates architectural decisions made after its training data was collected.&lt;/p&gt;

&lt;p&gt;Real example from &lt;a href="https://receiptclaimer.com.au/" rel="noopener noreferrer"&gt;receiptclaimer&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// AI suggested this in November 2025:
app.get('/api/receipts', async (req, res) =&amp;gt; {
  const { userId } = req.query;
  // ... validation logic
});

// But we standardized on this pattern in a few times!!!:
app.get('/api/receipts', withAuth(async (req, res) =&amp;gt; {
  const userId = req.user.id; // From auth middleware
  // ... no validation needed, it's in middleware
}));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI didn’t know about our &lt;code&gt;withAuth&lt;/code&gt; middleware because it was created 3 months after training cutoff. Result? 18 endpoints using the old pattern, 12 using the new one. All written by AI. All technically correct. All inconsistent.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Model Preference Drift (The Team Chaos Problem)
&lt;/h3&gt;

&lt;p&gt;Your frontend dev prefers Cursor. Your backend dev swears by GitHub Copilot. Your junior dev uses ChatGPT. Each AI has different preferences for how to solve problems.&lt;/p&gt;

&lt;p&gt;The result: Your codebase becomes a Frankenstein of 3 different “AI styles,” each internally consistent, but totally incompatible with each other.&lt;/p&gt;

&lt;p&gt;Real example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Copilot likes this: const user = await db.users.findById(userId)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Claude prefers: const user = await getUserById(userId) (wrapped in helper)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ChatGPT suggests: const user = await User.findById(userId) (ORM style)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three work. None are wrong. But when you have all three scattered across 100 files, your AI assistants get confused trying to help with refactoring. Which pattern should they follow?&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Undetected Semantic Duplicates (The Invisible Repetition Problem)
&lt;/h3&gt;

&lt;p&gt;This is the most insidious one. AI generates code that looks different but does the same thing.&lt;/p&gt;

&lt;p&gt;Traditional duplicate detection tools (like jscpd) only catch copy-paste duplicates — exact text matches. But AI never copy-pastes. It generates fresh code every time, with different variable names, slightly different logic, but functionally identical.&lt;/p&gt;

&lt;p&gt;Real example from &lt;a href="https://receiptclaimer.com.au/" rel="noopener noreferrer"&gt;receiptclaimer&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File 1: src/api/receipts.ts
const validateReceipt = (data) =&amp;gt; {
  if (!data.amount || data.amount &amp;lt;= 0) return false;
  if (!data.date || new Date(data.date) &amp;gt; new Date()) return false;
  if (!data.merchant || data.merchant.trim().length === 0) return false;
  return true;
}

// File 2: src/services/receipt-validator.ts  
export function isValidReceipt(receipt) {
  const hasAmount = receipt.amount &amp;amp;&amp;amp; receipt.amount &amp;gt; 0;
  const hasValidDate = receipt.date &amp;amp;&amp;amp; new Date(receipt.date) &amp;lt;= new Date();
  const hasMerchant = receipt.merchant?.trim().length &amp;gt; 0;
  return hasAmount &amp;amp;&amp;amp; hasValidDate &amp;amp;&amp;amp; hasMerchant;
}

// File 3: src/utils/validation.ts
class ReceiptValidator {
  static validate(r) {
    return r.amount &amp;gt; 0 &amp;amp;&amp;amp; 
           new Date(r.date) &amp;lt;= new Date() &amp;amp;&amp;amp; 
           r.merchant.trim() !== '';
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three different files. Three different names. Three different syntaxes. Same exact logic.&lt;/p&gt;

&lt;p&gt;Traditional linters see zero duplication (0% text overlap). But they’re wasting hundreds of AI tokens and confusing the models. When Copilot sees all three, it doesn’t know which pattern to follow, so it creates a fourth variant.&lt;/p&gt;

&lt;p&gt;We found 23 of these in our codebase. That’s 8,450 tokens of wasted context every time AI tries to understand our validation logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Context Fragmentation (The Token Budget Problem)
&lt;/h3&gt;

&lt;p&gt;AI models have limited context windows. GPT-4 Turbo has 128K tokens. Claude 3.5 has 200K. Sounds like a lot, right?&lt;/p&gt;

&lt;p&gt;Wrong.&lt;/p&gt;

&lt;p&gt;When your code is fragmented across dozens of files with deep import chains, AI needs to load massive amounts of context just to understand one function.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/api/users.ts (850 tokens)
import { getUserById } from '../services/user-service'; // +2,100 tokens
import { validateUser } from '../utils/user-validation'; // +1,800 tokens  
import { UserModel } from '../models/user'; // +2,100 tokens
import { logger } from '../lib/logger'; // +450 tokens
import { cache } from '../helpers/cache'; // +900 tokens

export const getUser = async (id) =&amp;gt; {
  // 20 lines of actual code
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To understand this 20-line function, AI needs to load:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The function itself: 850 tokens&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All its imports: 7,350 tokens&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Become a member&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Their transitive dependencies: ~4,000 more tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total: 12,200 tokens for a 20-line function.&lt;/p&gt;

&lt;p&gt;Now multiply this across your entire codebase. We discovered that some of our “simple” user management operations were costing 15,000+ tokens just for AI to understand the context. That’s 10% of GPT-4’s context window for one feature domain.&lt;/p&gt;

&lt;p&gt;The result? AI gives incomplete answers, misses important context, or suggests refactorings that break transitive dependencies it couldn’t fit in its window.&lt;/p&gt;

&lt;p&gt;Why Traditional Metrics Miss This Entirely&lt;br&gt;
If you’re running SonarQube, CodeClimate, or similar tools, you feel pretty confident about your code quality. You shouldn’t be.&lt;/p&gt;

&lt;p&gt;Traditional metrics were designed for human code review, not AI code consumption:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cyclomatic complexity: Measures branching logic (good for humans debugging). Useless for detecting semantic duplicates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Code coverage: Measures test coverage (good for reliability). Doesn’t detect context fragmentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Duplication detection: Measures text similarity (catches copy-paste). Blind to AI-generated semantic duplicates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dependency graphs: Shows imports (good for architecture). Doesn’t measure token cost.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these tools answer the questions that matter in an AI-first world:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How much does it cost AI to understand this file?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Are there semantically similar patterns AI keeps recreating?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is this code organized in a way AI can consume efficiently?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Will AI suggestions be consistent with our existing patterns?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’re using 2015 metrics for 2025 problems.&lt;/p&gt;

&lt;p&gt;The Real Cost (In Numbers You Can Measure)&lt;br&gt;
Let me translate this into business impact, using real numbers from &lt;a href="https://receiptclaimer.com.au/" rel="noopener noreferrer"&gt;receiptclaimer&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;Before AI-readiness optimization:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;23 &lt;strong&gt;semantic duplicate patterns&lt;/strong&gt; (undetected by traditional tools)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Average &lt;strong&gt;context budget&lt;/strong&gt; per feature: 12,000 tokens&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AI response quality: ~60% useful without additional clarification&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Time to onboard new AI patterns: ~2 hours of prompt engineering per feature&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Developer frustration: High (AI keeps suggesting “wrong” patterns)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Impact on velocity
&lt;/h3&gt;

&lt;p&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Week 1–4: 10x faster than baseline ✅&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Week 5–12: 5x faster than baseline ⚠️&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Week 13–20: pretty much baseline ❌&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Week 21+: Velocity crisis — considering partial rewrite ❌❌&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hidden cost: We spent 4 months going fast in the wrong direction. The refactoring tax came due, and it was massive.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Comes Next
&lt;/h2&gt;

&lt;p&gt;Here’s the uncomfortable truth: Every team using AI coding assistants is accumulating this debt right now. The only difference is some realize it, most don’t.&lt;/p&gt;

&lt;p&gt;The good news? This is measurable. Fixable. Preventable.&lt;/p&gt;

&lt;p&gt;Over the next few weeks, I’m going to break down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How to detect &lt;strong&gt;semantic duplicates&lt;/strong&gt; AI creates (even traditional tools miss)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to measure &lt;strong&gt;context costs and fragmentation&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to optimize your codebase so AI tools work with your patterns instead of against them&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real case study of how we refactored &lt;a href="https://receiptclaimer.com.au/" rel="noopener noreferrer"&gt;receiptclaimer&lt;/a&gt; and quantified the results&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built aiready suite tools to solve this problem for myself and my team. It’s open source, configurable, and designed for the AI-first development workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@aiready/cli" rel="noopener noreferrer"&gt;@aiready/cli&lt;/a&gt;: Unified CLI interface for running all below analysis tools together or individually&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/@aiready/pattern-detect" rel="noopener noreferrer"&gt;@aiready/pattern-detect&lt;/a&gt;: Detect semantic duplicate patterns that waste AI context window tokens&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/@aiready/context-analyzer" rel="noopener noreferrer"&gt;@aiready/context-analyzer&lt;/a&gt;: Analyze context window costs, import depth, cohesion, and fragmentation&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/@aiready/consistency" rel="noopener noreferrer"&gt;@aiready/consistency&lt;/a&gt;: Check naming conventions and pattern consistency across your codebase&lt;br&gt;
Because here’s what I learned: Making your codebase AI-ready doesn’t just make AI better. It makes your code better for humans too.&lt;/p&gt;

&lt;p&gt;Clean, consistent, well-organized code has always been the ideal. AI just makes the cost of not doing it much more immediate and painful.&lt;/p&gt;

&lt;p&gt;The tsunami is here. But we can learn to surf!&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%2Fbm1bzrvqnuea63lszlyd.png" 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%2Fbm1bzrvqnuea63lszlyd.png" alt=" " width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next in this series: Part 2 — “Why Your Codebase is Invisible to AI (And What to Do About It)” — We’ll dive deep into semantic duplicates and context fragmentation, with concrete examples and detection strategies.&lt;/p&gt;

&lt;p&gt;Have questions or war stories about AI-generated tech debt? Drop them in the comments. I read every one.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>coding</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
