<?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: Steve Fenton</title>
    <description>The latest articles on DEV Community by Steve Fenton (@_steve_fenton_).</description>
    <link>https://dev.to/_steve_fenton_</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%2F2913455%2F532f94ec-d896-44e0-ab98-a1cae91a8278.jpg</url>
      <title>DEV Community: Steve Fenton</title>
      <link>https://dev.to/_steve_fenton_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_steve_fenton_"/>
    <language>en</language>
    <item>
      <title>Continuous Delivery Office Hours Ep.3: Branching strategies</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Mon, 15 Jun 2026 12:09:50 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/continuous-delivery-office-hours-ep3-branching-strategies-4d8k</link>
      <guid>https://dev.to/_steve_fenton_/continuous-delivery-office-hours-ep3-branching-strategies-4d8k</guid>
      <description>&lt;p&gt;Your branching strategy can support Continuous Delivery, or make it an impossible goal. You should assess the impact of how you branch on your ability to deliver software at all times, and you'll find some branching techniques that work, while others that make software delivery more like walking in the dark through a field of rakes.&lt;/p&gt;

&lt;p&gt;Continuous Integration is the practice of integrating code changes frequently, typically multiple times a day. This means you should check your code multiple times a day and keep your main branch deployable. Continuous Integration is a prerequisite for Continuous Delivery.&lt;/p&gt;

&lt;p&gt;The name "Continuous Integration" provides solid hints about the crucial parts of the practice. Everyone should &lt;em&gt;integrate&lt;/em&gt; their code into a shared branch (feature branches don't count) and this should be done &lt;em&gt;continuously&lt;/em&gt;, which means you're doing it all the time; at least once a day, but ideally more often.&lt;/p&gt;

&lt;p&gt;You'll often speak to developers who want to stretch the definition of Continuous Integration, but you can't escape those foundations. Merging the main branch into a long-lived branch feels like Continuous Integration, but you'll notice no changes come back for ages until someone finally merges to main. Then you have to perform a large, complex merge, which you should avoid.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://dora.dev/capabilities/continuous-delivery/" rel="noopener noreferrer"&gt;DORA research on Continuous Delivery&lt;/a&gt; includes the capabilities of Continuous Integration and trunk-based development. The statistics suggest you can get similar benefits as long as you limit yourself to 3 (or fewer) short-lived branches (less than a day old).&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch the episode
&lt;/h2&gt;

&lt;p&gt;You can watch the episode below, or read on to find some of the key discussion points.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=WDHZAHGxpR8" rel="noopener noreferrer"&gt;Watch Continuous Delivery Office Hours Ep.3&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The worst branching strategy
&lt;/h2&gt;

&lt;p&gt;Since the ability to branch code was invented, developers have applied a great deal of creativity to how to use branches. The most common approach is feature branching, where each feature gets a branch of main that evolves separately until the feature is complete, and it's merged back into main. Release branching allows development to continue on main by taking a cut of the main branch that will be released. This allows hotfixes to be applied to the release branch without further destabilizing it.&lt;/p&gt;

&lt;p&gt;The utility of branching strategies is often eroded by the coordination overhead of maintaining the separate branches and merging different changes back together. The more complex the branching strategy, the more likely it is that you'll have merge conflicts and lost bug fixes. For example, you might fix a release branch and forget to merge the fix back to main, so the next release reintroduces the bug.&lt;/p&gt;

&lt;p&gt;This is why the worst branching strategy is Gitflow. This is a complicated branching strategy that creates dedicated branches for features, releases, and hotfixes alongside permanent main and develop branches. The overhead of Gitflow vastly outweighs its benefits.&lt;/p&gt;

&lt;p&gt;This is where trunk-based development shines, as it removes unnecessary complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  The best strategy is trunk-based development
&lt;/h2&gt;

&lt;p&gt;Trunk-based development is the process of making all commits directly to the main branch. This is complemented by out-of-band reviews that don't block merging and by feature toggles that decouple deployments from releases. It should be possible to deploy your software from the main branch at all times, even if features aren't complete.&lt;/p&gt;

&lt;p&gt;The DORA research allows up to 3 short-lived branches, which can be useful for teams working remotely (like open-source project teams), who can use branches and pull requests to coordinate their work. Even so, the goal is to keep branches short-lived and to merge frequently.&lt;/p&gt;

&lt;p&gt;Trunk-based development is complemented by automated builds and checks that run when code is committed to the main branch. If a problem is found during these checks, the team should prioritize the fix over other development work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Elite performance comes from small batches
&lt;/h2&gt;

&lt;p&gt;Teams with the best software delivery performance work in small steps. Trunk-based development and Continuous Integration are crucial practices for controlling batch size. Problems are discovered sooner and are easier to fix when you only have a small amount of change to reason about.&lt;/p&gt;

&lt;p&gt;Making frequent commits makes it easy to back out a bad change. If a test fails, you can discard changes since the last commit and try again, instead of trying to debug the problem. This is especially true when using AI coding assistants or other code generation techniques.&lt;/p&gt;

&lt;p&gt;Ultimately, for trunk-based development to succeed without friction, the entire team must be aligned on the process. It doesn't work if only some of the team are on board.&lt;/p&gt;




&lt;p&gt;Continuous Delivery Office Hours is a series of conversations about software delivery, with Tony Kelly, Bob Walker, and Steve Fenton.&lt;/p&gt;

&lt;p&gt;You can find more episodes on &lt;a href="https://www.youtube.com/playlist?list=PLAGskdGvlaw3CrxkUOAMmiy928lr5D4oh" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;, &lt;a href="https://podcasts.apple.com/us/podcast/continuous-delivery-office-hours/id1872101651" rel="noopener noreferrer"&gt;Apple Podcasts&lt;/a&gt;, and &lt;a href="https://pca.st/hwjaox59" rel="noopener noreferrer"&gt;Pocket Casts&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>software</category>
      <category>git</category>
    </item>
    <item>
      <title>Gravity Applies To Robots</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Thu, 11 Jun 2026 06:57:04 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/gravity-applies-to-robots-40l7</link>
      <guid>https://dev.to/_steve_fenton_/gravity-applies-to-robots-40l7</guid>
      <description>&lt;p&gt;Or, why AI systems fail in surprisingly familiar ways.&lt;/p&gt;

&lt;p&gt;With the introduction of AI-assisted coding tools and agents, many people were hoping we’d solve all the problems of human teams. Without the people, politics, and personalities software delivery would be easy.&lt;/p&gt;

&lt;p&gt;This vision is appealing because we’ve long blamed people for the failures in the system. But the evidence from multi-agent AI provides an awkward truth. The same classes of failure still happen in the same places, for reasons that have nothing to do with humanity.&lt;/p&gt;

&lt;p&gt;So, why do large batches of work still fail once you’ve eliminated laziness and stupidity?&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Village
&lt;/h2&gt;

&lt;p&gt;Traditional thinking on software projects is like a strange village. It has been cut off from the rest of the world for thousands of years and has developed some interesting beliefs about the laws of nature. They carpet their walls, which makes it hard to vacuum. They make their roofs out of glass and struggle with indoor temperatures. And they make clothes from hair, because nobody is allergic to their own hair.&lt;/p&gt;

&lt;p&gt;Perhaps the strangest thing about the village is that they believe gravity is an act of human willpower.&lt;/p&gt;

&lt;p&gt;All the animals in the valley are birds, which seem to cling to the branches of bushes, else they glide away into the sky. They also have no fruit trees, which means they’ve never had a Newtonian epiphany. Without evidence to the contrary, their collective delusion has persisted for many generations.&lt;/p&gt;

&lt;p&gt;If you visited the village, you’d hear such philosophical musings as “The earth keeps those who keep themselves,” and “I will, therefore I stand.” Every Wednesday they gather in the town hall to remind each other that “If you stand firm in mind, the ground will rise to meet you.”&lt;/p&gt;

&lt;p&gt;To tackle the problem of carpet cleaning, the village invented a cast iron humanoid robot that vacuum-cleans the walls. To stop the robot floating away, they built suction devices into its heels. One day, a robot is being moved between houses when its power fails.&lt;/p&gt;

&lt;p&gt;To their amazement, the robot doesn’t float away. The village philosophers gathered together to discuss this strange event. The only logical conclusion they could reach was that the robot had developed human willpower, which allowed it to remain earthbound. How else could it stay on the ground?&lt;/p&gt;

&lt;h2&gt;
  
  
  It’s Not Willpower, It’s Gravity
&lt;/h2&gt;

&lt;p&gt;Outside of the village, we all know that gravity works on robots, just like it works on people, birds, and rocks. That doesn’t prevent us from making a similar mistake when it comes to building software.&lt;/p&gt;

&lt;p&gt;Large software projects frequently fail and the people in charge blame human factors. Blaming people for these failures because they’re slow, lazy, dim-witted, and require rest is like the village believing gravity is a manifestation of willpower.&lt;/p&gt;

&lt;p&gt;The reality is that software delivery has a form of gravity that increases relative to batch size. This is why swarms of AI agents fail in all the same ways teams do when you give it large and complex tasks.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://zenodo.org/records/18809207" rel="noopener noreferrer"&gt;The Organizational Physics of Multi-Agent AI&lt;/a&gt;, Jeremy McEntire describes an experiment where the same multi-service backend system was created by different arrangements of AI agents. There is a belief that co-ordinating a team of AI agents will allow more complex tasks to be handled by AI, but the result of the experiment was that the coordination complexity outweighs the benefits of the division of work between multiple agents.&lt;/p&gt;

&lt;p&gt;The failures of multi-agent work look familiar. They are the same as the failures of large projects, except there are no humans to blame. This proves the challenges are inherent to complex work and cannot be attributed to human factors.&lt;/p&gt;

&lt;p&gt;It strikes me that we have been blaming human factors for bad systems for too long and we need to acknowledge they’re not the reason for past IT system failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Babbling Equilibrium
&lt;/h2&gt;

&lt;p&gt;“When I use a word,” Humpty Dumpty said in rather a scornful tone, “it means just what I choose it to mean — neither more nor less.” — Lewis Carroll, Alice’s Adventures in Wonderland&lt;/p&gt;

&lt;p&gt;When I say “rock”, some of you will think of geology (rocca comes from Latin) while others will think of music (roccian comes from Old English). A select few may think of a seaside hard-sugar treat, or a tool used to hold unspun fibers.&lt;/p&gt;

&lt;p&gt;For something as simple as a word, I can reduce your interpretive preference by putting the word into a sentence. When more complex communication takes place, it’s rare to have perfect alignment on the meaning we intend to communicate. Communication precision reduces from perfect alignment and can degrade to a babbling equilibrium where no information is received in the message.&lt;/p&gt;

&lt;p&gt;This misalignment can be understood through the pre-DevOps problem of having a development team measured for throughput and an ops team measured for reliability. When you communicate the same information to these two silos, interpretation will vary drastically.&lt;/p&gt;

&lt;p&gt;This challenge in transferring information remains when a human instructs an AI agent to do work. Hence the counter-arguments of “you’re prompting it wrong.” What surprises more people is that it remains when AI agents send messages to other AI agents. This is why the multi-agent configurations performed worse than single-agent setups.&lt;/p&gt;

&lt;p&gt;When you understand why agent swarms compound the problem rather than solving it, the answer starts to look familiar. These aren’t new problems. Long before AI agents, human development teams were failing for exactly the same structural reasons. The teams that recovered did so by tackling the structure, not the people.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fixing the System of Work
&lt;/h2&gt;

&lt;p&gt;In my past roles, I was often asked to join a company to “fix the development team.” They had reached a stage where every deployment turned into a high-severity incident, every change resulted in highly visible bugs, and the business had lost faith in the ability of the team to deliver working software.&lt;/p&gt;

&lt;p&gt;The teams usually had basic tools in place, like version control and automated builds. What was missing was the rest of the deployment pipeline, and this was the root cause of all the problems. Here’s how I’d fix it.&lt;/p&gt;

&lt;p&gt;Deployment automation made production releases repeatable and reliable, removing the most painful and wide-reaching failures of these teams. This led to more frequent deployments, which in turn reduced the size of work batches. Breaking work into smaller steps is a good way to improve communication success.&lt;/p&gt;

&lt;p&gt;Test automation increased our confidence that the software was deployable. It wasn’t uncommon to find teams with no automated tests, so adding characterizing tests around the most important features reduced the number of embarrassing software versions the team produced, such as the kind where nobody can even sign in.&lt;/p&gt;

&lt;p&gt;Monitoring and alerting helped the team understand how the system ran in production. As we fine-tuned the tools, the team became the first people to know when there was a problem, or the early signs a problem was emerging. By prioritizing work that kept the software healthy, we improved the relationship with the business, including executives who dealt with complaint escalations, and we made customers happier with the software.&lt;/p&gt;

&lt;p&gt;The result of these three changes isn’t just improvements to deployments, software quality, and observability. Having a complete pipeline lowers your batch size. This keeps complexity low and solves the communication and co-ordination problems that become insurmountable in large batches of work. The kind of problems that make it impossible for AI agents to deliver working software, just as they prevented teams from doing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Batches Have Gravity
&lt;/h2&gt;

&lt;p&gt;There are fundamental laws of software delivery that mean batches have a gravitational force that becomes unmanageable by human teams or AI agents. The larger the batches, the heavier everything gets, increasing the amount of energy needed to move things.&lt;/p&gt;

&lt;p&gt;Rather than searching for bigger tractors to move giant objects, organizations with modern software engineering practices make everything fit in a lightweight backpack. Small batches are the secret sauce behind Continuous Delivery and the &lt;a href="https://dora.dev/research/?view=detail" rel="noopener noreferrer"&gt;DORA research&lt;/a&gt; increases our confidence in this approach.&lt;/p&gt;

&lt;p&gt;Just as Fred Brooks observed in “The Mythical Man Month”, adding people to a late software project makes it later. McEntire’s research suggests this applies equally to situations where you simply increase the number of AI agents tackling the work.&lt;/p&gt;

&lt;p&gt;Continuous Delivery remains the best way to deliver software, no matter who or what is writing the code.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>software</category>
    </item>
    <item>
      <title>Why Octopus invests in developer experience</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Mon, 08 Jun 2026 16:27:59 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/why-octopus-invests-in-developer-experience-28dd</link>
      <guid>https://dev.to/_steve_fenton_/why-octopus-invests-in-developer-experience-28dd</guid>
      <description>&lt;p&gt;When you join Octopus, you get a great laptop and your choice from a range of docks, monitors, webcams, and input devices. You also get a home office allowance, which lets you upgrade your space and get 50% back. You may want a sit/stand desk, an awesome chair, and portrait lighting so everyone can see how delighted you are when they demo their cool new feature.&lt;/p&gt;

&lt;p&gt;What we ask in return is that you set yourself up to do your best work. Invest in your &lt;a href="https://www.hanselman.com/blog/brain-bytes-back-buns-the-programmers-priorities" rel="noopener noreferrer"&gt;brain, bytes, back, and buns&lt;/a&gt;, as Scott Hanselman put it. The essential idea behind this is that when you win, Octopus wins. We all win!&lt;/p&gt;

&lt;p&gt;Yet you can throw a soggy cat at a conference, and the chances are it will splash someone from an organization with a completely different approach to developer experience. One that doesn't value the sustainable delivery of their people's best work. Why is that?&lt;/p&gt;

&lt;h2&gt;
  
  
  A fork stuck in the road
&lt;/h2&gt;

&lt;p&gt;As we've seen in the software industry, silos are the source of all kinds of chaos. DevOps was created when someone realized the scale of the problem caused by having two teams with conflicting goals working on opposite sides of the same problem. Leaders whipped developers up for feature throughput and wanted to hold operations teams to account for reliability.&lt;/p&gt;

&lt;p&gt;In hindsight, it's obvious that this isn't going to work, but we did it for decades. You can get halfway to DevOps just by aligning the goals. When both teams share the same target, they'll work out how to get you the rest of the way.&lt;/p&gt;

&lt;p&gt;If we zoom out on our organization, we're likely to find a similar silo/goal conflict between engineering managers and the finance team. We ask the engineering manager to build a high-performing team, while we direct finance to spend as little money as possible. This structural incentive problem leads developers to get laptops and tools that someone has negotiated to be "good enough," and trust me, they aren't.&lt;/p&gt;

&lt;p&gt;When you look at developer experience through a FinBoss lens, where finance and engineering managers align around the return on investment, you'll find the optimal spend on developer tools shifts right rapidly.&lt;/p&gt;

&lt;p&gt;FinCost organizations reduce costs through standardization, commoditization, and by delaying kit refreshes for as long as possible. They often spend less than $1,000 on a laptop without realizing the true cost of an under-spec'd machine. Meanwhile, FinBoss organizations are seeking the $30,000 annual return on a $3,000 investment.&lt;/p&gt;

&lt;p&gt;To achieve this ROI, finance and engineering leadership work together to design policies that allow engineers to choose from a set of well-designed options. The combination of investment in great tools and individual choice in building the right setup is the path to success.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tiny visible costs
&lt;/h2&gt;

&lt;p&gt;FinCost organizations are driving decisions based on small, visible costs. Where there's a paper trail, there are savings to make: the purchase of a laptop, the training budget, and the conference invoice. These are part of the legible model, so there is no guesswork or experimental method needed to cost them. The numbers are right there on the page.&lt;/p&gt;

&lt;p&gt;Once you're managing costs, it's not uncommon to dial up the control, too. You limit options, standardize across the organization, and negotiate in bulk on everything to drive costs even lower. Compared to competitors, you could be spending 75% less on laptops, and just look at the savings from those pesky licenses and SaaS tools various teams were using. Hooray.&lt;/p&gt;

&lt;p&gt;Instead of letting engineers attend conferences they find relevant to their work, the organization negotiates a bulk purchase for a single conference. Instead of teams buzzing with diverse ideas and approaches, they all sit and watch the same talk. It's cheaper that way.&lt;/p&gt;

&lt;p&gt;A wooden fence encloses my garden. A fence lasts a long time if you give it a protective coat of wood preserver every once in a while. A tin of wood preserve costs about $20 and a few hours of mindful application each year. Over 5 years, I can save $100 by skipping the treatment. If I do this, my fence lasts about 10 years instead of 30.&lt;/p&gt;

&lt;p&gt;The cost of a tin of wood preserver is immediate and visible. The cost of replacing the fence is far higher, but it won't be visible for years. Additionally, if the fence provides value beyond privacy, like keeping a goat out of my vegetable garden, the cost of the fence failing could be the cost of my whole crop, which is even less legible to my cost control mindset.&lt;/p&gt;

&lt;p&gt;If you're creating software, it's likely to be more valuable than a fence. In fact, it should be giving you returns multiple times your investment. It's like a golden goose. You feed it well, and you get regular, valuable deliveries. If you had a golden goose, you wouldn't try to save on food costs if it reduced the flow of golden eggs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1qbcyohcmkuiw9bgb9f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1qbcyohcmkuiw9bgb9f.png" alt="A cartoon showing a character trying to save money by reducing the cost of feeding a golden goose. The goose doesn't survive this experiment." width="800" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same logic plays out with training. A FinCost organization cuts the training budget because the line item is visible and the return isn't. Individual engineers stop attending relevant courses, and teams miss out on the steady accumulation of skill that comes from ongoing, targeted learning. Nobody raises a purchase order for "capability that didn't grow this year."&lt;/p&gt;

&lt;p&gt;Then something goes wrong. Delivery is slow, the codebase is a mess, or a competitor pulls ahead. Someone decides the answer is transformation, and that means Scaled Agile, or whatever flavor of desperation is in fashion in exec suites at the time.&lt;/p&gt;

&lt;p&gt;So the whole department gets booked onto an external SAFe course. Not one or two people who need it. Everyone. The invoice lands, and it's eye-watering: many times what a thoughtful, ongoing training program would have cost across the same period. The organization that was too cautious to spend $500 on a course people wanted just spent $50,000 on one nobody asked for.&lt;/p&gt;

&lt;p&gt;This is the hidden tax of FinCost thinking. Small, visible costs get cut. The problems that those small costs would have prevented quietly compound. Eventually, the pressure releases all at once, in an expensive, rushed, and hard-to-argue-against way, because now there's a crisis with a visible price tag.&lt;/p&gt;

&lt;p&gt;The tin of wood preserver was the right investment all along.&lt;/p&gt;

&lt;h2&gt;
  
  
  The invisible people-hours
&lt;/h2&gt;

&lt;p&gt;Developers work around 40 hours a week. Stripe's Developer Coefficient found that productivity friction can eat up roughly half of those hours. That's the time that evaporates before a single line of useful code is written. Across the global developer workforce, Stripe put a number on that loss: $300 billion. It's worth noting that only $85 billion of this is attributable to bad code. The rest is pure friction: slow tools, broken environments, waiting for builds, wrestling with under-spec'd machines. Productivity means more than writing code faster.&lt;/p&gt;

&lt;p&gt;That friction has a texture. It's a developer losing flow because their laptop is thrashing memory, and they've lost the thread of what they were thinking.&lt;/p&gt;

&lt;p&gt;It's waiting 10 minutes for a build that would have completed in 2 minutes on a faster machine. It's the workarounds you built because the approved tool wasn't good enough, which obliterates hours of your week for maintenance. It's the skilled engineers who start looking for a new role because the environment makes them feel like you don't take their work seriously.&lt;/p&gt;

&lt;p&gt;None of this appears on a purchase order. None of it shows up in a variance report. It just quietly drains the value your software could be creating.&lt;/p&gt;

&lt;p&gt;There's also an upside case, not just a loss case. Software that ships faster captures more market share. Developers who stay in flow write better code with fewer bugs, which means less rework and fewer incidents. A high-performing team attracts other high performers. The return on investing in developer experience isn't just "we lose less time"; it's sales opportunities, reduced churn, higher product quality, and a compounding advantage over competitors who are still buying $800 laptops and calling it responsible.&lt;/p&gt;

&lt;p&gt;When you focus on cost control, there's a ceiling on how much you can save. When you look for return on investment, there's no equivalent ceiling on how much you can gain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CFO lens
&lt;/h2&gt;

&lt;p&gt;When I asked Sammy, our CFO, about why we invest in people, powerful machines, and great tools, he said: "At Octopus, we think about equipment as a productivity tool. Developers are one of our most expensive and constrained resources. If spending a few extra thousand dollars on a fast machine and proper screen space saves time, reduces cognitive load, or keeps someone in flow more often, it pays for itself very quickly."&lt;/p&gt;

&lt;p&gt;That means our finance team doesn't ask "What's the cheapest laptop we can buy?" Instead, they ask, "What setup helps this person do their best work?" From a finance perspective, this is about a high-ROI spend, not indulgence.&lt;/p&gt;

&lt;p&gt;Octopus is running the FinBoss playbook, which aligns finance and leadership in empowering employees to do their best work. That means expanding what you're willing to measure so that you can balance the visible costs with traditionally invisible returns.&lt;/p&gt;

&lt;p&gt;The responsibility for providing this environment for employees rests with all leaders, including Sammy, and is part of the deal employees have with the company; we'll give you the best environment and tools if you give us the greatest work of your career.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reckoning
&lt;/h2&gt;

&lt;p&gt;If we've ever met, I've likely mentioned &lt;a href="https://dora.dev/research/" rel="noopener noreferrer"&gt;DORA's research&lt;/a&gt;. I'm a super-fan of their State of DevOps reports, because they provide us techniques, practices, and outcomes that are all linked through complex relationships. The model shows that transformational leadership, lean product management, and Continuous Delivery drive software delivery performance and organizational outcomes.&lt;/p&gt;

&lt;p&gt;While many of the capabilities in the DORA model are technical, many others relate to leadership. Particularly relevant to developer experience are generative organizational culture, transformational leadership, empowering teams to choose tools, team experimentation, and a learning culture. You can read about these and more on the &lt;a href="https://dora.dev/capabilities/" rel="noopener noreferrer"&gt;DORA website&lt;/a&gt;. Together, they back up the FinBoss concept with tens of thousands of survey samples that support the case.&lt;/p&gt;

&lt;p&gt;The question is: Which organization are you now, and which do you want to be? Is it FinCost, operating myopically against the bottom line, or FinBoss, sharing the responsibility for developer experience and employee productivity? The fork in the road was never a choice. We know FinCost is a dead end, and the benefits of FinBoss aren't soft claims; they're measurable outcomes.&lt;/p&gt;

</description>
      <category>devex</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Automatically update GitHub Action versions</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Mon, 01 Jun 2026 19:20:26 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/automatically-update-github-action-versions-337g</link>
      <guid>https://dev.to/_steve_fenton_/automatically-update-github-action-versions-337g</guid>
      <description>&lt;p&gt;You don’t notice your GitHub Actions versions until you start getting warnings about things like “Node 20 is no longer supported”. When you think about it, GitHub Actions are yet another dependency that needs to be kept up to date and present supply chain risks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Dependabot to do the work
&lt;/h2&gt;

&lt;p&gt;The good news is, you can get Dependabot to keep your GitHub Actions up to date for you. You can add instructions for this to your .github/dependabot.yml:&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;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="na"&gt;updates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;package-ecosystem&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;github-actions"&lt;/span&gt;
    &lt;span class="na"&gt;directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/"&lt;/span&gt;
    &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weekly"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case I already had configuration for my npm dependencies:&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;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="na"&gt;updates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;package-ecosystem&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;npm"&lt;/span&gt;
    &lt;span class="na"&gt;directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/"&lt;/span&gt;
    &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weekly"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it’s trivial to add multiple updates to the same file:&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;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="na"&gt;updates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;package-ecosystem&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;npm"&lt;/span&gt;
    &lt;span class="na"&gt;directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/"&lt;/span&gt;
    &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weekly"&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;package-ecosystem&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;github-actions"&lt;/span&gt;
    &lt;span class="na"&gt;directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/"&lt;/span&gt;
    &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weekly"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Automatic pull requests
&lt;/h2&gt;

&lt;p&gt;When you first commit this file, you’ll notice pull requests start appearing for your review.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90itqd7rhembp35ygx90.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90itqd7rhembp35ygx90.jpg" alt="Dependabot pull request to update a GitHub Action version" width="800" height="663"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup pnpm cache&lt;/span&gt;
    &lt;span class="s"&gt;uses&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/cache@v4 (-)&lt;/span&gt;
    &lt;span class="s"&gt;uses&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/cache@v5 (+)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple example of how you can use Dependabot to keep your GitHub Actions up to date. You can find more information about Dependabot in the &lt;a href="https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/about-dependabot-version-updates" rel="noopener noreferrer"&gt;GitHub documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>github</category>
      <category>devops</category>
    </item>
    <item>
      <title>Harness engineering: The power of AI, guided by human intelligence</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Tue, 26 May 2026 06:25:39 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/harness-engineering-the-power-of-ai-guided-by-human-intelligence-kb4</link>
      <guid>https://dev.to/_steve_fenton_/harness-engineering-the-power-of-ai-guided-by-human-intelligence-kb4</guid>
      <description>&lt;p&gt;Vibe coding offered us a tantalizing dream. Have a conversation with AI, forget the code exists, and ship software. This can be a useful way to solve localized and one-off problems. For production systems that need to live, breathe, and evolve for years, it's a different story.&lt;/p&gt;

&lt;p&gt;A new idea called "harness engineering" points to what you need to create production-grade AI-generated code, and the metaphor hidden in the name tells you everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The horse and the harness
&lt;/h2&gt;

&lt;p&gt;Horses are powerful animals, but left to their own devices, they direct their power toward whatever they want. A harness doesn't diminish the horse's strength; it channels it. The human holding the reins isn't doing the physical work; they're doing the intelligent work: choosing the destination, reading the terrain, knowing when to slow down.&lt;/p&gt;

&lt;p&gt;Harness engineering works the same way. The AI agent is your horse. It's generative, fast, tireless, and capable of producing large software systems with a small team of engineers directing the work. The harness is the system of tools, constraints, and feedback loops that channels all that raw capability toward something coherent, maintainable, and trustworthy.&lt;/p&gt;

&lt;p&gt;When teams attempt to deliver large systems with AI agents without a harness, they typically get run over and trampled by the horse. You'll know if you're missing the harness if you find yourself scheduling fixing sessions and tidy-up days as part of your process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why vibe coding doesn't scale
&lt;/h2&gt;

&lt;p&gt;When Andrej Karpathy coined "vibe coding" in early 2025, he was describing something delightfully honest: a mode where you "fully give in to the vibes, embrace exponentials, and forget that the code even exists."&lt;/p&gt;

&lt;p&gt;When you vibe code, you accept all changes without reviewing them and pass any error messages back to the AI to fix. When you use this approach, you let the levels of success and failure push you down different routes. If it won't do what you want, you flex on your ideas to get something that works.&lt;/p&gt;

&lt;p&gt;Karpathy said this works for "throwaway weekend projects," and a year later, he's moved on to calling the professional version "agentic engineering."&lt;/p&gt;

&lt;p&gt;The distinction matters. Vibe coding is epistemically passive: you surrender understanding along with the keyboard. Harness engineering is epistemically demanding; it just redirects what you need to understand. Instead of understanding every function, you need to understand the system that constrains how functions get written.&lt;/p&gt;

&lt;p&gt;OpenAI created harness engineering as part of an experiment. A team spent 5 months building an internal product with no manually written code. The logic, tests, build configuration, documentation, and observability tooling were all created by AI agents. They created over a million lines of code with 3 engineers and deployed the system to internal users and external alpha testers. They estimate this took 10% of the time it would have taken a team to write the system without AI agents.&lt;/p&gt;

&lt;p&gt;The insight from this experiment was that &lt;em&gt;environment legibility&lt;/em&gt; is the crucial factor in getting AI agents to deliver software that works. Without this legibility, agents fail as they can't find or reason about the information needed to complete the task.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 3 practices that make harness engineering work
&lt;/h2&gt;

&lt;p&gt;Based on &lt;a href="https://openai.com/index/harness-engineering/" rel="noopener noreferrer"&gt;OpenAI's write-up&lt;/a&gt; and Birgitta Böckeler's sharp analysis on the &lt;a href="https://martinfowler.com/articles/exploring-gen-ai/harness-engineering.html" rel="noopener noreferrer"&gt;Thoughtworks blog&lt;/a&gt;, harness engineering clusters around three categories of practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context engineering
&lt;/h2&gt;

&lt;p&gt;When it comes to currently available AI agents, context is a precious resource. You don't have an unlimited context window, so you need to be smart with how you use it. Providing a giant agent markdown file filled with instructions only crowds out the real task. Large agent markdown files are also hard to understand and update.&lt;/p&gt;

&lt;p&gt;Instead, limit the agent markdown file to a hundred lines and use it as a table of contents. You can link out to individual documents with maps, execution plans, and design specifications. They should be well-organized within the codebase so they are versioned and discoverable.&lt;/p&gt;

&lt;p&gt;You can provide dynamic context from observability data, logs, metrics, traces, and information from browser dev tools. That will let the agent detect and fix bugs it introduces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architectural constraints
&lt;/h2&gt;

&lt;p&gt;This is where harness engineering most clearly diverges from vibe coding's "anything goes" philosophy. The OpenAI team enforced a rigid architectural model whereby the business domain was divided into a sequence of fixed layers:&lt;/p&gt;

&lt;p&gt;Types → Config → Repo → Service → Runtime → UI&lt;/p&gt;

&lt;p&gt;Dependencies can flow only in the direction of the arrows, and cross-cutting concerns like auth, telemetry, and feature flags enter through a single explicit interface called "Providers". Nothing else is allowed. You should enforce your design with custom linters and structural tests, which you can implement using AI agents.&lt;/p&gt;

&lt;p&gt;You can use the error messages in custom enforcement tools to provide remediation instructions so AI agents can fix violations themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entropy management as garbage collection
&lt;/h2&gt;

&lt;p&gt;Agents are pattern replicators. If you give them a codebase full of inconsistencies, they'll faithfully reproduce them at scale. You can solve this by running background agents that scan for deviations and automatically fix them. You need to keep the code well factored and consistent to make it legible for future agent runs.&lt;/p&gt;

&lt;p&gt;When an agent struggles with a task, you shouldn't fix it by hand. Identify what capability is missing, and then make it legible and enforceable for the agent. After making adjustments, you get the AI tools to write the fix. This improves the harness and makes it more valuable over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The human's job in harness engineering
&lt;/h2&gt;

&lt;p&gt;With agents handling the coding, humans shift their focus to designing environments, specifying intent, and building feedback loops.&lt;/p&gt;

&lt;p&gt;Environment design concerns the arrangement of code, documentation, and constraints. Intent is specified through precise prompts that connect high-level goals to coherent implementations. Feedback loops come from test automation, structural checks, and agent-led reviews, minimizing the need to step in and fix what agents are doing.&lt;/p&gt;

&lt;p&gt;The code review burden is managed through mechanical checks built into the harness, with agents handling the initial review. A review is escalated only when human judgment is needed, for example, to approve a novel architectural design. This prevents the code review from becoming a bottleneck.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for the future
&lt;/h2&gt;

&lt;p&gt;In the Platform Engineering community, we have been discussing the role of platform engineers as organizational enablers of AI. Platform teams may create and maintain templates for harness engineering that provide a solid starting point for environment legibility and for providing appropriate constraints. They might even provide shared custom linters and structural testing tools.&lt;/p&gt;

&lt;p&gt;Bringing harness engineering into an existing codebase may be more difficult than applying the technique to new systems. There will be fewer clear standards that will weaken the harness. The accumulated entropy of an established code base will pose similar problems to introducing test-driven development or a code linter for the first time.&lt;/p&gt;

&lt;p&gt;If harness engineering gains traction, it will encourage the industry to converge on boring, well-established technology choices. Languages and tech stacks with more high-quality samples in training data and years of community Q&amp;amp;A coverage will naturally produce better results than niche tech stacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Harness engineering and Continuous Delivery
&lt;/h2&gt;

&lt;p&gt;For teams already practicing Continuous Delivery, harness engineering is a natural fit. The techniques will fit into existing feedback loops and validation practices.&lt;/p&gt;

&lt;p&gt;Harness engineering forces teams to adopt long-standing good practices like high-quality documentation, modular design, consistent naming, and capturing architectural decisions. Agents have no tacit knowledge; until it is made explicit, it doesn't exist.&lt;/p&gt;

&lt;p&gt;You'll need to supplement harness engineering with a robust automated test suite that proves the system works as intended, since the harness constrains how code is written; it doesn't validate that user needs are satisfied.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Building a harness is a continuous process, and it might not prove its value until you've completed months of iteration. You should look for existing foundations that will give you a head start, like pre-commit hooks, custom linters, structural testing frameworks, documentation, and test automation.&lt;/p&gt;

&lt;p&gt;Each existing foundation can be woven into a harness, which you then iterate on as you identify gaps. By making fixes through the harness rather than directly in the code, you strengthen the harness and make agents more capable. At the same time, the human's work shifts to the interesting work of choosing the direction and reading the terrain.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>software</category>
    </item>
    <item>
      <title>Continuous Delivery Office Hours Ep.2: Remaining deployable at all times</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Mon, 18 May 2026 11:10:22 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/continuous-delivery-office-hours-ep2-remaining-deployable-at-all-times-2pn9</link>
      <guid>https://dev.to/_steve_fenton_/continuous-delivery-office-hours-ep2-remaining-deployable-at-all-times-2pn9</guid>
      <description>&lt;p&gt;When you can’t deploy on demand, you’ve lost control of your software. Risk accumulates in unreleased code, and the more changes you store in one place, the more chance they have of triggering overheads, rework, and failures. When you have blockers stopping you from going live, you’ll start to accumulate dangerously high levels of risk unless you prioritize deployability.&lt;/p&gt;

&lt;p&gt;By choosing to do work that returns software to a deployable state ahead of any other kinds of work, like feature development, you’ll avoid the toxicity of tangled work batches. Instead, you can smoothly flow changes between test and production and get the feedback you need to be confident that your software works.&lt;/p&gt;

&lt;p&gt;Crucially, if you discover a high-severity bug or security problem, there are no roadblocks to getting fixes into production. You don’t need a special “expedited lane” for these changes, which means you don’t skip steps that let bad changes into your codebase.&lt;/p&gt;

&lt;p&gt;Let’s take a look at problem indicators that will help you identify and fix common deployability issues. The goal of answering the deployability question is a mile marker, not the destination, but if you can’t answer the question, you’re going to waste time looking for landmarks!&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch the episode
&lt;/h2&gt;

&lt;p&gt;You can watch the episode below, or read on to find some of the key discussion points.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=QCVrQ0fjdJw" rel="noopener noreferrer"&gt;CD Office Hours: Episode 2.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The awkward silence problem
&lt;/h2&gt;

&lt;p&gt;When you ask your team, “Are we ready to deploy?”, the correct answer is either “absolutely” or “no way”. The worst possible answer is silence or confusion. If the team doesn’t know whether they can deploy, they’re missing the deployment pipeline that would generate the answer.&lt;/p&gt;

&lt;p&gt;When you commit a code change, build errors should be returned to you within a couple of minutes. At the end of 5 minutes from your commit, a suite of fast-running tests should tell you if you’ve broken functionality or the quality attributes of your application. Dependency checks, code scanning, and other static analysis tools should have told you if you have a problem. If you have long-running tests or tests that depend on the new software version being deployed to a test environment, you should know in another 5-20 minutes if they’ve detected a problem.&lt;/p&gt;

&lt;p&gt;After all these checks, you should have a version of your software running in a test environment that you have high confidence in. If someone asked you whether you’re ready to deploy, you’d answer “absolutely”.&lt;/p&gt;

&lt;p&gt;Deployment automation makes sure the deployment is a non-event. It guarantees the same process is used to deploy to all environments, and makes it trivial to deploy on demand. A solid deployment pipeline contains all the checks you need to know whether you can deploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual testing is a ceiling, not a floor
&lt;/h2&gt;

&lt;p&gt;Teams often treat manual testing as a foundation for verifying that a software version works. In reality, it acts more like a ceiling, limiting your ability to flow changes to production. As your software becomes more complex, the ceiling descends as the testing takes longer.&lt;/p&gt;

&lt;p&gt;Long test cycles make you subvert your process to the speed at which you can test. You’ll notice when this happens because you’ll keep looping back to fix bugs and restart the test process. From the earliest change you make, through each bug list and all the re-testing, right through to the final software version, you are not deployable.&lt;/p&gt;

&lt;p&gt;Automating your tests is the real foundation for your software. This raises the ceiling and moves the constraint away from the test cycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your old code wasn’t written to be tested
&lt;/h2&gt;

&lt;p&gt;If your application is successful, it will have some history. Part of that history is often that it wasn’t written with test automation in mind. That means you need to identify where your risk is, work out how to find the seams that will make it testable, and start adding characterizing tests.&lt;/p&gt;

&lt;p&gt;Once some old code is wrapped with tests, it becomes far easier to change the code design, because the tests will fail if you break something.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automation is living documentation
&lt;/h2&gt;

&lt;p&gt;When developers move on, a portion of your institutional knowledge goes with them. High-quality documentation can help teams distribute this knowledge and reduce its loss, and the best kind of documentation is test automation.&lt;/p&gt;

&lt;p&gt;Well-written automation, like tests, deployment automation, and infrastructure as code, performs useful functions while effortlessly documenting them. Because you make all changes through the living documentation, it is always up to date.&lt;/p&gt;

&lt;p&gt;The hidden cost of undocumented knowledge becomes painfully clear when you have to deploy without the person who normally handles it. You follow their checklist carefully, confirm every step, and everything looks right; yet the deployment still fails. What you didn’t know is that the checklist stopped being accurate months ago, because the person doing the deployments stopped consulting it. All the new steps they introduced lived in their head, not on paper.&lt;/p&gt;

&lt;p&gt;The living documentation built into automation tools is especially valuable when onboarding new developers. Rather than relying on tribal knowledge passed down through conversations and shadowing, a new team member can read the test suite and understand not just what the software does, but what it’s supposed to do and why certain behaviors matter. That’s documentation that keeps pace with the code because it is the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The value of long-term sustainability
&lt;/h2&gt;

&lt;p&gt;Like its Agile predecessors, Continuous Delivery values long-term sustainability. That means you invest a little more effort up front to constrain maintenance costs over the long term. Writing tests may mean a feature takes &lt;strong&gt;20-25%&lt;/strong&gt; more time to implement, but the defect density can be &lt;strong&gt;91% lower&lt;/strong&gt; than similar features not guided by tests (&lt;a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2009/10/Realizing-Quality-Improvement-Through-Test-Driven-Development-Results-and-Experiences-of-Four-Industrial-Teams-nagappan_tdd.pdf" rel="noopener noreferrer"&gt;Microsoft VS&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;You could reduce 40 hours of bug fixing to just 3.6 hours by guiding feature development with tests, and you also save on other overheads caused by escaped bugs, like reputational damage, customer churn, support costs, pinpointing and debugging, test cycles, and feature delay.&lt;/p&gt;

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

&lt;p&gt;While it takes some effort to set up a strong deployment pipeline, knowing whether a software version is deployable pays dividends. Technical practices like test-driven development and pair programming are needed to keep software economically viable in the long term, even though they require a little more effort up front.&lt;/p&gt;

&lt;p&gt;If you can’t answer the question “Is your software deployable?”, you’re sure to run into trouble.&lt;/p&gt;

&lt;p&gt;Happy deployments!&lt;/p&gt;

</description>
      <category>automation</category>
      <category>cicd</category>
      <category>devops</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>How AI Makes You 56% Faster and 19% Slower</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Tue, 12 May 2026 11:32:13 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/how-ai-makes-you-56-faster-and-19-slower-33k</link>
      <guid>https://dev.to/_steve_fenton_/how-ai-makes-you-56-faster-and-19-slower-33k</guid>
      <description>&lt;p&gt;&lt;strong&gt;The flow rate of change means we don’t have all the answers!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There’s a growing body of research around AI coding assistants with a confusing range of conflicting results. This is to be expected when the landscape is constantly shifting from coding suggestions to agent-based workflows to Ralph Wiggum loops and beyond.&lt;/p&gt;

&lt;p&gt;The Reichenbach Falls in Switzerland has a drop of 250 meters and a flow rate of 180–300 cubic meters (enough to fill about 1,500 bathtubs) every minute. This is comparable to the rate of change in tools and techniques around coding assistants over the past year, so few of us are using it in the same way. You can’t establish best practices under these conditions; only practical point-in-time techniques.&lt;/p&gt;

&lt;p&gt;As an industry, we, like Sherlock Holmes and James Moriarty, are battling on the precipice of this torrent, and the survival of high-quality software and sustainable delivery is at stake.&lt;/p&gt;

&lt;p&gt;Given the rapid evolution of tools and techniques, I hesitate to cite studies from 2025, let alone 2023. Yet these are the most-cited studies on the effectiveness of coding assistants, and they present conflicting findings. One study reports developers completed tasks 56% faster, while another reports a 19% slowdown.&lt;/p&gt;

&lt;p&gt;The studies provide a platform for thinking critically about AI in software development, enabling more constructive discussions, even as we fumble our collective way toward understanding how to use it meaningfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  The GitHub Self-Assessment
&lt;/h2&gt;

&lt;p&gt;The often-cited 56% speed up stems from a 2023 collaboration between &lt;a href="https://arxiv.org/abs/2302.06590" rel="noopener noreferrer"&gt;Microsoft Research, GitHub, and MIT&lt;/a&gt;. The number emerged from a lab test in which developers were given a set of instructions and a test suite to see how quickly and successfully they could create an HTTP server in JavaScript.&lt;/p&gt;

&lt;p&gt;In this test, the AI-assisted group completed the task in 71 minutes, compared to 161 minutes for the control group. That makes it 55.8% faster. Much of the difference came from the speed at which novice developers completed the task. Task success was comparable between the two groups.&lt;/p&gt;

&lt;p&gt;There are weaknesses in this approach. The tool vendor was involved in defining the task against which the tool would be measured. If I were sitting an exam, it would be to my advantage to set the questions. Despite this, we can generously accept that it made the coding task faster, and that the automated tests sufficiently defined task success.&lt;/p&gt;

&lt;p&gt;We might also be generous in stating that tools have improved over the past three years. Benchmarking reports like those from METR have found that AI has doubled the length of tasks it can handle every 7 months; other improvements are likely.&lt;/p&gt;

&lt;p&gt;We’ve also observed the emergence of techniques that introduce work plans and task chunking, thereby improving the agent’s ability to perform larger tasks that would otherwise incur context decay.&lt;/p&gt;

&lt;p&gt;And METR is also the source of our cautionary counter finding on task speed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The METR sense check
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://arxiv.org/pdf/2507.09089" rel="noopener noreferrer"&gt;METR&lt;/a&gt; study in 2025 examined the impact of contemporary tools on task completion times in real-world open-source projects. The research is based on 246 tasks performed by 16 developers who had experience using AI tools. Each task was randomly assigned to an AI-assisted group and a control group. Screen recordings were captured to check and categorize the task completion.&lt;/p&gt;

&lt;p&gt;The research found that tasks were slowed by 19%, which appears to contradict the earlier report. In reality, the active coding time was reduced by AI tools, as was the task of searching for answers, testing, and debugging. The difference in the METR report was that it identified tools that introduced new task categories, such as reviewing AI output, prompting, and waiting for responses. These new tasks, along with increased idle/overhead time, consumed the gains and pushed overall task completion times into the red.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ivhl4qhapm7zc0tvlrj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ivhl4qhapm7zc0tvlrj.png" alt="Time saved by AI is often taken up by new tasks associated with AI-assisted work" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://arxiv.org/abs/2507.09089" rel="noopener noreferrer"&gt;METR Measuring the Impact of Early-2025 AI&lt;/a&gt;. Task category comparison.&lt;/p&gt;

&lt;p&gt;One finding from the METR study worth noting is the perception problem. Developers predicted AI assistants would speed them up. After completing the task, they also estimated they had saved time, even though they were 19% slower. This highlights that our perceptions of productivity are unreliable, as they were when we believed that multitasking made us more productive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lack of consensus
&lt;/h2&gt;

&lt;p&gt;A recently released study from &lt;a href="https://www.multitudes.com/data-to-cut-through-the-hype" rel="noopener noreferrer"&gt;Multitudes&lt;/a&gt;, based on data collected over 10 months in 2025, highlights the lack of consensus around the productivity benefits of AI coding tools. They found that the number of code changes increased, but this was countered by an increase in out-of-hours commits.&lt;/p&gt;

&lt;p&gt;This appears to be a classic case of increasing throughput at the expense of stability, with out-of-hours commits representing failure demand rather than feature development. It also confuses the picture as developers working more hours would also create more commits, even without an AI assistant.&lt;/p&gt;

&lt;p&gt;Some of the blame was attributed to adoption patterns that gave little time for learning and increased delivery pressure on teams, now that they had tools to that were supposed to help them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The wicked talent problem
&lt;/h2&gt;

&lt;p&gt;One finding that repeatedly comes up in the research is that AI coding assistants benefit novice developers more than those with deep experience. This makes it likely that the use of these tools will exacerbate a wicked talent problem. Novice developers may never shed their reliance on tools, as they become accustomed to working at a higher level of abstraction.&lt;/p&gt;

&lt;p&gt;This is excellent news for those selling AI coding tools, as an ever-expanding market of developers who can’t deliver without the tools will be a fruitful source of future income. When investors are ready to recoup, organizations will have little choice but to accept whatever pricing structure is required to make vendors profitable. Given the level of investment, this may be a difficult price to accept.&lt;/p&gt;

&lt;p&gt;The problem may deepen as organizations have stopped hiring junior developers, believing that senior developers can delegate junior-level tasks to AI tools. This doesn’t align with the research, which shows junior developers speed up the most when using AI.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://octopus.com/publications/ai-pulse-report" rel="noopener noreferrer"&gt;AI Pulse Report&lt;/a&gt; compares this to the aftermath of the dot-com bubble, when junior hiring was frozen, resulting in a shortage of skilled developers. When hiring picked up again, increased competition for talent led to higher salaries.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzl49343exidisiks6x74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzl49343exidisiks6x74.png" alt="Organizations are slowing the hiring of junior developers" width="800" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="http://octopus.com/publications/ai-pulse-report" rel="noopener noreferrer"&gt;The AI Pulse Report&lt;/a&gt;. Hiring plans for junior developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuous means safe, quick, and sustainable
&lt;/h2&gt;

&lt;p&gt;While many practitioners recognize the relevance of value stream management and the theory of constraints to AI adoption, a counter-movement is emerging that calls for the complete removal of downstream roadblocks.&lt;/p&gt;

&lt;p&gt;“If you can’t complete code reviews at the speed at which they are created with AI, you should stop doing them. Every other quality of a system should be subverted to straight-line speed. Why waste time in discovery when it would starve the code-generating machine? Instead, we should build as much as we can as fast as we can.”&lt;/p&gt;

&lt;p&gt;As a continuous delivery practitioner and a long-time follower of the DORA research program, this makes no sense to me. One of the most powerful findings in the DORA research is that a user-centric approach beats flat-line speed in terms of product performance. You can slow development down to a trickle if you’ve worked out your discovery process, because you don’t need many rounds of chaotic or random experiments when you have a deep understanding of the user and the problem they want solved.&lt;/p&gt;

&lt;p&gt;We have high confidence that continuous delivery practices improve the success of AI adoption. You shouldn’t rush to dial up coding speed until you’ve put those practices in place, and you shouldn’t remove practices in the name of speed. That means working in small batches, integrating changes into the main branch every few hours, keeping your code deployable at all times, and automating builds, code analysis, tests, and deployments to smooth the flow of change.&lt;/p&gt;

&lt;p&gt;Continuous delivery is about getting all types of changes to users safely, quickly, and sustainably. The calls to remove stages from the deployment pipeline to expedite delivery compromise the safety and sustainability of software delivery, permanently degrading the software’s value for a temporary gain.&lt;/p&gt;

&lt;h2&gt;
  
  
  It’s a system
&lt;/h2&gt;

&lt;p&gt;There’s so much to unpack in the research, and many of the studies are zoomed in on a single link in a much longer chain. Flowing value from end to end safely, quickly, and sustainably should be the goal, rather than merely maintaining flat-line speed or optimizing individual tasks, especially when those tasks are the constraining factor.&lt;/p&gt;

&lt;p&gt;With the knowledge we’ve built over the last seven decades, we should be moving into a new era of professionalism in software engineering. Instead, we’re being distracted by speed above all other factors. When my local coffee shop did this, complete with a clipboard-wielding Taylorist assessor tasked with bringing order-to-delivery times down to 30 seconds, the delivery of fast, bad coffee convinced me to find a new place to get coffee. Is this what we want from our software?&lt;/p&gt;

&lt;p&gt;The results across multiple studies show that claims of a revolution are premature, unless it’s an overlord revolution that will depress the salaries of those pesky software engineers and develop a group of builders unable to deliver software unless it’s through these new tools. Instead, we should examine the landscape and learn from research and from one another as we work out how to use LLM-based tools effectively in our complex socio-technical environments.&lt;/p&gt;

&lt;p&gt;We are at a crossroads: either professionalize our work or adopt a prompt-and-fix model that resembles the earliest attempts to build software. There are infinite futures ahead of us. I don’t dread the AI-assisted future as a developer, but as a software user. I can’t tolerate the quality and usability chasm that will result from removing continuous delivery practices in the name of speed.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>coding</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Continuous Delivery Office Hours Ep.1: Continuous Delivery should be your top priority</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Tue, 05 May 2026 09:07:21 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/continuous-delivery-office-hours-ep1-continuous-delivery-should-be-your-top-priority-16j0</link>
      <guid>https://dev.to/_steve_fenton_/continuous-delivery-office-hours-ep1-continuous-delivery-should-be-your-top-priority-16j0</guid>
      <description>&lt;p&gt;Continuous Delivery promotes low-risk releases, faster time-to-market, higher quality, lower costs, better products, and happier teams. Software is at the core of everything a business does today, so organizations must be able to respond to customer needs more quickly than ever.&lt;/p&gt;

&lt;p&gt;Taking a quarter or a month to deliver new functionality puts companies behind their competition and prevents them from serving their customers. Few practices offer as much return on investment as Continuous Delivery, but many organizations continue to resist it, often making their deployment problems worse in the process.&lt;/p&gt;

&lt;p&gt;Understanding why Continuous Delivery matters and how to implement it effectively can transform not only your deployment process but also your entire software development approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Watch the episode
&lt;/h2&gt;

&lt;p&gt;You can watch the episode below, or read on to find some of the key discussion points.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=V67ASNnUGDs" rel="noopener noreferrer"&gt;Watch Continuous Delivery Office Hours Ep.1&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Continuous Delivery?
&lt;/h2&gt;

&lt;p&gt;At its core, Continuous Delivery means you can deploy your software at any time. A good indication of whether a team practices Continuous Delivery is whether they prioritize work that keeps software deployable. Other development styles usually continue working on features and return to deployability issues later.&lt;/p&gt;

&lt;p&gt;That means teams must have fast, automated feedback for every change, highlighting when the software has an issue that would prevent its deployment. Deployments to all environments must be automated, with artifacts and deployment processes pinned to avoid unexpected changes between deployments.&lt;/p&gt;

&lt;h2&gt;
  
  
  The big three: Time, risk, and money
&lt;/h2&gt;

&lt;p&gt;The longer the intervals between deployments, the more you accumulate risk, and the more you delay the value the changes will realize. If you wait six months between deployments, you're more likely to get caught in a firefighting loop, spending more time pinpointing bug sources because of the volume of changes.&lt;/p&gt;

&lt;p&gt;Crucially, until you place new features in users' hands, you accumulate market risk that the changes won't solve the underlying problem in a way users accept.&lt;/p&gt;

&lt;h2&gt;
  
  
  The deployment paradox
&lt;/h2&gt;

&lt;p&gt;Human psychology works against us when deployments go wrong. Having waited six months to deploy, the pain of the firefighting stage and the increased risk of deploying large batches of changes mean people develop an aversion to deployments.&lt;/p&gt;

&lt;p&gt;When a process is stressful and goes wrong, we naturally want to do it less often. You might think: "If we do fewer deployments, we'll have less pain." But this is precisely backwards.&lt;/p&gt;

&lt;p&gt;Decreasing deployment frequency increases batch size, making the next deployment more likely to go wrong and cause pain. This is like avoiding the dentist after a painful checkup; the longer you leave it, the worse the next visit will be.&lt;/p&gt;

&lt;p&gt;Risk-averse organizations have instincts that work against their goal of safety. The solution isn't to deploy less often; it's to deploy more frequently with smaller batches of changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping software deployable during feature development
&lt;/h2&gt;

&lt;p&gt;Another objection to Continuous Integration and Delivery is that features take time to build, so you can't deploy while a feature is in flight. With an infinity of overlapping feature development, this would result in never deploying (or, more likely, work taking place in long-lived branches).&lt;/p&gt;

&lt;p&gt;The solution is to separate deployments from feature release. Trunk-based development (integrating changes into the main branch every day, often many times each day) and feature toggles make it possible to work from a shared code base without making in-flight features visible to users.&lt;/p&gt;

&lt;p&gt;There are many benefits to feature toggles beyond supporting Continuous Delivery. They also let you share features early with specific user segments or roll them out progressively rather than all at once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changing what deployment success means
&lt;/h2&gt;

&lt;p&gt;When you separate deployment from release, you also transform how you measure deployment success. You're no longer testing whether new functionality works during deployment. You're only verifying that the application is running and healthy. This focus makes deployments faster and less stressful.&lt;/p&gt;

&lt;p&gt;Feature toggles reduce the stress and burden of deployments because you'll no longer miss deployment issues while checking functionality or miss functionality problems while monitoring deployments. Separating these concerns means each gets proper attention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving dependency challenges
&lt;/h2&gt;

&lt;p&gt;Feature toggles also address one of the most complex problems in microservices: deployment dependencies. Despite the promise of independently deployable services, teams often create elaborate deployment choreographies to ensure services are deployed in a specific order. Sometimes they give up entirely and deploy everything simultaneously. They accept unpredictable behavior during deployment or direct users to a holding page until it's complete.&lt;/p&gt;

&lt;p&gt;When deployments form a chain of dependencies, the architecture isn't truly microservices but a distributed monolith. Real microservices should deploy independently. Feature toggles make this possible. Deploy all services when ready, then switch on functionality once dependencies are in place.&lt;/p&gt;

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

&lt;p&gt;Continuous Delivery isn't just about deploying more often. It's about reducing risk through smaller changes, separating deployment from release, maintaining deployable code at all times, and giving teams the confidence to move quickly and safely.&lt;/p&gt;

&lt;p&gt;The instinct to slow down after problems is natural, but it's counterproductive. The path to safer deployments runs through more frequent deployments, not fewer. Organizations that embrace this counterintuitive truth gain a competitive advantage through faster feedback, lower risk, and ultimately, better software.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>cicd</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Running Astro in a preview container</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Mon, 27 Apr 2026 15:12:52 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/running-astro-in-a-preview-container-2b35</link>
      <guid>https://dev.to/_steve_fenton_/running-astro-in-a-preview-container-2b35</guid>
      <description>&lt;p&gt;If you’ve ever worked on a collection of different Node apps, you’ve likely encountered version conflicts. Everyone wants a different version of Node or PNPM, and your new job is trying to align them all, or managing versions daily.&lt;/p&gt;

&lt;p&gt;That’s when open-source hero Kostis Kapelonis said, “Why don’t we run the preview in a container?” In fact, he didn’t just say this; he also submitted a PR. I told you he’s an open-source hero.&lt;/p&gt;

&lt;p&gt;The PR added a Dockerfile and a docker-compose.yaml file to the project, which let you spin up the preview site using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once Kostis had done all the hard work, I added a small enhancement to make Astro’s live preview work when you change files. That meant you could start the container and keep working while all your changes are instantly visible in the preview. That keeps the developer inner loop nice and tight.&lt;/p&gt;

&lt;p&gt;If you want to do the same, here’s how to make it happen. Once again, I added a very small cherry to Kostis’ wonderfully fluffy cake, so send your adoration his way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a Docker compose file
&lt;/h2&gt;

&lt;p&gt;Here’s the &lt;code&gt;docker-compose.yml&lt;/code&gt; file for your Astro project. It goes in the root directory.&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;astro&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="err"&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;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.:/app&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/app/node_modules&lt;/span&gt;
    &lt;span class="s"&gt;environment&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NODE_ENV=development&lt;/span&gt;
 &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;HOST=0.0.0.0&lt;/span&gt;
    &lt;span class="s"&gt;stdin_open&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="s"&gt;tty&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This maps the volumes, with a special case for node_modules. It exposes Astro’s port &lt;code&gt;3000&lt;/code&gt; inside the container to port 3000 on your machine so you can open it in your browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Docker file
&lt;/h2&gt;

&lt;p&gt;Here’s the &lt;code&gt;Dockerfile&lt;/code&gt;, which also goes in your project’s root directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Use Node 20 as the base image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:20-slim&lt;/span&gt;

&lt;span class="c"&gt;# Install pnpm globally&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PNPM_HOME="/pnpm"&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PATH="$PNPM_HOME:$PATH"&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;corepack &lt;span class="nb"&gt;enable&lt;/span&gt;

&lt;span class="c"&gt;# Set the working directory&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;# Copy package files&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json pnpm-lock.yaml* ./&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Copy the rest of the source code&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;# Expose the default Astro port&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="c"&gt;# Start the dev server&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["pnpm", "compose:dev"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There’s an optimization here around the package files, which is why they get their own copy command. There’s an extra command in the package.json file that we call here, too. It’s a variation of the dev script we use, but switches out the Astro run with a slight variation (the addition of the --host flag) lets just show the important bits in this code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;     
    &lt;/span&gt;&lt;span class="nl"&gt;"compose:dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm-run-all --parallel dev:img dev:dictionary compose:dev:astro dev:watch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"compose:dev:astro"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"astro dev --host"&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;h2&gt;
  
  
  The Vite config change
&lt;/h2&gt;

&lt;p&gt;The final change is the one that makes the live refresh to work. This goes in your astro.config.mjs file, and I popped it right after the existing server config.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nl"&gt;vite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;usePolling&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Spinning it up
&lt;/h2&gt;

&lt;p&gt;The first time I ran this, I started things up with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;--build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then stop the container with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you haven’t changed the container, you can start it with the faster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>astro</category>
    </item>
    <item>
      <title>Developer Productivity in the Age of AI: Why Your Past Predicts Your Future</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Mon, 20 Apr 2026 11:57:29 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/developer-productivity-in-the-age-of-ai-why-your-past-predicts-your-future-i84</link>
      <guid>https://dev.to/_steve_fenton_/developer-productivity-in-the-age-of-ai-why-your-past-predicts-your-future-i84</guid>
      <description>&lt;p&gt;You're looking at a list of things you'd love to do, and you're looking at AI coding tools as a way to boost your way down that list. You might not have the relationships mapped out, but you can see there is some route to value if you spend on LLMs that speed up code.&lt;/p&gt;

&lt;p&gt;You're now in the developer productivity game.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea behind developer productivity
&lt;/h2&gt;

&lt;p&gt;The roots of developer productivity are straightforward. Some smart engineering managers figured out that a small team of developers with the best machines, screens, and development tools could generate value at a rate and quality that far exceeded their "head count". You could also supply all these upgrades to developers at a cost way below the fully loaded cost of 1 more developer.&lt;/p&gt;

&lt;p&gt;The return on investment for this approach was incredible, but traditional engineering managers didn't understand it. They thought developers were asking for more screens because it made them look more important. This emerged from organizations that rewarded managers for empire-building by granting them larger offices with better views.&lt;/p&gt;

&lt;p&gt;I'm a big fan of Ron Westrum's Typology of Organizational Cultures. For this post, though, we'll keep things simple and refer to traditional thinking (keep equipment costs low) and modern thinking (provide high-quality tools).&lt;/p&gt;

&lt;p&gt;We have never shaken off this traditional-versus-modern divide over developer productivity. And now, the subject has returned to the spotlight due to AI and, more specifically, LLM-based coding tools. Your organization's past approach to developer productivity will determine whether you can successfully integrate AI tools into your development teams.&lt;/p&gt;

&lt;p&gt;Let's look at why.&lt;/p&gt;

&lt;h2&gt;
  
  
  A tale of two cities
&lt;/h2&gt;

&lt;p&gt;Traditional organizations operate through control. Managers dictate how work is done, choosing the processes and tools workers must use. Instructions flow downward, and managers define efficiency. Workers are evaluated individually against the manager's prescribed methods, rather than by outcomes.&lt;/p&gt;

&lt;p&gt;Modern organizations operate through trust. Teams choose how to work, selecting from available options or proposing new tools when needs emerge. Authority flows to those closest to the work. Performance is a team sport measured by outcomes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Traditional&lt;/th&gt;
&lt;th&gt;Modern&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Operates through control&lt;/td&gt;
&lt;td&gt;Operates through trust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Efficiency is manager directed&lt;/td&gt;
&lt;td&gt;Productivity is worker-led&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finds the cheapest tools&lt;/td&gt;
&lt;td&gt;Chooses the best tools for each job&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prefers expanding teams&lt;/td&gt;
&lt;td&gt;Prefers small teams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tooling is a cost&lt;/td&gt;
&lt;td&gt;Tooling increases value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance is individual&lt;/td&gt;
&lt;td&gt;Value flows from collaboration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As we experiment with AI coding tools, we are gaining crucial insights. We are developing a better understanding of how much human oversight is needed to successfully and sustainably deliver high-quality software to users. A strong guiding hand is crucial in directing and correcting the output of these tools.&lt;/p&gt;

&lt;p&gt;The value of any software you build, by hand or with assistance, comes from the flow of information. That means listening to software users and collaborating internally. While the code is what gets left behind by the process, it's only an artifact of a more fundamental learning process. The ability to learn and share knowledge will also benefit teams as they discover how to apply AI coding tools to this process.&lt;/p&gt;

&lt;p&gt;It's also clear that Continuous Delivery and automation remain paramount. In the past, automated linting, security scanning, and tests gave us confidence in the code teams wrote; now, they can provide us with confidence in code generated by LLMs. DORA's &lt;a href="https://dora.dev/ai/" rel="noopener noreferrer"&gt;AI Capabilities Model&lt;/a&gt; includes 7 capabilities essential to successful AI adoption, including user-centric focus, strong version control practices, and working in small batches.&lt;/p&gt;

&lt;p&gt;For organizations that haven't adopted Continuous Delivery, rocky shores lie ahead when they unleash AI tools on their codebases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Return on an unspecified investment
&lt;/h2&gt;

&lt;p&gt;Now here's the fascinating conundrum for anyone trying to calculate a return on investment for AI coding tools. The commercial tools indeed remove many tasks that, as a developer, I don't want to do, though they also introduce new ones. I see why people would like to use them to remove much of the noise and focus on the essential details in the software. The problem is, you run out of credits fast, so if you want to use these tools full-time, you'll need subscription levels that support that.&lt;/p&gt;

&lt;p&gt;Credit exhaustion is the first friction point where traditional organizations will come unstuck. Developers who rely heavily on AI coding tools will slow drastically when credits run out. This will likely become a significant problem over time as developers become more dependent on working at the high level of abstraction that prompting offers.&lt;/p&gt;

&lt;p&gt;Imagine if coding languages had similar limits. You'd run out of Python hours and have to continue your work using assembly language.&lt;/p&gt;

&lt;p&gt;Organizations with a cost focus will challenge developers who want a higher budget for these tools. Any manager who has previously denied more screen real estate is likely to reject higher subscription costs for AI coding tools. Their view in both cases is that the promised productivity isn't real.&lt;/p&gt;

&lt;p&gt;The second hurdle for these commercial tools is the uncertain future pricing. We know some AI companies are burning through investment cash, which means the price we pay is subsidized by their desire for growth. There must be a pivot point at which they begin the search for profitability. This will once again trigger problems in cost-focused organizations.&lt;/p&gt;

&lt;p&gt;Some developers are already thinking ahead and looking for open-source models they can run locally to reduce cost uncertainty, but, as always, you pay one way or another. The time spent assessing, updating, and managing these models is a direct loss of the productivity you're trying to gain.&lt;/p&gt;

&lt;p&gt;One solution may be for commercial vendors to offer fixed-price, unlimited use through local models. The challenger to this solution will come from Platform Engineering or DevEx teams, who could supply a packaged open-source local solution for developers to reduce the overhead of selection and maintenance.&lt;/p&gt;

&lt;h2&gt;
  
  
  The nature of problems changes
&lt;/h2&gt;

&lt;p&gt;Traditional and modern organizations face the same challenges, but you can see that culture fundamentally shapes how they are addressed.&lt;/p&gt;

&lt;p&gt;Modern organizations will judge their return on investment by the value they deliver. Their past investments in Continuous Delivery will provide a solid foundation for them to experiment with new tools, and they'll creatively address the cost issues associated with AI coding tools.&lt;/p&gt;

&lt;p&gt;Traditional organizations will seek to minimize costs, avoid investing in automated pipelines, and demand higher developer output with no real basis for expecting it.&lt;/p&gt;

&lt;p&gt;The set of capabilities a modern organization applies to high-throughput, high-quality software delivery is surrounded by subtle, interconnected relationships. For the traditional organizations that just want to "buy AI", the benefits are unlikely to arrive.&lt;/p&gt;

&lt;p&gt;Happy deployments!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>devex</category>
      <category>cicd</category>
    </item>
    <item>
      <title>Setting GitHub as a trusted publisher for npm</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Mon, 13 Apr 2026 13:36:59 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/setting-github-as-a-trusted-publisher-for-npm-560i</link>
      <guid>https://dev.to/_steve_fenton_/setting-github-as-a-trusted-publisher-for-npm-560i</guid>
      <description>&lt;p&gt;So, stuff happened and &lt;strong&gt;npm&lt;/strong&gt; has been updated to reduce the volume of stuff happening. In a world of SBOMs, SLSA, and supply chain attacks, it's time to get serious about publishing packages. In this case, that means using the new &lt;em&gt;Trusted Publisher&lt;/em&gt; feature to connect GitHub (or GitLab) to &lt;strong&gt;npm&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set the trusted publisher on npm
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Sign into &lt;a href="https://npmjs.com" rel="noopener noreferrer"&gt;npm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Select the package you want to set up, for example &lt;code&gt;astro-accelerator-utils&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;Settings&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;em&gt;Trusted Publishers&lt;/em&gt; section, select your provider, in my case it's &lt;strong&gt;GitHub&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enter you repository information:

&lt;ul&gt;
&lt;li&gt;Organization or user name, for example &lt;code&gt;Steve-Fenton&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Repository name, for example &lt;code&gt;astro-accelerator-utils&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The result should be that &lt;code&gt;Steve-Fenton/astro-accelerator-utils&lt;/code&gt; matches your repo in GitHub&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Provide the workflow file name

&lt;ul&gt;
&lt;li&gt;This should match the workflow that will publish the package, in my case &lt;code&gt;build-astro.yml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The file must be in &lt;code&gt;.github/workflows/&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Set up connection&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you use environments, you can optionally limit publishing by environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check you GitHub Action
&lt;/h2&gt;

&lt;p&gt;In your permissions section, you need to allow &lt;code&gt;id-token&lt;/code&gt; to be written.&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;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;id-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then use the &lt;code&gt;npm publish&lt;/code&gt; step in your workflow.&lt;/p&gt;

&lt;p&gt;I conditionally publish based on the version number, so I only publish when the version number changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Publish if version has been updated&lt;/span&gt;
    &lt;span class="s"&gt;env&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;NPM_AUTH_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.NPM_AUTH_TOKEN }}&lt;/span&gt;
    &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;PACKAGE_NAME=$(node -p "require('./package.json').name")&lt;/span&gt;
        &lt;span class="s"&gt;LOCAL_VERSION=$(node -p "require('./package.json').version")&lt;/span&gt;
        &lt;span class="s"&gt;REMOTE_VERSION=$(npm view $PACKAGE_NAME version || echo "0.0.0")&lt;/span&gt;

        &lt;span class="s"&gt;if [ "$LOCAL_VERSION" != "$REMOTE_VERSION" ] &amp;amp;&amp;amp; [ "$(printf '%s\n%s' "$REMOTE_VERSION" "$LOCAL_VERSION" | sort -V | tail -n1)" = "$LOCAL_VERSION" ]; then&lt;/span&gt;
        &lt;span class="s"&gt;echo "Local version $LOCAL_VERSION is higher than remote version $REMOTE_VERSION. Publishing..."&lt;/span&gt;
        &lt;span class="s"&gt;echo "//registry.npmjs.org/:_authToken=$NPM_AUTH_TOKEN" &amp;gt; ~/.npmrc&lt;/span&gt;
        &lt;span class="s"&gt;npm publish --access public&lt;/span&gt;
        &lt;span class="s"&gt;else&lt;/span&gt;
        &lt;span class="s"&gt;echo "Version $LOCAL_VERSION is not newer than $REMOTE_VERSION. Skipping publish."&lt;/span&gt;
        &lt;span class="s"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a more secure way to publish npm packages, but it's also easier because you don't need to keep updating tokens and secrets.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>npm</category>
      <category>github</category>
    </item>
    <item>
      <title>Roll up your chair: How one small change sparked a DevOps revolution</title>
      <dc:creator>Steve Fenton</dc:creator>
      <pubDate>Tue, 31 Mar 2026 09:22:47 +0000</pubDate>
      <link>https://dev.to/_steve_fenton_/roll-up-your-chair-how-one-small-change-sparked-a-devops-revolution-33p4</link>
      <guid>https://dev.to/_steve_fenton_/roll-up-your-chair-how-one-small-change-sparked-a-devops-revolution-33p4</guid>
      <description>&lt;p&gt;My first encounter with DevOps was so simple that I didn’t even realize its power. Let me share the story so you can see how it went from accidental discovery to deliberate practice, and why it was such a dramatic pivot.&lt;/p&gt;

&lt;p&gt;The backdrop to this pivotal moment was a software delivery setup you might find anywhere. The development team built software in a reasonably iterative and incremental fashion. About once a month, the developers created a gold copy and passed it to the ops team.&lt;/p&gt;

&lt;p&gt;The ops team installed the software on our office instance (we drank our own champagne). After two weeks of smooth running, they promoted the version to customer instances.&lt;/p&gt;

&lt;p&gt;It wasn’t a perfect process, but it benefited from muscle memory, so there wasn’t an urgent imperative to change it. The realization that a change was needed came from the first DevOps moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The unplanned first moment
&lt;/h2&gt;

&lt;p&gt;When the ops team deployed the new version, they would review the logs to see if anything interesting or unexpected popped up as a result of the deployment. If they found something, they couldn’t get a quick answer, and it sometimes meant they opted to roll back rather than wait.&lt;/p&gt;

&lt;p&gt;This was a comic-strip situation because the development team was a few meters away in their team room. It’s incredible how something as simple as a door transforms co-located teams into remote workers.&lt;/p&gt;

&lt;p&gt;The ops team raised their request through official channels, and the developers didn’t even know they were causing more work and stress because the ticket hadn’t reached them yet.&lt;/p&gt;

&lt;p&gt;Thankfully, one of the ops team members highlighted this. The next time they started a deployment, a developer was paired with them to watch the logs. A low-fi solution and not one you’d think much about. That developer was me. For this post, we’ll call my ops team partner “Tony”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared surprises lead to learning
&lt;/h2&gt;

&lt;p&gt;The day-one experience of this new collaborative process didn’t seem groundbreaking. When a log message popped up that surprised Tony, it surprised me too. The messages weren’t any more helpful to a developer than they were to the ops team.&lt;/p&gt;

&lt;p&gt;I could think through what might be happening, talk it through, and then Tony and I would come up with a theory. We’d test the theory by trying to make another similar log message appear. Then we’d scratch our heads and try to decide whether this could wait for a fix or warranted a rollback.&lt;/p&gt;

&lt;p&gt;The plan to bring people from the two teams together was intended to remove the massive communication lag, and it did. But further improvements were to come as a side effect, yielding more significant gains.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resolve pain pathways by completing the loop
&lt;/h2&gt;

&lt;p&gt;As a developer, when you generate log messages and then have to interpret them, you’ve completed a pain loop. Pain loops are potent drivers of improvement.&lt;/p&gt;

&lt;p&gt;Most organizations have unresolved pain pathways. That means someone creates pain, like a developer throwing thousands of vague exceptions every minute, and then someone else feels it, like Tony when he’s trying to work out what the log means.&lt;/p&gt;

&lt;p&gt;There are two ways to resolve the pain pathway.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Process: You create procedures to bring pain below the threshold and to limit the rate at which it is generated.&lt;/li&gt;
&lt;li&gt;Loops: You connect the pain into a loop, so the person causing the pain feels its signal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I’m the one who gets the electric shock when I press the button, I stop pushing it, even if someone in a white coat instructs me to continue the experiment.&lt;/p&gt;

&lt;p&gt;With the pain loop connected, I realized we should log fewer messages to reduce the scroll and review burden. Instead of needing institutional knowledge of which messages were perpetually present and could therefore be ignored, we could stop logging them.&lt;/p&gt;

&lt;p&gt;The (perhaps asymptotic) goal was to log only the events that required human review, with a toggle that let more verbose logging be generated on demand. Instead of scrolling through a near-infinite list of logs, you’d have a nearly empty view. If a log appeared, it was important enough to warrant your attention.&lt;/p&gt;

&lt;p&gt;The next idea was to improve the information in the log messages. We could identify which customer or user experienced the error and provide context for it. By improving these error messages, we could often identify the bug before we even opened the code, dramatically reducing our investigation time.&lt;/p&gt;

&lt;p&gt;This process evolved into &lt;a href="https://stevefenton.co.uk/blog/2017/11/the-three-fs-of-event-log-monitoring/" rel="noopener noreferrer"&gt;the three Fs of event logging&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create positive spirals with delightful deployments
&lt;/h2&gt;

&lt;p&gt;Another thread that emerged from the simple act of sitting together during deployments was the realization that the deployment process was nasty. We created an installer file, and the ops team would move it to the target server, double-click it, then follow the prompts to configure the instance.&lt;/p&gt;

&lt;p&gt;Having to paste configuration values into the installer was slow and error-prone. We spent a disproportionate amount of time improving this process.&lt;/p&gt;

&lt;p&gt;Admittedly, we were solving this one “inside the box” by improving an individual installation with DIY scripts, a can of lubricating spray, and sticky tape. This didn’t improve the experience of repeating the install across several environments and multiple production instances.&lt;br&gt;
However, I did get to experience the stress of deployments when their probability of success was anything less than “very high”. When deployments weren’t a solved problem, they could damage team reputation, erode trust, and reduce autonomy.&lt;/p&gt;

&lt;p&gt;Failed deployments are the leading cause of organizations working in larger batches. Large batches are a leading cause of failed deployments. This is politely called a negative spiral, and you have to reverse it urgently if you want to survive.&lt;/p&gt;

&lt;h2&gt;
  
  
  At last, a panacea
&lt;/h2&gt;

&lt;p&gt;The act of sitting a developer with an ops team member during deployments isn’t going to solve all your problems. As we scaled from 6 to 30 developers, pursued innovative new directions for our product, and repositioned our offering and pricing, new pain kept emerging. Continuous improvement really is a game of whack-a-mole, and there’s no final state.&lt;/p&gt;

&lt;p&gt;Despite this, the simple act of sitting together, otherwise known as collaboration, caused a chain reaction of beneficial changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sharing goals and pain
&lt;/h3&gt;

&lt;p&gt;When you’re sitting with someone working on the same problem, all the departmental otherness evaporates. You’re just two humans trying to make things work.&lt;/p&gt;

&lt;p&gt;Instead of holding developers accountable for feature throughput and the ops team for stability, we shared a combined goal of high throughput and high stability in software delivery.&lt;/p&gt;

&lt;p&gt;That removed the goal conflict and encouraged us to share and solve common problems together. This also works when you repeat the alignment exercise with other areas, like compliance and finance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Completing the pain loop
&lt;/h3&gt;

&lt;p&gt;The problem with our logging strategy was immediately apparent when one of the people generating the logs had to wade through them. This is a powerful motivator for change.&lt;/p&gt;

&lt;p&gt;Identifying unresolved pain paths and closing the pain loop isn’t a form of punishment; it’s a moment of realization. It’s the reason we should all use the software we build: it highlights the unresolved pain paths we’re burdening our users with.&lt;/p&gt;

&lt;p&gt;Pain loops are crucial to meaningful improvements in software delivery.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reducing the toil
&lt;/h3&gt;

&lt;p&gt;Great developers are experts at automating things. When you expose this skill set to repetitive work, a developer’s instinct is to eliminate the toil.&lt;/p&gt;

&lt;p&gt;For the ops team, the step-by-step deployment checklist was just part of doing business. They were so familiar with the process that it became invisible.&lt;/p&gt;

&lt;p&gt;When we reduced the toil, the ops team was definitely happier, even though we hadn’t solved all the rough edges yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refining the early ideas
&lt;/h2&gt;

&lt;p&gt;The fully-formed ideas didn’t arrive immediately. The rough shapes were polished over time into a set of repeatable and connected DevOps habits.&lt;/p&gt;

&lt;p&gt;The three Fs, incident causation principles, alerting strategy, and monitor selection guidelines graduated into deliberate approaches long after this story.&lt;/p&gt;

&lt;p&gt;I developed an approach to software delivery improvement that used these ideas to address trust issues between developers and the business. By reducing negative signals caused by failed deployments and escaped bugs, we increased trust in the development team, enhanced their reputation, and increased their autonomy.&lt;/p&gt;

&lt;p&gt;We combined these practices with Octopus Deploy for deployment and runbook automation and an observability platform, which meant the team was the first to spot problems rather than users. When there was a problem, it was trivial to fix, and the new version could be rolled out in no time.&lt;/p&gt;

&lt;p&gt;Unlike the original organization, where we increased collaboration between teams, we created fully cross-functional teams that worked together all the time. Every skill required to deliver and operate the software was embedded, minimizing dependencies and the risk of silos, tickets, and bureaucracy.&lt;/p&gt;

&lt;p&gt;These cross-functional teams also proved to be the best way to level up team members.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unicorn portals
&lt;/h2&gt;

&lt;p&gt;You can’t work with a database whizz for long before you start thinking about query performance, maintenance plans, and normalization. You build better software when you develop these skills. You can’t work with an infrastructure expert without learning about failovers, networking, and zero-downtime deployments. You build better software when you develop these skills, too.&lt;/p&gt;

&lt;p&gt;When people say they can’t hire these highly skilled developers, they miss the crucial point. A team designed in this cross-functional style takes new team members and upgrades them into these impossible-to-find unicorns. You may start as a backend developer, a database administrator, or a test analyst, but you grow into a generalizing specialist with many new skills.&lt;/p&gt;

&lt;p&gt;Creating these unicorn portals is the most valuable skill development managers can bring to an organization. You need to hire to fill gaps and foster an environment where skills transfer fluidly throughout the team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Roll up your chair
&lt;/h2&gt;

&lt;p&gt;What became a sophisticated and repeatable process for team transformation could be traced back to that simple act of sitting together. It was a small, easy change that led to increased empathy and understanding, and then a whole set of improvements.&lt;/p&gt;

&lt;p&gt;Staring at that rapid stream of logs was the pivot point that led to the most healthy and human approach to DevOps.&lt;/p&gt;

&lt;p&gt;We didn’t have the research to confirm it back then, but deployment automation, shared goals, observability, small batches, and Continuous Delivery are all linked to better outcomes for the people, teams, and organization. Everybody wins when you do DevOps right.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>software</category>
      <category>culture</category>
    </item>
  </channel>
</rss>
