<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ve Sharma</title>
    <description>The latest articles on Forem by Ve Sharma (@vevarunsharma).</description>
    <link>https://forem.com/vevarunsharma</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1071794%2F5742ff38-c757-449e-8642-38adde37c6d0.jpg</url>
      <title>Forem: Ve Sharma</title>
      <link>https://forem.com/vevarunsharma</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/vevarunsharma"/>
    <language>en</language>
    <item>
      <title>GitHub Copilot SDK vs Azure AI Foundry Agents: Which One Should Your Company Use?</title>
      <dc:creator>Ve Sharma</dc:creator>
      <pubDate>Tue, 10 Feb 2026 04:45:04 +0000</pubDate>
      <link>https://forem.com/vevarunsharma/github-copilot-sdk-vs-azure-ai-foundry-agents-which-one-should-your-company-use-1n7n</link>
      <guid>https://forem.com/vevarunsharma/github-copilot-sdk-vs-azure-ai-foundry-agents-which-one-should-your-company-use-1n7n</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR for the Busy Person
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot SDK&lt;/strong&gt; gives you the same agentic core that powers Copilot CLI — context management, tool orchestration, MCP integration, model routing — so you can embed it in any app without building an agent platform from scratch. Best for: developer tools, Copilot Extensions, and any software where the user is a developer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure AI Foundry Agents&lt;/strong&gt; is a full platform for building, deploying, and governing general-purpose enterprise AI agents across any business domain. Best for: Product &amp;amp; end-user facing apps, customer support, document processing, ops automation, and multi-agent workflows outside of dev.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They're complementary.&lt;/strong&gt; Most enterprises will use both — Copilot SDK for the developer layer, Foundry for the business layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Both are enterprise-ready.&lt;/strong&gt; GitHub's platform carries SOC 2 Type II, ISO 27001, IP indemnification, and has feature set that covers the entire SDLC.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Problem: Building Agentic Workflows From Scratch Is Hard
&lt;/h2&gt;

&lt;p&gt;Building agentic workflows from scratch is hard.&lt;/p&gt;

&lt;p&gt;You have to manage context across turns, orchestrate tools and commands, route between models, integrate MCP servers, and think through permissions, safety boundaries, and failure modes. Even before you reach your actual product logic, you've already built a small platform.&lt;/p&gt;

&lt;p&gt;Most teams don't want to build a platform. They want to build a product.&lt;/p&gt;

&lt;p&gt;This is the core problem both &lt;strong&gt;GitHub Copilot SDK&lt;/strong&gt; and &lt;strong&gt;Azure AI Foundry Agents&lt;/strong&gt; solve — but they solve it for different audiences, in different contexts, with different trade-offs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Confusion
&lt;/h2&gt;

&lt;p&gt;After talking to customers and internal teams, one theme keeps coming up:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We want to build AI agents. Do we use the GitHub Copilot SDK or Azure AI Foundry? What's the difference? Can we use both?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The short answer: &lt;strong&gt;they solve different problems&lt;/strong&gt;. But the overlap in marketing language ("agents," "AI," "SDK") makes it murky. Let's fix that.&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%2F3xd5u5fqawekmwduxf4s.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3xd5u5fqawekmwduxf4s.jpg" alt="confused meme" width="500" height="756"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is the GitHub Copilot SDK?
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/github/copilot-sdk" rel="noopener noreferrer"&gt;GitHub Copilot SDK&lt;/a&gt; (now in technical preview) removes the burden of building your own agent infrastructure. It lets you take the &lt;strong&gt;same Copilot agentic core that powers GitHub Copilot CLI&lt;/strong&gt; and embed it in any application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the SDK handles for you:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;You used to build this yourself&lt;/th&gt;
&lt;th&gt;Copilot SDK handles it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Context management across turns&lt;/td&gt;
&lt;td&gt;✅ Maintained automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool/command orchestration&lt;/td&gt;
&lt;td&gt;✅ Automated invocation and chaining&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP server integration&lt;/td&gt;
&lt;td&gt;✅ Built-in protocol support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model routing (GPT-4.1, etc.)&lt;/td&gt;
&lt;td&gt;✅ Dynamic, policy-based routing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Planning and execution loops&lt;/td&gt;
&lt;td&gt;✅ Multi-step reasoning out of the box&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permissions and safety boundaries&lt;/td&gt;
&lt;td&gt;✅ Enforced by the runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Streaming responses&lt;/td&gt;
&lt;td&gt;✅ First-class support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth and session lifecycle&lt;/td&gt;
&lt;td&gt;✅ Managed under the hood&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What you focus on:&lt;/strong&gt; Your domain logic. Your tools. Your product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Available in:&lt;/strong&gt; TypeScript/Node.js, Python, Go, .NET&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Designed for:&lt;/strong&gt; Developer-facing applications — Copilot Extensions, dev portals, CLI tools, code review bots, internal productivity tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Matters
&lt;/h3&gt;

&lt;p&gt;Without the SDK, you're stitching together an LLM API, a context window manager, a tool registry, an execution loop, error handling, and auth — before writing a single line of product code. The SDK collapses all of that into an import.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your App
    │
    ├── Your product logic + custom tools
    ├── Copilot SDK (agentic core)
    │       │
    │       └──── handles context, orchestration,
    │             MCP, model routing, safety
    │       │
    │       └──── HTTPS ──▶ GitHub Cloud (inference)
    │
    └── Your UI / API / Extension
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What Is Azure AI Foundry Agent Service?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://azure.microsoft.com/en-ca/products/ai-foundry/agent-service/" rel="noopener noreferrer"&gt;Azure AI Foundry&lt;/a&gt; is a &lt;strong&gt;full platform for building, deploying, and governing enterprise AI agents&lt;/strong&gt; for any business domain — not just developer workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Foundry gives you:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-agent orchestration (multiple specialized agents coordinating on a workflow)&lt;/li&gt;
&lt;li&gt;Deep data connectors (SharePoint, SQL, M365, external APIs, Logic Apps)&lt;/li&gt;
&lt;li&gt;Bring your own model (Azure OpenAI, open-source, frontier, or custom)&lt;/li&gt;
&lt;li&gt;Goal-driven autonomy with thread-based memory&lt;/li&gt;
&lt;li&gt;Full governance stack (Entra ID, Purview, Defender)&lt;/li&gt;
&lt;li&gt;One-click deploy to Teams, M365 Copilot, web apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Designed for:&lt;/strong&gt; Business-wide automation — customer support agents, document processing pipelines, HR/finance/IT workflows, knowledge management with RAG.&lt;/p&gt;




&lt;h2&gt;
  
  
  When to Use Which
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use the Copilot SDK when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your user is a developer.&lt;/strong&gt; You're building tools that live in the developer workflow — IDE extensions, CLI tools, Copilot Chat extensions, internal dev portals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want to ship fast.&lt;/strong&gt; The SDK gives you a production-tested agentic core on day one. No need to build context management, tool orchestration, or model routing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You're extending GitHub Copilot.&lt;/strong&gt; Building a &lt;code&gt;@my-tool&lt;/code&gt; extension for Copilot Chat is a first-class use case.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want to stay in the GitHub ecosystem.&lt;/strong&gt; Your code, your PRs, your CI/CD, and now your AI agent — all on the same platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need something lightweight.&lt;/strong&gt; Import the SDK, register your tools, start a session. That's it.&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%2F5l64uh3i744ovcrjh3pt.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%2F5l64uh3i744ovcrjh3pt.png" alt="impressive" width="702" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Azure AI Foundry when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your user is not a developer.&lt;/strong&gt; You're building for support teams, ops, finance, HR, or customers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need multi-agent orchestration.&lt;/strong&gt; Multiple specialized agents collaborating on a complex workflow (e.g., triage → investigate → resolve → notify).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need deep data integration.&lt;/strong&gt; Connecting to SharePoint, SQL, CRM, ERP, or other enterprise data sources via built-in connectors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want to bring your own model.&lt;/strong&gt; Fine-tuned models, open-source models, or models from different providers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You need VNet isolation or customer-managed encryption.&lt;/strong&gt; For workloads where network-level isolation or key management is a hard requirement.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use both when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You're an enterprise with &lt;strong&gt;developer teams AND business teams&lt;/strong&gt; that both need AI agents.&lt;/li&gt;
&lt;li&gt;Your dev team uses Copilot SDK for internal tooling, while your platform team uses Foundry for customer-facing agents.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────┐
│             ENTERPRISE AI STACK              │
│                                              │
│  ┌───────────────────┐ ┌──────────────────┐  │
│  │  Developer Layer  │ │  Business Layer  │  │
│  │                   │ │                  │  │
│  │  Copilot SDK      │ │  Azure AI        │  │
│  │  • @extensions    │ │  Foundry Agents  │  │
│  │  • Dev portals    │ │  • Product apps  │  │
│  │  • CLI agents     │ │  • Biz pipelines │  │
│  │  • Ops workflows  │ │  • Ops workflows │  │
│  └───────────��───────┘ └──────────────────┘│
│                                              │
│  Shared: Microsoft identity, models, trust   │
└──────────────────────────────────────────────┘
&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%2Fu5dipdphmpz9wqf88tag.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5dipdphmpz9wqf88tag.jpg" alt="dev-meme-2" width="500" height="528"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Trade-Offs Worth Knowing
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Copilot SDK&lt;/th&gt;
&lt;th&gt;Azure AI Foundry&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Time to first agent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fast — import SDK, register tools, go&lt;/td&gt;
&lt;td&gt;Slower — more config, but more control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agentic core included?&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Yes — same engine as Copilot CLI&lt;/td&gt;
&lt;td&gt;You build or configure your own agent logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Model choice&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GitHub-hosted models (GPT-5.3, etc.) + BYO Model&lt;/td&gt;
&lt;td&gt;BYO model, Azure OpenAI, open-source, frontier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Built-in&lt;/td&gt;
&lt;td&gt;Supported via configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-agent orchestration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Early / evolving&lt;/td&gt;
&lt;td&gt;First-class, production-ready&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data connectors&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You build your own (via custom tools)&lt;/td&gt;
&lt;td&gt;Built-in (SharePoint, SQL, M365, Logic Apps)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deployment surface&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Your app, VS Code, GitHub.com&lt;/td&gt;
&lt;td&gt;Teams, M365 Copilot, web apps, containers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Network isolation (VNet)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not available&lt;/td&gt;
&lt;td&gt;✅ Full VNet / private endpoint support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Customer-managed keys&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Microsoft-managed&lt;/td&gt;
&lt;td&gt;✅ Azure Key Vault&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Infrastructure ownership&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GitHub-managed (less to operate)&lt;/td&gt;
&lt;td&gt;Your Azure subscription (more control, more ops)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Billing model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per Copilot seat&lt;/td&gt;
&lt;td&gt;Azure consumption-based&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Developer tools and workflows&lt;/td&gt;
&lt;td&gt;Business-wide automation at scale&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  A Note on Enterprise Readiness &amp;amp; Compliance
&lt;/h2&gt;

&lt;p&gt;There's a misconception that GitHub is only "good enough" for compliance compared to Azure. &lt;strong&gt;That's not accurate.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub is an enterprise-grade platform trusted by the world's largest companies and governments. The compliance posture is strong and getting stronger:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Certification / Control&lt;/th&gt;
&lt;th&gt;GitHub (incl. Copilot)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SOC 2 Type II&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Available (Copilot Business &amp;amp; Enterprise in scope)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SOC 1 Type II&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ISO/IEC 27001:2022&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Copilot in scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FedRAMP Moderate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;🔄 Actively pursuing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;IP Indemnification&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Included for enterprise plans&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;No training on your code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Copilot Business/Enterprise data is never used for model training&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Duplicate detection filtering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Available to reduce IP risk&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;GitHub's story is the &lt;strong&gt;end-to-end developer platform&lt;/strong&gt; — code, security, CI/CD, and now AI — all enterprise-ready under one roof. The Copilot SDK extends that story into your own applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On data residency specifically:&lt;/strong&gt; yes, Azure AI Foundry offers more granular region-bound controls (VNet isolation, customer-managed keys, explicit region pinning). This matters for certain regulated workloads. But for many enterprises — especially in the US and Canada — data-in-transit concerns with GitHub Copilot are well-addressed by existing encryption, privacy controls, and contractual terms. Data residency is worth understanding, but it shouldn't be the &lt;em&gt;sole&lt;/em&gt; deciding factor. Evaluate it alongside your actual regulatory requirements, not as a blanket blocker.&lt;/p&gt;




&lt;h2&gt;
  
  
  Decision Framework
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What are you building?
│
├── A developer tool, extension, or dev or ops workflow?
│   └── ✅ GitHub Copilot SDK
│       • You get a production-tested agentic core out of the box
│       • Ship fast, stay in the GitHub ecosystem
│       • Enterprise-ready compliance
│
├── A product, business/ops/customer-facing agent?
│   └── ✅ Azure AI Foundry
│       • Multi-agent orchestration, data connectors, BYO model
│       • Full Azure governance and network isolation
│
├── Both?
│   └── ✅ Use both — they're complementary
│
└── Not sure yet?
    └── Start with the user:
        • Developer or internal? → Copilot SDK
        • End-facing user or Non-developer? → Foundry
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Copilot SDK removes the hardest part of building agents.&lt;/strong&gt; Context, orchestration, MCP, model routing, safety — it's all handled. You focus on your product.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Foundry is for the business.&lt;/strong&gt; When your agents are for an user facing product or orchestrate across departments, or serve non-developer users, Foundry is the right tool.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GitHub is enterprise-ready.&lt;/strong&gt; SOC 2, ISO 27001, IP indemnification, no training on your data. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;They're complementary, not competing.&lt;/strong&gt; Copilot SDK for the developer/ops layer. Foundry for the product/business layer. Same Microsoft ecosystem underneath.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start with the user, not the technology.&lt;/strong&gt; Who is the agent serving? That answer picks your tool.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/github/copilot-sdk" rel="noopener noreferrer"&gt;GitHub Copilot SDK (repo)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.blog/news-insights/company-news/build-an-agent-into-any-app-with-the-github-copilot-sdk/" rel="noopener noreferrer"&gt;Build an Agent into Any App — GitHub Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://copilot.github.trust.page/faq" rel="noopener noreferrer"&gt;GitHub Copilot Trust Center&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/enterprise-cloud@latest/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/accessing-compliance-reports-for-your-organization" rel="noopener noreferrer"&gt;GitHub Enterprise Compliance Reports&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://azure.microsoft.com/en-ca/products/ai-foundry/agent-service/" rel="noopener noreferrer"&gt;Azure AI Foundry Agent Service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/building-secure-governable-ai-agents-with-microsoft-foundry/4472736" rel="noopener noreferrer"&gt;Building Secure, Governable AI Agents with Foundry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://resources.github.com/learn/pathways/copilot/extensions/building-your-first-extension/" rel="noopener noreferrer"&gt;Copilot Extensions — Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;I’m Ve Sharma, a Solution Engineer at Microsoft focusing on Cloud &amp;amp; AI working on GitHub Copilot. I help developers become AI-native developers and optimize the SDLC for teams. I also make great memes. Find me on &lt;a href="https://www.linkedin.com/in/vevarunsharma" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or &lt;a href="https://github.com/VeVarunSharma" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>azure</category>
      <category>ai</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>Building Context-Aware CI with GitHub Copilot SDK and Microsoft WorkIQ</title>
      <dc:creator>Ve Sharma</dc:creator>
      <pubDate>Mon, 26 Jan 2026 04:42:57 +0000</pubDate>
      <link>https://forem.com/vevarunsharma/building-context-aware-ci-with-github-copilot-sdk-and-microsoft-workiq-31bg</link>
      <guid>https://forem.com/vevarunsharma/building-context-aware-ci-with-github-copilot-sdk-and-microsoft-workiq-31bg</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Building Context-Aware GitHub Actions with the Copilot SDK and Microsoft WorkIQ&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  TL;DR for the Busy Dev
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Problem&lt;/strong&gt;: Enterprise devs waste hours on rework because they miss decisions made in meetings they didn't attend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solution&lt;/strong&gt;: GitHub Copilot SDK + Microsoft WorkIQ = CI that queries your M365 meetings and fails PRs that violate team agreements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stack&lt;/strong&gt;: GitHub Actions + &lt;code&gt;@github/copilot-sdk&lt;/code&gt; npm package + &lt;code&gt;@microsoft/workiq&lt;/code&gt; via MCP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outcome&lt;/strong&gt;: Three-state CI check (PASS/WARN/FAIL) with PR comments linking violations to specific meeting decisions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to use&lt;/strong&gt;: Enterprise teams already on M365 who want to enforce institutional knowledge automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When to skip&lt;/strong&gt;: Small teams, async-first orgs, or repos without feature-scoped meetings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Show me the code&lt;/strong&gt;: &lt;a href="https://github.com/VeVarunSharma/contoso-vibe-engineering/pull/27" rel="noopener noreferrer"&gt;Full implementation on GitHub&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The $50,000 Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;Picture this: Your team spends 2 hours in a planning meeting deciding to use PostgreSQL for the new user service. Three developers nod along. Two weeks later, someone opens a PR adding MongoDB.&lt;/p&gt;

&lt;p&gt;The code review catches it. Eventually. After 40 hours of development.&lt;/p&gt;

&lt;p&gt;This isn't a made-up scenario. According to a 2024 study by Stripe, developers spend &lt;strong&gt;17.3 hours per week&lt;/strong&gt; on maintenance tasks, with a significant portion attributed to "undoing work that shouldn't have been done in the first place."&lt;/p&gt;

&lt;p&gt;The root cause? &lt;strong&gt;Context fragmentation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Your decisions live in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meeting transcripts (Teams)&lt;/li&gt;
&lt;li&gt;Email threads&lt;/li&gt;
&lt;li&gt;Team messages&lt;/li&gt;
&lt;li&gt;Loop pages &amp;amp; power point decks&lt;/li&gt;
&lt;li&gt;Someone's head&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your CI/CD pipeline? It only knows about your code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if your CI could attend your meetings?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Enter the Dynamic Duo: Copilot SDK + WorkIQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GitHub Copilot SDK
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/github/copilot-sdk" rel="noopener noreferrer"&gt;Copilot SDK&lt;/a&gt; (&lt;code&gt;@github/copilot-sdk&lt;/code&gt;) lets you build agentic workflows that leverage GitHub's AI infrastructure. Think of it as programmable Copilot—you define the prompt, the tools, and the outcome.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CopilotClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@github/copilot-sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Create a session with MCP servers for tool access&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;CopilotClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;COPILOT_GITHUB_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;mcpServers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;workiq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-y&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@microsoft/workiq&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mcp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Send prompt and wait for response&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendAndWait&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You are a compliance analyst...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Analyze this PR for meeting compliance&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What it brings to the table:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Structured prompts with MCP tool access&lt;/li&gt;
&lt;li&gt;File system and repository awareness&lt;/li&gt;
&lt;li&gt;Configurable MCP servers for external integrations&lt;/li&gt;
&lt;li&gt;Runs in CI environments with &lt;code&gt;sendAndWait()&lt;/code&gt; for synchronous responses&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Microsoft WorkIQ
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/microsoft/work-iq-mcp" rel="noopener noreferrer"&gt;WorkIQ&lt;/a&gt; is Microsoft's natural language interface to your M365 data. It's currently in public preview and supports:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data Source&lt;/th&gt;
&lt;th&gt;Example Query&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Emails&lt;/td&gt;
&lt;td&gt;"What did Sarah say about the deadline?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Meetings&lt;/td&gt;
&lt;td&gt;"Summarize decisions from yesterday's sprint planning"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Documents&lt;/td&gt;
&lt;td&gt;"Find PowerPoints about Q4 roadmap"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Teams&lt;/td&gt;
&lt;td&gt;"What blockers came up in #engineering today?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;People&lt;/td&gt;
&lt;td&gt;"Who's working on Project Alpha?"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @microsoft/workiq

&lt;span class="c"&gt;# Query your M365 data&lt;/span&gt;
workiq ask &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"What architectural decisions were made this week?"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What it brings to the table:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Natural language queries to M365&lt;/li&gt;
&lt;li&gt;Meeting transcripts and decisions&lt;/li&gt;
&lt;li&gt;Cross-platform context (Teams, Outlook, SharePoint)&lt;/li&gt;
&lt;li&gt;MCP server mode for tool integration&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Together They're Batman and Robin
&lt;/h2&gt;

&lt;p&gt;Separately, they're powerful. Together, they're transformative.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Copilot SDK Alone&lt;/th&gt;
&lt;th&gt;WorkIQ Alone&lt;/th&gt;
&lt;th&gt;Combined&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Analyzes code&lt;/td&gt;
&lt;td&gt;Queries meetings&lt;/td&gt;
&lt;td&gt;Validates code against meeting decisions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generates reports&lt;/td&gt;
&lt;td&gt;Summarizes context&lt;/td&gt;
&lt;td&gt;Links violations to specific discussions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runs in CI&lt;/td&gt;
&lt;td&gt;Requires human invocation&lt;/td&gt;
&lt;td&gt;Fully automated compliance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No organizational context&lt;/td&gt;
&lt;td&gt;No code awareness&lt;/td&gt;
&lt;td&gt;Full-stack intelligence&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The magic&lt;/strong&gt;: WorkIQ provides the &lt;em&gt;institutional memory&lt;/em&gt;. Copilot SDK provides the &lt;em&gt;reasoning engine&lt;/em&gt;. Together, they close the loop between "what we decided" and "what we built."&lt;/p&gt;




&lt;h2&gt;
  
  
  Real Implementation: Decision Compliance CI Check
&lt;/h2&gt;

&lt;p&gt;Here's what we built—a GitHub Action that fails PRs violating team agreements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────────┐
│                     Pull Request Opened                       │
├──────────────────────────────────────────────────────────────┤
│  1. Extract keywords from branch (feature/user-auth → auth)  │
│  2. CopilotClient.createSession() with WorkIQ MCP server     │
│  3. session.sendAndWait() → WorkIQ queries M365 meetings     │
│  4. Analyze PR diff against those decisions                  │
│  5. Generate structured report (JSON + Markdown)             │
│  6. Post PR comment with findings                            │
│  7. CI outcome: ✅ PASS / ⚠️ WARN / ❌ FAIL                   │
└──────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Workflow (Simplified)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/workiq-decision-compliance.yml&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;Meeting Decision Compliance&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;synchronize&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;compliance-check&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&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;Setup Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22&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;Install and build SDK script&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.github/scripts/workiq-decision-compliance&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;npm ci&lt;/span&gt;
          &lt;span class="s"&gt;npm run build&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;Run Decision Compliance Agent&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.github/scripts/workiq-decision-compliance&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;COPILOT_GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.COPILOT_GITHUB_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;WORKIQ_TENANT_ID&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.WORKIQ_TENANT_ID }}&lt;/span&gt;
          &lt;span class="na"&gt;PR_TITLE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.pull_request.title }}&lt;/span&gt;
          &lt;span class="na"&gt;PR_NUMBER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.pull_request.number }}&lt;/span&gt;
          &lt;span class="na"&gt;CHANGED_FILES&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.changed-files.outputs.all_changed_files }}&lt;/span&gt;
          &lt;span class="na"&gt;LOOKBACK_DAYS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;7"&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;node dist/index.js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The SDK Script (Key Sections)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/index.ts - Main entry point&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CopilotClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@github/copilot-sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;configSchema&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;buildUserPrompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SYSTEM_PROMPT&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./prompts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;parseComplianceResult&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;configSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Create session with WorkIQ as MCP server&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;CopilotClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;COPILOT_GITHUB_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;mcpServers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;workiq&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-y&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@microsoft/workiq&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mcp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-t&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tenantId&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Send prompt and wait for structured response&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendAndWait&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SYSTEM_PROMPT&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;buildUserPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="c1"&gt;// Parse and act on results&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseComplianceResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Exit code based on status&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;FAIL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Developers See
&lt;/h3&gt;

&lt;p&gt;When a PR is analyzed, they get a comment like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## 📋 Meeting Decision Compliance Report

| Status | Decisions Checked | Violations | Warnings |
|--------|-------------------|------------|----------|
| ⚠️ WARN | 3 | 0 | 1 |

### Decisions Analyzed
1. **2026-01-20 Sprint Planning**: Use Zod for all API validation
2. **2026-01-18 Architecture Review**: REST endpoints use noun-based naming

### Warnings
- **Naming Convention** (2026-01-18): Endpoint `/api/getUsers` uses verb prefix
  - 💡 Recommendation: Rename to `/api/users` for REST consistency

### Compliance Evidence
- ✅ Found Zod schemas in src/validators/
- ✅ Database uses PostgreSQL via Drizzle ORM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Enterprise Impact
&lt;/h2&gt;

&lt;p&gt;For teams already invested in M365, this is a force multiplier:&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer → Writes code → PR review → "Wait, didn't we decide X?"
→ Rework → Re-review → Merge (3-5 days)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  After
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer → Writes code → CI checks decisions → Fix before review
→ PR review → Merge (1-2 days)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ROI Calculation (Conservative)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;Savings&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rework incidents/month&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;6 incidents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hours per incident&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;24 hours/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developer cost/hour&lt;/td&gt;
&lt;td&gt;$75&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$1,800/month&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team of 10 devs&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$18,000/month&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And that's just direct rework. The indirect benefits—faster onboarding, preserved institutional knowledge, reduced meeting FOMO—compound over time.&lt;/p&gt;




&lt;h2&gt;
  
  
  More Use Cases (Beyond Compliance)
&lt;/h2&gt;

&lt;p&gt;Once you have this pipeline, the possibilities expand:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;WorkIQ Query&lt;/th&gt;
&lt;th&gt;Copilot SDK Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sprint Alignment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"What's committed for this sprint?"&lt;/td&gt;
&lt;td&gt;Verify PR implements sprint items&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stakeholder Notification&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Who discussed this feature?"&lt;/td&gt;
&lt;td&gt;Auto-tag relevant people on PR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ADR Validation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"What architecture decisions exist?"&lt;/td&gt;
&lt;td&gt;Check code against ADRs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Onboarding Context&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"What decisions led to this code?"&lt;/td&gt;
&lt;td&gt;Generate context for new devs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Risk Assessment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Were there concerns about this approach?"&lt;/td&gt;
&lt;td&gt;Surface historical objections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Meeting Prep&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"What PRs relate to tomorrow's review?"&lt;/td&gt;
&lt;td&gt;Auto-generate meeting agendas&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Honest Pros and Cons
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Benefit&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Automated institutional memory&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Decisions become enforceable, not just documented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reduced meeting FOMO&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Miss a meeting? CI has your back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Faster code reviews&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reviewers focus on logic, not policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Self-documenting PRs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Context travels with the code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Graceful degradation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WARN state handles ambiguity without blocking&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  ❌ Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Challenge&lt;/th&gt;
&lt;th&gt;Mitigation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;M365 admin consent required&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One-time setup, but needs IT involvement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Meeting quality matters&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Garbage in, garbage out—transcripts need clear decisions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;False positives possible&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;WARN state prevents blocking on uncertain cases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Keyword matching is imperfect&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Future: Use embeddings for semantic matching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Public preview (WorkIQ)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;APIs may change; not for mission-critical yet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Copilot license + M365 license + compute time&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  When to Use This (And When Not To)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Good Fit
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enterprise teams (50+ devs) on M365&lt;/li&gt;
&lt;li&gt;Regulated industries needing audit trails&lt;/li&gt;
&lt;li&gt;Teams with frequent architectural discussions&lt;/li&gt;
&lt;li&gt;Repos with long-lived feature branches&lt;/li&gt;
&lt;li&gt;Organizations fighting "tribal knowledge" loss&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❌ Skip It If
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Small teams (&amp;lt; 10 devs) with high context sharing&lt;/li&gt;
&lt;li&gt;Async-first orgs (decisions in docs, not meetings)&lt;/li&gt;
&lt;li&gt;Open source projects (no M365 integration)&lt;/li&gt;
&lt;li&gt;Repos with no feature-scoped meetings&lt;/li&gt;
&lt;li&gt;Teams that don't record/transcribe meetings&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;GitHub Copilot license&lt;/li&gt;
&lt;li&gt;Microsoft 365 with Teams/Outlook&lt;/li&gt;
&lt;li&gt;WorkIQ admin consent (&lt;a href="https://aka.ms/workiq-admin-consent" rel="noopener noreferrer"&gt;guide&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Node.js 22+&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Quick Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Clone the reference implementation&lt;/span&gt;
git clone https://github.com/VeVarunSharma/contoso-vibe-engineering
&lt;span class="nb"&gt;cd &lt;/span&gt;contoso-vibe-engineering/.github/scripts/workiq-decision-compliance

&lt;span class="c"&gt;# 2. Install dependencies&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# 3. Accept WorkIQ EULA (first time only)&lt;/span&gt;
npx &lt;span class="nt"&gt;-y&lt;/span&gt; @microsoft/workiq accept-eula

&lt;span class="c"&gt;# 4. Test the WorkIQ connection&lt;/span&gt;
npx &lt;span class="nt"&gt;-y&lt;/span&gt; @microsoft/workiq ask &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"What meetings do I have this week?"&lt;/span&gt;

&lt;span class="c"&gt;# 5. Add secrets to your repo&lt;/span&gt;
gh secret &lt;span class="nb"&gt;set &lt;/span&gt;COPILOT_GITHUB_TOKEN
gh secret &lt;span class="nb"&gt;set &lt;/span&gt;WORKIQ_TENANT_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Full Implementation
&lt;/h3&gt;

&lt;p&gt;The reference implementation includes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Key files:&lt;/span&gt;
&lt;span class="c"&gt;# .github/workflows/workiq-decision-compliance.yml  - GitHub Actions workflow&lt;/span&gt;
&lt;span class="c"&gt;# .github/scripts/workiq-decision-compliance/       - TypeScript SDK script&lt;/span&gt;
&lt;span class="c"&gt;#   ├── src/index.ts    - Main entry point&lt;/span&gt;
&lt;span class="c"&gt;#   ├── src/config.ts   - Zod config validation&lt;/span&gt;
&lt;span class="c"&gt;#   ├── src/prompts.ts  - System and user prompts&lt;/span&gt;
&lt;span class="c"&gt;#   └── src/types.ts    - TypeScript interfaces&lt;/span&gt;
&lt;span class="c"&gt;# .github/skills/workiq-copilot/                    - Documentation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;This is just the beginning. The Copilot SDK + MCP ecosystem is evolving fast. Expect more business layer and enterprise value context integrations in the pipeline.&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%2Fwa86p3mcfmsugh2f6cos.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%2Fwa86p3mcfmsugh2f6cos.png" alt="cover-image" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;The Copilot SDK gives you programmable AI reasoning. WorkIQ gives you access to your organization's collective memory. Together, they bridge the gap between what your team &lt;em&gt;decided&lt;/em&gt; and what your code &lt;em&gt;does&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For enterprise developers drowning in meetings, context switches, and "I didn't know we decided that" moments—this is the escape hatch.&lt;/p&gt;

&lt;p&gt;The future of agentic devOps &amp;amp; CI isn't just testing code—it's validating intent.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I’m Ve Sharma, a Solution Engineer at Microsoft focusing on Cloud &amp;amp; AI working on GitHub Copilot. I help developers become AI-native developers and optimize the SDLC for teams. I also make great memes. Find me on &lt;a href="https://www.linkedin.com/in/vevarunsharma" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or &lt;a href="https://github.com/VeVarunSharma" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>githubcopilot</category>
      <category>microsoft</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>GitHub + Azure DevOps: The Better Together Story (And Why GitHub Should Be Your Future</title>
      <dc:creator>Ve Sharma</dc:creator>
      <pubDate>Mon, 19 Jan 2026 05:14:46 +0000</pubDate>
      <link>https://forem.com/vevarunsharma/github-azure-devops-the-better-together-story-and-why-github-should-be-your-future-1bb6</link>
      <guid>https://forem.com/vevarunsharma/github-azure-devops-the-better-together-story-and-why-github-should-be-your-future-1bb6</guid>
      <description>

&lt;h2&gt;
  
  
  &lt;strong&gt;🧭 TL;DR for the Busy Person — Why GitHub Should Be Your Long‑Term SDLC Home (Even If You're Using Azure DevOps Today)&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Azure DevOps isn’t going away&lt;/strong&gt; — it remains excellent for Boards, Pipelines, Test Plans, enterprise workflow, and hybrid/legacy workloads.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;GitHub is where Microsoft is investing for AI‑native software development&lt;/strong&gt; — Copilot Workspace, repo‑wide reasoning, agents, automated fixes, and modern CI/CD workflows.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Copilot works great with Azure DevOps&lt;/strong&gt;, but &lt;strong&gt;advanced AI features only unlock when repos live in GitHub&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  The best path?
&lt;strong&gt;Start Copilot inside Azure DevOps → Migrate repos gradually → Move new projects to GitHub by default.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  This keeps risk low while letting teams benefit from GitHub’s AI automation, security tooling, and unified developer experience.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🚀 The Future of Software Development: GitHub as the AI-Native Platform&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Over the past two years, GitHub has transformed from a developer tool into a full AI‑powered software development platform.  &lt;/p&gt;

&lt;p&gt;Microsoft &amp;amp; GitHub are pouring much more resources and getting some of the smartest minds at the company to improve the GitHub platform, including the Copilot.&lt;/p&gt;

&lt;p&gt;GitHub now offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Agentic workflows&lt;/strong&gt; (multi-step reasoning, automated refactors, multi-file edits, across the SDLC.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Top Tier LLMs&lt;/strong&gt; - There's large variety of top off the shelf models (Gemini, Anthropic, OpenAI, etc) for developers, and the ability to use your own models via Microsoft Foundry.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Copilot Workspace&lt;/strong&gt; (task planning → implementation → PR → CI)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Copilot Autofix&lt;/strong&gt; (security + code quality fixes generated automatically)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Graph-based repo understanding&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;GitHub Actions ecosystem&lt;/strong&gt; (90K+ reusable workflows)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Deep GitHub Advanced Security integration&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a non-exhaustive list as there would be too many features to list. See the &lt;a href="https://github.blog/changelog" rel="noopener noreferrer"&gt;GitHub Changelog for yourself here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Azure DevOps is still strong, but built on a &lt;strong&gt;services model&lt;/strong&gt; (Repos, Boards, Pipelines) rather than a unified AI runtime.&lt;br&gt;&lt;br&gt;
GitHub is now effectively &lt;strong&gt;the AI layer for Microsoft‑based development&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🔍 GitHub vs Azure DevOps — A Balanced, Honest Comparison&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;High-Level Summary&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Azure DevOps&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI &amp;amp; Copilot depth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full repo reasoning, Workspace, Agents, PR intelligence, Autofix&lt;/td&gt;
&lt;td&gt;IDE‑only Copilot, limited PR intelligence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Repo intelligence&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cloud‑based semantic graph, multi-file context&lt;/td&gt;
&lt;td&gt;No server-side intelligence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CI/CD&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GitHub Actions (huge ecosystem, cloud-native)&lt;/td&gt;
&lt;td&gt;Azure Pipelines (mature, enterprise, hybrid)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GitHub Advanced Security built-in; Autofix; dependency insights&lt;/td&gt;
&lt;td&gt;Scanning available but no Autofix, fewer AI-powered fixes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dev Experience&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Unified repos → PR → CI → Security → AI&lt;/td&gt;
&lt;td&gt;Split experience across services&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ecosystem&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Largest open-source + enterprise dev community&lt;/td&gt;
&lt;td&gt;Strong enterprise workflows, compliance, approvals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Planning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GitHub Projects (improving rapidly)&lt;/td&gt;
&lt;td&gt;Azure Boards (richer today)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Test Management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Integrations / GitHub apps&lt;/td&gt;
&lt;td&gt;Azure Test Plans best-in-class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best Fit For&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Modern, cloud-native, AI-assisted teams&lt;/td&gt;
&lt;td&gt;Enterprise, hybrid, legacy, structured planning&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Azure DevOps is still excellent.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
GitHub is simply where the &lt;strong&gt;future direction of AI-driven DevOps&lt;/strong&gt; is going.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🤖 GitHub Copilot: GitHub vs Azure DevOps (Important Differences)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Copilot works in both environments… &lt;strong&gt;but the experience is not equal&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;💡 Copilot with Azure DevOps (what you get)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Code completions in VS Code / Visual Studio&lt;/li&gt;
&lt;li&gt;  Copilot Chat in IDE&lt;/li&gt;
&lt;li&gt;  Basic explanations + code edits&lt;/li&gt;
&lt;li&gt;  Some PR help (summaries)&lt;/li&gt;
&lt;li&gt;  No repo-level graph or reasoning&lt;/li&gt;
&lt;li&gt;  No agents&lt;/li&gt;
&lt;li&gt;  No Workspace&lt;/li&gt;
&lt;li&gt;  No AI-powered Autofix&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;🔮 Copilot with GitHub (what unlocks)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Repo-wide reasoning&lt;/strong&gt; (Copilot Workspace)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Multi-step planning → coding → PR creation&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;AI-generated PR summaries + inline reviewing&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Copilot Autofix&lt;/strong&gt; (security, quality, dependency fixes)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Agentic workflows&lt;/strong&gt; across repos + CI/CD&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Better diffs, test generation, refactor support&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Native integration with GitHub Actions&lt;/strong&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%2Fgo8swgintosdy2aai0gv.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%2Fgo8swgintosdy2aai0gv.png" alt="ghcp-comparison" width="800" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Bottom Line:&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;If your code lives in GitHub → Copilot becomes &lt;strong&gt;10x more powerful&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Azure DevOps users still get value — great place to start — but &lt;strong&gt;the ceiling is lower&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;⚖️ Pros &amp;amp; Cons — A Balanced View&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  The &lt;strong&gt;AI-native development platform&lt;/strong&gt; inside Microsoft&lt;/li&gt;
&lt;li&gt;  Copilot Workspace + Agents + Autofix&lt;/li&gt;
&lt;li&gt;  Superior PR + review experience&lt;/li&gt;
&lt;li&gt;  Best-in-class security tooling&lt;/li&gt;
&lt;li&gt;  GitHub Actions ecosystem&lt;/li&gt;
&lt;li&gt;  Developers overwhelmingly prefer GitHub&lt;/li&gt;
&lt;li&gt;  Faster onboarding of new hires&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;GitHub — Cons&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  GitHub Projects still catching up to Azure Boards&lt;/li&gt;
&lt;li&gt;  Migration effort required for pipelines and YAML normalization&lt;/li&gt;
&lt;li&gt;  Some enterprise compliance workflows still maturing&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Azure DevOps — Pros&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Azure Boards: still best enterprise planning tool&lt;/li&gt;
&lt;li&gt;  Azure Pipelines: powerful, hybrid, legacy-ready&lt;/li&gt;
&lt;li&gt;  Test Plans: far ahead for structured QA&lt;/li&gt;
&lt;li&gt;  Enterprise approvals &amp;amp; audit trails robust&lt;/li&gt;
&lt;li&gt;  No need to migrate everything at once&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Azure DevOps — Cons&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  AI capability capped at IDE level&lt;/li&gt;
&lt;li&gt;  No server-side repo reasoning&lt;/li&gt;
&lt;li&gt;  Multiple services lead to tool fragmentation&lt;/li&gt;
&lt;li&gt;  Long-term innovation emphasis has shifted toward GitHub&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🔄 A Practical, Low-Risk Transition Strategy (Used by Real Customers)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Microsoft field guidance now follows this pattern:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1️⃣ Start with Copilot — inside Azure DevOps&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This reduces friction and avoids platform conversations too early.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  No migration&lt;/li&gt;
&lt;li&gt;  No workflow disruption&lt;/li&gt;
&lt;li&gt;  Fastest path to measurable productivity gains&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; show value → build internal pull.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2️⃣ Move &lt;em&gt;one&lt;/em&gt; high-value repo to GitHub&lt;/strong&gt;
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;  A microservice&lt;/li&gt;
&lt;li&gt;  A heavily changed repo&lt;/li&gt;
&lt;li&gt;  A team that is cloud-native&lt;/li&gt;
&lt;li&gt;  A repo with active CI/CD challenges&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Reason:&lt;/strong&gt; teams instantly feel improved PR + automation experience.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3️⃣ Expand GitHub footprint as value becomes undeniable&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Developer-led, not top-down.&lt;/p&gt;

&lt;p&gt;Most orgs follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Copilot adoption&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Selective repo moves&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Standardize new projects on GitHub&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Integrate Azure Boards with GitHub&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Shift CI/CD to GitHub Actions over time&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This avoids big-bang migrations.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🏗️ Recommended Hybrid Model (Best of Both Worlds)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Many customers land here during transition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Keep using Azure Boards&lt;/strong&gt; (excellent planning tool)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Move source code to GitHub&lt;/strong&gt; (AI-native)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Use GitHub Actions&lt;/strong&gt; for modern workflows&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Keep Azure Pipelines&lt;/strong&gt; for complex/legacy workloads&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Integrate Test Plans as needed&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This lets teams modernize without breaking what works.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;💼 Business &amp;amp; Technical Benefits of Moving to GitHub&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Business Benefits&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Faster delivery = reduced time-to-market&lt;/li&gt;
&lt;li&gt;  Better quality reduces production risk&lt;/li&gt;
&lt;li&gt;  Developers happier → talent retention improves&lt;/li&gt;
&lt;li&gt;  Lower tool fragmentation&lt;/li&gt;
&lt;li&gt;  AI-assisted automation reduces cost of delivery&lt;/li&gt;
&lt;li&gt;  Aligns with Microsoft’s investment strategy&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Technical Benefits&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  More automation with Copilot Workspace &amp;amp; Agents&lt;/li&gt;
&lt;li&gt;  Richer PR reviews (summaries, test suggestions, change reasoning)&lt;/li&gt;
&lt;li&gt;  Repo-wide graph understanding improves refactors&lt;/li&gt;
&lt;li&gt;  GitHub Advanced Security detects + fixes issues automatically&lt;/li&gt;
&lt;li&gt;  GitHub Actions easier to maintain than Pipelines YAML&lt;/li&gt;
&lt;li&gt;  Huge marketplace ecosystem&lt;/li&gt;
&lt;li&gt;  Better alignment with open-source standards&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%2Fghpw0a7aiflq0qvamcl4.jpeg" 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%2Fghpw0a7aiflq0qvamcl4.jpeg" alt="cover-image" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;You don’t need to choose GitHub &lt;em&gt;or&lt;/em&gt; Azure DevOps.&lt;br&gt;&lt;br&gt;
Most organizations start hybrid and let developer experience drive the long-term destination.&lt;/p&gt;

&lt;p&gt;The truth is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Azure DevOps is excellent at planning + enterprise workflows.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;GitHub is the long-term AI-native engineering platform.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start with Copilot where you are.&lt;br&gt;&lt;br&gt;
Move code when it makes sense.&lt;br&gt;&lt;br&gt;
Let productivity metrics guide the rest.&lt;/p&gt;

</description>
      <category>github</category>
      <category>azure</category>
      <category>githubcopilot</category>
      <category>devops</category>
    </item>
    <item>
      <title>What If Your CI Pipeline Could catch regulatory compliance violations of your code?</title>
      <dc:creator>Ve Sharma</dc:creator>
      <pubDate>Tue, 13 Jan 2026 03:35:41 +0000</pubDate>
      <link>https://forem.com/vevarunsharma/what-if-your-ci-pipeline-could-catch-regulatory-compliance-violations-of-your-code-405b</link>
      <guid>https://forem.com/vevarunsharma/what-if-your-ci-pipeline-could-catch-regulatory-compliance-violations-of-your-code-405b</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR for the Busy Dev:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Traditional CI checks&lt;/strong&gt; (linting, tests, SAST) are deterministic—same input always produces the same output&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-powered CI checks&lt;/strong&gt; using GitHub Copilot CLI can catch nuanced compliance violations that rule-based scanners miss&lt;/li&gt;
&lt;li&gt;We built a &lt;strong&gt;PIPA BC (Privacy) compliance gate&lt;/strong&gt; that analyzes code for consent verification, data minimization, PHI logging, and more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-compliant code fails the pipeline&lt;/strong&gt; with a detailed report of violations&lt;/li&gt;
&lt;li&gt;Best used &lt;strong&gt;alongside&lt;/strong&gt; (not replacing) deterministic checks for defense in depth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ROI&lt;/strong&gt;: Catching a privacy violation in CI costs ~$100. Catching it post-breach? $4.45 million average (IBM 2023)&lt;/li&gt;
&lt;li&gt;Example: Here are 2 examples in PR formats using the compliance workflow:&lt;a href="https://github.com/VeVarunSharma/contoso-vibe-engineering/pull/13" rel="noopener noreferrer"&gt; Compliant version&lt;/a&gt;, and the &lt;a href="https://github.com/VeVarunSharma/contoso-vibe-engineering/pull/15" rel="noopener noreferrer"&gt;Non-compliant version failing in the CI&lt;/a&gt;. &lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Problem: Privacy Compliance is Hard to Automate
&lt;/h2&gt;

&lt;p&gt;If you've worked with healthcare, finance, or government data, you know the drill. Regulations like &lt;strong&gt;PIPA BC&lt;/strong&gt;, &lt;strong&gt;HIPAA&lt;/strong&gt;, &lt;strong&gt;GDPR&lt;/strong&gt;, and &lt;strong&gt;PIPEDA&lt;/strong&gt; require specific handling of personal information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Verify consent before data access&lt;/li&gt;
&lt;li&gt;✅ Minimize data exposure (return only what's needed)&lt;/li&gt;
&lt;li&gt;✅ Never log sensitive values like SIN, PHN, or medical records&lt;/li&gt;
&lt;li&gt;✅ Maintain audit trails&lt;/li&gt;
&lt;li&gt;✅ Implement proper authentication and authorization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Traditional static analysis tools can catch some of these—hardcoded secrets, missing auth middleware, SQL injection. But they struggle with &lt;strong&gt;contextual violations&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is this &lt;code&gt;console.log()&lt;/code&gt; statement printing a patient's Social Insurance Number, or just a debug message?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's where non-deterministic, AI-powered checks come in.&lt;/p&gt;




&lt;h2&gt;
  
  
  Deterministic vs. Non-Deterministic CI Checks
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Deterministic&lt;/th&gt;
&lt;th&gt;Non-Deterministic (AI)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Same input → Same result, always&lt;/td&gt;
&lt;td&gt;May vary slightly between runs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ESLint, Jest, Trivy, CodeQL&lt;/td&gt;
&lt;td&gt;GitHub Copilot CLI, LLM analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Strengths&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Predictable, fast, cheap&lt;/td&gt;
&lt;td&gt;Understands context, catches nuance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Weaknesses&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pattern-based, easy to bypass&lt;/td&gt;
&lt;td&gt;Can hallucinate, slower, costs $&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Syntax, known vulnerabilities&lt;/td&gt;
&lt;td&gt;Compliance, code review, intent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The key insight&lt;/strong&gt;: These aren't competing approaches—they're complementary layers of defense.&lt;/p&gt;




&lt;h2&gt;
  
  
  Our Use Case: PIPA BC Compliance for Healthcare APIs
&lt;/h2&gt;

&lt;p&gt;British Columbia's &lt;strong&gt;Personal Information Protection Act (PIPA)&lt;/strong&gt; governs how private-sector organizations handle personal information. For healthcare apps, this means:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PIPA Section&lt;/th&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;What to Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Section 6&lt;/td&gt;
&lt;td&gt;Consent&lt;/td&gt;
&lt;td&gt;Is consent verified before PHI access?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Section 4&lt;/td&gt;
&lt;td&gt;Data Minimization&lt;/td&gt;
&lt;td&gt;Are we returning only necessary fields?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Section 11&lt;/td&gt;
&lt;td&gt;Purpose Limitation&lt;/td&gt;
&lt;td&gt;Is a purpose required and validated?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Section 34&lt;/td&gt;
&lt;td&gt;Security&lt;/td&gt;
&lt;td&gt;Auth middleware? No PHI in logs?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Section 34&lt;/td&gt;
&lt;td&gt;Audit Trail&lt;/td&gt;
&lt;td&gt;Are accesses logged (without PHI values)?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Let's build a CI gate that checks all of this.&lt;/p&gt;




&lt;h2&gt;
  
  
  The GitHub Action: How It Works
&lt;/h2&gt;

&lt;p&gt;Here's our workflow that runs on every push to &lt;code&gt;main&lt;/code&gt;:&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PIPA BC Compliance Check&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;services/medical-api/**"&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;opened&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;synchronize&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;reopened&lt;/span&gt;
  &lt;span class="na"&gt;workflow_dispatch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# Allows manual trigger for testing&lt;/span&gt;

&lt;span class="c1"&gt;# Ensure only one compliance check runs at a time per PR&lt;/span&gt;
&lt;span class="na"&gt;concurrency&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pipa-compliance-${{ github.event.pull_request.number || github.run_id }}&lt;/span&gt;
  &lt;span class="na"&gt;cancel-in-progress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
  &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;

&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;COMPLIANCE_THRESHOLD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pipa-compliance-check&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;PIPA BC Compliance Analysis&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;timeout-minutes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repository&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# Full history for accurate diff&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;Get changed files&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;changed-files&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tj-actions/changed-files@v44&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;services/medical-api/**/*.ts&lt;/span&gt;
            &lt;span class="s"&gt;services/medical-api/**/*.tsx&lt;/span&gt;
            &lt;span class="s"&gt;services/medical-api/**/*.js&lt;/span&gt;
            &lt;span class="s"&gt;services/medical-api/**/*.jsx&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check if relevant files changed&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;check-files&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;if [ -z "${{ steps.changed-files.outputs.all_changed_files }}" ]; then&lt;/span&gt;
            &lt;span class="s"&gt;echo "skip=true" &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;
            &lt;span class="s"&gt;echo "No relevant TypeScript/JavaScript files changed in medical-api"&lt;/span&gt;
          &lt;span class="s"&gt;else&lt;/span&gt;
            &lt;span class="s"&gt;echo "skip=false" &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;
            &lt;span class="s"&gt;echo "Files to analyze:"&lt;/span&gt;
            &lt;span class="s"&gt;echo "${{ steps.changed-files.outputs.all_changed_files }}"&lt;/span&gt;
          &lt;span class="s"&gt;fi&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;Setup Node.js&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.check-files.outputs.skip != 'true'&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22&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;Install GitHub Copilot CLI&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.check-files.outputs.skip != 'true'&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;npm i -g @github/copilot&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;Run PIPA BC Compliance Agent&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.check-files.outputs.skip != 'true'&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;COPILOT_GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.COPILOT_GITHUB_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_REPOSITORY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.repository }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;set -euo pipefail&lt;/span&gt;

          &lt;span class="s"&gt;# Build the list of changed files&lt;/span&gt;
          &lt;span class="s"&gt;CHANGED_FILES="${{ steps.changed-files.outputs.all_changed_files }}"&lt;/span&gt;

          &lt;span class="s"&gt;# Read the agent prompt&lt;/span&gt;
          &lt;span class="s"&gt;AGENT_PROMPT=$(cat .github/agents/pipa-bc-compliance.agent.md)&lt;/span&gt;

          &lt;span class="s"&gt;# Build the full prompt&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT="$AGENT_PROMPT"&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$'\n\n## Context\n'&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+="- Repository: $GITHUB_REPOSITORY"&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$'\n- Service: services/medical-api'&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$'\n- Changed Files: '"$CHANGED_FILES"&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$'\n\n## Task\n'&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+='1. Read the PIPA BC compliance documentation at services/medical-api/PIPA_COMPLIANCE.md'&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$'\n2. Analyze the changed files for PIPA BC compliance'&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$'\n3. Check each file against all PIPA BC requirements (consent, data minimization, purpose limitation, security, audit logging, access control)'&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$'\n4. Generate a compliance report at services/medical-api/pipa-compliance-report.md'&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$'\n5. The report MUST include a JSON block with compliance_score and status fields'&lt;/span&gt;

          &lt;span class="s"&gt;# Run Copilot CLI with the agent&lt;/span&gt;
          &lt;span class="s"&gt;copilot --prompt "$PROMPT" --allow-all-tools --allow-all-paths &amp;lt; /dev/null&lt;/span&gt;

&lt;span class="s"&gt;. . .&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the full file here: &lt;a href="https://github.com/VeVarunSharma/contoso-vibe-engineering/blob/main/.github/workflows/pipa-bc-compliance.yml" rel="noopener noreferrer"&gt;.github/workflows/pipa-bc-compliance.yml&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Happening Here?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Checkout &amp;amp; Setup&lt;/strong&gt;: Standard CI setup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install Copilot CLI&lt;/strong&gt;: The &lt;code&gt;@github/copilot&lt;/code&gt; npm package provides terminal access to Copilot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load the Agent Prompt&lt;/strong&gt;: We read our compliance rules from a markdown file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run Analysis&lt;/strong&gt;: Copilot analyzes the entire codebase against our rules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail on Critical&lt;/strong&gt;: If critical violations are found, the pipeline fails&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The magic is in the &lt;strong&gt;agent prompt&lt;/strong&gt;—a markdown file that tells Copilot exactly what to look for.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example 1: Compliant Code ✅
&lt;/h2&gt;

&lt;p&gt;Here's a PIPA-compliant patient endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ Auth middleware applied to all routes&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requireAuth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;zValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;query&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPatientQuerySchema&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;patientId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;purpose&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;query&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ✅ Purpose required&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;c&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// ✅ Verify role has permission for this purpose&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;ROLE_PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;purpose&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="nf"&gt;createAuditLog&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ACCESS_DENIED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Access denied&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ✅ Verify consent before data access&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;consentResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;verifyConsent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;patientId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;purpose&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;consentResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createAuditLog&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ACCESS_DENIED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Consent verification failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;patient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;patients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findFirst&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;patients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;patientId&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// ✅ Apply data minimization based on purpose&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filteredData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;filterPHI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;patient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;purpose&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// ✅ Audit log with field names only, no PHI values&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createAuditLog&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PATIENT_ACCESS&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fieldsAccessed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;filteredData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_accessedFields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Names only!&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;filteredData&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;CI Result&lt;/strong&gt;: ✅ PASS&lt;/p&gt;

&lt;p&gt;Here are some examples of the GitHub Compliance CI check in action taken from the example repo.&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%2Fyhwdvbcpknkvyqfxsu16.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%2Fyhwdvbcpknkvyqfxsu16.png" alt="compliance-pass-1" width="800" height="463"&gt;&lt;/a&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%2F7fiv1y885p4e8jhsj1un.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%2F7fiv1y885p4e8jhsj1un.png" alt="compliance-pass-2" width="800" height="790"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Example 2: Non-Compliant Code ❌
&lt;/h2&gt;

&lt;p&gt;Here's intentionally bad code for demo purposes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ VIOLATION 8: Hardcoded credentials&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API_SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sk-prod-12345-abcdef-secret-key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DATABASE_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;super_secret_password_123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ❌ VIOLATION 1: No authentication middleware&lt;/span&gt;
&lt;span class="nx"&gt;app&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;patientId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// ❌ VIOLATION 7: No purpose validation&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;purpose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;purpose&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Optional and ignored!&lt;/span&gt;

  &lt;span class="c1"&gt;// ❌ VIOLATION 2: No consent verification&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;patient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;patients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findFirst&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;patients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;patientId&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// ❌ VIOLATION 4: Logging PHI values&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[PATIENT] SIN: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;patient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;socialInsuranceNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[PATIENT] Health Card: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;patient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;healthCardNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`[PATIENT] Medical History: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;patient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;medicalHistory&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// ❌ VIOLATION 6: No audit logging&lt;/span&gt;

  &lt;span class="c1"&gt;// ❌ VIOLATION 3: Returns ALL fields (no data minimization)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;patient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;_internal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;API_SECRET_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Exposing secrets!&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ❌ VIOLATION 5: Bulk export with no access controls&lt;/span&gt;
&lt;span class="nx"&gt;app&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/export/all&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allPatients&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;patients&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;patients&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;allPatients&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;CI Result&lt;/strong&gt;: ❌ FAIL&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%2Fbbjamafjgcqlleuwbum0.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%2Fbbjamafjgcqlleuwbum0.png" alt="non-compliance-fail-1" width="800" height="679"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The report is uploaded as an artifact, and it's attached right in the Pull Request for other agents &amp;amp; humans to review, and to possibly to other agentic actions from this type of trigger.&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%2Ftwqacn85od03zms6dd5k.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%2Ftwqacn85od03zms6dd5k.png" alt="non-compliance-fail-2" width="800" height="802"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The report identifies all 8 violations with specific line numbers and PIPA sections violated.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step-by-Step Setup Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;GitHub repository with Actions enabled&lt;/li&gt;
&lt;li&gt;GitHub Copilot subscription (Business or Enterprise)&lt;/li&gt;
&lt;li&gt;Fine-grained Personal Access Token with Copilot permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Create the Copilot Token
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;GitHub Settings → Developer settings → Personal access tokens → Fine-grained tokens&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create a new token with:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repository access&lt;/strong&gt;: Your target repo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions&lt;/strong&gt;: &lt;code&gt;Copilot&lt;/code&gt; → Read-only&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Copy the token&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Add the Secret
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to your repo's &lt;strong&gt;Settings → Secrets and variables → Actions&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create a new secret: &lt;code&gt;COPILOT_GITHUB_TOKEN&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Paste your token&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 3: Create the Agent Prompt
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;.github/agents/pipa-bc-compliance.agent.md&lt;/code&gt;:&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;# PIPA BC Compliance Agent&lt;/span&gt;

You are a privacy compliance auditor for British Columbia's PIPA.

&lt;span class="gu"&gt;## Your Task&lt;/span&gt;

Analyze all TypeScript/JavaScript files for PIPA violations:

&lt;span class="gu"&gt;### Critical Violations (Immediate Fail)&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; [ ] PHI values logged to console (SIN, PHN, medical records)
&lt;span class="p"&gt;-&lt;/span&gt; [ ] No authentication on endpoints accessing PHI
&lt;span class="p"&gt;-&lt;/span&gt; [ ] No consent verification before data access
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Hardcoded credentials or API keys
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Bulk data export without access controls

&lt;span class="gu"&gt;### Major Violations&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; [ ] Missing purpose validation on data requests
&lt;span class="p"&gt;-&lt;/span&gt; [ ] No data minimization (returning all fields)
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Missing audit logging

&lt;span class="gu"&gt;## Output Format&lt;/span&gt;

Generate a report with:
&lt;span class="p"&gt;
1.&lt;/span&gt; Overall compliance score (0-100)
&lt;span class="p"&gt;2.&lt;/span&gt; List of violations with file, line, and PIPA section
&lt;span class="p"&gt;3.&lt;/span&gt; Remediation guidance for each violation

If any CRITICAL violations exist, include this line:
"THIS ASSESSMENT CONTAINS A CRITICAL VULNERABILITY"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the full file for this compliance agent here: &lt;a href="https://github.com/VeVarunSharma/contoso-vibe-engineering/blob/main/.github/agents/pipa-bc-compliance.agent.md" rel="noopener noreferrer"&gt;.github/agents/pipa-bc-compliance.agent.md&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Create the Workflow
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;.github/workflows/pipa-compliance.yml&lt;/code&gt; with the workflow shown above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Test It
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Push compliant code → Should pass ✅&lt;/li&gt;
&lt;li&gt;Push non-compliant code → Should fail ❌&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Pros and Cons
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Benefit&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Catches contextual violations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Understands "is this log statement printing PHI?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Natural language rules&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No regex patterns or AST parsing required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Adapts to your codebase&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Learns patterns from your actual code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reduces manual review time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Flags issues before human reviewers see them&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Documentation as code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent prompts are readable, version-controlled&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  ❌ Cons
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Drawback&lt;/th&gt;
&lt;th&gt;Mitigation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Non-deterministic output&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Run multiple times, require consensus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Can hallucinate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Human review of flagged issues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Slower than linting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Run on specific paths, use caching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Costs money&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Only run on PRs to protected branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Requires Copilot license&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ROI justifies for compliance-heavy orgs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  When to Use Each Type
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Deterministic Checks For:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Syntax errors and formatting (ESLint, Prettier)&lt;/li&gt;
&lt;li&gt;✅ Type checking (TypeScript)&lt;/li&gt;
&lt;li&gt;✅ Known vulnerability patterns (CodeQL, Trivy)&lt;/li&gt;
&lt;li&gt;✅ Unit and integration tests (Jest, Playwright)&lt;/li&gt;
&lt;li&gt;✅ Secret scanning (git-secrets, Gitleaks)&lt;/li&gt;
&lt;li&gt;✅ Dependency vulnerabilities (Dependabot, Snyk)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Non-Deterministic (AI) Checks For:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Privacy compliance (PIPA, HIPAA, GDPR intent)&lt;/li&gt;
&lt;li&gt;✅ Business logic validation&lt;/li&gt;
&lt;li&gt;✅ Code review augmentation&lt;/li&gt;
&lt;li&gt;✅ Documentation completeness&lt;/li&gt;
&lt;li&gt;✅ API contract compliance&lt;/li&gt;
&lt;li&gt;✅ Security posture assessment&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Hybrid Approach (Recommended)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Fast, deterministic checks first&lt;/span&gt;
  &lt;span class="na"&gt;lint-and-test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pnpm lint&lt;/span&gt;
      &lt;span class="pi"&gt;-&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;pnpm test&lt;/span&gt;
      &lt;span class="pi"&gt;-&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;pnpm typecheck&lt;/span&gt;

  &lt;span class="c1"&gt;# AI compliance check after deterministic passes&lt;/span&gt;
  &lt;span class="na"&gt;compliance-check&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lint-and-test&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;copilot --prompt "..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only run the expensive AI check if the cheap checks pass first.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters: The Business Case
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Cost of Getting It Wrong
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;Cost to Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Development (caught in CI)&lt;/td&gt;
&lt;td&gt;~$100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QA/Staging&lt;/td&gt;
&lt;td&gt;~$1,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production (pre-breach)&lt;/td&gt;
&lt;td&gt;~$10,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Post-breach (notification, legal, fines)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$4.45M average&lt;/strong&gt; (IBM 2023)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For PIPA BC specifically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fines&lt;/strong&gt;: Up to $100,000 per violation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reputation&lt;/strong&gt;: Healthcare data breaches make headlines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lawsuits&lt;/strong&gt;: Class actions for privacy violations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ROI Calculation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Annual Copilot Business license: ~$228/developer
PRs per developer per year: ~200
Cost per AI compliance check: ~$1.14

Violations caught per 100 PRs: ~5
Cost to fix in CI: $100 × 5 = $500
Cost to fix post-production: $10,000 × 5 = $50,000

Savings per 100 PRs: $49,500
ROI: 4,342%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if AI checks only catch &lt;strong&gt;one&lt;/strong&gt; violation per quarter that would have reached production, they pay for themselves.&lt;/p&gt;




&lt;h2&gt;
  
  
  For Government and Regulated Industries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Non-Deterministic Checks Matter More Here
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Regulations are written in natural language&lt;/strong&gt;—AI understands intent, not just patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auditors ask "why"&lt;/strong&gt;—AI can explain its reasoning in reports&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requirements change frequently&lt;/strong&gt;—Update a markdown file, not regex rules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defense in depth&lt;/strong&gt;—Another layer for compliance-by-design&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implementation Tips
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start with critical violations only&lt;/strong&gt;—Get quick wins before expanding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human-in-the-loop&lt;/strong&gt;—Require approval for AI-flagged issues, don't auto-reject&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit the auditor&lt;/strong&gt;—Review AI decisions quarterly for accuracy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document everything&lt;/strong&gt;—AI reports become compliance evidence&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&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.amazonaws.com%2Fuploads%2Farticles%2Fp9hyq64y0pemmty6vgvn.jpeg" 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%2Fp9hyq64y0pemmty6vgvn.jpeg" alt="Github-ci-cover-image" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Non-deterministic CI checks aren't replacing your test suite—they're augmenting it. For compliance-heavy domains like healthcare, finance, and government, AI-powered analysis catches the nuanced violations that rule-based scanners miss.&lt;/p&gt;

&lt;p&gt;The setup is straightforward:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Copilot token&lt;/li&gt;
&lt;li&gt;Write your compliance rules in plain English&lt;/li&gt;
&lt;li&gt;Add the workflow&lt;/li&gt;
&lt;li&gt;Push and watch it work&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The cost of a privacy breach—in fines, reputation, and user trust—dwarfs the cost of an AI-powered CI check. For organizations handling sensitive data, this isn't optional anymore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start small. Catch one critical violation. Prove the ROI. Then expand.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot" rel="noopener noreferrer"&gt;GitHub Copilot CLI Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bclaws.gov.bc.ca/civix/document/id/complete/statreg/03063_01" rel="noopener noreferrer"&gt;PIPA BC Full Text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/VeVarunSharma/contoso-vibe-engineering" rel="noopener noreferrer"&gt;Example Repository (this article's code)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ibm.com/reports/data-breach" rel="noopener noreferrer"&gt;IBM Cost of a Data Breach Report 2023&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;I’m Ve Sharma, a Solution Engineer at Microsoft focusing on Cloud &amp;amp; AI working on GitHub Copilot. I help developers become AI-native developers and optimize the SDLC for teams. I also make great memes. Find me on &lt;a href="https://www.linkedin.com/in/vevarunsharma" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or &lt;a href="https://github.com/VeVarunSharma" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>devops</category>
      <category>ai</category>
      <category>security</category>
    </item>
    <item>
      <title>Injecting AI Agents into CI/CD: Using GitHub Copilot CLI in GitHub Actions for Smart Failures</title>
      <dc:creator>Ve Sharma</dc:creator>
      <pubDate>Mon, 15 Dec 2025 02:49:01 +0000</pubDate>
      <link>https://forem.com/vevarunsharma/injecting-ai-agents-into-cicd-using-github-copilot-cli-in-github-actions-for-smart-failures-58m8</link>
      <guid>https://forem.com/vevarunsharma/injecting-ai-agents-into-cicd-using-github-copilot-cli-in-github-actions-for-smart-failures-58m8</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR for the Busy Dev
&lt;/h2&gt;

&lt;p&gt;We are used to CI/CD pipelines that fail on syntax errors or failed unit tests. But what about "qualitative" failures? By embedding the &lt;strong&gt;GitHub Copilot CLI&lt;/strong&gt; directly into a GitHub Action, you can build &lt;strong&gt;AI Agents&lt;/strong&gt; that review your code for security, logic, or product specs. If the Agent detects a critical issue, it triggers a programmatic failure, stopping the merge before a human even reviews it.&lt;/p&gt;




&lt;p&gt;The holy grail of DevOps is "Shift Left"—catching problems as early as possible. We have mastered this for &lt;strong&gt;deterministic&lt;/strong&gt; issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Linter:&lt;/strong&gt; "You missed a semicolon." -&amp;gt; ❌ Fail.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Jest:&lt;/strong&gt; "Expected 200, got 500." -&amp;gt; ❌ Fail.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But we still rely heavily on humans for &lt;strong&gt;non-deterministic&lt;/strong&gt; reviews:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  "Is this SQL query actually secure?"&lt;/li&gt;
&lt;li&gt;  "Did we update the documentation for this new feature?"&lt;/li&gt;
&lt;li&gt;  "Does this code actually meet the acceptance criteria?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article demonstrates how to bridge that gap. We will build a &lt;strong&gt;Security Agent&lt;/strong&gt; that lives in your CI pipeline, scans your code using the Copilot CLI, and &lt;strong&gt;fails the build&lt;/strong&gt; if it finds a critical vulnerability.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture: How It Works
&lt;/h2&gt;

&lt;p&gt;This isn't just asking ChatGPT to summarize a PR. We are building a closed-loop system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;The Brain:&lt;/strong&gt; The GitHub Copilot CLI (&lt;code&gt;npm i -g @github/copilot&lt;/code&gt;), which creates the intelligence layer.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Persona:&lt;/strong&gt; A markdown file (&lt;code&gt;.github/agents/security-reporter.agent.md&lt;/code&gt;) that acts as the System Prompt.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Trigger:&lt;/strong&gt; A bash script that parses the AI's natural language output for specific "Kill Switch" phrases to determine pass/fail.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1: Defining the Agent (Prompt Engineering)
&lt;/h2&gt;

&lt;p&gt;The most critical part of this workflow isn't the YAML; it's the &lt;strong&gt;Prompt Engineering&lt;/strong&gt;. We need the AI to be a harsh auditor, not a helpful assistant.&lt;/p&gt;

&lt;p&gt;We store this prompt in &lt;code&gt;.github/agents/security-reporter.agent.md&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://github.com/VeVarunSharma/contoso-vibe-engineering/blob/main/.github/agents/security-reporter.agent.md" rel="noopener noreferrer"&gt;Link to full prompt file here.&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
name: SecurityReportAgent
description: Security Report Agent - Analyzes TypeScript and React code for security vulnerabilities and creates security reports
model: GPT-5.1 (Preview)
---

## Purpose

This agent performs comprehensive security analysis of the Astro, TypeScript code. It identifies security vulnerabilities, assesses risks, and produces detailed security reports without modifying the codebase directly.

## Security Scanning Capabilities

This agent can perform comprehensive security analysis across the full stack:

### Code Analysis

- **SAST (Static Code Analysis)** - Scans TypeScript/React source code for security vulnerabilities
- Identify security vulnerabilities including:
  - SQL Injection risks
  - Cross-Site Scripting (XSS) vulnerabilities
  - Cross-Site Request Forgery (CSRF) issues
  - Authentication and authorization flaws
  - Insecure cryptographic implementations
  - Hardcoded secrets or credentials
  - Path traversal vulnerabilities
  - Insecure deserialization
  - Insufficient input validation
  - Information disclosure risks
  - Missing security headers
  - Dependency vulnerabilities
  - Input validation analysis - review all user input handling
  - Data Encryption - check encryption at rest and in transit
  - Error Handling - ensure errors don't leak sensitive information

### Dependency &amp;amp; Component Analysis

- **SCA (Software Composition Analysis)** - Monitors npm dependencies for known vulnerabilities &amp;amp; CVEs
- **License Scanning** - Identifies licensing risks in open source components
- **Outdated Software Detection** - Flags unmaintained frameworks and end-of-life runtimes
- **Malware Detection** - Checks for malicious packages in supply chain

### Infrastructure &amp;amp; Configuration

- **Secrets Detection** - Finds hardcoded API keys, passwords, certificates
- **Cloud Configuration Review** - Azure Functions and services security posture
- **IaC Scanning** - Analyzes Terraform/CloudFormation/Kubernetes configurations
- **Container Image Scanning** - Scans Azure container images for vulnerabilities

### API &amp;amp; Runtime Security

- **API Security** - Reviews endpoint security and access controls
- **Database Security** - Checks for secure queries and connection practices
- **WebSocket Security** - Validates secure WebSocket implementations
- **File Upload Security** - Reviews secure file handling practices

### Compliance &amp;amp; Best Practices

- OWASP Top 10: Check against latest OWASP security risks
- TypeScript/React Security Guidelines: Verify adherence to Node.js and React security best practices
- Secure coding standards: Validate code follows industry standards
- Dependency scanning: Check for known vulnerabilities in npm dependencies
- Security headers: Verify proper HTTP security headers
- Data privacy: Review GDPR/privacy compliance considerations

### Security Metrics &amp;amp; Reporting

- **Vulnerability Count by Severity** - Critical, High, Medium, Low categorization
- **Code Coverage Analysis** - Security-critical code coverage metrics
- **OWASP Top 10 Mapping** - Maps findings to current OWASP risks
- **CWE Classification** - Uses Common Weakness Enumeration for standardization
- **Risk Score** - Overall security posture assessment
- **Remediation Timeline** - Priority-based fix recommendations

## Report Structure

### Security Assessment Report

1. **Executive Summary**
   - **Security Posture**: [Risk Level] (e.g., HIGH RISK, MEDIUM RISK)
   - **Score**: [0-10]/10
   - **Findings Summary**:
     | Severity | Count |
     | :--- | :--- |
     | Critical | [Count] |
     | High | [Count] |
     | Medium | [Count] |
     | Low | [Count] |
   - Brief overview of the security state.

2. Vulnerability Findings
   For each vulnerability:

- Severity: Critical/High/Medium/Low
- Category: (e.g., Injection, Authentication, etc.)
- Location: File and line number
- Description: What the issue is
- Impact: Potential consequences
- Recommendation: How to fix it
- References: OWASP/CWE/Microsoft docs

3. Security Best Practices Review

- Areas following best practices
- Areas needing improvement
- Configuration recommendations

4. Dependency Analysis

- Vulnerable packages identified
- Recommended updates

5. Action Items

- Prioritized list of fixes needed
- Quick wins vs. complex remediation

6. Intentional Vulnerabilities

- List any critical or high severity findings found in:
  - Any file within the `infra/` directory.
  - Any file path containing the string `legacy-vibe`.
- Mark them as "Intentional - No Action Required".

7. Critical Vulnerability Warning

- Review all CRITICAL severity findings.
- Filter out any findings that are located in the "Intentional Vulnerabilities" paths defined above (files in `infra/` or containing `legacy-vibe/`).
- If there are any REMAINING Critical vulnerabilities after filtering:
  1. List them briefly under a header "### Blocking Critical Vulnerabilities".
  2. Include exactly this message at the end of the report:

THIS ASSESSMENT CONTAINS A CRITICAL VULNERABILITY


- Do not adapt or change this message in any way.
- If all critical vulnerabilities were filtered out as intentional, DO NOT include the warning message.

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  The "Kill Switch" Logic
&lt;/h3&gt;

&lt;p&gt;LLMs are chatty. To make an LLM compatible with a binary CI/CD environment (Pass/Fail), we need to force it to output a specific "signal" string when things go wrong.&lt;/p&gt;

&lt;p&gt;In our prompt, we give it this explicit instruction:&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="p"&gt;7.&lt;/span&gt; Critical Vulnerability Warning
&lt;span class="p"&gt;-&lt;/span&gt; Review all CRITICAL severity findings.
&lt;span class="p"&gt;-&lt;/span&gt; Filter out any findings that are located in "Intentional Vulnerabilities" paths (e.g., /legacy-vibe).
&lt;span class="p"&gt;-&lt;/span&gt; If there are any REMAINING Critical vulnerabilities:
&lt;span class="p"&gt;  1.&lt;/span&gt; List them briefly.
&lt;span class="p"&gt;  2.&lt;/span&gt; Include exactly this message at the end of the report:

THIS ASSESSMENT CONTAINS A CRITICAL VULNERABILITY
&lt;span class="p"&gt;
-&lt;/span&gt; Do not adapt or change this message in any way.
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that string appears in the output, our pipeline dies. If it doesn't, we proceed. This turns natural language into a boolean check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: The GitHub Action Workflow
&lt;/h2&gt;

&lt;p&gt;Here is the full implementation. We use &lt;code&gt;actions/setup-node&lt;/code&gt; to install the Copilot CLI, pass it the repository context, and capture the output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisite:&lt;/strong&gt; You must create a fine-grained Personal Access Token (PAT) with &lt;code&gt;Copilot Requests: Read&lt;/code&gt; permissions and add it to your repo secrets as &lt;code&gt;COPILOT_GITHUB_TOKEN&lt;/code&gt;.&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Security Agent Workflow&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;main"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;security-assessment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repository&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&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;Setup Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22&lt;/span&gt;

      &lt;span class="c1"&gt;# 1. Install the Intelligence&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;Install GitHub Copilot CLI&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;npm i -g @github/copilot&lt;/span&gt;

      &lt;span class="c1"&gt;# 2. Run the Agent&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;Run Security Agent via Copilot CLI&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;COPILOT_GITHUB_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.COPILOT_GITHUB_TOKEN }}&lt;/span&gt;
          &lt;span class="na"&gt;GITHUB_REPOSITORY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.repository }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;set -euo pipefail&lt;/span&gt;

          &lt;span class="s"&gt;# Construct the Prompt&lt;/span&gt;
          &lt;span class="s"&gt;# We combine the System Prompt (Agent definition) with Dynamic Context&lt;/span&gt;
          &lt;span class="s"&gt;AGENT_PROMPT=$(cat .github/agents/security-reporter.agent.md)&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT="$AGENT_PROMPT"&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$'\n\nContext:\n'&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+="- Repository: $GITHUB_REPOSITORY"&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$'\n\nTask:\n'&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$"\n- Execute the instructions on the full codebase"&lt;/span&gt;
          &lt;span class="s"&gt;PROMPT+=$'\n- Generate the security report at /security-reports/security-assessment-report.md'&lt;/span&gt;

          &lt;span class="s"&gt;# Execute Copilot&lt;/span&gt;
          &lt;span class="s"&gt;# We use &amp;lt; /dev/null to prevent the CLI from waiting for interactive input&lt;/span&gt;
          &lt;span class="s"&gt;copilot --prompt "$PROMPT" --allow-all-tools --allow-all-paths &amp;lt; /dev/null&lt;/span&gt;

      &lt;span class="c1"&gt;# 3. Save the Report (Artifacts are forever!)&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;Upload security report artifact&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always()&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/upload-artifact@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&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;security-assessment-report-${{ github.run_id }}&lt;/span&gt;
          &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;security-reports/security-assessment-report.md&lt;/span&gt;
          &lt;span class="na"&gt;retention-days&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;

      &lt;span class="c1"&gt;# 4. The Logic Check (The "Smart Fail")&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check for critical vulnerabilities&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always()&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;set -euo pipefail&lt;/span&gt;
          &lt;span class="s"&gt;REPORT_PATH="security-reports/security-assessment-report.md"&lt;/span&gt;

          &lt;span class="s"&gt;if [ ! -f "$REPORT_PATH" ]; then&lt;/span&gt;
            &lt;span class="s"&gt;echo "No report found. Something went wrong."&lt;/span&gt;
            &lt;span class="s"&gt;exit 1&lt;/span&gt;
          &lt;span class="s"&gt;fi&lt;/span&gt;

          &lt;span class="s"&gt;# The Grep Trap: Looking for the Kill Switch&lt;/span&gt;
          &lt;span class="s"&gt;if grep -q "THIS ASSESSMENT CONTAINS A CRITICAL VULNERABILITY" "$REPORT_PATH"; then&lt;/span&gt;
            &lt;span class="s"&gt;echo "❌ CRITICAL VULNERABILITY DETECTED - Workflow failed"&lt;/span&gt;
            &lt;span class="s"&gt;echo "The security assessment found critical vulnerabilities that must be addressed."&lt;/span&gt;
            &lt;span class="s"&gt;exit 1 # This breaks the build!&lt;/span&gt;
          &lt;span class="s"&gt;else&lt;/span&gt;
            &lt;span class="s"&gt;echo "✅ No critical vulnerabilities detected"&lt;/span&gt;
          &lt;span class="s"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The "Aha!" Moment: Watching it Fail
&lt;/h2&gt;

&lt;p&gt;In my demo repo (&lt;a href="https://github.com/VeVarunSharma/contoso-vibe-engineering" rel="noopener noreferrer"&gt;which you can find here&lt;/a&gt;), I have an intentionally vulnerable file &lt;code&gt;apps/contoso-web-app/app/api/legacy-vibe/route.ts&lt;/code&gt; containing a raw SQL query (SQL Injection).&lt;/p&gt;

&lt;p&gt;When the action runs, the Agent:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Scans the file.&lt;/li&gt;
&lt;li&gt; Identifies &lt;code&gt;db.query("SELECT * FROM users WHERE id = " + id)&lt;/code&gt; as a &lt;strong&gt;Critical Risk&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Writes the report.&lt;/li&gt;
&lt;li&gt; Appends &lt;code&gt;THIS ASSESSMENT CONTAINS A CRITICAL VULNERABILITY&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The final step of the GitHub Action sees that string and exits with code &lt;code&gt;1&lt;/code&gt;. The PR is blocked.&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%2Flytxg9jsh3ofbb1q6644.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%2Flytxg9jsh3ofbb1q6644.png" alt="Security-reporter-agent-failing" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the summarized report from the Security Reporter Agent right in the Github Action.&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%2Fwdprfyhxy04l6439r4zi.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%2Fwdprfyhxy04l6439r4zi.png" alt="detailed-report" width="800" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Expanding the Horizon: Other Use Cases
&lt;/h2&gt;

&lt;p&gt;Once you have this "Agent Runner" pattern established, you can apply it to almost any qualitative check.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The "Acceptance Criteria" Guard
&lt;/h3&gt;

&lt;p&gt;Imagine a workflow that reads your PR description and the linked Jira ticket/Issue.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Prompt:&lt;/strong&gt; "Compare the code changes against the acceptance criteria in the Issue. If the code misses a criterion, output &lt;code&gt;MISSING_REQUIREMENTS&lt;/code&gt;."&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Benefit:&lt;/strong&gt; Prevents developers from merging code that works technically but misses the product goal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. The Documentation Enforcer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Prompt:&lt;/strong&gt; "Analyze the changes in &lt;code&gt;src/&lt;/code&gt;. Check if &lt;code&gt;README.md&lt;/code&gt; or &lt;code&gt;docs/&lt;/code&gt; have been updated to reflect these changes. If new features are added without docs, output &lt;code&gt;MISSING_DOCS&lt;/code&gt;."&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Benefit:&lt;/strong&gt; Keeps your documentation from drifting away from reality.&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%2Fzvx4pn6xx9ijekmdzr03.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%2Fzvx4pn6xx9ijekmdzr03.png" alt="dev-wow-meme" width="586" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Reality Check: Pros vs. Cons
&lt;/h2&gt;

&lt;p&gt;This is bleeding-edge territory ("Agentic DevOps"). It is powerful, but you must know the trade-offs.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ The Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Contextual Understanding:&lt;/strong&gt; Unlike a regex search for &lt;code&gt;password =&lt;/code&gt;, an Agent understands that &lt;code&gt;const apiKey = process.env.KEY&lt;/code&gt; is safe, but &lt;code&gt;const apiKey = "12345"&lt;/code&gt; is not.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Reduced Review Fatigue:&lt;/strong&gt; It handles the tedious "first pass" of a code review, letting humans focus on architecture and complexity.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Educational:&lt;/strong&gt; The generated reports explain &lt;em&gt;why&lt;/em&gt; something is wrong, teaching junior devs as they commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❌ The Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Non-Determinism:&lt;/strong&gt; LLMs are probabilistic. Occasionally, the Agent might miss something it caught yesterday, or flag a false positive. You need mechanisms (like the "Intentional Vulnerabilities" filter in my prompt) to handle this.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Latency &amp;amp; Cost:&lt;/strong&gt; A full repo scan via LLM takes significantly longer than a linter (minutes vs seconds). This is best used on PRs, not on every local commit.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Hallucinations:&lt;/strong&gt; The Agent might claim a library is deprecated when it isn't. Human oversight is still required to verify the failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&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.amazonaws.com%2Fuploads%2Farticles%2Fg6vo4myuemryrgxhj9eo.jpeg" 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%2Fg6vo4myuemryrgxhj9eo.jpeg" alt="cover-image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are entering an era where CI/CD pipelines don't just compile code - they &lt;strong&gt;understand&lt;/strong&gt; it.&lt;/p&gt;

&lt;p&gt;By using the GitHub Copilot CLI in your Actions, you can create a layer of defense that thinks like a senior engineer but runs automatically like a unit test. Start with a Security Agent, refine your prompts, and see what else you can automate.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I’m Ve Sharma, a Solution Engineer at Microsoft focusing on Cloud &amp;amp; AI working on GitHub Copilot. I help developers become AI-native developers and optimize the SDLC for teams. I also make great memes. Find me on &lt;a href="https://www.linkedin.com/in/vevarunsharma" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or &lt;a href="https://github.com/VeVarunSharma" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>cicd</category>
      <category>githubcopilot</category>
      <category>ai</category>
    </item>
    <item>
      <title>Vibe Coding is Technical Debt. Vibe Engineering is the Fix</title>
      <dc:creator>Ve Sharma</dc:creator>
      <pubDate>Mon, 01 Dec 2025 21:09:28 +0000</pubDate>
      <link>https://forem.com/vevarunsharma/vibe-coding-is-technical-debt-vibe-engineering-is-the-fix-5a8j</link>
      <guid>https://forem.com/vevarunsharma/vibe-coding-is-technical-debt-vibe-engineering-is-the-fix-5a8j</guid>
      <description>&lt;h3&gt;
  
  
  TL;DR for the Busy Dev
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Vibe Coding&lt;/strong&gt; is "Single Player Mode": Prompting based on intuition, pasting code, and moving fast. It’s great for POCs but creates "Context Amnesia" and security risks in production.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Vibe Engineering&lt;/strong&gt; is "Multiplayer Mode": Architecting the constraints, rules, and agents to produce reliable software at scale.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Fix:&lt;/strong&gt; Move context from your head to the Repo. Use &lt;strong&gt;Context Engineering Primitives&lt;/strong&gt; (Instructions, Prompts, Agents) to enforce standards.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Result:&lt;/strong&gt; A workflow where the prompt remains the same, but the output shifts from "insecure" to "production-ready" automatically.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The "Vibe" Shift
&lt;/h2&gt;

&lt;p&gt;We’ve all been there. You have a Lo-Fi playlist on, a fresh coffee, and an LLM chat window open. You ask for a React component, you paste it, it works.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;Vibe Coding&lt;/strong&gt;. The strategy is simple: &lt;em&gt;"Prompt, Paste, and Pray."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At my last company (YGG), we Vibe Coded our way to an MVP at breakneck speed and kept up with major business pivots that required constant rework. It felt like magic and we got it down 4x faster with less devs saving us 7 figures of costs. But when we prepared for launch, we hit a wall that "vibes" couldn't fix.&lt;br&gt;
We discovered that vibe coding can actually be vulnerability-as-a-service.&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%2F4uevynrojiqr4of6jyw7.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%2F4uevynrojiqr4of6jyw7.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We had an external security audit, and the report came back: &lt;strong&gt;163 pages of vulnerabilities&lt;/strong&gt;, including 15 rated Severe. Too name a few issues, we had SQL injection risks, SSRF threat vectors, and inconsistent authentication patterns.&lt;/p&gt;

&lt;p&gt;The diagnosis wasn't that the AI was "bad." The diagnosis was &lt;strong&gt;Context Amnesia&lt;/strong&gt; and discovering that vibe coding can also be vulnerability-as-a-service. We were prompting in a chat window that didn't know our security protocols, didn't know our auth patterns, and didn't know our infrastructure rules.&lt;/p&gt;

&lt;p&gt;That is when we shifted to &lt;strong&gt;Vibe Engineering&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Result?
&lt;/h3&gt;

&lt;p&gt;By applying these methods, we didn't just fix the bugs. We shipped the product on time. We addressed every single High and Severe vulnerability before launch, and in our subsequent sprints, our security ticket volume dropped significantly compared to our "Vibe Coding" days.&lt;/p&gt;
&lt;h2&gt;
  
  
  Defining the Terms
&lt;/h2&gt;

&lt;p&gt;To fix the problem, we first have to define the methodology. What exactly is the difference between just using AI and &lt;em&gt;engineering&lt;/em&gt; with AI?&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Vibe Coding
&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.amazonaws.com%2Fuploads%2Farticles%2Fvc76rsecl1y2r4l0febv.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%2Fvc76rsecl1y2r4l0febv.png" alt="vibe-coding-meme" width="716" height="713"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; The practice of writing software using natural language, intuition, and heavy reliance on AI "vibes" rather than syntax.&lt;br&gt;
&lt;em&gt;E.g: "It looks correct, so it is correct."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Strategy:&lt;/strong&gt; "Prompt, Paste, and Pray."&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Vibe:&lt;/strong&gt; Fast, magical, and chaotic.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Trap: Single Player Mode.&lt;/strong&gt; It relies entirely on &lt;em&gt;your&lt;/em&gt; mental context. If you forget to tell the AI to secure the endpoint, it won't.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2. Vibe Engineering
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; The discipline of architecting context, constraints, and agents to produce reliable software at scale.&lt;br&gt;
&lt;em&gt;E.g: "Trust the Agent, but Verify the Spec."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Strategy:&lt;/strong&gt; "Plan, Orchestrate, and Verify."&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Vibe:&lt;/strong&gt; Disciplined, context-aware, and consistent.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Upgrade: Multiplayer Mode.&lt;/strong&gt; It follows the &lt;em&gt;team's&lt;/em&gt; rules and the &lt;em&gt;repo's&lt;/em&gt; context, regardless of which developer is prompting.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Comparison: Coding vs. Engineering
&lt;/h2&gt;

&lt;p&gt;Here is the breakdown of how the workflow shifts when you move from individual usage to team-based orchestration.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Vibe Coding (Individual)&lt;/th&gt;
&lt;th&gt;Vibe Engineering (Team/Agent)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;The Human Role&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The Typist / Prompter&lt;/td&gt;
&lt;td&gt;The Architect / Orchestrator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;The Context&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Whatever is in your chat window&lt;/td&gt;
&lt;td&gt;The entire Repo + &lt;code&gt;*.agents.md&lt;/code&gt;, + other .md ruleset files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;The Quality Check&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;"Does it run?" (Eye test)&lt;/td&gt;
&lt;td&gt;"Does it pass the test suite?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;The Danger&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Breaking Production / Security&lt;/td&gt;
&lt;td&gt;Over-engineering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;The Tooling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Chatbots &amp;amp; Tab-Complete&lt;/td&gt;
&lt;td&gt;Agents, Plan Mode, &amp;amp; MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  It’s Not a Boolean, It’s a Spectrum
&lt;/h2&gt;

&lt;p&gt;Before we dive into the fix, let's be clear: &lt;strong&gt;Vibe Coding isn't "wrong."&lt;/strong&gt; It’s a tool.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Vibe Coding (0-60% Maturity):&lt;/strong&gt; Excellent for prototyping, hackathons, and exploring new APIs. If you need to test an idea in 30 minutes, Vibe Code it.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Vibe Engineering (60-100% Maturity):&lt;/strong&gt; Critical for production, teams, and long-term maintenance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The danger lies in staying in "Vibe Mode" when you move to production. Conversely, you don't want to &lt;strong&gt;Over-Engineer&lt;/strong&gt; a weekend project with complex agent rules. It’s a gradient, and knowing when to switch gears is the skill of the future AI-native developer.&lt;/p&gt;
&lt;h2&gt;
  
  
  Context Engineering Primitives
&lt;/h2&gt;

&lt;p&gt;Vibe Engineering relies on codifying your team's "vibes" into the repository. At GitHub &amp;amp; Microsoft, we call these &lt;strong&gt;Context Engineering Primitives&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;File Pattern&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom Instructions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*.instructions.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Rules of Engagement.&lt;/strong&gt; Always-on guidelines that influence all interactions.&lt;/td&gt;
&lt;td&gt;1. Coding Standards (No &lt;code&gt;any&lt;/code&gt; types)&lt;br&gt;2. Security Rules (No raw SQL)&lt;br&gt;3. Tech Stack (Always use Tailwind)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reusable Prompts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*.prompts.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Executable Commands.&lt;/strong&gt; Specific tasks you run frequently.&lt;/td&gt;
&lt;td&gt;1. Generating boilerplate components&lt;br&gt;2. Writing Unit Tests&lt;br&gt;3. Creating Atomic Commits&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;*.agents.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Personas &amp;amp; Workflows.&lt;/strong&gt; Specialized contexts with specific tools.&lt;/td&gt;
&lt;td&gt;1. Security Review Agent&lt;br&gt;2. Terraform/SRE Agent&lt;br&gt;3. Migration Agent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Context Engineering Primitives in a Repo
&lt;/h3&gt;

&lt;p&gt;Here's what these primitives look like in an actual repo:&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%2Fr2o9llz5syuz38pnpcj3.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%2Fr2o9llz5syuz38pnpcj3.png" alt="context-eng-primitives" width="322" height="401"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Real World Example 1: The App Layer (Next.js)
&lt;/h2&gt;

&lt;p&gt;Let's look at how "Vibe Coding" vs. "Vibe Engineering" handles the exact same prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The User Prompt:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Write a quick endpoint to fetch user data by ID."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  ❌ Scenario A: Vibe Coding (No Context)
&lt;/h3&gt;

&lt;p&gt;Without instructions, the AI optimizes for speed. It assumes you just want the data &lt;em&gt;now&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/app/api/legacy-vibe/route.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;searchParams&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;searchParams&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 🚩 RISK 1: SQL Injection vulnerability via template literal&lt;/span&gt;
  &lt;span class="c1"&gt;// 🚩 RISK 2: No input validation (Zod is missing)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`SELECT * FROM users WHERE id = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

  &lt;span class="c1"&gt;// 🚩 RISK 3: Returning full object including password_hash and salt&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ Scenario B: Vibe Engineering (With &lt;code&gt;agents.md&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;We add a &lt;code&gt;.github/agents/security.agent.md&lt;/code&gt; file to the repo with non-negotiables: &lt;em&gt;1. Always use ORM methods. 2. Validate inputs with Zod. 3. Never return sensitive fields.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here's what the agent file looks like (it's 3x longer than what you see here):&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%2Fgzv1xbimroltbay9fwtq.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%2Fgzv1xbimroltbay9fwtq.png" alt="agent-file" width="800" height="772"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now here's the updated code running that same initial user prompt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/app/api/secure-vibe/route.ts&lt;/span&gt;
&lt;span class="c1"&gt;// Context: .github/copilot-instructions.md active&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ SUCCESS 1: Zod Schema for validation&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;QuerySchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;searchParams&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// ✅ SUCCESS 2: Validate input&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;QuerySchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;safeParse&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;searchParams&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// ✅ SUCCESS 3: Use ORM method (No raw SQL)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// ✅ SUCCESS 4: Return only safe fields (DTO)&lt;/span&gt;
    &lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Real World Example 2: The Infrastructure Layer (Terraform)
&lt;/h2&gt;

&lt;p&gt;This is even more critical in Cloud Ops. A "Vibe Coded" infrastructure often leads to public buckets and leaked keys.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The User Prompt:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Write Terraform for an Azure Function to process payments."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  ❌ Scenario A: Vibe Coding (The "It Works" Trap)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"azurerm_linux_function_app"&lt;/span&gt; &lt;span class="s2"&gt;"payment_api"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vibe-payment-api"&lt;/span&gt;
  &lt;span class="nx"&gt;location&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"East US"&lt;/span&gt;

  &lt;span class="c1"&gt;# 🚩 MISTAKE 1: Hardcoded Secrets (The Cardinal Sin)&lt;/span&gt;
  &lt;span class="nx"&gt;app_settings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"STRIPE_API_KEY"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sk_live_12345_DONOTCOMMIT"&lt;/span&gt; 
    &lt;span class="s2"&gt;"DB_CONN"&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Server=tcp:db.windows.net;Pwd=Password123!"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;site_config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;# 🚩 MISTAKE 2: Public &amp;amp; Insecure&lt;/span&gt;
    &lt;span class="nx"&gt;http2_enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="nx"&gt;minimum_tls_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.0"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;# 🚩 MISTAKE 3: Governance (Missing tags)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ Scenario B: Vibe Engineering (With &lt;code&gt;terraform.agent.md&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;We use a &lt;strong&gt;Terraform Agent&lt;/strong&gt; context file that enforces: "Always use Key Vault references" and "Enforce Managed Identity."&lt;/p&gt;

&lt;p&gt;Here's what the agent file looks like:&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%2Fqfo2o0ujf2snsjnr1cml.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%2Fqfo2o0ujf2snsjnr1cml.png" alt="agent-file-eng" width="800" height="619"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now here's the updated code, using that same prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"azurerm_linux_function_app"&lt;/span&gt; &lt;span class="s2"&gt;"payment_api"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"secure-payment-api"&lt;/span&gt;
  &lt;span class="nx"&gt;location&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"East US"&lt;/span&gt;

  &lt;span class="c1"&gt;# ✅ SUCCESS 1: Managed Identity (Identity as Perimeter)&lt;/span&gt;
  &lt;span class="nx"&gt;identity&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"SystemAssigned"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;# ✅ SUCCESS 2: Secrets via Key Vault References&lt;/span&gt;
  &lt;span class="nx"&gt;app_settings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"STRIPE_API_KEY"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.stripe.id})"&lt;/span&gt;
    &lt;span class="s2"&gt;"DB_CONN"&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.db.id})"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;site_config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;# ✅ SUCCESS 3: Modern Security Standards&lt;/span&gt;
    &lt;span class="nx"&gt;http2_enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="nx"&gt;minimum_tls_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.2"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;# ✅ SUCCESS 4: FinOps Happy + compliance success&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;CostCenter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Payments-Team"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Enterprise Win: True "Shift Left" Security
&lt;/h2&gt;

&lt;p&gt;For Enterprise teams, this methodology solves a massive headache: &lt;strong&gt;The Shift Left.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Usually, "Shift Left" means catching security issues in the CI/CD pipeline or during a Pull Request review. While better than fixing it in production, it still creates friction and rework.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vibe Engineering shifts security all the way to the Prompt.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By Codifying your constraints (e.g., "Always use Managed Identity") into the Repo Context:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Prevention &amp;gt; Detection:&lt;/strong&gt; You aren't catching a bad pattern in a scan; you are preventing the AI from suggesting it in the first place.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Velocity:&lt;/strong&gt; Developers don't have to rewrite code after a failed pipeline run.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Governance:&lt;/strong&gt; You ensure that every junior developer (and every AI agent) defaults to your organization's architectural standards without needing to memorize the wiki.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Workflow: From Vulnerability Github Issue to Merged PR
&lt;/h2&gt;

&lt;p&gt;How does this look in practice when fighting a real security fire? Here is an actual workflow to fix an SSRF vulnerability using a security Agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The Vulnerability:&lt;/strong&gt;&lt;br&gt;
We identified a CVE in our Next.js middleware handling. It needed a surgical fix.&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%2Fr8lzgfqbtsizohecl0wr.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%2Fr8lzgfqbtsizohecl0wr.png" alt="issue-image" width="800" height="647"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Assigning the Agent:&lt;/strong&gt;&lt;br&gt;
Instead of pulling a developer off their sprint, I opened a GitHub Issue and assigned it to our custom &lt;code&gt;@security-agent&lt;/code&gt; (which is configured to focus solely on vulnerabilities).&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%2Fv6z5tem13zvjy8tioq98.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%2Fv6z5tem13zvjy8tioq98.png" alt="assigning-the-agent" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Orchestration &amp;amp; Execution:&lt;/strong&gt;&lt;br&gt;
The agent analyzed the repo, found the vulnerable middleware pattern, and proposed a fix. It didn't just guess - it traced the data flow.&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%2Fy3o57sztvt1e2pj7rm3a.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%2Fy3o57sztvt1e2pj7rm3a.png" alt="agent-execution" width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Verification:&lt;/strong&gt;&lt;br&gt;
The agent ran the linting rules and ensured the fix didn't break existing routing, along with running CodeQL. As well as a security impact report!&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%2Fnx8s3powgntk4zptmt2n.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%2Fnx8s3powgntk4zptmt2n.png" alt="agent-verification" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. The Merge:&lt;/strong&gt;&lt;br&gt;
I reviewed the PR. Because the agent followed our &lt;code&gt;copilot-instructions.md&lt;/code&gt; the code style matched ours exactly. The &lt;code&gt;security.agent.md&lt;/code&gt; ensured all other security best practices specific to our repo meet our standards. I clicked merge.&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%2F2q30vwnzcd20k42jh0ai.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%2F2q30vwnzcd20k42jh0ai.png" alt="agent-merge" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Success!&lt;/p&gt;

&lt;h2&gt;
  
  
  Entering Agent HQ: Orchestration at Scale
&lt;/h2&gt;

&lt;p&gt;We are moving beyond simple chat. We are entering the era of &lt;strong&gt;Agent Orchestration&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%2Fzs2pbkudflhiqvumsflk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs2pbkudflhiqvumsflk.jpg" alt="ghu-agent-hq" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At GitHub Universe, we announced &lt;strong&gt;Agent HQ&lt;/strong&gt;. This turns GitHub into an open ecosystem where you can choose the right model for the specific job and a centralized agent orchestration platform.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Need complex architectural reasoning? Route the agent to &lt;strong&gt;Claude 3.5 Sonnet&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Need massive context analysis? Route to &lt;strong&gt;Gemini&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Need fast execution? Route to &lt;strong&gt;OpenAI&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't just prompt a chatbot anymore -  you act as the &lt;strong&gt;General Contractor&lt;/strong&gt;, hiring the right specialized agent for the right task.&lt;/p&gt;

&lt;p&gt;This is already being done at scale at Github itself!&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%2Fsznj1qujn9r3807518sm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsznj1qujn9r3807518sm.jpg" alt="ghu-agent-commmiter" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&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.amazonaws.com%2Fuploads%2Farticles%2Fh2qr6ihl2g3z6umg2ewo.jpeg" 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%2Fh2qr6ihl2g3z6umg2ewo.jpeg" alt="vibe-code-vibe-eng-comparison" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  To start Vibe Engineering tomorrow:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Avoid Single Player Mode:&lt;/strong&gt; Don't rely on your mental context.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Codify Your Vibes:&lt;/strong&gt; Create a root &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; file today.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leverage Context Engineering Primitives:&lt;/strong&gt; use &lt;code&gt;.*.agents.md&lt;/code&gt;,  &lt;code&gt;.*.instructions.md&lt;/code&gt;, &lt;code&gt;.*.prompts.md&lt;/code&gt; files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orchestrate:&lt;/strong&gt; Don't just generate code—&lt;strong&gt;Engineer the System&lt;/strong&gt; that generates the code. Use Agents to support this system.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vibe coding is fun for hackathons. Vibe Engineering is for production.&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%2Fa5k7ukf6u76w54wasffw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa5k7ukf6u76w54wasffw.jpg" alt="last-meme-whoosh" width="636" height="392"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;You can find the source code for this article here too:&lt;br&gt;
&lt;a href="https://github.com/VeVarunSharma/contoso-vibe-engineering" rel="noopener noreferrer"&gt;https://github.com/VeVarunSharma/contoso-vibe-engineering&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I’m Ve Sharma, a Solution Engineer at Microsoft focusing on Cloud &amp;amp; AI working on Github Copilot. I help developers become AI-native developers and optimize the SDLC for teams. I also make great memes. Find me on &lt;a href="https://www.linkedin.com/in/vevarunsharma" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or &lt;a href="https://github.com/VeVarunSharma" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>githubcopilot</category>
      <category>github</category>
      <category>vibecoding</category>
      <category>agents</category>
    </item>
    <item>
      <title>Architecting for Speed &amp; Safety: How We 2x'd Dev Velocity with ts-rest and Next.js API (and supercharged our AI copilot)</title>
      <dc:creator>Ve Sharma</dc:creator>
      <pubDate>Mon, 17 Nov 2025 16:31:46 +0000</pubDate>
      <link>https://forem.com/vevarunsharma/architecting-for-speed-safety-how-we-2xd-dev-velocity-with-ts-rest-and-nextjs-api-and-56nb</link>
      <guid>https://forem.com/vevarunsharma/architecting-for-speed-safety-how-we-2xd-dev-velocity-with-ts-rest-and-nextjs-api-and-56nb</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;The tl;dr for the Busy Dev&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Our initial backend was technically robust but slow to adapt to frequent business pivots, putting our V1 platform at risk. We needed a stack that prioritized both speed and safety.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Choice:&lt;/strong&gt; We picked &lt;strong&gt;&lt;a href="https://ts-rest.com/" rel="noopener noreferrer"&gt;ts-rest&lt;/a&gt; with Next.js&lt;/strong&gt; over the tighter coupling of (tRPC)[&lt;a href="https://trpc.io/" rel="noopener noreferrer"&gt;https://trpc.io/&lt;/a&gt;] and the isolation of a traditional REST API.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Why it Won:&lt;/strong&gt; It was the perfect "Goldilocks" solution for our team.

&lt;ul&gt;
&lt;li&gt;  ✅ &lt;strong&gt;End-to-end type safety&lt;/strong&gt; like tRPC, but with the flexibility of REST.&lt;/li&gt;
&lt;li&gt;  💻 &lt;strong&gt;Simplified DevEx:&lt;/strong&gt; The entire stack runs locally with a single command.&lt;/li&gt;
&lt;li&gt;  🤖 &lt;strong&gt;AI-Copilot Optimized:&lt;/strong&gt; Co-locating the frontend, backend, and a shared &lt;code&gt;DataContract.ts&lt;/code&gt; file provided perfect context for GitHub Copilot, boosting its accuracy with minimal setup.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;The Results:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  🚀 &lt;strong&gt;2x faster&lt;/strong&gt; feature development.&lt;/li&gt;
&lt;li&gt;  🐛 &lt;strong&gt;~30 fewer&lt;/strong&gt; frontend-to-backend bugs per week.&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;We hit our revised product launch deadline.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&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%2Fvuoxaq43ow0pkblmp2rv.png" alt="ts-rest-stack-v2" width="800" height="800"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  The Challenge: Navigating a Sea of Shifting Requirements
&lt;/h2&gt;

&lt;p&gt;I was managing a team working on a platform refactor, and we were stuck. A month and a half behind schedule, our progress was crippled by the complexity of our backend. We were building an MVP for a token launch, and our top priority was speed to market, not architectural perfection. The current stack was failing us.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our Previous Architecture: More Complexity than we needed
&lt;/h3&gt;

&lt;p&gt;Our original backend was fantastic from technical standards but a practical bottleneck after we had a major pivot of our business model (and anticipated more pivots). It was a custom-built, event-bus system using a Command Query Responsibility Segregation (CQRS) pattern with Domain-Driven Design. Housed in our monorepo as a separate service, it was deployed independently on GCP Cloud Run.&lt;/p&gt;

&lt;p&gt;This architecture was designed for maximum quality and correctness. However, this came at a steep price. A seemingly small change would trigger a cascade of required updates across 7-10 different layers of code. This rigid structure meant our motto became: &lt;strong&gt;Maximum quality, maximum standards, minimum speed.&lt;/strong&gt; For an MVP with a CEO who frequently pivoted on product requirements, this was untenable.&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%2Fh95vrxnq5qe4ehjbd5y5.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%2Fh95vrxnq5qe4ehjbd5y5.png" alt="previous-architecture" width="800" height="1294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Spike: Finding the Right Tool for the Job
&lt;/h2&gt;

&lt;p&gt;It was clear we needed a change. I initiated a technical spike to explore solutions that would dramatically increase our development velocity. I documented my findings in an Architectural Decision Records (ADR) document to carefully weigh the trade-offs of each option. &lt;br&gt;
Here's a look at what we considered:&lt;/p&gt;
&lt;h3&gt;
  
  
  Option 1: tRPC - Maximum Type Safety, Maximum Coupling
&lt;/h3&gt;

&lt;p&gt;tRPC offers incredible end-to-end type safety by sharing types directly between the client and server.&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%2Fu033tzgn5ynly5m9ppc6.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%2Fu033tzgn5ynly5m9ppc6.png" alt="option-1-trpc" width="800" height="911"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;End-to-end type safety:&lt;/strong&gt; Reduces the chances of runtime errors.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Simplified development:&lt;/strong&gt; No need for separate API type definitions.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Tight Coupling:&lt;/strong&gt; This was the biggest drawback. We wanted the option to scale out our backend independently in the future.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// backend/router.ts
import { initTRPC } from '@trpc/server';
const t = initTRPC.create();

export const appRouter = t.router({
  getUser: t.procedure.input(z.string()).query(({ input }) =&amp;gt; {
    return { id: input, name: 'John Doe' };
  }),
});

export type AppRouter = typeof appRouter;

// frontend/client.ts
import { createTRPCReact } from '@trpc/react-query';
import type { AppRouter } from '../backend/router';

export const trpc = createTRPCReact&amp;lt;AppRouter&amp;gt;();

// frontend/MyComponent.tsx
function MyComponent() {
  const userQuery = trpc.getUser.useQuery('1');
  return &amp;lt;div&amp;gt;{userQuery.data?.name}&amp;lt;/div&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Option 2: A Traditional REST API - Simple but Lacking
&lt;/h3&gt;

&lt;p&gt;We also considered a conventional REST API with an Express server. This would be decoupled but wouldn't solve our type safety issues and would add significant development friction between frontend and backend and add bloated boilerplate.&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%2Fsmx5cb2z4g3nrt4jt7m6.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%2Fsmx5cb2z4g3nrt4jt7m6.png" alt="option-2-rest-api-express" width="800" height="759"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Decoupled:&lt;/strong&gt; Clear separation between frontend and backend services.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;No inherent type safety:&lt;/strong&gt; Requires manual type definition, leading to bugs.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Development friction:&lt;/strong&gt; Requires managing two separate local development processes.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Scaling Complexity:&lt;/strong&gt; As the application grows, the amount of manual type definitions and API call boilerplate increases, making the codebase more brittle and harder to maintain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a quick look at a simple representation:&lt;/p&gt;

&lt;p&gt;Backend (Express):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// services/my-api/src/index.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PrismaClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;database&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// From monorepo package&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PrismaClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3001&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findUnique&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User not found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Frontend (React/Next.js):&lt;/p&gt;

&lt;p&gt;Notice the manual type definition and fetch logic. If the backend user shape changes, this code will break at runtime without any warning during development. This was happening very frequently for the team at the time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// components/UserProfile.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Manually defined type - must be kept in sync with the backend!&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserProfile&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`http://localhost:3001/users/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nf"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Option 3: ts-rest - The Goldilocks Solution
&lt;/h3&gt;

&lt;p&gt;Then I discovered ts-rest. It offered the best of both worlds: end-to-end type safety with the flexibility of REST. We implemented it directly within our Next.js app's &lt;code&gt;/api&lt;/code&gt; folder, which deploys as scalable serverless functions.&lt;/p&gt;

&lt;p&gt;The key was its "contract-first" approach. A single &lt;code&gt;DataContract.ts&lt;/code&gt; file defines the entire API surface, generating typed clients for the frontend and typed routers for the backend.&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%2Fn2q6aw2g9bjae4zd0ssa.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%2Fn2q6aw2g9bjae4zd0ssa.png" alt="option-3-ts-rest" width="800" height="650"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;End-to-end type safety:&lt;/strong&gt; The contract ensures consistency and catches bugs at compile time.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;RESTful by design:&lt;/strong&gt; Familiar, scalable, and built on web standards.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Semi-Decoupled:&lt;/strong&gt; Self-contained logic that could be easily migrated to a separate server later if needed.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Superb developer experience:&lt;/strong&gt; A single &lt;code&gt;pnpm run dev&lt;/code&gt; command for easy local end-to-end testing.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;AI-Copilot Friendly:&lt;/strong&gt; The co-located backend, frontend, and shared contract provide rich context for AI assistants, leading to more accurate code generation and bug detection.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Serverless Limitations:&lt;/strong&gt; The serverless nature of Next.js API routes is not ideal for long-running jobs. For those, a separate, dedicated microservice would still be required.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Some Architectural Coupling:&lt;/strong&gt; While significantly less coupled than tRPC, the backend logic still lives inside the frontend application's codebase.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Small Learning Curve &amp;amp; Setup:&lt;/strong&gt; It introduces another "mini-framework" layer to the stack that the team needs to learn and configure.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Smaller Community:&lt;/strong&gt; Its community is smaller compared to mainstream REST implementations or even the more popular tRPC, which can mean fewer resources and community-driven solutions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a glimpse of what the ts-rest contract and implementation look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// contract.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;initContract&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ts-rest/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;initContract&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;router&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/posts/:id`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;responses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&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="na"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Get a post by id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// pages/api/[...ts-rest].ts (Next.js server)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createNextRoute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createNextRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ts-rest/next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./contract&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postsRouter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createNextRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Implementation here&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;World&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;createNextRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;postsRouter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="c1"&gt;// lib/api-client.ts (React client)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;initQueryClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@ts-rest/react-query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./contract&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;initQueryClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3000/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;baseHeaders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// components/MyComponent.tsx&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Result: Shipping Faster and with Fewer Bugs
&lt;/h2&gt;

&lt;p&gt;The decision to go with ts-rest was a game-changer. The team began moving twice as fast on features that required backend integration. We saw a dramatic drop in bug tickets related to frontend-to-backend communication. Most importantly, we were able to hit our revised product launch deadline.&lt;/p&gt;

&lt;p&gt;The frontend developers, in particular, had loved this new setup. The ability to run and test the full application locally has been a huge boost to their productivity and confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Unforeseen Advantage: Supercharging Our AI Copilot
&lt;/h2&gt;

&lt;p&gt;A major pro we hadn't fully anticipated was how this architecture would empower our use of AI coding assistants like GitHub Copilot. We quickly realized a fundamental truth: &lt;strong&gt;Context is king in AI-driven software development.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By having the frontend, backend, and the shared &lt;code&gt;DataContract.ts&lt;/code&gt; file all living in a contextually adjacent space, we gave Copilot a complete, end-to-end picture of every feature. This had significant effects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;More Accurate Generation:&lt;/strong&gt; Copilot could reference the data contract and backend logic to generate client-side code that correctly fetched and handled data from the start.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Smarter Debugging:&lt;/strong&gt; The AI was far better at catching errors, flagging incompatible data types between the frontend and backend because it could see both sides of the conversation.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Holistic Refactoring:&lt;/strong&gt; Updating a type in the contract prompted Copilot to provide intelligent suggestions for updating the implementation on &lt;em&gt;both&lt;/em&gt; the client and the server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While you can configure Copilot to work effectively across separate repos, it often requires extra setup. The beauty of our approach was that this rich, end-to-end context was provided &lt;strong&gt;naturally and with zero additional configuration&lt;/strong&gt;, turning our AI assistant into a true force multiplier for every developer on the team.&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%2Fmtbizva6pl4wnyfsfc23.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%2Fmtbizva6pl4wnyfsfc23.png" alt="Dev-in-F1" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Final Takeaways: Why This Stack Was a Game-Changer&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For our specific needs—building an V1 of a platform quickly with rapidly changing requirements—the pros of ts-rest far outweighed the cons. The decision fundamentally improved our team's velocity and the quality of our product.&lt;/p&gt;

&lt;p&gt;Here’s a summary of our biggest wins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Massive Velocity Boost:&lt;/strong&gt; We started moving &lt;strong&gt;2x faster&lt;/strong&gt; on backend-dependent features. This wasn't just a small improvement; it was the key factor that allowed us to hit our critical MVP deadline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Drastic Bug Reduction:&lt;/strong&gt; The type-safe contract enforced by ts-rest virtually eliminated a whole class of common and frustrating frontend-to-backend integration errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A+ Developer Experience:&lt;/strong&gt; The ability to run and test the full application locally with a single &lt;code&gt;pnpm run dev&lt;/code&gt; command was a huge morale and productivity booster for the entire team.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AI as a Force Multiplier:&lt;/strong&gt; This was the surprise win. Our architecture provided the perfect context for GitHub Copilot &lt;em&gt;by default&lt;/em&gt;. It made the AI smarter at generating code, catching bugs, and refactoring across the stack, making every developer more efficient without any extra configuration.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While not a silver bullet for every project, combining ts-rest with Next.js gave us the ultimate trifecta for our platform V1: speed, safety, and a supercharged AI development workflow.&lt;/p&gt;

</description>
      <category>github</category>
      <category>tsrest</category>
      <category>webdev</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>So… what is GitHub Copilot’s "Raptor mini"and why should devs care?</title>
      <dc:creator>Ve Sharma</dc:creator>
      <pubDate>Tue, 11 Nov 2025 20:15:32 +0000</pubDate>
      <link>https://forem.com/vevarunsharma/so-what-is-github-copilots-raptor-miniand-why-should-devs-care-3n30</link>
      <guid>https://forem.com/vevarunsharma/so-what-is-github-copilots-raptor-miniand-why-should-devs-care-3n30</guid>
      <description>&lt;p&gt;GitHub quietly slipped a new model into Copilot called &lt;strong&gt;“Raptor mini (Preview)”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The changelog basically said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Raptor mini, a new experimental model, is now rolling out in GitHub Copilot to Pro, Pro+, and Free plans in Visual Studio Code… Rollout will be gradual.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;…which does &lt;strong&gt;not&lt;/strong&gt; tell us what it is, why it exists, or when you should pick it over the other models.&lt;/p&gt;

&lt;p&gt;So we did what devs do: we poked at the UI, looked at the supported-models table, and dug into the VS Code debug logs. And it turns out there’s enough there to form a pretty good picture of what Raptor mini actually is.&lt;/p&gt;

&lt;p&gt;This post is that picture.&lt;/p&gt;




&lt;h2&gt;
  
  
  TL;DR for the busy dev
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Raptor mini = an (OpenAI GPT-5-mini–family model fine-tuned by Microsoft/GitHub for Copilot.)[&lt;a href="https://gh.io/copilot-openai-fine-tuned-by-microsoft" rel="noopener noreferrer"&gt;https://gh.io/copilot-openai-fine-tuned-by-microsoft&lt;/a&gt;]&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;It’s &lt;strong&gt;served from GitHub’s Azure OpenAI tenant&lt;/strong&gt; (not you calling OpenAI directly).&lt;/li&gt;
&lt;li&gt;It has a &lt;strong&gt;surprisingly big context window (~264k)&lt;/strong&gt; and &lt;strong&gt;big output (~64k)&lt;/strong&gt; for something called “mini.”&lt;/li&gt;
&lt;li&gt;It already &lt;strong&gt;knows how to do Copilot things&lt;/strong&gt; (chat, ask, edit, agent) and was good at &lt;strong&gt;tool/MCP flows&lt;/strong&gt; in testing.&lt;/li&gt;
&lt;li&gt;You should try it for &lt;strong&gt;workspace-scale, repetitive, “apply this everywhere”&lt;/strong&gt; tasks inside VS Code.&lt;/li&gt;
&lt;li&gt;It looks like a &lt;strong&gt;stealth testbed&lt;/strong&gt; for a code-forward GPT-5-codex-mini that GitHub/Microsoft want real usage on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If that’s enough for you — activate it in your Github Copilot Models, and go open Copilot Chat in VS Code, pick &lt;strong&gt;“Raptor mini (Preview)”&lt;/strong&gt;, and try a real task.&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%2Ff8z9dk8cmevlfixmoeca.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%2Ff8z9dk8cmevlfixmoeca.png" alt="vs-code-copilot-models" width="400" height="884"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want the receipts, keep reading.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. What GitHub actually told us (the boring part)
&lt;/h2&gt;

&lt;p&gt;From the Copilot UI/docs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’s called &lt;strong&gt;Raptor mini (Preview)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It shows up in &lt;strong&gt;VS Code Copilot Chat&lt;/strong&gt; model picker.&lt;/li&gt;
&lt;li&gt;It’s labeled as &lt;strong&gt;“fine-tuned GPT-5 mini.”&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Docs say it’s &lt;strong&gt;deployed on GitHub-managed Azure OpenAI.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That alone says: GitHub took an OpenAI GPT-5-mini, ran their own fine-tuning/config, and is exposing it only through Copilot, not as a general-purpose public API.&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%2Fodkahmdh374ph61wm7fp.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%2Fodkahmdh374ph61wm7fp.png" alt="github-copilot-model-list" width="800" height="603"&gt;&lt;/a&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%2F74xyjm2v5jqg9vdlrkzn.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%2F74xyjm2v5jqg9vdlrkzn.png" alt="copilot-docs-description" width="800" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So far: ✅ real model, ✅ real preview, ❌ zero detail.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. What the debug logs tell us (the fun part)
&lt;/h2&gt;

&lt;p&gt;From the VS Code debug logs we can actually see the model object. It looked like this:&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="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;"billing"&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;"is_premium"&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;"multiplier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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;"capabilities"&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;"family"&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-mini"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"limits"&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;"max_context_window_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;264000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"max_output_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;64000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"max_prompt_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200000&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"max_prompt_image_size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3145728&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"max_prompt_images"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"supported_media_types"&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="s2"&gt;"image/jpeg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"image/png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"image/webp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"image/gif"&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="nl"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"model_capabilities"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"supports"&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;"parallel_tool_calls"&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;"streaming"&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;"structured_outputs"&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;"tool_calls"&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="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;"tokenizer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"o200k_base"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chat"&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;"oswe-vscode-prime"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"is_chat_default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"is_chat_fallback"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"model_picker_category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"versatile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"model_picker_enabled"&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;"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;"Raptor mini (Preview)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"policy"&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;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unconfigured"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"terms"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enable access to the latest Raptor mini model from Microsoft. [Learn more about how GitHub Copilot serves Raptor mini](https://gh.io/copilot-openai-fine-tuned-by-microsoft)."&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;"preview"&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;"supported_endpoints"&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="s2"&gt;"/chat/completions"&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="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;"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;"Azure OpenAI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"raptor-mini"&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;p&gt;A couple important takeaways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Family is &lt;code&gt;gpt-5-mini&lt;/code&gt;.&lt;/strong&gt; So we’re not dealing with an old GPT-4 derivative. Possibly gpt-5-codex-mini.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;264k context&lt;/strong&gt; is &lt;em&gt;large&lt;/em&gt; for a model GitHub calls “mini.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;64k output&lt;/strong&gt; means long edits, long summaries, long multi-file instructions are on the table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool calls + parallel tool calls&lt;/strong&gt; means it’s built to play nicely with Copilot’s “do stuff, not just talk” surface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vision: true&lt;/strong&gt; — you can hand it an image (1 image) and it won’t freak out.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s already more concrete than the public announcement.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. So… what is it really?
&lt;/h2&gt;

&lt;p&gt;A good working definition for your team:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Raptor mini is a Copilot-tuned GPT-5-mini (possibly codex mini) hosted by GitHub/Microsoft on Azure, sized and wired to do big, editor-style, multi-file tasks quickly, and to cooperate with Copilot tools/agents.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s it. Not magic, but very handy.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Why should devs care?
&lt;/h2&gt;

&lt;p&gt;Because this is one of the first times GitHub is letting us touch a &lt;strong&gt;GPT-5-family&lt;/strong&gt; model that is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Editor-first.&lt;/strong&gt; It actually behaves in the context of Copilot chat/ask/edit/agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context-heavy.&lt;/strong&gt; 200k+ prompt tokens means “I want you to look at a lot of stuff in this workspace” becomes realistic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action-friendly.&lt;/strong&gt; It was &lt;strong&gt;“using tools, skills, and MCPs amazingly and editing properly”&lt;/strong&gt; in testing — that’s exactly what you want from a Copilot model, not just a chatty assistant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast enough.&lt;/strong&gt; Even with “reasoning: high” you saw ~122 tokens/sec, which is fine for an IDE loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Probably the shape of future Copilot models.&lt;/strong&gt; This feels like GitHub/Microsoft collecting real-world data before shipping something more “stable” under a friendlier name.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In other words: &lt;strong&gt;this model is pointed at actual, boring, high-value dev tasks&lt;/strong&gt; — “rename this pattern everywhere,” “update docs across files,” “fix this class and regenerate the tests,” not just “explain this LeetCode.”&lt;/p&gt;




&lt;h2&gt;
  
  
  5. When to use Raptor mini vs. other models
&lt;/h2&gt;

&lt;p&gt;Here’s a practical way to tell your readers “use this one now”:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Use Raptor mini when…
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You’re in &lt;strong&gt;VS Code&lt;/strong&gt; and already using &lt;strong&gt;Copilot Chat/Ask/Edit/Agent&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You want to &lt;strong&gt;apply or explain changes across multiple files&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You want it to &lt;strong&gt;call MCP/tools&lt;/strong&gt; reliably.&lt;/li&gt;
&lt;li&gt;You pasted a &lt;strong&gt;long error / long diff / long file&lt;/strong&gt; and don’t want to get “too long” pushback.&lt;/li&gt;
&lt;li&gt;You care more about &lt;strong&gt;getting a correct edit&lt;/strong&gt; than getting a 1,000-word essay.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🟡 Maybe pick something else when…
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need &lt;strong&gt;extremely creative / longform / non-coding&lt;/strong&gt; output.&lt;/li&gt;
&lt;li&gt;You need a &lt;strong&gt;documented, versioned model card&lt;/strong&gt; (this is still preview).&lt;/li&gt;
&lt;li&gt;You don’t have it in your model picker yet (GitHub said rollout is gradual).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. How to try it right now
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Enable the Raptor Mini Model in Github Copilot settings (Copilot Pro+ tier needed)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open &lt;strong&gt;VS Code&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open &lt;strong&gt;GitHub Copilot Chat&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the &lt;strong&gt;model picker&lt;/strong&gt; at the top.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose &lt;strong&gt;“Raptor mini (Preview)”&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run a &lt;strong&gt;real&lt;/strong&gt; task, e.g.:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   I have the file that's open in the editor. Explain why this custom hook is rerendering so often, then propose the smallest fix, then apply the edit.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Scan the components in src/components and update every usage of &amp;lt;OldButton&amp;gt; to &amp;lt;NewButton variant="primary" /&amp;gt;. Show me the diff per file.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;If you want to nerd out, open &lt;strong&gt;Developer Tools&lt;/strong&gt; in VS Code and watch the network/model info — that’s where we saw the &lt;code&gt;oswe-vscode-prime&lt;/code&gt; / &lt;code&gt;raptor-mini&lt;/code&gt; bits.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  7. What we still don’t know (and should be honest about)
&lt;/h2&gt;

&lt;p&gt;This is a preview. That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub can &lt;strong&gt;change the underlying model&lt;/strong&gt; without telling us.&lt;/li&gt;
&lt;li&gt;We don’t have the &lt;strong&gt;full fine-tuning description&lt;/strong&gt; (what tasks, what data).&lt;/li&gt;
&lt;li&gt;We don’t have a &lt;strong&gt;stable latency/perf sheet&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Naming might change — GitHub has been shuffling Copilot models fairly often.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if you’re writing internal guidance for your team, phrase it as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Use Raptor mini in VS Code Copilot when it’s available, especially for long or tool-heavy edits. It’s experimental, so results may change.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8. A quick hypothesis (the hype part, but reasonable)
&lt;/h2&gt;

&lt;p&gt;This looks like GitHub/Microsoft dogfooding a code-forward GPT-5-mini in the safest place possible — Copilot inside VS Code — where they control the context, the tools, and the telemetry.&lt;/p&gt;

&lt;p&gt;That’s how you get real data on: “Can it handle 200k-token workspace prompts?”, “Does it call tools well?”, “Do developers accept the edits?” — all the things you can’t learn from a generic chat playground.&lt;/p&gt;

&lt;p&gt;So yeah, &lt;strong&gt;a little hype is justified&lt;/strong&gt; — not because the name is cool, but because this is how the next generation of Copilot models will actually get trained/tuned.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Closing
&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.amazonaws.com%2Fuploads%2Farticles%2Fhy4581gezzqyzexwd4p2.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%2Fhy4581gezzqyzexwd4p2.png" alt="gpt-5-mini-stealth-reveal" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub didn’t give us the story, so we had to reconstruct it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What it is:&lt;/strong&gt; Copilot-tuned GPT-5-mini (possibly codex mini) on Azure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it matters:&lt;/strong&gt; big context + good tool use = better real VS Code tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Who should try it:&lt;/strong&gt; anyone already living in Copilot that hits “this is too long” or “stop ignoring my workspace” walls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What to expect:&lt;/strong&gt; it’ll change — it’s a preview — but trying it now gives you better edits today &lt;em&gt;and&lt;/em&gt; better models tomorrow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’ve got it in your picker, give it a real job. Not “write a poem,” but “touch 12 files safely.”&lt;/p&gt;

&lt;p&gt;And if you don’t have it yet… GitHub said rollout is gradual, so check back. 😉&lt;/p&gt;

&lt;p&gt;I'd love to hear other developers thoughts on this and see what the community can further prove with this and how they're using Mini-Raptor.&lt;/p&gt;




</description>
      <category>github</category>
      <category>githubcopilot</category>
      <category>ai</category>
      <category>vscode</category>
    </item>
    <item>
      <title>I'm Going All-In on AI for Developers.</title>
      <dc:creator>Ve Sharma</dc:creator>
      <pubDate>Mon, 10 Nov 2025 21:21:31 +0000</pubDate>
      <link>https://forem.com/vevarunsharma/im-going-all-in-on-ai-for-developers-3i9p</link>
      <guid>https://forem.com/vevarunsharma/im-going-all-in-on-ai-for-developers-3i9p</guid>
      <description>&lt;p&gt;It feels like every developer is drinking from a firehose of AI information right now. We're seeing mind-blowing demos, new tools launching every week, and a mountain of buzzwords.&lt;/p&gt;

&lt;p&gt;As a developer myself, I've been watching this unfold with a mix of excitement and skepticism. It's easy to get caught up in the hype, but I keep coming back to one fundamental question:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How does this actually help us, the developers in the trenches, ship better code faster and with less friction?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We've all seen AI generate a perfect sorting algorithm. But what about untangling a messy legacy codebase? What about navigating the complex security and compliance demands of a large enterprise? How do we move from cool party tricks to indispensable tools for professional software development?&lt;/p&gt;

&lt;p&gt;I believe we're at a pivotal moment, and I've decided to go all-in on finding the answers.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Promise to You: The Mission
&lt;/h2&gt;

&lt;p&gt;I want to use this space to share everything I learn from the front lines of AI-powered software development. My goal is to cut through the noise and provide practical, honest insights you can actually use.&lt;/p&gt;

&lt;p&gt;You can expect me to write about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Advanced GitHub Copilot Workflows: We'll go way beyond autocomplete. I'm talking about using Copilot for effective refactoring, generating complex unit tests, and understanding unfamiliar codebases.&lt;/li&gt;
&lt;li&gt;The Reality of "Agentic DevOps": It's the new hot buzzword, but what does it mean? We'll demystify the term and look at what's possible today in automating the entire development lifecycle, from issue creation to secure deployment.&lt;/li&gt;
&lt;li&gt;AI-Powered DevSecOps: How can AI help us shift security even further left? I'll be exploring how tools like GitHub Advanced Security are getting smarter and how to leverage AI in helping us catch vulnerabilities before they ever leave the IDE.&lt;/li&gt;
&lt;li&gt;Lessons from the Enterprise: I'll be spending my days working with some of Canada's largest enterprise development teams. I plan to share non-confidential insights and common patterns on how large, complex organizations are actually adopting these tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  So, What's Changing?
&lt;/h3&gt;

&lt;p&gt;To make this my full-time focus, I'm incredibly excited to share that I've joined Microsoft as a Senior Solution Engineer on the Cloud &amp;amp; AI team focusing on Dev Tools.&lt;/p&gt;

&lt;p&gt;I'll be sitting right at the intersection of Microsoft and GitHub, focusing entirely on the developer tool stack. This role is a perfect opportunity to dive deep into the technology, work hands-on with enterprise developers, and contribute to the vision for the future of development. &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%2Fgv1q4agrz84hzak2yv55.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgv1q4agrz84hzak2yv55.jpg" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And I'm thrilled to be doing it from the Microsoft Vancouver office!&lt;/p&gt;

&lt;p&gt;I see this role less as a job and more as a license to learn in public and share that journey with all of you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building This Conversation Together
&lt;/h3&gt;

&lt;p&gt;This is where you come in. I don't want this to be a one-way street. I want to build a community around these topics.&lt;br&gt;
I have a question for you:&lt;/p&gt;

&lt;p&gt;What are your biggest questions, doubts, or even skepticisms about AI in your daily development workflow? What's working and what's not?&lt;/p&gt;

&lt;p&gt;Let me know in the comments below. What you're curious about will directly shape what I write about next. &lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>microsoft</category>
      <category>github</category>
    </item>
  </channel>
</rss>
