<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Leo</title>
    <description>The latest articles on DEV Community by Leo (@leobaniak).</description>
    <link>https://dev.to/leobaniak</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3997121%2F061e76e1-0a08-4d9d-827c-24f1e8b9e15b.png</url>
      <title>DEV Community: Leo</title>
      <link>https://dev.to/leobaniak</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/leobaniak"/>
    <language>en</language>
    <item>
      <title>GitHub takes rule insights up a level: bypass counts across the whole org</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sat, 22 Aug 2026 16:24:23 +0000</pubDate>
      <link>https://dev.to/leobaniak/github-takes-rule-insights-up-a-level-bypass-counts-across-the-whole-org-5fij</link>
      <guid>https://dev.to/leobaniak/github-takes-rule-insights-up-a-level-bypass-counts-across-the-whole-org-5fij</guid>
      <description>&lt;h2&gt;
  
  
  The news, in one sentence
&lt;/h2&gt;

&lt;p&gt;After a public preview earlier this year at the repository level, GitHub has promoted rule insights to the organization scope, so an org admin can see how rulesets are firing across every repo in one dashboard instead of a repo at a time. Per the August 12 changelog, the feature is in public preview.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually landed
&lt;/h2&gt;

&lt;p&gt;The dashboard lives under an organization's Settings, in the Repository tab. Once you turn it on, four things show up.&lt;/p&gt;

&lt;p&gt;An aggregated view of rule evaluation metrics for all repositories in the organization. GitHub's own screenshot description covers a chart of ruleset evaluations broken into totals for allowed, failed and bypassed runs.&lt;/p&gt;

&lt;p&gt;A top repositories by bypasses list. This is the one that will change how platform teams spend their Monday morning.&lt;/p&gt;

&lt;p&gt;Filters by evaluation status, branch, ruleset and date range.&lt;/p&gt;

&lt;p&gt;A CSV export of the underlying data for reporting and record keeping.&lt;/p&gt;

&lt;p&gt;That is the scope of the preview. There is no new enforcement primitive, no new rule type, no new API surface called out in the changelog. What changed is the vantage point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the vantage point is the story
&lt;/h2&gt;

&lt;p&gt;If you run rulesets as your gating primitive, the operational question you cannot answer at the repo level is the interesting one: across three hundred repositories, which ones are quietly bypassing branch protection for release cuts, and which ones are hitting a failing rule so often that the rule itself is probably wrong?&lt;/p&gt;

&lt;p&gt;You had two ways to reconstruct that before. Walk the repo-level dashboards one at a time. Or ship ruleset evaluation events into your SIEM through the audit log and build the aggregation yourself. Both work. Both cost time you were spending on something else.&lt;/p&gt;

&lt;p&gt;An org-scoped roll-up collapses that into a single query. The specific one worth running first is the top-bypasses list. Bypasses are the metric that indicates either a legitimate escape hatch you granted and forgot about, or a rule that everyone quietly agreed to ignore because it fires on the wrong thing. Both cases are policy debt. You want the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it without wasting the exercise
&lt;/h2&gt;

&lt;p&gt;The failure mode of a governance dashboard is that it becomes a wallpaper chart nobody clicks. Two suggestions for the first two weeks of the preview, if you are the person turning it on.&lt;/p&gt;

&lt;p&gt;First, pick a date range that spans the last release. Filter by "bypassed", sort by count, and walk the top ten repos with the owner of each one. Half the conversations will be "yes, the CAB approved that for the hotfix"; the other half will be "I did not know that role could bypass". The second half is why the dashboard exists.&lt;/p&gt;

&lt;p&gt;Second, export the CSV once a week for a month and diff it. Trend matters more than absolute count. A bypass rate creeping up on a repo that used to be quiet is the signal you want on-call to see before an auditor does.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it will not tell you
&lt;/h2&gt;

&lt;p&gt;This is a preview, and a scoped one. Some things worth flagging so a platform team does not budget for them yet.&lt;/p&gt;

&lt;p&gt;The changelog does not commit to a webhook or a rule-fired event stream tied to this dashboard. If your control loop is "on bypass, page the security channel", you are still going through the audit log pipeline you already have. The dashboard is a review surface, not an alerting surface.&lt;/p&gt;

&lt;p&gt;The dashboard is inside GitHub's own Settings UI. For teams that consolidate governance in a separate policy plane, the CSV export is the integration point, and CSV means batch, not near real time.&lt;/p&gt;

&lt;p&gt;And public preview is public preview. GA timelines are not in the changelog, and the feature set can move.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to look next
&lt;/h2&gt;

&lt;p&gt;If you already ship GitHub audit events to a warehouse, the honest question this release forces is whether the dashboard replaces those queries or just gives you a faster read for the common case. My guess is the latter, at least until GitHub adds an event feed. Either way, the top-bypasses list is a useful weekly report the day it turns on, and it is a report most orgs did not have last month.&lt;/p&gt;

</description>
      <category>github</category>
      <category>rulesets</category>
      <category>policy</category>
      <category>governance</category>
    </item>
    <item>
      <title>SMIL and timing charts: planning SVG animation on paper</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sat, 22 Aug 2026 16:07:44 +0000</pubDate>
      <link>https://dev.to/leobaniak/smil-and-timing-charts-planning-svg-animation-on-paper-4l87</link>
      <guid>https://dev.to/leobaniak/smil-and-timing-charts-planning-svg-animation-on-paper-4l87</guid>
      <description>&lt;p&gt;You want to animate an SVG's &lt;code&gt;viewBox&lt;/code&gt;. CSS shrugs. You want the animation to keep playing when the SVG is dropped into an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag. JavaScript shrugs. That's the corner SMIL still owns, and a piece on Smashing Magazine spends its time on the part everyone skips: how to plan the sequence before you type a single tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tag, and the thing it can do
&lt;/h2&gt;

&lt;p&gt;SMIL is the animation syntax that lives inside SVG. You nest an &lt;code&gt;&amp;lt;animate&amp;gt;&lt;/code&gt; element inside the shape you want to move, tell it which attribute to change, and give it a duration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;animate&lt;/span&gt;
  &lt;span class="na"&gt;attributeName=&lt;/span&gt;&lt;span class="s"&gt;"fill"&lt;/span&gt;
  &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;"someOtherColor"&lt;/span&gt;
  &lt;span class="na"&gt;dur=&lt;/span&gt;&lt;span class="s"&gt;"someDuration"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the whole primitive. &lt;code&gt;&amp;lt;animateTransform&amp;gt;&lt;/code&gt; covers the transform attribute, &lt;code&gt;&amp;lt;set&amp;gt;&lt;/code&gt; handles a discrete jump. Per the article, each SMIL tag targets one element and one property at a time. So a fade-plus-slide is two tags. A palette shift across three shapes is three. The author's own line: "SMIL has a problem: it gets bloated quickly."&lt;/p&gt;

&lt;p&gt;The upside is what those tags can reach. Geometry attributes — &lt;code&gt;viewBox&lt;/code&gt;, &lt;code&gt;stroke-width&lt;/code&gt;, &lt;code&gt;clip-path&lt;/code&gt; references, &lt;code&gt;fill-opacity&lt;/code&gt; — animate declaratively, no script attached. The article notes that many SVG attributes now have CSS property counterparts (geometry properties have been supported across the major browsers since 2024), but &lt;code&gt;viewBox&lt;/code&gt; is called out as one that still has no CSS equivalent. It's also the reason SMIL survives in &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;-embedded SVG: the browser runs the animation, but it won't run any script inside that same file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Timing charts as the source of truth
&lt;/h2&gt;

&lt;p&gt;Once you have five or ten of these tags, the file stops telling you what happens when. The Smashing piece proposes a diagram that is deliberately low-tech: draw a horizontal or vertical line per animation, mark the start with a circle and the end with a bar, and stack them in temporal order. Labels carry the duration; you do not scale the lines to the millisecond. A dot lights up at t=1s; a bar drops at t=1.3s; the next line begins where the previous one ends.&lt;/p&gt;

&lt;p&gt;Two things fall out of the chart. You can see, at a glance, which animations should share a start point — and you can spot the ones that should be chained to another animation's edge instead of pinned to an absolute timestamp. That is where syncbase timing comes in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pinning one animation to another
&lt;/h2&gt;

&lt;p&gt;Syncbase values let you write a &lt;code&gt;begin&lt;/code&gt; attribute in terms of another animation's &lt;code&gt;id&lt;/code&gt;. The example from the source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;animate&lt;/span&gt;
  &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"colorChange"&lt;/span&gt;
  &lt;span class="na"&gt;begin=&lt;/span&gt;&lt;span class="s"&gt;"1s"&lt;/span&gt;
  &lt;span class="err"&gt;...&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;animate&lt;/span&gt;
  &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"opacityChange"&lt;/span&gt;
  &lt;span class="na"&gt;begin=&lt;/span&gt;&lt;span class="s"&gt;"colorChange.end - 300ms"&lt;/span&gt;
  &lt;span class="err"&gt;...&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second animation starts 300ms before the first one ends. Quote from the piece: "Using syncbase values, the beginning of an animation is positioned in time relative to the &lt;code&gt;.begin&lt;/code&gt; or &lt;code&gt;.end&lt;/code&gt; of some other animation." Change &lt;code&gt;colorChange&lt;/code&gt;'s duration later and every downstream &lt;code&gt;begin&lt;/code&gt; moves with it. The chart is the map; syncbase is how you wire the map into the file.&lt;/p&gt;

&lt;p&gt;A caveat the article calls out: with a negative offset, browsers may jump the animation "to where it would have been had the computer peeked into the future." So a syncbase reference to a not-yet-started animation with &lt;code&gt;- 300ms&lt;/code&gt; on the front is not the same as a plain delay. Draw the chart first; you'll catch it there before the browser catches it for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this actually unlocks
&lt;/h2&gt;

&lt;p&gt;The through-line of the piece is not that SMIL is better than CSS animation. It's that SMIL is still the tool when the thing you need to move is an SVG attribute CSS does not model, and that a multi-shape sequence written straight into markup is only maintainable if you have a plan sitting next to the file. A line-segment chart on paper (or in whatever drawing tool is open) is that plan.&lt;/p&gt;

&lt;p&gt;Two things worth trying on the next SVG you touch: animate &lt;code&gt;viewBox&lt;/code&gt; with SMIL to reframe a diagram, and rewrite one existing keyframe sequence as &lt;code&gt;id&lt;/code&gt;-chained SMIL to see whether the chart-then-code loop reads better than a wall of &lt;code&gt;@keyframes&lt;/code&gt; percentages. If the chart looks tangled, the animation will be tangled. Fix it on the page first.&lt;/p&gt;

</description>
      <category>svg</category>
      <category>smil</category>
      <category>animation</category>
      <category>html</category>
    </item>
    <item>
      <title>Codex CLI arrives as a repo-versioned pipeline step</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sat, 22 Aug 2026 08:27:11 +0000</pubDate>
      <link>https://dev.to/leobaniak/codex-cli-arrives-as-a-repo-versioned-pipeline-step-5e6f</link>
      <guid>https://dev.to/leobaniak/codex-cli-arrives-as-a-repo-versioned-pipeline-step-5e6f</guid>
      <description>&lt;h2&gt;
  
  
  A pipeline slot for the coding agent
&lt;/h2&gt;

&lt;p&gt;The first time I saw a coding agent used well in CI, it was somebody's Friday afternoon experiment: a shell action that curled a prompt into an API and hoped for the best. It worked. It also stored the API key in a plain repo variable, ran with full container write access, and lived in a script nobody wanted to touch. That is the whole reason I paid attention to this week's news: OpenAI's Codex CLI now ships as a proper first-party pipeline action, with a model choice, a sandbox mode and prompts committed alongside the rest of the pipeline. That last part is what stuck with me.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually shipped
&lt;/h2&gt;

&lt;p&gt;An OpenAI platform integration holds the API key as an encrypted secret. A new Codex CLI action consumes it. In the YAML you pick a model from the Codex family, choose a sandbox mode, and point at one or more prompts. The prompts can be inline, but the interesting shape is when they live as files in the repo. That means the prompt is a reviewable, versioned artifact next to the code it operates on. Change the prompt, open a PR. Roll it back, git revert.&lt;/p&gt;

&lt;p&gt;The sandbox modes are the safety knob. &lt;code&gt;WORKSPACE_WRITE&lt;/code&gt; is the default and lets the agent read and write inside the pipeline filesystem. &lt;code&gt;READ_ONLY&lt;/code&gt; confines it to a look-but-do-not-touch role, good for review or triage prompts. &lt;code&gt;FULL_ACCESS&lt;/code&gt; opens the whole container.&lt;/p&gt;

&lt;p&gt;A minimal step, in the shape the announcement uses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Codex review&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CODEX_CLI&lt;/span&gt;
  &lt;span class="na"&gt;integration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gpt-5-codex&lt;/span&gt;
  &lt;span class="na"&gt;sandbox_mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;READ_ONLY&lt;/span&gt;
  &lt;span class="na"&gt;prompts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;codex-prompt.md&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is small on the page and large in what it changes about your pipeline. The agent run is now a versioned step with the same review path as any other change.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually like about it
&lt;/h2&gt;

&lt;p&gt;Prompts as files, in the repo, is the win. Anyone who has tried to reconstruct why an agent behaved differently last Tuesday knows how quickly a chat-based workflow becomes irreproducible. Making the prompt an artifact you can diff turns a black box into a testable input.&lt;/p&gt;

&lt;p&gt;The default sandbox mode is more permissive than I would have picked. If you accept &lt;code&gt;WORKSPACE_WRITE&lt;/code&gt; without thinking, an agent step can rewrite files inside the runner immediately. That is fine when the run itself is scoped and ephemeral, less fine when the same pipeline pushes a branch or opens a PR right after. Start with &lt;code&gt;READ_ONLY&lt;/code&gt; while you tune the prompt, then step up. The announcement itself gives the same advice, which I appreciated.&lt;/p&gt;

&lt;p&gt;The model choice is a real one. You pick from a Codex family plus the general gpt-5 model, so you pin a specific behaviour instead of inheriting whatever your provider defaults to that week. For CI, that is more valuable than the raw quality delta between models. Reproducibility beats vibes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How other CI tools handle coding agents in the pipeline
&lt;/h2&gt;

&lt;p&gt;The interesting question is how each tool wires a stateful, credentialed, sometimes destructive command into a job. The shapes are more different than they look.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions.&lt;/strong&gt; The mature answer is a marketplace action plus repo or org secrets. Anthropic ships an official Claude Code action; community actions cover other providers. The strong point is OIDC federation: a workflow can mint a short-lived token to a cloud IAM role without a long-lived key sitting anywhere. If your governance story leans on OIDC and audit logs at scale, this is still the deepest option, and it is the better fit if your organisation already lives inside GitHub's identity envelope.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitLab CI.&lt;/strong&gt; CI/CD variables plus a job template. Nothing agent-specific out of the box, but the template pattern is cheap and works with any CLI you can install. Job-level ID tokens give you the same short-lived credential shape as Actions' OIDC. For teams already all-in on GitLab this is usually simpler than adding a new tool, and it keeps the agent step in the same review and approvals flow as the rest of your pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CircleCI.&lt;/strong&gt; Orbs are the packaging layer, and the SDK-flavoured ones keep multiplying. The strong point is contexts: they scope secrets to specific projects or environments. If you want a coding agent that can only see production credentials in a manual-approval job, contexts do that cleanly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jenkins.&lt;/strong&gt; Plugins and shell steps. It is the flexible end of the spectrum: nothing is out of reach, but nothing is done for you. Teams with a lot of in-house Groovy will keep it, and there is a fair argument that Jenkins remains the better fit when the pipeline needs to talk to on-prem systems the SaaS options do not reach.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buddy.&lt;/strong&gt; This week's news. The Codex CLI action packages the model choice, the sandbox mode and the prompt-as-file convention into a single YAML block. The concrete reason to reach for it: the sandbox knob and the prompt-file shape reduce the amount of glue you have to write yourself when the goal is a repeatable, reviewable agent step. The &lt;a href="https://buddy.works/blog/openai-codex-cli-buddy-pipelines?utm_source=cicd.deployment.to&amp;amp;utm_medium=referral&amp;amp;utm_campaign=codex-cli" rel="noopener noreferrer"&gt;OpenAI Codex CLI action announcement&lt;/a&gt; walks through the fuller shape.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these are wrong. The pattern is what matters: an agent step needs a credential boundary, a filesystem boundary and a versioned prompt. Whichever tool gets you those three fastest is the right one for your team.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I am watching next
&lt;/h2&gt;

&lt;p&gt;Two things. First, whether the sandbox default drifts to read-only across the ecosystem as teams learn what a write-capable agent does to a cache directory. A permissive default is a reasonable Day One choice and a nervous Day Ninety one. Second, whether prompt-as-file becomes the norm or dies as a habit. Everything about CI/CD works better when the config is in the repo, and prompts are just another kind of config now. If a year from now most teams are still pasting prompts into web UIs, the ergonomics lost.&lt;/p&gt;

</description>
      <category>openai</category>
      <category>codex</category>
      <category>aiagents</category>
      <category>pipelines</category>
    </item>
    <item>
      <title>The arrayref takeover is the crates.io threat model, not a surprise</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sat, 22 Aug 2026 00:24:14 +0000</pubDate>
      <link>https://dev.to/leobaniak/the-arrayref-takeover-is-the-cratesio-threat-model-not-a-surprise-2o2k</link>
      <guid>https://dev.to/leobaniak/the-arrayref-takeover-is-the-cratesio-threat-model-not-a-surprise-2o2k</guid>
      <description>&lt;p&gt;Cargo pulls hundreds of transitive dependencies and runs their build scripts on your runner as whatever user Rust happens to be. (Reassuring, isn't it.) This week that trust boundary got tested in public. DevOps.com reports that attackers took over the maintainer account behind the arrayref Rust crate and used the access to publish four additional attacker-owned crates loaded with information-stealing malware. Wiz researchers, per the same report, tie the campaign to overlap with nation-state supply-chain activity.&lt;/p&gt;

&lt;p&gt;You should already have assumed this could happen. The interesting part is what your pipeline is doing about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the trust actually failed
&lt;/h2&gt;

&lt;p&gt;The technical detail worth noticing is the direction of the attack. Nobody had to smuggle a malicious PR past a code review. Nobody had to slip a typosquat past a sleepy developer. Somebody logged in as the maintainer and pushed. Whatever crates.io had between "signed in" and "release published" was the entire trust boundary, and this week it was one factor short.&lt;/p&gt;

&lt;p&gt;Every ecosystem has this hinge. npm has it. PyPI has it. RubyGems has it. crates.io is not unusually reckless here; it is representative. If your defence-in-depth stops at "we trust the registry", you have one lock protecting your build farm and the key is a phishable password.&lt;/p&gt;

&lt;h2&gt;
  
  
  What cargo audit and cargo vet can and cannot see
&lt;/h2&gt;

&lt;p&gt;If you have hardened your Rust builds, you probably reach for two things. &lt;code&gt;cargo audit&lt;/code&gt; compares your lockfile against the RustSec advisory database. &lt;code&gt;cargo vet&lt;/code&gt; records human review of specific crate versions. Both are useful. Neither would have caught this on day one.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cargo audit&lt;/code&gt; is downstream of somebody filing the advisory. In a live compromise, the malicious version sits on the registry before it lands in the database, and you learn about it on whatever timeline the researchers publish on. &lt;code&gt;cargo vet&lt;/code&gt; fares better in principle, because a new version from a compromised maintainer shows up as unreviewed. But &lt;code&gt;vet&lt;/code&gt; only works if you gate CI on it and if your team is willing to say no to an unvetted release under deadline pressure. In practice, most teams add &lt;code&gt;cargo vet&lt;/code&gt;, watch it flag things for a while, and then quietly stop reading the output.&lt;/p&gt;

&lt;h2&gt;
  
  
  The build script problem nobody wants to fix
&lt;/h2&gt;

&lt;p&gt;Here is the sharper edge. Cargo lets crates ship &lt;code&gt;build.rs&lt;/code&gt; scripts that execute at compile time. That is by design, and it is how a lot of the ecosystem works: bindings, code generation, feature detection. It is also why "we pinned the lockfile" is not enough on its own. A pinned, malicious &lt;code&gt;build.rs&lt;/code&gt; still runs on your CI runner the first time you compile it, and it runs with whatever secrets that runner is allowed to see.&lt;/p&gt;

&lt;p&gt;The mitigations here are unglamorous:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run cargo builds on ephemeral runners with no long-lived credentials in scope. If your CI runner sees your production deploy key at build time, you have a problem that predates any specific compromise.&lt;/li&gt;
&lt;li&gt;Egress-filter the runner. A build script that phones home to an unknown host should not be able to reach it.&lt;/li&gt;
&lt;li&gt;Cache and mirror the registry through a controlled proxy so you have a chokepoint to detect a bad version and roll back to a known-good one.&lt;/li&gt;
&lt;li&gt;Treat every dependency bump as a change that could execute code on your infrastructure, because it can.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that is Rust-specific. None of it requires the registry to fix anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  How other registries are moving on the same shape
&lt;/h2&gt;

&lt;p&gt;npm has been quietly moving in the opposite direction from Rust: recent releases disable lifecycle scripts by default, which shrinks the equivalent of &lt;code&gt;build.rs&lt;/code&gt; blast radius on &lt;code&gt;npm install&lt;/code&gt;. PyPI now offers trusted publishers backed by short-lived OIDC tokens, so a stolen maintainer password is worth less than it used to be. Sigstore-style keyless signing exists across ecosystems, and mostly is not required by default. The pattern is the same everywhere. The primitives to make a maintainer takeover survivable exist. They are opt-in. Most projects have not opted in.&lt;/p&gt;

&lt;p&gt;crates.io will patch what it can on the account side. What matters more is whether your pipeline treats the registry as a trusted party or as an internet stranger you compile with root.&lt;/p&gt;

&lt;p&gt;Pick one. The attackers already have.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>cargo</category>
      <category>supplychain</category>
      <category>malware</category>
    </item>
    <item>
      <title>Docker Sandboxes plug into GitHub Agentic Workflows as an agent runtime</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Fri, 21 Aug 2026 16:25:44 +0000</pubDate>
      <link>https://dev.to/leobaniak/docker-sandboxes-plug-into-github-agentic-workflows-as-an-agent-runtime-2eoj</link>
      <guid>https://dev.to/leobaniak/docker-sandboxes-plug-into-github-agentic-workflows-as-an-agent-runtime-2eoj</guid>
      <description>&lt;p&gt;You gave an AI agent write access to your CI runner. Sit with that for a second. The agent can shell out, resolve DNS, mount your workspace, and read whatever secret the job has in scope. Every "autonomous coding agent in CI" pitch of the last year quietly assumed you were fine with that.&lt;/p&gt;

&lt;p&gt;Docker's new blog post says: maybe stop assuming. It shows an AI coding agent running inside a Docker Sandbox, itself inside a GitHub Actions job, doing the actual work of finding a bug, writing a Testcontainers regression test, patching the code, and opening a draft PR. Same outcome, different trust boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the workflow actually does
&lt;/h2&gt;

&lt;p&gt;The example lives in a &lt;code&gt;.md&lt;/code&gt; workflow file that GitHub Agentic Workflows (&lt;code&gt;gh-aw&lt;/code&gt;) compiles into a normal &lt;code&gt;.lock.yml&lt;/code&gt; before Actions runs it. In the front matter the workflow declares an &lt;code&gt;engine&lt;/code&gt;, a &lt;code&gt;sandbox.agent.runtime&lt;/code&gt; of &lt;code&gt;docker-sbx&lt;/code&gt;, a &lt;code&gt;network.allowed&lt;/code&gt; list, and a &lt;code&gt;safe-outputs.create-pull-request&lt;/code&gt; block that pins the PR to a &lt;code&gt;src/**&lt;/code&gt; allowlist and a &lt;code&gt;[docker-sbx sample]&lt;/code&gt; title prefix.&lt;/p&gt;

&lt;p&gt;The task is deliberately small: a Java service with a case-sensitivity bug in email handling. The agent reads the code, runs the existing tests, spins up a PostgreSQL container through Testcontainers, adds a regression test for the case variation, fixes the code under &lt;code&gt;src/&lt;/code&gt;, reruns the full suite, and opens a draft PR. Docker's write-up reports it did all of this on a GitHub-hosted &lt;code&gt;ubuntu-24.04&lt;/code&gt; runner in a little over eleven minutes.&lt;/p&gt;

&lt;p&gt;Nothing about the outcome is novel. What is novel is where the agent lived while doing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boundary Docker moved
&lt;/h2&gt;

&lt;p&gt;A stock GitHub Actions job is one big blast radius. Every step shares the same filesystem, the same daemon socket if you exposed one, and the same secrets that the job requested. Give the agent &lt;code&gt;bash&lt;/code&gt; and it gets everything the runner has.&lt;/p&gt;

&lt;p&gt;Docker Sandboxes wrap the agent in a microVM with its own kernel, its own filesystem, and its own network stack. Inside that microVM, the sandbox runs a private Docker daemon, so when the agent's Testcontainers call opens a PostgreSQL container, it hits that daemon and not the host runner's. The &lt;code&gt;network.allowed&lt;/code&gt; field is the second wall: the sandbox will only reach the destination groups the workflow declared. In the sample those are &lt;code&gt;defaults&lt;/code&gt;, &lt;code&gt;github&lt;/code&gt;, &lt;code&gt;containers&lt;/code&gt;, and &lt;code&gt;java&lt;/code&gt;. Anything else the agent tries to talk to, it cannot.&lt;/p&gt;

&lt;p&gt;And the return path is not a free-for-all either. The &lt;code&gt;safe-outputs&lt;/code&gt; block is a hard filter on what the agent is allowed to produce. &lt;code&gt;protected-files: blocked&lt;/code&gt; plus an &lt;code&gt;allowed-files&lt;/code&gt; glob means the compiled workflow rejects any patch that touches a path outside the allowlist. Docker notes that the sample run's draft PR contained exactly two files, both under &lt;code&gt;src/**&lt;/code&gt;: the new test and the fix. Everything else the agent might have poked at stays inside the sandbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this leaves you
&lt;/h2&gt;

&lt;p&gt;The good part: for the first time, the isolation is expressed in a file you can review, sign, and diff. The workflow front matter is the policy. If a colleague sends you a PR that widens &lt;code&gt;network.allowed&lt;/code&gt; or drops &lt;code&gt;protected-files: blocked&lt;/code&gt;, you can see it. That is a very different security posture from "the agent has a shell, please trust our prompt".&lt;/p&gt;

&lt;p&gt;The rough edges are the ones you would expect. Docker Sandboxes are a Docker product on a Docker daemon verified by Docker's own runtime, so you are trading the runner's trust boundary for Docker's. And &lt;code&gt;network.allowed&lt;/code&gt; groups like &lt;code&gt;defaults&lt;/code&gt; are shortcuts to lists of destinations Docker curates; treat them the way you would treat any allowlist someone else wrote for you (read it).&lt;/p&gt;

&lt;h2&gt;
  
  
  How other CI tools handle the same problem
&lt;/h2&gt;

&lt;p&gt;Every CI vendor has had to answer the "where does untrusted code run" question, long before agents made it worse. The shapes vary.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions&lt;/strong&gt;, on its own, gives you one job-scoped VM per workflow, and everything inside it shares state. The Docker Sandboxes integration is the vendor's first-party answer to "yes, but I want a real boundary inside that VM". Practical, but tied to Docker's runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitLab CI&lt;/strong&gt; leans on executors. The Kubernetes executor already gives you a fresh pod per job with its own network policy, which is a good boundary for most workloads and cheaper to reason about than a microVM. For agent isolation specifically, a Kubernetes executor with a strict &lt;code&gt;NetworkPolicy&lt;/code&gt; is often the better fit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CircleCI&lt;/strong&gt; offers reusable executors and Docker-in-Docker, but the isolation story stops at container boundaries. Fine for build steps, thin for autonomous agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jenkins&lt;/strong&gt; hands you the primitives (ephemeral agents, containerized builds, cloud plugins) and asks you to compose them. Powerful, but the trust boundary is whatever your platform team wired up on a Tuesday.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buildkite&lt;/strong&gt; puts the agent on your infrastructure by design, so the boundary is whatever you set on the host. It scales best when your platform team already has microVM or Firecracker plumbing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buddy&lt;/strong&gt; runs each pipeline action in an ephemeral container spun up per run and torn down after, which gives you a per-step isolation default without a separate executor configuration to maintain. If your objection to Actions is "one big VM for the whole job", that per-action model is one concrete reason to look (&lt;a href="https://buddy.works/docs/pipelines/actions?utm_source=cicd.deployment.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=docker-sandboxes" rel="noopener noreferrer"&gt;docs&lt;/a&gt;). It is not a microVM; for kernel-boundary isolation on the same host, Docker Sandboxes are still the closer fit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Signed workflows. Isolated agents. Filtered PRs. Not a bad week for people who have to explain to auditors what "the AI wrote it" means.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>githubactions</category>
      <category>aiagents</category>
      <category>sandboxes</category>
    </item>
    <item>
      <title>GitHub says 2.9 billion commits a month, and CI is the downstream tenant</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Fri, 21 Aug 2026 08:24:21 +0000</pubDate>
      <link>https://dev.to/leobaniak/github-says-29-billion-commits-a-month-and-ci-is-the-downstream-tenant-4eee</link>
      <guid>https://dev.to/leobaniak/github-says-29-billion-commits-a-month-and-ci-is-the-downstream-tenant-4eee</guid>
      <description>&lt;h2&gt;
  
  
  The number, and what sits on top of it
&lt;/h2&gt;

&lt;p&gt;The New Stack put a monthly load on GitHub on August 20, 2026: 2.9 billion commits, 130 million merged pull requests, 24 million new repositories. The headline is blunt about the direction of travel, saying the platform cannot keep up. Actions runs on the same substrate as every push, PR event and repository create in that ledger. When any of those queues back up, workflows feel it before the business dashboards do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where a strained substrate lands in CI
&lt;/h2&gt;

&lt;p&gt;Push events fan out to workflow triggers. Merged PRs kick checks. Repository creates seed webhook subscriptions. Every one of those paths is a queue with a fair-scheduling policy behind it. When ingest outpaces drain, the symptoms are ones on-call already knows: workflow starts drift from seconds to minutes, cache lookups miss more often because eviction runs harder, and reruns pile up because the first attempt timed out on a network hop that used to be free.&lt;/p&gt;

&lt;p&gt;Nothing exotic on that list. It is the standard failure mode of any managed tenant when the platform is over-committed. What is new is the size of the denominator. At 2.9 billion commits a month, a one percent regression in trigger latency is not a rounding error. It is 29 million delayed jobs a month.&lt;/p&gt;

&lt;h2&gt;
  
  
  The growth story vs. the pager story
&lt;/h2&gt;

&lt;p&gt;The public framing of a scale milestone is a growth number. The operator framing is a capacity question: at what point does the SLA I was buying quietly become best effort? GitHub has not, per the reporting, tied the growth number to a revised commitment. What is on the record is that the load is up and the pipes are strained.&lt;/p&gt;

&lt;p&gt;That gap is where most CI outages live. The status page stays green while p95 job start creeps past what a release train assumes. No incident. No pager. The build just took longer, and the deploy window slid.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two knobs worth touching this week
&lt;/h2&gt;

&lt;p&gt;Regardless of how the platform side plays out, two things are worth revisiting.&lt;/p&gt;

&lt;p&gt;The first is timeouts. If your workflow has a hard job-level timeout tuned against last quarter's start-time distribution, widen the guard so a slow scheduler does not cascade into a false failure. Log the observed scheduling delay as a metric you own, not one you have to ask the vendor for.&lt;/p&gt;

&lt;p&gt;The second is a fallback lane. Hosted runners are the default because they are free of toil. When the shared pool is under pressure, self-hosted runners or a second CI plane against the same repo become the rollback path. Keeping them warm costs toil. It costs less toil than explaining why a merge sat for forty minutes on release day.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ledger keeps growing
&lt;/h2&gt;

&lt;p&gt;Nothing in the reporting suggests the numbers stop climbing. Commits, PRs and repository creates are lagging indicators of headcount, and now of coding agents writing against the same endpoints at machine speed. The next 2.9 billion lands on the same pipes. Plan your CI on the assumption that the scheduler you got last quarter is the best one you will get.&lt;/p&gt;

</description>
      <category>github</category>
      <category>actions</category>
      <category>scale</category>
      <category>infrastructure</category>
    </item>
    <item>
      <title>isolated-vm ships a sandbox escape, and the migration story catches up with itself</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Fri, 21 Aug 2026 00:23:44 +0000</pubDate>
      <link>https://dev.to/leobaniak/isolated-vm-ships-a-sandbox-escape-and-the-migration-story-catches-up-with-itself-52ja</link>
      <guid>https://dev.to/leobaniak/isolated-vm-ships-a-sandbox-escape-and-the-migration-story-catches-up-with-itself-52ja</guid>
      <description>&lt;p&gt;You run untrusted JavaScript inside a sandbox because you are a responsible adult and you have read the incident postmortems. The sandbox is the whole point. It is the line between "customer plugin" and "your production Node process, doing whatever the plugin wants". So what happens when the sandbox itself hands out the keys?&lt;/p&gt;

&lt;p&gt;That is the shape of this week's news. Endor Labs disclosed a flaw in isolated-vm, tracked as GHSA-864f-rcv7-6rh4 (CVE assignment pending), that lets code inside the sandbox corrupt memory in the host process and, from there, run whatever it likes. Patches are out in versions 7.0.1 and 6.2.0. Everything below those on either release line is a problem you already have.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bug, in one paragraph
&lt;/h2&gt;

&lt;p&gt;The escape lives in &lt;code&gt;ExternalCopy&lt;/code&gt;, the machinery isolated-vm uses to move data across V8 isolate boundaries. Senior security researcher Cris Staicu describes it as a time-of-check-to-time-of-use flaw in the C++ glue: the &lt;code&gt;ExternalCopy&lt;/code&gt; constructor iterates over the &lt;code&gt;transferList&lt;/code&gt; option twice, validates each element on the first pass, then transfers each element on the second pass without revalidating. A cooperative attacker inside the sandbox can swap what a slot points at between those two passes. Type confusion. Corrupted host memory. Hijacked control flow. RCE outside the isolate.&lt;/p&gt;

&lt;p&gt;Note where this is not. It is not a bug in V8's isolate primitive. It is in the serialization layer bolted on top of it. Which is precisely where sandbox escapes tend to live, because the isolate itself has had thousands of person-years of Chrome-team scrutiny and the glue code has had considerably less.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this one hurts more than a normal RCE
&lt;/h2&gt;

&lt;p&gt;Two reasons, and they compound.&lt;/p&gt;

&lt;p&gt;First, the audience. isolated-vm exists to run code you do not trust. Every project that pulled it in did so specifically because the threat model assumes the code inside is hostile. When a normal Node dependency has an RCE, the attacker still has to get their code onto your box. Here, the attacker's code being on your box is Tuesday.&lt;/p&gt;

&lt;p&gt;Second, who is downstream. DevOps.com lists over a million weekly downloads and names n8n, Mastra, Sim.ai, Activepieces, Screeps, Fly.io, Algolia and TripAdvisor among the users. Some of those are workflow platforms that let end users write JavaScript. Some are edge-compute or search products where "run this snippet" is the entire product. If you build on top of any of them, your effective patch window is however long it takes their team to redeploy.&lt;/p&gt;

&lt;p&gt;And there is the migration wrinkle. isolated-vm is where a lot of people landed after vm2 went unmaintained. The whole point of moving was to get out from under an abandoned sandbox with a poor security record. That is still the right move. But it is worth saying plainly: swapping runtimes does not fix the class of bug. The C++ glue between V8 isolates is where these live, and there is no version of Node where "run untrusted JS in-process" stops being a load-bearing trust boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to patch, and what to check after
&lt;/h2&gt;

&lt;p&gt;Pin to 7.0.1 or 6.2.0 depending on which line you are on, and rebuild anything that vendors a native module. That is the easy part.&lt;/p&gt;

&lt;p&gt;The harder part is what runs inside the isolate. Any sandboxed code that executed between the vulnerable version being deployed and the patch landing must be treated as potentially having escaped. That means, at minimum:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Audit host-process activity around the sandbox for the window where the vulnerable version was live: outbound network to anything the host would not normally talk to, unexpected child processes, filesystem writes outside the tenant's scoped directory.&lt;/li&gt;
&lt;li&gt;Rotate any secret the host process could read. Not the ones the sandbox is supposed to see. The ones on the host side of the boundary: API keys, database credentials, cloud-provider tokens, signing keys.&lt;/li&gt;
&lt;li&gt;If the sandbox was on a build runner, treat the runner as tainted and cycle it. A build runner that hosted an escape does not become clean because you upgraded a dependency.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is fun. All of it is the actual cost of running untrusted code in-process, made visible for a week.&lt;/p&gt;

&lt;h2&gt;
  
  
  The uncomfortable question
&lt;/h2&gt;

&lt;p&gt;Should you be running untrusted JavaScript in the same OS process as anything you care about, at all? The pragmatic answer is that isolated-vm, patched, is fine for many use cases and dramatically cheaper than a per-tenant Firecracker microVM or a WASM runtime with a real capability boundary. The honest answer is that any in-process sandbox is one C++ glue bug away from being a very expensive &lt;code&gt;child_process.exec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Patch this week. Then, this quarter, ask whether the next sandbox escape (there will be a next one) is one your architecture can absorb without rotating half your production secrets. If the answer is no, the sandbox is not the boundary. It is a suggestion.&lt;/p&gt;

</description>
      <category>isolatedvm</category>
      <category>vm2</category>
      <category>node</category>
      <category>sandboxescape</category>
    </item>
    <item>
      <title>Docker argues AI agent security is a systems problem, not a review problem</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Thu, 20 Aug 2026 16:24:53 +0000</pubDate>
      <link>https://dev.to/leobaniak/docker-argues-ai-agent-security-is-a-systems-problem-not-a-review-problem-ijj</link>
      <guid>https://dev.to/leobaniak/docker-argues-ai-agent-security-is-a-systems-problem-not-a-review-problem-ijj</guid>
      <description>&lt;p&gt;Somewhere in the last two years, "AI agent" stopped meaning a chatbot and started meaning a headless process with your build credentials. The security model for that process, in most shops, is still whatever a tired human notices in a PR at 6pm. Docker took a swing at that gap on 18 August 2026 with a blog post called "17,600 Actions: Agent Security Is a Systems Problem." The argument, in one line: you cannot code-review an actor that fires thousands of actions in a session. So stop trying.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Docker is actually claiming
&lt;/h2&gt;

&lt;p&gt;The post points at an OpenAI/Hugging Face incident in which an attacker generated 17,600 actions through an agent, and argues that agent security "can't rely on human review." Docker's phrasing for the alternative is that controls have to "constrain, observe, and govern agents at speed." Translation for the pipeline crowd: policy engines, sandboxes, and audit trails have to live inside the same loop as the agent, not after the fact.&lt;/p&gt;

&lt;p&gt;Fair, as far as it goes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the human-review model breaks
&lt;/h2&gt;

&lt;p&gt;Think about how you would review 17,600 tool calls. You wouldn't. You would eyeball the first ten, notice they look reasonable, approve the batch, and go to lunch. That is the honest workflow. It works for a forty-line diff and falls apart the instant the actor is faster than you.&lt;/p&gt;

&lt;p&gt;Every classic CI safeguard we lean on assumes bounded, discrete events. A pull request has a diff. A push is one commit. A deploy has a version. Agents don't respect that shape. One session can rewrite a workflow file, mint a token, push a container, and open ten PRs before you finish your coffee. The human-in-the-loop is not slow because of the human. It's slow because the batch size moved.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "systems-level" has to mean in practice
&lt;/h2&gt;

&lt;p&gt;The Docker post is thin on prescriptions, which is the frustrating part of an argument that is otherwise correct. If you want to constrain, observe and govern at agent speed, three unglamorous things have to be in place before you invite the bot to the party:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A capability boundary the agent physically cannot cross.&lt;/strong&gt; Not a system prompt, not a "please don't". A sandbox with no network by default, scoped credentials with a stated TTL, filesystem writes pinned to a workspace directory. Guardrails that hold when the model is wrong, or hostile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine-speed policy, not human-speed approval.&lt;/strong&gt; Every action the agent proposes has to pass a policy check that runs in milliseconds. Deny a &lt;code&gt;sudo&lt;/code&gt;, deny a push to &lt;code&gt;main&lt;/code&gt;, deny an outbound to an unallowlisted host, and record the attempt. The reviewer is code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An audit stream you can actually replay.&lt;/strong&gt; A structured log of every tool call, prompt fragment and permission decision, with a stable id per session. If you cannot reconstruct what the agent did between 02:14 and 02:19, you don't have security. You have optimism.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The unglamorous version of "agent security" is a policy engine, a sandbox runtime, and an append-only log. It looks a lot like the trust boundary you already have around your build runners. That should not be a surprise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the argument bends
&lt;/h2&gt;

&lt;p&gt;Where the post overreaches is the implicit "abandon human review." Human review is not the fix at 17,600 actions per session, but it is still the fix for the ten that matter: the ones where the agent asks for a new secret, a new external endpoint, or a change to CI configuration itself. A well-designed system escalates those to a human and lets the rest go. The system is not a replacement for review. It is a triage layer that makes review possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The verdict
&lt;/h2&gt;

&lt;p&gt;Docker is right that "watch the PR" is no longer a security model for a class of actors that can outpace your attention. Where the post is thin, the answer is unglamorous and already known to anyone who has hardened a CI runner: sandbox the runtime, mediate every action with policy, keep an audit trail you would testify from. Which is the real story here. Your agent is a runner with a better prompt. Treat it as one, and stop expecting the pull request to save you.&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>security</category>
      <category>docker</category>
      <category>governance</category>
    </item>
    <item>
      <title>The &lt;geolocation&gt; element lands in Chrome 144</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Thu, 20 Aug 2026 16:08:44 +0000</pubDate>
      <link>https://dev.to/leobaniak/the-element-lands-in-chrome-144-5g7m</link>
      <guid>https://dev.to/leobaniak/the-element-lands-in-chrome-144-5g7m</guid>
      <description>&lt;p&gt;I wired up a scratch page with the new &lt;code&gt;&amp;lt;geolocation&amp;gt;&lt;/code&gt; element the morning I read the writeup, and the surprise is how small the markup gets. What used to be a &lt;code&gt;navigator.geolocation.getCurrentPosition(...)&lt;/code&gt; dance is now a handful of attributes on a single tag.&lt;/p&gt;

&lt;p&gt;Per the Piccalilli writeup, &lt;code&gt;&amp;lt;geolocation&amp;gt;&lt;/code&gt; ships in Chrome 144+. The element began life as a general-purpose &lt;code&gt;&amp;lt;permission&amp;gt;&lt;/code&gt; element and was narrowed down to geolocation specifically. The article's headline claim is that it is better than the older Geolocation JavaScript API in every way except browser support, and after wiring it up that framing lines up with what the attributes and events actually let you do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The smallest useful markup
&lt;/h2&gt;

&lt;p&gt;Per the source, the element takes three main HTML attributes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;accuracymode&lt;/code&gt;, which accepts &lt;code&gt;approximate&lt;/code&gt; (the default, equivalent to &lt;code&gt;enableHighAccuracy: false&lt;/code&gt;) or &lt;code&gt;precise&lt;/code&gt; (equivalent to &lt;code&gt;enableHighAccuracy: true&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;autolocate&lt;/code&gt;, a boolean that requests a location automatically when permission was previously granted.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;watch&lt;/code&gt;, a boolean that turns a one-shot read into a continuous stream, the same distinction as &lt;code&gt;getCurrentPosition&lt;/code&gt; vs &lt;code&gt;watchPosition&lt;/code&gt; on the older API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also an &lt;code&gt;onlocation&lt;/code&gt; attribute for wiring an inline handler to the update event. The source does not hand you a full opinionated skeleton beyond those, so I am not going to invent one. Read the surface plainly: three declarative knobs and a place to attach a listener.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading position from JavaScript
&lt;/h2&gt;

&lt;p&gt;You still need JavaScript to get the coordinates out. Per the source, feature-detect with &lt;code&gt;if ("HTMLGeolocationElement" in window)&lt;/code&gt;. On the element itself, the writeup names these properties: &lt;code&gt;isValid&lt;/code&gt;, &lt;code&gt;invalidReason&lt;/code&gt;, &lt;code&gt;initialPermissionStatus&lt;/code&gt;, &lt;code&gt;permissionStatus&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt; and &lt;code&gt;error&lt;/code&gt;. Position data mirrors the shape you already know from the older API: &lt;code&gt;position.coords&lt;/code&gt; (with &lt;code&gt;latitude&lt;/code&gt;, &lt;code&gt;longitude&lt;/code&gt;, &lt;code&gt;altitude&lt;/code&gt;, &lt;code&gt;accuracy&lt;/code&gt;, &lt;code&gt;altitudeAccuracy&lt;/code&gt;, &lt;code&gt;heading&lt;/code&gt; and &lt;code&gt;speed&lt;/code&gt;) and &lt;code&gt;position.timestamp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Four events fire on the element per the source: &lt;code&gt;validationstatuschange&lt;/code&gt;, &lt;code&gt;promptaction&lt;/code&gt;, &lt;code&gt;promptdismiss&lt;/code&gt; and &lt;code&gt;location&lt;/code&gt;. The last one is the one you spend most of the day with. The two &lt;code&gt;prompt*&lt;/code&gt; events are the pieces the older API never gave you: a hook for when the browser's permission prompt is shown or dismissed, without you having to manage the modal yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  A styleable granted state
&lt;/h2&gt;

&lt;p&gt;This is the part that made me sit up. Per the source, there is a &lt;code&gt;:granted&lt;/code&gt; CSS pseudo-class that reflects the granted permission state on the element. The article uses it as &lt;code&gt;:not(:granted)&lt;/code&gt; — style the fallback UI while permission is missing, then let the granted state take over. That is a real declarative expression of a state that used to live in JavaScript, and it means the "waiting for the user" and "we have coordinates" branches of your UI can be written in CSS alone. Recovering from a prior denial is also called out in the writeup: the element supports user-controlled re-prompting even after a previous deny, which is a specific rough edge of the old API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Progressive enhancement in one tag
&lt;/h2&gt;

&lt;p&gt;The recommended pattern in the source is neat. Put a fallback button inside the &lt;code&gt;&amp;lt;geolocation&amp;gt;&lt;/code&gt; tags. On supporting browsers the element renders itself and hides the child; on non-supporting browsers the child renders as if the parent were not there. Wire that button to &lt;code&gt;navigator.geolocation.watchPosition()&lt;/code&gt; or &lt;code&gt;navigator.geolocation.getCurrentPosition()&lt;/code&gt; in the usual way. One markup path, one JS path, and no runtime branching in your component tree.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it runs, and where it does not
&lt;/h2&gt;

&lt;p&gt;Read the support line honestly. Per the source, this is Chrome 144+, one engine. The writeup makes no Baseline claim, and does not report Firefox or Safari status, and neither will I. So the deployment story is: keep the fallback in place, add the &lt;code&gt;&amp;lt;geolocation&amp;gt;&lt;/code&gt; element as the enhancement, feature-detect at runtime with &lt;code&gt;HTMLGeolocationElement in window&lt;/code&gt; before you rely on any of the new events, and leave the old &lt;code&gt;navigator.geolocation&lt;/code&gt; call site alone until the other engines land it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm watching next
&lt;/h2&gt;

&lt;p&gt;Two things. First, whether &lt;code&gt;:granted&lt;/code&gt; picks up matching implementations in the other engines. A state-driven pseudo-class is only as useful as its cross-engine reach. Second, whether the &lt;code&gt;&amp;lt;permission&amp;gt;&lt;/code&gt; origin of this element grows sibling elements for the other permission-gated APIs, or whether &lt;code&gt;&amp;lt;geolocation&amp;gt;&lt;/code&gt; stays a single-purpose tag. For now I am adding it as a progressive enhancement on one page that already talks to the older API, and letting the fallback carry everyone else.&lt;/p&gt;

</description>
      <category>html</category>
      <category>geolocation</category>
      <category>permissions</category>
      <category>progressiveenhancement</category>
    </item>
    <item>
      <title>Self-healing tests fixed themselves. Now the deploy needs a second look.</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Thu, 20 Aug 2026 08:26:11 +0000</pubDate>
      <link>https://dev.to/leobaniak/self-healing-tests-fixed-themselves-now-the-deploy-needs-a-second-look-5gj0</link>
      <guid>https://dev.to/leobaniak/self-healing-tests-fixed-themselves-now-the-deploy-needs-a-second-look-5gj0</guid>
      <description>&lt;p&gt;I got the ping around four in the afternoon: our nightly end-to-end suite went red on a signup flow, then green ten minutes later, on the same commit. Nobody had touched the code. The test framework had noticed a button had drifted, guessed at a new locator, and moved on. The deploy pipeline never blinked.&lt;/p&gt;

&lt;p&gt;That memory came back reading a DevOps.com essay published on August 19, 2026, arguing that self-healing tests, the ones that inspect the page, propose a new locator, and rerun themselves to a green result after a front-end change, need an explicit deployment gate. Otherwise a repaired-and-green run silently unblocks a release that a human never actually looked at.&lt;/p&gt;

&lt;p&gt;If you have never met a self-healing test in the wild, the pitch is genuinely lovely. Front-end teams reshuffle the DOM every sprint, and the day someone renames a container should not cost you two hours of triage. So the tool watches the failing step, walks the DOM, finds the element that most likely used to be the target, patches the locator in memory, and reruns. Green. Pipeline keeps flowing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The catch worth naming out loud
&lt;/h2&gt;

&lt;p&gt;Here is the uncomfortable part. A rerun-to-green after a locator swap is not the same signal as a plain green run. The first time it happens on your service, it might be a harmless class rename. The second time, it might be a designer moving the confirm-order button under a collapsed accordion, and the healed selector is now clicking a totally different control. From the pipeline's point of view, both look like a passing suite. The commit gets a check mark, the deploy job fires, and by the time your users notice, the auto-repair is already three commits deep in main.&lt;/p&gt;

&lt;p&gt;That is the argument in the DevOps.com piece, and I think it lands. The healing itself is fine. What breaks is that a repair event and a passing test event reach the pipeline through the same door.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a real gate looks like
&lt;/h2&gt;

&lt;p&gt;The gate the essay is asking for is small and boring, which is the good news. Concretely, in most modern CI setups it means three moving parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The test runner emits a distinct signal when a locator was rewritten during the run, not just pass or fail.&lt;/li&gt;
&lt;li&gt;That signal blocks promotion to the next environment until a human clicks approve.&lt;/li&gt;
&lt;li&gt;The approval UI shows a diff of the old selector, the new selector, and a screenshot of what actually got clicked.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of that is exotic. Most e2e platforms already record the repair in a report. The missing step is wiring the report back into the pipeline as a gate, so the deploy job waits on a healed-run review the same way it waits on a security scan or a manual QA sign-off.&lt;/p&gt;

&lt;h2&gt;
  
  
  How pipeline platforms model this today
&lt;/h2&gt;

&lt;p&gt;Nobody in the CI space ships a "self-healed test gate" out of the box, but every major platform has the primitives to build one. Worth being honest about the trade-offs, because none of these is a clean win:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions&lt;/strong&gt; with &lt;code&gt;environments&lt;/code&gt; and required reviewers is the most common pattern I see. You emit the healed flag from your test job, set an output, and route the deploy job through a protected environment that only opens on a manual approval. It works, but the approval UI does not show you the selector diff by default. You have to link out to your test tool.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitLab CI&lt;/strong&gt; has &lt;code&gt;when: manual&lt;/code&gt; jobs and protected environments that do the same thing. GitLab's advantage is that the pipeline graph shows the manual gate as an obvious yellow node, so it is harder to miss on the merge request page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Argo Rollouts&lt;/strong&gt; with a metric-analysis step is honestly the better fit if you want the gate to be automatic rather than human-in-the-loop. If a healed test correlates with a real user-facing metric like error rate or form submissions, you can hold the rollout on the metric instead of on a click. For teams already doing progressive delivery this is where I would start, not with a manual approval.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jenkins&lt;/strong&gt; with an &lt;code&gt;input&lt;/code&gt; step is the veteran option, and if you already run Jenkins the pipeline DSL makes the gate a two-line change. The trade-off is that the approval sits at a URL people forget to bookmark, so review latency tends to be higher.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CircleCI&lt;/strong&gt; has approval jobs that behave like Jenkins input steps, plus workflow-level filters, so the pattern is available. The friction is that context passing between jobs is verbose compared to Actions outputs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buddy&lt;/strong&gt; pipelines let you gate an action on a variable from a previous action and add a wait-for-approval step before deploy, so the healed-run flag becomes a normal conditional. It is one option among several here; the reason to pick it is if you want the approval and the pipeline log in the same UI without wiring a second tool. If your team already lives in Argo or in the GitLab merge request page, stay put. See the &lt;a href="https://buddy.works/docs/pipelines/pipeline-actions?utm_source=cicd-deployment-to&amp;amp;utm_medium=article&amp;amp;utm_campaign=self-healing-gate" rel="noopener noreferrer"&gt;pipeline actions docs&lt;/a&gt; for the trigger-condition shape.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A rough YAML sketch of that shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Run&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;e2e&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tests"&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BUILD"&lt;/span&gt;
  &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HEAL_FLAG&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;$HEAL_FLAG"&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Review&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;healed&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;run"&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;WAIT_FOR_APPLY"&lt;/span&gt;
  &lt;span class="na"&gt;trigger_condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VAR_IS"&lt;/span&gt;
  &lt;span class="na"&gt;trigger_variable_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HEAL_FLAG"&lt;/span&gt;
  &lt;span class="na"&gt;trigger_variable_value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true"&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Deploy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;production"&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;KUBERNETES_APPLY_DEPLOYMENT_CONFIG"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Placeholders, obviously. Your test runner has to be the thing that sets &lt;code&gt;HEAL_FLAG&lt;/code&gt;, and none of this rescues you from a suite that heals ten times per run and desensitises the humans on the other end.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I am watching next
&lt;/h2&gt;

&lt;p&gt;Two things. First, whether any of the mainstream e2e test tools start shipping the healed signal as a first-class pipeline output, so we can stop parsing report JSON by hand. Second, whether teams actually turn the gate on once they build it. A gate that everyone clicks through on autopilot in six seconds is worse than no gate, because the pipeline log now says a human approved the healed run when what really happened is that nobody read it. If you have found a way to keep those reviews honest past week three, I would love to hear how on your next PR.&lt;/p&gt;

</description>
      <category>selfhealingtests</category>
      <category>endtoendtests</category>
      <category>deploymentgate</category>
      <category>qualitygates</category>
    </item>
    <item>
      <title>EKS clusters lag on an AWS auth deprecation, per The New Stack</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Thu, 20 Aug 2026 00:25:02 +0000</pubDate>
      <link>https://dev.to/leobaniak/eks-clusters-lag-on-an-aws-auth-deprecation-per-the-new-stack-3i17</link>
      <guid>https://dev.to/leobaniak/eks-clusters-lag-on-an-aws-auth-deprecation-per-the-new-stack-3i17</guid>
      <description>&lt;p&gt;The New Stack reports that 81% of Amazon EKS clusters still run an AWS EKS authentication method that the vendor has already deprecated, published as part of a wider look at Kubernetes fleet security management. For platform teams whose deploy pipelines target EKS, that share is a migration flag more than a headline. The auth path baked into your kubeconfigs, CI service accounts and IaC modules is on borrowed time, and the reported fleet share says most peers have not started moving yet.&lt;/p&gt;

&lt;p&gt;The piece frames the gap as a fleet-scale problem. Clusters age in place, and the deploy pipelines wired against them inherit whichever auth style was current the day the cluster was first stood up. Over enough years, the installed base drifts behind the vendor's own guidance, and any large fleet ends up with a long tail of pipelines still speaking the older protocol. Per The New Stack, that tail is now the majority of clusters.&lt;/p&gt;

&lt;p&gt;The report, as it stands, does not pin AWS to a specific removal date, and this write-up is not going to guess one. Read the 81% as a snapshot: it is the size of the migration you or your platform peers still owe, not a deadline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this bites CI/CD
&lt;/h2&gt;

&lt;p&gt;Two failure modes tend to show up on the day a cluster-auth deprecation flips from warned to removed.&lt;/p&gt;

&lt;p&gt;Cluster access from pipelines is the loud one. Every job that authenticates to EKS through the deprecated flow, whether that is an &lt;code&gt;aws eks update-kubeconfig&lt;/code&gt; call, a helm or kubectl step, or a Terraform provider pinned against the old auth surface, starts returning &lt;code&gt;Unauthorized&lt;/code&gt;. The recovery is a re-plumb of the cluster's own auth model, which is slower and more coordinated than rolling back a normal deploy.&lt;/p&gt;

&lt;p&gt;Automation identities are the quiet one. Non-human principals like CI runners, in-cluster controllers and GitOps agents are usually the last things anyone re-authenticates, because nobody notices they broke until a deploy fails. On a real platform team's fleet, the audit and swap-out of every service principal is where the actual work sits.&lt;/p&gt;

&lt;p&gt;The reported 81% is a share, not an inventory. It says how many clusters across the sample the piece cites are still on the deprecated path. It does not say which of your clusters are, or which of your pipelines authenticate through them. If you have not run that inventory yet, the number is a signal that the industry has not either. Do it before the removal date lands, not after.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>eks</category>
      <category>kubernetes</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Agent Plugins 1.0 goes GA across VS Code, Copilot CLI and the Copilot app</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Wed, 19 Aug 2026 16:25:41 +0000</pubDate>
      <link>https://dev.to/leobaniak/agent-plugins-10-goes-ga-across-vs-code-copilot-cli-and-the-copilot-app-347g</link>
      <guid>https://dev.to/leobaniak/agent-plugins-10-goes-ga-across-vs-code-copilot-cli-and-the-copilot-app-347g</guid>
      <description>&lt;h2&gt;
  
  
  The moment I stopped shipping the same plugin twice
&lt;/h2&gt;

&lt;p&gt;Every time I have shipped a Copilot plugin, some part of me knew I would end up shipping it twice. Once for the editor, once for the CLI, once more for whichever surface a teammate insisted on. So the GitHub changelog line dated August 12 landed as a quiet relief for me: Agent Plugins 1.0 is now generally available across VS Code, Copilot CLI, the GitHub Copilot SDK and the Copilot app, on all Copilot plans. One package, four places it can attach.&lt;/p&gt;

&lt;p&gt;If you have never authored one of these, the friction is the point. You had skills, you had an MCP server config, and you had a slightly different envelope for every host. Now GitHub says compatible clients can discover the skills and MCP server configuration they support from the same package. That is the whole pitch, and if you have been threading agent tooling into pipelines and IDEs in the same week, it changes what "supporting Copilot" costs you.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the release actually does
&lt;/h2&gt;

&lt;p&gt;The change is small and load-bearing. Agent Plugins 1.0 is a shared package format that is portable across the three Copilot surfaces plus the SDK. Installations flow through a marketplace called Awesome Copilot, which ships enabled by default in VS Code, Copilot CLI and the Copilot app.&lt;/p&gt;

&lt;p&gt;A few things worth noting from the changelog itself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The support is described as generally available across all Copilot plans, so this is not gated behind a preview flag.&lt;/li&gt;
&lt;li&gt;Existing Copilot plugins that predate the 1.0 spec keep working. There is no forced migration.&lt;/li&gt;
&lt;li&gt;Skills live under &lt;code&gt;skills/&lt;/code&gt;, MCP configuration lives in &lt;code&gt;mcp.json&lt;/code&gt;, and any files that only make sense inside Copilot land in a &lt;code&gt;com.github.copilot/&lt;/code&gt; directory that other compatible clients ignore.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last bullet is the one I keep re-reading. That directory pattern is how a portable format tolerates a vendor-specific escape hatch without turning back into a fork. Every client sees the same tree, and the Copilot-only bits are quarantined by convention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this shows up on a CI/CD desk
&lt;/h2&gt;

&lt;p&gt;If your pipeline already touches any of these surfaces, and most of them do now, plugins are the seam where "agent behaviour" becomes "code you own". A skill you ship in &lt;code&gt;skills/&lt;/code&gt; is a thing your build can generate, sign and version. An &lt;code&gt;mcp.json&lt;/code&gt; you ship in the same package is a thing your reviewer can diff in a PR. The move to one artifact means the review, the provenance and the release cadence collapse into a single object.&lt;/p&gt;

&lt;p&gt;That has a knock-on effect on rollout. When a plugin was three ports, teams tended to update the surface they used most and drift on the other two. One package with one release means the CLI and the app catch up automatically, which matters when the plugin talks to a production MCP server and you would rather not have three versions of your tool contract in the wild.&lt;/p&gt;

&lt;p&gt;The DX win on any given day is modest. The compounding win over a quarter is bigger. You author once and you post-mortem once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migrating a plugin you already ship
&lt;/h2&gt;

&lt;p&gt;The changelog spells out the mechanical bits, and they are short. If you have an existing Copilot plugin, three moves get you onto the 1.0 spec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json-doc"&gt;&lt;code&gt;&lt;span class="c1"&gt;// plugin.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;url-of-agent-plugins-1.0-schema&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="c1"&gt;// your existing fields stay&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then check that skills live under &lt;code&gt;skills/&lt;/code&gt;, MCP config sits in &lt;code&gt;mcp.json&lt;/code&gt;, and anything Copilot-specific is moved into the &lt;code&gt;com.github.copilot/&lt;/code&gt; folder so other clients skip it cleanly. That is the migration. Everything else the changelog promises to leave alone.&lt;/p&gt;

&lt;p&gt;If you are starting fresh, the pull is stronger. You pick up marketplace discovery via Awesome Copilot without extra work, and you inherit whatever installation UX the surface owner ships without writing it yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The enterprise knobs worth reading twice
&lt;/h2&gt;

&lt;p&gt;For anyone whose day job includes signing off on what installs itself into a developer laptop, the governance surface is worth reading twice. The changelog names three settings inside &lt;code&gt;managed-settings.json&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;enabledPlugins&lt;/code&gt; for automatic installation or blocking&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;extraKnownMarketplaces&lt;/code&gt; to add sources&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;strictKnownMarketplaces&lt;/code&gt; to restrict to managed sources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last flag is the one I would flip early. A marketplace that ships enabled by default is convenient. A marketplace that ships enabled by default without a way to lock the source list would keep me up. &lt;code&gt;strictKnownMarketplaces&lt;/code&gt; puts the org back in charge of where plugin code comes from, and it does so before the "which plugins" question, which is the right order.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rough edges I would keep an eye on
&lt;/h2&gt;

&lt;p&gt;Enthusiasm with the receipts still attached. A few things I would want to watch settle before I recommend this to a friend running a hundred-engineer org:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The marketplace ships enabled by default. Fine for reach, less fine for a security team that wants a curated allowlist before anyone can install. If you are in a regulated setting, wire up &lt;code&gt;strictKnownMarketplaces&lt;/code&gt; on day one.&lt;/li&gt;
&lt;li&gt;Backward compatibility is a promise, not a plan. Pre-1.0 plugins keep working today. The open question is how long, and whether newer marketplace features quietly become 1.0-only over the next few releases.&lt;/li&gt;
&lt;li&gt;Portability is a claim about compatible clients. The four GitHub-owned surfaces are the ones the changelog names. Third-party editors and CLI hosts that say they are Copilot-compatible will have their own catch-up schedules.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of these are dealbreakers. All are worth a five-minute conversation with whoever owns your dev-tools policy.&lt;/p&gt;

&lt;h2&gt;
  
  
  How other agent surfaces are approaching the same problem
&lt;/h2&gt;

&lt;p&gt;Portable plugin formats are having a moment across the agent ecosystem. The Model Context Protocol has been doing the same job at the transport layer, giving skills and tools a shared way to describe themselves regardless of which host loads them. Editor extension ecosystems (the VS Code marketplace being the obvious ancestor) already showed how much friction a shared package format removes once tooling catches up. Terminal-first agents typically ship their own plugin shapes, pinned to that vendor's CLI. Watching one release land Agent Plugins 1.0 across an editor, a CLI and an app is the first time I have seen a large vendor try to hit all three surfaces with a single artifact.&lt;/p&gt;

&lt;p&gt;The interesting comparison in six months will not be "is Agent Plugins 1.0 portable enough?" It will be "which non-Copilot host actually implements it?" A shared format lives or dies by the second implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I am watching next
&lt;/h2&gt;

&lt;p&gt;Two things. First, whether &lt;code&gt;plugin.json&lt;/code&gt; picks up a proper signing story over the next few releases. Portable plugins without a portable trust story are a bigger blast radius, not a smaller one. Second, whether Awesome Copilot grows a machine-readable curation layer a security team can point at. If both of those show up, this stops being a DX release and starts being an infrastructure release, and I will happily write that one up too.&lt;/p&gt;

</description>
      <category>githubcopilot</category>
      <category>plugins</category>
      <category>agents</category>
      <category>vscode</category>
    </item>
  </channel>
</rss>
