<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Invoke.dev]]></title><description><![CDATA[Exploring the intersection of Developer Experience and AI without the hype. ]]></description><link>https://read.invoke.dev</link><image><url>https://substackcdn.com/image/fetch/$s_!T0Ji!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67aa6b89-1133-4ca4-9f63-4faa9ece12ef_440x440.png</url><title>Invoke.dev</title><link>https://read.invoke.dev</link></image><generator>Substack</generator><lastBuildDate>Wed, 15 Apr 2026 07:54:47 GMT</lastBuildDate><atom:link href="https://read.invoke.dev/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Invoke.dev]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[invoke@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[invoke@substack.com]]></itunes:email><itunes:name><![CDATA[Alex Robinson]]></itunes:name></itunes:owner><itunes:author><![CDATA[Alex Robinson]]></itunes:author><googleplay:owner><![CDATA[invoke@substack.com]]></googleplay:owner><googleplay:email><![CDATA[invoke@substack.com]]></googleplay:email><googleplay:author><![CDATA[Alex Robinson]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[AI Mandates]]></title><description><![CDATA[AI mandates make honest feedback professionally dangerous, putting successful adoption at risk. What engineering leaders owe their teams when mandates arrive from above.]]></description><link>https://read.invoke.dev/p/ai-mandates</link><guid isPermaLink="false">https://read.invoke.dev/p/ai-mandates</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Tue, 07 Apr 2026 13:32:44 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e6341d5a-6b8a-4981-a56a-b4574a373618_1344x768.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>AI adoption metrics are improving inside organizations where honest feedback has become professionally dangerous. High usage numbers and favorable survey results are the predictable output of mandates tied to performance reviews. They tell you what people are willing to report, not what&#8217;s actually happening.</p><h2>Adoption That Can&#8217;t Be Questioned Isn&#8217;t Adoption</h2><p>AI mandates, formal requirements that engineers use specific tools, meet usage thresholds, or demonstrate AI integration in performance reviews, have become a standard corporate response to competitive pressure. Shopify, Duolingo, Coinbase, and Block are the names that made headlines, but the pattern runs far deeper. A <a href="https://hrtechedge.com/survey-finds-most-companies-now-require-employees-to-use-ai/?ref=invoke.dev">September 2025 survey</a> found 58% of companies now require some employees to use AI tools, with 24% mandating it across all roles.</p><p>The business case for these mandates relies on productivity numbers that don&#8217;t survive scrutiny. Vendor-funded studies report 55% faster task completion. The independent research lands differently. The <a href="https://dora.dev/research/2025/dora-report/?ref=invoke.dev">DORA 2025 report</a> analyzed telemetry from over 10,000 developers across 1,255 teams and found no significant correlation between AI adoption and organizational-level delivery outcomes. <a href="https://www.faros.ai/blog/ai-software-engineering?ref=invoke.dev">Faros AI found</a> that while individual developers completed 21% more tasks, PR review times increased 91% and PR sizes grew 154%. The bottleneck moved rather than disappeared.</p><p><a href="https://getdx.com/blog/ai-productivity-gains-are-10-percent-not-10x/?ref=invoke.dev">DX&#8217;s longitudinal study</a> across 400 companies found that AI usage increased by an average of 65% while PR throughput increased by just under 10%. That figure is consistent with what other independent research is finding as the realistic ceiling.</p><p>The gap between what mandates promise and what organizations experience is significant. What makes it worse is that the organizations least likely to discover this gap are the ones that have made honest feedback professionally dangerous.</p><h2>The Mechanism That Produces Silence</h2><p>When engineers raise concerns about AI adoption, specific things tend to happen. They get labeled as resistant to change. Their concerns get reframed as fear rather than technical judgment.</p><p>The most visible recent example is Block. Employees voiced concerns about AI mandates in a company-wide meeting. Within a month, <a href="https://www.cnn.com/2026/02/26/business/block-layoffs-ai-jack-dorsey?ref=invoke.dev">the company announced a 40% workforce reduction</a>. Jack Dorsey cited AI as the reason. Block&#8217;s stock rose 24%.</p><p>The lesson engineers draw from that sequence doesn&#8217;t need to be causally accurate to be real. Enough people observed the pattern for it to shape behavior. When speaking up about AI concerns produces visible professional consequences, people stop speaking up. Usage metrics improve while the underlying experience deteriorates. The organization goes blind to its own problems.</p><p>Companies that mandate AI and then blame it for layoffs are engaged in what researchers now call <a href="https://builtin.com/articles/ai-washing-layoffs?ref=invoke.dev">AI washing</a>. A <a href="https://builtin.com/articles/ai-washing-layoffs?ref=invoke.dev">Resume.org survey</a> found that 59% of hiring managers cite AI as the reason for cuts because it lands better with investors than admitting to financial pressure. It&#8217;s a better story than overhiring.</p><p>When AI is simultaneously mandated and the justification for headcount reductions, engineers are not being irrational when they treat questions about AI adoption as questions about their continued employment. They&#8217;re reading the room accurately.</p><h2>What Gets Lost</h2><p>The costs of silence-based adoption don&#8217;t show up in usage metrics.</p><p>The first cost is the diagnostic signal. DORA&#8217;s research is explicit: AI amplifies existing organizational strengths and weaknesses. Teams that can tell you where AI creates friction are the teams that could help you fix it. When those teams go quiet, the organizations most in need of course correction lose the feedback loops that would enable it. You keep optimizing a metric that stopped connecting to reality.</p><p>The second cost is the apprenticeship structure. <a href="https://arxiv.org/abs/2510.07435?ref=invoke.dev">Feng et al.</a>, in a peer-reviewed study of 442 developers, documented a shift that no productivity metric captures. Before mandate-driven adoption, junior engineers learned through pair programming, code reviews, and mentorship. After that, it shifted to what participants described as private copy-paste. Senior engineers became reviewers of AI output rather than mentors, developing human judgment. <a href="https://www.gartner.com/en/articles/ai-lock-in?ref=invoke.dev">Gartner projects</a> that by 2030, half of enterprises will face irreversible skill shortages in at least two critical roles because of unchecked automation. That projection is the long-horizon consequence of a short-horizon decision being made right now, in thousands of engineering organizations, without anyone measuring it.</p><p>The third cost is senior talent. The burnout study established that autonomy is the single strongest protective factor against AI-related burnout, stronger than learning resources and stronger than positive attitudes toward AI. When mandates remove autonomy, prescribe tools, require usage metrics, and tie compliance to performance reviews, the engineers with the most options respond first. They don&#8217;t complain. They leave. The organizations that notice this are measuring retention alongside adoption. Most are not.</p><h2>The Structural Problem</h2><p>Psychological safety is the belief that you won&#8217;t be punished for speaking up with questions, concerns, or mistakes. An <a href="https://www.technologyreview.com/2025/12/16/1125899/creating-psychological-safety-in-the-ai-era/?ref=invoke.dev">MIT Technology Review survey</a> found 83% of executives believe it measurably improves AI initiative success. That same survey found organizations often promote a &#8220;safe to experiment&#8221; message publicly while deeper undercurrents work against it.</p><p>The message and the mechanism are different things.</p><p>The mechanism is organizational design, not communication. It&#8217;s what happens to the engineers who speak up. It&#8217;s whether usage metrics are tied to performance reviews. It&#8217;s whether skeptics get engaged or reassigned. It&#8217;s whether the engineering leader who reports that adoption is struggling gets support or pressure. These are structural questions, and they have structural answers.</p><p>AI mandates also land on workforces that often already have a calibrated read on what happens to people who push back. Prior layoffs, return-to-office pressure, and performance friction have already taken a toll on psychological safety before AI tools enter the conversation. The mandate doesn&#8217;t arrive in a vacuum. It arrives in an organizational history, and engineers read it through that history.</p><h2>What Engineering Leaders Can Do</h2><p>The engineering leader&#8217;s position is specific: you receive mandates from above and absorb the consequences below. You didn&#8217;t design the context, but you have discretion within it. That discretion is where responsible adoption actually lives.</p><p>Separate adoption metrics from performance evaluation. Tying AI usage to performance reviews guarantees that usage data is socially constructed rather than organizationally informative. If engineers believe their job security depends on demonstrating usage, their reported usage tells you nothing about genuine integration. For most engineering leaders, this is a design choice within their direct authority.</p><p>Instrument the system rather than the people. Telemetry on PR sizes, review times, deployment frequency, and change failure rate tells you what&#8217;s actually happening without asking people to self-report under pressure. If AI adoption is improving the system, you&#8217;ll see it. If it&#8217;s creating bottlenecks, you&#8217;ll see those too. The frame shifts from &#8220;are people using the tool&#8221; to &#8220;is the tool working,&#8221; which is a more honest question. The <a href="https://invoke.dev/ai-assisted-code-reviews/">PR review bottleneck</a> is often the first place this shows up.</p><p>Protect the apprenticeship loop deliberately. Define which problem types junior engineers solve without AI during their development period. Require that the developer who submitted the AI-generated code explain it before it is merged. <a href="https://invoke.dev/the-critical-thinking-paradox/">Skill erosion</a> is not hypothetical. It follows a documented pattern when developers stop practicing the reasoning that builds expertise. These aren&#8217;t anti-AI policies. They&#8217;re skill resilience policies, and naming them that way matters for how the team receives them.</p><p>Name the pressure your team is under. Your team already knows the mandate came from above. They know you&#8217;re operating within constraints you didn&#8217;t design. Being explicit about the organizational context, while being clear about what you control within it. This builds trust, which is critical for an effective adoption.</p><h2>The Measure That Matters</h2><p>Usage rate is not a measure of successful adoption. It&#8217;s a measure of compliance.</p><p>The actual measure is whether the people doing the integration can tell you honestly where it&#8217;s working, where it&#8217;s not, and what it&#8217;s costing them, and whether that honesty changes anything. Right now, in most engineering organizations, it doesn&#8217;t. Changing that is harder than deploying a tool and more consequential than any adoption metric. It&#8217;s also the part of this problem that only engineering leaders can solve, because it lives inside the teams they run, not in the mandates they receive.</p>]]></content:encoded></item><item><title><![CDATA[Total Cost of Ownership]]></title><description><![CDATA[Planning for the Real Cost of AI in Engineering]]></description><link>https://read.invoke.dev/p/total-cost-of-ownership</link><guid isPermaLink="false">https://read.invoke.dev/p/total-cost-of-ownership</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Tue, 31 Mar 2026 11:51:55 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/c4cecdde-9e9e-4a52-b3ec-f29b1d07d465_1344x768.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Most ROI calculations for AI tooling share the same quiet flaw. They project productivity gains from research conducted on developers who use AI substantively every day, then price the investment at the tier where developers use it occasionally. The math looks compelling, but it isn&#8217;t realistic.</p><h1>Three Tiers</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!X7xx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!X7xx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png 424w, https://substackcdn.com/image/fetch/$s_!X7xx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png 848w, https://substackcdn.com/image/fetch/$s_!X7xx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png 1272w, https://substackcdn.com/image/fetch/$s_!X7xx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!X7xx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png" width="1080" height="607" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:607,&quot;width&quot;:1080,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:57999,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://read.invoke.dev/i/192674395?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!X7xx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png 424w, https://substackcdn.com/image/fetch/$s_!X7xx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png 848w, https://substackcdn.com/image/fetch/$s_!X7xx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png 1272w, https://substackcdn.com/image/fetch/$s_!X7xx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ad65f7c-0aa6-4761-a4f3-e12ee4ebc389_1080x607.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The AI coding tool market has sorted itself into three adoption tiers, each with different usage patterns and a different relationship to the productivity research teams cite when making the investment case.</p><p><strong>AI Tourists</strong> spend $10-20 per developer per month. Tourists use AI the way most of us use Stack Overflow: occasionally, when stuck, for quick lookups or autocomplete on familiar patterns. AI hasn&#8217;t changed how they work.</p><p><strong>AI Commuters</strong> spend $100-200 per developer per month. Commuters use AI across the full SDLC: planning, generation, refactoring, debugging, code review. This is what &#8220;we use AI for development&#8221; actually means when organizations report productivity gains.</p><p><strong>AI Natives</strong> spend $1,000 or more per developer per month. This tier runs full agentic workflows: multiple parallel agents executing multi-file tasks autonomously, agents that draft specs, generate code, run tests, and open pull requests without human prompting at each step.</p><p>The productivity research that justifies AI investment was conducted on substantive users. <a href="https://newsletter.getdx.com/p/why-arent-ai-productivity-gains-higher">Abi Noda</a>, whose firm DX has tracked AI adoption across hundreds of engineering organizations, puts it plainly: developers save about three hours per week when they&#8217;re actually using the tools. Developers in the heaviest usage quartile show measurable gains. Light users show minimal impact. A developer doing real agentic work throughout the day is a Commuter. That&#8217;s the realistic baseline for budgeting.</p><h1>Why Commuter Is the Realistic Baseline</h1><p>The Commuter range isn&#8217;t a power-user premium. It&#8217;s what a developer who uses agentic coding tools throughout a normal workday actually consumes.</p><p>Here&#8217;s why. Agentic coding tools don&#8217;t send a single prompt and wait. Each interaction is a multi-turn conversation: the system prompt, the full conversation history, the contents of files pulled into context, and tool-use tokens from file reads, searches, and test runs. A straightforward &#8220;refactor this function&#8221; request might load tens of thousands of tokens before the model generates a single line. A session working across multiple files on a mid-size codebase consumes more. As the day progresses, each follow-up request carries the accumulated history of everything before it. Context compounds.</p><p>The result is that a developer using agentic tools regularly throughout the day lands in the $100-200 per developer per month range. <a href="https://code.claude.com/docs/en/costs">Anthropic publishes an average daily cost figure</a> consistent with this range for API users. That average reflects normal development work: planning a feature, iterating on implementation, debugging, reviewing diffs. The math works out roughly the same whether you&#8217;re on a flat-rate subscription that covers that usage or paying API rates directly.</p><p>For organizations deploying at scale, the structure matters. Team plans bundle access and usage into a per-seat fee. Enterprise plans separate the two: the seat fee covers access, and token consumption is metered on top at API rates. Either way, the underlying consumption is the same. A developer doing substantive agentic work costs roughly what the Commuter tier costs, regardless of how the invoice is structured.</p><h1>What You&#8217;re Actually Paying For</h1><p>Subscription pricing obscures a meaningful gap between what you pay and what you consume. Flat-rate plans are priced well below actual API cost at heavy usage levels. That gap represents a vendor subsidy designed to build habit and market share at below-cost pricing.</p><p><a href="https://www.vantage.sh/blog/cursor-pricing-explained">Cursor&#8217;s June 2025 switch</a> from request-based pricing to a credit model tied to actual API consumption was an early signal of where this is heading. The developer backlash was sharp enough that Cursor apologized and issued refunds. That reaction tells you something: developers had become dependent on flat-rate pricing, and the dependency became visible the moment it was threatened.</p><p>Commuter adoption also requires a stack, not a single tool. An IDE assistant, a code review tool, a chat model. At honest per-seat pricing, that&#8217;s $100-200 per developer per month in subscriptions alone before any overhead. A more honest planning assumption runs the ROI at 2-3x current subscription pricing. If the investment still works, proceed with confidence. If it only pencils at today&#8217;s subsidized rates, that&#8217;s a pricing dependency worth naming explicitly.</p><h1>The Hidden Costs</h1><p>Subscription pricing, even at honest Commuter rates, isn&#8217;t the full story. Five cost categories don&#8217;t appear on vendor pricing pages.</p><p><strong>Rework and quality debt.</strong> <a href="https://www.coderabbit.ai/blog/state-of-ai-vs-human-code-generation-report">CodeRabbit&#8217;s analysis of 470 pull requests</a> found AI-generated code produces 1.7x more defects than human-written code, with security vulnerabilities appearing twice as often. <a href="https://leaddev.com/technical-direction/how-ai-generated-code-accelerates-technical-debt">GitClear&#8217;s analysis of 211 million lines of code</a> found code duplication surged eight-fold between 2022 and 2024. A Harness survey found 67% of developers now spend more time debugging AI-generated code than writing it themselves. The tool generating more defects is simultaneously increasing the time required to catch them.</p><p><strong>Review bottleneck.</strong> <a href="https://www.faros.ai/blog/key-takeaways-from-the-dora-report-2025">Agentic coding drives 98% more pull requests and 154% larger PRs</a>, according to Faros AI&#8217;s analysis of 10,000 developers, while review time jumps 91% and organizational delivery metrics stay flat. AI generates a 500-line PR at near-zero marginal cost. A senior engineer still needs two hours to evaluate it. Accelerating code generation without modernizing review doesn&#8217;t improve throughput. It moves the bottleneck downstream.</p><p><strong>Adoption ramp.</strong> Productivity gains require rebuilding the workflow around the tools. CI/CD pipelines need hardening to handle the volume. Teams need to develop and standardize a shared library of agent skills and workflows before individuals work efficiently. Best practices are still maturing, and that instability has a cost. What worked six months ago may already be obsolete.</p><p><strong>Governance and compliance.</strong> Any serious AI implementation requires governance: access controls, data handling policies, audit logging, and security review processes. For publicly traded companies and large organizations, that bar is higher still. <a href="https://www.veracode.com/blog/genai-code-security-report/">Veracode found that AI introduced security vulnerabilities in 45% of coding tasks</a>, because models optimize for tests passing rather than security properties. The tooling, training, and remediation work to meet that bar doesn&#8217;t appear on the vendor pricing page.</p><p><strong>Skill erosion.</strong> <a href="https://www.anthropic.com/research/AI-assistance-coding-skills">Anthropic&#8217;s January 2026 randomized study</a> found developers using AI scored 17% lower on code comprehension than those who coded manually, with debugging showing the largest gap. The capability that makes AI output valuable is the human judgment to evaluate it. A workforce that generates code quickly but can&#8217;t debug when AI fails, can&#8217;t understand system architecture, and can&#8217;t maintain code over the long term is a compounding liability, not a productivity asset.</p><h1>What Defensible Budgeting Looks Like</h1><p>Three moves make the calculation honest. First, budget at Commuter costs with 30-40% Year One overhead for the hidden categories. Use cases that still deliver positive ROI at that number are worth pursuing. Use cases that only pencil at Tourist pricing aren&#8217;t ready for workflow-level investment.</p><p>Second, stress-test the subsidy. Build a second scenario at 2-3x current subscription pricing. A decision that depends on a specific vendor pricing structure should acknowledge that dependency in the risk column, alongside technical risk.</p><p>Third, treat engineering depth as a strategic asset. The fundamentals that let developers evaluate AI output are the same capabilities that provide leverage when vendor pricing shifts. Minimum competency floors aren&#8217;t about slowing adoption. They preserve the auditing capability that makes AI output usable.</p><p>The ROI case for AI tooling works, at honest cost inputs, with realistic productivity estimates, for use cases that match the research conditions. The number is more modest than the vendor pitch and the cost is higher than the pricing page suggests. But there&#8217;s genuine value here for teams that measure it correctly.</p><p>I&#8217;m curious whether your team has done the full TCO version and where it lands. Does the investment hold at Commuter costs with the hidden categories included? That&#8217;s the conversation worth having before the budget is set.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Treat Skills as Code]]></title><description><![CDATA[Agent skills are the most portable tool in agentic engineering. Time to give them the quality discipline they deserve.]]></description><link>https://read.invoke.dev/p/treat-skills-as-code</link><guid isPermaLink="false">https://read.invoke.dev/p/treat-skills-as-code</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Tue, 17 Mar 2026 12:44:37 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/5db64f30-6d95-4175-945c-8092d735ba7e_1344x768.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Agent skills have quietly become the most portable building block in agentic engineering. A single SKILL.md file works across Claude Code, Gemini CLI, Codex, and any agent that supports the <a href="https://agentskills.io/">open standard</a>. Write it once, use it everywhere. No vendor lock-in, no framework dependency, no API integration. Just a folder with markdown and optional scripts.</p><p>That portability is why skills matter more than most people realize. MCPs tie you to specific tool integrations. Custom agents require scaffolding. Skills are plain text that any model can read, and they carry your team&#8217;s institutional knowledge in a format that survives platform changes.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>But there&#8217;s a problem. We treat skills like documentation when we should treat them like code.</p><h1>Skills Ship Without Tests</h1><p>Every other dependency in your stack has quality gates. Libraries have test suites. APIs have contracts. Infrastructure has validation. Skills have none of that. They&#8217;re markdown files that load into a context window and steer agent behavior with zero guarantees.</p><p>A broken skill doesn&#8217;t throw an error. It silently degrades output, triggers on the wrong task, or wastes tokens explaining things the model already knows. You won&#8217;t see a stack trace. You&#8217;ll see a slightly worse result that you might not even notice, because you have no baseline to compare against.</p><p>Most skill authors iterate by feel. Write the SKILL.md, test it manually a couple of times, ship it, move on. Did it actually trigger when it should? No idea. Did it improve output quality? Probably, maybe, it felt better. When models update (and they update constantly), did the skill stop working? You&#8217;ll find out when someone complains, or more likely, you won&#8217;t find out at all.</p><p>This is the measurement gap. Without a baseline, you can&#8217;t distinguish a skill that helps from one that wastes tokens. Without regression testing, model updates silently break skills that worked last month. Without structured evaluation, &#8220;it seems better&#8221; is the best feedback you&#8217;ll ever get. Improving from anecdotal evidence is like optimizing database queries without a profiler.</p><p>The skills ecosystem keeps growing. The <a href="https://tessl.io/registry">Tessl Registry</a> hosts over 2,000 public skills. Teams are building internal skill libraries shared across engineering organizations. Multiple agents consuming the same broken skill compounds the damage across every session. Anthropic acknowledged the gap directly in their <a href="https://claude.com/blog/improving-skill-creator-test-measure-and-refine-agent-skills">March 2026 skill-creator update</a>, which added structured evals and benchmarking to the authoring workflow. The ecosystem needed quality infrastructure. It&#8217;s arriving.</p><h1>What Makes a Skill Good</h1><p>Before reaching for evaluation tools, you need to know what &#8220;good&#8221; looks like. These heuristics come from <a href="https://docs.claude.com/en/docs/agents-and-tools/agent-skills/best-practices">Anthropic&#8217;s best practices</a>, Tessl&#8217;s review scoring criteria, and findings from the <a href="https://arxiv.org/html/2602.12670v1">SkillsBench benchmark</a>. They catch the majority of issues manually.</p><h2>Trigger accurately</h2><p>The description field in your frontmatter is the only thing the agent reads before deciding whether to load the full skill. It carries disproportionate weight.</p><pre><code><code># Good: specific, third-person, includes trigger phrases
---
name: api-design
description: &gt;
  Designs REST APIs following team conventions for naming,
  versioning, and error handling. Use when creating new
  endpoints, reviewing API designs, or updating existing
  APIs to match current standards.
---

# Bad: vague, no trigger context
---
name: api-helper
description: Helps with API stuff
---</code></code></pre><p>Write descriptions in third person. Include an explicit &#8220;Use when...&#8221; clause. Test the description against near-miss queries, things that share keywords with your skill but shouldn&#8217;t trigger it. The negative test cases matter more than the positive ones. Anthropic&#8217;s documentation notes that Claude uses the description to choose the right skill from potentially 100+ available skills. If your description doesn&#8217;t include both what the skill does and when to use it, the skill is invisible.</p><h2>Stay lean</h2><p>Every token in your SKILL.md competes with conversation history, other skills, and the actual task. Anthropic&#8217;s guidance is blunt: Claude is already very smart. Only add context Claude doesn&#8217;t have.</p><p>The single highest-leverage improvement for any skill: read every paragraph and ask, &#8220;If I delete this, would the agent&#8217;s output actually get worse?&#8221; If the answer is probably not, delete it. Most skills are 40-60% longer than they need to be. Don&#8217;t explain what PDFs are before showing how to extract text from them. Don&#8217;t define REST conventions before describing your team&#8217;s specific API patterns. Encode what&#8217;s unique to your context: team conventions, architecture decisions, deployment procedures.</p><p>Keep SKILL.md under 500 lines. Under 300 is better.</p><h2>Use progressive disclosure</h2><p>Skills use a three-level loading system that controls token cost. At startup, only metadata (name and description, roughly 100 tokens) loads into context. The full SKILL.md loads only when the skill triggers. Referenced files load only when the SKILL.md explicitly directs the agent to read them.</p><pre><code><code>api-design/
&#9500;&#9472;&#9472; SKILL.md              &#8592; Loads on trigger (~200 lines)
&#9500;&#9472;&#9472; references/
&#9474;   &#9500;&#9472;&#9472; error-codes.md    &#8592; Loads only when needed
&#9474;   &#9492;&#9472;&#9472; naming-rules.md   &#8592; Loads only when needed
&#9492;&#9472;&#9472; scripts/
    &#9492;&#9472;&#9472; validate.py       &#8592; Executes, never loads into context</code></code></pre><p>Put detailed schemas, checklists, and examples in reference files. Never chain references more than one level deep. SKILL.md can point to <code>references/error-codes.md</code>, but that file should not reference another file. Agents fail on multi-hop chains.</p><h2>Match specificity to the need</h2><p>Not every instruction needs the same specificity. Match it to how fragile the task is.</p><p>Database migrations need exact scripts with no parameters. This requires high specificity, because variation is a bug. Code review needs heuristics and guidance, because the right feedback depends on context. Report generation sits in the middle: provide a template but let the agent adapt to the data.</p><p>For every instruction that uses MUST, ALWAYS, or NEVER, check whether you&#8217;ve explained why. &#8220;Filter test accounts because production reports with test data caused incorrect business decisions&#8221; works better than &#8220;ALWAYS filter test accounts.&#8221; Models respond to reasoning better than commands.</p><h2>Make it testable</h2><p>A skill you can&#8217;t evaluate is a skill you can&#8217;t improve. Design with verification in mind. Identify the failure modes you&#8217;d see without the skill. Define what correct output looks like for 3-5 realistic scenarios. Include concrete input/output examples in the skill itself, because models follow demonstrated patterns better than abstract instructions.</p><pre><code><code># In your eval definition
{
  "skill_name": "api-design",
  "evals": [
    {
      "id": 1,
      "prompt": "Design endpoints for user profile management",
      "expected_output": "REST endpoints following team naming 
        conventions with proper versioning and error handling",
      "assertions": [
        "Uses plural nouns for resource names",
        "Includes /v1/ path prefix",
        "Defines error response schema"
      ]
    }
  ]
}</code></code></pre><p>These heuristics work for manual review. But manual review doesn&#8217;t scale, doesn&#8217;t catch regressions across model updates, and doesn&#8217;t produce the data you need to improve systematically. That requires tooling.</p><h1>The Evaluation Landscape</h1><p>At least three solutions now exist for skill evaluation. Each approaches the problem from a different angle, and together they signal where the market is heading: skills require the same quality infrastructure as any other code dependency.</p><h2>Anthropic Skill-Creator 2.0</h2><p>Anthropic&#8217;s <a href="https://claude.com/blog/improving-skill-creator-test-measure-and-refine-agent-skills">March 2026 update</a> added structured evaluation directly into the skill authoring workflow. It runs parallel A/B tests with blind comparison (a comparator agent judges output quality without knowing which version produced it). It optimizes trigger descriptions using a train/holdout split to prevent overfitting. The entire workflow runs through natural language. No coding required.</p><p>The limitation is scope. Skill-creator works inside Claude&#8217;s ecosystem only. No cross-model testing, no CI/CD integration, no registry for distributing evaluated skills to a team.</p><h2>Promptfoo (OpenAI)</h2><p><a href="https://openai.com/index/openai-to-acquire-promptfoo/">OpenAI acquired Promptfoo on March 9, 2026</a> for its evaluation and red-teaming capabilities. Promptfoo&#8217;s open-source CLI lets you define test rubrics in YAML, run assertions against agent output, and scan for security vulnerabilities using OWASP and NIST presets. Over 350,000 developers use it, including teams at 25% of Fortune 500 companies.</p><p>Promptfoo is a general-purpose eval tool, not skill-specific. It has no structural review, no skill registry, and no built-in concept of baseline-vs-skill comparison. OpenAI committed to keeping it open source, but the deepest integration will favor the Frontier enterprise platform. It represents where OpenAI sees the evaluation layer heading: embedded in the platform, tightly coupled with agent deployment.</p><h2>Tessl</h2><p><a href="https://tessl.io/">Tessl</a> is the most vendor-agnostic option available at the moment. Built as a package manager for agent skills, it provides the full lifecycle: build, evaluate, distribute, optimize. Its evaluation stack has three layers.</p><p><code>tessl skill lint</code> validates structure and packaging. Does the frontmatter parse? Are required fields present? Think of it as a compilation check.</p><p><code>tessl skill review</code> scores your skill against best practices across three dimensions: validation (schema hygiene), implementation quality (clear instructions, concrete examples), and activation quality (discoverable triggers, specific keywords). The output includes actionable suggestions.</p><pre><code><code>$ tessl skill review ./api-design

Validation Checks
  &#10004; frontmatter_valid
  &#10004; name_field - 'api-design'
  &#10004; description_field - valid (186 chars)
  &#10004; description_voice - uses third person
  &#9888; description_trigger_hint - missing 'Use when...'
  &#10004; skill_md_line_count - 147 (&lt;= 500)

Implementation Score: 78%
Activation Score: 62%
Overall Score: 71%</code></code></pre><p><code>tessl eval run</code> measures behavioral impact. It generates realistic scenarios, runs the agent through each scenario with and without the skill, and scores outputs against criteria. The gap between baseline and skill-augmented scores tells you whether the skill changes behavior in the direction you want. If there&#8217;s barely any difference, the agent handled the task fine without your skill. If scores drop, the instructions hurt more than they help.</p><p>Tessl&#8217;s registry hosts over 2,000 evaluated skills. Evals run automatically when you publish, catching regressions before they reach users. Results are version-pinned, so you can compare v1.1.0 against v1.2.0 with data instead of intuition. It works across Claude Code, Gemini CLI, Codex, and any agent supporting the skill spec.</p><h2>Where each tool fits</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!V5bQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!V5bQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png 424w, https://substackcdn.com/image/fetch/$s_!V5bQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png 848w, https://substackcdn.com/image/fetch/$s_!V5bQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png 1272w, https://substackcdn.com/image/fetch/$s_!V5bQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!V5bQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png" width="1456" height="802" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:802,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:417822,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://read.invoke.dev/i/191247779?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!V5bQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png 424w, https://substackcdn.com/image/fetch/$s_!V5bQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png 848w, https://substackcdn.com/image/fetch/$s_!V5bQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png 1272w, https://substackcdn.com/image/fetch/$s_!V5bQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf1de0b1-0009-4fb7-8bb9-1f82d434f9cd_2320x1278.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>These tools aren&#8217;t competing. They&#8217;re complementary, and together they represent the market converging on a single idea: skills need quality infrastructure. Anthropic built it into the authoring experience. OpenAI acquired it for the security layer. Tessl built the vendor-agnostic lifecycle platform.</p><p>The practical starting point: use Anthropic&#8217;s skill-creator for the authoring loop if you&#8217;re working in Claude. Use Tessl&#8217;s lint and review to catch structural issues and get a scored quality baseline that works across agents. The tools compose well together, and Tessl&#8217;s own documentation suggests using both.</p><h1>What This Means</h1><p>Skills are the most portable, most universal tool available for specializing AI agents. They work across models, across agents, across platforms. That&#8217;s rare in an ecosystem where most tools lock you into a specific vendor.</p><p>But portability without quality is just distributing problems faster. A bad skill deployed across a team&#8217;s agents doesn&#8217;t fail loudly. It fails quietly, across every session, degrading output in ways nobody measures because nobody has a baseline.</p><p>The evaluation infrastructure now exists. Anthropic, OpenAI, and Tessl each built their version in the first quarter of 2026. The question isn&#8217;t whether the tooling is ready. The question is whether we&#8217;ll apply the same discipline to skills that we apply to every other dependency in our stack.</p><p>What does your team&#8217;s skill quality process look like? Are you measuring impact, or still iterating by feel?</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Context Engineering for AI-Assistant Development ]]></title><description><![CDATA[AI coding tools have a context problem.]]></description><link>https://read.invoke.dev/p/context-engineering-for-ai-assistant</link><guid isPermaLink="false">https://read.invoke.dev/p/context-engineering-for-ai-assistant</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Sun, 08 Mar 2026 15:51:25 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1296d0e3-ed78-425b-9f50-c72187e50efb_1344x768.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>AI coding tools have a context problem. Every token loaded into a context window competes for the model&#8217;s attention. <a href="https://arxiv.org/abs/2307.03172?ref=invoke.dev">Stanford and Berkeley research</a> documented the &#8220;lost-in-the-middle&#8221; phenomenon: LLMs perform best when relevant information is at the beginning or end of the input, with significant degradation when it is buried in the middle. Practitioners have found that models become unreliable when context usage exceeds <a href="https://www.youtube.com/watch?v=rmvDxxNubIg&amp;ref=invoke.dev">40-60% of maximum capacity</a>. A model claiming 200K tokens becomes unreliable around 130K.</p><p>So what we include matters. When we include it matters. How we organize it matters. <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents?ref=invoke.dev">Anthropic frames the challenge clearly</a>: building effective AI agents is less about finding the right words and more about answering the question, &#8220;What configuration of context is most likely to generate the desired behavior?&#8221;</p><p>We&#8217;ve gone from one tool with one config file to three or four AI coding tools, each with its own conventions for context files, skill directories, and configuration formats. Claude Code reads <code>CLAUDE.md</code>. Gemini CLI reads <code>GEMINI.md</code>. Codex CLI reads <code>AGENTS.md</code>. Copilot wants <code>.github/copilot-instructions.md</code>. Maintain separate configs for each tool, and you&#8217;re managing the same knowledge in multiple places. Change a convention in one file, forget to update another, and your tools start contradicting each other.</p><p><a href="https://martinfowler.com/articles/exploring-gen-ai/context-engineering-coding-agents.html?ref=invoke.dev">Thoughtworks&#8217; analysis</a> of context engineering for coding agents found that the number of configuration options has exploded, with Claude Code leading innovations and other tools quickly following. The fragmentation creates a real maintenance burden.</p><p>Don&#8217;t pick one tool. Build a shared knowledge architecture that any tool can consume, with thin wrappers for tool-specific quirks. After a year working with Claude Code, Codex CLI, and Gemini CLI across a modular codebase, I&#8217;ve converged on a four-layer approach that separates concerns and keeps things tool-agnostic.</p><h2>A Layered Approach</h2><p>Two dimensions matter for understanding how context reaches the model.</p><p>The first is <strong>what decides to load it.</strong> <a href="https://martinfowler.com/articles/exploring-gen-ai/context-engineering-coding-agents.html?ref=invoke.dev">B&#246;ckeler&#8217;s analysis</a> identifies three triggers: the agent software automatically loads some context on every interaction (your AGENTS.md), the LLM decides to load other context when it judges it relevant (skills, MCP tools), and the developer explicitly triggers the rest (slash commands, manual file references). This distinction matters because it determines reliability. Agent-loaded context is deterministic. LLM-loaded context is probabilistic; the model might not activate a skill when you expect it to.</p><p>The second is <strong>whether execution is probabilistic or guaranteed.</strong> Most of this architecture is probabilistic guidance. Project knowledge and skills describe what the model should do, and it probably follows them. Probably. Hooks are different. They fire deterministically, executing shell commands at lifecycle boundaries regardless of the model&#8217;s decision. You can write &#8220;always run Prettier after editing files&#8221; in your AGENTS.md, and the model will follow it most of the time. A hook guarantees it.</p><p>These two dimensions are organized into four layers:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JuN-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a94f3c9-2a72-4b15-8dde-3a354fde852b_1076x1183.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JuN-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a94f3c9-2a72-4b15-8dde-3a354fde852b_1076x1183.png 424w, https://substackcdn.com/image/fetch/$s_!JuN-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a94f3c9-2a72-4b15-8dde-3a354fde852b_1076x1183.png 848w, https://substackcdn.com/image/fetch/$s_!JuN-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a94f3c9-2a72-4b15-8dde-3a354fde852b_1076x1183.png 1272w, https://substackcdn.com/image/fetch/$s_!JuN-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a94f3c9-2a72-4b15-8dde-3a354fde852b_1076x1183.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JuN-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a94f3c9-2a72-4b15-8dde-3a354fde852b_1076x1183.png" width="1076" height="1183" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a94f3c9-2a72-4b15-8dde-3a354fde852b_1076x1183.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1183,&quot;width&quot;:1076,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!JuN-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a94f3c9-2a72-4b15-8dde-3a354fde852b_1076x1183.png 424w, https://substackcdn.com/image/fetch/$s_!JuN-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a94f3c9-2a72-4b15-8dde-3a354fde852b_1076x1183.png 848w, https://substackcdn.com/image/fetch/$s_!JuN-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a94f3c9-2a72-4b15-8dde-3a354fde852b_1076x1183.png 1272w, https://substackcdn.com/image/fetch/$s_!JuN-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a94f3c9-2a72-4b15-8dde-3a354fde852b_1076x1183.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The dependency direction flows upward. Project Knowledge orients the AI on every interaction. Tools provide raw capabilities. Hooks enforce deterministic behavior at lifecycle boundaries. Skills bundle domain knowledge with tool references and load on demand.</p><h2>Layer 1: Project Knowledge</h2><p>Project Knowledge answers &#8220;where am I and what matters here.&#8221; It describes the architecture, module boundaries, conventions, and domain concepts. Without it, an AI tool has capabilities but no orientation.</p><p><code>AGENTS.md</code> is the portable format: a markdown file at the repository root and optionally in module directories. The <a href="https://agents.md/?ref=invoke.dev">AGENTS.md specification</a> emerged in mid-2025 as a vendor-neutral standard, now stewarded by the Agentic AI Foundation under the Linux Foundation. It&#8217;s been <a href="https://cobusgreyling.medium.com/what-is-agents-md-2846b586b116?ref=invoke.dev">adopted by over 60,000 repositories</a> and is supported by Codex CLI, Cursor, GitHub Copilot, and others. Claude Code and Gemini CLI can be configured to read it.</p><p>The format cascades. An agent reads the root <code>AGENTS.md</code> first, then the local one for the current directory. This mirrors how <code>.gitignore</code> works: the closest file takes precedence. A root file describes the overall architecture and conventions. Module-level files describe internal structure, dependencies, and domain concepts specific to that module.</p><p>Keep it concise. There&#8217;s a practical constraint: <a href="https://www.aihero.dev/a-complete-guide-to-agents-md?ref=invoke.dev">frontier models can reliably follow roughly 150-200 instructions</a> before consistency degrades. Smaller models handle fewer. Every instruction in your AGENTS.md competes with every other instruction for the model&#8217;s attention. Community advice converges on <a href="https://docs.factory.ai/cli/configuration/agents-md?ref=invoke.dev">keeping AGENTS.md files under 150 lines</a>. A 500-line AGENTS.md with embedded examples, full API schemas, and copy-pasted documentation doesn&#8217;t make the model smarter. It makes it worse. Describe the module&#8217;s purpose, boundaries, and conventions, then point to skills for detailed patterns.</p><p>Where a tool requires its own context file, the tool-specific file should reference <code>AGENTS.md</code> and add only tool-specific instructions. One source of truth, thin wrappers.</p><pre><code><code># CLAUDE.md
See AGENTS.md for project architecture and module context.

## Tool-Specific Notes
- MCP servers available: Filesystem, GitHub
- Skills directory: `.agents/skills/`
</code></code></pre><p>For Gemini CLI, configure it to read AGENTS.md directly by adding <code>{"context":{"fileName":["AGENTS.md"]}}</code> to <code>.gemini/settings.json</code>. This eliminates the wrapper entirely.</p><h3>Path-Scoped Rules</h3><p>Some tools support path-specific conventions that fire when the AI encounters a particular file type. Think of them as file-type checklists: &#8220;when you see this kind of file, check these things.&#8221; These complement the broader project knowledge without duplicating it.</p><p>This is the least portable part of the architecture. Copilot uses <code>.github/instructions/*.md</code> with <code>applyTo</code> frontmatter. Claude Code uses <code>.claude/rules/</code>. Cursor uses <code>.cursor/rules/*.mdc</code>. Other CLI tools don&#8217;t support path-scoped rules at all. Author them in the format of your primary tool and accept this as tool-specific.</p><p>Rules are checklists, not architecture descriptions. They don&#8217;t duplicate what AGENTS.md covers. Each rule file stays under 20 lines and delegates to skills for detail. If a rule file starts describing module purpose, dependencies, and domain concepts, that content belongs in AGENTS.md.</p><pre><code><code>---
applyTo: ["**/*Controller.ts", "**/*Service.ts"]
---
# Service Files
- Single responsibility per service
- Dependencies injected via constructor
- Error handling with typed exceptions
- Service under 300 lines

&#8594; Detailed patterns: `.agents/skills/backend/`
</code></code></pre><h2>Layer 2: Tools</h2><p>Tools provide raw capabilities: querying systems, running builds, searching code, and linting files. They&#8217;re primitives that don&#8217;t know about project conventions. Skills compose them.</p><p>MCP is the standard transport for external tool connections. <a href="https://modelcontextprotocol.io/?ref=invoke.dev">Every major tool supports stdio-based MCP servers</a>. Build an MCP server once, and it works across Claude Code, Codex CLI, and Gemini CLI.</p><p>But MCP has a cost. Every connected MCP server loads its tool definitions into the context window upfront, whether you need them or not. <a href="https://www.anthropic.com/engineering/code-execution-with-mcp?ref=invoke.dev">Anthropic&#8217;s guidance on MCP efficiency</a> documents the problem: as connected tools grow, loading all definitions slows agents and increases costs. Connect several MCP servers, and you can burn 50,000+ tokens before the conversation starts. That&#8217;s context budget consumed by tool descriptions rather than project knowledge.</p><p>Be selective. Connect only the MCP servers that the current workflow requires. If a tool has deterministic I/O and doesn&#8217;t need runtime queries, a shell script is cheaper than an MCP server. Reserve MCP for external APIs, databases, and services that need dynamic interaction.</p><h2>Layer 3: Hooks</h2><p>Hooks are the only deterministic layer in this architecture. They&#8217;re shell commands that fire at specific lifecycle events regardless of what the model decides. A PostToolUse hook that runs your formatter after every file write doesn&#8217;t depend on the model remembering to format. It runs every time.</p><blockquote><p>As <a href="https://claude.com/blog/how-to-configure-hooks?ref=invoke.dev">Anthropic&#8217;s documentation</a> puts it: &#8220;Prompts are great for suggestions; hooks are guarantees.&#8221;</p></blockquote><p>Claude Code and Gemini CLI both support hooks with similar event models. Claude Code offers PreToolUse, PostToolUse, SessionStart, and Stop events. <a href="https://developers.googleblog.com/tailor-gemini-cli-to-your-workflow-with-hooks/?ref=invoke.dev">Gemini CLI added hooks in January 2026</a> with equivalent events: BeforeTool, AfterTool, BeforeAgent, AfterAgent. The hook scripts themselves are fully portable shell commands. Only the configuration wrapper differs.</p><p>The most practical hook patterns fall into three categories. Formatting and linting: run your code formatter after every file write so the model never produces code that violates style rules. Safety gates: block dangerous operations like <code>rm -rf</code>, writing to production configs, or committing secrets. Context injection: load recent git commits, open tickets, or environment state at session start so the model has fresh context without you pasting it manually.</p><pre><code><code>{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$(jq -r '.tool_input.file_path')\""
          }
        ]
      }
    ]
  }
}
</code></code></pre><p>One caution: hooks run with your full user permissions. There&#8217;s no sandbox. Treat hook scripts like production code. Validate inputs, use absolute paths, and be deliberate about what you allow.</p><h2>Layer 4: Skills</h2><p>Skills are where this architecture pays off. A skill bundles everything an AI needs to understand a domain and do work in it: reference documentation, checklists, templates, and the tool invocations required to complete actions.</p><p>The <a href="https://agentskills.io/specification?ref=invoke.dev">Agent Skills specification</a> was released as an open standard in late 2025 and has been adopted by <a href="https://thenewstack.io/agent-skills-anthropics-next-bid-to-define-ai-standards/?ref=invoke.dev">Microsoft, OpenAI, Atlassian, Figma, Cursor, and GitHub</a>. The format is deliberately simple: a directory containing a <code>SKILL.md</code> file with YAML frontmatter and markdown instructions, plus optional scripts and references.</p><p>Skills solve the context budget problem with progressive disclosure. At startup, the model sees just the skill&#8217;s metadata, roughly 100 tokens describing what it does. The full instructions load only when the model determines the skill is relevant. The <a href="https://agentskills.io/specification?ref=invoke.dev">specification recommends</a> keeping SKILL.md instructions under 5,000 tokens. Additional references load on demand, so smaller files mean less context consumption.</p><pre><code><code>skills/backend/
&#9500;&#9472;&#9472; SKILL.md              # What this skill knows and can do
&#9500;&#9472;&#9472; references/           # Patterns, examples, anti-patterns
&#9474;   &#9500;&#9472;&#9472; patterns.md       # Canonical patterns (single source of truth)
&#9474;   &#9492;&#9472;&#9472; anti-patterns.md  # What to avoid
&#9500;&#9472;&#9472; checklists/           # Structured criteria
&#9474;   &#9492;&#9472;&#9472; service-review.md # Applies references during review
&#9492;&#9472;&#9472; templates/            # Scaffolding
    &#9492;&#9472;&#9472; service.md        # Applies references during generation
</code></code></pre><p>Organize by domain, not by activity. A <code>react-review</code> skill and a <code>react-generation</code>skill would duplicate the same pattern knowledge. Instead, a single <code>react</code> skill contains all the patterns, with separate checklists for review and templates for generation.</p><blockquote><p>Token generation is probabilistic. Scripts are deterministic.</p></blockquote><p>Skills can also leverage scripts for deterministic tasks. When you need exact behavior, like validating against a checklist or applying a specific code transformation, the skill runs a script rather than asking the model to generate the logic each time.</p><h2>Making It Portable</h2><p>Author content in generic formats, store it in one location, and point tools to that location.</p><p>The obvious approach is to symlink from every tool-specific directory to one canonical location. This creates a problem. VS Code automatically scans <code>.github/skills/</code>, <code>.claude/skills/</code>, and <code>.agents/skills/</code>. If the same skill appears in multiple directories via symlinks, it shows up multiple times in the slash command menu. Duplicate skill names cause <code>.github/skills/</code> to take precedence, but the duplicates clutter the UI and waste the discovery budget.</p><p>The cleaner approach: pick one canonical directory and configure tools to read from it. <code>.agents/skills/</code> is the natural choice since it&#8217;s the vendor-neutral location that <a href="https://developers.openai.com/codex/skills/?ref=invoke.dev">Codex CLI scans natively</a>. For tools that don&#8217;t scan <code>.agents/skills/</code> by default, use a single symlink from their expected location. Avoid creating parallel paths that VS Code will discover independently.</p><pre><code><code>project/
&#9500;&#9472;&#9472; AGENTS.md                          &#8592; Portable context (all tools)
&#9500;&#9472;&#9472; CLAUDE.md                          &#8592; Imports AGENTS.md + Claude notes
&#9500;&#9472;&#9472; .mcp.json                          &#8592; MCP server config (Claude Code)
&#9500;&#9472;&#9472; .agents/
&#9474;   &#9492;&#9472;&#9472; skills/                        &#8592; Canonical skill location
&#9474;       &#9500;&#9472;&#9472; backend/
&#9474;       &#9500;&#9472;&#9472; frontend/
&#9474;       &#9492;&#9472;&#9472; testing/
&#9500;&#9472;&#9472; .claude/
&#9474;   &#9492;&#9472;&#9472; skills -&gt; ../.agents/skills    &#8592; Symlink (Claude Code)
&#9500;&#9472;&#9472; .gemini/
&#9474;   &#9500;&#9472;&#9472; skills -&gt; ../.agents/skills    &#8592; Symlink (Gemini CLI)
&#9474;   &#9492;&#9472;&#9472; settings.json                  &#8592; Reads AGENTS.md
&#9500;&#9472;&#9472; .github/
&#9474;   &#9492;&#9472;&#9472; instructions/                  &#8592; Path-scoped rules (Copilot)
&#9492;&#9472;&#9472; modules/
    &#9492;&#9472;&#9472; auth/
        &#9492;&#9472;&#9472; AGENTS.md                  &#8592; Module-specific knowledge
</code></code></pre><p><code>.github/skills/</code> is absent. VS Code already discovers <code>.agents/skills/</code> and <code>.claude/skills/</code>, so adding a third symlink in <code>.github/skills/</code> would triple every skill in the dropdown. If your primary tool is VS Code with Copilot, you could use <code>.github/skills/</code> as the canonical location and symlink from <code>.claude/</code> and <code>.agents/</code>instead. One real directory and symlinks where the tool can&#8217;t discover the canonical location.</p><p>Portability varies by layer. Project Knowledge and Skills are highly portable because AGENTS.md and SKILL.md are cross-tool standards. Tools are highly portable because MCP is the universal transport protocol. Hooks have moderate portability: Claude Code and Gemini CLI use similar event models, but Codex CLI doesn&#8217;t support hooks yet. Path-scoped rules have the lowest portability, with no universal standard across tools.</p><h2>Where This Breaks Down</h2><p>The four layers handle static context well: the project knowledge, conventions, and domain expertise that don&#8217;t change within a session. They don&#8217;t solve the harder problems that emerge during extended work.</p><p><strong>Long sessions and context rot.</strong> As a session accumulates conversation history, tool outputs, and intermediate results, the model&#8217;s effective working memory shrinks. <a href="https://research.trychroma.com/context-rot?ref=invoke.dev">Chroma Research</a> documented this: related-but-irrelevant content is worse than random noise because it looks relevant enough to distract. No amount of AGENTS.md tuning fixes a context window that&#8217;s 80% full of stale conversation.</p><p><strong>Trajectory poisoning.</strong> When a session goes wrong, errors become context for subsequent reasoning. The model builds on its own mistakes, and no amount of correction fixes a poisoned trajectory. The context itself is the problem.</p><p><strong>The reasoning cliff.</strong> As tasks require more reasoning steps or involve more interacting variables, model accuracy doesn&#8217;t decline gradually. It collapses. <a href="https://machinelearning.apple.com/research/gsm-symbolic?ref=invoke.dev">Apple&#8217;s GSM-Symbolic research</a> found that adding a single irrelevant clause to a math problem led to performance drops of up to 65% across all models. You can&#8217;t fix a task that&#8217;s past the cliff by prompting better. You have to simplify the task itself.</p><p><strong>Cross-agent handoffs.</strong> Subagents help by providing a clean context window for each step. But information gets lost at the boundary. The summary a subagent returns is never as rich as the full context it operated in. Important nuances, edge cases discovered during the investigation, and contextual reasoning are all compressed into a few hundred tokens.</p><h2>What Practitioners Actually Do</h2><p>The teams getting consistent value from AI coding tools have developed instincts that complement the static architecture.</p><p><strong>Start fresh when quality degrades.</strong> The most practical response to trajectory poisoning is simple: commit your work, close the session, and start a new one with a clean context. Treat sessions like git branches. When one goes sideways, abandon it rather than trying to salvage the accumulated mess.</p><p><strong>Keep tasks small.</strong> <a href="https://www.augmentcode.com/guides/ai-coding-agents-for-spec-driven-development-automation?ref=invoke.dev">Multi-file benchmark data</a> shows 87% success on single-file tasks, dropping to 19% on multi-file infrastructure work. Limit each task to touching 2-3 files. If you can&#8217;t explain what the AI should do in a sentence or two, the task is too big. Split it.</p><p><strong>Use subagents for context isolation, not role-playing.</strong> Agents aren&#8217;t about personas. Their value lies in constraining which context loads at each step. A research subagent pulls documentation and API references. An implementation skill loads only the module being modified. Think of subagents as context boundaries.</p><p><strong>Plan before prompting.</strong> Write your own requirements. Make your own architecture decisions. Draft your own test cases. Then use the AI for implementation. As Osmani describes it, <a href="https://addyosmani.substack.com/?ref=invoke.dev">start by brainstorming a detailed specification</a> with the AI, outlining a step-by-step plan, and then writing code. The upfront investment feels slow but prevents wasted cycles when the model goes off-track.</p><h2>Getting Started</h2><p>Start simple. Create an <code>AGENTS.md</code> at your project root with the architecture summary, module map, and key conventions. Whenever you find yourself giving the AI the same instruction twice, add it to AGENTS.md instead.</p><p>Then identify your first skill. Pick the domain where your team spends the most time correcting AI output. If the AI keeps generating code that violates your architecture patterns, that&#8217;s your first skill. Encode the patterns, create a checklist, and point to example files in the codebase.</p><p>Set up the symlink structure early. Create <code>.agents/skills/</code> as your canonical location, then symlink from <code>.claude/skills/</code> and <code>.gemini/skills/</code>. One-time cost that pays off every time you add or modify a skill.</p><p>Add layers incrementally. Path-scoped rules when you notice file-type-specific mistakes. Hooks when you find yourself repeating &#8220;please run the formatter&#8221; in every session. Don&#8217;t build the full architecture before you&#8217;ve validated that the first two layers are working.</p><p>Monitor what&#8217;s actually reaching the model. Claude Code&#8217;s <code>/context</code> command shows what&#8217;s loaded and how much space each piece consumes. Gemini CLI&#8217;s <code>/stats</code> provides similar visibility. If your AGENTS.md and MCP tool definitions are consuming 40% of the context window before you&#8217;ve typed anything, the architecture needs trimming. The best context engineering is invisible when it works and diagnosable when it doesn&#8217;t.</p><p>Treat these files like code. Subject them to code review, version them, and update them when conventions change. Teams that get consistent value from AI tools invest in maintaining this context architecture alongside their codebase.</p><h2>Where the Standards Are Headed</h2><p>The standardization landscape is moving fast. AGENTS.md and the Agent Skills format have broad adoption, but both specifications are young. A <a href="https://github.com/agentsmd/agents.md/issues/135?ref=invoke.dev">v1.1 proposal for AGENTS.md</a> is working to codify implicit behaviors around discovery, layering, and precedence that the community has adopted but never documented. The community is still debating whether AGENTS.md should eventually be merged into README.md.</p><p>Some questions remain open. How detailed should module-level AGENTS.md files be before they become more noise than signal? When does a skill&#8217;s reference documentation grow large enough to need its own progressive disclosure? How do you measure whether a skill is actually improving AI output quality versus just adding tokens?</p><p>The fundamental tension remains: we&#8217;re building static architectures for tools whose hardest problems are dynamic. The four layers give you the best possible starting position for each session. What happens during the session still depends on task decomposition, session hygiene, and engineering judgment.</p><p>The tools improve constantly. The constraints will shift. But the core challenge won&#8217;t change: AI coding tools are only as good as the context in which they operate. Managing that context with intention, rather than hoping the model figures it out, is how you get consistent value from these tools.</p><p>I&#8217;m curious how others are handling the multi-tool fragmentation problem. Are you maintaining separate configs per tool, or converging on a shared architecture?</p>]]></content:encoded></item><item><title><![CDATA[Signal Check: February 20, 2026]]></title><description><![CDATA[This week's signal in AI and engineering]]></description><link>https://read.invoke.dev/p/signal-check-february-20-2026</link><guid isPermaLink="false">https://read.invoke.dev/p/signal-check-february-20-2026</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Fri, 20 Feb 2026 13:02:35 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/85649138-0e1e-49b0-ae54-16fb6b9d2ab1_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em>February 20, 2026</em></p><p>The psychological cost of AI adoption got a name this week, along with the data to back it up. Developers are using AI tools more than ever while trusting them less, and researchers are starting to explain why the gap keeps widening.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2><a href="https://simonwillison.net/2026/Feb/15/deep-blue/">Deep Blue</a></h2><p><em>Simon Willison</em></p><p>Willison and the Oxide and Friends podcast coined a term for the existential dread software developers feel watching AI close in on their work: &#8220;Deep Blue.&#8221; Named after the chess machine. Not a doomer take or an optimist spin. A practitioner saying, &#8220;This feeling is real, and we should talk about it.&#8221;</p><h2><a href="https://margaretstorey.com/blog/2026/02/09/cognitive-debt/">How Generative and Agentic AI Shift Concern from Technical Debt to Cognitive Debt</a></h2><p><em>Margaret-Anne Storey</em></p><p>Technical debt lives in the code. Cognitive debt lives in developers&#8217; heads. Storey watched a student team hit a wall at week 8: they could no longer make simple changes because nobody could explain why the system was built the way it was. Shared understanding evaporated faster than the code quality. When agents write the code, the mental model for understanding it never forms.</p><h2><a href="https://stackoverflow.blog/2026/02/18/closing-the-developer-ai-trust-gap">Mind the Gap: Closing the AI Trust Gap for Developers</a></h2><p><em>Stack Overflow</em></p><p>AI usage rose to 84%. Trust dropped to 29%. Stack Overflow digs into why familiarity breeds skepticism rather than confidence. The core tension: developers are trained for deterministic thinking, and AI is probabilistic. Same question, two different answers, both plausible. That variability violates foundational expectations about how tools should behave.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[AI-Assisted Reviews with GitHub Copilot]]></title><description><![CDATA[In my last article, I argued that engineering teams should fix the review process before scaling code generation.]]></description><link>https://read.invoke.dev/p/ai-assisted-reviews-with-github-copilot</link><guid isPermaLink="false">https://read.invoke.dev/p/ai-assisted-reviews-with-github-copilot</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Tue, 17 Feb 2026 13:02:33 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/60f6cedb-8346-4f15-af9f-8dfd59e0eeed_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In my <a href="https://read.invoke.dev/p/ai-assisted-code-reviews">last article</a>, I argued that engineering teams should fix the review process before scaling code generation. AI review tools won&#8217;t solve the capacity problem, but they handle what humans struggle to sustain: speed, consistency, and pattern recognition.</p><p>This is the practical follow-up. Copilot code review has added path-specific instructions, agentic tool calling, a CLI code-review agent, and local IDE review since going GA. Most teams install it, leave the defaults, and wonder why it floods their PRs with noise. Configuration separates a tool the team ignores after a month from one that sticks.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>Instruction Files: Two Layers</h1><p>Copilot&#8217;s instruction system has two layers. Repository-wide instructions live in <code>.github/copilot-instructions.md</code> and apply to every review. Path-specific instructions live in <code>.github/instructions/</code> and target file patterns through YAML frontmatter.</p><p>Encode your universal standards in the repository-wide file. Write short, imperative directives rather than paragraphs. Copilot processes &#8220;Flag hardcoded API keys or credentials&#8221; far more reliably than &#8220;Please be careful to look for any secrets that might have been accidentally committed.&#8221;</p><p><a href="https://github.blog/ai-and-ml/unlocking-the-full-power-of-copilot-code-review-master-your-instructions-files/">GitHub&#8217;s own guide</a> is explicit: vague directives like &#8220;be more accurate&#8221; add noise that confuses the LLM.</p><pre><code><code>&lt;!-- .github/copilot-instructions.md --&gt;

# Code Review Instructions

## Security
- Flag hardcoded API keys, tokens, or credentials
- Check that user input is validated before use
- Verify that sensitive data is not logged or exposed in error messages

## Error Handling
- Verify errors are handled, not silently ignored
- Check that error messages provide useful context for debugging
- Flag empty catch blocks

## Quality
- Flag functions longer than 40 lines
- Flag deeply nested logic (more than 3 levels)
- Check for missing nil/null guards on optional values

## Do Not Comment On
- Code formatting or style (handled by linters)
- Import ordering
- Trailing whitespace or line length</code></code></pre><p>Keep this file under 1,000 lines. The &#8220;Do Not Comment On&#8221; section matters. Every low-value comment competes for attention with the ones that count. If your linters already handle formatting, tell Copilot explicitly.</p><p>Path-specific instructions target parts of the codebase where generic rules fall short. Each file uses an <code>applyTo</code> frontmatter property with glob patterns. The <code>excludeAgent</code> property controls which Copilot agent reads which file, so you can run different rules for the code review agent and the coding agent.</p><pre><code><code>&lt;!-- .github/instructions/views.instructions.md --&gt;
---
applyTo: "**/Views/**/*.swift"
excludeAgent: "coding-agent"
---

# View Layer Review Standards

- Flag views exceeding 30 lines of body content
- Check that views do not make network calls directly
- Verify accessibility modifiers are present on interactive elements
- Flag any business logic in view code; it belongs in the view model
- Check that navigation is handled through the coordinator, not inline</code></code></pre><pre><code><code>&lt;!-- .github/instructions/tests.instructions.md --&gt;
---
applyTo: "**/Tests/**/*.swift"
---

# Test Review Standards

- Verify each test method tests a single behavior
- Check that test names describe the expected behavior
- Flag tests without assertions
- Flag any test that hits the network or file system without mocking
- Check that test data is created within the test, not shared across tests</code></code></pre><p>Organize by concern: views, networking, models, tests, security. <a href="https://github.blog/changelog/2025-11-12-copilot-code-review-and-coding-agent-now-support-agent-specific-instructions/">GitHub recommends</a> separating topics into distinct instruction files rather than cramming everything into one. A typical iOS project:</p><pre><code><code>.github/
&#9500;&#9472;&#9472; copilot-instructions.md          # Repository-wide standards
&#9492;&#9472;&#9472; instructions/
    &#9500;&#9472;&#9472; views.instructions.md         # View layer conventions
    &#9500;&#9472;&#9472; networking.instructions.md    # API and networking patterns
    &#9500;&#9472;&#9472; models.instructions.md        # Data model conventions
    &#9500;&#9472;&#9472; tests.instructions.md         # Testing standards
    &#9492;&#9472;&#9472; security.instructions.md      # Security-specific checks</code></code></pre><h1>Linters Handle Rules, AI Handles Judgment</h1><p>Don&#8217;t let Copilot duplicate what linters already catch. Linters enforce formatting, flag syntax errors, and check naming conventions deterministically. They&#8217;re fast, consistent, and produce zero false positives for well-defined rules.</p><p>Copilot&#8217;s strength is semantic analysis: logic correctness, edge cases, security vulnerabilities, and fuzzy checks that depend on context. Can a function name communicate its intent? Does the error handling account for this specific situation? Does this change duplicate logic from another module? Linters can&#8217;t make those calls.</p><p>The <a href="https://dev.to/techgirl1908/how-i-taught-github-copilot-code-review-to-think-like-a-maintainer-3l2c">Goose project maintainers</a> discovered this when they enabled Copilot code review and the other maintainers said the results were too noisy. The fix was telling Copilot exactly what the CI pipeline already covers:</p><pre><code><code>## CI Pipeline Context

Important: You review PRs before CI completes.
Do not flag issues that CI will catch.

### What Our CI Checks
- cargo fmt --check
- cargo test
- clippy lints
- npm run lint:check

## Skip These (Low Value)
Do not comment on:
- Style/formatting (handled by rustfmt, prettier)
- Clippy warnings
- Test failures
- Missing dependencies</code></code></pre><p>They also set a confidence threshold: &#8220;Only comment when you have HIGH CONFIDENCE (&gt;80%) that an issue exists. Be concise: one sentence per comment when possible.&#8221; That alone cut the noise dramatically.</p><p>The filtering pipeline looks like this: linters catch mechanical issues in CI, Copilot handles semantic analysis, human reviewers focus on architecture, business logic, and mentoring.</p><h1>Tuning: Start Minimal and Iterate</h1><p><a href="https://www.cubic.dev/blog/the-false-positive-problem-why-most-ai-code-reviewers-fail-and-how-cubic-solved-it">Research from Cubic</a> found that up to 40% of AI code review alerts get ignored. A developer who receives fifteen low-value comments on their first AI-reviewed PR will ignore comment sixteen, even if it&#8217;s the one that matters.</p><p>Start with five to ten rules that address your most common review feedback. Add rules one at a time and observe the results. If Copilot flags something your team doesn&#8217;t care about, add an explicit exclusion.</p><p>Show, don&#8217;t describe. Copilot is better at mimicry than interpretation. Telling it &#8220;prefer protocol-based dependency injection&#8221; may or may not flag violations. Show it a concrete example of the wrong approach alongside the right one, and accuracy improves noticeably.</p><pre><code><code>## Dependency Injection

Prefer protocol-based dependency injection over concrete types.

Bad:
class ProfileViewModel {
    let service = UserService()
}

Good:
class ProfileViewModel {
    let service: UserServiceProtocol
    init(service: UserServiceProtocol) {
        self.service = service
    }
}</code></code></pre><p>Watch for hallucinations. Copilot will invent concerns that don&#8217;t exist in the code, and vague instructions make this worse. The more specific your directives, the less room the model has to fabricate.</p><p>GitHub warns against including external links (Copilot won&#8217;t follow them) or requesting product behavior changes like blocking merges or altering comment formatting. Stick to what it can do: analyze code and leave comments.</p><h1>Review Before the PR Exists</h1><p>Most teams overlook Copilot&#8217;s ability to review locally, before code reaches a pull request.</p><p><strong>In the CLI</strong>, the <code>/review</code><a href="https://github.blog/changelog/2026-01-21-github-copilot-cli-plan-before-you-build-steer-as-you-go/"> slash command</a> analyzes staged or unstaged changes without leaving the terminal. Start an interactive <code>copilot</code> session in your project directory and run <code>/review</code>. Copilot delegates to a specialized <a href="https://github.blog/changelog/2026-01-14-github-copilot-cli-enhanced-agents-context-management-and-new-ways-to-install/">code-review agent</a> that focuses on surfacing genuine issues rather than style nitpicks. It reads the same <code>.github/copilot-instructions.md</code> from your repository.</p><pre><code><code># Start an interactive Copilot session in your project
$ copilot

# Review current changes (staged or unstaged)
&gt; /review

# Target a specific branch diff and focus area
&gt; /review Review changes in my current branch against main. Focus on security issues.</code></code></pre><p>The <code>/review</code> command runs inside an interactive session, not as a standalone flag. You can specify what to focus on. The code-review agent can also <a href="https://github.blog/changelog/2026-01-14-github-copilot-cli-enhanced-agents-context-management-and-new-ways-to-install/">run in parallel</a> with other specialized agents (Explore, Task, Plan), so a complex debugging session might analyze code, run tests, and review changes concurrently.</p><p><strong>In VS Code</strong>, open the Source Control view, hover over &#8220;Changes,&#8221; and click &#8220;Copilot Code Review.&#8221; Copilot reviews staged or unstaged changes and leaves inline comments using the same instruction files from your repository.</p><p><strong>In JetBrains</strong>, open the Commit tool window and select &#8220;Copilot: Review Code Changes&#8221; to get feedback before committing.</p><p>This shifts feedback earlier, while the code is still fresh in the developer&#8217;s mind. Cleaner PRs follow, and human reviewers stop wasting time on issues Copilot could have caught locally.</p><h1>Put Review Logic in Skills, Not Just Instructions</h1><p><a href="https://docs.github.com/en/copilot/concepts/agents/about-agent-skills">Agent Skills</a> go deeper than instruction files. Skills are folders containing instructions, scripts, and resources that Copilot loads when relevant. They work across VS Code, the CLI, and the coding agent. Where instruction files provide guidelines, skills enable specialized workflows with procedural knowledge and deterministic scripts.</p><p>There&#8217;s a practical reason to prefer skills over instruction files for the bulk of your review logic: portability. Instruction files in <code>.github/copilot-instructions.md</code> are GitHub-specific. They work with Copilot and nothing else. Skills follow the <a href="https://agentskills.io/home">agentskills.io</a> open standard, which means the same skill folder works across any tool that supports the format. If your team uses Claude Code alongside Copilot, or switches between Cursor and the CLI, review standards encoded as skills travel with you. Instruction files don&#8217;t.</p><p>Keep the repository-wide instruction file thin. Use it for Copilot-specific behavior: what to skip, confidence thresholds, response format. Move the substantive review logic, your team&#8217;s conventions, security checks, and architecture rules into skills that any agentic tool can consume.</p><p>You can get the best of both worlds by using <a href="https://github.blog/changelog/2025-09-03-copilot-code-review-path-scoped-custom-instruction-file-support/">path-specific instruction files</a> to point Copilot toward portable skills. Since instruction files and skills are both natural language that the LLM reads and follows, an instruction file can reference a skill by name or path, and Copilot will <a href="https://tiberriver256.github.io/ai%20and%20technology/skills-catalog-part-1-indexing-ai-context/">load and use it</a>. This gives you path-scoped triggering from instruction files with portable review logic in skills:</p><pre><code><code>&lt;!-- .github/instructions/swiftui-review.instructions.md --&gt;
---
applyTo: "**/Views/**/*.swift"
---
When reviewing SwiftUI views, use the swiftui-review skill
for team conventions and accessibility checks.
Flag any UIKit usage in SwiftUI view files.</code></code></pre><p>The instruction file stays thin: a few lines of path-specific context. The skill holds the detailed review logic and works across Copilot, Claude Code, and any other tool that supports the agentskills.io standard.</p><p>A code review skill for your team might encode the checks that matter most:</p><pre><code><code>code-review-skill/
&#9500;&#9472;&#9472; SKILL.md
&#9500;&#9472;&#9472; SECURITY.md
&#9492;&#9472;&#9472; scripts/
    &#9492;&#9472;&#9472; check_conventions.sh</code></code></pre><pre><code><code>&lt;!-- code-review-skill/SKILL.md --&gt;
---
name: team-code-review
description: &gt;
  Review code changes against team conventions and security standards.
  Use when asked to review code, PRs, or diffs.
---

# Code Review Skill

## Review Process
1. Run scripts/check_conventions.sh on changed files
2. Review SECURITY.md for security-specific checks
3. Evaluate logic correctness and edge case handling
4. Check for duplicated logic across the codebase

## What to Flag
- Functions exceeding cyclomatic complexity of 10
- Missing error handling on network calls
- Force unwraps in production code (test code is fine)
- Direct dependency on concrete implementations

## What to Skip
- Formatting issues (handled by SwiftLint)
- Import ordering
- Minor naming preferences</code></code></pre><p>The <code>scripts/check_conventions.sh</code> handles deterministic checks that don&#8217;t need an LLM. Token generation is probabilistic; scripts are deterministic. Use scripts for validation (lint checks, schema conformance), transformation (reformatting, boilerplate updates), and integration (API calls with specific auth requirements).</p><p>Skills use progressive disclosure. At startup, the model sees only the skill&#8217;s name and description from the YAML frontmatter, roughly 100 tokens. The full instructions load only when the skill is relevant. Additional files like <code>SECURITY.md</code> load on demand, keeping context lean until expertise is needed.</p><p>For Copilot specifically, store skills in the repository (<code>.github/skills/</code>) for your team, or in your home directory (<code>~/.copilot/skills/</code>) for personal use across projects. For broader use, keep skills in a shared repository that any tool can reference. They&#8217;re just folders, so they work with git and can be shared through whatever mechanism your team already uses.</p><h1>Automate PR Reviews</h1><p>Repository rulesets trigger Copilot review automatically. Go to Settings &gt; Rules &gt; Rulesets and create a new branch ruleset. Under &#8220;Branch rules,&#8221; select &#8220;Automatically request Copilot code review.&#8221; Two subsettings control the behavior:</p><p><strong>Review new pushes</strong> re-runs Copilot review when new commits land on the PR, so feedback stays current as the code evolves. Without this, Copilot only reviews once at PR creation.</p><p><strong>Review draft pull requests</strong> triggers reviews on drafts so authors can iterate with Copilot before requesting human review. This pairs well with local review: catch what you can locally, push a draft, let Copilot do a full pass, then mark ready for review.</p><p>Organization owners can apply rulesets across multiple repositories using pattern matching (<code>*feature</code> matches all repository names ending in &#8220;feature&#8221;). This rolls out Copilot review consistently without per-repo configuration.</p><p>Copilot code review also integrates <a href="https://docs.github.com/en/copilot/concepts/agents/code-review">CodeQL for security analysis</a> (enabled by default) and optionally ESLint and PMD. These tools run alongside the AI review, combining deterministic security scanning with probabilistic code analysis.</p><h1>Know If It&#8217;s Working</h1><p><a href="https://www.atlassian.com/blog/announcements/how-we-cut-pr-cycle-time-with-ai-code-reviews">Atlassian cut PR cycle time by 45%</a> by making Copilot the automated first reviewer on every PR. Their 18-hour average wait for first feedback dropped to minutes. New engineers merged their first PR five days faster.</p><p>But faster individual throughput doesn&#8217;t guarantee better team outcomes. The <a href="https://faros.ai/blog/key-takeaways-from-the-dora-report-2025">2025 DORA report</a> found that individual developers merged 98% more PRs while organizational delivery stability decreased 7.2%. <a href="https://www.cortex.io/post/ai-is-making-engineering-faster-but-not-better-state-of-ai-benchmark-2026">Cortex&#8217;s 2026 benchmark</a> found incidents per PR up 24% and change failure rates up 30% with AI adoption.</p><h2>What GitHub&#8217;s Dashboard Tells You</h2><p>GitHub&#8217;s <a href="https://docs.github.com/en/copilot/how-tos/administer-copilot/manage-for-enterprise/view-usage-and-adoption">Copilot usage metrics dashboard</a>, currently in public preview for Enterprise customers, tracks four categories: daily and weekly active users, code completion acceptance rates, chat interactions by mode (Ask, Edit, Agent), and agent adoption percentage. A separate <a href="https://docs.github.com/en/copilot/how-tos/administer-copilot/manage-for-enterprise/view-code-generation">code generation dashboard</a> breaks down lines of code changed by users versus agents, grouped by model and language.</p><p>The <a href="https://docs.github.com/en/rest/copilot/copilot-usage-metrics">usage metrics API</a> provides user-level granularity through JSON exports of <code>user_initiated_interaction_count</code>, <code>code_acceptance_activity_count</code>, and lines of code suggested versus accepted. Organization-level analytics arrived in December 2025. Team-level data is accessible through the <a href="https://docs.github.com/en/rest/copilot/copilot-metrics">Copilot Metrics API</a>. All of these derive from IDE telemetry, so users must have telemetry enabled to appear in reports.</p><p>This data answers adoption questions well. You can see who&#8217;s using Copilot, how often, in which IDEs, and with which models. You can spot teams with low adoption or users who interact frequently but rarely accept suggestions. For a rollout, these are useful leading indicators.</p><h2>What It Doesn&#8217;t Tell You</h2><p>None of GitHub&#8217;s built-in metrics track code review activity. No dashboard shows how many PRs Copilot reviewed, how many comments it left, how often authors accepted or dismissed suggestions, or the ratio of actionable feedback to noise. Nothing links Copilot usage data to PR workflow outcomes such as cycle time, change failure rate, or reviewer load distribution.</p><p>That&#8217;s a significant gap. These metrics measure whether people <em>use</em> Copilot, not whether it <em>helps</em>. Acceptance rate for code completions tells you suggestions are relevant. It says nothing about whether the code that ships is better or whether reviewers spend less time on routine checks.</p><h2>Measuring What Matters</h2><p>For code review, you&#8217;ll need to instrument your own measurements. GitHub&#8217;s <a href="https://docs.github.com/en/rest/pulls">Pull Request API</a> and <a href="https://docs.github.com/en/rest/pulls/reviews">Reviews API</a> provide the raw data. Track these before enabling AI review and compare after.</p><p><strong>PR cycle time.</strong> Time from PR creation to merge. This is the headline metric. If AI review works, the wait for first feedback drops and the overall cycle compresses.</p><p><strong>Reviewer load distribution.</strong> How many reviews each team member performs. AI review should flatten the curve, reducing the burden on the one or two senior engineers who currently review everything.</p><p><strong>Actionable comment rate.</strong> How many AI comments developers address versus dismiss. This is the best signal for instruction quality. If the team ignores most of Copilot&#8217;s feedback, the instructions need work, not the team.</p><p><strong>Change failure rate.</strong> Deployment failures or incidents tied to merged PRs. If this increases alongside faster cycle times, you&#8217;re trading quality for speed. The DORA and Cortex findings suggest this is the default outcome without deliberate quality gates.</p><p>Combine GitHub&#8217;s usage metrics API with your PR data for a fuller picture. Correlating <code>code_acceptance_activity_count</code> with PR cycle time per user reveals whether developers who engage more with Copilot also ship faster, or just generate more code that sits in review.</p><p>Run a focused experiment. Pick a two-week sprint. Measure current cycle times and reviewer load. Enable Copilot review on routine code first, where a false positive costs little and the team can calibrate without pressure. If the numbers improve, expand. If they don&#8217;t, tune the instructions before scaling.</p><h1>Start Simple</h1><p>The instinct is to write exhaustive instruction files covering every convention your team has discussed. Resist it. Start with the repository-wide file and five to ten rules. Add path-specific instructions only after the base is stable. Introduce skills when workflows justify the complexity. Expand based on what Copilot gets wrong.</p><p>The teams getting consistent value from AI code review share one trait: they treat configuration as a living document, not a one-time setup. The bottleneck was never writing code. It was proving the code works.</p><div><hr></div><h1>Implementation Checklist</h1><h2>Baseline</h2><p>Measure current PR cycle time across the team, from creation to merge. Record the median and 90th percentile.</p><p>Identify your reviewer load distribution. Who reviews the most PRs? How does your top reviewer&#8217;s load compare to the team average?</p><p>Document your current change failure rate. Without a baseline, you won&#8217;t know whether AI review improves or degrades quality.</p><p>Confirm your linting and CI pipeline catches formatting, syntax, and known anti-patterns. AI review should never duplicate what deterministic tools already handle.</p><h2>Configure</h2><p>Create <code>.github/copilot-instructions.md</code> with five to ten rules targeting your most common review feedback. Keep it under 1,000 lines. Include a &#8220;Do Not Comment On&#8221; section for anything linters already cover.</p><p>Add path-specific instruction files in <code>.github/instructions/</code> only after the base file is stable. Organize by concern: views, networking, models, tests, security.</p><p>Include concrete code examples showing correct and incorrect patterns. Copilot is better at mimicry than interpretation.</p><p>Set a confidence threshold. Tell Copilot to comment only when confidence is high and to keep comments concise.</p><h2>Pilot</h2><p>Enable Copilot review on routine code first, where false positives cost little. Use repository rulesets to automate review on a subset of branches or repositories.</p><p>Run the pilot for at least two weeks. Collect feedback from PR authors and human reviewers on comment quality and noise.</p><p>Track the actionable comment rate. If the team ignores most feedback, revise the instructions before expanding.</p><p>Encourage local review in the IDE or CLI before pushing. Cleaner PRs mean less noise for both AI and human reviewers.</p><h2>Expand</h2><p>Once the pilot is stable, enable automatic review on draft PRs so authors iterate with AI feedback before requesting human review.</p><p>Add skills for workflows complex enough to justify them: security checks, architectural conventions, team-specific patterns. Store them in a shared repository so they work across Copilot, Claude Code, Cursor, and other agentic tools.</p><p>Apply rulesets across repositories using organization-level pattern matching.</p><p>Monitor GitHub&#8217;s usage metrics dashboard for adoption trends. Correlate <code>code_acceptance_activity_count</code> with your PR cycle time data to see whether engagement translates to faster delivery.</p><h2>Sustain</h2><p>Treat instruction files as living documents. When Copilot flags something your team ignores, add an exclusion. When it misses something important, add a directive.</p><p>Review metrics monthly against your baseline. If the change failure rate climbs alongside faster cycle times, tighten quality gates before scaling further.</p><p>Verify senior engineers spend less time on repetitive checks and more on architecture, business logic, and mentoring. That outcome justifies the investment.</p><p>Never commit code you can&#8217;t explain.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Signal Check: February 13, 2026]]></title><description><![CDATA[This week's signal in AI and engineering]]></description><link>https://read.invoke.dev/p/signal-check-february-14-2026</link><guid isPermaLink="false">https://read.invoke.dev/p/signal-check-february-14-2026</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Fri, 13 Feb 2026 13:15:16 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ce0e4604-0925-41d8-88fb-683a1dd0ed98_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p></p><p>We&#8217;re two years into mainstream AI adoption and still figuring out the basics. How does it change workloads? Who&#8217;s accountable for agent-written code? This week brought a rigorous eight-month study, a legal analysis, and a practitioner reckoning that all point to the same conclusion: the tooling is ahead of our understanding of how to use it.</p><h2><a href="https://hbr.org/2026/02/ai-doesnt-reduce-work-it-intensifies-it">AI Doesn&#8217;t Reduce Work, It Intensifies It</a></h2><p><em>Aruna Ranganathan &amp; Xingqi Maggie Ye, Harvard Business Review</em></p><p>UC Berkeley tracked 200 employees for eight months. AI didn&#8217;t give time back. Workers expanded their scope, absorbed other people&#8217;s responsibilities, and stopped noticing where work ended. One engineer nailed it: &#8220;You had thought that maybe you could work less. But then, really, you don&#8217;t work less.&#8221; The Hacker News thread asked the obvious follow-up. If AI is so effective at reducing work, why are workloads increasing for companies that adopt it?</p><h2><a href="https://atmoio.substack.com/p/there-is-no-skill-in-ai-coding">There Is No Skill in AI Coding</a></h2><p><em>Mo Bitar</em></p><p>Bitar takes Karpathy&#8217;s honest assessment of agentic coding and turns it into a performance review. The comments are worth reading too. One reader compared AI to a leavening agent: too much and your bread implodes. Another pointed out that syntax memorization, the thing AI supposedly replaces, was already handled by LSPs and autocomplete years ago. The real work was never typing.</p><h2><a href="https://law.stanford.edu/2026/02/08/built-by-agents-tested-by-agents-trusted-by-whom/">Built by Agents, Tested by Agents, Trusted by Whom?</a></h2><p><em>Stanford Law School CodeX</em></p><p>Stanford&#8217;s legal team asks the question most engineering orgs are quietly avoiding. When agents optimize for &#8220;pass the tests&#8221; rather than &#8220;build good software,&#8221; who answers for it? The piece is blunt about the stakes. Reading and writing code has been the bedrock of this profession for seventy years. If that skill becomes optional, we should determine what replaces it as the basis for accountability.</p><h2><a href="https://x.com/karpathy/status/2019137879310836075">Karpathy: From &#8220;Vibe Coding&#8221; to &#8220;Agentic Engineering&#8221;</a></h2><p><em>Andrej Karpathy, via X</em></p><p>Karpathy called the original &#8220;vibe coding&#8221; post &#8220;a shower of thoughts throwaway tweet&#8221; and seemed genuinely surprised that it defined a movement. The new term is more deliberate. The community split predictably between those who see a new discipline forming and those who see a rebrand of common sense. What&#8217;s worth paying attention to: Karpathy still acknowledges models make &#8220;subtle conceptual errors,&#8221; overcomplicate code, and won&#8217;t manage their own confusion. That&#8217;s honest, coming from the person who started all of this.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[AI-assisted Code Reviews]]></title><description><![CDATA[Improve the Review Bottleneck Before Scaling Code Generation]]></description><link>https://read.invoke.dev/p/ai-assisted-code-reviews</link><guid isPermaLink="false">https://read.invoke.dev/p/ai-assisted-code-reviews</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Tue, 10 Feb 2026 13:03:11 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8e1bf704-4f9d-4d32-adbb-d3651f707ba0_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The Pull Request process has been a bottleneck for years. AI code generation didn&#8217;t create the problem, but it&#8217;s making it worse.</p><p>Before reaching for AI tools to increase code volume, fix the review process. </p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><blockquote><p>There&#8217;s no point in generating code faster if it sits in a queue waiting for someone to look at it. That&#8217;s not a productivity gain. It&#8217;s a traffic jam.</p></blockquote><p>The symptoms are familiar to anyone who&#8217;s worked on a team larger than a handful of engineers.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!W9yx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!W9yx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!W9yx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!W9yx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!W9yx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!W9yx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:211691,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://read.invoke.dev/i/187297009?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!W9yx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!W9yx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!W9yx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!W9yx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3da2085-df7e-45c4-93e7-8c0903ac700d_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Wait times are the most visible problem. <a href="https://www.atlassian.com/blog/announcements/how-we-cut-pr-cycle-time-with-ai-code-reviews">Atlassian&#8217;s engineers</a> waited an average of 18 hours for a first review comment, with median PR-to-merge times over three days. A developer submits a PR, switches context to something else, and then has to reload everything when feedback finally arrives. Each switch <a href="https://jonnyzzz.com/blog/2026/01/16/code-review-bottleneck/">costs roughly 23 minutes</a> of refocusing time.</p><p>Review responsibility tends to concentrate among a few senior engineers. They know the codebase best, so they get tagged on everything. When <a href="https://shiftmag.dev/code-review-problems-and-fixes-5060/">only the tech lead</a>consistently reviews PRs, it creates a <a href="https://thenewstack.io/the-anatomy-of-slow-code-reviews/">bottleneck that stalls the entire team</a>. Senior engineers end up spending their time catching naming conventions and missing null checks rather than mentoring or solving harder problems.</p><p>Then there&#8217;s fatigue. <a href="https://smartbear.com/learn/code-review/best-practices-for-peer-code-review/">SmartBear&#8217;s study of 2,500 code reviews at Cisco Systems</a> found that defect detection drops sharply after 60 minutes of continuous review, and reviewing faster than 500 lines of code per hour causes a severe decline in effectiveness. When reviewers are exhausted, approvals become rubber stamps. The gate still exists, but it no longer catches problems.</p><p>AI coding tools increased the volume without increasing review capacity. <a href="https://www.qodo.ai/blog/best-ai-code-review-tools-2026/">GitHub&#8217;s Octoverse report</a> shows monthly code pushes crossing 82 million, with about 41% AI-assisted. The number of human reviewers hasn&#8217;t changed.</p><p>The code itself is harder to review. <a href="https://www.coderabbit.ai/blog/state-of-ai-vs-human-code-generation-report">AI-authored PRs contain 10.83 issues on average</a> compared to 6.45 for human-written code. Security vulnerabilities appear 1.5-2x more often. And the code looks clean. AI output is polished enough to <a href="https://arxiv.org/html/2508.14727v1">hide subtle errors</a>, so every line needs scrutiny, and there are now more lines to review than ever before.</p><p>Increasing code volume in an already constrained review process doesn&#8217;t improve throughput. It degrades it.</p><p>AI code review tools won&#8217;t fix the fundamental capacity problem. But they address aspects of review that humans struggle to sustain: speed, consistency, and pattern recognition.</p><p>The biggest gain is eliminating the wait for first feedback. <a href="https://www.atlassian.com/blog/announcements/how-we-cut-pr-cycle-time-with-ai-code-reviews">Atlassian cut PR cycle time by 45%</a> by making AI the automated first reviewer on every PR. That 18-hour wait dropped to minutes. New engineers who used the AI reviewer merged their first PR five days faster. The code still needed human review, but authors could start fixing obvious problems immediately rather than sit idle.</p><p>Consistency is the less obvious but more durable gain. AI applies the same rules to every pull request. No bad days. No variation based on which reviewer picks up the PR. Traditional linters enforce formatting and reliably catch known anti-patterns; they should be the first layer of any review pipeline. But linters can&#8217;t evaluate whether a function name communicates intent, whether error handling is sufficient for the context, or whether a block of code duplicates logic from elsewhere. Custom lint rules are time-consuming to write and brittle to maintain. AI handles these fuzzy checks naturally. You describe the check in plain language, and it applies probabilistic judgment. Linters for deterministic rules, AI for pattern matching.</p><p>Think of it as triage. AI handles the first pass, catches common mistakes, and flags obvious security issues. By the time a senior engineer opens the PR, most of the noise is gone. They can focus on architecture, business logic, and mentoring.</p><blockquote><p>AI operates within a limited context. Maintainability, scalability, and architectural fit demand judgment that current models can&#8217;t provide. </p></blockquote><p>Senior engineers earn that title precisely because they connect code changes to business needs, architectural direction, and long-term system health. That connective reasoning is the review work that matters most. <a href="https://graphite.com/blog/ai-wont-replace-human-code-review">Graphite&#8217;s analysis</a> put it simply: AI can tell you code is inefficient, but only a senior developer can explain why a different approach works better for your specific system.</p><p>Even a perfect automated review that caught every defect would still fall short. Preventing bugs isn&#8217;t the only reason for a code review. A human must be accountable for every change that reaches production. No tool changes that.</p><p>Code review also serves purposes that don&#8217;t show up in cycle time metrics. It&#8217;s how senior engineers mentor juniors, how teams share context, and how better solutions surface through discussion.</p><p>The instinct when AI tools arrive is to prioritize code generation. That&#8217;s backward. The constraint was never writing code. It was proving that the code works.</p><p>The organizations seeing results with their AI adoption started with review, not generation. <a href="https://www.atlassian.com/blog/announcements/how-we-cut-pr-cycle-time-with-ai-code-reviews">Atlassian cut PR cycle time by 45%</a> by making AI the automated first reviewer on every PR. The biggest gain wasn&#8217;t catching more bugs. It was eliminating the wait for the first feedback.</p><p>But there&#8217;s a trap. Out of the box, most AI review tools produce more noise than signal. They flag style preferences, suggest unnecessary refactors, and generate comments that don&#8217;t warrant attention. A developer who gets fifteen low-value comments on their first AI-reviewed PR will ignore comment sixteen, even if it&#8217;s the one that matters. Fine-tuning the AI instructions determines whether it becomes part of the workflow or is quietly disabled after a month.</p><p>The sequencing matters. Measure your current review process. Know your cycle times, your reviewer load distribution, and your change failure rate. Introduce AI review on routine code first, where the cost of a false positive is low, and the team can calibrate without pressure. Validate that senior engineers are spending less time on repetitive checks and more on architecture, business logic, and mentoring. Then, once the review infrastructure can handle increased volume, scale code generation.</p><p>Generating code faster is easy. The hard part is building the review process that keeps up.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Critical Thinking Paradox]]></title><description><![CDATA[AI coding assistants demand strong critical thinking skills while systematically undermining the development of these same skills. Adopt research-backed strategies for preserving expertise while using AI effectively.]]></description><link>https://read.invoke.dev/p/the-critical-thinking-paradox</link><guid isPermaLink="false">https://read.invoke.dev/p/the-critical-thinking-paradox</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Mon, 02 Feb 2026 16:26:14 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/be8c0adb-adfa-4c90-9c3b-79886efdadbd_1536x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>AI coding tools have a problem. They require strong critical thinking to use effectively, yet they erode the very skills on which they depend. The better AI gets at writing code, the worse we become at evaluating it.</p><p>When developers delegate thinking to AI, they shift from solving problems to orchestrating code production. Developers move from &#8220;independent thinking, manual coding, iterative debugging&#8221; to &#8220;AI-assisted ideation, interactive programming, collaborative optimization.&#8221; Researchers call this <a href="https://arxiv.org/abs/2506.23253">material disengagement</a>. They selectively supervise rather than engage deeply.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p><a href="https://arxiv.org/abs/2601.20245">Anthropic&#8217;s January 2026 study</a> provides the evidence. In a randomized trial with 52 software engineers learning a new Python library, participants using AI scored 17% lower on comprehension tests than those who coded manually, with debugging as the largest gap. Developers using AI couldn&#8217;t identify errors or explain why the code failed.</p><p>The speed gains weren&#8217;t statistically significant. Participants using AI finished approximately two minutes faster on average, but spent up to 30% of their time composing queries. For learning tasks, AI slows you down while reducing what you learn.</p><p>Developers get trapped in a vicious cycle. They submit incorrect AI-generated code, ask the AI to fix it, receive more incorrect code, and repeat the process. Only a minority <a href="https://arxiv.org/abs/2501.10091">analyzes what the AI produces</a>. Fixing the prompt feels easier than understanding the code.</p><p>Meanwhile, enterprises measure velocity rather than understanding. <a href="https://survey.stackoverflow.co/2025/">Stack Overflow&#8217;s 2025 survey</a> found that 84% of developers now use AI tools, yet only 33% trust their accuracy. The top source of frustration, cited by 66%, is solutions that are &#8220;almost right, but not quite.&#8221; We optimize for the wrong metrics. Output without learning. Speed without comprehension.</p><h1>Why Critical Thinking Matters</h1><p>AI-generated code looks correct. That&#8217;s the problem. It compiles, passes basic tests, and reads like something a competent developer wrote. But <a href="https://www.coderabbit.ai/blog/state-of-ai-vs-human-code-generation-report">CodeRabbit&#8217;s analysis of 470 pull requests</a> found that AI-generated code produces 1.7x more issues than human-written code. Security vulnerabilities appear twice as often. Logic errors increase 75%. These aren&#8217;t obvious failures. They&#8217;re subtle defects that slip through review and surface in production.</p><p>AI doesn&#8217;t understand your codebase. It doesn&#8217;t know your architecture, business rules, or domain constraints. <a href="https://www.veracode.com/blog/ai-generated-code-security-risks/">Veracode&#8217;s 2025 report</a> found that AI introduced security vulnerabilities in 45% of coding tasks because models optimize for the shortest path to a passing result, not the safest one. The code works in isolation but ignores the system it&#8217;s joining. One development leader described it bluntly: &#8220;Very difficult to maintain, very difficult to understand, and in a production environment, none of that is suitable.&#8221;</p><p>The debt compounds. <a href="https://leaddev.com/technical-direction/how-ai-generated-code-accelerates-technical-debt">GitClear&#8217;s analysis of 211 million lines of code</a> found that code duplication surged 8-fold between 2022 and 2024. Copy-pasted lines now exceed refactored lines. MIT professor Armando Solar-Lezama called AI a &#8220;brand new credit card that is going to allow us to accumulate technical debt in ways we were never able to do before.&#8221; A <a href="https://www.sonarsource.com/blog/the-inevitable-rise-of-poor-code-quality-in-ai-accelerated-codebases/">Harness survey</a> found that 67% of developers now spend more time debugging AI-generated code than writing it themselves.</p><p>Critical thinking matters more now because the cost of skipping it is higher. Bad code from a junior developer triggers scrutiny. Confident-sounding code from AI bypasses it. The volume overwhelms reviewers. The plausibility defeats skepticism. Without deliberate evaluation, technical debt accumulates until the only path forward is a costly rewrite.</p><h1>Inverting the Workflow</h1><p>The current workflow runs backward. AI writes code and humans fix, review, and maintain it. This inverts learning and produces developers who can&#8217;t function when AI fails.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2im0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2im0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!2im0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!2im0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!2im0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2im0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1266931,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://read.invoke.dev/i/186608209?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!2im0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!2im0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!2im0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!2im0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3fb7f79e-b561-48a5-965b-c36a22282bf9_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Addy Osmani describes a different approach: &#8220;<a href="https://addyosmani.com/blog/ai-coding-workflow/">AI-augmented software engineering rather than AI-automated software engineering</a>.&#8221; The distinction matters. He uses AI aggressively while staying &#8220;proudly accountable for the software produced.&#8221;</p><p>The fix is simple in concept. Flip the workflow: humans plan and create, AI refactors and maintains, humans verify. Let AI handle the drudgery. Keep humans doing creative problem-solving that builds expertise.</p><h2>Think Before You Prompt</h2><p>Write your own requirements. Make your own architecture decisions. Draft your own test cases. Then use AI for validation: &#8220;Did you consider this option? Here are the trade-offs.&#8221; Get education, not answers.</p><p>Osmani&#8217;s workflow starts with brainstorming a detailed specification with the AI, then outlining a step-by-step plan, before writing any actual code. &#8220;This upfront investment might feel slow, but it pays off enormously.&#8221; He likens it to doing &#8220;waterfall in 15 minutes,&#8221; a rapid structured planning phase that makes subsequent coding smoother.</p><p>The key insight: if you ask the AI for too much at once, &#8220;it&#8217;s likely to get confused or produce a jumbled mess that&#8217;s hard to untangle.&#8221; Developers report AI-generated code that feels &#8220;like 10 devs worked on it without talking to each other.&#8221; The fix is to stop, back up, and split the problem into smaller pieces.</p><h2>Apply Systematic Review</h2><p><a href="https://github.blog/news-insights/research/does-github-copilot-improve-code-quality-heres-what-the-data-says/">GitHub&#8217;s research</a> found that developers using Copilot wrote 13.6% more lines of code with fewer readability errors, but only under rigorous human review. Use structured rubrics: inconsistent naming, unclear identifiers, excessive complexity, missing documentation, repeated code. Review is where learning happens.</p><p>Osmani treats every AI-generated snippet as if it were produced by a junior developer. &#8220;I read through the code, run it, and test it as needed. You absolutely have to test what it writes.&#8221; He sometimes spawns a second AI session to critique code produced by the first. &#8220;The key is to not skip the review just because an AI wrote the code. If anything, AI-written code needs extra scrutiny.&#8221;</p><h2>Set Intentional Boundaries</h2><p>A study found that participants who succeed <a href="https://arxiv.org/abs/2511.13996">limit AI&#8217;s contribution to approximately 30%</a>. Reserve creative and high-level decisions for yourself. Use AI for boilerplate, not core problem-solving. After each interaction, ask: &#8220;Did I learn anything?&#8221;</p><p>Anthropic&#8217;s research revealed distinct interaction patterns with dramatically different outcomes. The lowest-scoring developers delegated the work entirely to AI. The highest-scoring developers asked only conceptual questions while coding independently. They used AI for understanding, not production.</p><p>The pattern that combined speed with strong learning: &#8220;Generation-then-Comprehension.&#8221; Generate code, then ask follow-up questions to understand it. Alternatively, the &#8220;Hybrid Code-Explanation&#8221; approach: request code and explanations simultaneously. Slower, but you actually learn.</p><h2>Build Fast Feedback Loops</h2><p>Generate code during planning to see implications early. Test AI output immediately. Don&#8217;t accumulate tech debt. Treat AI drafts as conversation starters, not final products.</p><p>Osmani weaves testing into the workflow itself. &#8220;If I&#8217;m using a tool like Claude Code, I&#8217;ll instruct it to run the test suite after implementing a task, and have it debug failures if any occur.&#8221; This tight feedback loop (write code, run tests, fix) works because the AI excels at it, provided the tests exist.</p><p>Without tests, the agent might assume everything is fine when in reality it&#8217;s broken several things. So invest in tests. It amplifies the AI&#8217;s usefulness and your confidence in the result.</p><h2>Maintain Skills Deliberately</h2><p>Spend a few hours weekly on manual coding. Read documentation, not AI explanations. Talk to both AI optimists and skeptics. The goal isn&#8217;t rejecting AI. It&#8217;s remaining competent when AI fails.</p><p>Osmani addresses this directly: &#8220;For those worried that using AI might degrade their abilities, I&#8217;d argue the opposite, if done right. By reviewing AI code, I&#8217;ve been exposed to new idioms and solutions. By debugging AI mistakes, I&#8217;ve deepened my understanding.&#8221;</p><p>The catch is the &#8220;if done right&#8221; part. You must stay informed, actively reviewing and understanding everything. Otherwise, you&#8217;re just outsourcing your judgment to a statistical engine.</p><h1>The Stakes</h1><p>We&#8217;re creating a workforce that generates code quickly but cannot debug when AI fails, cannot understand system architecture, cannot maintain code over the long term, and cannot develop the expertise required to become senior engineers.</p><p>Here&#8217;s the uncomfortable truth from Anthropic&#8217;s research: <a href="https://arxiv.org/abs/2601.19062">developers rate disempowering interactions more favorably</a>. They actively seek complete solutions. They accept AI output without pushback. The disempowerment isn&#8217;t manipulation. It&#8217;s voluntary abdication.</p><p>But everything you&#8217;ve learned won&#8217;t be wasted. Problem-solving and decomposition matter forever. The question isn&#8217;t whether AI will keep improving. It will. The question is whether we improve alongside it.</p><p>Done right, AI handles the drudgery while we focus on creativity. It enables prototyping at the speed of thought. It frees mental energy for meaningful work. But only if we stay in the driver&#8217;s seat.</p><p>The developers who thrive won&#8217;t generate the most code or ship the fastest. They&#8217;ll be the ones who never stop thinking critically. They&#8217;ll treat AI as a powerful tool requiring careful thought, not a substitute for it.</p><p>Next time you reach for an AI coding tool, pause. Am I learning from this interaction, or outsourcing my thinking? Your answer determines whether AI amplifies or atrophies your abilities.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[MCPs, Agents, Skills. Oh My!]]></title><description><![CDATA[Understanding the emerging ecosystem of LLM building blocks]]></description><link>https://read.invoke.dev/p/mcps-agents-skills-oh-my</link><guid isPermaLink="false">https://read.invoke.dev/p/mcps-agents-skills-oh-my</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Tue, 27 Jan 2026 13:36:54 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/4cec017c-d9b1-4dcf-8022-e7a389540989_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>LLMs are, without question, an impressive achievement at a scale few companies have the resources to pull off. However, when first introduced, LLMs had very limited practical applications. They&#8217;re unaware of the world after their training cutoff and unable to connect to tools that would let them accomplish real-world tasks. Ask a model to check your calendar, query a database, or search for recent news, and it can only apologize or hallucinate. The model has general intelligence but no hands to work with.</p><p>The model ecosystem has grown to include tools that allow the models to connect to the real world, moving beyond a static understanding. Most notably among these tools are MCPs, agents, and skills. Each of these tools solves a specific limitation, building toward AI tools that can actually get work done.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>MCP: Connecting Models to the World</h1><p><a href="https://modelcontextprotocol.io/">Model Context Protocol </a>gives LLMs the ability to connect to external tools and data sources. Through MCP, a model can access your file system, query databases, call APIs, and search the web. The protocol standardizes these connections, enabling tool integrations to work across different models and platforms. Build an MCP server once, and it works with Claude, GPT, and any other model that supports the protocol.</p><p>This was a game-changer. MCP quickly became <a href="https://www.anthropic.com/news/model-context-protocol">a de facto standard</a> adopted across model providers and tools. Suddenly, AI assistants could do things rather than just discuss them.</p><p>But MCP brought its own problems. Every tool definition <a href="https://www.anthropic.com/engineering/code-execution-with-mcp">loads into the context window upfront</a>, whether you need it or not. Connect several MCP servers, and you might burn 50,000+ tokens before the conversation even starts. This exacerbates issues with context windows, leaving less room for the actual work and accelerating context rot, the degradation in model performance as token counts climb.</p><h1>Agents: Isolating Context</h1><p>Agents address the context window pressure by allowing subprocesses to work with isolated context windows. When a lead agent spawns a subagent, that worker gets a fresh context, separate from the main conversation. The subagent might consume 100,000 tokens investigating a problem, but returns only a condensed summary. The main thread stays clean.</p><p>This alleviates much of the pressure from context rot, but agents remain general-purpose rather than specialized. An agent knows how to reason and use tools, but it doesn&#8217;t know your company&#8217;s specific processes, conventions, or requirements. Every agent needs the same detailed instructions repeated, and there&#8217;s no good way to share that expertise across your team.</p><h1>Skills: Lightweight Specialization</h1><p>This is where skills come into play. <a href="https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills">Skills</a> package procedural knowledge, the &#8220;how we do things here&#8221; that agents lack, into lightweight, reusable modules. A skill is just a folder containing instructions, workflows, and optional scripts.</p><pre><code><code>code-review-skill/
&#9500;&#9472;&#9472; SKILL.md           # Main instructions with metadata
&#9500;&#9472;&#9472; CHECKLIST.md       # Review criteria for your team
&#9492;&#9472;&#9472; scripts/
    &#9492;&#9472;&#9472; lint_check.py  # Deterministic validation</code></code></pre><p>Skills are only fully loaded on demand. At startup, the model sees just the skill&#8217;s metadata, roughly 100 tokens describing what it does. The full instructions load only when the model determines the skill is relevant. This progressive disclosure keeps the context window lean until expertise is actually needed.</p><p>Skills can also leverage scripts for deterministic tasks, making them more efficient than general reasoning. When you need exact behavior, like applying a specific code transformation or validating against a checklist, the skill runs a script rather than asking the model to generate the logic each time. Token generation is probabilistic; scripts are deterministic.</p><p>Skills can be used in combination with MCPs and agents, but they provide significant value on their own. You don&#8217;t need a complex multi-agent setup to benefit. A single model with the right skills can handle sophisticated workflows that would otherwise require elaborate prompting or custom tooling.</p><h1>Deep Dive: Working with Skills</h1><p>Let&#8217;s look at how to derive practical value from skills in engineering workflows.</p><h2>What Makes a Good Skill</h2><p>The best skills encode knowledge that would take an outsider weeks to absorb. Your team&#8217;s code review standards, your deployment procedures, your API design conventions. This institutional knowledge typically lives in wikis nobody reads or in the heads of senior engineers. Skills make it actionable.</p><p>A skill should have a clear, narrow purpose. &#8220;Code review&#8221; is better than &#8220;help with development.&#8221; The model needs to know when to activate the skill, and vague descriptions lead to false matches or missed opportunities.</p><p>Include enough context that the skill works without additional explanation. If your code review skill references your team&#8217;s error handling patterns, include those patterns in the skill rather than assuming the model knows them.</p><h2>Structure and Organization</h2><p>Every skill starts with a SKILL.md file containing YAML frontmatter and markdown instructions:</p><pre><code><code>---
name: api-design
description: Design REST APIs following team conventions
version: 1.0.0
---

# API Design Skill

## Conventions
- Use plural nouns for resource names
- Version APIs in the URL path (/v1/resources)
- Return 201 for successful creation, 200 for updates
...</code></code></pre><p>Additional markdown files can provide specialized guidance. A code review skill might use separate files for security, performance, and style reviews. The model loads these as needed based on the task.</p><p>Scripts go in a scripts directory. These handle operations where deterministic execution matters more than flexibility. A skill for database migrations might include a script that validates migration files against your schema conventions before the model even looks at the content.</p><pre><code><code>code-review-skill/
&#9500;&#9472;&#9472; SKILL.md &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; Instructions + YAML metadata
&#9474;                        (loaded when skill activates)
&#9500;&#9472;&#9472; CHECKLIST.md &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; Team-specific review criteria
&#9474;                        (loaded when needed)
&#9500;&#9472;&#9472; SECURITY.md &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472; Security-focused guidance
&#9474;                        (loaded for security reviews)
&#9492;&#9472;&#9472; scripts/
&#9;&#9492;&#9472;&#9472; lint_check.py &#9472;&#9472; Deterministic validation
                     &#9; (executed, not generated)</code></code></pre><h2>Where Scripts Add Value</h2><p>Scripts shine for three types of tasks:</p><p><strong>Validation</strong>: Check that the generated code meets structural requirements before presenting it. Lint checks, schema validation, and format verification.</p><p><strong>Transformation</strong>: Apply consistent changes that would be tedious to describe in natural language. Reformatting imports, updating boilerplate, applying code style rules.</p><p><strong>Integration</strong>: Connect to external systems where precise interactions are required. API calls with specific authentication, database queries with exact syntax, and file operations with particular permissions.</p><p>The model handles reasoning and judgment. Scripts handle precision and reliability.</p><h2>Sharing and Versioning</h2><p>Skills are just folders, so they work with your existing tools. Store them in Git for version control. Share them through Google Drive or your team&#8217;s documentation system. The <a href="https://agentskills.io/home">agentskills.io</a> open standard means skills you create work across platforms that support the format.</p><p>For team adoption, start with skills that codify processes you&#8217;re already documenting. Onboarding checklists, incident response procedures, and release processes. These have clear value, and the content already exists in some form.</p><h2>Measuring Impact</h2><p>Track token consumption before and after skill adoption. The theoretical gains are significant, skills loading ~5,000 tokens versus MCP tools loading 60,000+, but your specific workflows will vary.</p><p>More importantly, track whether the model&#8217;s outputs improve. Are code reviews catching the issues your team cares about? Are the generated APIs following your conventions? Skills should produce noticeably better results for your specific context, not just save tokens.</p><h1>Putting It Together</h1><p>The full stack works like this:</p><ul><li><p><strong>LLM</strong>: Provides reasoning and generation capabilities</p></li><li><p><strong>MCP</strong>: Connects the model to external tools and data sources</p></li><li><p><strong>Agents</strong>: Enable parallel processing with isolated context windows</p></li><li><p><strong>Skills</strong>: Supply domain expertise and deterministic procedures</p></li></ul><p>You don&#8217;t need all layers for every workflow. A model with skills but no MCP connections can still provide substantial value for tasks that don&#8217;t require access to external tools. Skills layered on MCP give you both connectivity and expertise. Agents add parallel processing when tasks genuinely benefit from isolation.</p><p>For most engineering teams, skills offer the highest return for the lowest complexity. Start there. Add agents when you have workflows that clearly need parallel, isolated execution. Expand MCP connections as you identify tools the model needs to access.</p><h1>Looking Ahead</h1><p>In the course of a year, we&#8217;ve seen MCP, agents, and skills emerge as standards for getting more out of LLMs. Each solves a real limitation: MCP connects models to tools, agents manage context isolation, and skills provide lightweight specialization.</p><p>It will be interesting to see what this year brings.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Avoiding the AI Complexity Cliff]]></title><description><![CDATA[Managing scope in AI-assisted development]]></description><link>https://read.invoke.dev/p/avoiding-the-ai-complexity-cliff</link><guid isPermaLink="false">https://read.invoke.dev/p/avoiding-the-ai-complexity-cliff</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Tue, 20 Jan 2026 13:36:34 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/a9e0fa20-1228-4147-9786-574ca85c3371_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5STM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e86cb51-fba1-4a24-ba9a-a1f4b3f494fc_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5STM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e86cb51-fba1-4a24-ba9a-a1f4b3f494fc_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!5STM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e86cb51-fba1-4a24-ba9a-a1f4b3f494fc_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!5STM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e86cb51-fba1-4a24-ba9a-a1f4b3f494fc_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!5STM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e86cb51-fba1-4a24-ba9a-a1f4b3f494fc_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5STM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e86cb51-fba1-4a24-ba9a-a1f4b3f494fc_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3e86cb51-fba1-4a24-ba9a-a1f4b3f494fc_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;content.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="content.png" title="content.png" srcset="https://substackcdn.com/image/fetch/$s_!5STM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e86cb51-fba1-4a24-ba9a-a1f4b3f494fc_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!5STM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e86cb51-fba1-4a24-ba9a-a1f4b3f494fc_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!5STM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e86cb51-fba1-4a24-ba9a-a1f4b3f494fc_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!5STM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e86cb51-fba1-4a24-ba9a-a1f4b3f494fc_1536x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In AI-assisted development, LLMs would ideally understand everything there is to know about our codebase, interpret any instructions, and answer any question with the full context of the project. After all, context is king, especially with LLMs. But most real-world projects are too large and complex for that to be even remotely feasible.</p><p>A typical enterprise application might contain more than 200,000 lines of code across 1,500 files. That&#8217;s roughly 800,000 tokens before documentation, build configuration, or tests. Even a million-token window can&#8217;t hold it all. But capacity isn&#8217;t the real constraint. Models start degrading long before they hit the limit.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Research from Stanford and Berkeley identified what they call the <a href="https://arxiv.org/abs/2307.03172">lost-in-the-middle phenomenon</a>: LLMs perform best when relevant information sits at the beginning or end of the input context, with significant degradation when models must access information buried in the middle. Performance follows a U-shaped curve, favoring primacy and recency while struggling with everything between.</p><p>Practitioners have noticed this gap between advertised capacity and effective use. Dex Horthy at HumanLayer popularized the term &#8220;dumb zone&#8221; in his presentation <a href="https://www.youtube.com/watch?v=rmvDxxNubIg">&#8220;No Vibes Allowed: Solving Hard Problems in Complex Codebases&#8221;</a> to describe the region where LLM reasoning degrades as context usage grows past 40-60% of maximum capacity. A model claiming 200K tokens becomes unreliable around 130K. The threshold isn&#8217;t a gradual decline. It&#8217;s a cliff.</p><p>We can&#8217;t just feed in context and hope for miracles. Every token competes for the model&#8217;s limited attention budget. What we include matters. When we include it matters. The order in which we present information matters. Context engineering becomes as important as the prompts themselves.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!x-xB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F950b87b8-a986-4ff0-a33e-6eadacb68668_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!x-xB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F950b87b8-a986-4ff0-a33e-6eadacb68668_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!x-xB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F950b87b8-a986-4ff0-a33e-6eadacb68668_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!x-xB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F950b87b8-a986-4ff0-a33e-6eadacb68668_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!x-xB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F950b87b8-a986-4ff0-a33e-6eadacb68668_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!x-xB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F950b87b8-a986-4ff0-a33e-6eadacb68668_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/950b87b8-a986-4ff0-a33e-6eadacb68668_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;content_1.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="content_1.png" title="content_1.png" srcset="https://substackcdn.com/image/fetch/$s_!x-xB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F950b87b8-a986-4ff0-a33e-6eadacb68668_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!x-xB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F950b87b8-a986-4ff0-a33e-6eadacb68668_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!x-xB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F950b87b8-a986-4ff0-a33e-6eadacb68668_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!x-xB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F950b87b8-a986-4ff0-a33e-6eadacb68668_1536x1024.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Three Patterns, One Problem</strong></h2><p>What makes AI-assisted development challenging isn&#8217;t any single limitation. It&#8217;s the interaction of three related patterns that compound as work complexity increases. Understanding these patterns is essential for knowing when to push forward and when to start fresh.</p><p>The first is <strong>context rot</strong>. This is about volume and position, not task difficulty. As you add more tokens to the context window, the model&#8217;s ability to find and use relevant information degrades. The culprit is attention: every token competes with every other token. Add 10,000 tokens of background code, and the 500 tokens that actually matter get harder to locate.</p><p><a href="https://research.trychroma.com/context-rot">Chroma Research</a> documented this effect systematically. Information buried in the middle of long contexts gets missed, even when it&#8217;s exactly what the model needs. Related-but-irrelevant content is worse than random noise because it looks relevant enough to distract. The practical result: you can make a model perform worse by giving it more context, even when that context is accurate and related to the task.</p><p>The second, and often most damaging in practice, is <strong>trajectory poisoning</strong>. When an AI coding session goes wrong, the errors don&#8217;t just disappear. They become part of the context the model uses for subsequent reasoning. The model references its own mistakes. Attempts to correct them introduce more confusion. Failed approaches, abandoned code paths, and accumulated misunderstandings pollute the working context until the model gets stuck in patterns it can&#8217;t escape.</p><p>There is no course correction that can fix the context. Once a trajectory goes bad, the context is poisoned. Every subsequent interaction draws on that polluted history. The model confidently builds on flawed foundations, producing output that looks reasonable but compounds the original errors.</p><p>The third is the <strong>reasoning cliff</strong>. This is about task complexity, not context size. As problems require more reasoning steps or involve more interacting variables, model accuracy doesn&#8217;t decline gradually. It collapses.</p><p><a href="https://machinelearning.apple.com/research/gsm-symbolic">Apple&#8217;s GSM-Symbolic research</a> documented this threshold systematically. Adding a single clause that seems relevant to a math problem caused performance drops of up to 65% across all state-of-the-art models, even when that clause contributed nothing to the solution. The models aren&#8217;t reasoning through the problem. They&#8217;re pattern-matching, and extra complexity breaks the pattern. The practical result: you can&#8217;t fix a task that&#8217;s past the cliff by prompting better. You have to simplify the task itself.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fW90!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fW90!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!fW90!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!fW90!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!fW90!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fW90!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1282555,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://read.invoke.dev/i/185102624?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fW90!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!fW90!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!fW90!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!fW90!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F250a9e25-c96d-44ca-a3fa-cde4245a6884_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>These patterns interact. Context rot makes trajectory poisoning more likely. Poisoned trajectories push tasks past the reasoning cliff. The compound effect explains why AI-assisted development can feel so inconsistent: sometimes brilliantly helpful, sometimes stubbornly wrong in ways that resist correction.</p><h3><strong>Diminishing Returns</strong></h3><p>These phenomena share a common root. Transformer attention scales quadratically with sequence length. Every token must be compared with every other token, so doubling context length quadruples computational cost. But the problem isn&#8217;t just compute. The model&#8217;s ability to maintain meaningful relationships across vast token distances degrades even when hardware handles the load.</p><p>Apple&#8217;s research revealed something counterintuitive: when problems become very difficult, models actually expend less reasoning effort. Their internal heuristics signal diminishing returns, so they give up rather than trying harder. <a href="https://towardsdatascience.com/your-1m-context-window-llm-is-less-powerful-than-you-think/">Stanford researchers</a> found similar limits on working memory. LLMs can track at most 5-10 variables before performance degrades toward random guessing.</p><p>Don&#8217;t assume that because an answer is computable from the context, an LLM can compute it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!b0kF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b0ae0de-9323-45ed-8d52-332910551ba7_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!b0kF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b0ae0de-9323-45ed-8d52-332910551ba7_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!b0kF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b0ae0de-9323-45ed-8d52-332910551ba7_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!b0kF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b0ae0de-9323-45ed-8d52-332910551ba7_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!b0kF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b0ae0de-9323-45ed-8d52-332910551ba7_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!b0kF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b0ae0de-9323-45ed-8d52-332910551ba7_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6b0ae0de-9323-45ed-8d52-332910551ba7_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;content_5.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="content_5.png" title="content_5.png" srcset="https://substackcdn.com/image/fetch/$s_!b0kF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b0ae0de-9323-45ed-8d52-332910551ba7_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!b0kF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b0ae0de-9323-45ed-8d52-332910551ba7_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!b0kF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b0ae0de-9323-45ed-8d52-332910551ba7_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!b0kF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b0ae0de-9323-45ed-8d52-332910551ba7_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Managing Complexity</strong></h2><p>The temptation when hitting these limits is to wait for better models. Larger context windows. More sophisticated reasoning. The tools improve constantly. This approach misses the point.</p><p>Addy Osmani captures it well in his <a href="https://addyo.substack.com/p/my-llm-coding-workflow-going-into">LLM coding workflow guide</a>: scope management is everything. Feed the LLM manageable tasks, not the whole codebase at once. Break projects into iterative steps and tackle them one by one. Each chunk should be small enough that the AI can handle it effectively and you can understand the code it produces.</p><p>This mirrors good software engineering practice, but it&#8217;s even more important with AI in the loop. LLMs do best with focused prompts: implement one function, fix one bug, add one feature at a time. If you ask for too much at once, the model is likely to produce low-quality results.</p><p><strong>Keep Tasks Small and Focused</strong></p><p>Keep the problem scope narrow enough that you can hold the entire context in your head. If you can&#8217;t explain what the AI should do in a sentence or two, the task is too big. Split it.</p><p>Provide only the context the AI needs for the current task. Dumping your entire codebase into context doesn&#8217;t help. It actively hurts by filling the effective working space with noise.</p><p><strong>Use Subagents to Scope Context, Not Define Roles</strong></p><p>Agents aren&#8217;t just about role-playing different personas. Their real value lies in constraining which context is loaded at each step of work.</p><p>A research agent pulls documentation and API references. An implementation skill loads only the module being modified. Testing skills focus on test files and the code under test. <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">Anthropic&#8217;s context engineering guidance</a> explains this pattern: rather than having a single agent maintain state across an entire project, specialized sub-agents handle focused tasks with clean context windows.</p><p>The subagent pattern works because each step operates with focused context rather than the accumulated noise of everything that came before. Think of skills and subagents as context boundaries, not personality changes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MjWm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F229b35dd-8291-4380-a3af-5ee92b8b87c4_1536x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MjWm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F229b35dd-8291-4380-a3af-5ee92b8b87c4_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!MjWm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F229b35dd-8291-4380-a3af-5ee92b8b87c4_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!MjWm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F229b35dd-8291-4380-a3af-5ee92b8b87c4_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!MjWm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F229b35dd-8291-4380-a3af-5ee92b8b87c4_1536x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MjWm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F229b35dd-8291-4380-a3af-5ee92b8b87c4_1536x1024.png" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/229b35dd-8291-4380-a3af-5ee92b8b87c4_1536x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;content_6.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="content_6.png" title="content_6.png" srcset="https://substackcdn.com/image/fetch/$s_!MjWm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F229b35dd-8291-4380-a3af-5ee92b8b87c4_1536x1024.png 424w, https://substackcdn.com/image/fetch/$s_!MjWm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F229b35dd-8291-4380-a3af-5ee92b8b87c4_1536x1024.png 848w, https://substackcdn.com/image/fetch/$s_!MjWm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F229b35dd-8291-4380-a3af-5ee92b8b87c4_1536x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!MjWm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F229b35dd-8291-4380-a3af-5ee92b8b87c4_1536x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Clear Context Between Tasks</strong></p><p>One of the most practical lessons from production AI coding is to start fresh when output quality degrades. The <strong>&#8220;poisoned trajectory&#8221;</strong> problem is real.</p><p>Once an AI session goes wrong, the errors become part of the context. The model references its own mistakes. Attempts to correct them introduce more noise. The context fills with false starts and abandoned approaches.</p><p>The fix is simple. Commit your work, close the session, and start a new one with a clean context. Treat sessions like git branches. When one goes sideways, abandon it rather than trying to salvage the accumulated mess.</p><p>Session hygiene matters more than most practitioners realize. The teams getting consistent value from AI tools have developed strong instincts about when to start over rather than push through degraded output.</p><h2><strong>Engineering Judgment Still Required</strong></h2><p>Waiting for the models to fix the problem is a losing strategy. The alternative is treating scope management as a core skill. Decomposing complex problems into focused tasks isn&#8217;t a workaround for tool limitations. It&#8217;s the practice that makes AI assistance genuinely useful.</p><p>This shouldn&#8217;t be surprising. Breaking complex problems into manageable pieces was always good engineering practice. We just didn&#8217;t notice how much we relied on human ability to infer meaning from an ambiguous context. Humans read a vague ticket, pull in relevant knowledge from memory, ask clarifying questions, and still produce coherent work. LLMs can&#8217;t.</p><p>Adherence to a structured SDLC that was optional in a pre-AI world becomes essential when your implementation partner takes instructions literally and forgets everything between sessions. Processes like <a href="https://github.com/github/spec-kit/blob/main/spec-driven.md">Spec-Driven Development</a> or <a href="https://deepwiki.com/humanlayer/advanced-context-engineering-for-coding-agents">Research Plan Implementation (RPI)</a> are tailored for working with coding agents. Each phase benefits from AI assistance. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jxX1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jxX1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic 424w, https://substackcdn.com/image/fetch/$s_!jxX1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic 848w, https://substackcdn.com/image/fetch/$s_!jxX1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic 1272w, https://substackcdn.com/image/fetch/$s_!jxX1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jxX1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:89525,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://read.invoke.dev/i/185102624?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jxX1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic 424w, https://substackcdn.com/image/fetch/$s_!jxX1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic 848w, https://substackcdn.com/image/fetch/$s_!jxX1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic 1272w, https://substackcdn.com/image/fetch/$s_!jxX1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1074d25f-8502-4545-a424-0a12f9a01ed2_1536x1024.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We can&#8217;t completely outsource engineering to LLMs. Keeping humans in the loop is critical. Humans are still far more efficient at inferring meaning, managing context, and interpreting ambiguity. It is human ingenuity that is necessary to design the systems, make judgment calls, and decompose problems into chunks that fit within the effective working zone. That work can&#8217;t be automated.</p><p>The tools improve constantly. The constraints I&#8217;ve described will shift. But the fundamental concepts hold. AI amplifies engineering capability rather than replacing engineering judgment. The complexity cliff exists. Working deliberately within their boundaries is how you get value from these tools without drowning in confident-sounding mistakes.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[AI Reality Check]]></title><description><![CDATA[The Forces Challenging the Future of AI]]></description><link>https://read.invoke.dev/p/ai-reality-check</link><guid isPermaLink="false">https://read.invoke.dev/p/ai-reality-check</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Tue, 13 Jan 2026 23:37:41 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/162ef151-78be-4b8c-a855-f33657ec1d4b_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We&#8217;ve been operating under the assumption that AI success is inevitable. Scale the models, add more compute, and wait for the next generation; breakthrough capabilities will emerge. Companies are betting billions on AI&#8217;s success.</p><p>The pressure on companies to adopt AI or be left behind has been overwhelming. But what if the premise is wrong? What if the current approach faces fundamental constraints that more money and more computing power can&#8217;t solve?</p><h1>The Converging Headwinds</h1><p>Recently, the tone of the conversation has shifted, with AI now being referred to as a bubble. We&#8217;re hitting structural limits, and it seems the technical architecture has plateaued. These challenges aren&#8217;t isolated technical problems. The following are a few of the headwinds that AI must overcome to succeed in the long term.</p><p><strong>The economics don&#8217;t work.</strong></p><p>OpenAI projects cumulative <a href="https://www.cnbc.com/2025/09/06/openai-business-to-burn-115-billion-through-2029-the-information.html">losses of $115 billion through 2029</a>. Anthropic burned $2 billion in 2024. The entire industry loses money on every inference request. Companies claim they&#8217;ll reach profitability through scale, but <a href="https://aimagazine.com/news/mit-why-95-of-enterprise-ai-investments-fail-to-deliver">95% of AI pilots fail to deliver returns</a>.</p><p>Currently, AI is heavily subsidized, but those subsidies will start to taper off soon. The path to profitability requires price increases that users might not accept. That&#8217;s a fundamental business problem.</p><p><strong>Scaling has plateaued.</strong></p><p>No model feels significantly smarter than GPT-4 from March 2023. OpenAI&#8217;s recent models delivered improvements far less noticeable than the leap from GPT-3 to GPT-4. Ilya Sutskever, who pioneered scaling laws, now says <a href="https://www.reuters.com/technology/artificial-intelligence/openai-rivals-seek-new-path-smarter-ai-current-methods-hit-limitations-2024-11-11/">&#8220;results from scaling up pre-training have plateaued.&#8221;</a> A survey of AI researchers found <a href="https://www.livescience.com/technology/artificial-intelligence/current-ai-models-a-dead-end-for-human-level-intelligence-expert-survey-claims">76% say scaling current approaches won&#8217;t reach AGI</a>.</p><p>Industry veterans are acknowledging what the benchmarks show: we&#8217;ve hit diminishing returns. More compute and larger models aren&#8217;t delivering breakthrough capabilities anymore.</p><p><strong>The training data is exhausted.</strong></p><p>According to Elon Musk, <a href="https://techcrunch.com/2025/01/08/elon-musk-agrees-that-weve-exhausted-ai-training-data/">&#8220;We&#8217;ve now exhausted basically the cumulative sum of human knowledge in AI training.&#8221;</a> The industry&#8217;s response is synthetic data, but that is likely to trigger <a href="https://www.ibm.com/think/topics/model-collapse">model collapse</a>: train on AI-generated content recursively, and models produce gibberish after nine iterations.</p><p>Meanwhile, <a href="https://ahrefs.com/blog/what-percentage-of-new-content-is-ai-generated/">74% of new webpages contain AI-generated text</a>. The internet is filling with synthetic content, poisoning the well for future training. It&#8217;s a degenerative loop with no clear solution.</p><p><strong>Datacenter infrastructure can&#8217;t keep up.</strong></p><p>By 2027, <a href="https://www.gartner.com/en/newsroom/press-releases/2024-11-12-gartner-predicts-power-shortages-will-restrict-40-percent-of-ai-data-centers-by-20270">Gartner predicts 40% of AI data centers will hit power shortages</a>. Electricity demand is climbing to <a href="https://www.gartner.com/en/newsroom/press-releases/2024-11-12-gartner-predicts-power-shortages-will-restrict-40-percent-of-ai-data-centers-by-20270">500 terawatt-hours annually, 2.6 times what we used in 2023</a>. Utilities need <a href="https://www.datacenterknowledge.com/energy-power-supply/power-shortages-will-restrict-40-of-ai-data-centers-by-2027-gartner">five years or more to add new capacity</a>. Hyperscalers can&#8217;t wait that long, so they&#8217;re cutting deals directly with power providers.</p><p>Meanwhile, residents near data centers pay <a href="https://www.pewresearch.org/short-reads/2025/10/24/what-we-know-about-energy-use-at-us-data-centers-amid-the-ai-boom/">$16-18 more per month on their electric bills</a>. The US faces an <a href="https://www.visualcapitalist.com/shortage-of-u-s-data-center-capacity-2023-2028p/">11-gigawatt capacity shortfall this year, growing to 10 gigawatts by 2028</a>. Companies scouting data center sites don&#8217;t struggle to find land. They struggle to find grid connections and communities willing to accept them.</p><p>Water makes things worse. <a href="https://watercalculator.org/footprint/data-centers-water-use/">US data centers consumed 174 billion gallons in 2020</a>. <a href="https://www.lincolninst.edu/publications/land-lines-magazine/articles/land-water-impacts-data-centers/">Texas alone will hit 399 billion gallons by 2030</a>. <a href="https://www.eesi.org/articles/view/data-centers-and-water-consumption">Large facilities evaporate 5 million gallons daily</a>, enough for a city of 50,000 people. <a href="https://www.bloomberg.com/graphics/2025-ai-impacts-data-centers-water-data/">Two-thirds of new data centers built since 2022 sit in regions already facing water stress</a>, putting them in direct competition with residential and agricultural.</p><p><strong>Unproven ROI.</strong></p><p><a href="https://www.nttdata.com/global/en/insights/focus/2024/between-70-85p-of-genai-deployment-efforts-are-failing">Between 70-85% of AI initiatives fail to meet expected outcomes</a>, according to MIT and RAND Corporation research. <a href="https://workos.com/blog/why-most-enterprise-ai-projects-fail-patterns-that-work">Companies abandoned 42% of their AI projects in 2025</a>, up from just 17% in 2024, per S&amp;P Global Market Intelligence&#8217;s survey of over 1,000 enterprises. The average organization cancels 46% of AI proofs of concept before production.</p><p><a href="https://www.mckinsey.com/capabilities/quantumblack/our-insights/the-state-of-ai">McKinsey&#8217;s 2025 State of AI survey</a> found that only 6% of organizations qualify as &#8220;AI high performers,&#8221; generating an EBIT impact of 5% or more from their AI use. Just 39% report any enterprise-level EBIT impact at all. There&#8217;s a fundamental question about whether these tools can deliver ROI at scale.</p><p><strong>Hallucinations and AI slop eroding trust.</strong></p><p>Developer trust in AI tools dropped from 43% to 33% while active distrust climbed to 46%, according to <a href="https://survey.stackoverflow.co/2025/ai">Stack Overflow&#8217;s 2025 survey</a>. The decline stems from the effort required to review and rework AI-generated code to address hallucinations, security issues, and quality problems. AI generates code faster than humans can review it.</p><p><a href="https://www.faros.ai/blog/ai-software-engineering">Research by Faros AI</a> found that code review times increased by 91% and pull request sizes grew by 154% with AI adoption. <a href="https://leaddev.com/technical-direction/how-ai-generated-code-accelerates-technical-debt">GitClear&#8217;s analysis</a> of 211 million lines of code revealed 10x more duplication and a doubling of code churn, driving a <a href="https://www.askflux.ai/blog/256-billion-reasons-to-use-an-ai-code-analysis-platform">41% increase in bugs</a> and long-term maintenance costs.</p><p><strong>Legal exposure and regulatory requirements are mounting.</strong></p><p>A number of copyright lawsuits target AI companies for training on protected works without permission. In February 2025, Thomson Reuters won the first major US ruling <a href="https://www.wired.com/story/thomson-reuters-ai-copyright-lawsuit/">against Ross Intelligence</a>. The court found AI training harmed the market for original content and failed the transformative use threshold under the fair use doctrine. Additional lawsuits claim ChatGPT contributed to suicides, testing whether AI companies face product liability for harmful outputs.</p><p><a href="https://digital-strategy.ec.europa.eu/en/policies/regulatory-framework-ai">The EU AI Act</a> requires full compliance by August 2026, with fines reaching 7% of global annual turnover. Like GDPR, it applies extraterritorially to any company serving EU users. Organizations must classify AI systems by risk level, maintain decision-making documentation, implement human oversight mechanisms, and register high-risk systems in an EU database. Legal costs and regulatory compliance will rise regardless of technical progress.</p><h1>What This Means for Engineering Leaders</h1><p>These headwinds aren&#8217;t future concerns. They&#8217;re affecting decisions now.</p><p>The smart play is healthy skepticism. When vendors promise transformative capabilities, demand proof tied to specific business outcomes. When projects require significant investment, build exit criteria based on concrete metrics, not faith in future improvements. When teams want to adopt AI for productivity, they calculate actual costs, including compute, licensing, and the productivity tax of dealing with hallucinations.</p><p>The more important question is strategic positioning. If the current AI approach faces fundamental limits, what should we build that doesn&#8217;t depend on exponential improvements in capability? Where can we create value with current, plateau-level capabilities? What would our architecture look like if AGI never arrives or delivers only incremental gains?</p><h1>Where This Leaves Us</h1><p>I&#8217;m not arguing that AI has no value. Current tools deliver real productivity gains in specific contexts. I&#8217;m arguing that betting your engineering strategy on continued exponential improvement is increasingly risky.</p><p>The evidence suggests we&#8217;re hitting fundamental constraints&#8212;economic, technical, environmental, and social. Companies that recognize this reality and plan accordingly will be better positioned than those waiting for breakthroughs that may never come.</p><p>What patterns are you seeing in your organizations? Are the promised gains materializing, or are you seeing the same quiet disappointment?</p>]]></content:encoded></item><item><title><![CDATA[Pragmatic AI Adoption]]></title><description><![CDATA[Avoid the Slop and Amplify Innovation]]></description><link>https://read.invoke.dev/p/pragmatic-ai-adoption</link><guid isPermaLink="false">https://read.invoke.dev/p/pragmatic-ai-adoption</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Tue, 06 Jan 2026 18:30:40 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/08891615-9e82-4568-b74d-e42ce6cccdd4_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Software engineering organizations have made AI adoption a priority. After over a year working with these tools, I&#8217;ve settled on a pragmatic approach focused on what we know about software engineering and developer experience.</p><p>The promises haven&#8217;t materialized. <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/">Recent research</a> found experienced developers took 19% longer to complete tasks when using AI tools, despite believing they were 20% faster. Trust is declining as well, even as the models improve. According to a recent <a href="https://survey.stackoverflow.co/2025/">Stack Overflow Developer Survey</a>, only 33% of developers trust AI accuracy, while 46% actively distrust it.</p><p>Let&#8217;s be clear about what we&#8217;re working with. LLMs are <a href="https://en.wikipedia.org/wiki/Stochastic_parrot">stochastic parrots</a> that generate tokens based on probability distributions. They don&#8217;t reason, learn from mistakes, or remember what failed minutes ago. As scope and complexity increase, output correctness decreases. This isn&#8217;t a bug. It&#8217;s a fundamental limitation. This is why it is important to prioritize the human-in-the-loop when adopting AI.</p><p><strong>What AI Does Well:</strong></p><ul><li><p>Pattern matching across vast training data</p></li><li><p>Generating boilerplate and common code structures</p></li><li><p>Quick context synthesis from large text volumes</p></li><li><p>Identifying potential issues based on common patterns</p></li><li><p>Providing near-instant feedback on common mistakes</p></li></ul><p>&#10240;<strong>What Humans Do Well:</strong></p><ul><li><p>Understanding business context and user needs</p></li><li><p>Making judgment calls on trade-offs</p></li><li><p>Learning from mistakes and adapting approaches</p></li><li><p>Reasoning about novel problems from limited data</p></li><li><p>Collaborating across disciplines to clarify requirements</p></li></ul><p><strong>Where AI Adds Value</strong></p><p>These differences matter. An organization&#8217;s ability to innovate is directly proportional to its long-term value. You can&#8217;t automate away the work that drives competitive advantage. The real value lies in quality-of-life improvements when AI supports rather than replaces developer roles. Here a five ways to adopt AI to augment rather than replace developers. Successful adoption requires proper configuration and realistic expectations.</p><p><strong>Quality Gates</strong></p><p>One of the easiest ways to introduce AI into the software development lifecycle is to have it review code changes in Pull Requests/Merge Requests. AI acts as a fuzzy logic linter. It won&#8217;t eliminate the need for human review, but it can catch common mistakes and suggest improvements that traditional linters cannot.</p><p>This reduces the burden on senior developers who perform code reviews and provides faster feedback to code authors, allowing them to address issues more quickly. However, AI tools can produce more noise than signal if not correctly configured.</p><p><strong>Code Assistant</strong></p><p>When integrated into an IDE, AI enhances refactoring, autocomplete, and quick-fix tools by leveraging patterns from training data. It can also be used to explain complex code when documentation is missing.</p><p>Copying and pasting code from a chat interface or working from a terminal CLI only creates more friction. While articulating a problem can be a valuable thinking tool, a chat interface is the wrong UI for most programming tasks. The AI coding CLIs are amazing in what they can do, but they make it difficult for developers to see the full context of the software, thereby relinquishing control to the AI. The AI code assistant should be nearly invisible, keeping the developer in the flow. So invest in an IDE or text editor that has native AI integration.</p><p><strong>Analysis</strong></p><p>The source of many software bugs is a misunderstanding of requirements. AI can help by asking clarifying questions, rephrasing business requirements in engineering terms, and translating needs into technical designs.</p><p>This leads to clearer shared understanding between engineering and product, more thoroughly considered designs, and faster identification of requirement gaps before implementation. At the same time, AI can&#8217;t make decisions about technical trade-offs or replace human-to-human collaboration.</p><p><strong>Debugging</strong></p><p>AI assists in analyzing crash logs or error logs to find root causes. The most valuable implementations don&#8217;t just read logs in isolation. They correlate signals across the system, linking runtime behavior, performance counters, recent code changes, and deployment history to identify patterns humans might miss.</p><p>This accelerates troubleshooting and helps generate root-cause analysis documentation, preventing similar issues in the future.</p><p><strong>Research</strong></p><p>Whether designing a feature, developing a strategy proposal, or fixing a bug, web search tasks can be outsourced to AI. This can simplify the research efforts by leveraging AI to quickly search across multiple sources and summarize findings. This can be useful for exploring both divergent and convergent ideas to weigh trade-offs and identify gaps.</p><p>With a good prompt or MCP server, AI can be constrained to search only trusted sources and official documentation, reducing the likelihood of hallucinations. But it is still important to think critically of any finding to avoid losing time going down the wrong path.</p><p><strong>Setting Realistic Expectations</strong></p><p>The current LLM architecture can&#8217;t replace human ingenuity or drastically improve developer velocity when working on complex software. But it can make daily work less tedious. That&#8217;s valuable, even if it&#8217;s not the transformation vendors promised.</p><p>Be realistic about AI&#8217;s impact. Research shows automation often shifts toil rather than eliminating it. Time saved in writing code often reappears later in increased review time, rework, or bug fixing. So instead of positioning AI as a productivity improvement, position it as a developer experience improvement to amplify what makes great engineers valuable: judgment, creativity, and reasoning through complex problems.</p><p>The risk of poor AI implementation isn&#8217;t just immediate productivity loss. It&#8217;s long-term skill erosion. Over-automation creates engineers who can&#8217;t diagnose problems because they never learned the fundamentals. Junior engineers need to make mistakes, debug their own code, and understand system behavior from first principles. AI should guide this learning, not replace it.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke.dev! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Simplify Your iOS CI with Makefiles]]></title><description><![CDATA[Harness the power of the classic MAKE utility for efficient and portable iOS builds]]></description><link>https://read.invoke.dev/p/simplify-your-ios-ci-with-makefiles</link><guid isPermaLink="false">https://read.invoke.dev/p/simplify-your-ios-ci-with-makefiles</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Tue, 01 Oct 2024 10:03:27 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ba23eb3a-15b6-4234-a398-0e9de729210e_1680x1200.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>An iOS project of any size can benefit from automating the build process. Before reaching for a more complex solution like Fastlane or GitHub Actions, consider starting with the humble MAKE utility. MAKE has been around since 1976 and is preinstalled on any UNIX-like OS, including macOS, making it easy to adopt.</p><h2>The Elegant Simplicity of MAKE</h2><p>MAKE is the inspiration for many modern build tools, including Fastlane, and is still an excellent option for many projects needing automation but don't want to invest in complicated build systems. Here are a few benefits of using Makefiles over some alternatives.</p><p>1. <strong>Simplicity: </strong>Makefiles use a straightforward syntax that's easy to read and write.</p><p>2. <strong>Portability:</strong> Since MAKE is preinstalled on most UNIX-like systems, there are no dependencies to install and maintain on CI servers or developer machines. </p><p>3. <strong>Consistency:</strong> They provide a single source of truth for build and test commands.</p><p>4. <strong>Version Control:</strong> Your build process is now versioned alongside your code.</p><p>Let's look at how you can implement a Makefile for your iOS CI process.</p><h2>Implementing a Makefile for iOS CI</h2><p>Here's a basic structure for your iOS project's Makefile:</p><pre><code>PROJECT = $(shell ls -1 . | grep .xcodeproj)
SCHEME = ExampleProject
BUILD_DIR = .build

.DEFAULT_GOAL := help

help:
  @echo Goals:
  @echo "help - display this message"
  @echo "clean - clean the project"
  @echo "build - build the project"
  @echo "test - test the project"

clean:
  @echo Cleaning...
  xcodebuild clean \
    -project $(PROJECT) \
    -scheme $(SCHEME) \
    | xcbeautify
  @rm -rf $(BUILD_DIR)

build: clean
  @echo Building...
  xcodebuild build \
    -project $(PROJECT) \
    -scheme $(SCHEME) \
    -derivedDataPath $(BUILD_DIR) \
    | xcbeautify

test: clean
  @echo Testing...
  xcodebuild test \
    -project $(PROJECT) \
    -scheme $(SCHEME) \
    -derivedDataPath $(BUILD_DIR) 

.PHONY: help clean build test</code></pre><h2>Breaking Down the Makefile</h2><p>This Makefile defines several goals: help, clean, build, and test. Let's examine each goal:</p><p>1. <strong>help:</strong> Is a convenient goal to print out the available goals.</p><p>2. <strong>clean:</strong> Cleans the build folder.</p><p>3. <strong>build:</strong> Builds the project using xcodebuild.</p><p>4. <strong>test:</strong> Runs the test suite.</p><p>This is a simple example Makefile that can easily be extended to include goals for deploying to TestFlight or running SwiftLint. </p><h3>Define Prerequisites</h3><p>Prerequisites of a goal are listed after the colon, ensuring that it executes the prereqs before executing the specified goal.</p><pre><code>build: clean</code></pre><h3>Setting a Default</h3><p>By convention, running <code>make</code> without additional parameters will execute the first goal in the file. As of MAKE 3.80, the default can be set explicitly using the <code>.DEFAULT_GOAL </code>variable, making it a bit clearer.</p><pre><code>.DEFAULT_GOAL := help</code></pre><h3>Variables</h3><p>Variable values can be passed in as command-line arguments to MAKE or as environment variables, adding additional flexibility in configuring a Makefile.  </p><pre><code>make build SCHEME=MyScheme</code></pre><h3>Why so .PHONY?</h3><p>By default, Makefile goals are file targets &#8212; they are expected to produce a file with the same name as the goal. If that file already exists, it won't run the goal. Using <code>.PHONY</code> tells MAKE that a goal will not produce a file.</p><h2>GitHub Actions</h2><p>Turn the Makefile into a Continuous Integration process by integrating it with a GitHub Action workflow. </p><ul><li><p>Keeps the GH Action workflow simple</p></li><li><p>Developers can use the same commands as CI to execute builds locally</p></li></ul><h2>When MAKE isn't enough</h2><p>While MAKE is a straightforward solution, it can become more complex as a project grows. As a Makefile becomes more complex, there is a point of diminishing returns. To scale a build system for complex projects with many modules, consider alternatives like <a href="https://buck.build">BUCK</a> or <a href="https://bazel.build">BAZEL</a>, which support concepts like remote build execution and remote build caches.</p><h2>Wrapping Up</h2><p>MAKE is a simple yet powerful tool that can bring consistency, efficiency, and clarity to your CI pipeline without hiding details away behind unnecessary abstractions.</p><p>As you integrate this approach into your workflow, consider:</p><ul><li><p>How can you tailor the Makefile to your team's specific needs?</p></li><li><p>What other areas of your development process could benefit from similar standardization?</p></li><li><p>How might this approach evolve as your team and project grow?</p></li></ul><p>Remember, the goal is to spend less time fighting with CI and more time building great iOS apps. Happy coding!</p><h2>Further Reading</h2><ul><li><p><a href="https://arturgruchala.com/lost-art-of-makefile/">The Lost Art of Makefile: A Guide for iOS Developers</a></p></li><li><p><a href="https://makefiletutorial.com">Makefile Tutorial by Example</a></p></li></ul><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Mastering Swift Package Collections]]></title><description><![CDATA[Swift Package Manager is a powerful solution for managing dependencies and creating modular apps.]]></description><link>https://read.invoke.dev/p/mastering-swift-package-collections</link><guid isPermaLink="false">https://read.invoke.dev/p/mastering-swift-package-collections</guid><dc:creator><![CDATA[Alex Robinson]]></dc:creator><pubDate>Tue, 24 Sep 2024 10:00:00 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f5a4e166-9f97-4d53-b0c0-683a26f66b10_1680x1201.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a href="https://www.swift.org/package-manager/">Swift Package Manager</a> is a powerful solution for managing dependencies and creating modular apps. Over the years, Xcode support for SwiftPM has gradually improved, streamlining the development workflow. In Xcode 13, discovering and managing third-party Swift packages became a little easier with the introduction of <a href="https://www.swift.org/blog/package-collections/">Swift Package Collections</a>.</p><p>A Package Collection is a JSON file that describes a curated list of packages that can be shared directly or online. It can also be signed to prevent tampering. Collections can be a great way to share dependencies across an organization or make frequently used packages more accessible.</p><p>Xcode is pre-configured with a single Package Collection published by Apple. Adding an import statement to a file for one of the packages in this collection results in a fix-it prompt to add the dependency to the project. Adding new collections can enable this same fix-it for other Swift Packages.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6PoD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d91c488-5f35-489f-a0b1-690ec009e0ef_1382x206.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6PoD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d91c488-5f35-489f-a0b1-690ec009e0ef_1382x206.webp 424w, https://substackcdn.com/image/fetch/$s_!6PoD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d91c488-5f35-489f-a0b1-690ec009e0ef_1382x206.webp 848w, https://substackcdn.com/image/fetch/$s_!6PoD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d91c488-5f35-489f-a0b1-690ec009e0ef_1382x206.webp 1272w, https://substackcdn.com/image/fetch/$s_!6PoD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d91c488-5f35-489f-a0b1-690ec009e0ef_1382x206.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6PoD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d91c488-5f35-489f-a0b1-690ec009e0ef_1382x206.webp" width="1382" height="206" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9d91c488-5f35-489f-a0b1-690ec009e0ef_1382x206.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:206,&quot;width&quot;:1382,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;fix-it_hude9767f07c068af0d1e300f009ed895d_47039_1382x206_fit_q75_h2_box_3.webp&quot;,&quot;title&quot;:&quot;fix-it_hude9767f07c068af0d1e300f009ed895d_47039_1382x206_fit_q75_h2_box_3.webp&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="fix-it_hude9767f07c068af0d1e300f009ed895d_47039_1382x206_fit_q75_h2_box_3.webp" title="fix-it_hude9767f07c068af0d1e300f009ed895d_47039_1382x206_fit_q75_h2_box_3.webp" srcset="https://substackcdn.com/image/fetch/$s_!6PoD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d91c488-5f35-489f-a0b1-690ec009e0ef_1382x206.webp 424w, https://substackcdn.com/image/fetch/$s_!6PoD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d91c488-5f35-489f-a0b1-690ec009e0ef_1382x206.webp 848w, https://substackcdn.com/image/fetch/$s_!6PoD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d91c488-5f35-489f-a0b1-690ec009e0ef_1382x206.webp 1272w, https://substackcdn.com/image/fetch/$s_!6PoD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d91c488-5f35-489f-a0b1-690ec009e0ef_1382x206.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>The <a href="https://swiftpackageindex.com/">Swift Package Index</a> maintained by <a href="https://daveverwer.com/">Dave Verwer</a> and <a href="https://finestructure.co/">Sven A. Schmidt</a> makes it easy to find Swift Packages as well as Package Collections.</p><h3><strong>Add a Package Collection in Xcode</strong></h3><p>Adding a collection, like the <a href="https://www.pointfree.co/">Pointfree</a> open-source packages, to Xcode is straightforward. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TMp-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198b5dd-2215-43f7-a5fc-51cf6044fc60_960x768.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TMp-!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198b5dd-2215-43f7-a5fc-51cf6044fc60_960x768.gif 424w, https://substackcdn.com/image/fetch/$s_!TMp-!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198b5dd-2215-43f7-a5fc-51cf6044fc60_960x768.gif 848w, https://substackcdn.com/image/fetch/$s_!TMp-!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198b5dd-2215-43f7-a5fc-51cf6044fc60_960x768.gif 1272w, https://substackcdn.com/image/fetch/$s_!TMp-!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198b5dd-2215-43f7-a5fc-51cf6044fc60_960x768.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TMp-!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198b5dd-2215-43f7-a5fc-51cf6044fc60_960x768.gif" width="960" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f198b5dd-2215-43f7-a5fc-51cf6044fc60_960x768.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:960,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;add-package.gif&quot;,&quot;title&quot;:&quot;add-package.gif&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="add-package.gif" title="add-package.gif" srcset="https://substackcdn.com/image/fetch/$s_!TMp-!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198b5dd-2215-43f7-a5fc-51cf6044fc60_960x768.gif 424w, https://substackcdn.com/image/fetch/$s_!TMp-!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198b5dd-2215-43f7-a5fc-51cf6044fc60_960x768.gif 848w, https://substackcdn.com/image/fetch/$s_!TMp-!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198b5dd-2215-43f7-a5fc-51cf6044fc60_960x768.gif 1272w, https://substackcdn.com/image/fetch/$s_!TMp-!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff198b5dd-2215-43f7-a5fc-51cf6044fc60_960x768.gif 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Steps to add a collection:</p><ol><li><p>Within Xcode, click <em><strong>File &gt; Add Packages</strong>&#8230;</em></p></li><li><p>Under <em><strong>Package Dependencies</strong></em>, click the <em><strong>+</strong></em></p></li><li><p>In the bottom left corner of the package browser, click the <em>+</em>_ and select <em><strong>Add Package Collection&#8230;</strong></em></p></li><li><p>Paste the URL to the Package Collection</p></li><li><p>Confirm by clicking <em><strong>Add Collection</strong></em>&#10240;</p></li></ol><p>Once added, it is easy for Xcode to find and import your favorite packages. Try importing a module that isn&#8217;t already a project dependency, and Xcode will warn you. But if the package is part of a package collection registered with Xcode, then Xcode will provide a fix-it that will automatically add the dependency to the project.</p><h3><strong>Add a Package Collection from the Command Line</strong></h3><p>Using the Pointfree open-source collection of Swift packages as an example, the following command will add the collection to SwiftPM and make it available in Xcode.</p><pre><code><code>$ swift package-collection add https://swiftpackageindex.com/pointfreeco/collection.json</code></code></pre><div><hr></div><h2><strong>Creating Your Own Swift Package Collections</strong></h2><p>Creating new collections can be a convenient way to share common packages used internally within an organization or to group related packages of an open-source project, like <a href="https://swiftpackageindex.com/vapor">Vapor</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!o6Pr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cf78928-e369-4d0f-be8e-1dbed155dfaf_1193x608.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!o6Pr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cf78928-e369-4d0f-be8e-1dbed155dfaf_1193x608.webp 424w, https://substackcdn.com/image/fetch/$s_!o6Pr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cf78928-e369-4d0f-be8e-1dbed155dfaf_1193x608.webp 848w, https://substackcdn.com/image/fetch/$s_!o6Pr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cf78928-e369-4d0f-be8e-1dbed155dfaf_1193x608.webp 1272w, https://substackcdn.com/image/fetch/$s_!o6Pr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cf78928-e369-4d0f-be8e-1dbed155dfaf_1193x608.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!o6Pr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cf78928-e369-4d0f-be8e-1dbed155dfaf_1193x608.webp" width="1193" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2cf78928-e369-4d0f-be8e-1dbed155dfaf_1193x608.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:608,&quot;width&quot;:1193,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;creation-flow_hu0502bb7e9cef67ff370fa861d7425029_22270_1193x608_fit_q75_h2_box_3.webp&quot;,&quot;title&quot;:&quot;creation-flow_hu0502bb7e9cef67ff370fa861d7425029_22270_1193x608_fit_q75_h2_box_3.webp&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="creation-flow_hu0502bb7e9cef67ff370fa861d7425029_22270_1193x608_fit_q75_h2_box_3.webp" title="creation-flow_hu0502bb7e9cef67ff370fa861d7425029_22270_1193x608_fit_q75_h2_box_3.webp" srcset="https://substackcdn.com/image/fetch/$s_!o6Pr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cf78928-e369-4d0f-be8e-1dbed155dfaf_1193x608.webp 424w, https://substackcdn.com/image/fetch/$s_!o6Pr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cf78928-e369-4d0f-be8e-1dbed155dfaf_1193x608.webp 848w, https://substackcdn.com/image/fetch/$s_!o6Pr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cf78928-e369-4d0f-be8e-1dbed155dfaf_1193x608.webp 1272w, https://substackcdn.com/image/fetch/$s_!o6Pr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cf78928-e369-4d0f-be8e-1dbed155dfaf_1193x608.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4><strong>Step 1: Define the input of the package collection in a JSON file</strong></h4><p>To get started, create a JSON file describing the metadata for the collection and the packages to include. At a minimum, the packages should contain a Github URL, but you can also specify additional information to provide additional context. Check out the <a href="https://github.com/apple/swift-package-collection-generator/tree/main/Sources/PackageCollectionGenerator">README</a> to learn more about the options.</p><pre><code><code>{
&nbsp; "name": "Collection Example",
&nbsp; "overview": "This is a sample package collection.",
&nbsp; "keywords": [
&nbsp; &nbsp; "SwiftUI Navigation",
&nbsp; &nbsp; "Composable Architecture"
&nbsp; ],
&nbsp; "packages": [
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; "url": "https://github.com/pointfreeco/swift-composable-architecture"
&nbsp; &nbsp; },
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; "url": "https://github.com/pointfreeco/swiftui-navigation"
&nbsp; &nbsp; }
&nbsp; ],
&nbsp; "author": {
&nbsp; &nbsp; "name": "Jane Doe"
&nbsp; }
}</code></code></pre><h4><strong>Step 2: Generate the output file with the package-collection-generate command</strong></h4><p>Apple provides the <a href="https://github.com/apple/swift-package-collection-generator">package collection generator</a> to simplify generating the collection by filling in the detailed metadata from the repositories, including a complete list of the available versions.</p><p>The package collection generator does not currently ship with the Swift toolchain, so it needs to be built from the source.</p><p>Clone the git repository.</p><pre><code><code>$ git clone https://github.com/apple/swift-package-collection-generator.git </code></code></pre><p>Build the generator from the source.</p><pre><code><code>$ swift build --configuration release</code></code></pre><p>Install the commands on your system path.</p><pre><code><code>install .build/release/package-collection-generate /usr/local/bin/package-collection-generate

install .build/release/package-collection-diff /usr/local/bin/package-collection-diff

install .build/release/package-collection-sign /usr/local/bin/package-collection-sign

install .build/release/package-collection-validate /usr/local/bin/package-collection-validate</code></code></pre><p>Now, with our input.json, the generator can fill in additional metadata for each package from GitHub.</p><pre><code><code>$ package-collection-generate input.json generated-output.json</code></code></pre><p>The <strong>generated-output.json</strong> is now a complete description of our package collection.</p><h3><strong>Step 3: Sign Collection (Optional)</strong></h3><p>To prevent tampering with the collection, you can sign it using the <strong>package-collection-sign</strong> command. This command takes the generated JSON file as an input and generates a signed collection file. This step requires generating a signing certificate on the Apple developer portal. Check out the <a href="https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageCollections.md#package-collection-signing-optional">SwiftPM documentation</a> for more details on the signing requirements.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XtxX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15066a4f-3645-4080-bfe4-c268425e4031_1786x1138.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XtxX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15066a4f-3645-4080-bfe4-c268425e4031_1786x1138.webp 424w, https://substackcdn.com/image/fetch/$s_!XtxX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15066a4f-3645-4080-bfe4-c268425e4031_1786x1138.webp 848w, https://substackcdn.com/image/fetch/$s_!XtxX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15066a4f-3645-4080-bfe4-c268425e4031_1786x1138.webp 1272w, https://substackcdn.com/image/fetch/$s_!XtxX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15066a4f-3645-4080-bfe4-c268425e4031_1786x1138.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XtxX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15066a4f-3645-4080-bfe4-c268425e4031_1786x1138.webp" width="1456" height="928" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/15066a4f-3645-4080-bfe4-c268425e4031_1786x1138.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:928,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;signing-certificate_huba43b682281f5060af1a576cf1011abd_250552_1786x1138_fit_q75_h2_box_3.webp&quot;,&quot;title&quot;:&quot;signing-certificate_huba43b682281f5060af1a576cf1011abd_250552_1786x1138_fit_q75_h2_box_3.webp&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="signing-certificate_huba43b682281f5060af1a576cf1011abd_250552_1786x1138_fit_q75_h2_box_3.webp" title="signing-certificate_huba43b682281f5060af1a576cf1011abd_250552_1786x1138_fit_q75_h2_box_3.webp" srcset="https://substackcdn.com/image/fetch/$s_!XtxX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15066a4f-3645-4080-bfe4-c268425e4031_1786x1138.webp 424w, https://substackcdn.com/image/fetch/$s_!XtxX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15066a4f-3645-4080-bfe4-c268425e4031_1786x1138.webp 848w, https://substackcdn.com/image/fetch/$s_!XtxX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15066a4f-3645-4080-bfe4-c268425e4031_1786x1138.webp 1272w, https://substackcdn.com/image/fetch/$s_!XtxX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15066a4f-3645-4080-bfe4-c268425e4031_1786x1138.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><pre><code><code>$ package-collection-sign
generated-output.json

&nbsp; &nbsp; signed-output.json

&nbsp; &nbsp; priivate-key.pem

&nbsp; &nbsp; certificate.cer</code></code></pre><h4><strong>Step 4: Distribute the collection on GitHub or the Swift Package Index</strong></h4><p>Once you have generated the package collection file, you can publish it. The file can be published to GitHub or the Swift Package Index for public collections. The collection can also be shared directly with team members for internal collections.</p><p>These steps might seem like a lot of up-front work to create a Package Collection. Fortunately, collections don&#8217;t need to be created frequently. </p><div><hr></div><h2><strong>Conclusion</strong></h2><p>Package Collections aren&#8217;t going to save hours of development time, but they will make commonly used packages more accessible while staying in the editor flow.</p><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://read.invoke.dev/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Invoke! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item></channel></rss>