Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
156890 stories
·
33 followers

From Staying in Your Line to The Connected Product Owner—Two Patterns Every Scrum Master Should Recognize | Gunnar Fischer

1 Share

Gunnar Fischer: From Staying in Your Line to The Connected Product Owner—Two Patterns Every Scrum Master Should Recognize

The Great Product Owner: The Connected PO Who Makes Information Flow

Read the full Show Notes and search through the world's largest audio library on Agile and Scrum directly on the Scrum Master Toolbox Podcast website: http://bit.ly/SMTP_ShowNotes.

 

"This Product Owner didn't need to be the smartest person in the room, but everybody knew, okay, this is a really smart guy." - Gunnar Fischer

 

The best Product Owner Gunnar ever worked with was what he calls the connected PO. This person had a deep professional network—inside the company and with the customer—and could talk to anyone: a colleague, the client, a brand-new team member they were onboarding. They were socially sharp without being shallow. They could disagree clearly, even harshly, and then turn around and say, "now let's talk about something else," with kindness. When this PO said no, it was a no people respected; when they said yes, it was a yes people trusted, because everyone knew the PO could push back. The praise behind their back matched the praise in the room. They had a private life, too—not married to the job, which made them a more well-rounded human. But the specifically Product Owner skill Gunnar names is this: they could look at the product across different time horizons—what does it need to do in one month, three months, one year—and they kept juggling functionality, contracts, customer situation, and economic reality at the same time. Their technical background helped, but they understood the line: "It's not my job to be the technically most savvy guy, but I'm willing to share my knowledge with everybody." As Gunnar puts it, the difference between a subject matter expert and a Product Owner is that the Product Owner makes the information flow.

 

Self-reflection Question: Does your Product Owner make information flow across the team, the customer, and management—or are they hoarding context as the "expert"?

The Bad Product Owner: The Stay-in-Your-Line, Accept-Your-Fate PO

Read the full Show Notes and search through the world's largest audio library on Agile and Scrum directly on the Scrum Master Toolbox Podcast website: http://bit.ly/SMTP_ShowNotes.

 

"You manage the backlog, you do the customer calls, you write the user stories—but you were not involved in any of the bigger decisions." - Gunnar Fischer

 

The anti-pattern Gunnar sees most often isn't malice—it's resignation. Most Product Owners aren't given the access or the permissions they need to be successful, and so they accept their fate. They manage the backlog, take the customer calls, write the user stories, sometimes talk to management—but they aren't part of the bigger decisions: ROI on a feature, whether to build it at all, the product vision a year out. Management keeps those decisions to itself, and the accept-your-fate PO doesn't challenge that arrangement. They stay in their line. They don't push back when sales drops in an urgent request that ruins the plan. They don't challenge the developers when an estimate feels wrong. They become very protective of the things they can control—their privileges, their processes, the artifacts—and when the bad times come, they get thrown under the bus. Gunnar's diagnosis is direct: the role of a great PO is to have constructive, respectful disagreements at every level—with the client, with management, with the team—and to be okay disappointing people. "Once you see that people go down to the mechanics, then it's a really bad smell, I would say." Saying yes to everything doesn't make you safe; it makes you replaceable.

 

In this segment, we refer to Geoff Watts' Scrum Mastery and its line about the great Scrum Master being dispensable and wanted—a frame that applies to Product Owners just as well.

 

Self-reflection Question: Where in the past month did your Product Owner say "yes" when the right answer was a respectful "no, not yet"?

 

[The Scrum Master Toolbox Podcast Recommends]

🔥In the ruthless world of fintech, success isn't just about innovation—it's about coaching!🔥

Angela thought she was just there to coach a team. But now, she's caught in the middle of a corporate espionage drama that could make or break the future of digital banking. Can she help the team regain their mojo and outwit their rivals, or will the competition crush their ambitions? As alliances shift and the pressure builds, one thing becomes clear: this isn't just about the product—it's about the people.

 

🚨 Will Angela's coaching be enough? Find out in Shift: From Product to People—the gripping story of high-stakes innovation and corporate intrigue.

 

Buy Now on Amazon

 

[The Scrum Master Toolbox Podcast Recommends]

 

About Gunnar Fischer

 

Gunnar is the leader of the Chocolate Guild. Agile practitioner with a software developer background and a strong interest in people, intercultural contacts and the bigger picture. Gunnar's purpose is to teach and to learn, to grow as a person and to support others who want the same.

 

You can link with Gunnar Fischer on LinkedIn.

 

You can also read Gunnar's writing on his blog, Leader of the Chocolate Guild.





Download audio: https://traffic.libsyn.com/secure/scrummastertoolbox/20260703_Gunnar_Fischer_F.mp3?dest-id=246429
Read the whole story
alvinashcraft
24 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Episode 579: The Headless Lifestyle

1 Share

This week, we discuss Anthropic's 18-day Fable timeout, whether AI is actually killing jobs, and OpenAI's trillion-dollar IPO problem. Plus, SoftBank's golden goose slides.

Watch the YouTube Live Recording of Episode 579

Runner-up Titles

  • Everything is Files
  • It’s just about meetings
  • Did you do the pre-meet?
  • Meetings
  • Judgement
  • Let it ride
  • If it’s hot, turn on the AC
  • I don’t have time for a towel.
  • Headless HEB

Rundown

Relevant to your Interests

Listener Feedback

Conferences

SDT News & Community

Recommendations





Download audio: https://aphid.fireside.fm/d/1437767933/9b74150b-3553-49dc-8332-f89bbbba9f92/bbe440e0-fec2-493a-bc1f-60ab12c41363.mp3
Read the whole story
alvinashcraft
31 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Switching the Aspire Community Toolkit to NuGet Trusted Publishing

1 Share

Recently I had to fix something that had become a bit too easy to ignore in the Aspire Community Toolkit: our NuGet publishing in CI had started failing, and the fix I wanted wasn’t “rotate the key and hope for the best.” If I was going to touch the release pipeline anyway, I wanted to move us onto NuGet’s newer trusted publishing model and stop depending on a long-lived API key stored in GitHub secrets.

That meant updating the workflows that publish our beta and stable packages: .github/workflows/dotnet-main.yml and .github/workflows/dotnet-release.yml. In our case those map to separate GitHub Environments as well, nuget-beta for mainline builds and nuget-stable for releases, so the supporting configuration needed to line up for both the beta path and the stable release path.

What we were changing

The old model was the familiar one:

1
2
- name: Publish to NuGet
  run: dotnet nuget push ./*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{ secrets.NUGET_PACKAGE_PUSH_TOKEN }}

It works until it doesn’t. Keys expire, get rotated, get copied around, or just become another piece of release infrastructure that nobody wants to touch because if it breaks you find out at the worst possible moment.

Trusted publishing is a much nicer fit for GitHub Actions. Instead of pre-provisioning a long-lived API key, the workflow exchanges GitHub’s OIDC token for a short-lived NuGet API key at runtime. So the runner only gets credentials for the duration of that job, and only if the workflow matches the trust policy configured in nuget.org.

The workflow changes

One detail that I think is worth calling out: we only changed the publish-nuget job in each workflow. The rest of dotnet-main.yml and dotnet-release.yml stayed exactly as they were. That made it much easier to reason about the migration because we were only changing the authentication mechanism, not refactoring the whole release pipeline at the same time.

The heart of the change was pretty small.

First, the publishing job needs permission to request an OIDC token:

1
2
3
4
5
publish-nuget:
  runs-on: ubuntu-latest
  permissions:
    id-token: write
    contents: read

That id-token: write permission is the important one. Without it, GitHub won’t mint the OIDC token that NuGet/login needs.

Then I replaced the static API key with NuGet/login@v1:

1
2
3
4
5
6
7
8
- name: NuGet login (OIDC)
  id: login
  uses: NuGet/login@v1
  with:
    user: ${{ secrets.NUGET_USER }}

- name: Publish to NuGet
  run: dotnet nuget push ./*.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{ steps.login.outputs.NUGET_API_KEY }} --skip-duplicate

There are two details here that are easy to miss:

  1. NuGet/login still wants a username, so I added a NUGET_USER secret to the GitHub Environment used by the publishing job (nuget-beta for the main workflow and nuget-stable for the release workflow in our case). That value should be your existing nuget.org username, not some new service account you invent for the migration.
  2. The API key now comes from ${{ steps.login.outputs.NUGET_API_KEY }}, which is short-lived and scoped to that workflow run.

I also added --skip-duplicate, because package publishing jobs are exactly the sort of thing you end up re-running after fixing an unrelated failure. If the package is already on nuget.org, I want the rerun to be boring, not fatal.

The setup detail that bit me

The part that matters most isn’t actually in GitHub, it’s in nuget.org.

When you create the trusted publishing policy for a package, nuget.org wants to know exactly which GitHub repository and workflow file are allowed to publish it. And “exactly” really does mean exactly. The policy has to match the workflow filename, not just the repository or a rough pattern.

So if your beta packages are published by .github/workflows/dotnet-main.yml, that exact workflow path needs to be in the nuget.org policy for the nuget-beta environment. If your stable packages are published by .github/workflows/dotnet-release.yml, that needs its own matching policy for nuget-stable as well.

This is where I think people are most likely to get tripped up. It’s easy to assume that “the repo is trusted” or “the workflow name is close enough.” It isn’t. If the filename in nuget.org doesn’t match the workflow that’s actually running, the login step won’t be able to exchange the OIDC token for a NuGet API key.

Why I kept the old path around

I didn’t want to flip both publishing paths over and immediately delete the old secret-based setup.

Instead, I treated the beta flow as the proving ground. Once the trusted publishing path succeeded there, I had much higher confidence applying the same pattern to the stable release workflow. That’s also why I recommend keeping the old API key path available until you’ve seen the new flow complete successfully at least once.

The failure mode for trusted publishing is usually configuration, not code:

  • the wrong workflow filename in nuget.org
  • the wrong repository bound to the policy
  • missing id-token: write
  • forgetting the NUGET_USER environment secret
  • setting NUGET_USER to the wrong account name

Those are all easy mistakes to make, and much easier to recover from if you haven’t immediately torn out the previous publishing path.

For the same reason, I strongly recommend treating the old secret as a temporary safety net. Once you remove the old API-key-based path, getting back to a known-good state is a lot more annoying than just leaving it alone until the trusted publishing path has proved itself.

The practical setup checklist

If you’re doing this yourself, here’s the checklist I wish I’d had up front:

  1. Create a trusted publishing policy in nuget.org for each package flow you want to support.
  2. Make sure the policy references the exact GitHub repository and exact workflow filename.
  3. Add id-token: write to the publish job permissions.
  4. Add a NUGET_USER secret to the GitHub Environment used by that job.
  5. Use NuGet/login@v1 and publish with ${{ steps.login.outputs.NUGET_API_KEY }}.
  6. Add --skip-duplicate so reruns don’t fail unnecessarily.
  7. Keep the old API-key-based path around until the new flow has succeeded end-to-end.

How I validated it before the first publish

Before trusting the workflow change, I wanted to know that package creation itself wasn’t going to be the thing that failed. The local command I used for that sanity check was:

1
dotnet pack -c Release -o ./artifacts

That obviously doesn’t test the OIDC exchange with nuget.org, but it does confirm that the package output you’re about to hand to the workflow is sound. When you’re changing release automation, separating “can I create the package?” from “can the runner authenticate?” is a useful way to keep the blast radius small.

Why this is better

The immediate win was getting our CI publishing working again, but the longer-term improvement is operational. We no longer have a long-lived NuGet push key sitting around as a secret that we need to manage manually. Publishing is now tied to the workflow identity itself, which is exactly what I want for release automation.

It’s one of those changes that’s not especially flashy when you look at the diff, but it meaningfully tightens the supply chain story around package publishing. And if you’re already on GitHub Actions, it’s a pretty natural upgrade once you know where the sharp edges are.

If you want to see what this looked like in practice, the beta migration landed first in PR #1452, and the stable release follow-up went into PR #1453. That sequencing was deliberate: prove the pattern on the beta path, then roll it forward to the stable one once the moving parts were understood.

Honestly, the biggest lesson from this migration was that the YAML change is the easy part. The real work is making sure GitHub, nuget.org, and your workflow filenames all agree on who is allowed to publish what.

Read the whole story
alvinashcraft
55 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

DWX 2026 Wrap-Up: Four Days of Innovation, Conversations, and Enterprise Document Solutions

1 Share
DWX 2026 was a great success for Text Control. We had the opportunity to meet with many developers, discuss document processing solutions, and showcase our latest innovations in document technology. In this wrap-up, we share our experiences and insights from the event.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

Octopus Easy Mode - Ephemeral Environments

1 Share

In the previous post, you created a functional Kubernetes deployment project. In this post, you’ll create Ephemeral Environments to simulate the deployment of feature branches.

Prerequisites

  • An Octopus Cloud account. If you don’t have one, you can sign up for a free trial.
  • The Octopus AI Assistant Chrome extension. You can install it from the Chrome Web Store.

The Octopus AI Assistant will work with an on-premises Octopus instance, but it requires more configuration. The cloud-hosted version of Octopus doesn’t need extra configuration. This means the cloud-hosted version is the easiest way to get started.

Creating the project

Ephemeral environments support the creation and destruction of short-lived environments and their associated resources. These environments are often used to deploy feature-branch builds, allowing developers to interact with their work before it is merged into a mainline branch.

Paste the following prompt into the Octopus AI Assistant and run it:

Create a Kubernetes project called "K8s Web App with Ephemeral Environments", and then:
* Use client side apply in the Kubernetes step (the mock Kubernetes cluster only supports client side apply).
* Disable verification checks in the Kubernetes steps (the mock Kubernetes cluster doesn't support verification checks).
* Enable retries on the K8s deployment step.
* Add support for ephemeral environments, with the Parent Environment and Ephemeral Environment channel both called "Features"

---

Create a token account called "Mock Token".

---

Create a feed called "Docker Hub" pointing to "https://index.docker.io" using anonymous authentication.

---

Create a Kubernetes target with the tag "Kubernetes", the URL https://mockk8s.octopusdemos.com, attach it to the "Development", "Test", "Production" environments and the "Features" parent environment, using the health check container image "octopusdeploy/worker-tools:6.5.0-ubuntu.22.04" from the "Docker Hub" feed, using the token account, and the "Hosted Ubuntu" worker pool.

The document separator (---) is used to split the prompt into multiple sections. Each section is applied sequentially, which allows you to create different types of resources in a single prompt.

As we did in the last post, the AI Assistant creates a functional Kubernetes project pointing to a mock Kubernetes server.

We then added support for ephemeral environments, which requires:

  • A parent environment called Features
  • A channel that deploys to ephemeral environments, also called Features

Parent Environment Channel

Create a new deployment of the project, select the Features channel, and define the FeatureBranch custom field to the name of a feature branch like features/font-change:

New Release

The value assigned to the custom field is used as the name for the new environment. Any invalid characters, like the backslash, are automatically sanitized to provide a valid environment name.

The deployment is visible in the Ephemeral Environments section:

Ephemeral Environments

Because the Kubernetes step is configured to deploy resources to the namespace #{Octopus.Environment.Name | ToLower}, the ephemeral deployment creates resources in a namespace based on the ephemeral environment name, keeping it separate from the traditional deployments to the Development, Test, and Production environments.

You’ll also notice that the Kubernetes target was selected for the deployment because it was attached to the parent Features environment. This demonstrates how durable Octopus resources are linked to ephemeral environment deployments.

Runbooks can be used for those scenarios where you need to provision and deprovision the environment.

Run the following prompt to add two runbooks to the project:

Create a runbook called "Provision Environment" in the project "K8s Web App with Ephemeral Environments".
Allow the runbook to be run from the "Features" environment.
Add a "Run a kubectl script" step run against the target tag "Kubernetes" and echo the text "Provisioning the environment" from a bash script.
Run the step from the "Hosted Ubuntu" worker pool.

---

Create a runbook called "Deprovision Environment" in the project "K8s Web App with Ephemeral Environments".
Allow the runbook to be run from the "Features" environment.
Add a "Run a kubectl script" step run against the target tag "Kubernetes" and echo the text "Deprovisioning the environment" from a bash script.
Run the step from the "Hosted Ubuntu" worker pool.

In the Ephemeral Environments project section, open the Settings tab, and select the new runbooks from the Provisioning runbook and Deprovisioning runbook fields:

Ephemeral Environments Runbooks

Both runbooks must have a published snapshot. Open each runbook, click the Publish button, and click the Publish button again:

Publish Runbooks

Now, when you deploy to an ephemeral environment, the Provision Environment runbook is executed. After one week, the Deprovision Environment runbook is automatically executed, or you can manually deprovision an environment in the Ephemeral Environments section under the Overview tab:

Deprovision Environment

What just happened?

You created a sample Kubernetes project with:

  • A channel called Features to deploy to an ephemeral environment based on a custom field value
  • A Parent Environment called Features
  • A Kubernetes target linked to the Features parent environment
  • Two runbooks: one to provision the ephemeral environment, and another to deprovision it
Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

Code review is theater now

1 Share

Back in March, Gene Kim shared a conversation he had with Jez Humble on LinkedIn. Jez made a beautifully sarcastic remark:

Don’t worry about code reviews, Gene. Code reviews and approvals have always involved a lot of theater. We just need to perpetuate that illusion a little longer and keep pretending that humans are actually reviewing all that agent-generated code.

Jez is absolutely right; code reviews do involve a lot of theater. Especially now in the era of AI-generated code. In the short amount of time since this post, this trend has become more pronounced. Code review used to be considered a solid approach to ensuring quality and compliance. It just isn’t anymore, and we need to be honest about its effectiveness for development teams today.

The chocolate belt wrappers

Consider the all-too-familiar process of reviewing a pull request (PR). The notification bell icon lights up, indicating that you have something to review. You open it, review the code, slap “LGTM” on it, and click “approve.” It compiles. Ship it.

Now consider the scenario in which agents write the majority of the PRs. You probably know how this ends up if you’ve ever seen the “Job Switching” episode of I Love Lucy.

Lucy and Ethel wrapping chocolates

In the episode, Lucy and Ethel take jobs on an assembly line wrapping chocolates. Everything starts fine until then the belt speeds up. Lucy and Ethel can’t keep pace, so they start hiding chocolates wherever they can. The chocolates keep coming. The wrapping of chocolates, what we call code review, becomes theater.

In our world, these chocolates are PRs, AI coding agents are the belt, and code review is Lucy, frantically trying to keep up while the quality of what’s getting through drops with every passing minute. A lot of what’s coming off that belt can be slop. It compiles. (Or, sometimes not.) If you’re lucky, it passes your test matrix. Looking closely at the code, it looks fine until you realize the model copied a pattern from its training data that doesn’t actually fit your problem. The person reviewing would likely not realize this. The reviewer would likely check whether the syntax and structure are correct, not whether the code should exist in the first place.

Agents can produce huge chunks of code in the time it takes to read this sentence. The PRs reflect this. Now consider the burden this places on a reviewer. Is it reasonable to evaluate a 40,000-line change? Does it get better if we atomize it into 4,000 tiny 10-line diffs? You can read each diff and still miss whether it’s the right change. That’s because you weren’t part of the reasoning that produced it. You have no context whatsoever. It’s like flipping to the middle of a book and claiming you know where you are in the story.

Yes, AI makes producing code much, much faster. However, reviewing that code has become much, much harder. As an industry, we tout and celebrate the speed. But we don’t talk about the PRs piling up, putting everyone downstream under pressure.

The chocolate belt speeds up

If you take a look at the 2026 DORA report, 90% of developers now use AI tools at work. Developers are spending 2+ hours a day with these tools, completing 21% more tasks and merging 98% more pull requests.

With great power comes great responsibility. The average number of bugs per developer is up 54%. Faros AI’s analysis of 10,000+ developers found incidents per pull request are up 242.7%. We’ve essentially doubled our merge rates while breaking things three times as often. We see the impact of AI-generated code in our own data, too. Our 2026 AI Pulse report found that AI reduces task hours across every part of the delivery pipeline except for code review. 72% of developers use AI to write code, but only 56% bother using it for their reviews. The chocolate belt is accelerating, and Lucy and Ethel are starting to look nervous.

To be fair, Daniel Stenberg, the creator of curl, recently noted that AI-generated contributions have gone from slop to genuinely good. Problem solved, right? Not quite. PRs are arriving faster than his team can review them. We have better chocolates, but the same belt speed problem. Our review queue is starting to resemble a backlog.

So what do we do about it? The prevailing sentiment right now is to chuck AI at the review problem, too. Make Ethel check Lucy’s work. But think about that. They’re standing at the same belt and they’ve trained on the same data. They have the same blind spots. “AI reviewed it so we’re good” is the new “the dog ate my homework.” Except now the dog wrote the homework, ate it, barfed it up, and gave it an A+.

That’s the real takeaway from the DORA data. AI is an amplifier. It can amplify our intelligence or our stupidity. We need to be careful. Right now, a lot of us have the chocolate belt of PRs cranked up to full speed.

Enter the wrapping machine

The chocolate belt does exactly what it’s supposed to do. The wrapping process (code review) is what failed. And the fix has been staring us in the face since the Continuous Delivery (CD) movement began. Our deployment pipeline is the assurance mechanism, not the human with the approve button. If quality and security requirements are missing from the pipeline as automated checks, code review will never ensure they are met. We are simply hoping that a human – somewhere in the chain – might catch the problem.

Yes, we still need people who can look at a system and say, “This is the wrong approach.” That’s not going away. But we’re expecting that same person also to be the last line of defense against every bug and every security gap in every deployment. That was never going to work. We just didn’t have a reason to admit it until now.

What’s actually in the chocolate

Let’s stop pretending code review is something it isn’t.

Code review is great for knowledge sharing and catching design-level issues. But it’s horrible at catching every bug in a 40,000-line diff. Bugs matter when code is shipping to production.

So the question we should be asking ourselves isn’t “how do we make code review scale?” It’s “how do we build a pipeline that can verify what it’s shipping, regardless of who or what wrote the code?”

Policy-as-code is one way to get there. We write rules that define our deployment standards, and the pipeline checks every deployment against them. The developer sees what went wrong and how to fix it. There’s no waiting around for someone to review a diff.

Learning to wrap chocolate

It would be foolish of me not to mention the fact that there’s something a chocolate wrapping machine can’t teach you. And that’s the process of wrapping chocolate. In our world, that’s the act of conducting a code review. It’s how junior engineers develop judgment.

Mentorship comes from reading other people’s code, getting feedback on your own, and absorbing the unwritten reasons behind certain decisions. That pipeline is already breaking. 73% of organizations have reduced junior developer hiring in the past two years. Junior devs dropped from 32.8% to 24.8% of Stack Overflow respondents between 2024 and 2025. If we let that continue without figuring out another way for juniors to learn, we’re in trouble. We end up with a generation of engineers who can prompt effectively but can’t reason about a system’s design.

I’m not saying we need to remove code review. But we need to stop kidding ourselves that it’s the all-seeing, all-knowing quality gate we’ve built it up to be.

Wrapping up

To reiterate, Jez was right. Code review has worked well enough when humans are involved in the volume of code being reviewed. It was good enough when a team merged a handful of PRs a day. However, it’s not good enough when AI is generating them.

The answer isn’t a better performance. It’s a better pipeline. One that can prove our software works before it hits production. The CD community has been saying this for years. Most of us just didn’t have a reason urgent enough to listen. But with the advent of AI and code generation, we’re now compelled to.

If our quality gates live in our pipeline, it doesn’t matter whether the code was written by a human, an AI, or a very determined cat walking across a keyboard.

If the quality of our code reviews is determined by a human’s abilities, we’re in trouble, because AI sped up the belt, and the chocolates aren’t going to wrap themselves.

Happy deployments!

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories