<?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: Majdi Zlitni</title>
    <description>The latest articles on DEV Community by Majdi Zlitni (@majdizlitni).</description>
    <link>https://dev.to/majdizlitni</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F663655%2Fc25e42cd-b11f-44d6-845f-44d0014ba343.jpg</url>
      <title>DEV Community: Majdi Zlitni</title>
      <link>https://dev.to/majdizlitni</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/majdizlitni"/>
    <language>en</language>
    <item>
      <title>Agent Skills and how to use them</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Sat, 29 Aug 2026 17:00:46 +0000</pubDate>
      <link>https://dev.to/majdizlitni/agent-skills-and-how-to-use-them-46hb</link>
      <guid>https://dev.to/majdizlitni/agent-skills-and-how-to-use-them-46hb</guid>
      <description>&lt;p&gt;If your AI assistant keeps giving generic, unreliable answers, the problem is not the model. It is the missing structure around it. That is exactly what Agent Skills solve.&lt;/p&gt;

&lt;p&gt;Modern LLMs are strong enough to handle complex tasks. The real issue is that they are working without stable context, rules, or domain-specific instructions that guide how they should behave in your environment.&lt;/p&gt;

&lt;p&gt;This is where Agent Skills change the equation.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Agent Skills Overview&lt;/li&gt;
&lt;li&gt;Why Agent Skills?&lt;/li&gt;
&lt;li&gt;How Do Agent Skills Work?&lt;/li&gt;
&lt;li&gt;Start from real expertise&lt;/li&gt;
&lt;li&gt;Project skills vs personal skills&lt;/li&gt;
&lt;li&gt;How Copilot uses agent skills&lt;/li&gt;
&lt;li&gt;Creating and adding a skill&lt;/li&gt;
&lt;li&gt;Example SKILL.md file&lt;/li&gt;
&lt;li&gt;Triggering a skill in VS Code&lt;/li&gt;
&lt;li&gt;Skills vs custom instructions&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Agent Skills Overview
&lt;/h2&gt;

&lt;p&gt;Agent skills are instructions and resources that a model can use for a given task to improve its output.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgzokni1w4t3znvoo179f.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgzokni1w4t3znvoo179f.gif" alt="Working agent" width="402" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agent skills are designed to work with modern AI coding assistants and LLM-based agents. While our current implementation leverages GitHub Copilot across tools like VS Code and CLI workflows, the architecture remains provider-agnostic and can be adapted to any compatible AI platform.&lt;/p&gt;

&lt;p&gt;You can create your own skills so an agent can perform tasks in a specific way.&lt;/p&gt;

&lt;p&gt;You can use both skills and custom instructions to teach Copilot how to work in your repository and how to perform specific tasks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Agent Skills?
&lt;/h2&gt;

&lt;p&gt;Agents are massively capable, but often they don't have the needed context for more reliable output. Using skills we can solve this by packaging user-specific context into a portable version an agent can load on demand so agents can be:&lt;/p&gt;

&lt;p&gt;Domain expertise: Capture specialized knowledge as reusable instructions and resources.&lt;br&gt;&lt;br&gt;
Repeatable workflows: Turn multi-step tasks into consistent, auditable procedures.&lt;br&gt;&lt;br&gt;
Cross-product reuse: Build a skill once and use it across any skills-compatible agent.&lt;/p&gt;

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


&lt;h2&gt;
  
  
  How Do Agent Skills Work?
&lt;/h2&gt;

&lt;p&gt;Agents load skills in three stages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discovery&lt;/strong&gt;: At startup, agents load only the name and description of each available skill, just enough to know when it might be relevant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Activation&lt;/strong&gt;: When a task matches a skill's description, the agent reads the full SKILL.md instructions into context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Execution&lt;/strong&gt;: The agent follows the instructions, optionally executing bundled code or loading referenced files as needed.&lt;/p&gt;

&lt;p&gt;Full instructions load only when a task calls for them, so agents can keep many skills on hand with only a small context footprint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh1a3wjxraz6syvd9z8ft.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh1a3wjxraz6syvd9z8ft.gif" alt="Confused Pulp Fiction" width="426" height="213"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Start from real expertise
&lt;/h2&gt;

&lt;p&gt;A common pitfall in skill creation is asking an LLM to generate a skill without providing domain-specific context, relying solely on the LLM’s general training knowledge. The result is vague, generic procedures (“handle errors appropriately,” “follow best practices for authentication”) rather than the specific API patterns, edge cases, and project conventions that make a skill valuable.&lt;/p&gt;

&lt;p&gt;Effective skills are grounded in real expertise. The key is feeding domain-specific context into the creation process.&lt;/p&gt;

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


&lt;h2&gt;
  
  
  Project skills vs personal skills
&lt;/h2&gt;

&lt;p&gt;Project skills, stored in your repository (.github/skills, .claude/skills, or .agents/skills)&lt;br&gt;&lt;br&gt;
Personal skills, stored in your home directory and shared across projects (~/.copilot/skills or ~/.agents/skills)&lt;/p&gt;


&lt;h2&gt;
  
  
  How Copilot uses agent skills
&lt;/h2&gt;

&lt;p&gt;When performing tasks, Copilot will decide when to use your skills based on your prompt and the skill's description.&lt;/p&gt;

&lt;p&gt;When Copilot chooses to use a skill, the SKILL.md file will be injected in the agent's context, giving the agent access to your instructions. It can then follow those instructions and use any scripts or examples you may have included in the skill's directory.&lt;/p&gt;

&lt;p&gt;For Copilot code review on GitHub:&lt;/p&gt;

&lt;p&gt;If you want to ensure Copilot code review uses a skill, place it in a review-focused directory like &lt;code&gt;code-review&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
Skills in &lt;code&gt;.github/skills&lt;/code&gt; can also be picked up automatically when relevant.&lt;/p&gt;


&lt;h2&gt;
  
  
  Creating and adding a skill
&lt;/h2&gt;

&lt;p&gt;To create an agent skill, you write a &lt;code&gt;SKILL.md&lt;/code&gt; file and optionally add supporting files like scripts or examples.&lt;/p&gt;

&lt;p&gt;Create a skills directory in one of these locations:&lt;/p&gt;

&lt;p&gt;Project skills:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.github/skills  
.claude/skills  
.agents/skills  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Personal skills:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.copilot/skills  
~/.agents/skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each skill must live in its own folder:&lt;br&gt;
&lt;code&gt;.github/skills/webapp-testing&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Folder names must be lowercase and use hyphens.&lt;/p&gt;

&lt;p&gt;Inside it, create &lt;code&gt;SKILL.md&lt;/code&gt;.&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;Important&lt;/p&gt;

&lt;p&gt;Skill files must be named &lt;code&gt;SKILL.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It must include:&lt;/p&gt;

&lt;p&gt;YAML frontmatter:&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name (required)&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lowercase identifier matching folder name&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;description (required)&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;when the skill should be used&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;license (optional)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Markdown body:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Instructions
- Examples
- Guidelines for the agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Example SKILL.md file
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&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;resume-update&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use this skill when the user asks to update, rewrite, or tailor a resume for a job application.&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="c1"&gt;# Resume Update Skill&lt;/span&gt;

&lt;span class="c1"&gt;## Instructions&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Rewrite resumes based on job description&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Improve clarity and structure&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Use concise bullet points&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Highlight relevant skills and achievements&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Keep it ATS-friendly&lt;/span&gt;

&lt;span class="c1"&gt;## Example&lt;/span&gt;
&lt;span class="na"&gt;User&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Update my resume for a .NET backend role&lt;/span&gt;  
&lt;span class="na"&gt;Assistant&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Returns a rewritten resume emphasizing .NET, APIs, and backend experience.&lt;/span&gt;

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Triggering a skill in VS Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option 1: Natural language
&lt;/h3&gt;

&lt;p&gt;Just ask normally:&lt;/p&gt;

&lt;p&gt;Help me update my resume for a .NET backend role&lt;/p&gt;

&lt;p&gt;If skill matches description → it auto-loads&lt;/p&gt;




&lt;h3&gt;
  
  
  Option 2: Slash command
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/resume-update
/webapp-testing
/github-actions-debugging

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

&lt;/div&gt;



&lt;p&gt;You can also add extra context:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/resume-update for senior backend role&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  SKILL.md structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&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;skill-name&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;When and why this skill should be used&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="na"&gt;Then markdown instructions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="c1"&gt;### Instructions&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Step &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Step &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Step &lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Skills vs custom instructions
&lt;/h2&gt;

&lt;p&gt;We recommend using custom instructions for simple instructions relevant to almost every task (for example information about your repository's coding standards), and skills for more detailed instructions that Copilot should only access when relevant.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
    </item>
    <item>
      <title>10 EF Core Performance Mistakes That Ship to Production</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Wed, 26 Aug 2026 16:16:05 +0000</pubDate>
      <link>https://dev.to/majdizlitni/10-ef-core-performance-mistakes-that-ship-to-production-1gpc</link>
      <guid>https://dev.to/majdizlitni/10-ef-core-performance-mistakes-that-ship-to-production-1gpc</guid>
      <description>&lt;p&gt;If your API is fast with seed data but slows down in production, EF Core is rarely the root cause. It is usually the amplifier.&lt;/p&gt;

&lt;p&gt;Most teams do not have one catastrophic query. They have many small query-shape decisions that compound into high P95 latency, lock pressure, and unnecessary database scale-up.&lt;/p&gt;

&lt;p&gt;This article is a practical field guide to 10 EF Core performance mistakes I keep seeing in production .NET APIs, and the fixes that usually move the needle first.&lt;/p&gt;

&lt;h2&gt;
  
  
  In this post
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why this matters in production&lt;/li&gt;
&lt;li&gt;How to spot issues fast&lt;/li&gt;
&lt;li&gt;Architecture map of the anti-patterns&lt;/li&gt;
&lt;li&gt;Quick summary of all 10 mistakes&lt;/li&gt;
&lt;li&gt;Mistake 1: N+1 Queries&lt;/li&gt;
&lt;li&gt;Mistake 2: Missing AsNoTracking&lt;/li&gt;
&lt;li&gt;Mistake 3: Loading Whole Entities&lt;/li&gt;
&lt;li&gt;Mistake 4: No Pagination&lt;/li&gt;
&lt;li&gt;Mistake 5: Client-Side Evaluation&lt;/li&gt;
&lt;li&gt;Mistake 6: Tracking Read-Only Data&lt;/li&gt;
&lt;li&gt;Mistake 7: Cartesian Explosion&lt;/li&gt;
&lt;li&gt;Mistake 8: No Compiled Queries&lt;/li&gt;
&lt;li&gt;Mistake 9: Missing Indexes&lt;/li&gt;
&lt;li&gt;Mistake 10: SaveChanges in a Loop&lt;/li&gt;
&lt;li&gt;Batch ops caveat: ExecuteUpdate and ExecuteDelete&lt;/li&gt;
&lt;li&gt;Decision matrix: what to fix first&lt;/li&gt;
&lt;li&gt;What EF Core 10 improves&lt;/li&gt;
&lt;li&gt;Troubleshooting checklist&lt;/li&gt;
&lt;li&gt;Production baseline checklist&lt;/li&gt;
&lt;li&gt;Wrap-up&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What counts as a performance mistake?
&lt;/h2&gt;

&lt;p&gt;An EF Core performance mistake is any data-access pattern that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;returns correct results in development&lt;/li&gt;
&lt;li&gt;passes tests&lt;/li&gt;
&lt;li&gt;but degrades badly under real data volume or concurrency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words: correctness is not enough. Query shape is architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to detect issues quickly
&lt;/h2&gt;

&lt;p&gt;Before changing code, instrument first.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AppDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseNpgsql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LogLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Information&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnableSensitiveDataLogging&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsDevelopment&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use this as your first pass:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;many SELECTs per request: likely N+1&lt;/li&gt;
&lt;li&gt;huge result row count for small parent set: likely cartesian explosion&lt;/li&gt;
&lt;li&gt;read endpoints with heavy tracking snapshots: missing AsNoTracking&lt;/li&gt;
&lt;li&gt;list endpoints without LIMIT/TOP: missing pagination&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The anti-pattern map
&lt;/h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsa11r4dbbvc2cfq01etw.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsa11r4dbbvc2cfq01etw.png" alt="EF Core anti-pattern architecture map" width="510" height="1846"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prefer scalable quality for sharing and zoom:&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;The 10 mistakes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;N+1 queries&lt;/li&gt;
&lt;li&gt;Loading full entities instead of projections&lt;/li&gt;
&lt;li&gt;Missing AsNoTracking on read paths&lt;/li&gt;
&lt;li&gt;No pagination on list endpoints&lt;/li&gt;
&lt;li&gt;Client-side evaluation patterns&lt;/li&gt;
&lt;li&gt;Tracking read-only graphs&lt;/li&gt;
&lt;li&gt;Cartesian explosion from multiple collection Includes&lt;/li&gt;
&lt;li&gt;No compiled queries on hot paths&lt;/li&gt;
&lt;li&gt;Missing indexes on hot filters and joins&lt;/li&gt;
&lt;li&gt;SaveChanges inside loops&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Plus one operational caveat: ExecuteUpdate and ExecuteDelete bypass the change tracker and should be coordinated with explicit transaction boundaries when mixed with tracked changes.&lt;/p&gt;

&lt;p&gt;&lt;a id="mistake-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1) N+1 Queries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;You load a parent set, then each navigation access triggers another database round trip.&lt;/p&gt;

&lt;h3&gt;
  
  
  Smell
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Request count looks normal&lt;/li&gt;
&lt;li&gt;SQL command count explodes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fix
&lt;/h3&gt;

&lt;p&gt;Use projection or eager loading intentionally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;customerId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;OrderDto&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Total&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Price&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quantity&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;ItemCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use projection for API contracts. Use Include when domain logic needs full related aggregates in memory.&lt;/p&gt;

&lt;p&gt;&lt;a id="mistake-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2) Missing AsNoTracking
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Tracking every entity in read paths increases memory and CPU for change detection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix
&lt;/h3&gt;

&lt;p&gt;Default to no tracking on query endpoints.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Posts&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Published&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OrderByDescending&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PublishedAt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For write paths, opt back in explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a id="mistake-3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3) Loading Whole Entities
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Fetching full rows when you only need 2-3 columns inflates payload and materialization cost.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix
&lt;/h3&gt;

&lt;p&gt;Project to DTOs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;UserListItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DisplayName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AvatarUrl&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Projection usually improves all of these at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;less SQL payload&lt;/li&gt;
&lt;li&gt;lower materialization cost&lt;/li&gt;
&lt;li&gt;better API boundary control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a id="mistake-4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4) No Pagination
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Unbounded lists eventually become accidental load tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix
&lt;/h3&gt;

&lt;p&gt;Apply deterministic ordering and pagination.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Articles&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OrderByDescending&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreatedAt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Skip&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PageSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always cap server-side page size to prevent accidental heavy requests.&lt;/p&gt;

&lt;p&gt;&lt;a id="mistake-5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5) Client-Side Evaluation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Non-translatable logic forces EF Core to pull data and evaluate in memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix
&lt;/h3&gt;

&lt;p&gt;Keep filters SQL-translatable, move complex logic after narrowing rows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;filtered&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Payments&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;PaymentStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Settled&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Amount&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reference&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rule: filter, sort, and paginate before materialization. Terminal operators like ToListAsync end translation and execute the query.&lt;/p&gt;

&lt;p&gt;&lt;a id="mistake-6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6) Tracking Read-Only Data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Long-running request flows with tracked entities increase memory pressure and GC churn.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix
&lt;/h3&gt;

&lt;p&gt;Use one of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AsNoTracking for pure reads&lt;/li&gt;
&lt;li&gt;AsNoTrackingWithIdentityResolution when graph identity consistency matters
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;graph&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTrackingWithIdentityResolution&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use AsNoTrackingWithIdentityResolution when you need consistent identity for repeated references in the same result graph without full tracking overhead.&lt;/p&gt;

&lt;p&gt;&lt;a id="mistake-7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7) Cartesian Explosion
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Multiple collection Includes on one query create row multiplication.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix
&lt;/h3&gt;

&lt;p&gt;Use split queries when shape is unavoidable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Events&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsSplitQuery&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Split queries trade one huge cross-product for multiple smaller round trips. Measure both modes on your dataset.&lt;/p&gt;

&lt;p&gt;&lt;a id="mistake-8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8) No Compiled Queries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Hot endpoints repeatedly pay query translation overhead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix
&lt;/h3&gt;

&lt;p&gt;Precompile stable high-frequency queries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AppDbContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GetUserByIdCompiled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;EF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CompileAsyncQuery&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;AppDbContext&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsNoTracking&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&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;GetUserByIdCompiled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply compiled queries selectively to the highest-throughput read paths.&lt;/p&gt;

&lt;p&gt;&lt;a id="mistake-9"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  9) Missing Indexes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Critical filters run as scans instead of seeks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix
&lt;/h3&gt;

&lt;p&gt;Create indexes for common predicates and sort keys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;modelBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HasIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CustomerId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also verify generated SQL and query plan. If your API filter is index-friendly but still scanning, check collation mismatches and implicit conversions.&lt;/p&gt;

&lt;p&gt;Index guidance for hot endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;index frequent WHERE columns&lt;/li&gt;
&lt;li&gt;index JOIN keys&lt;/li&gt;
&lt;li&gt;index ORDER BY columns used with pagination&lt;/li&gt;
&lt;li&gt;prefer composite indexes that match filter plus sort order&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a id="mistake-10"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  10) SaveChanges in a Loop
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Each SaveChanges call is a round trip and transaction boundary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix
&lt;/h3&gt;

&lt;p&gt;Batch entity changes, then persist once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MarkProcessed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this runs inside import or reconciliation jobs, moving SaveChanges out of the loop is often the fastest immediate win.&lt;/p&gt;

&lt;p&gt;&lt;a id="batch-ops-caveat"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Batch operations caveat: ExecuteUpdate and ExecuteDelete
&lt;/h2&gt;

&lt;p&gt;ExecuteUpdate and ExecuteDelete bypass the change tracker.&lt;/p&gt;

&lt;p&gt;If you mix them with tracked updates in the same unit of work, wrap all operations in an explicit transaction to protect consistency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;BeginTransactionAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Orders&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;OrderStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pending&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreatedAt&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;cutoff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteUpdateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;setters&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;setters&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OrderStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Expired&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;audit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CleanupAudit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;RanAtUtc&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Affected&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;affectedRows&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CleanupAudits&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="n"&gt;audit&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CommitAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why this matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;batch operators bypass change tracker&lt;/li&gt;
&lt;li&gt;SaveChanges interceptors may not run for those operations&lt;/li&gt;
&lt;li&gt;mixed write workflows should be explicit about consistency boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Decision matrix: what to fix first
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;First fix&lt;/th&gt;
&lt;th&gt;Then&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;many SQL commands per request&lt;/td&gt;
&lt;td&gt;projection or Include cleanup&lt;/td&gt;
&lt;td&gt;check for lazy loading&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;large payload and high serialization cost&lt;/td&gt;
&lt;td&gt;projection DTOs&lt;/td&gt;
&lt;td&gt;AsNoTracking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;high read-path memory&lt;/td&gt;
&lt;td&gt;AsNoTracking&lt;/td&gt;
&lt;td&gt;query-level projection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;huge row count from multi-Include&lt;/td&gt;
&lt;td&gt;AsSplitQuery&lt;/td&gt;
&lt;td&gt;endpoint-specific projection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;slow large updates/deletes&lt;/td&gt;
&lt;td&gt;ExecuteUpdate/ExecuteDelete&lt;/td&gt;
&lt;td&gt;transaction + audit strategy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;list endpoint timeout&lt;/td&gt;
&lt;td&gt;pagination&lt;/td&gt;
&lt;td&gt;indexes + projection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hot endpoint CPU overhead&lt;/td&gt;
&lt;td&gt;compiled query&lt;/td&gt;
&lt;td&gt;caching strategy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What EF Core 10 helps with
&lt;/h2&gt;

&lt;p&gt;EF Core 10 improves the baseline, but does not remove bad query-shape costs.&lt;/p&gt;

&lt;p&gt;Useful platform gains to leverage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;improved LINQ ergonomics for complex joins&lt;/li&gt;
&lt;li&gt;stronger behavior around split-query ordering consistency&lt;/li&gt;
&lt;li&gt;runtime improvements in .NET 10 that help materialization paths&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bottom line: framework improvements help good patterns more than bad ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting checklist
&lt;/h2&gt;

&lt;p&gt;If performance is still poor after applying fixes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;inspect SQL plans, not just LINQ&lt;/li&gt;
&lt;li&gt;verify index usage in production-like data&lt;/li&gt;
&lt;li&gt;confirm no hidden lazy-loading path in serialization&lt;/li&gt;
&lt;li&gt;verify query count per request in high-traffic endpoints&lt;/li&gt;
&lt;li&gt;re-check page size limits and default sort columns&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A practical baseline for production APIs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Default reads to no tracking&lt;/li&gt;
&lt;li&gt;Project to DTOs, not entities&lt;/li&gt;
&lt;li&gt;Always paginate collection endpoints&lt;/li&gt;
&lt;li&gt;Measure query count per request&lt;/li&gt;
&lt;li&gt;Add indexes for every top-traffic filter&lt;/li&gt;
&lt;li&gt;Compile truly hot queries&lt;/li&gt;
&lt;li&gt;Avoid SaveChanges inside loops&lt;/li&gt;
&lt;li&gt;Treat batch operations as transaction-sensitive writes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;EF Core performance is rarely about a single trick. It is about query-shape discipline applied consistently.&lt;/p&gt;

&lt;p&gt;If your P95 latency is climbing, start here before scaling the database tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;Most EF Core incidents are not caused by obscure ORM bugs. They come from convenient defaults used past their safe limits.&lt;/p&gt;

&lt;p&gt;If you adopt one rule, make it this: shape data intentionally at query time. Projection, no-tracking reads, pagination, and index-aware filters will solve most production regressions before you need heavier architecture changes.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>efcore</category>
      <category>performance</category>
    </item>
    <item>
      <title>Effective AI Agents with GitHub Copilot</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Mon, 24 Aug 2026 16:44:08 +0000</pubDate>
      <link>https://dev.to/majdizlitni/effective-ai-agents-with-github-copilot-4ck7</link>
      <guid>https://dev.to/majdizlitni/effective-ai-agents-with-github-copilot-4ck7</guid>
      <description>&lt;p&gt;The most successful AI agent do NOT use complex and over-engineered frameworks. Instead, they use simple, modular patterns.&lt;/p&gt;

&lt;p&gt;To use agents you don't need to learn massive third-party agent frameworks to build powerful AI assistants. Using GitHub Copilot you get all pieces natively: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copilot Agent Mode&lt;/li&gt;
&lt;li&gt;Custom Agents &lt;/li&gt;
&lt;li&gt;Agent Skills &lt;/li&gt;
&lt;li&gt;Prompt Files&lt;/li&gt;
&lt;li&gt;Model Context Protocol (MCP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will break down the core principles on how to implement them in your daily development workflow!&lt;/p&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What is an AI Agent?&lt;/li&gt;
&lt;li&gt;
How Effective Agents Work

&lt;ul&gt;
&lt;li&gt;Pattern 1: Prompt Chaining&lt;/li&gt;
&lt;li&gt;Pattern 2: Routing&lt;/li&gt;
&lt;li&gt;Pattern 3: Parallelization&lt;/li&gt;
&lt;li&gt;Pattern 4: Orchestrator Workers The Project Manager&lt;/li&gt;
&lt;li&gt;Pattern 5: Evaluator Optimizer&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Handoffs Between Agents

&lt;ul&gt;
&lt;li&gt;Why Single Agents Fail&lt;/li&gt;
&lt;li&gt;Architect to Developer Handoff&lt;/li&gt;
&lt;li&gt;Preserving Context Across Handoffs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Mastering Agent Skills

&lt;ul&gt;
&lt;li&gt;The Copilot Customization Pyramid&lt;/li&gt;
&lt;li&gt;
What is an Agent Skill? &lt;/li&gt;
&lt;li&gt;Integrating External Systems via MCP&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
Quick Comparison Matrix
&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. What is an AI Agent?
&lt;/h2&gt;

&lt;p&gt;Before we dive, let's clear up what an &lt;strong&gt;Agent&lt;/strong&gt; actually is. &lt;/p&gt;

&lt;p&gt;An agent is as a fully autonomous system using different tools to achieve a request independently&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxfrzvzr5nnl5kcv5fjlv.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxfrzvzr5nnl5kcv5fjlv.png" alt="Agent" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Basic Building Block
&lt;/h3&gt;

&lt;p&gt;An &lt;strong&gt;Augmented LLM&lt;/strong&gt; is simply a language model (like GPT-5.6 Luna or Claude Opus) connected to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Context&lt;/strong&gt;: Your project's code files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: The ability to run commands and execute tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt;: The chat history.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In GitHub Copilot, every query you send has access to these augmentations natively inside your IDE!&lt;/p&gt;




&lt;h2&gt;
  
  
  2. How Effective Agents Work
&lt;/h2&gt;

&lt;p&gt;Rather than letting an AI run completely wild, effective agentic systems use one of the folowing core design patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pattern 1: Prompt Chaining
&lt;/h3&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzyq6ruhx3p2kujjxg7df.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzyq6ruhx3p2kujjxg7df.png" alt="Effective Agents" width="800" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Breaking a big task into a sequence of small, step-by-step prompts. Between each step, code execution acts as a &lt;strong&gt;Gate&lt;/strong&gt; to verify output before moving to the next step.&lt;br&gt;
This can be achieved by: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create a reusable prompt file inside &lt;code&gt;.github/prompts/create-feature.prompt.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- .github/prompts/create-feature.prompt.md --&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; Read the user requirements and generate the Entity Framework Core model in &lt;span class="sb"&gt;`Domain/Entities/`&lt;/span&gt;.
&lt;span class="p"&gt;2.&lt;/span&gt; Run &lt;span class="sb"&gt;`dotnet build`&lt;/span&gt; in the terminal to verify zero compilation errors.
&lt;span class="p"&gt;3.&lt;/span&gt; If build succeeds, create the corresponding DTO class in &lt;span class="sb"&gt;`Application/DTOs/`&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Pattern 2: Routing
&lt;/h3&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx7xkiyn2p5i05ch9srhk.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx7xkiyn2p5i05ch9srhk.png" alt="the Router" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It classifying the user's intent and sending the request to a specialized assistant or tool.&lt;/p&gt;

&lt;p&gt;Using GitHub Copilot's &lt;code&gt;@&lt;/code&gt; participants:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@workspace&lt;/code&gt;: Searches your entire codebase structure.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@azure&lt;/code&gt;: Handles cloud infrastructure questions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@github&lt;/code&gt;: Interacts with PRs, issues, and actions.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Pattern 3: Parallelization
&lt;/h3&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9pbbs85t6a2e298d8wh8.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9pbbs85t6a2e298d8wh8.png" alt="Agent Parallelization" width="799" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This run multiple AI checks simultaneously and combining their output into a single summary.&lt;/p&gt;

&lt;p&gt;When running automated GitHub Actions or code reviews, trigger multiple custom prompts in parallel (e.g., checking security flaws, checking unit test coverage, checking formatting) and combine the results.&lt;/p&gt;




&lt;h3&gt;
  
  
  Pattern 4: Orchestrator Workers The Project Manager
&lt;/h3&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgwff6p6kwfyx5gtoc402.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgwff6p6kwfyx5gtoc402.png" alt="Orchestrator-Workers" width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A central agent dynamically breaks a complex, unpredictable request into sub-tasks, delegates work to specialized agents or tool steps, and combines the results.&lt;/p&gt;

&lt;p&gt;This is exactly how &lt;strong&gt;Copilot Agent Mode&lt;/strong&gt; works! When you prompt Copilot Agent Mode in VS Code to "Add modern rate-limiting to all ASP.NET Core endpoints," it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scans your solution file.&lt;/li&gt;
&lt;li&gt;Identifies all endpoint classes.&lt;/li&gt;
&lt;li&gt;Edits &lt;code&gt;Program.cs&lt;/code&gt; to add middleware.&lt;/li&gt;
&lt;li&gt;Updates individual controller attributes.&lt;/li&gt;
&lt;li&gt;Runs &lt;code&gt;dotnet build&lt;/code&gt; to confirm everything compiles.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Pattern 5: Evaluator Optimizer
&lt;/h3&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgxj9ourcu7htzblz4yvc.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgxj9ourcu7htzblz4yvc.png" alt="Evaluator-Optimizer" width="800" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One loop generates the solution, while an evaluation step (like a compiler or unit test suite) provides feedback until the code passes all criteria.&lt;/p&gt;

&lt;p&gt;It matters because LLM make mistakes, but tools like &lt;code&gt;dotnet test&lt;/code&gt; or &lt;code&gt;npm test&lt;/code&gt; provide objective &lt;strong&gt;ground truth&lt;/strong&gt;. Letting Copilot fix its own errors based on compiler output makes it dramatically more accurate!&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Handoffs Between Agents
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Single Agents Fail
&lt;/h3&gt;

&lt;p&gt;When you try to make one single prompt handle architecture design, database migration, backend coding, and unit testing, you run into &lt;strong&gt;Context Rot&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The prompt becomes huge and expensive.&lt;/li&gt;
&lt;li&gt;The model forgets early instructions.&lt;/li&gt;
&lt;li&gt;The AI gets confused between different roles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Solution:&lt;/strong&gt; Use &lt;strong&gt;Agent Handoffs&lt;/strong&gt;. Divide your system into small, hyper-focused custom agents, and pass the task smoothly from one agent to the next.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd5gyx9m5z4rtpqefng9t.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd5gyx9m5z4rtpqefng9t.png" alt="Agent Handoffs" width="800" height="563"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Architect to Developer Handoff
&lt;/h3&gt;

&lt;p&gt;In GitHub Copilot, custom agents live inside the &lt;code&gt;.github/agents/&lt;/code&gt; folder as Markdown files with YAML frontmatter.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Define the Architect Agent
&lt;/h4&gt;

&lt;p&gt;Create &lt;code&gt;.github/agents/solution-architect.agent.md&lt;/code&gt;:&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Define the Backend Developer Agent
&lt;/h4&gt;

&lt;p&gt;Create &lt;code&gt;.github/agents/backend-developer.agent.md&lt;/code&gt;:&lt;/p&gt;




&lt;h3&gt;
  
  
  Preserving Context Across Handoffs
&lt;/h3&gt;

&lt;p&gt;When passing work between agents, avoid losing context by using these &lt;strong&gt;Practices&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;File-based handoff:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Agent writes output to a shared workspace file (e.g. &lt;code&gt;.copilot/plans/spec.md&lt;/code&gt;) for the next agent to consume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Structured summary:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Include a short bullet list of key decisions in the handoff prompt.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Minimal tool access:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Grant each agent only the tools it needs (e.g. no terminal access for design agents).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  4. Mastering Agent Skills
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Copilot Customization Pyramid
&lt;/h3&gt;

&lt;p&gt;To turn Copilot into a true expert in your codebase, GitHub provides 5 customization layers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Global Rules&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; / &lt;code&gt;AGENTS.md&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Task Prompts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.github/prompts/*.prompt.md&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Specialized Personas&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.github/agents/*.agent.md&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Procedural Skills&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.github/skills/*/SKILL.md&lt;/code&gt; (agentskills.io)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;External Tooling&lt;/td&gt;
&lt;td&gt;Model Context Protocol (MCP)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  What is an Agent Skill?
&lt;/h3&gt;

&lt;p&gt;While &lt;strong&gt;Custom Instructions&lt;/strong&gt; tell Copilot &lt;em&gt;what style of code to write&lt;/em&gt;, an &lt;strong&gt;Agent Skill&lt;/strong&gt; teaches Copilot &lt;em&gt;how to perform a specific standard operating procedure (SOP)&lt;/em&gt; step-by-step.&lt;/p&gt;

&lt;p&gt;Agent Skills follow the open &lt;strong&gt;&lt;code&gt;agentskills.io&lt;/code&gt;&lt;/strong&gt; standard, making them portable across AI environments!&lt;/p&gt;




&lt;h3&gt;
  
  
  Integrating External Systems via MCP
&lt;/h3&gt;

&lt;p&gt;To connect your Copilot agents to real-world infrastructure (Azure SQL, GitHub Issues, Jira, Redis), use &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now your agents can directly inspect Azure resource health or query GitHub Issues without leaving VS Code!&lt;/p&gt;




&lt;h3&gt;
  
  
  Human-in-the-Loop Safety &amp;amp; Guardrails
&lt;/h3&gt;

&lt;p&gt;Never leave an autonomous agent completely unsupervised in production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Require Confirmation for Destructive Commands:&lt;/strong&gt; Use terminal execution settings in VS Code to prompt for approval on &lt;code&gt;git push --force&lt;/code&gt;, &lt;code&gt;docker run&lt;/code&gt;, or &lt;code&gt;az deploy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set Iteration Limits:&lt;/strong&gt; Limit Copilot Agent Mode loops to a maximum of 5–10 attempts so it doesn't get stuck in an endless loop if tests fail.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Quick Comparison Matrix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuration Type&lt;/th&gt;
&lt;th&gt;Where It Lives&lt;/th&gt;
&lt;th&gt;Main Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Global Rules&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Coding style, project conventions, library choices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prompt Files&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.github/prompts/*.prompt.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Single-click reusable task workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom Agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.github/agents/*.agent.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specialized developer personas &amp;amp; handoff rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent Skills&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.github/skills/*/SKILL.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Step-by-step procedure guides (&lt;code&gt;agentskills.io&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP Servers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;.vscode/mcp.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Real-time external API &amp;amp; database integration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  6. Conclusion
&lt;/h2&gt;

&lt;p&gt;Building powerful AI agents doesn't require complex external frameworks. By combining &lt;strong&gt;GitHub Copilot Agent Mode&lt;/strong&gt;, &lt;strong&gt;Custom Agents&lt;/strong&gt;, &lt;strong&gt;Agent Skills&lt;/strong&gt;, and &lt;strong&gt;MCP&lt;/strong&gt;, you can build a clean, reliable, and production-grade developer agent right inside your IDE!&lt;/p&gt;

&lt;p&gt;Have you built custom agents or skills for GitHub Copilot yet? Let me know in the comments below!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>dotnet</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>The Context Packet: The Right Architectural Coding Agents</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Mon, 24 Aug 2026 00:44:12 +0000</pubDate>
      <link>https://dev.to/majdizlitni/the-context-packet-the-right-architectural-coding-agents-5agc</link>
      <guid>https://dev.to/majdizlitni/the-context-packet-the-right-architectural-coding-agents-5agc</guid>
      <description>&lt;p&gt;A coding agent with access to your entire repository does not necessarily understand your system better. It may understand less.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3wp87d7x36doh9xupdhi.gif" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3wp87d7x36doh9xupdhi.gif" alt="The Odyssey screaming" width="480" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because a large repository may contains obsolete code, and decisions that were never written down. Giving an agent more files increases the amount of text it can inspect, but this does not guarantee it will identify the constraints that matter more.&lt;/p&gt;

&lt;p&gt;The better design is a &lt;strong&gt;context packet&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdm3duz59apykdedxc1sy.gif" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdm3duz59apykdedxc1sy.gif" alt="SpongeBob SquarePants Rainbow " width="400" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;a small, versioned, machine-readable description of the system. The packet complements source code by recording the contracts and decisions that source code alone may not reveal.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Repository Access Is Not System Understanding
&lt;/h2&gt;

&lt;p&gt;A normal coding request might look simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Add retry handling to the payment notification worker.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An agent can find the worker, inspect its dependencies, and produce a patch quickly. But a safe implementation depends on questions that may not be answered in the worker's directory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the message delivered at least once?&lt;/li&gt;
&lt;li&gt;Does the payment provider support idempotency keys?&lt;/li&gt;
&lt;li&gt;Which exceptions are transient?&lt;/li&gt;
&lt;li&gt;Does the consumer rely on a specific delivery count?&lt;/li&gt;
&lt;li&gt;Can this change be deployed independently of the producer?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The repository may contain clues, but clues are not contracts.&lt;/p&gt;

&lt;p&gt;When the agent receives only the ticket and nearby files, it fills the gaps with plausible assumptions. When it receives the entire repository, it has a different problem: the important rule may be surrounded by thousands of irrelevant or contradictory signals.&lt;/p&gt;

&lt;p&gt;The gap comes from context design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieval Boundaries and Signal Density
&lt;/h2&gt;

&lt;p&gt;AI coding systems have a finite context budget. The deeper concern is &lt;strong&gt;signal density&lt;/strong&gt;: the proportion of useful constraints among all the material an agent must interpret.&lt;/p&gt;

&lt;p&gt;Suppose an agent receives 100 files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10 define the target feature&lt;/li&gt;
&lt;li&gt;20 are related infrastructure&lt;/li&gt;
&lt;li&gt;30 are historical implementations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent can technically read all of them. It still has to decide which rules apply, which code is authoritative, and which behavior is accidental.&lt;/p&gt;

&lt;p&gt;More input creates more opportunities for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conflicting examples&lt;/li&gt;
&lt;li&gt;Outdated implementation patterns&lt;/li&gt;
&lt;li&gt;Incorrect dependency inference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common response is to improve the prompt. But prompts are a weak place to store architecture because they are difficult to version and validate.&lt;/p&gt;

&lt;p&gt;The retrieval boundary should answer three questions before content is added to the packet:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can this change affect it?&lt;/li&gt;
&lt;li&gt;Does it define a contract to keep?&lt;/li&gt;
&lt;li&gt;Is it up to date for this branch/commit/env?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This turns context selection into a policy that can be inspected and improved.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Context Packet Pattern
&lt;/h2&gt;

&lt;p&gt;A context packet is the minimal scoped input for a single change or workflow. It includes only the necessary context and constraints, built from a dependency graph instead of folder structure.&lt;/p&gt;

&lt;p&gt;A useful packet covers these technical layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Intent&lt;/strong&gt;: expected outcome
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boundary&lt;/strong&gt;: services, modules, files, data in scope
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contracts&lt;/strong&gt;: APIs, events, schemas, ownership, compatibility
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constraints&lt;/strong&gt;: security, reliability, performance, compliance
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evidence&lt;/strong&gt;: tests, traces, incidents, metrics, examples
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution policy&lt;/strong&gt;: allowed tools and required approvals
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The packet should be versioned and reviewed like code.&lt;br&gt;
It should also remain small enough that an engineer can read it and update it without a separate platform team.&lt;/p&gt;
&lt;h3&gt;
  
  
  A Context Packet in a PR
&lt;/h3&gt;

&lt;p&gt;Taking the example of opening a PR titled &lt;strong&gt;“Retry payment notifications after provider timeouts.”&lt;/strong&gt; The agent does not need a second copy of the repository. It needs the small set of facts that determine whether the change is safe.&lt;/p&gt;

&lt;p&gt;The context assembler follows the changed worker through its dependency graph and produces a short packet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;change&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;retry-payment-notifications&lt;/span&gt;
&lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;payments-platform&lt;/span&gt;

&lt;span class="na"&gt;intent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Retry provider timeouts without sending a notification twice.&lt;/span&gt;

&lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PaymentNotificationWorker.cs&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PaymentProviderAdapter.cs&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PaymentNotification.v2.schema.json&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ADR-017-provider-retries.md&lt;/span&gt;

&lt;span class="na"&gt;edit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PaymentNotificationWorker.cs&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NotificationReplayTests.cs&lt;/span&gt;

&lt;span class="na"&gt;must_preserve&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NotificationId is stable for every delivery attempt.&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;The adapter classifies provider failures.&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Dead-letter records include the failure classification.&lt;/span&gt;

&lt;span class="na"&gt;checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NotificationReplayTests&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DeadLetterContractTests&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent makes one scoped change using the packet. It can read/edit code and rerun tests, but not change infra or identity. CI/CD runs two checks and rejects the PR if it edits outside edit or lacks evidence.&lt;/p&gt;

&lt;p&gt;That is the complete loop:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftj3uu2pu2ghtu7h203r9.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftj3uu2pu2ghtu7h203r9.png" alt="Complete loop" width="800" height="53"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each field has a job:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;read&lt;/code&gt; supplies relevant implementation and architecture decisions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;edit&lt;/code&gt; limits the proposed diff.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;must_preserve&lt;/code&gt; records behavior that source code may not explain.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;checks&lt;/code&gt; connects the packet to the delivery pipeline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep the packet as a change brief, not as a repository summary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context Assembler and Dependency Graph
&lt;/h3&gt;

&lt;p&gt;The assembler starts with the files changed by the pull request and follows declared dependencies outward. A simple graph might look like this:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffdwba2bs0d393survvt3.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffdwba2bs0d393survvt3.png" alt="Context Packet Scoop" width="799" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The graph determines what belongs in the packet. A node is included when it is directly changed, is a dependency of a changed node, or defines an operational contract for that dependency. Unrelated services and historical examples stay outside the retrieval boundary.&lt;/p&gt;

&lt;p&gt;The assembler can collect artifacts from controlled sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repository ownership metadata&lt;/li&gt;
&lt;li&gt;Architecture decision records&lt;/li&gt;
&lt;li&gt;API and event schemas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The assembler should rank artifacts by relevance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring Packet Value
&lt;/h2&gt;

&lt;p&gt;A well-organized packet is useful only when it improves engineering outcomes.&lt;/p&gt;

&lt;p&gt;Start with four signals:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rework&lt;/td&gt;
&lt;td&gt;Did the agent need repeated corrections about the same constraint?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boundary violations&lt;/td&gt;
&lt;td&gt;Did the proposal touch files or tools outside its declared scope?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evidence coverage&lt;/td&gt;
&lt;td&gt;Were the required checks appropriate and actually run?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review effort&lt;/td&gt;
&lt;td&gt;Did reviewers spend less time reconstructing system context?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Tradeoffs and Operational Limits
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Context Assembly Has a Maintenance Cost
&lt;/h3&gt;

&lt;p&gt;Owners must update contracts, schemas, and service metadata. This cost is real. It is also preferable to depending on undocumented knowledge that exists only in one engineer's memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Narrow Context Can Hide Important Dependencies
&lt;/h3&gt;

&lt;p&gt;A packet that is too narrow can create false confidence. Include dependency evidence and make the agent able to request an expanded boundary. Expansion should be logged and, for sensitive boundaries, approved.&lt;/p&gt;

&lt;h3&gt;
  
  
  Versioning Adds Friction
&lt;/h3&gt;

&lt;p&gt;Recording packet versions, source revisions, and freshness introduces process overhead. That overhead pays for itself mainly on changes where debugging and rollback are expensive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authorization Belongs to the Runtime
&lt;/h3&gt;

&lt;p&gt;A packet can say that an agent may edit a path, but the runtime must enforce it. Never use a prompt or JSON field as the only security boundary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture Ownership Remains Human
&lt;/h3&gt;

&lt;p&gt;Engineers still define the contract, decide which behavior is intentional, and accept the tradeoffs. The packet makes that work explicit and reusable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The value of a context packet lies in helping an agent distinguish governing rules from code that happens to be nearby.&lt;/p&gt;

&lt;p&gt;AI-assisted development becomes more reliable when context is designed and maintained as part of the engineering system.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>AI Is Changing What 'Correct Software' Means</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Sat, 22 Aug 2026 16:41:58 +0000</pubDate>
      <link>https://dev.to/majdizlitni/ai-is-changing-what-correct-software-means-14hf</link>
      <guid>https://dev.to/majdizlitni/ai-is-changing-what-correct-software-means-14hf</guid>
      <description>&lt;p&gt;Software engineers used to define a "Correct software" via a simple deterministic binary an &lt;em&gt;Expected Output&lt;/em&gt;.&lt;br&gt;
All Test are passed, but this is collapsing, a green CI pipeline no longer guarantees correct software, with AI-generated code that's look syntactically perfect and test-compliant yet they are semantically wrong in a ways that appears in productions.&lt;br&gt;
The bottleneck in software engineering is no longer writing code, it is verifying it execution intent&lt;/p&gt;


&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The Determinism Illusion&lt;/li&gt;
&lt;li&gt;Why Unit Tests Fail to Catch AI Era Bugs&lt;/li&gt;
&lt;li&gt;The Architecture Shift: From Test Suites to Verification Engines&lt;/li&gt;
&lt;li&gt;Practical Implementation Invariant Verification in Dot NET and Azure&lt;/li&gt;
&lt;li&gt;Tradeoffs and Structural Limitations&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  The Determinism Illusion
&lt;/h2&gt;

&lt;p&gt;Traditional software used to relies on deterministic assertions. We write code with known paths, control inputs, and verify exact results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CalculateDiscount_StandardUser_ReturnsTenPercent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DiscountCalculator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Standard&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orderTotal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&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;This works well because we write the logics and most bugs comes from missed edge cases or small mistakes.&lt;br&gt;
But with AI-generated codes, it follows a patterns based on trained context and user prompt. An agent will write code that pass 100% of our unit tests but silently violation non-functional, implicit system boundaries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It Adds hidden performance costs.&lt;/li&gt;
&lt;li&gt;It breaks state machine idempotency under concurrent execution.&lt;/li&gt;
&lt;li&gt;It bypasses domain entity validation rules by instantiating raw records directly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we got a syntactically valid and test passing code but &lt;strong&gt;architecturally incorrect.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Unit Tests Fail to Catch AI Era Bugs
&lt;/h2&gt;

&lt;p&gt;AI agents are exceptionally good at writing tests for the very code they just generated. If an agent writes a flawed implementation, it generates an equally flawed, matching assertion suite.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd025cmxzesjy0h5wsreh.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd025cmxzesjy0h5wsreh.png" alt="AI Generation Loop" width="711" height="950"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When tests mirror the assumptions of the generation engine, unit tests become a confirmation bias machine.&lt;/p&gt;

&lt;p&gt;To govern AI-generated code, we must shift our definition of correctness from &lt;strong&gt;Output Equality&lt;/strong&gt; (&lt;code&gt;Assert.Equal&lt;/code&gt;) to &lt;strong&gt;System Invariants&lt;/strong&gt; (&lt;code&gt;Constraint Validation at Execution Runtime&lt;/code&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture Shift: From Test Suites to Verification Engines
&lt;/h2&gt;

&lt;p&gt;In an AI-native engineering workflow, correctness is defined by &lt;strong&gt;bounded runtime guardrails&lt;/strong&gt; and &lt;strong&gt;architectural fitness functions&lt;/strong&gt;.&lt;br&gt;
Instead of testing whether a function returned &lt;code&gt;10&lt;/code&gt;, a verification engine continuously enforces structural constraints across the entire codebase execution model.&lt;br&gt;
Using this we are not just checking test results we are enforcing rules at runtime and checking that the system design stays valid.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Implementation Invariant Verification in Dot NET and Azure
&lt;/h2&gt;

&lt;p&gt;Let's build a practical implementation of an architectural verification pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Enforce System Invariants in the Architecture Pipeline
&lt;/h3&gt;

&lt;p&gt;Instead of trusting AI-generated tests we will enforce rules that our system must always follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Before merge (CI) → check code structure&lt;/li&gt;
&lt;li&gt;At runtime → check what the AI is trying to do
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;NetArchTest.Rules&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Xunit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ArchitectureVerificationTests&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DomainEntities_MustBeImmutable_AndNeverBypassedByAgents&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Enforce that AI-generated code cannot introduce mutable state into the Core Domain&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InCurrentDomain&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;That&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ResideInNamespace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"OrderSystem.Domain"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;BeImmutable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetResult&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;True&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSuccessful&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"AI generated mutable entities in the domain layer!"&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="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Handlers_MustEnforceIdempotencyDecorator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Ensure every generated Command Handler implements IIdempotentCommand&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InCurrentDomain&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;That&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;HaveNameEndingWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CommandHandler"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ImplementInterface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IIdempotentCommand&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetResult&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;True&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSuccessful&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"AI generated a command handler lacking explicit idempotency execution!"&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 2: Runtime Semantic Guardrail Verification Engine
&lt;/h3&gt;

&lt;p&gt;For AI agent workflows running in production or ambient background tasks when it tries to change code or data, we validate its intent before allowing it so we ensure: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No direct DB access outside repositories&lt;/li&gt;
&lt;li&gt;No performance-heavy allocations&lt;/li&gt;
&lt;li&gt;Every external change must trigger an event
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.SemanticKernel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Extensions.Logging&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;ExecutionIntent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;TaskDescription&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;TargetNamespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;ProposedDiff&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;VerificationResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;StructuralDivergenceReason&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentVerificationEngine&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;readonly&lt;/span&gt; &lt;span class="n"&gt;Kernel&lt;/span&gt; &lt;span class="n"&gt;_kernel&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;readonly&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AgentVerificationEngine&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AgentVerificationEngine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Kernel&lt;/span&gt; &lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AgentVerificationEngine&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_kernel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;_logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;VerificationResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;VerifyAgentActionAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ExecutionIntent&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Define hard system invariants that the LLM engine cannot negotiate&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;verificationPrompt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"""
&lt;/span&gt;            &lt;span class="n"&gt;You&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;Architectural&lt;/span&gt; &lt;span class="n"&gt;Verification&lt;/span&gt; &lt;span class="n"&gt;Engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Evaluate&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;proposed&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="n"&gt;against&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;system&lt;/span&gt; &lt;span class="n"&gt;invariants&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

            &lt;span class="n"&gt;SYSTEM&lt;/span&gt; &lt;span class="n"&gt;INVARIANTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;direct&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="n"&gt;access&lt;/span&gt; &lt;span class="n"&gt;outside&lt;/span&gt; &lt;span class="n"&gt;Infrastructure&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Repositories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
            &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;Memory&lt;/span&gt; &lt;span class="n"&gt;allocations&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;critical&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt; &lt;span class="n"&gt;must&lt;/span&gt; &lt;span class="n"&gt;avoid&lt;/span&gt; &lt;span class="n"&gt;heap&lt;/span&gt; &lt;span class="nf"&gt;overhead&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;boxing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="n"&gt;ReadOnlySpan&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;applicable&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
            &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;All&lt;/span&gt; &lt;span class="n"&gt;external&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;modifications&lt;/span&gt; &lt;span class="n"&gt;MUST&lt;/span&gt; &lt;span class="n"&gt;emit&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;IntegrationEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

            &lt;span class="n"&gt;PROPOSED&lt;/span&gt; &lt;span class="n"&gt;CHANGE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
            &lt;span class="n"&gt;Diff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;

            &lt;span class="n"&gt;Respond&lt;/span&gt; &lt;span class="n"&gt;ONLY&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"is_valid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Detailed failure justification"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="s"&gt;""";
&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;KernelArguments&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TargetNamespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"diff"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProposedDiff&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_kernel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InvokePromptAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;verificationPrompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;responseJson&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// System parses verification evaluation deterministically&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;VerificationResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;responseJson&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;
  
  
  Azure Deployment Architecture
&lt;/h3&gt;

&lt;p&gt;Deploy this verification process directly inside your &lt;strong&gt;Azure DevOps Pipeline&lt;/strong&gt; or &lt;strong&gt;GitHub Actions Engine&lt;/strong&gt; alongside Azure Container Apps for isolation:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fssj3plhmxlmflsr8n8jt.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fssj3plhmxlmflsr8n8jt.png" alt="Azure DevOps Pipeline" width="576" height="1208"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Tradeoffs and Structural Limitations
&lt;/h2&gt;

&lt;p&gt;Moving to an invariant-driven verification architecture introduces real engineering trade-offs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Increased CI Execution Latency&lt;/strong&gt;: Evaluating structural ASTs and executing dynamic LLM-driven verification gates adds 30–90 seconds per pull request compared to simple syntax compilation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High Upfront Modeling Cost&lt;/strong&gt;: Defining system invariants requires deep domain expertise. You cannot ask an AI to write your system invariants — doing so reintroduces the confirmation bias loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Over-Constrained Evolution&lt;/strong&gt;: Overly strict architectural fitness functions can cause false positives, blocking valid edge-case refactoring tasks generated by agents or human engineers.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;AI is not removing the need for software engineering — &lt;strong&gt;it is raising the level of abstraction.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When writing code becomes frictionless, the primary value of a senior engineer shifts from &lt;em&gt;syntax authoring&lt;/em&gt; to &lt;em&gt;system boundary definition&lt;/em&gt;. Stop relying solely on traditional unit tests to validate AI-generated code. Build verification engines that enforce immutable architecture invariants, audit non-deterministic outputs, and protect runtime stability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Software correctness is no longer about passing unit tests. It is about proving your system cannot violate its core invariants.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;How are you adapting your CI/CD pipelines to handle AI-generated code? Are you relying on static unit testing, or building verification boundaries? Drop your thoughts in the comments below!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>softwareengineering</category>
      <category>testing</category>
    </item>
    <item>
      <title>Vibium Under the Hood</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Sat, 25 Jul 2026 20:02:58 +0000</pubDate>
      <link>https://dev.to/majdizlitni/vibium-under-the-hood-4k5i</link>
      <guid>https://dev.to/majdizlitni/vibium-under-the-hood-4k5i</guid>
      <description>&lt;p&gt;My &lt;a href="https://dev.to/majdizlitni/vibium-a-cli-browser-automation-tool-3dl9"&gt;previous blog&lt;/a&gt; in my automation series was a first step on how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Vibium&lt;/li&gt;
&lt;li&gt;Record a login scenario&lt;/li&gt;
&lt;li&gt;Visualize recorded test&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refreshing, &lt;a href="https://github.com/VibiumDev/vibium" rel="noopener noreferrer"&gt;Vibium is an open source&lt;/a&gt; automation tool, written in Go with JS/TS, Python, and Java client libraries.&lt;/p&gt;

&lt;p&gt;In this blog post, we will go through:&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Protocol Bet: Why WebDriver BiDi&lt;/li&gt;
&lt;li&gt;System Architecture&lt;/li&gt;
&lt;li&gt;Daemon Mode&lt;/li&gt;
&lt;li&gt;Using Vibium MCP and SKILLs&lt;/li&gt;
&lt;li&gt;Reliability vs Speed with AI Agents&lt;/li&gt;
&lt;li&gt;Closing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Protocol Bet: Why WebDriver BiDi
&lt;/h2&gt;

&lt;p&gt;Vibium's design isn't a CLI choice, it's the protocol used underneath.&lt;/p&gt;

&lt;p&gt;Browser automation has gone through three protocol generations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebDriver (2004–present)&lt;/strong&gt;: Selenium’s foundation. Uses HTTP + JSON with a request/response model that controls browsers in a one-way manner: the browser only responds when asked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chrome DevTools Protocol (2017–present)&lt;/strong&gt;: CDP swapped HTTP for WebSockets, and that unlocked bidirectional communication: the browser sends and receives events in real time like logs, network activity, and DOM changes. Puppeteer and Playwright are both built on CDP, but it is Chrome-internal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebDriver BiDi (2021–present)&lt;/strong&gt;: The W3C's answer to "what if we kept CDP's bidirectional WebSocket model but made it an actual cross-vendor standard?".&lt;/p&gt;

&lt;p&gt;And that's the main reason I think Vibium is built directly on WebDriver BiDi.&lt;/p&gt;

&lt;p&gt;Below is the diagram presenting these interactions:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgrlvfccx1uv5sq7e8xph.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgrlvfccx1uv5sq7e8xph.png" alt="Diagram instructions" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here our browser can push events, like messages, and when a page throws an error, &lt;strong&gt;WebDriver BiDi can receive them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Browser support is still maturing with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chrome/Chromium supports BiDi via ChromeDriver&lt;/li&gt;
&lt;li&gt;Firefox has native support&lt;/li&gt;
&lt;li&gt;Edge inherits Chromium's support&lt;/li&gt;
&lt;li&gt;Safari's support is in development&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tooling ecosystem is converging on this protocol, not just Vibium.&lt;/p&gt;

&lt;h2&gt;
  
  
  System Architecture
&lt;/h2&gt;

&lt;p&gt;Vibium ships as a single compiled binary. This indicates that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can invoke it directly from the CLI.&lt;/li&gt;
&lt;li&gt;You can use the MCP server and register it with an agent host.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both surfaces funnel into the same internal command engine, which talks to Chrome over a BiDi WebSocket connection it manages internally.&lt;/p&gt;

&lt;p&gt;Both methods target the Vibium binary, which interacts with Chrome using WebDriver BiDi over WebSocket.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9r5tzsr4urs10vezvmjp.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9r5tzsr4urs10vezvmjp.png" alt="integrations" width="800" height="792"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two details worth calling out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Vibium uses the same core engine for CLI commands, MCP tools, and language clients. Client libraries connect to the binary through WebSocket instead of rebuilding browser automation logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vibium can be installed as an agent skill via&lt;br&gt;
&lt;code&gt;npx skills add https://github.com/VibiumDev/vibium --skill vibe-check&lt;/code&gt;&lt;br&gt;
allowing AI coding agents to discover and use it through a &lt;code&gt;SKILL.md&lt;/code&gt; definition and automatically resolve the required binary.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Daemon Mode
&lt;/h2&gt;

&lt;p&gt;Daemon mode improves performance. Instead of starting a new browser for every command, it keeps a background browser alive and reuses it across all commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vibium go https://example.com
vibium map
vibium click @e1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the browser starts once, keeping agent workflows faster. The daemon can also be manually controlled with &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;status&lt;/code&gt;, and &lt;code&gt;stop&lt;/code&gt; commands, which is useful for CI environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Vibium MCP and SKILLs
&lt;/h2&gt;

&lt;p&gt;Before moving on to the AI integration with Vibium I wanted to clarify the difference between MCP and Skills because there is slight confusion&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;MCP (Model Context Protocol)&lt;/strong&gt; is the runtime used by agents  to execute tools. It controls the communication between agents and binaries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SKILL.md&lt;/strong&gt; is definition on how to do things it is a file that describes a tool used by MCP
so MCP reads SKILL.md to know how to expose and invoke the skill.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short: MCP execute using skills, and a skill tells MCP how execute.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To use a skill defined via &lt;code&gt;SKILL.md&lt;/code&gt;, you first need to register it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add https://github.com/VibiumDev/vibium &lt;span class="nt"&gt;--skill&lt;/span&gt; vibe-check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc3fu9ezyrvj47mjzq3wb.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc3fu9ezyrvj47mjzq3wb.png" alt="using skills" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once added, I used the vibe-check skill to automate a simple scenario.&lt;br&gt;
I use this prompt within GitHub Copilot in agent mode&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use the vibe-Check skill to open https://opensource-demo.orangehrmlive.com/web/index.php/auth/login
and login using:
Username: Admin
Password: admin123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/22GHvcus2Ls"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Reliability vs Speed with AI Agents
&lt;/h2&gt;

&lt;p&gt;Using Vibium with AI is very interesting but this comes with a balance between &lt;strong&gt;speed&lt;/strong&gt; and &lt;strong&gt;reliability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;At first glance it seems very fast and smart, it understands what the user wants using simple words and execute actions based on that.&lt;br&gt;
But in practical things can get messy &lt;/p&gt;

&lt;p&gt;It true that AI can know the UI elements with a faster setup but as you can seen a simple login flow still struggles, the agent got stuck and couldn't identify the element from the first attempts.&lt;br&gt;
The interesting part is how it behaves using a quickly recover, &lt;br&gt;
it true that it gives more adaptability but also a less deterministic behavior.&lt;/p&gt;

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

&lt;p&gt;Betting on WebDriver BiDi aligns with a cross-vendor standard for browser automation. Vibium is moving toward a full AI-driven system built on three layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sense (Retina):&lt;/strong&gt; Browser-level observation via a Chrome extension
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Think (Cortex):&lt;/strong&gt; Memory, reasoning, and navigation planning
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Act (Vibium):&lt;/strong&gt; Execution using BiDi
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vibium is early, maturing these layers could move browser automation from "sometimes works" to production-ready.&lt;/p&gt;

&lt;p&gt;Explore the &lt;a href="https://github.com/VibiumDev/vibium/blob/main/skills/vibe-check/SKILL.md" rel="noopener noreferrer"&gt;CLI reference&lt;/a&gt;, &lt;a href="https://github.com/VibiumDev/vibium/blob/main/docs/explanation/webdriver-bidi.md" rel="noopener noreferrer"&gt;BiDi explainer&lt;/a&gt;, and &lt;a href="https://github.com/VibiumDev/vibium/blob/main/ROADMAP.md" rel="noopener noreferrer"&gt;roadmap&lt;/a&gt; in the repo to dig deeper.&lt;/p&gt;




&lt;p&gt;What’s your biggest bottleneck with browser automation today? Drop your thoughts or check out the repo to start experimenting!&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>opensource</category>
      <category>browserautomation</category>
      <category>ai</category>
    </item>
    <item>
      <title>Vibium: A CLI Browser Automation Tool</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Fri, 24 Jul 2026 07:00:00 +0000</pubDate>
      <link>https://dev.to/majdizlitni/vibium-a-cli-browser-automation-tool-3dl9</link>
      <guid>https://dev.to/majdizlitni/vibium-a-cli-browser-automation-tool-3dl9</guid>
      <description>&lt;p&gt;Browser automation has been dominated by tools like &lt;a href="https://www.selenium.dev" rel="noopener noreferrer"&gt;Selenium&lt;/a&gt; and &lt;a href="https://playwright.dev" rel="noopener noreferrer"&gt;Playwright&lt;/a&gt;. They're very powerful, but you need to understand the DOM, manage selectors, and set up a testing stack before doing anything meaningful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vibium&lt;/strong&gt; takes a different approach, by using a step-based commands.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open a website&lt;/li&gt;
&lt;li&gt;Find an element&lt;/li&gt;
&lt;li&gt;Fill a field&lt;/li&gt;
&lt;li&gt;Click a button&lt;/li&gt;
&lt;li&gt;Validate the result&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vibium supports two ways for agentic usage:&lt;br&gt;
A command-style skill used for browser automation, and an MCP server for structured workflows. For element discovery, vibium find uses semantic signals like text, labels, placeholders, test IDs, CSS, XPath, and the accessibility tree, then returns stable references that can be reused until the page changes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why Vibium?&lt;/li&gt;
&lt;li&gt;Installing Vibium&lt;/li&gt;
&lt;li&gt;Your First Vibium Automation&lt;/li&gt;
&lt;li&gt;Understanding the Core Commands&lt;/li&gt;
&lt;li&gt;Recording&lt;/li&gt;
&lt;li&gt;Viewing the Trace&lt;/li&gt;
&lt;li&gt;Where Vibium Fits&lt;/li&gt;
&lt;li&gt;Vibium vs. Selenium vs. Playwright&lt;/li&gt;
&lt;li&gt;Final Thoughts&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Why Vibium?
&lt;/h2&gt;

&lt;p&gt;Traditional automation usually follows a familiar path:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the CSS selector&lt;/li&gt;
&lt;li&gt;Inspect the DOM&lt;/li&gt;
&lt;li&gt;Set up a framework&lt;/li&gt;
&lt;li&gt;Write the code&lt;/li&gt;
&lt;li&gt;Maintain the selectors as the app changes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In Playwright, that ends up looking like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Locator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"#username"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;FillAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Admin"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing wrong with that it works, and it's the standard for a reason. But it requires you to already know the DOM structure before you write a single line.&lt;/p&gt;

&lt;p&gt;Vibium flips the workflow around. Instead of hunting for selectors first, you &lt;em&gt;discover&lt;/em&gt; elements interactively and reference them as you go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@e1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Admin"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vibium finds the element for you and hands back a temporary reference (&lt;code&gt;@e1&lt;/code&gt;) that you can immediately act on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Vibium
&lt;/h2&gt;

&lt;p&gt;Install the CLI globally with npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;npm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first browser-based command you run will automatically download a managed &lt;strong&gt;Chrome for Testing&lt;/strong&gt; build, so there's no separate browser setup step.&lt;/p&gt;

&lt;p&gt;Verify everything works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://example.com&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;A browser will open with the given URL &lt;/p&gt;

&lt;h2&gt;
  
  
  Your First Vibium Automation
&lt;/h2&gt;

&lt;p&gt;Let's automate a simple login flow against the &lt;a href="https://opensource-demo.orangehrmlive.com" rel="noopener noreferrer"&gt;OrangeHRM demo site&lt;/a&gt;.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Start recording&lt;/li&gt;
&lt;li&gt;Open OrangeHRM&lt;/li&gt;
&lt;li&gt;Find the username field and enter a value&lt;/li&gt;
&lt;li&gt;Find the password field and enter a value&lt;/li&gt;
&lt;li&gt;Click the login button&lt;/li&gt;
&lt;li&gt;Stop recording and save the trace&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Using &lt;code&gt;Vibium map&lt;/code&gt; to scans the current page for interactive elements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here a line by line PowerShell script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://opensource-demo.orangehrmlive.com"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@e1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Admin"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@e2"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin123"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@e3"&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;stop&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1t45beenhw21rlgu12se.gif" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1t45beenhw21rlgu12se.gif" alt="Vibium tutorial" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's a full, working login automation in about ten lines no selector hunting, no test framework scaffolding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Core Commands
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Start recording&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Open URL&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;go&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Find element&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Username"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fill input&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@e1"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Admin"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Find and click button&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;vibium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@e3"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Recording
&lt;/h2&gt;

&lt;p&gt;This is the one distinction worth internalizing before you build anything real with Vibium.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recording mode&lt;/strong&gt; is great for exploring a workflow, and sketching out an automation quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing the Trace
&lt;/h2&gt;

&lt;p&gt;After you stop recording:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vibium record stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vibium writes out a &lt;code&gt;record.zip&lt;/code&gt; trace file. Open it with the Playwright Trace Viewer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; playwright
playwright show-trace record.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there you can step through screenshots, actions, timing, failures, and browser state for the whole session handy for debugging a flaky step after the fact.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhmx939jbecw4tf5k9vbb.gif" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhmx939jbecw4tf5k9vbb.gif" alt="playwright record" width="760" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Vibium Fits
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AI agents.&lt;/strong&gt; Vibium's command surface maps naturally onto the kind of steps an LLM already reasons in "open the site, find the login field, enter credentials, click submit, verify the result" which makes it noticeably easier for an agent to generate a working automation than raw locator-based code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test automation.&lt;/strong&gt; Regression suites, smoke tests, end-to-end tests, and user-journey validation (login → create user → update profile → logout, for example) all map cleanly onto Vibium's step-based style.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Internal automation.&lt;/strong&gt; Repetitive browser work data entry, admin dashboards, report pulling, back-office workflows is often not worth building a full test framework for. Vibium's low ceremony makes it a reasonable fit for these one-off or lightly-maintained scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vibium vs. Selenium vs. Playwright
&lt;/h2&gt;

&lt;p&gt;Selenium and Playwright still win on ecosystem maturity, plugin support, and battle-tested reliability at scale. Vibium's edge is in how quickly you can go from "I want to automate this" to a working script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Vibium lowers the barrier to entry for browser automation, especially for AI-driven workflows. But it does so by shifting responsibility from the developer to the tool.&lt;/p&gt;

&lt;p&gt;If you're a developer, a QA engineer, or you're building AI agents that need to act on the web, &lt;a href="https://vibium.com" rel="noopener noreferrer"&gt;Vibium&lt;/a&gt; is worth a look.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>testing</category>
      <category>automation</category>
    </item>
    <item>
      <title>What Actually Enforces Code Standards in the AI Era</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Sat, 18 Jul 2026 15:21:09 +0000</pubDate>
      <link>https://dev.to/majdizlitni/what-actually-enforces-code-standards-in-the-ai-era-17kf</link>
      <guid>https://dev.to/majdizlitni/what-actually-enforces-code-standards-in-the-ai-era-17kf</guid>
      <description>&lt;p&gt;If your team has ever spent 20 minutes on a pull request arguing about brace placement instead of the actual bug, welcome to the club.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;StyleCop&lt;/strong&gt; was the tool to keep C# codebases from turning into everyone's personal-style soup. It did its job. But it's also old, slow, and wasn't built for a world where half your codebase might be vibe coded.&lt;/p&gt;

&lt;p&gt;The good news: .NET now ships with everything you need to enforce style natively, faster, and without an extra NuGet package. This post walks through &lt;em&gt;why&lt;/em&gt; the old approach creaks under modern workloads, and gives you a copy-pasteable migration plan to fix it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Real Cost of Style Debates&lt;/li&gt;
&lt;li&gt;Quick Refresher: What Is StyleCop?&lt;/li&gt;
&lt;li&gt;Do We Even Need Linters Now That AI Writes Code?&lt;/li&gt;
&lt;li&gt;The Problem With StyleCop: It's Slow&lt;/li&gt;
&lt;li&gt;The Modern Toolbox&lt;/li&gt;
&lt;li&gt;The 3 Layer Guardrail Strategy&lt;/li&gt;
&lt;li&gt;Step by Step Migration Guide&lt;/li&gt;
&lt;li&gt;Before and After Seeing It In Action&lt;/li&gt;
&lt;li&gt;Key Takeaways&lt;/li&gt;
&lt;li&gt;Wrapping Up&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Real Cost of Style Debates
&lt;/h2&gt;

&lt;p&gt;Nobody has ever gotten a promotion for winning a tabs-vs-spaces argument. Yet these debates eat real time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PR bikeshedding&lt;/strong&gt;,reviewers nitpick spacing instead of catching actual logic bugs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Noisy git diffs&lt;/strong&gt;,one developer's auto-formatter touches 300 lines to fix a 3-line bug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cognitive overhead&lt;/strong&gt;,jumping between services that each "feel" different slows everyone down.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A linter's whole job is to make these arguments boring and automatic, so humans can focus on things that actually matter,like whether the code &lt;em&gt;works&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Refresher: What Is StyleCop?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;StyleCop&lt;/strong&gt; (and its Roslyn-based version, &lt;code&gt;StyleCop.Analyzers&lt;/code&gt;) is a static analysis tool that checks the &lt;em&gt;visual grammar&lt;/em&gt; of your C# code,not bugs, not security holes, just style:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are public members documented?&lt;/li&gt;
&lt;li&gt;Are namespaces organized consistently?&lt;/li&gt;
&lt;li&gt;Do braces follow the "approved" pattern?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not checking if your code is &lt;em&gt;correct&lt;/em&gt;. It's checking if your code &lt;em&gt;looks&lt;/em&gt; correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do We Even Need Linters Now That AI Writes Code?
&lt;/h2&gt;

&lt;p&gt;Short answer: &lt;strong&gt;yes, more than ever.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI coding assistants (Copilot, Cursor, and friends) are great at logic, but they have zero awareness of your team's conventions. They're trained on millions of repos with wildly different styles, so pasted-in AI code tends to bring some chaos with it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Paradigm mixing&lt;/strong&gt;,old-school patterns sitting right next to brand-new C# syntax in the same file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Random formatting&lt;/strong&gt;,inconsistent spacing and bracing, because the model has no idea what &lt;em&gt;your&lt;/em&gt; team prefers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comment bloat&lt;/strong&gt;,giant XML doc comments explaining that &lt;code&gt;GetName()&lt;/code&gt; "gets the name."&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip:&lt;/strong&gt; Think of AI-generated code like a very talented intern who's never seen your style guide. Brilliant ideas, questionable formatting. It needs a quick pass before it joins the team.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Problem With StyleCop: It's Slow
&lt;/h2&gt;

&lt;p&gt;Here's the part that actually hurts: &lt;code&gt;StyleCop.Analyzers&lt;/code&gt; walks the compiler's entire Abstract Syntax Tree (AST) &lt;em&gt;every time you build locally&lt;/em&gt;. On a large, modern codebase, that adds real, measurable time to every single compile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Code → Hit Build → Roslyn AST + Heavy StyleCop Analysis → Slow Build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it gets worse: hundreds of style rules are configured as &lt;strong&gt;Warnings&lt;/strong&gt;, so your build output turns into a wall of noise. Real errors get buried underneath "add a blank line here" messages. That's not code quality,that's warning fatigue.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Modern Toolbox
&lt;/h2&gt;

&lt;p&gt;Microsoft baked style enforcement directly into the .NET SDK, so you don't need a heavyweight third-party package anymore. Here are your main options:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Native &lt;code&gt;.editorconfig&lt;/code&gt; (the real successor to StyleCop)&lt;/strong&gt;&lt;br&gt;
Define your rules in a plain text file. The .NET SDK reads it instantly and surfaces issues as built-in compiler diagnostics. No extra packages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. CSharpier&lt;/strong&gt;&lt;br&gt;
An opinionated formatter, like Prettier for C#. It skips debates entirely,one deterministic output, no configuration arguments. Runs outside the compiler, so it doesn't touch build performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. SonarQube / SonarCloud&lt;/strong&gt;&lt;br&gt;
For the &lt;em&gt;deep&lt;/em&gt; stuff,security holes, memory leaks, async anti-patterns,push that to a cloud-based SAST engine instead of your local build. Keep local checks fast and lightweight; let the cloud do the heavy lifting asynchronously.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Good for&lt;/th&gt;
&lt;th&gt;Runs where&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;.editorconfig&lt;/code&gt; + SDK analyzers&lt;/td&gt;
&lt;td&gt;Style, naming, layout&lt;/td&gt;
&lt;td&gt;Local build (fast)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSharpier&lt;/td&gt;
&lt;td&gt;Deterministic formatting&lt;/td&gt;
&lt;td&gt;Out-of-process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SonarQube/Cloud&lt;/td&gt;
&lt;td&gt;Security &amp;amp; deep quality checks&lt;/td&gt;
&lt;td&gt;CI / cloud (async)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  The 3 Layer Guardrail Strategy
&lt;/h2&gt;

&lt;p&gt;The trick to using AI tools without letting them wreck your codebase is a simple pipeline: &lt;strong&gt;Seed → Ground → Enforce.&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;1. SEED                 2. GROUND              3. ENFORCE
AI Instruction File  →  IDE Format on Save  →  CI Gate
(AGENTS.md)             (.editorconfig)        (dotnet format)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Seed&lt;/strong&gt;: Tell the AI your conventions upfront, before it generates a single line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ground&lt;/strong&gt;: Let your IDE auto-fix formatting the moment code is pasted or saved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce&lt;/strong&gt;: Fail the build in CI if anything slipped through ungrounded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Three checkpoints. Nothing style-broken survives all three.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step by Step Migration Guide
&lt;/h2&gt;

&lt;p&gt;Here's the hands-on plan to move off StyleCop and onto native tooling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Set Project-Wide Standards
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;Directory.Build.props&lt;/code&gt; file at the root of your repo (next to your &lt;code&gt;.sln&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Project&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Turn on the SDK's built-in Roslyn analyzers --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;EnableNETAnalyzers&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/EnableNETAnalyzers&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;AnalysisLevel&amp;gt;&lt;/span&gt;latest&lt;span class="nt"&gt;&amp;lt;/AnalysisLevel&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;AnalysisMode&amp;gt;&lt;/span&gt;Recommended&lt;span class="nt"&gt;&amp;lt;/AnalysisMode&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Make the build actually respect .editorconfig --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;EnforceCodeStyleInBuild&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/EnforceCodeStyleInBuild&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This applies the same rules across every project in the solution, no more "well, &lt;em&gt;my&lt;/em&gt; microservice does it differently."&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Generate Your &lt;code&gt;.editorconfig&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet new editorconfig
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then customize it. Here's a solid starting template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;root&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="nn"&gt;[*.cs]&lt;/span&gt;
&lt;span class="c"&gt;# Indentation &amp;amp; layout
&lt;/span&gt;&lt;span class="py"&gt;indent_style&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;space&lt;/span&gt;
&lt;span class="py"&gt;indent_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;4&lt;/span&gt;
&lt;span class="py"&gt;end_of_line&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;lf&lt;/span&gt;
&lt;span class="py"&gt;insert_final_newline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="c"&gt;# Modern C# preferences
&lt;/span&gt;&lt;span class="py"&gt;csharp_style_file_scoped_namespaces&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true:error&lt;/span&gt;

&lt;span class="c"&gt;# Explicit rule mappings (these replace old StyleCop rules)
&lt;/span&gt;&lt;span class="py"&gt;dotnet_diagnostic.IDE0005.severity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;warning   # remove unused usings&lt;/span&gt;
&lt;span class="py"&gt;dotnet_diagnostic.IDE0040.severity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;warning   # require explicit access modifiers&lt;/span&gt;
&lt;span class="py"&gt;dotnet_diagnostic.IDE0055.severity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;warning   # flag whitespace/brace issues&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Give Your AI Tools the Memo
&lt;/h3&gt;

&lt;p&gt;Drop a &lt;code&gt;AGENTS.md&lt;/code&gt; file in your repo root so AI assistants know the rules &lt;em&gt;before&lt;/em&gt; they start typing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# C# Code Generation Rules&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; All generated code must follow the root &lt;span class="sb"&gt;`.editorconfig`&lt;/span&gt;.
&lt;span class="p"&gt;-&lt;/span&gt; Use file-scoped namespaces only.
&lt;span class="p"&gt;-&lt;/span&gt; Keep classes tightly encapsulated; prefer primary constructors.
&lt;span class="p"&gt;-&lt;/span&gt; Skip self-explanatory XML doc comments on basic properties.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the "Seed" layer from earlier; cheap insurance against a lot of cleanup later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Automate Formatting Locally
&lt;/h3&gt;

&lt;p&gt;In your IDE (Visual Studio, VS Code, Rider,doesn't matter which), turn on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Format on Save&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Format on Paste&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what actually "grounds" AI-pasted code into your team's style, automatically, with zero manual effort.&lt;/p&gt;

&lt;p&gt;Need to clean up an entire existing codebase in one go?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Add a CI Gate
&lt;/h3&gt;

&lt;p&gt;Add this to your pipeline (GitHub Actions, Azure DevOps, whatever you use) &lt;em&gt;before&lt;/em&gt; the build step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&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;Verify Code Style &amp;amp; Layout Compliance&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;dotnet format --verify-no-changes --verbosity normal&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;Execute Production Build&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;dotnet build --configuration Release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If anyone bypasses their IDE formatting (we all know someone), the pipeline catches it before it merges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before and After Seeing It In Action
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;: technically compiles, but it's a mess:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// InconsistentOrderProcessingService.cs&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;MyApp.Core&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;MyApp.Services&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;orderService&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;readonly&lt;/span&gt; &lt;span class="n"&gt;IRepository&lt;/span&gt; &lt;span class="n"&gt;_repo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;orderService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IRepository&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;_repo&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;

      &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_repo&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="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;==&lt;/span&gt;&lt;span class="k"&gt;null&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="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Order context is missing."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Business execution path...&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;p&gt;&lt;strong&gt;After&lt;/strong&gt;,run &lt;code&gt;dotnet format&lt;/code&gt;, and this is what comes out the other side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// OrderProcessingService.cs&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;MyApp.Core&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;MyApp.Services&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderProcessingService&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;readonly&lt;/span&gt; &lt;span class="n"&gt;IRepository&lt;/span&gt; &lt;span class="n"&gt;_repository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;OrderProcessingService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_repository&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;repository&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="nf"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ProcessOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_repository&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="n"&gt;orderId&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="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&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="nf"&gt;InvalidOperationException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Order with ID &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; was not found."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Business execution path...&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;Same logic. Zero manual cleanup. Nobody had to open a PR comment thread about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;StyleCop is slow&lt;/strong&gt; because it walks the full AST on every local build; that adds up fast on large codebases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-generated code needs grounding&lt;/strong&gt;, not banning. Seed it with conventions, then auto-format on save.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.editorconfig&lt;/code&gt; + SDK analyzers&lt;/strong&gt; replace most of what StyleCop did, natively, and faster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI should verify, not fix.&lt;/strong&gt; Use &lt;code&gt;dotnet format --verify-no-changes&lt;/code&gt; as a gate, not a cleanup crew.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Split concerns&lt;/strong&gt;: style stays local and fast; deep security/quality checks (SonarQube) move to CI/cloud.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ready to use template
&lt;/h2&gt;

&lt;p&gt;Reading about code standards is easy. Applying them consistently across a team is the hard part.&lt;/p&gt;

&lt;p&gt;To make this process easier, I created a ready-to-use .NET code governance template that packages the approach described in this article&lt;br&gt;
👉 &lt;strong&gt;&lt;a href="https://github.com/Majdi-Zlitni/DotStyle" rel="noopener noreferrer"&gt;DotStyle .NET Code Governance Template&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Moving off StyleCop isn't about lowering your standards, it's about enforcing them somewhere that doesn't slow you down. Seed your AI tools with clear rules, let your IDE ground the output automatically, and use CI as the final backstop. Fast local builds, clean diffs, and PR reviews that actually talk about the code instead of the commas.&lt;/p&gt;

&lt;p&gt;Give it a try on one repo this week, use a proper &lt;code&gt;.editorconfig&lt;/code&gt;, wire up &lt;code&gt;dotnet format&lt;/code&gt; in CI, and see how much quieter your next pull request review is.&lt;/p&gt;

&lt;p&gt;Have a different setup that works for your team? something else entirely? Drop it in the comments 👇&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Bypassing the Parser: Connecting Azure AI Foundry to VS Code Copilot via BYOK</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Wed, 17 Jun 2026 09:51:35 +0000</pubDate>
      <link>https://dev.to/majdizlitni/bypassing-the-parser-connecting-azure-ai-foundry-to-vs-code-copilot-via-byok-35d</link>
      <guid>https://dev.to/majdizlitni/bypassing-the-parser-connecting-azure-ai-foundry-to-vs-code-copilot-via-byok-35d</guid>
      <description>&lt;p&gt;The &lt;strong&gt;vibe coding&lt;/strong&gt; era just took a massive hit. &lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbi5fzdce38gf5j9b1b9.gif" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbi5fzdce38gf5j9b1b9.gif" alt="frightening" width="399" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As of &lt;strong&gt;June 1, 2026&lt;/strong&gt;, GitHub completely dismantled its old request-based model for Copilot and transitioned to a strict Usage-Based Billing Model powered by &lt;a href="https://docs.github.com/en/copilot/concepts/billing/usage-based-billing-for-individuals" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub AI Credits&lt;/strong&gt;&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;For developers riding on the &lt;a href="https://docs.github.com/en/copilot/how-tos/copilot-on-github/set-up-copilot/enable-copilot/set-up-for-students" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Copilot Student plan&lt;/strong&gt;&lt;/a&gt;, the reality is harsh: while basic inline code completions remain unlimited, Copilot Chat and agentic features are now heavily restricted. To make matters worse, top-tier reasoning models have been completely stripped from the Student tier self-selection menu to keep the free tier sustainable.&lt;/p&gt;

&lt;p&gt;But if you are a student with an &lt;a href="https://azure.microsoft.com/en-us/free/students" rel="noopener noreferrer"&gt;&lt;strong&gt;Azure for Students subscription&lt;/strong&gt;&lt;/a&gt;, you hold a massive golden ticket in your hands: &lt;strong&gt;Free Azure cloud credits&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykirqicdl6xklhfmjcef.gif" 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%2Fykirqicdl6xklhfmjcef.gif" alt="Money moeny" width="437" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By using the &lt;strong&gt;Bring Your Own Key (BYOK)&lt;/strong&gt; feature inside VS Code, you can deploy cutting-edge coding models on your own Azure instance and route them straight into your IDE, falling into three distinct tiers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloud-Hosted Enterprise Models (Azure AI Foundry &amp;amp; OpenAI)&lt;/li&gt;
&lt;li&gt;External Third-Party API Gateways (DeepSeek, OpenRouter &amp;amp; Anthropic)&lt;/li&gt;
&lt;li&gt;Fully Offline Local Models (Ollama, vLLM &amp;amp; Foundry Local)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While BYOK supports everything from local Ollama instances to third-party gateways, this guide will focus specifically on Azure subscription credits using Azure AI Foundry.&lt;/p&gt;

&lt;p&gt;Here is how to trick the system, bypass the budget limits, and build your own autonomous development environment.&lt;/p&gt;
&lt;h2&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%2Fww72z5wq55j5ccxyglfx.gif" alt="haking" width="480" height="270"&gt;
&lt;/h2&gt;
&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prerequisites: Snagging Your Azure Student Subscription&lt;/li&gt;
&lt;li&gt;
vs code Configuration Blueprint

&lt;ul&gt;
&lt;li&gt;Step 1: Open the Custom Models Panel&lt;/li&gt;
&lt;li&gt;Step 2: Input Your Azure Endpoint Details&lt;/li&gt;
&lt;li&gt;Step 3: Clear the IDE Cache Layers&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The Result: Infinite Coding Freedom&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Prerequisites: Snagging Your Azure Student Subscription
&lt;/h2&gt;

&lt;p&gt;First you need a valid &lt;strong&gt;Azure subscription&lt;/strong&gt; with active credits to host your models. If you don't have one yet, Microsoft offers a dedicated &lt;strong&gt;Azure for Students&lt;/strong&gt; tier that gives you free cloud credits annually with no credit card required.&lt;/p&gt;
&lt;h3&gt;
  
  
  Scenario A: You Already Have an Active Azure subscription
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Log into &lt;a href="https://ai.azure.com/home" rel="noopener noreferrer"&gt;Azure AI Foundry&lt;/a&gt; and create a new Azure Foundry resource.&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8169gnnusme2iikj5seq.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8169gnnusme2iikj5seq.png" alt="Microsoft Foundry resource" width="630" height="490"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new project under your subscription(student subscription if you have one). Select an optimal region for model availability (for my case I selected &lt;code&gt;Sweden Central&lt;/code&gt;). Create your resource group.&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw23mlmlt49hc4crg8ztw.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw23mlmlt49hc4crg8ztw.png" alt="New foundry project" width="624" height="663"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate to the &lt;strong&gt;Model Catalog&lt;/strong&gt; and choose &lt;strong&gt;Explore Models&lt;/strong&gt;.&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F68n70p9dq05fjx29kgg8.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F68n70p9dq05fjx29kgg8.png" alt="Explore model" width="800" height="85"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select your preferred available coding model.&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fenwvfnudelwck6jrz1r4.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fenwvfnudelwck6jrz1r4.png" alt="Model selection" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploy it using the default settings, making note of the target model name (e.g.,for my case I used &lt;code&gt;gpt-5.3-codex&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy your &lt;strong&gt;Endpoint URL&lt;/strong&gt; and &lt;strong&gt;API Keys&lt;/strong&gt; from the model deployment dashboard. Keep these secure we will need them for VS Code.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Scenario B: You Need to Create One
&lt;/h3&gt;

&lt;p&gt;Head over to the official &lt;a href="https://azure.microsoft.com/en-us/free/students" rel="noopener noreferrer"&gt;Azure for Students Portal&lt;/a&gt;, sign in using your academic university email address (&lt;code&gt;.edu&lt;/code&gt; or your institutional domain), and verify your student status. Your cloud sandbox and free credit allotment will provision instantly.&lt;/p&gt;


&lt;h2&gt;
  
  
  vs code Configuration Blueprint
&lt;/h2&gt;

&lt;p&gt;Instead of wrestling with native extension limitations, we are going to configure your connection as an open-standard, &lt;strong&gt;OpenAI-Compatible gateway&lt;/strong&gt;, while preserving the specialized &lt;strong&gt;Responses API&lt;/strong&gt; handling required by modern Azure Foundry endpoints.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Open the Custom Models Panel
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Launch &lt;strong&gt;VS Code&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Open your &lt;strong&gt;Copilot Chat&lt;/strong&gt; panel on the sidebar.&lt;/li&gt;
&lt;li&gt;Click on the model selection dropdown menu at the top or bottom of the chat interface.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;"Other Models..."&lt;/strong&gt; from the bottom of the list.
&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%2Fuj2ktitlhj5g2p735jk4.png" alt="other models option" width="391" height="255"&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Step 2: Input Your Azure Endpoint Details
&lt;/h3&gt;

&lt;p&gt;A new UI panel labeled &lt;strong&gt;"Adding custom endpoint"&lt;/strong&gt; will appear. Populate the fields using the credentials you copied from your Azure AI Foundry dashboard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Endpoint URL:&lt;/strong&gt; Paste your Azure endpoint (ensure it targets the base &lt;code&gt;/openai/v1&lt;/code&gt; route).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Key:&lt;/strong&gt; Paste your secure Azure endpoint key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model ID:&lt;/strong&gt; Match it to your deployment name (e.g., &lt;code&gt;gpt-5.3-codex&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&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%2Fw6l7rqc8ab4xr78s2dy3.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%2Fw6l7rqc8ab4xr78s2dy3.png" alt="custom endpoint" width="799" height="439"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  💡 Pro-Tip: Deep Tweaking via JSON
&lt;/h3&gt;

&lt;p&gt;If you prefer fine-grained control or want to explicitly enforce parameters like context windows or vision support, you can open your user &lt;code&gt;chatLanguageModels.json&lt;/code&gt; file via the Command Palette (&lt;code&gt;Ctrl+Shift+P&lt;/code&gt; / &lt;code&gt;Cmd+Shift+P&lt;/code&gt; -&amp;gt; &lt;strong&gt;&lt;code&gt;Chat: Manage Language Models&lt;/code&gt;&lt;/strong&gt;) and drop in this clean schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[Azure AI Foundry (BYOK)]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"vendor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"customendpoint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"apiKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${input:chat.lm.secret.YOUR_SECRET_ID}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"apiType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"responses"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"models"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpt-5.3-codex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GPT-5.3 Codex (Foundry)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[https://***.services.ai.azure.com/openai/v1](https://***.services.ai.azure.com/openai/v1)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"toolCalling"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"vision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"maxInputTokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;128000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"maxOutputTokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Clear the IDE Cache Layers
&lt;/h3&gt;

&lt;p&gt;To ensure VS Code registers the new custom endpoint layout:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reload your window via the Command Palette (&lt;code&gt;Developer: Reload Window&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Open your Copilot Chat panel.&lt;/li&gt;
&lt;li&gt;Click the model dropdown selection menu. You should now see your deployed model available as a selectable model option!
&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb6zprj8o7e21xclptl2w.png" alt="your model" width="380" height="258"&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Result: Infinite Coding Freedom
&lt;/h2&gt;

&lt;p&gt;Once your endpoint is active and your environment is refreshed, you are ready to build without constraints. &lt;/p&gt;

&lt;p&gt;You have officially decoupled your IDE's intelligence layer from restrictive credit pools. By routing your Azure subscription credits straight into your workspace via a BYOK configuration, you gain full autonomy over your development ecosystem completely free of token caps or artificial feature tiers. Happy hacking!&lt;/p&gt;

&lt;p&gt;I would love to get your feedback and insights on this.&lt;/p&gt;

&lt;p&gt;Are you currently implementing BYOK setups or custom routing within your local teams and IDEs?&lt;br&gt;
How are you balancing API performance and cost management across modern developer environments?&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>githubcopilot</category>
      <category>azure</category>
    </item>
    <item>
      <title>Stop Writing 'Fixed Bug': Git Day-to-Day with Conventional Commits</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Fri, 15 May 2026 15:12:57 +0000</pubDate>
      <link>https://dev.to/majdizlitni/stop-writing-fixed-bug-git-day-to-day-with-conventional-commits-44ol</link>
      <guid>https://dev.to/majdizlitni/stop-writing-fixed-bug-git-day-to-day-with-conventional-commits-44ol</guid>
      <description>&lt;p&gt;We’ve all been there. A critical bug is reported in production. You grab your coffee, crack your knuckles, and run 'git log' to trace when the issue was introduced. And what do you see?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7a3b4c9 fixed bug
1d9e2f4 updated config
9f8a7b6 wip
3c2d1e8 finally works pls
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F1r5qroj4fyizyhg8wo32.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%2F1r5qroj4fyizyhg8wo32.png" alt="A chaotic commit history compared side-by-side with a perfectly clean, structured Conventional Commit history" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tracking what actually happened turns into an archaeological dig. When hundreds of developers on a team all push commits with vague messages, your repository's history becomes a chaotic nightmare.&lt;/p&gt;

&lt;p&gt;But there is a better way. Welcome to &lt;strong&gt;Conventional Commits&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a Conventional Commit?
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://www.conventionalcommits.org/" rel="noopener noreferrer"&gt;Conventional Commit&lt;/a&gt; provides a lightweight, standardized structure to your commit messages. By imposing a simple set of rules, commits become easily readable by both human developers and automated machines (like your CI/CD pipelines).&lt;/p&gt;

&lt;p&gt;Think of it as turning your Git history from a messy journal into a structured database.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Anatomy of a Perfect Commit
&lt;/h3&gt;

&lt;p&gt;The standard format is simple but powerful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;type&amp;gt;[optional scope]: &amp;lt;description&amp;gt;

[optional body]

[optional footer(s)] 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a real-world comparison:&lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;Bad Commit&lt;/strong&gt;: 'fixed the token issue'&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Good Commit&lt;/strong&gt;: 'fix(auth): resolve token parsing issue caused by expired JWT format'&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Commit Types (Prefixes)
&lt;/h3&gt;

&lt;p&gt;To keep things consistent, we use predefined prefixes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;feat:&lt;/strong&gt; A new feature for the user or the API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fix:&lt;/strong&gt; A bug fix for the user or the API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;docs:&lt;/strong&gt; Documentation-only changes (README, swagger, etc.).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;style:&lt;/strong&gt; Formatting, missing semi-colons, etc; no code change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;chore:&lt;/strong&gt; Changes to the build process or auxiliary tools (e.g., updating dependencies).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;refactor:&lt;/strong&gt; A code change that neither fixes a bug nor adds a feature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;test:&lt;/strong&gt; Adding missing tests or refactoring tests; no production code change.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Pro Tip:&lt;/strong&gt; Need to memorize these? Add a '.gitmessage' template to your project so every time you run 'git commit', the types are printed as comments in your editor!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔄 Revamping Your Daily Git Workflow
&lt;/h2&gt;

&lt;p&gt;Adopting Conventional Commits is more than just typing a prefix; it’s a mindset shift. Your daily workflow adjusts to prioritize clean, isolated history.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Branch Out
&lt;/h3&gt;

&lt;p&gt;Always ensure you're starting on a clean, isolated branch from 'main'.&lt;br&gt;
&lt;code&gt;bash&lt;br&gt;
git checkout main&lt;br&gt;
git pull&lt;br&gt;
git checkout -b feature/user-profile&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Make Isolated Changes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pitfall:&lt;/strong&gt; Don't group unrelated changes together. If you are fixing a UI bug and adding a new database field, those belong in &lt;em&gt;separate&lt;/em&gt; commits, and possibly separate branches. Keep your commits atomic.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Commit Accurately
&lt;/h3&gt;

&lt;p&gt;Use the prefixes rigorously! Be descriptive but concise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add src/components/UserProfile.tsx
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"feat(ui): add user profile dashboard component"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Rebase, Don't Merge (Usually)
&lt;/h3&gt;

&lt;p&gt;When bringing your feature branch up to date with 'main', prefer rebasing over merging.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Merging&lt;/strong&gt; ('git merge main') creates a "merge commit," tying two histories together. It's safe, but it makes the history look like a tangled web.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rebasing&lt;/strong&gt; ('git rebase main') plucks your commits and plays them &lt;em&gt;on top&lt;/em&gt; of the latest 'main'. It creates a beautiful, perfectly linear history.&lt;/li&gt;
&lt;/ul&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%2F2ataqi1uqhqw3ihlghec.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%2F2ataqi1uqhqw3ihlghec.png" alt="A diagram illustrating tracking isolated changes on a feature branch, followed by a rebase against main" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch origin
&lt;span class="c"&gt;# Rebase your current branch onto the latest main&lt;/span&gt;
git rebase origin/main
&lt;span class="c"&gt;# Resolve any conflicts, then force push safely:&lt;/span&gt;
git push &lt;span class="nt"&gt;--force-with-lease&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why Go Through the Trouble?
&lt;/h2&gt;

&lt;p&gt;Making your commits structured feels like extra typing at first. But the ROI is massive:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Instant Context for Reviewers:&lt;/strong&gt; Your peers instantly understand the scope and intent of your Pull Request. 'chore(deps)' tells them this is a dependency update, while 'feat(checkout)' tells them to look for new business logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Changelogs:&lt;/strong&gt; Scripts can automatically parse 'feat' and 'fix' commits to generate pristine Release Notes instantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD Magic:&lt;/strong&gt; Tools like Semantic Release rely wholly on these prefixes to automate versioning and deployments (which we cover in the next article!).&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion &amp;amp; Next Steps
&lt;/h2&gt;

&lt;p&gt;Switching to Conventional Commits transforms how your team interacts with the codebase. You stop guessing what a commit does and start treating your Git history as a source of truth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your Challenge for Today:&lt;/strong&gt;&lt;br&gt;
Try formatting your next 3 commits using the Conventional format. See how much cleaner your 'git log' looks!&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Part 2&lt;/strong&gt; of this series, we will take this to the next level. We'll show you how to leverage these structured commits to &lt;em&gt;completely automate your application versioning&lt;/em&gt; using &lt;strong&gt;Semantic Release&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you found this helpful, drop a ❤️ below! How does your team structure commit messages? Let me know in the comments!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Level Up Your Dev Setup: Get GitHub Copilot for Free with the Student Developer Pack</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Wed, 22 Apr 2026 10:54:24 +0000</pubDate>
      <link>https://dev.to/majdizlitni/level-up-your-dev-setup-get-github-copilot-for-free-with-the-student-developer-pack-20m4</link>
      <guid>https://dev.to/majdizlitni/level-up-your-dev-setup-get-github-copilot-for-free-with-the-student-developer-pack-20m4</guid>
      <description>&lt;p&gt;Hey coding wizards, open source heroes, and dedicated learners! Ever felt like the tools you need to build the next big thing are locked behind a paywall steeper than mount Everest? Or maybe you're just tired of writing boilerplate code manually while your wallet looks a bit thin?&lt;/p&gt;

&lt;p&gt;Fear not! &lt;a href="https://github.com" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt;, in its infinite wisdom and generosity, has compiled the ultimate cheat code for students: the &lt;a href="https://education.github.com/pack" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Student Developer Pack&lt;/strong&gt;&lt;/a&gt;. But what exactly is it, how do you get your hands on it, and most importantly, how can you use it to access top-tier AI tools like &lt;a href="https://github.com/copilot" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt;&lt;/a&gt;? Let's dive in!&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%2Fgnda5uweqz7cmhbf42lv.gif" 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%2Fgnda5uweqz7cmhbf42lv.gif" alt="faster typer" width="500" height="300"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What is the Developer Pack?&lt;/li&gt;
&lt;li&gt;How to Claim Your Pack: Step by Step&lt;/li&gt;
&lt;li&gt;The Ultimate AI Workbench: VS Code and GitHub Copilot&lt;/li&gt;
&lt;li&gt;Tips to Maximize Your Pack&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What is the Developer Pack?
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://education.github.com/pack" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Student Developer Pack&lt;/strong&gt;&lt;/a&gt; provides students with free access valid for 2 years to premium developer tools, cloud hosting, domains, and learning platforms to kickstart your career.&lt;br&gt;
After the 2-year period, you can reapply and renew your benefits&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who Qualifies?&lt;/strong&gt;&lt;br&gt;
Any currently enrolled &lt;a href="https://education.github.com/pack/join" rel="noopener noreferrer"&gt;student&lt;/a&gt; (high school, college, university, or verified bootcamps) aged 13+ with a verifiable school email address or proof of enrollment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's Included?&lt;/strong&gt; You get a massive bundle of resources, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GitHub Ecosystem&lt;/strong&gt;: Free &lt;a href="https://docs.github.com/en/get-started/learning-about-github/githubs-plans#github-pro" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Pro&lt;/strong&gt;&lt;/a&gt; &amp;amp; &lt;a href="//github.com/copilot"&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt;&lt;/a&gt;. Includes 1 free certification voucher.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://azure.microsoft.com/en-us" rel="noopener noreferrer"&gt;&lt;strong&gt;Microsoft Azure&lt;/strong&gt;&lt;/a&gt;: $100 credit and 25+ free services for 1 year.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud &amp;amp; Domains&lt;/strong&gt;: $200 &lt;a href="https://www.digitalocean.com" rel="noopener noreferrer"&gt;&lt;strong&gt;DigitalOcean&lt;/strong&gt;&lt;/a&gt; credit. Grab a free &lt;code&gt;.me&lt;/code&gt; (w/ SSL) from &lt;a href="https://www.namecheap.com" rel="noopener noreferrer"&gt;&lt;strong&gt;Namecheap&lt;/strong&gt;&lt;/a&gt;, a &lt;code&gt;.TECH&lt;/code&gt; domain, or choose from 25+ other extensions like &lt;code&gt;.live&lt;/code&gt; and &lt;code&gt;.dev&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Developer Tools&lt;/strong&gt;: Full educational license for all &lt;a href="https://www.jetbrains.com/academy/student-pack/" rel="noopener noreferrer"&gt;&lt;strong&gt;JetBrains&lt;/strong&gt;&lt;/a&gt; IDEs (IntelliJ, PyCharm, etc.), plus a &lt;a href="https://www.datadoghq.com/blog/datadog-github-student-developer-pack/" rel="noopener noreferrer"&gt;&lt;strong&gt;Datadog&lt;/strong&gt;&lt;/a&gt; Pro Account (10 servers for 2 years).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Learning &amp;amp; Interview Prep&lt;/strong&gt;: 3 months of &lt;a href="https://campus.datacamp.com" rel="noopener noreferrer"&gt;&lt;strong&gt;DataCamp&lt;/strong&gt;&lt;/a&gt;, free &lt;a href="https://www.pluralsight.com" rel="noopener noreferrer"&gt;&lt;strong&gt;Pluralsight&lt;/strong&gt;&lt;/a&gt; training, 1 week of &lt;a href="https://www.interviewcake.com/github-students" rel="noopener noreferrer"&gt;&lt;strong&gt;Interview cake&lt;/strong&gt;&lt;/a&gt;, and 20 free questions + 10% off at &lt;a href="https://www.algoexpert.io/github-students" rel="noopener noreferrer"&gt;&lt;strong&gt;AlgoExpert&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MongoDB Certification&lt;/strong&gt;: Receive a 100% free certification voucher within 24 hours of completing any Learning Path on &lt;a href="https://learn.mongodb.com" rel="noopener noreferrer"&gt;&lt;strong&gt;MongoDB University&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Productivity &amp;amp; Design&lt;/strong&gt;: Free &lt;a href="https://www.notion.so" rel="noopener noreferrer"&gt;&lt;strong&gt;Notion&lt;/strong&gt;&lt;/a&gt; Education plan (extra sharing &amp;amp; AI features), 2,000 &lt;a href="https://www.slidecoach.ai/en" rel="noopener noreferrer"&gt;&lt;strong&gt;SlideCoach&lt;/strong&gt;&lt;/a&gt; AI presentation credits, and 60 &lt;strong&gt;Premium Icons&lt;/strong&gt; monthly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Business&lt;/strong&gt;: Zero transaction fees on your first $1,000 in revenue via &lt;a href="https://stripe.com" rel="noopener noreferrer"&gt;&lt;strong&gt;Stripe&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;And many more!&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2F33kp4s2bnskoaqbaomuu.gif" 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%2F33kp4s2bnskoaqbaomuu.gif" alt="GitHub student pack tools" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Claim Your Pack: Step by Step
&lt;/h2&gt;

&lt;p&gt;Getting access is straightforward, but the verification step requires a little attention to detail. Here is exactly how to get approved:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Prep Your GitHub Profile&lt;/strong&gt;&lt;br&gt;
Ensure your &lt;a href="https://github.com/settings/profile" rel="noopener noreferrer"&gt;GitHub profile name&lt;/a&gt; matches your student ID. If your account is named "DarkNinja99" with no real name attached, the automated system is going to be very suspicious. Use your real name!&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%2Few46aqjqr6ptp318fggj.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%2Few46aqjqr6ptp318fggj.png" alt="GitHub Profile" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Confirm Your Payment Information&lt;/strong&gt;&lt;br&gt;
Go to your &lt;a href="https://github.com/settings/billing/payment_information" rel="noopener noreferrer"&gt;Payment Information settings&lt;/a&gt; and include your full name, last name, address, city, country, and zip code. Don't panic, they will not request a credit card! This is simply required as part of the verification process.&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%2F82fkpiykfhwks2pnvlno.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%2F82fkpiykfhwks2pnvlno.png" alt="Billing info" width="800" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Enable Two-Factor Authentication (2FA)&lt;/strong&gt;&lt;br&gt;
GitHub requires you to secure your account. Head over to your &lt;a href="https://github.com/settings/security" rel="noopener noreferrer"&gt;Security settings&lt;/a&gt; and enable 2FA via the &lt;a href="https://github.com/settings/two_factor_authentication/setup/intro" rel="noopener noreferrer"&gt;setup page&lt;/a&gt;.&lt;br&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%2Ffs4qmbige1hvem2sqiof.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%2Ffs4qmbige1hvem2sqiof.png" alt="2FA" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Add Your School Email&lt;/strong&gt;&lt;br&gt;
Go to your &lt;a href="https://github.com/settings/emails" rel="noopener noreferrer"&gt;GitHub account settings&lt;/a&gt; and add your school issued email address. Verify it. (A school verification email is required for the most efficient process).&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%2Fy0yadz0ys5b4uwxwv4hi.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%2Fy0yadz0ys5b4uwxwv4hi.png" alt="Email verification" width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt;&lt;br&gt;
Head over to &lt;a href="https://education.github.com/pack" rel="noopener noreferrer"&gt;education.github.com/pack&lt;/a&gt;, click "Sign up for Student Developer Pack". Select your role in education as "Student" ,and select this school email as an academic domain associated with your school/university.&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%2Fym44w1x4cwmd5ta9evwm.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%2Fym44w1x4cwmd5ta9evwm.png" alt="Education benefits Application" width="455" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Application Submitted&lt;/strong&gt;&lt;br&gt;
Your application has been submitted successfully! If needed earlier in the process, you may have used your webcam to snap a picture of your Student ID or transcript.&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%2Fxbmwpniq14ysqt2ha1c6.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%2Fxbmwpniq14ysqt2ha1c6.png" alt="submitted application" width="479" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Wait for the Magic&lt;/strong&gt;&lt;br&gt;
Once you submit, the initial review process generally takes between 48 to 72 hours. Using a valid school-issued email address is the most effective way to speed up this phase. Welcome to the big leagues!&lt;br&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%2Fpzqxdefpbxkh1lb61jms.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%2Fpzqxdefpbxkh1lb61jms.png" alt="Education benefits pending" width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Ultimate AI Workbench: VS Code and GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;One of the absolute best perks of the Student Pack is free access to &lt;a href="https://github.com/copilot" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Copilot Pro&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Having Copilot tightly integrated into your IDE feels exactly like having an endlessly patient, 10x senior engineer sitting right next to you, pair-programming. It doesn't just format your text; it understands your intent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before We Take Off (The Prerequisites):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VS Code 1.99+&lt;/strong&gt; (or version 1.116+ to have the magic built right in).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot + Copilot Chat extensions&lt;/strong&gt; installed (if you're running pre-v1.116).&lt;/li&gt;
&lt;li&gt;An active &lt;strong&gt;GitHub Copilot subscription&lt;/strong&gt; (which you just scored for free with your Student Pack!).&lt;/li&gt;
&lt;li&gt;Make sure you are signed into your authenticated GitHub account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Give It a Mission!&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Here comes the fun part. Tell your agent what you want to accomplish (e.g., &lt;em&gt;"Refactor the database connection logic in &lt;code&gt;src/&lt;/code&gt; to use the new connection pool pattern and ensure all tests pass"&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Now sit back, sip your coffee, and watch it autonomously navigate files, write code, run tests, and fix errors!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this setup, you're not just writing lines of code anymore you're architecting solutions while your AI pair-programmer handles the manual labor.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tips to Maximize Your Pack
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Don't Hoard, Use!&lt;/strong&gt; The free cloud credits (like DigitalOcean and Azure) are a use-it-or-lose-it investment in your education. Deploy a portfolio site or spin up a backend server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Snag a Free Domain:&lt;/strong&gt; Pair your free domain from Namecheap or .tech with your hosting credits to deploy live, working projects. Recruiters &lt;em&gt;love&lt;/em&gt; seeing live sites!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turbocharge Your Learning:&lt;/strong&gt; Use your free access to platforms like &lt;strong&gt;Educative&lt;/strong&gt; or &lt;strong&gt;Frontend Masters&lt;/strong&gt; to dive deep into modern frameworks and algorithms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure Your Secrets:&lt;/strong&gt; Get comfortable with tools like &lt;strong&gt;1Password&lt;/strong&gt; (included in the pack) from day one. Good security habits start early!&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The GitHub Student Developer Pack is more than just free software; it's a massive sandbox for your coding career. By leveraging tools like VS Code and GitHub Copilot, you can learn faster, build bigger, and code smarter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop writing code that only lives on your laptop. Claim your pack, build something real, and launch it to the world!&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Got questions about getting set up? Drop them in the comments below! Happy coding!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>github</category>
      <category>vscode</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>Augmented Coding Patterns: The Developer's Playbook for Working With AI</title>
      <dc:creator>Majdi Zlitni</dc:creator>
      <pubDate>Fri, 06 Feb 2026 11:19:11 +0000</pubDate>
      <link>https://dev.to/majdizlitni/augmented-coding-patterns-the-developers-playbook-for-working-with-ai-4pbc</link>
      <guid>https://dev.to/majdizlitni/augmented-coding-patterns-the-developers-playbook-for-working-with-ai-4pbc</guid>
      <description>&lt;h2&gt;
  
  
  AI as your new pair partner but are you using it right?
&lt;/h2&gt;

&lt;p&gt;Every developer I know has tried AI-assisted coding but most are doing it wrong.&lt;/p&gt;

&lt;p&gt;They paste code, get output, accept or reject. Rinse, repeat. That's not augmented coding that's autocomplete with extra steps.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://lexler.github.io/augmented-coding-patterns/" rel="noopener noreferrer"&gt;&lt;strong&gt;Augmented Coding Patterns&lt;/strong&gt;&lt;/a&gt; project created by Lada Kesseler&lt;br&gt;
changes that. &lt;br&gt;
It's a living catalog of &lt;strong&gt;patterns&lt;/strong&gt;, &lt;strong&gt;anti-patterns&lt;/strong&gt;, and &lt;strong&gt;obstacles&lt;/strong&gt; that define how developers should truly collaborate with LLMs in their daily workflow.&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%2F5eji2bms3wmdmmtrd3sm.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%2F5eji2bms3wmdmmtrd3sm.png" alt="Augmented Coding: Mapping the Uncharted Territory" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What Are Augmented Coding Patterns?
&lt;/h2&gt;

&lt;p&gt;Think of them like the Gang of Four design patterns but for human-AI collaboration. They're recurring solutions to recurring problems that arise when you use LLMs (Claude, GPT, Copilot, etc.) as coding partners.&lt;/p&gt;

&lt;p&gt;The catalog is organized into three pillars:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;What It Covers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Patterns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Proven techniques that work feedback loops, semantic zooming, visible context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Anti-Patterns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Traps developers fall into blind trust, context starvation, over-delegation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Obstacles&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Inherent limitations of LLMs you must design around&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Pattern 1: Feedback Loops
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;You give the AI a big task. It gives you 200 lines. You read them, find 3 bugs, rewrite half of it. You just wasted 15 minutes.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Pattern
&lt;/h3&gt;

&lt;p&gt;Build &lt;strong&gt;small, iterative cycles&lt;/strong&gt;. Ask for one function. Validate. Ask for the next. Correct course early.&lt;/p&gt;
&lt;h3&gt;
  
  
  Real Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Anti-pattern (one-shot prompting):&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;"Build me a complete ASP.NET Core REST API with authentication,
JWT, validation, rate limiting, and SQL Server integration for a Todo app."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pattern (feedback loop):&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;Step 1: "Create the Express server setup with CORS and JSON middleware."
→ Review → Approve

Step 2: "Add a POST /api/todos route with Zod validation for title (string, 
required) and completed (boolean, default false)."
→ Review → Fix the Zod schema import → Approve

Step 3: "Add JWT middleware. Here's my auth flow: [describe]."
→ Review → Adjust token expiry → Approve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each iteration is small enough to validate in under 60 seconds. Errors are caught before they compound.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation in Practice
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Step 1&lt;/em&gt;: You ask AI to scaffold the validation layer&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Step 2&lt;/em&gt;: You ask AI to create the route handler using your schema&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Step 3&lt;/em&gt;: You review: AI used &lt;code&gt;safeParse&lt;/code&gt; correctly, returns flattened errors.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Step 4&lt;/em&gt;: Let's say it didn't add the &lt;code&gt;userId&lt;/code&gt; from JWT. You correct: "Add &lt;code&gt;userId&lt;/code&gt; from &lt;code&gt;req.user.id&lt;/code&gt; to the created todo."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key: &lt;strong&gt;never let more than 30 lines go unreviewed&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pattern 2: Semantic Zooming
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;You're stuck at one level of abstraction. Either you're in the weeds asking about semicolons, or you're at 30,000 feet asking "how should I architect this?"&lt;/p&gt;

&lt;h3&gt;
  
  
  The Pattern
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Shift between levels deliberately.&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start high (architecture)&lt;/li&gt;
&lt;li&gt;Toom to mid-level (module design)&lt;/li&gt;
&lt;li&gt;Dive to low-level (implementation)&lt;/li&gt;
&lt;li&gt;Zoom out to verify the big picture still holds.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ZOOM LEVEL 1 Architecture:
"I'm building a notification service. I need to support email, SMS, and push notifications. What's the best pattern? I want it extensible."

AI Response: Strategy pattern + factory + message queue.

ZOOM LEVEL 2 Module Design:
"Show me the interface for the NotificationStrategy and the factory that selects the right one."

ZOOM LEVEL 3 Implementation:
"Implement the EmailStrategy using AWS SES. Here are my SES configuration constraints: [details]."

ZOOM BACK TO LEVEL 1:
"Given what we've built, does this architecture handle the case where SMS fails and we need to retry with exponential backoff? What needs to change?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each zoom level gives the AI the right amount of context to produce useful output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Level 1: &lt;em&gt;The architecture AI suggested&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Level 2: &lt;em&gt;The factory&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Level 3: &lt;em&gt;The implementation&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Pattern 3: Visible Context Show Your Work
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;You ask the AI to fix a bug but don't show it the error message, the test that failed, or the surrounding code. It hallucinates a solution for a problem it can't see.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Pattern
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Externalize everything the AI needs&lt;/strong&gt;: error logs, test output, type definitions, database schemas, business rules. Make the invisible visible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Context-starved prompt:&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;"My user registration is broken. Fix it."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Context-rich prompt:&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;"My user registration throws this error:

  PrismaClientKnownRequestError: Unique constraint failed 
  on the fields: (`email`)

Here's my register function: [paste code]
Here's my Prisma schema for User: [paste schema]
Here's the test that fails: [paste test]

The test creates a user, then tries to create another with 
the same email. I expect a 409 Conflict response but I'm 
getting a 500."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI now has a crystal-clear picture and can respond with accurate response.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Top 3 Anti-Patterns to Avoid
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Blind Trust
&lt;/h3&gt;

&lt;p&gt;Never accept AI output without reading it. Period. The AI doesn't know your business rules, your deployment constraints, or your team conventions.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Context Starvation
&lt;/h3&gt;

&lt;p&gt;The less context you give, the more the AI hallucinates. Every prompt should include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Relevant code&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Errors&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Types&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constraints&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Over-Delegation
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;"Build me a production-ready microservices architecture"&lt;/code&gt; is not a prompt it's a prayer. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break it down&lt;/li&gt;
&lt;li&gt;Own the decisions&lt;/li&gt;
&lt;li&gt;AI will handle the implementation&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;The developers who will thrive in the AI era aren't the ones who prompt the best. They're the ones who &lt;strong&gt;collaborate&lt;/strong&gt; the best.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;References:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://lexler.github.io/augmented-coding-patterns/" rel="noopener noreferrer"&gt;&lt;em&gt;Augmented Coding Patterns&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soundcloud.com/heavybit/o11ycast-ep-87-augmented-coding-patterns-with-lada-kesseler" rel="noopener noreferrer"&gt;&lt;em&gt;O11ycast Ep. #87: Augmented Coding Patterns with Lada Kesseler&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lexler/augmented-coding-patterns" rel="noopener noreferrer"&gt;&lt;em&gt;Augmented-coding-patterns GitHub Repo&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
