<?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>A native ClickHouse target lands in a CI platform, and the boring parts are the point</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Tue, 15 Sep 2026 10:25:19 +0000</pubDate>
      <link>https://dev.to/leobaniak/a-native-clickhouse-target-lands-in-a-ci-platform-and-the-boring-parts-are-the-point-4nh0</link>
      <guid>https://dev.to/leobaniak/a-native-clickhouse-target-lands-in-a-ci-platform-and-the-boring-parts-are-the-point-4nh0</guid>
      <description>&lt;p&gt;The first thing I do when a new database target lands in a CI tool is check what happens to my secrets. Not the marketing screenshots. The connection string, the password, and the retry behaviour when the query hangs at 3am. Buddy shipped a native ClickHouse target last week, and it clears exactly that first checkpoint: store the connection once, then run queries, schema migrations, and post-deployment data checks from any pipeline step.&lt;/p&gt;

&lt;p&gt;If you have ever wired ClickHouse into a generic runner, you know the shape of the pain. You stash a URL and a password in five secret variables, then paste a &lt;code&gt;clickhouse-client&lt;/code&gt; invocation into shell steps across three workflows, and hope nobody adds a verbose flag that echoes the DSN into a public build log. The new target moves that plumbing behind a stored connection you configure at the workspace level.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually changes in the day
&lt;/h2&gt;

&lt;p&gt;A native database target is not a headline feature. It is a quiet one, and that is why I like it. Look at the workflow it unlocks: a schema migration step that reads the same stored connection as the downstream analytics check, a post-deploy assertion that counts rows against the release you just cut, a rollback path that does not require re-entering credentials during a hotfix at the worst possible hour.&lt;/p&gt;

&lt;p&gt;Two things I would still test before trusting this in a critical release path. First, how the target surfaces errors when a query times out or returns a partial result set, because ClickHouse queries can succeed loudly and fail quietly on tail cases. Second, whether the audit trail on the stored connection is granular enough to answer "who ran what against production last Thursday" without an export dance through three UIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How other tools tackle the same job
&lt;/h2&gt;

&lt;p&gt;You have options for pointing a pipeline at ClickHouse, and each of them makes a different trade. An honest tour:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;dbt.&lt;/strong&gt; If your team already lives in dbt for transformations and tests, dbt is the stronger pick for analytics checks against ClickHouse. Its test primitives were built for exactly that shape, and the community around ClickHouse-flavoured dbt is real.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flyway or Liquibase.&lt;/strong&gt; Dedicated schema-migration tools with community and third-party ClickHouse drivers. Worth the extra layer if you need repeatable, versioned migrations with proper checksums.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bytebase.&lt;/strong&gt; A change-management surface on top of migrations, with review workflows and drift detection. Overkill for a small stack, appropriate when compliance wants a paper trail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions or GitLab CI with &lt;code&gt;clickhouse-client&lt;/code&gt;.&lt;/strong&gt; The lowest-friction path when your team has strong Bash discipline and does not want another abstraction. The trade is exactly what a stored native target is now solving: credentials spread across secret variables until nobody remembers which one the migration step reads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buddy.&lt;/strong&gt; A fair option when you want the connection stored once and the same target reused across query, migration and post-deploy check steps in one pipeline. See the &lt;a href="https://buddy.works/blog/clickhouse-target-buddy-pipelines?utm_source=cicd.deployment.to&amp;amp;utm_medium=post&amp;amp;utm_campaign=clickhouse-target" rel="noopener noreferrer"&gt;ClickHouse target release notes&lt;/a&gt; for the specifics.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I am watching next: whether the stored target composes cleanly with the pipeline's existing secrets and outputs surface, so a migration step and an analytics check can share a hostname without pretending to share a transaction. That is the part that decides whether this stays a nice convenience or becomes the default way I reach for ClickHouse in a build.&lt;/p&gt;

</description>
      <category>pipeline</category>
      <category>deploy</category>
      <category>clickhouse</category>
      <category>database</category>
    </item>
    <item>
      <title>Google named Leader in Gartner's inaugural Enterprise AI Assistants Magic Quadrant</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Mon, 14 Sep 2026 00:27:14 +0000</pubDate>
      <link>https://dev.to/leobaniak/google-named-leader-in-gartners-inaugural-enterprise-ai-assistants-magic-quadrant-2d26</link>
      <guid>https://dev.to/leobaniak/google-named-leader-in-gartners-inaugural-enterprise-ai-assistants-magic-quadrant-2d26</guid>
      <description>&lt;p&gt;Google Cloud said this week that Gartner has placed it in the Leaders quadrant of its inaugural 2026 Magic Quadrant for Enterprise AI Assistants, on both axes: Completeness of Vision and Ability to Execute. The Google post ties the placement to Gemini Enterprise, which it frames as moving past chat into multi-step, end-to-end workflows driven by AI agents.&lt;/p&gt;

&lt;p&gt;The badge is a marketing outcome. What lands on a platform team is the product framing. Per Google's post, Gemini Enterprise drives multi-step, end-to-end workflows through AI agents, and those are the workflows a pipeline already runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the announcement actually contains
&lt;/h3&gt;

&lt;p&gt;The post asserts a Leader placement on both dimensions and links to the full Magic Quadrant through Gartner. It does not restate Gartner's methodology, the other vendors on the chart, or the specific criteria weighted for a category that did not exist before. What is public is Google's placement claim and the Gemini Enterprise pitch attached to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where an assistant lands in the pipeline
&lt;/h3&gt;

&lt;p&gt;Two things carry over into build and deploy work regardless of a ranking.&lt;/p&gt;

&lt;p&gt;First, agent workflows need credentials somewhere. An assistant that reaches into source control, an artifact store, or a runner is a new principal in the identity system. It inherits whatever access the surrounding tooling already grants, and the surface is wider than a demo shows.&lt;/p&gt;

&lt;p&gt;Second, multi-step means auditable, or it does not. Every action an agent takes should leave a trace a reviewer can read later. If the audit event drops the agent's identity, or collapses ten steps into a single line, the trail stops being useful during a post-incident review.&lt;/p&gt;

&lt;p&gt;For platform teams the useful questions start after the badge: which scopes an assistant is granted, whose audit log the actions land in, and what the blast radius looks like when an agent misfires. Those answers belong in a runbook.&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>security</category>
    </item>
    <item>
      <title>Your DevOps platform's real bill is not on the invoice</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sun, 13 Sep 2026 16:24:59 +0000</pubDate>
      <link>https://dev.to/leobaniak/your-devops-platforms-real-bill-is-not-on-the-invoice-3f3f</link>
      <guid>https://dev.to/leobaniak/your-devops-platforms-real-bill-is-not-on-the-invoice-3f3f</guid>
      <description>&lt;p&gt;The first time I watched a finance partner cross-reference our CI/CD invoice with actual minutes burned, I felt my stomach drop for the platform team. We had negotiated the seat price down to the cent. We had not really priced the six-minute pipeline that ran a hundred and fifty times a day across three environments, or the four engineers who quietly kept the runner fleet from wandering off. GitLab put out a blog post this week that names this whole shadow bill directly, and it is worth reading with a spreadsheet open.&lt;/p&gt;

&lt;p&gt;The framing is simple. Subscription fees and license costs, GitLab writes, "only tell one part of the story." The total cost of ownership for a DevOps platform also includes variable costs like CI/CD compute and AI usage, plus the infrastructure, tools, and employee time required to keep software delivery moving. There is nothing revolutionary in that sentence, but I have watched enough platform reviews go sideways on exactly this point to be glad someone is writing it down as a checklist.&lt;/p&gt;

&lt;h2&gt;
  
  
  The line items nobody prices at signup
&lt;/h2&gt;

&lt;p&gt;When you buy a CI/CD platform you buy a promise about seats. What you consume, month after month, is closer to a utility bill.&lt;/p&gt;

&lt;p&gt;Start with compute. Every hosted-runner minute has a rate card, and the rate goes up sharply once you leave the free tier or step onto a bigger machine class. If you have not looked at your own numbers lately, pull the last three months of runner minutes by workflow and sort descending. Usually one or two workflows dominate. Then look at how many of those runs were retries, PR churn, or scheduled jobs that nobody remembers scheduling. That is real money.&lt;/p&gt;

&lt;p&gt;Then AI usage. Any platform now shipping agent features or in-editor assistants prices those on tokens or requests, and the meter runs whether the suggestion shipped or not. In my own team we saw the AI line item move from a rounding error to a real budget conversation in about a quarter, and we were not doing anything unusual with it. If you have not yet, ask your vendor for a per-user, per-day breakdown before signing a bigger tier.&lt;/p&gt;

&lt;p&gt;Then the human line. Engineer time to build custom actions, to babysit self-hosted runners, to chase flaky tests, to onboard a new team onto the pipeline template. This is the cost that never appears on any invoice and often outweighs everything else. GitLab's post lumps this in with "the infrastructure, tools, and employee time required to keep software delivery moving," which I think is exactly right, if a little polite about how large that number can get.&lt;/p&gt;

&lt;h2&gt;
  
  
  A back-of-the-envelope that will not embarrass you
&lt;/h2&gt;

&lt;p&gt;If your finance partner wants a defensible number, four buckets get you most of the way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Subscription and seats.&lt;/strong&gt; Sticker price times headcount, minus whatever multi-year discount you actually secured. This is the easy row.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variable platform usage.&lt;/strong&gt; Hosted-runner minutes, storage for artifacts and caches, network egress if your platform meters it, and AI or agent tokens. Pull last quarter, annualise it, and add a growth factor honest to your hiring plan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adjacent infrastructure.&lt;/strong&gt; Self-hosted runner fleet (VMs, container hosts, the load balancer in front of them), the secrets manager, the artifact registry, and whatever observability you point at CI. Some of this may already be on a cloud bill; count it anyway.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;People time.&lt;/strong&gt; Platform engineers dedicated to the pipeline, plus a fraction of every other engineer's week that goes to pipeline maintenance instead of shipping. A conservative one day per engineer per month is a starting point; measure it if you can.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add the four. That is your TCO. It will be a bigger number than the invoice, and that is the point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the platforms actually differ
&lt;/h2&gt;

&lt;p&gt;The comparison worth having is not "which one has the lowest seat price." It is which one moves cost from the invoice into your engineering-hours column, or the other way around. A few honest observations, based on running or watching each of these in production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions&lt;/strong&gt; is where most teams already are, so the marginal seat cost is often zero. The bill quietly grows through Actions minutes on hosted runners and, more recently, Copilot and agent tokens. If you host your own runners you inherit the whole babysitting workload, and it is not trivial.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitLab CI/CD&lt;/strong&gt; couples the pipeline to the SCM, the registry, the security scanners and now agent features in one subscription. That collapses several line items, which is the pitch the linked post is implicitly making. The trade-off is a heavier product surface to run, especially self-managed, and a real migration cost if you are not already there.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CircleCI&lt;/strong&gt; is a strong pick when your bottleneck is orchestration on hosted infra and you want to stop thinking about runner ops. It bills on credits, which makes forecasting straightforward, and its parallelism controls can genuinely bring wall-clock time and cost down at the same time. If you are heavy on custom Docker workflows across many services, it deserves a real look before anything else on this list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buildkite&lt;/strong&gt; flips the model: hosted control plane, your compute. If you already have a good Kubernetes or bare-metal fleet, the compute line collapses into an existing cloud bill and the platform bill stays small. If you do not, you are back to babysitting runners.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jenkins&lt;/strong&gt; has no license line, which is what makes it deceptively cheap. The people-time bucket is where the money lives, and it lives there permanently. I still like Jenkins on teams with a real platform crew and an unusual pipeline shape; I would not pick it fresh today for a small team optimising for TCO.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buddy&lt;/strong&gt; (&lt;a href="https://buddy.works/?utm_source=cicd.deployment.to&amp;amp;utm_medium=article&amp;amp;utm_campaign=devops-tco" rel="noopener noreferrer"&gt;buddy.works&lt;/a&gt;) is one option worth weighing when the human-time bucket is your worst one and you would rather build pipelines by dragging actions than by writing YAML. The pipeline editor collapses a lot of the setup work into visual configuration, which can lower the engineer-hours side of TCO for smaller teams. It is not the right answer if you want deep programmatic control of every step, or if your team already has a fluent YAML-first workflow that they like; CircleCI or Buildkite will fit better there.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these is universally cheapest. Cost lives in the shape of your team and your workload, not in the sticker price.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rough edge
&lt;/h2&gt;

&lt;p&gt;A TCO worksheet is only as honest as your telemetry. If you cannot tell me which workflow burned the most runner minutes last month, or how many AI calls your agents made and for what, you are not calculating TCO, you are guessing at it. Before you compare vendors, spend a week getting those two numbers out of your current platform. The comparison gets much shorter after that.&lt;/p&gt;

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

&lt;p&gt;I want to see whether platforms start publishing their AI and agent usage in the same shape as their compute usage: per user, per project, per pipeline, exportable. The compute meter got readable over the last few years, mostly because customers demanded it. The AI meter is where the compute meter was in 2019, and finance will be back with the same questions soon enough. If your vendor cannot show you a clean per-project AI breakdown yet, put it on the next QBR agenda. Mine did.&lt;/p&gt;

</description>
      <category>cicd</category>
      <category>tco</category>
      <category>platform</category>
      <category>cost</category>
    </item>
    <item>
      <title>Google's Antigravity SDK lets you assemble your own agent hub</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sun, 13 Sep 2026 08:26:08 +0000</pubDate>
      <link>https://dev.to/leobaniak/googles-antigravity-sdk-lets-you-assemble-your-own-agent-hub-4d83</link>
      <guid>https://dev.to/leobaniak/googles-antigravity-sdk-lets-you-assemble-your-own-agent-hub-4d83</guid>
      <description>&lt;p&gt;I have wanted this thing for months. Not the SDK exactly, but the small dignity of running an agent inside my own hub and being able to answer, at any point, "what is it doing right now?". Google's Antigravity SDK, published on September 8, 2026, is the piece I was waiting for: the same runtime that powers Antigravity 2.0 and the Antigravity CLI, exposed as a library you can wire into your own control plane.&lt;/p&gt;

&lt;p&gt;If you are on a platform team that has been quietly weighing "adopt a managed agent platform" against "build our own hub and keep control of the trust boundary", this changes the shape of that conversation. You are no longer choosing between the polished commercial box and a wall of glue code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the SDK actually is
&lt;/h2&gt;

&lt;p&gt;Google frames the choice honestly. For teams that want turnkey deployment and governance, the pitch is still Gemini Enterprise Agent Platform. The SDK is for the other camp: developers with bespoke workflows or custom execution engines, building lightweight agent hubs from the ground up. What they get is the runtime engine used inside Antigravity 2.0 and its CLI, published as a library. When the core runtime is updated, agents built on the SDK inherit those changes automatically.&lt;/p&gt;

&lt;p&gt;The runtime supports Gemini 3.1 Pro and Gemini 3.8 Flash, and the announcement centres on a Python API.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four pieces I care about
&lt;/h2&gt;

&lt;p&gt;Google groups the SDK around four building blocks, and each one maps onto a real pain I have hit trying to run agents in production workflows.&lt;/p&gt;

&lt;p&gt;Start with skills. A skill in the Antigravity SDK is a folder with a &lt;code&gt;SKILL.md&lt;/code&gt; file, and the runtime picks them up from filesystem paths you pass in, then injects them into the agent's prompt dynamically. No external registry to babysit. If you have ever shipped a prompt-template package and regretted the release process, you will feel the difference on your first commit.&lt;/p&gt;

&lt;p&gt;Next, the built-in file tools. The SDK ships &lt;code&gt;LIST_DIR&lt;/code&gt;, &lt;code&gt;FIND_FILE&lt;/code&gt;, &lt;code&gt;SEARCH_DIR&lt;/code&gt;, &lt;code&gt;VIEW_FILE&lt;/code&gt;, &lt;code&gt;CREATE_FILE&lt;/code&gt; and &lt;code&gt;EDIT_FILE&lt;/code&gt;, and they execute only inside directories you list in the &lt;code&gt;workspaces&lt;/code&gt; parameter, governed by declarative safety policies such as &lt;code&gt;policy.workspace_only()&lt;/code&gt;. Operations outside the authorized paths are blocked. This is the part I would have hand-rolled badly. Having it as a first-class config item saves an entire class of near-misses.&lt;/p&gt;

&lt;p&gt;Then the session trajectories. Every conversation carries a &lt;code&gt;save_dir&lt;/code&gt; and a &lt;code&gt;conversation_id&lt;/code&gt;, and the runtime persists full turn trajectories, tool receipts and artifacts under &lt;code&gt;traj-&amp;lt;conversation_id&amp;gt;&lt;/code&gt;. Reattach a session by passing the same id back in. Anyone who has tried to reconstruct what an agent actually did from a scrollback buffer will read the trajectory docs first.&lt;/p&gt;

&lt;p&gt;Last, the lifecycle hooks. Async hooks fire at session start, before and after each tool call, and at session end. The &lt;code&gt;pre_tool_call_decide&lt;/code&gt; hook is the human-in-the-loop gate: your code can approve, modify or reject a tool call before it runs. Hooks also broadcast telemetry over WebSockets, which is how the Google post frames the dashboard use case: watch multiple agents live and steer them when they drift.&lt;/p&gt;

&lt;p&gt;There is a small extra treat in the response API. A single model response exposes three concurrent async iterators: &lt;code&gt;response&lt;/code&gt; for the visible tokens, &lt;code&gt;response.thoughts&lt;/code&gt; for the internal reasoning deltas, and &lt;code&gt;response.tool_calls&lt;/code&gt; for typed tool events. If you want a UI that shows the agent's thinking in one pane and its actions in another, that is the shape you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it fits, and where I would still hesitate
&lt;/h2&gt;

&lt;p&gt;The best fit is a platform team that already knows what an agent hub should feel like for its developers, and just wants a runtime that will not fight them. The declarative workspace policies mean you can hand a hub to a product team without also handing them a paved road to shell out.&lt;/p&gt;

&lt;p&gt;I have two honest reservations. The SDK is Python in this announcement, so a JVM or Go platform team is looking at a sidecar or a wait. And it is a Google runtime built to run Gemini models. If your compliance story requires model portability, an SDK that lists two Gemini variants as its supported models is a signal to plan for that boundary early.&lt;/p&gt;

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

&lt;p&gt;Two things. Whether the trajectory format is stable enough to use as a compliance artifact (auditors love a directory of receipts, as long as the schema does not drift on them). And whether other agent runtimes take the "skills are directories" shape seriously. If they do, prompt packaging finally starts to look like software, and CI teams stop shipping prompts through backchannels.&lt;/p&gt;

&lt;p&gt;If you try it, tell me what your first hook did. Mine will be a boring one: log to the same aggregator every other service already writes to, so on-call has one place to look.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>sdk</category>
      <category>deploy</category>
    </item>
    <item>
      <title>GitLab's Co-Create recap lands W3C trace context and merge-train limits in CI/CD</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sun, 13 Sep 2026 00:26:35 +0000</pubDate>
      <link>https://dev.to/leobaniak/gitlabs-co-create-recap-lands-w3c-trace-context-and-merge-train-limits-in-cicd-3817</link>
      <guid>https://dev.to/leobaniak/gitlabs-co-create-recap-lands-w3c-trace-context-and-merge-train-limits-in-cicd-3817</guid>
      <description>&lt;h2&gt;
  
  
  What shipped
&lt;/h2&gt;

&lt;p&gt;GitLab's Co-Create program recap, published September 10, names three shipped CI/CD changes worth pulling out from the marketing frame: W3C Trace Context variables inside pipeline jobs, configurable merge-train pipeline limits, and a REST API for Terraform state protection rules. All three landed via GitLab's user-collaboration program in the first half of 2026, per the post.&lt;/p&gt;

&lt;p&gt;Two new predefined variables, &lt;code&gt;CI_TRACEPARENT&lt;/code&gt; and &lt;code&gt;CI_TRACESTATE&lt;/code&gt;, bring W3C Trace Context into pipeline jobs. Teams can now correlate traces across parent and child pipelines, per GitLab, so a slow child pipeline stops being an opaque "10 more minutes" in the parent's timeline.&lt;/p&gt;

&lt;p&gt;Configurable merge train pipeline limits landed alongside that. Teams can set a cap that matches their plan and capacity, per the post. If your merge train has ever quietly grown into a queue nobody remembered to cap, this is the knob.&lt;/p&gt;

&lt;p&gt;The third change is a REST API for Terraform state protection rules covering retrieve, create, update and delete. Protection-rule state moves out of the UI and into whatever governance pipeline already runs for the rest of your infrastructure controls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it will bite
&lt;/h2&gt;

&lt;p&gt;The tracing variables close a real observability gap, but they are variables, not spans. You still need an OpenTelemetry-aware collector on the runner side, or a job step that reads the variables and emits its own span, before anything shows up in your tracing backend. GitLab exposes the context; the plumbing between the CI job and the trace store is on you.&lt;/p&gt;

&lt;p&gt;The merge-train limits ship as a per-project setting, per the post. That helps a team owning one monorepo; it does not help a platform team that wants one cap across a hundred projects. Watch for whether an instance-wide equivalent follows.&lt;/p&gt;

&lt;p&gt;Co-Create itself was credited with more than 650 contributors and 4,874 product improvements across more than 100 product groups in H1 2026. The number to hold onto is the smaller one: three CI/CD changes that will change what your pipeline can do next Monday.&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>cicd</category>
      <category>tracing</category>
      <category>mergetrains</category>
    </item>
    <item>
      <title>Kubernetes 1.37 promotes gang scheduling to a first-class Workload API in beta</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sat, 12 Sep 2026 16:26:35 +0000</pubDate>
      <link>https://dev.to/leobaniak/kubernetes-137-promotes-gang-scheduling-to-a-first-class-workload-api-in-beta-2a8b</link>
      <guid>https://dev.to/leobaniak/kubernetes-137-promotes-gang-scheduling-to-a-first-class-workload-api-in-beta-2a8b</guid>
      <description>&lt;p&gt;Kubernetes 1.37 promotes three pieces of the Workload-Aware Scheduling (WAS) effort to beta, giving batch and ML pipelines a native, all-or-nothing scheduling primitive that until now lived in third-party operators. Per the release blog, the Workload and PodGroup APIs, Workload-Aware Preemption (WAP), and shared Dynamic Resource Allocation (DRA) ResourceClaims for PodGroups all graduate together.&lt;/p&gt;

&lt;p&gt;Gang scheduling itself is not new. Volcano, YuniKorn and Kueue have carried the pattern in operator form for years, each with its own PodGroup shape and its own answers on preemption and quota. The v1.37 beta is the same idea standardised into an API surface that the in-tree scheduler and the built-in Job controller can consume directly, without an out-of-tree scheduler plugin in the loop.&lt;/p&gt;

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

&lt;p&gt;Three things move from alpha to beta together, per the Kubernetes post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Workload and PodGroup APIs, the objects that let the scheduler treat a set of pods as a unit and refuse to place any of them unless all of them can be placed.&lt;/li&gt;
&lt;li&gt;Workload-Aware Preemption, the eviction logic that respects those grouping semantics instead of pulling one pod out of a gang and stranding the rest.&lt;/li&gt;
&lt;li&gt;Shared DRA ResourceClaims for PodGroups, so a group of pods that needs one GPU allocation or one network-fabric slice can share the claim rather than each pod holding its own.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Job controller is updated in the same release to consume the expanded APIs. That is the piece that matters for anyone who already runs batch or distributed training as Jobs. The blog lists advanced scheduling policies, more flexible disruption modes, and topology-aware placement as the new Job-level surface.&lt;/p&gt;

&lt;p&gt;Two enablers ship alongside. A &lt;code&gt;workloadbuilder&lt;/code&gt; Go library and a set of controller-integration APIs aim at operator authors who want to plug their own controllers into WAS without reimplementing the primitives from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where a platform team feels it
&lt;/h2&gt;

&lt;p&gt;Anywhere a pipeline schedules a distributed training run, a Spark job, or a large parallelised test matrix onto a shared cluster. The failure mode WAS is targeting is the one platform teams have been papering over with quotas and priority classes: half a training job's pods land, the other half wait behind a preemption, and the scheduled half sits burning GPU hours while the workload cannot actually start. All-or-nothing scheduling lines the accounting up with what the job needed.&lt;/p&gt;

&lt;p&gt;A related win is preemption you can reason about in a runbook. Under classic priority-based preemption, evicting one pod of a training gang effectively stalled the whole gang until the missing pod was rescheduled. WAP evicts at the workload boundary. Easier to explain to a data-science team asking why their run died, easier to page on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The alpha piece to note but not depend on
&lt;/h2&gt;

&lt;p&gt;Landing in alpha next to the beta graduations is a CompositePodGroup API, which layers multi-level topology constraints onto the PodGroup shape. The blog frames it around hierarchical workloads such as JobSet and LeaderWorkerSet, where a single logical training run is a group of groups: leaders, followers, and a specific placement relationship between them.&lt;/p&gt;

&lt;p&gt;Alpha means feature-gated off by default. Do not build a production dependency on CompositePodGroup during the 1.37 cycle. The shape may shift before beta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adoption and rollback
&lt;/h2&gt;

&lt;p&gt;The three beta pieces are enabled by default on upgrade. If a platform team runs a rule of "GA only in production", that rule still keeps WAS out until a later release. If the rule is "beta and above", the operational question is what your existing batch stack does when the built-in scheduler starts honouring PodGroup objects it did not previously understand. Volcano, Kueue and their peers each need their own audit against the native semantics before you flip a workload from operator-managed to controller-native, and the audit is the part that will surprise you if you skip it.&lt;/p&gt;

&lt;p&gt;Rolling back is a feature-gate disable on kube-apiserver, kube-controller-manager and the scheduler, followed by a restart. There is no data migration to unwind: a Workload object is CRD-shaped, and an older scheduler ignores it. Walk that path on a staging cluster before the upgrade, not after a bad preemption at 3am.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>scheduling</category>
      <category>batch</category>
      <category>aiml</category>
    </item>
    <item>
      <title>Safari Technology Preview 252 adds @supports named-feature(), unprefixed user-select and two accessible-name fixes</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sat, 12 Sep 2026 16:08:09 +0000</pubDate>
      <link>https://dev.to/leobaniak/safari-technology-preview-252-adds-supports-named-feature-unprefixed-user-select-and-two-50d5</link>
      <guid>https://dev.to/leobaniak/safari-technology-preview-252-adds-supports-named-feature-unprefixed-user-select-and-two-50d5</guid>
      <description>&lt;p&gt;I wired up the small pieces of this release before writing anything, and the ones I wanted most were the two I could not fake before. Named-feature() as a test, and a way to read a rule's own condition back off the OM. Not a headliner drop, but it clears a couple of stubborn corners.&lt;/p&gt;

&lt;p&gt;Safari Technology Preview 252 was published 11 September 2026 by Jon Davis and pulls in WebKit changes between 319252@main and &lt;a href="mailto:320112@main"&gt;320112@main&lt;/a&gt;. Preview channel, one engine, no Baseline claim on any of this.&lt;/p&gt;

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

&lt;p&gt;Five items, all small, all hand-authorable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@supports named-feature(...)&lt;/code&gt; now parses. A test aimed at behaviours that were previously undetectable — the ones a property/value probe or a &lt;code&gt;selector()&lt;/code&gt; body could not reach.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CSSConditionRule.supports&lt;/code&gt; and &lt;code&gt;CSSMediaRule.matches&lt;/code&gt; are exposed to the CSSOM.&lt;/li&gt;
&lt;li&gt;The unprefixed &lt;code&gt;user-select&lt;/code&gt; property is supported.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;text-decoration-inset&lt;/code&gt; now accepts percentage values.&lt;/li&gt;
&lt;li&gt;Two accessible-name fixes. A &lt;code&gt;display: contents&lt;/code&gt; element no longer includes text from its siblings in its accessible name. And list marker text no longer leaks into accessible names or values that requested the text without markers.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Named-feature() is the one to prototype under a &lt;code&gt;@supports&lt;/code&gt; block. It's the escape hatch we haven't had — where a property/value pair or a &lt;code&gt;selector()&lt;/code&gt; test can't answer whether a behaviour is on. Cross-engine landing is the next signal to watch. The two accessible-name fixes are the ones I'll re-run screen-reader spot checks against, because those are the kind of quiet correctness change that only shows up when you go looking.&lt;/p&gt;

</description>
      <category>safari</category>
      <category>webkit</category>
      <category>stp</category>
      <category>css</category>
    </item>
    <item>
      <title>Kubernetes 1.37 turns native histograms on by default for its own metrics</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sat, 12 Sep 2026 08:24:38 +0000</pubDate>
      <link>https://dev.to/leobaniak/kubernetes-137-turns-native-histograms-on-by-default-for-its-own-metrics-1jmn</link>
      <guid>https://dev.to/leobaniak/kubernetes-137-turns-native-histograms-on-by-default-for-its-own-metrics-1jmn</guid>
      <description>&lt;p&gt;Kubernetes 1.37 flips native histograms on by default for its own metrics, per the release blog. It is a beta graduation of the change that landed in 1.36 alpha under KEP-5808, and it targets one specific pain: the shape of the duration data the control plane exposes to Prometheus.&lt;/p&gt;

&lt;p&gt;Enabled by default means most clusters upgrading to 1.37 will start emitting the newer format without an opt-in flag. Whether your monitoring stack ingests it is a separate question.&lt;/p&gt;

&lt;h2&gt;
  
  
  Classic histograms, briefly
&lt;/h2&gt;

&lt;p&gt;A classic Prometheus histogram exports one time series per bucket boundary. A ten-bucket histogram with a handful of labels quietly turns into dozens of series, and the TSDB pays for every one of them. Get the boundaries wrong at design time and the data is quietly useless: latency that shifts into microseconds, or blows past the top bucket, vanishes into +Inf, and any &lt;code&gt;histogram_quantile&lt;/code&gt; call over coarse buckets interpolates its way to a plausible-looking wrong answer. The Kubernetes blog names all three of these: the bucket guessing game, cardinality cost, and interpolation error.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ships in 1.37
&lt;/h2&gt;

&lt;p&gt;Native histograms replace the fixed-bucket exposition with dynamically-sized buckets driven by the observed distribution. The blog cites duration and latency metrics as the target, calling out API server request latencies and scheduling durations. The KEP has been baking since 1.36; the beta step means enabled by default, still tunable through the standard feature-gate machinery if you need to back it out.&lt;/p&gt;

&lt;p&gt;The release calls the result high-resolution, low-cardinality observability, with a meaningful drop in telemetry storage and scraping overhead. That is the design goal restated, and the mechanism plausibly delivers it. Nothing in the release notes says otherwise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where a CI/CD team feels it
&lt;/h2&gt;

&lt;p&gt;Anywhere a pipeline reads control-plane latency percentiles to gate a step. If your progressive-delivery job queries API server request-duration percentiles to decide "cluster is healthy, promote the canary," the shape of the data behind that query is different in 1.37. Higher-resolution percentiles are the upside. The downside is that any alert threshold calibrated against interpolated numbers from classic buckets may fire at slightly different times, or stop firing, once the histogram gets more honest about what actually happened.&lt;/p&gt;

&lt;p&gt;Same story for the internal SLO dashboards that platform teams point at their clusters. The number you looked at last week and the number you look at next week are computed by different code paths, even if the label set on the graph is identical.&lt;/p&gt;

&lt;h2&gt;
  
  
  The scrape side is the catch
&lt;/h2&gt;

&lt;p&gt;Native histograms are a Prometheus feature. Your scrape stack has to understand them to store them. If you run an older Prometheus, an ingester that only speaks classic exposition, or a hosted metrics vendor that has not shipped native-histogram support yet, the new series can be dropped or downgraded to the classic representation on the wire, and the storage and quantile benefits go with them. The Kubernetes post does not enumerate a minimum stack; check your ingester's own release notes before you count the win. OpenTelemetry's exponential histogram is a sibling design solving the same problem from a different direction, so if your pipeline already routes through an OTel collector there is a translation step to think through as well.&lt;/p&gt;

&lt;p&gt;Second catch: it is beta. Beta in Kubernetes has meant "enabled by default and generally reliable" for a while now, but it is still not GA. If the platform team has a rule about only running GA features on production clusters, native histograms sit on the wrong side of that line until a later release lifts them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rollback path
&lt;/h2&gt;

&lt;p&gt;Standard feature-gate disable across the API server, controller manager and scheduler, followed by a restart. That is the operational read: nothing you have not done before, no data migration to unwind, dashboards revert to their previous shape the moment the classic exposition comes back. Worth walking through on a lab cluster before the upgrade, not during it.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>observability</category>
      <category>prometheus</category>
      <category>metrics</category>
    </item>
    <item>
      <title>interactive-widget lands in WebKit: three ways to react when the keyboard opens</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sat, 12 Sep 2026 04:08:51 +0000</pubDate>
      <link>https://dev.to/leobaniak/interactive-widget-lands-in-webkit-three-ways-to-react-when-the-keyboard-opens-2di2</link>
      <guid>https://dev.to/leobaniak/interactive-widget-lands-in-webkit-three-ways-to-react-when-the-keyboard-opens-2di2</guid>
      <description>&lt;p&gt;You built a chat UI. Sticky composer at the bottom, &lt;code&gt;position: fixed&lt;/code&gt;. On a phone the user taps the input, the on-screen keyboard slides up, and your composer sits under it. Or it does not. Or it does on one browser and not the other, and the layout viewport is a different height than it was two seconds ago, and half your app has scrolled itself into a corner. That behaviour, which used to be the browser's business alone, now has a knob. WebKit just wired it up.&lt;/p&gt;

&lt;h2&gt;
  
  
  The knob, and where it lives
&lt;/h2&gt;

&lt;p&gt;The directive is &lt;code&gt;interactive-widget&lt;/code&gt;, and it goes inside the same viewport meta tag you already have in every mobile page. Bramus confirmed the WebKit implementation on his blog and shows the exact shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt;
      &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0, interactive-widget=resizes-content"&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;Three values are defined. Each one answers the same question a different way: when a virtual keyboard (or any similar interactive UA widget) opens, which viewport should react?&lt;/p&gt;

&lt;h2&gt;
  
  
  Two viewports, one keyboard
&lt;/h2&gt;

&lt;p&gt;Fast refresher, because the values only make sense against it. A mobile browser tracks two viewports on the same page. The &lt;strong&gt;layout viewport&lt;/strong&gt; is what CSS resolves against, the box &lt;code&gt;100vh&lt;/code&gt; and your fixed elements pin themselves to. The &lt;strong&gt;visual viewport&lt;/strong&gt; is the currently visible slice of that layout, which can shrink when the user pinch-zooms or when browser chrome eats into it. Historically the keyboard could shrink either, both, or neither, and the choice was the browser's.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;interactive-widget&lt;/code&gt; moves that choice into the meta tag:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;resizes-visual&lt;/code&gt; is the default. Only the visual viewport gets smaller. Your layout stays the same size; the keyboard just crops what the user can see of it. Fixed elements do not move.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;resizes-content&lt;/code&gt; shrinks both viewports. The layout viewport becomes shorter for as long as the keyboard is up. &lt;code&gt;100vh&lt;/code&gt; reports the new, shorter height. Fixed elements reflow against it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;overlays-content&lt;/code&gt; shrinks neither. The keyboard is drawn on top of the page and the layout is left alone, similar to what the Virtual Keyboard API's &lt;code&gt;overlaysContent = true&lt;/code&gt; gives you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The default matches what Safari has always done and what Chromium switched to in Chrome 108, back in 2022, when the two engines aligned on "keyboard shrinks only the visual viewport" as the baseline. What is new is that a page can now opt out of the default in either direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Picking a value for a real layout
&lt;/h2&gt;

&lt;p&gt;Think in mechanism, not vibes. The value you want is the one that keeps your positioning math honest while the keyboard is on screen.&lt;/p&gt;

&lt;p&gt;If your UI is a normal document, an article, a form, a settings page, leave the default. &lt;code&gt;resizes-visual&lt;/code&gt; means your CSS heights do not twitch, the user scrolls the field into view, and life carries on. Changing it here would break more than it fixes.&lt;/p&gt;

&lt;p&gt;If your UI is a full-height app shell with a bottom-pinned toolbar (chat composer, note editor, camera controls), you probably want &lt;code&gt;resizes-content&lt;/code&gt;. The layout viewport becomes shorter, &lt;code&gt;100vh&lt;/code&gt; reports the smaller height, and the toolbar you pinned to &lt;code&gt;bottom: 0&lt;/code&gt; sits above the keyboard instead of behind it. No JavaScript required, no manual measurement of the keyboard height, no listening for &lt;code&gt;visualViewport.resize&lt;/code&gt;. You give up some layout stability, because a keyboard toggle now triggers a real reflow. That is the price for the layout you asked for.&lt;/p&gt;

&lt;p&gt;If you are drawing your own chrome and want the keyboard to feel like a floating panel on top of the app, &lt;code&gt;overlays-content&lt;/code&gt; is the honest answer. Nothing reflows; you take responsibility for whatever the keyboard is now covering, exactly as you would with the Virtual Keyboard API in overlay mode.&lt;/p&gt;

&lt;p&gt;Three values, one line of HTML, and the layout algorithm follows.&lt;/p&gt;

&lt;h2&gt;
  
  
  The support caveat you should not skip
&lt;/h2&gt;

&lt;p&gt;Two things to know before you ship it.&lt;/p&gt;

&lt;p&gt;First, "WebKit implemented it" is not the same sentence as "Safari shipped it". Bramus makes the distinction explicit and says it is not yet confirmed whether the WebKit implementation will actually land in Safari. WebKit is the engine; Safari is one of the browsers that ships that engine, and features can sit in WebKit for a while before a Safari release picks them up. To try it today he had to build WebKit locally and run it in the MobileMiniBrowser shell on the iPhone Simulator, which is not a workflow you hand to users.&lt;/p&gt;

&lt;p&gt;Second, since this is a viewport meta directive, an engine that has not implemented it will simply ignore the token and fall back to its own default behaviour. That is fine. You can add &lt;code&gt;interactive-widget=resizes-content&lt;/code&gt; to your app shell today and it will do nothing on browsers that do not know the value yet, and start doing the right thing on the ones that do. Progressive enhancement, in the most literal sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this leaves mobile layout craft
&lt;/h2&gt;

&lt;p&gt;The Virtual Keyboard API has been the JavaScript answer to this problem for a while, and it is still the right tool when you want to know the keyboard's pixel height and lay out around it. What &lt;code&gt;interactive-widget&lt;/code&gt; gives you is the declarative, HTML-only version: one directive in the tag you already ship, no scripts, no measurements. The two overlap on the &lt;code&gt;overlays-content&lt;/code&gt; case and diverge everywhere else.&lt;/p&gt;

&lt;p&gt;The interesting part is what a second engine picking this up does to the shape of the problem. A keyboard-aware layout has always meant either trusting the browser or measuring with JS and crossing your fingers. A meta directive that both major engines respect turns the question into a design choice that lives next to your other viewport tokens. Now the work is picking which value your app actually wants, and watching whether Safari itself picks up the WebKit change.&lt;/p&gt;

</description>
      <category>html</category>
      <category>viewport</category>
      <category>metaviewport</category>
      <category>webkit</category>
    </item>
    <item>
      <title>When your pipeline is fast and your product still isn't</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Sat, 12 Sep 2026 00:25:23 +0000</pubDate>
      <link>https://dev.to/leobaniak/when-your-pipeline-is-fast-and-your-product-still-isnt-130i</link>
      <guid>https://dev.to/leobaniak/when-your-pipeline-is-fast-and-your-product-still-isnt-130i</guid>
      <description>&lt;p&gt;The last time I tuned a CI pipeline from twelve minutes down to five, I felt like I'd earned my paycheck for the quarter. Then a PM told me that the feature we were racing to ship had been in prioritization discussions since April. It was August. My five minutes suddenly felt smaller.&lt;/p&gt;

&lt;p&gt;I thought about that conversation while reading Brad Nelson's piece on DevOps.com, "DevOps' Three Ways Were Never About Tooling." Nelson, who wrote "I Think, Therefore I Know: Scientific Thinking for Unscientific Organizations" and co-hosts The Agile for Agilists podcast, has a blunt argument. The community that reads a site like this one (and yes, I mean us) has been reducing DevOps maturity to a CI/CD scoreboard, and he thinks we are grading the wrong test.&lt;/p&gt;

&lt;h2&gt;
  
  
  The argument, in his words
&lt;/h2&gt;

&lt;p&gt;Nelson walks through the original DevOps canon: Flow, Feedback, and Continual Learning. His claim is that each was written to apply to the whole system that turns an idea into revenue, and each has been quietly narrowed to the slice an engineer can see from their laptop.&lt;/p&gt;

&lt;p&gt;On Flow, he asks a question I have been unable to shake: "what does the movement of value look like from aha to ka-ching?" His example, borrowed from Mik Kersten's "Project to Product," is a Nationwide analysis showing that only 2.5 percent of a 120-day end-to-end flow lived in development. If that number is anywhere near right for your org, adding engineers to speed up code is optimizing the least of it.&lt;/p&gt;

&lt;p&gt;On Feedback, Nelson is stricter than most CI/CD writing I read. Value can only be judged by the customer, he argues, so an internal loop, however fast, is not the loop that matters. He cites the familiar research (Pendo, Standish Group, Microsoft, Google) that around 80 percent of shipped features are rarely or never used. Fast delivery of the wrong thing is a more efficient way to be wrong.&lt;/p&gt;

&lt;p&gt;On Continual Learning, his framing is that feedback without a behavior change is a report, not learning. Every roadmap, he writes, is a stack of hypotheses until a user gets near it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the DX crowd should sit with this
&lt;/h2&gt;

&lt;p&gt;I want to defend our patch of ground for a moment. Faster pipelines are a component of Flow, not a distraction from it, and it is much easier to measure a build queue than a boardroom. But Nelson is landing a fair blow. Every deploy-frequency chart I have ever presented has treated "deploy" as the finish line. The customer meeting the change is the actual finish line. Deploy is a checkpoint on the way there.&lt;/p&gt;

&lt;p&gt;Where I would push back a little: the CI/CD scoreboard is not only vanity. When my team's median PR-to-main dropped under an hour, product started proposing smaller experiments, because the cost of trying one had collapsed. Fast pipelines change what leadership dares to attempt. That is Flow too, even if it is downstream of the interesting decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The verdict I'm sitting with
&lt;/h2&gt;

&lt;p&gt;Nelson does not hand you a Monday morning to-do list, and I think that is honest, because the answer depends entirely on where your 120 days actually live. If most of your lead time is in a build queue or a flaky test suite, keep tuning. You will feel the difference on your next PR. If most of it is in a prioritization meeting that reconvenes every two weeks, no runner upgrade will save you. It is a product problem wearing a pipeline costume.&lt;/p&gt;

&lt;p&gt;What I am watching next: whether the platform-engineering movement, which has spent a couple of years building golden paths for engineers, starts building the equivalent for the product-decision loop. That is the part of the pipeline no one has a Grafana dashboard for yet, and it is the part Nelson is asking us to look at.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>culture</category>
      <category>flow</category>
      <category>feedback</category>
    </item>
    <item>
      <title>GitLab's critical patch: unauth file read from the commits API</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Fri, 11 Sep 2026 16:26:11 +0000</pubDate>
      <link>https://dev.to/leobaniak/gitlabs-critical-patch-unauth-file-read-from-the-commits-api-5358</link>
      <guid>https://dev.to/leobaniak/gitlabs-critical-patch-unauth-file-read-from-the-commits-api-5358</guid>
      <description>&lt;p&gt;Every CI system is a trust hierarchy pretending to be a build tool. Somewhere at the bottom of that hierarchy, someone put an authentication check that assumed the caller had already been checked. This week that assumption cost GitLab a Critical.&lt;/p&gt;

&lt;p&gt;GitLab shipped patch releases 19.3.2, 19.2.6, and 19.1.8 on September 10, per the release note. Eighteen CVEs across Community Edition and Enterprise Edition, two of them Critical, six High, nine Medium, one Low. The self-managed guidance is the usual: upgrade immediately. GitLab.com is already running the patched version. GitLab Dedicated customers do not need to take action.&lt;/p&gt;

&lt;p&gt;You do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one to open first
&lt;/h2&gt;

&lt;p&gt;CVE-2026-85706 is the top of the read. Per the advisory: "an unauthenticated user could have read arbitrary files from the GitLab server due to improper path confinement and missing authentication enforcement in the repository commits API." Unauthenticated. Arbitrary files. From the commits API. Three phrases you never want in the same sentence.&lt;/p&gt;

&lt;p&gt;For self-managed the affected range is CE and EE 18.7 through 19.3, and the fix landed only in 19.1.8, 19.2.6 and 19.3.2. If your platform team has been letting patch windows slip because "we're on the latest minor", check whether "latest minor" means 19.3.0 or 19.3.2. There is a difference now, and it is public.&lt;/p&gt;

&lt;p&gt;The second Critical, CVE-2026-87719, has a smaller blast radius but a sharper one for anyone running Duo Chat. The advisory: "an authenticated user with Duo Chat access to obtain Advanced Search instance configurations and sensitive credentials using a specially crafted GraphQL subscription argument." Sensitive credentials. From a chat surface. Through a GraphQL subscription. If your assistant integration was already the part of the deployment nobody quite audited, congratulations: it is now the part nobody quite audited that also leaks configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the CI owner should actually rotate
&lt;/h2&gt;

&lt;p&gt;Past the two Criticals, CVE-2026-88765 (High) is next on the pile: "an authenticated user to achieve remote code execution by importing a specially crafted Git project export to overflow the Unicode conversion buffer." Project import is exactly the surface a Developer-role account is expected to touch. Now it is also a Unicode-buffer overflow away from RCE on the instance that owns your pipelines.&lt;/p&gt;

&lt;p&gt;Then CVE-2026-79708, also High: "a developer user to execute a policy test pipeline on projects within their group and access protected CI/CD variables." Protected CI/CD variables are the ones you told your compliance reviewer would only be reachable by protected branches on production jobs. A developer with policy-test-pipeline access can now reach them from a test path.&lt;/p&gt;

&lt;p&gt;Rotate the ones that live on affected instances. All of them, if that answer is faster than the audit.&lt;/p&gt;

&lt;h2&gt;
  
  
  The upgrade itself is the second incident
&lt;/h2&gt;

&lt;p&gt;Here is the part the release note says out loud, and the part worth rereading before scheduling the window: "This patch will cause downtime during the upgrade as migrations must complete before GitLab can start." That applies to single-node installs. Multi-node instances "with proper zero-downtime upgrade procedures" can apply the patch without downtime, per the same note. Which is to say: if you have not rehearsed the zero-downtime playbook, you are going to take the outage.&lt;/p&gt;

&lt;p&gt;A Critical unauthenticated file read is not a defer-until-next-Tuesday event. A migration-heavy patch is not a "run it in prod first" event. Those two facts collide, and the collision is where CI teams lose weekends.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verdict
&lt;/h2&gt;

&lt;p&gt;GitLab did the right thing here on the release-note side: a coordinated cut across three supported minor lines, per-CVE descriptions instead of a vague "security fixes" blurb, explicit deployment guidance for both the SaaS side and self-managed operators. That is the version of security shipping we want.&lt;/p&gt;

&lt;p&gt;It is also, as ever, only half of the transaction. The other half is you, on a Wednesday night, dragging a self-managed 19.2.x instance forward while your on-call engineer keeps refreshing the pipelines page.&lt;/p&gt;

&lt;p&gt;Signed advisories are cheap. Applying them is not.&lt;/p&gt;

&lt;p&gt;Rotate the CI/CD variables. Then upgrade.&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>security</category>
      <category>cve</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Kubernetes v1.37 stops your in-place Pod resize from stalling on a full node</title>
      <dc:creator>Leo</dc:creator>
      <pubDate>Fri, 11 Sep 2026 08:25:49 +0000</pubDate>
      <link>https://dev.to/leobaniak/kubernetes-v137-stops-your-in-place-pod-resize-from-stalling-on-a-full-node-4idd</link>
      <guid>https://dev.to/leobaniak/kubernetes-v137-stops-your-in-place-pod-resize-from-stalling-on-a-full-node-4idd</guid>
      <description>&lt;p&gt;The first time in-place Pod resize saved me a restart on a real service, I sat and stared at the terminal for a beat too long. Our stateful container was quietly walking its CPU request up by a full core, no eviction, no rollout, no 3am page. A week later a different Pod on a heavily bin-packed node tried the same trick and the resize just parked itself. Deferred. Waiting. That second experience is the whole reason I care about what landed in Kubernetes v1.37.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gap in-place resize left behind
&lt;/h2&gt;

&lt;p&gt;In-place Pod resize graduated to GA back in v1.35. It lets you edit the resource requests on a live container and have the kubelet apply the change without a restart, which is a genuinely different feeling on-call than every previous vertical-scaling story Kubernetes has shipped. The catch: if the node does not have enough allocatable headroom, the kubelet writes a &lt;code&gt;Deferred&lt;/code&gt; value into the container's &lt;code&gt;resizeStatus&lt;/code&gt; and the request sits there until capacity naturally frees up.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Deferred&lt;/code&gt; is not the same as &lt;code&gt;Infeasible&lt;/code&gt;. Infeasible means the request outright exceeds the physical machine, a LimitRange, or a quota, and the kubelet rejects it immediately. Deferred means the request is valid, the kubelet just does not have the room right now. Before v1.37, "right now" could stretch to "indefinitely", because the kube-scheduler was not watching running Pods for pending resizes and would not preempt anything to make space for one.&lt;/p&gt;

&lt;p&gt;Kubernetes v1.37 introduces, in alpha, scheduler preemption for in-place Pod resize, guarded by a new feature gate named &lt;code&gt;InPlacePodVerticalScalingSchedulerPreemption&lt;/code&gt;. Turn it on and the kube-scheduler will actively evict lower-priority Pods on the same node so a higher-priority Pod's Deferred resize can finally succeed.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the scheduler picks up a running Pod
&lt;/h2&gt;

&lt;p&gt;Normally, once a Pod has &lt;code&gt;spec.nodeName&lt;/code&gt; set, the scheduler considers it placed and stops looking at it. Under the new gate, the scheduler keeps watching Pods carrying the Deferred condition and pulls them back into active scheduling evaluations, specifically so they can trigger preemption. It holds onto them until the kubelet reports the resize actuated.&lt;/p&gt;

&lt;p&gt;A few design choices are worth knowing before you flip the gate on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Preemption is single-node.&lt;/strong&gt; Placement preemption evaluates every node in the cluster to find the best fit; resize preemption is scoped strictly to the Pod's current node. If evicting every eligible lower-priority workload on that node still does not free enough capacity, the resize stays Deferred.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The scheduler owns all resize preemption.&lt;/strong&gt; The kubelet has an existing critical-Pod admission handler that can evict locally at admission time, but under this gate that handler stays out of resize decisions. Every eviction runs through the scheduler, so global priority ordering, PodDisruptionBudgets, and graceful termination are respected the same way you already trust them for placement preemption.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reserved capacity, not a race.&lt;/strong&gt; The scheduler treats the requested delta as consumed the moment preemption starts, so a second scheduling loop cannot double-book the same CPU. If a higher-priority resize on the same node lands mid-preemption, the kubelet gives it precedence and the scheduler kicks off a new round.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Turning it off where you do not want it
&lt;/h2&gt;

&lt;p&gt;If you already run a controller that would rather size other Pods down or grow the node itself before anyone gets evicted, this behaviour is going to feel intrusive. v1.37 adds a &lt;code&gt;spec.podPreemptionPolicy&lt;/code&gt; field on the Node, with a &lt;code&gt;disableResizePreemption&lt;/code&gt; list of controller names that opts that node out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Node&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;node-name&amp;gt;&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;podPreemptionPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;disableResizePreemption&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cluster-autoscaler.kubernetes.io/disable-preemption"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;operator.example.com/policy-override"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Batch-only nodes, or nodes a custom autoscaler wants to own, can flag themselves and keep the scheduler off the eviction path there. Preemption becomes the last-resort tool the doc calls it, not the default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying it locally
&lt;/h2&gt;

&lt;p&gt;The feature gate must be enabled on the kube-apiserver, the kube-scheduler, and the kubelet, and every node has to be on v1.37 or later. The upstream announcement walks through a single-node kind setup that is the fastest way to internalise what the new controller loop actually does: constrain the node's CPU, deploy a low-priority Pod and a high-priority Pod that together nearly fill it, then patch the high-priority Pod's CPU request past the remaining headroom and watch preemption clear the room. Run that once before you argue for it on a real cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rough edges
&lt;/h2&gt;

&lt;p&gt;It is alpha, so the API shape is not promised across releases. The single-node scope carries a real limit: a resize that needs more room than the entire node can offer, even after evicting every eligible lower-priority Pod, will still park in Deferred. Cases like a memory-hungry VPA target on a small node are still a job for the cluster autoscaler, not for this. And every platform team I have talked to about this has the same fair worry: preemption acting on running Pods, even lower-priority ones, is a behaviour change your batch-job owners deserve a heads-up about before you enable the gate under them.&lt;/p&gt;

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

&lt;p&gt;Two things. First, whether this graduates at the same cadence core in-place resize did, alpha to GA over a few releases. Second, whether Vertical Pod Autoscaler starts to treat a Deferred status as a first-class recoverable state now that there is finally a story for unsticking one. If both happen, the "no restart, no re-schedule" promise of in-place resize gets a lot closer to the default experience for a lot more workloads, and the next time one of your services quietly walks its CPU up on a full node, you will not have to notice.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>scheduling</category>
      <category>alpha</category>
      <category>resize</category>
    </item>
  </channel>
</rss>
