<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://rogernoden.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://rogernoden.com/" rel="alternate" type="text/html" /><updated>2026-06-25T05:05:50-05:00</updated><id>https://rogernoden.com/feed.xml</id><title type="html">Rōger Nōden</title><subtitle>An amazing website.</subtitle><author><name>Rōger Nōden</name></author><entry><title type="html">The Patterns Didn’t Go Away. You Stopped Asking for Them.</title><link href="https://rogernoden.com/2026/06/patterns-didnt-go-away/" rel="alternate" type="text/html" title="The Patterns Didn’t Go Away. You Stopped Asking for Them." /><published>2026-06-22T00:00:00-05:00</published><updated>2026-06-22T00:00:00-05:00</updated><id>https://rogernoden.com/2026/06/patterns-didnt-go-away</id><content type="html" xml:base="https://rogernoden.com/2026/06/patterns-didnt-go-away/"><![CDATA[<p>Two posts crossed my feed the same week, from people who don’t know each other,
making what looked like opposite arguments. They were actually making the same
one.</p>

<p>The first was a study. Stephen Poletto’s team at Span looked at <strong>248,099 pull
requests and 65,697 production incidents</strong> and went hunting for the headline
everyone expects by now: <em>does AI write buggier code?</em> They couldn’t find it.
AI authorship, on its own, wasn’t a statistically significant driver of defect
rate. The teams shipping AI-assisted code cleanly and the teams shipping it into
a dumpster fire had the <em>same</em> AI. What separated them was everything around the
AI — review discipline, ownership boundaries, how much room they left for
refactoring, whether anyone capped the size of a pull request.</p>

<p>The second was a reflection. Jamie Sharp wrote about learning to build software
in the early 2000s, when “design was the work” and “the code was an artifact” —
when engineers shared a vocabulary of patterns and watched complexity on
purpose. His worry about now isn’t that the tools got worse. It’s that we
quietly decided the standard was optional: ask an agent to “build the thing,”
accept whatever comes back, ship it. No spec, no design, no bar the output has
to clear. His line stuck with me: <em>the tools didn’t lower the bar — we did, by
deciding the bar was optional.</em></p>

<p>One post is data. One is memory. They point at the same conclusion. The quality
problem people blame on AI isn’t coming from the AI.</p>

<h2 id="the-patterns-didnt-go-anywhere">The patterns didn’t go anywhere</h2>

<p>Here’s the part that should be reassuring and is mostly just inconvenient: every
practice that made code good before still makes code good now. Single
responsibility. Clear boundaries. Dependencies pointing the right direction.
Small, reviewable changes. Tests that double as design feedback. None of that
got repealed. Span’s findings are basically a measurement of those practices —
the teams with PR discipline and real ownership are the ones AI made <em>faster</em>,
not messier.</p>

<p>What changed is that the patterns stopped being automatic. For twenty years they
rode along inside the act of typing. You couldn’t write a class without deciding
what it was responsible for, because you had to write every line of it. The
friction did some of the thinking for you. Generation removed the friction, and
it took the accidental discipline with it. The patterns are still sitting right
there. They’re just no longer free.</p>

<h2 id="ai-is-a-junior-dev-who-never-internalizes-anything">AI is a junior dev who never internalizes anything</h2>

<p>The mental model I keep coming back to: an AI agent is the most capable junior
developer you will ever work with, and also the one who will never, on its own,
develop judgment.</p>

<p>A good junior gets a vague ticket, takes a swing, and hands you something that
works and is shaped wrong. You don’t conclude the junior is hopeless. You tell
them: this method’s doing three things, split it; this reaches into another
module’s internals, pass it in; this needs a test, and if the test is hard to
write, the design is the problem, not the test. Say it enough times and a human
junior starts doing it before you ask. That’s what “getting more senior” <em>is</em> —
internalizing the standard so it stops needing to be said.</p>

<p>The agent never makes that move. It will apply every pattern you name, cleanly
and instantly, and forget to apply a single one you didn’t. It has no standard
of its own to fall back on. Which means the standard has to come from you, every
time, out loud. The teams getting great results aren’t using better models.
They’re the ones still doing the senior half of the job — naming the patterns
the agent should follow, the way they’d direct a junior who hasn’t learned them
yet.</p>

<h2 id="garbage-in-garbage-out--now-at-full-speed">Garbage in, garbage out — now at full speed</h2>

<p>“Ship the thing” is a garbage prompt, and it produces exactly what it asks for:
code with no spec to satisfy, no design to honor, no bar to clear. It compiles.
It might even pass tests. And, in Sharp’s words, nobody — human or agent — can
safely change it later, because there was never a design to change. That’s not
an AI failure. Feed that brief to a contractor and you’d get the same slop, just
slower.</p>

<p>Flip the inputs and the output flips with it. Tell the agent the responsibility
each piece owns. Point it at the seam you actually want. Hand it the constraints
a good reviewer would enforce anyway. Cap the change so the review surface stays
human-sized — Span singled this out, because the one thing AI reliably <em>does</em>
inflate is PR size, and a giant diff is where review quietly stops happening.
Same model, same afternoon, completely different code. Garbage in, garbage out is
not a new law. AI just removed the wait between the garbage going in and coming
back out, which makes the quality of your inputs the whole game.</p>

<h2 id="the-bar-is-a-choice-you-make-on-purpose-now">The bar is a choice you make on purpose now</h2>

<p>I’ve <a href="/2025/09/building-with-ai/">written before</a> about treating AI like a pair
who types at 300 words a minute, not a lead architect — letting it draft, then
spending ten minutes on responsibilities, boundaries, and names before anything
merges. That checklist matters more now, not less, because the thing it’s really
defending is the bar itself. The discipline used to be enforced by how slow
writing code was. It now has to be enforced by you, deliberately, against a tool
whose entire appeal is that it removed the slowness that used to enforce it.</p>

<p>That’s the uncomfortable shift hiding inside both posts. The standard didn’t
move and the patterns didn’t expire. They just lost their free ride. Holding the
line on code quality is no longer something that happens to you while you work —
it’s a decision you make, out loud, on every change, or it doesn’t happen at all.</p>

<p>So the question Sharp leaves you with is the right one to sit with: are you using
these tools to ship faster, or to skip the part of the job that was always the
actual job? The good news, and the Span data backs this up, is that the teams who
kept doing the actual job are the ones pulling ahead. The patterns work. They
always did. You just have to ask.</p>

<p>— Roger</p>

<h2 id="further-reading">Further reading</h2>

<ul>
  <li>Poletto, Stephen.
<a href="https://www.linkedin.com/posts/spoletto_we-looked-at-248099-prs-and-65697-production-share-7467946179687763968-a0Jb/">“We looked at 248,099 PRs and 65,697 production incidents.”</a>
— the Span study finding that AI authorship isn’t the defect driver; the
engineering environment around it is.</li>
  <li>Sharp, Jamie.
<a href="https://www.linkedin.com/posts/jamie-sharp-mba-b8247911_when-i-learned-to-build-software-in-the-early-activity-7471747440220565504-Bhd4">“When I learned to build software in the early 2000s…”</a>
— on design as the real work, and the bar we decided was optional.</li>
</ul>]]></content><author><name>Rōger Nōden</name></author><category term="Technology" /><category term="Development" /><category term="AI" /><category term="Software Engineering" /><category term="Code Quality" /><category term="Engineering Leadership" /><category term="Practices" /><summary type="html"><![CDATA[Two posts crossed my feed the same week — one a 248,000-PR study, one a reflection on how we used to build — and they told the same story from opposite ends: AI didn't lower the bar on code quality. We stopped holding it there. The discipline still works. You just have to ask for it.]]></summary></entry><entry><title type="html">Nobody Changed the Code. It Still Broke.</title><link href="https://rogernoden.com/2026/06/nobody-changed-the-code-it-still-broke/" rel="alternate" type="text/html" title="Nobody Changed the Code. It Still Broke." /><published>2026-06-17T00:00:00-05:00</published><updated>2026-06-17T00:00:00-05:00</updated><id>https://rogernoden.com/2026/06/nobody-changed-the-code-it-still-broke</id><content type="html" xml:base="https://rogernoden.com/2026/06/nobody-changed-the-code-it-still-broke/"><![CDATA[<p>A function we hadn’t touched in weeks suddenly refused to start.</p>

<p>No new business logic. No deploy carrying a behavior change. The same code
that had been running quietly in production for ages now fell over on cold
start, crashing before it could handle a single request. The logs pointed at
something deep in startup, and the first instinct — the wrong one — was to go
hunting through our own code for what we broke.</p>

<p>We didn’t break anything. That’s the unsettling part, and it’s also the whole
story. The worst production bugs aren’t the ones where someone shipped a bad
line. They’re the ones where the ground shifted underneath code that never
moved.</p>

<h2 id="three-suspects-none-guilty-alone">Three suspects, none guilty alone</h2>

<p>It took my team a while to accept the shape of this bug, because it doesn’t
have a single cause. It has three. Each one, on its own, was completely fine.
They had coexisted happily for a long time. The crash only appeared when all
three lined
up at once — and the day they lined up, nobody on the team had done anything to
make it happen.</p>

<p>Here are the three suspects.</p>

<h2 id="suspect-one-aws-quietly-updated-the-runtime">Suspect one: AWS quietly updated the runtime</h2>

<p>The function runs on the managed .NET 8 Lambda runtime. AWS owns that runtime,
patches it, and rolls out new builds on its own schedule. At some point it moved
to a newer build (<code class="language-plaintext highlighter-rouge">dotnet:8.v88</code>).</p>

<p>That newer runtime ships its own AWS bootstrap library — the glue that sits
between Lambda’s execution environment and your handler. And the new bootstrap
was built against a newer <code class="language-plaintext highlighter-rouge">Amazon.Lambda.Core</code>, one that introduces a brand-new
type: <code class="language-plaintext highlighter-rouge">ILambdaResponseStream</code>.</p>

<p>This is normal. Runtimes get updated. New types get added. Nobody asked us, and
nobody needed to. From AWS’s side, this was an ordinary improvement.</p>

<h2 id="suspect-two-our-bundled-library-was-older">Suspect two: our bundled library was older</h2>

<p>Our function still bundles <code class="language-plaintext highlighter-rouge">Amazon.Lambda.Core 2.8.1</code>. That version does not
contain <code class="language-plaintext highlighter-rouge">ILambdaResponseStream</code>. My team confirmed it the tedious way — by
inspecting every installed version of the library up to 2.8.1. None of them have
the type.</p>

<p>So now there are two copies of the same AWS library in play: the newer one AWS
brought with its updated runtime, and the older one we packaged ourselves. They
disagree about which types exist.</p>

<p>On its own, this is still harmless. A version skew like this sits dormant all
the time. Two libraries can hold slightly different views of the world and
never collide — right up until something forces them to be reconciled. Nothing
in normal operation reads <em>every</em> type in <em>every</em> loaded assembly.</p>

<p>Until something does.</p>

<h2 id="suspect-three-the-upgrade-that-made-everything-strict">Suspect three: the upgrade that made everything strict</h2>

<p>The third suspect is the only thing that actually changed on our side, and it
looked completely innocent: a routine dependency-upgrade PR that bumped
AutoMapper (and, alongside it, MediatR).</p>

<p>Both of those libraries work by scanning assemblies at startup to discover what
they need — AutoMapper looks for mapping profiles, MediatR looks for handlers.
And the way we’d wired them up, we asked them to scan <strong>every loaded assembly</strong>.
That’s a common pattern, and it had worked for years.</p>

<p>But “every loaded assembly” includes AWS’s runtime bootstrap library. When the
upgraded AutoMapper walked that library and tried to enumerate its types, it hit
the reference to <code class="language-plaintext highlighter-rouge">ILambdaResponseStream</code> — a type that lived in the newer
<code class="language-plaintext highlighter-rouge">Amazon.Lambda.Core</code> but not in the 2.8.1 we’d bundled. The reference couldn’t
be resolved, the type load blew up, and because this happened during startup
scanning, it took the entire function down with it.</p>

<p>The detail that makes this maddening: before the upgrade, the scan tolerated
this. The older scanning behavior shrugged at a type it couldn’t fully resolve.
The new version is stricter. Same instruction from us — “scan everything” — but
now “everything” was enforced to the letter.</p>

<p>So that’s the full collision. A <strong>new AWS runtime</strong> brought a library with a new
type. Our <strong>old bundled library</strong> lacked that type. And a <strong>newly strict scan</strong>
insisted on reading every type in every assembly, including AWS’s. Remove any
one of the three and there’s no crash. Put them together and startup dies.</p>

<h2 id="the-fix">The fix</h2>

<p>Once the cause is clear, the fix is almost boring — which is exactly what you
want from a root-cause fix.</p>

<p>AutoMapper and MediatR never had any reason to inspect AWS’s internal runtime
libraries. There are no mapping profiles of ours in there. There are no handlers
of ours in there. We were asking two of our libraries to rummage through
infrastructure we don’t own, looking for things that could only ever live in
code we wrote.</p>

<p>So we stopped doing that. Instead of scanning every loaded assembly, we scan
only our own:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Before — scans EVERY loaded assembly, including AWS's runtime libraries</span>
<span class="n">services</span><span class="p">.</span><span class="nf">AddAutoMapper</span><span class="p">(</span><span class="n">AppDomain</span><span class="p">.</span><span class="n">CurrentDomain</span><span class="p">.</span><span class="nf">GetAssemblies</span><span class="p">());</span>
<span class="n">services</span><span class="p">.</span><span class="nf">AddMediatR</span><span class="p">(</span><span class="n">cfg</span> <span class="p">=&gt;</span> <span class="n">cfg</span><span class="p">.</span><span class="nf">RegisterServicesFromAssemblies</span><span class="p">(</span>
    <span class="n">AppDomain</span><span class="p">.</span><span class="n">CurrentDomain</span><span class="p">.</span><span class="nf">GetAssemblies</span><span class="p">()));</span>

<span class="c1">// After — scan only our own assemblies</span>
<span class="kt">var</span> <span class="n">ourAssemblies</span> <span class="p">=</span> <span class="n">AppDomain</span><span class="p">.</span><span class="n">CurrentDomain</span><span class="p">.</span><span class="nf">GetAssemblies</span><span class="p">()</span>
    <span class="p">.</span><span class="nf">Where</span><span class="p">(</span><span class="n">a</span> <span class="p">=&gt;</span> <span class="n">a</span><span class="p">.</span><span class="nf">GetName</span><span class="p">().</span><span class="n">Name</span><span class="p">?.</span><span class="nf">StartsWith</span><span class="p">(</span><span class="s">"YourApp."</span><span class="p">)</span> <span class="p">==</span> <span class="k">true</span><span class="p">)</span>
    <span class="p">.</span><span class="nf">ToArray</span><span class="p">();</span>

<span class="n">services</span><span class="p">.</span><span class="nf">AddAutoMapper</span><span class="p">(</span><span class="n">ourAssemblies</span><span class="p">);</span>
<span class="n">services</span><span class="p">.</span><span class="nf">AddMediatR</span><span class="p">(</span><span class="n">cfg</span> <span class="p">=&gt;</span> <span class="n">cfg</span><span class="p">.</span><span class="nf">RegisterServicesFromAssemblies</span><span class="p">(</span><span class="n">ourAssemblies</span><span class="p">));</span>
</code></pre></div></div>

<p>(That’s illustrative — your filter is whatever prefix your own assemblies share
— but the shape is the point.)</p>

<p>No functional behavior changes. The mappings and handlers that mattered all live
in our assemblies, so narrowing the scan finds exactly the same set of them. The
build passes cleanly. And as a bonus, the function is now immune to this entire
class of problem: AWS can update its runtime, swap its bundled libraries, and
add as many new types as it likes, and our startup scan will never look at any
of it.</p>

<h2 id="the-lesson">The lesson</h2>

<p>The narrow, technical takeaway is simple: <strong>scan only what you own.</strong> When a
library discovers your types by reflection, point it at your code, not at the
whole process. Reaching into assemblies you don’t control to find your own
mappings is asking to be surprised by someone else’s release notes.</p>

<p>The broader lesson is the one I keep relearning. Dangerous production bugs are
usually combinations, not single causes. Each ingredient here passed its own
review. The AWS runtime update was correct. Our bundled library version was
fine. The dependency upgrade was a clean, sensible bump. There was no bad commit
to find, because the bug didn’t live in any one change — it lived in the
intersection of three.</p>

<p>And “nothing changed” is almost never true. Our code didn’t change, but the
environment it runs in did, and a managed runtime is part of your dependency
graph whether you think about it that way or not. Latent version skew is sitting
in most systems right now, invisible, waiting for something to force every type
to be enumerated. The upgrade that finally did the forcing got the blame, but it
was only the third domino.</p>

<p>The fix took just minutes. Understanding why three innocent things added up to
a crash took longer — and was the part actually worth writing down.</p>

<p>— Roger</p>]]></content><author><name>Rōger Nōden</name></author><category term="Technology" /><category term="Development" /><category term=".NET" /><category term="AWS Lambda" /><category term="Debugging" /><category term="Dependencies" /><category term="Software Engineering" /><summary type="html"><![CDATA[A production Lambda started crashing on startup with no code change behind it. The cause was a three-way collision between a new AWS runtime, an old bundled library, and a routine dependency upgrade — and the fix is a one-line lesson in scoping what you scan.]]></summary></entry><entry><title type="html">AI Made Building Free. Your Org Still Has a Speed Limit.</title><link href="https://rogernoden.com/2026/06/org-speed-limit/" rel="alternate" type="text/html" title="AI Made Building Free. Your Org Still Has a Speed Limit." /><published>2026-06-15T00:00:00-05:00</published><updated>2026-06-15T00:00:00-05:00</updated><id>https://rogernoden.com/2026/06/org-speed-limit</id><content type="html" xml:base="https://rogernoden.com/2026/06/org-speed-limit/"><![CDATA[<p>A team I talked to recently was proud of a number: forty-one internal tools
shipped this year. Genuinely impressive throughput — agents, integrations, a
couple of slick little apps. I asked how many of the last ten were still in use.
The room did that thing rooms do now. Nobody knew, and the not-knowing was the
answer.</p>

<p>Last week I argued that
<a href="/2026/06/ai-moved-the-bottleneck/">AI didn’t kill Agile — it moved the constraint</a>:
when building got cheap, the bottleneck slid downstream from <em>can we build it?</em>
to <em>can anyone actually absorb it?</em> I made the case that Jobs to be Done is how
you decide <em>what</em> to point all that cheap capability at. But I left a thread
hanging on purpose. Knowing which job to chase tells you where to aim. It says
nothing about how <em>fast</em> an organization can actually take the hit.</p>

<p>That second number — the rate — is the whole game now. And a guy in a 1984
business novel already told us how it works.</p>

<h2 id="goldratts-uncomfortable-little-rule">Goldratt’s uncomfortable little rule</h2>

<p>Eliyahu Goldratt’s Theory of Constraints is almost annoyingly simple. Any system
has exactly one constraint at a time — one step that sets the pace for the whole
line. The throughput of the entire system is the throughput of that one step.
And here’s the part people hate: improving anything that <em>isn’t</em> the constraint
does nothing for the system. It just feels like progress.</p>

<p>For twenty years, engineering <em>was</em> the constraint, so every productivity gain
there was real — it moved the whole line. That’s the muscle memory we’re all
still running on. Make the developers faster, ship more, win.</p>

<p>Then we made building cheap, and the constraint moved. It’s now sitting squarely
on the organization’s ability to absorb change. Which means most of the effort
we’re still pouring into building <em>faster</em> is, in Goldratt’s terms, optimizing a
non-constraint. It feels like progress. It produces a graveyard.</p>

<h2 id="building-faster-just-grows-the-pile">Building faster just grows the pile</h2>

<p>Here’s the mechanism, because it’s the part that matters. In a factory, when you
run a non-bottleneck machine flat out, you don’t get more finished product. You
get inventory — half-built stuff stacking up in front of the slow step, going
stale, tying up cash, hiding problems.</p>

<p>Swap “inventory” for “unadopted capability” and you’ve described every AI
initiative graveyard I’ve ever seen. The forty-one tools. The pilot that never
rolled out. The copilot with twelve daily users out of four thousand seats. That
pile isn’t evidence of productivity — it’s work-in-progress stacked in front of
the constraint, quietly rotting. Goldratt’s line was that an hour saved at a
non-constraint is a mirage. A tool shipped past your absorption limit is worse:
it’s a mirage with a maintenance cost.</p>

<h2 id="the-move-nobody-wants-to-make">The move nobody wants to make</h2>

<p>Theory of Constraints is blunt about what comes next. Once you’ve found the
constraint, you <em>subordinate</em> everything else to it. Every other step runs at the
constraint’s pace, not its own — deliberately, even when it could go faster.</p>

<p>Translated, that’s a genuinely unpopular instruction: stop pushing capability
into the organization faster than the organization can absorb it. Cap how much
change is in flight at once — a WIP limit, but for transformation instead of
tickets. Let the edge <em>pull</em> the next capability when it has digested the last
one, instead of a central team <em>pushing</em> a firehose just because the firehose is
cheap now.</p>

<p>This cuts against every instinct we built during the scarcity years, when the
cardinal sin was an idle engineer. The idle engineer isn’t the expensive thing
anymore. The half-absorbed change is.</p>

<h2 id="adoption-has-a-speed-limit-and-its-human">Adoption has a speed limit, and it’s human</h2>

<p>Why can’t you just turn the rate up? Because the constraint is people changing
how they work, and Everett Rogers mapped that curve sixty years ago. A new way of
working spreads through a population at a rate — innovators first, then early
adopters, then the majority dragged across one reluctant cohort at a time. You
can grease it. You cannot skip it. Push harder than the curve allows and you
don’t accelerate adoption; you manufacture resistance, which is negative
progress.</p>

<p>That’s the thing a dashboard full of shipped-feature counts will never show you.
The capability side is now effectively infinite. The human side moves at the
speed of trust, habit, and how much disruption a team can hold before it stops
doing its actual job.</p>

<h2 id="you-can-raise-the-ceiling--slowly">You can raise the ceiling — slowly</h2>

<p>The good news, such as it is: the constraint isn’t fixed. Goldratt’s last step
is to <em>elevate</em> it — invest until it’s no longer the bottleneck. But absorptive
capacity, the way Cohen and Levinthal described it, is not something you buy in
a quarter. An organization’s ability to take in something new depends on what it
already knows and how well it’s wired to spread that knowledge around. It
compounds. The teams that can absorb fast in 2026 are the ones that built the
muscle in 2024.</p>

<p>So elevating the constraint is real work, and most of it is unglamorous: putting
engineers at the edge to lower the anxiety and break the habit — the forces I
wrote about last time — building the connective tissue that lets one team’s
adoption teach the next, and treating <em>can we absorb this?</em> as a capability you
invest in rather than a thing you assume. That’s the actual leverage point now.
Not another model. The metabolic rate.</p>

<h2 id="where-this-leaves-you">Where this leaves you</h2>

<p>The first post was about finding the bottleneck. This one is about the discipline
that finding it demands: stop optimizing the thing that is no longer the
constraint. Building was the hard part for so long that we’ve mistaken it for the
point. It isn’t anymore.</p>

<p>The teams that win the next few years won’t be the ones generating the most
capability. They’ll be the ones who matched their build rate to their absorption
rate, defended that limit when it felt like leaving speed on the table, and spent
their real energy raising the ceiling one compounding quarter at a time.</p>

<p>Goldratt would have found the whole thing familiar. We just gave the bottleneck
a new address.</p>

<h2 id="further-reading">Further reading</h2>

<ul>
  <li>Goldratt, Eliyahu M., and Jeff Cox.
<a href="https://en.wikipedia.org/wiki/The_Goal_%28novel%29"><em>The Goal: A Process of Ongoing Improvement.</em></a>
North River Press, 1984. — the original Theory of Constraints, delivered as a
factory novel.</li>
  <li>Rogers, Everett M.
<a href="https://en.wikipedia.org/wiki/Diffusion_of_innovations"><em>Diffusion of Innovations.</em></a>
Free Press, 1962 (5th ed., 2003). — the adoption curve and how new practices
actually spread through a population.</li>
  <li>Cohen, Wesley M., and Daniel A. Levinthal.
<a href="https://doi.org/10.2307/2393553">“Absorptive Capacity: A New Perspective on Learning and Innovation.”</a>
<em>Administrative Science Quarterly</em> 35, no. 1 (1990): 128–152. — why an
organization’s ability to absorb the new depends on what it already knows.</li>
</ul>]]></content><author><name>Rōger Nōden</name></author><category term="Technology" /><category term="Agile" /><category term="AI" /><category term="Agile" /><category term="Leadership" /><category term="Change Management" /><category term="Product Management" /><summary type="html"><![CDATA[The sequel to "It Moved the Constraint." Building is nearly free now, but organizations still absorb change at a stubbornly human rate — and Goldratt told us forty years ago what to do about a bottleneck you can't code past.]]></summary></entry><entry><title type="html">Camping at Leech Lake — June 2026</title><link href="https://rogernoden.com/2026/06/camping-leech-lake/" rel="alternate" type="text/html" title="Camping at Leech Lake — June 2026" /><published>2026-06-14T00:00:00-05:00</published><updated>2026-06-14T00:00:00-05:00</updated><id>https://rogernoden.com/2026/06/camping-leech-lake</id><content type="html" xml:base="https://rogernoden.com/2026/06/camping-leech-lake/"><![CDATA[<p>Back at it — second camping write-up, and this time the whole crew came
along: Jayson, plus <em>both</em> huskies, Echo and Dee OhGee. If you caught the
<a href="https://rogernoden.com/2026/05/camping-lake-winni-dam/">Lake Winni Dam post</a>
from Memorial Day, you’ll remember I was flying with a short bench that
weekend. Not this time. As always, the shorter, in-the-moment version of
all this — photos, quick takes — lives on Mastodon at
<strong><a href="https://woof.group/@w0ger">@w0ger@woof.group</a></strong>.</p>

<p>Two nights at Leech Lake. Here’s how it went.</p>

<h2 id="the-weekend">The Weekend</h2>

<figure>
  <img src="/images/posts//2026-06-14-camping-leech-lake/the-weekend.jpeg" alt="Dee OhGee resting his head on my lap in a camp chair" />
  <figcaption>
    Cool, gray, and quiet — exactly the kind of weekend Dee OhGee and I were after.
  </figcaption>
</figure>

<p>Another Corps of Engineers campground, another reminder that the COE
quietly runs some of the best campgrounds in the country. Leech Lake
Recreation Area was excellent — well maintained, genuinely quiet, and the
bathrooms and showers were clean the entire weekend. Site 15 had
everything we needed and then some. If you’ve been reading along, you know
I have a soft spot for these places, and Leech Lake did nothing to change
that.</p>

<p>The weather was the headline, and not in the way you’d expect for mid-June.
Cloudy and cool the whole time, with a high of only 58°F on Saturday. No
rain, though — which, after the Winni weekend got rained on for two days
straight, I’ll take cool-and-dry every single time. And here’s the thing:
58 degrees and overcast is <em>husky heaven</em>. Echo and Dee were in their
element. No panting, no hunting for shade, no frozen-water-bottle
babysitting. They just got to be sled dogs in the woods for two days, which
is all they’ve ever wanted out of life.</p>

<p>One repeat heads-up from the last trip: no firewood sold at the campground
itself. There’s a gift shop across the highway that sells bundles — we
grabbed two, both good and dry. Fair warning, though: they burned <em>fast</em>.
Two bundles didn’t even cover late Saturday afternoon into the evening.
Next time I’m buying more than I think I need, and then some.</p>

<p>The paddleboards stayed home this time. I’d been watching the forecast all
week, and once it locked in at 58 and cloudy with mid-60s water, the call
made itself. No sense hauling the Paddle Norths four hours round-trip to
look at them. They’ll get their weekend.</p>

<h2 id="the-saturday-drive">The Saturday Drive</h2>

<figure>
  <img src="/images/posts//2026-06-14-camping-leech-lake/saturday-drive.jpeg" alt="View through the windshield of a narrow two-track forest trail" />
  <figcaption>
    The two-track up toward Lake Winnie — lush, green, and narrow enough to
    keep things interesting.
  </figcaption>
</figure>

<p>Saturday afternoon we pointed the truck north and drove from the Leech Lake
dam up to Lake Winnibigoshish. If that name rings a bell, it’s because Echo
and I camped on Winnie over Memorial Day — but this was the <em>other</em> side of
the lake, which was fun to see. Same big water, completely different angle
on it.</p>

<p>On the way we found some forest trails worth poking around on. We ran 91 to
2348 to 2948 and back to 91 — an easy loop overall. Like a lot of the
routes out here right now, everything’s lush and green, with a few puddles
scattered along the way. Nothing deep, but enough to keep things
interesting. Some ruts here and there, but nothing a stock vehicle can’t
handle. The one knock: a few stretches were a bit narrow for a full-size
R1T — branches reaching in close, not a lot of room to swing wide. We
managed fine, but a Tacoma-sized rig would’ve been happier in spots. Quiet
out there, too — we passed exactly one other party, an ATV, the whole time.</p>

<p>Saturday evening we didn’t do much of anything, and that was exactly the
plan. Built a campfire, made s’mores — which were <em>excellent</em> — and let the
camp go quiet around us. The FireCan rode along as insurance in case
campfires were banned, but the fire ring was open, so it never left the
truck. Always nice to have the propane backup and not need it.</p>

<figure>
  <img src="/images/posts//2026-06-14-camping-leech-lake/smores.jpeg" alt="A finished s'more held up in front of the campfire" />
  <figcaption>
    Exhibit A: the s'mores delivered.
  </figcaption>
</figure>

<h2 id="whats-working-well">What’s Working Well</h2>

<p><strong>Thermacell Zone repellers.</strong> I went into this trip braced for the usual
Chippewa National Forest mosquito assault, and it just… didn’t materialize.
Partly the cool weather, sure, but the Thermacell Zones earned real credit.
Set them around the site and the bugs basically left us alone. After years
of swatting my way through northern Minnesota Junes, this felt like
cheating.</p>

<p><strong>Cool weather for the dogs.</strong> I’m filing this under gear even though it’s
just the sky. June heat is the thing I worry about most with two huskies,
and this trip removed the worry entirely. If I could special-order 58 and
cloudy for every summer trip, I would.</p>

<p><strong>The R1T off the pavement.</strong> The truck continues to be a fantastic
basecamp <em>and</em> a capable trail rig. Those forest roads up by Winnie were an
easy outing, but it’s nice to be reminded the R1T will happily go find the
puddles when you point it that way.</p>

<h2 id="what-could-be-better">What Could Be Better</h2>

<p><strong>JetBoil Genesis Basecamp.</strong> This is the real gear story of the weekend,
and not a happy one. I could not get the thing to stay lit. The included
windscreen is supposed to snap into place and it just wouldn’t seat right,
and the burner kept dying on me. The Genesis was supposed to run the Dutch
oven for Saturday’s planned ribeyes-and-cheesy-potatoes dinner, and with the
stove being uncooperative I bailed on that whole plan (more on the menu
pivot below). I’m going to pull it apart on the bench this week and figure
out what’s going on — could be the windscreen, could be the regulator,
could be me. I’ll report back once I’ve diagnosed it.</p>

<p><strong>That firewood burn rate.</strong> Not a complaint about the wood — it was dry
and good. Just a planning note to myself: two bundles isn’t even one full
Saturday afternoon-into-night. Buy extra.</p>

<p><strong>Late start, skipped meals.</strong> Minor, and honestly fine, but we got a slow
start Saturday and a couple of meals fell off the board (see below). No
regrets, but if I’d wanted to hit the full menu I’d have needed to move
quicker in the morning.</p>

<h2 id="the-menu">The Menu</h2>

<p>So the meal plan I packed and the meal plan we actually ate diverged a bit
— which is camping. Here’s what really happened.</p>

<p><strong>Friday</strong></p>

<ul>
  <li><em>Dinner</em> — Beer-braised brats with grilled peppers and onions, plus baked
beans. Exactly as planned, and exactly what you want after a three-hour
drive.</li>
</ul>

<p><strong>Saturday</strong></p>

<ul>
  <li><em>Breakfast</em> — Loaded breakfast burritos (sausage, peppers, onions, hash
browns, eggs, cheddar). As planned, and a strong start to the day.</li>
  <li><em>Lunch</em> — Skipped. Late start, and we were out chasing trails.</li>
  <li><em>Dinner</em> — Chicken Caesar wraps. These were <em>supposed</em> to be Saturday
lunch, but with the JetBoil refusing to cooperate, I promoted lunch to
dinner and kept things simple. No shame in lunch-for-dinner.</li>
  <li><em>Dessert</em> — S’mores, and they delivered.</li>
</ul>

<p><strong>Sunday</strong></p>

<ul>
  <li><em>Breakfast</em> — Skipped. We packed up and got on the road instead.</li>
  <li><em>Lunch</em> — <a href="https://deerstandrestaurant.com">The Deerstand</a> on the drive
home. Stop here. The ribs and the burger were both excellent, and there’s
a great outdoor space where Echo and Dee could hang out while we ate.
Highly recommend if you’re passing through.</li>
</ul>

<p>As for those Saturday ribeyes that never got cooked at camp — they came
home with us and got the proper treatment Sunday evening, once everything
was unpacked. Smoked low on the Traeger, then finished with a hard sear on
the grill, with corn going alongside. Honestly? They might’ve been better
off for the delay. Reverse-seared ribeye in your own backyard with the gear
cooperating beats a balky JetBoil any day.</p>

<h2 id="the-whole-crew">The Whole Crew</h2>

<figure>
  <img src="/images/posts//2026-06-14-camping-leech-lake/whole-crew.jpeg" alt="Jayson kneeling between Echo and Dee OhGee in front of the picnic tables" />
  <figcaption>
    The whole crew, finally together — two huskies who got to be cold for once.
  </figcaption>
</figure>

<p>Last trip I closed by listing who I missed — Dee OhGee stayed home, and
Jayson was off in Chicago. So it feels worth noting that this time everyone
was here. Jayson, Echo, and Dee, all in the woods, all in the cool air, all
where they belong. Two huskies who got to actually be cold for once, a
husband to share the fire with, and a quiet site under a gray northern sky.
That’s the trip I was hoping for back in May, and this was it.</p>

<hr />

<p>That’s Leech Lake. The JetBoil and I have a date with a workbench this week,
and the boards are still dry, so they owe me a paddle.</p>

<p><strong>Up next:</strong>
<a href="https://www.dnr.state.mn.us/state_parks/park.html?id=spk00148">Forestville Mystery Cave State Park</a>.
Should be a fun one.</p>

<p>More to come — here and on Mastodon. Thanks for reading.</p>]]></content><author><name>Rōger Nōden</name></author><category term="Camping" /><category term="Outdoors" /><category term="Camping" /><category term="Dogs" /><category term="Gear" /><category term="Overlanding" /><category term="Rivian R1T" /><summary type="html"><![CDATA[Two cool, cloudy nights at Leech Lake with Jayson, Echo, and Dee OhGee — a spotless Corps of Engineers campground, some off-road forest trails up toward Lake Winnie, a balky stove, and a menu that rearranged itself on the fly.]]></summary></entry><entry><title type="html">AI Didn’t Kill Agile. It Just Moved the Constraint.</title><link href="https://rogernoden.com/2026/06/ai-moved-the-bottleneck/" rel="alternate" type="text/html" title="AI Didn’t Kill Agile. It Just Moved the Constraint." /><published>2026-06-08T00:00:00-05:00</published><updated>2026-06-08T00:00:00-05:00</updated><id>https://rogernoden.com/2026/06/ai-moved-the-bottleneck</id><content type="html" xml:base="https://rogernoden.com/2026/06/ai-moved-the-bottleneck/"><![CDATA[<p>There’s a particular kind of meeting I’ve sat in a lot lately. A team demos
something genuinely impressive — an agent that drafts the integration, a tool
that turns a Figma frame into working components, a model wired into the support
queue. Everyone nods. Then someone asks the only question that matters: <em>who’s
actually using it?</em> And the room goes quiet.</p>

<p>That silence is the whole story of AI and Agile right now. We got very good at
building things, very fast. We did not get any better at the part that comes
after.</p>

<p>A lot of people have read that silence as proof that Agile is finished — that
sprints and backlogs and refinement were scaffolding for a slow era we’ve now
left behind. I don’t think that’s right. Agile didn’t die. The thing it was
quietly built to manage just stopped being the problem.</p>

<h2 id="the-constraint-we-built-agile-around">The constraint we built Agile around</h2>

<p>For twenty years, engineering capacity was the scarce resource. Good engineers
were expensive, hard to hire, and easy to waste. So we built an entire
discipline around protecting them.</p>

<p>Be honest about what the ceremonies were really for. The backlog rationed
attention. The sprint boundary kept stakeholders from re-pointing the team every
afternoon. Estimation was a polite way of saying <em>no, not this quarter.</em>
Prioritization, intake gates, the whole governance apparatus — all of it existed
to take a small, costly pool of build capacity and aim it at the highest-value
work while defending it from thrash.</p>

<p>That wasn’t bureaucracy for its own sake. It was a sensible response to a real
constraint. When you can only build a little, deciding <em>what</em> to build is the
entire game.</p>

<h2 id="when-the-scarce-thing-stops-being-scarce">When the scarce thing stops being scarce</h2>

<p>Now drop the price of building by an order of magnitude.</p>

<p>When a single engineer with the right tooling can produce in an afternoon what
used to take a team a sprint, the math underneath all those ceremonies quietly
breaks. The gate you built to protect a scarce resource doesn’t protect anything
anymore — it just adds latency to a resource that’s no longer scarce. Every
careful brake you installed is now drag.</p>

<p>This is the part teams feel before they can name it. The process that used to
feel like discipline starts to feel like wading through wet sand. People assume
they’re doing Agile wrong. They’re not. They’re running a system tuned for
scarcity in a world that just got abundant on one specific axis.</p>

<h2 id="the-bottleneck-didnt-vanish--it-moved">The bottleneck didn’t vanish — it moved</h2>

<p>Here’s the trap, though. Cheap building does not mean fast value. It just moves
the jam somewhere else.</p>

<p>Look at almost any organization with real AI investment and you’ll find the same
landscape: a pile of copilots, agents, internal tools, model integrations, three
pilots that demoed beautifully, and a quiet graveyard of prototypes nobody
folded into how the work actually gets done. The capability is sitting right
there. The absorption isn’t.</p>

<p>The constraint moved downstream. It used to live in <em>can we build it?</em> Now it
lives in <em>can anyone put it to work and prove it was worth it?</em> That’s not an
engineering question. It’s an organizational one — about workflows, trust,
change, and the unglamorous labor of getting a new capability all the way into
someone’s daily job.</p>

<h2 id="agilitys-job-just-inverted">Agility’s job just inverted</h2>

<p>For two decades, agility pointed inward. Its instinct was to protect engineering
<em>from</em> the organization — buffer the team, hold the line, keep the demands out.</p>

<p>If the bottleneck is now adoption, that instinct is exactly backwards. The job
isn’t to wall engineering off from the business. It’s to push engineering <em>into</em>
it — out to the front lines, pointed straight at the highest-value adoption
problems, close enough to the work to see whether anything actually changed.</p>

<p>Same word, opposite motion. Agility used to mean <em>defend the scarce thing.</em> Now
it means <em>get the abundant thing into contact with reality as fast as possible.</em></p>

<h2 id="what-you-replace-the-brakes-with">What you replace the brakes with</h2>

<p>The fear, reasonably, is that removing the brakes just gives you faster chaos.
And it would — speed pointed in no particular direction is simply waste,
accelerated. The answer isn’t no brakes. It’s swapping the external brakes of
scarcity for internal ones built on direction.</p>

<p>A few of the shifts I’d bet on:</p>

<p><strong>Goal-driven over spec-driven.</strong> When building is cheap, a fat specification is
a liability — you’ve over-constrained the implementation before you’ve learned
anything. Give teams a sharp goal and the guardrails, and let them find the
shape. (I’ve argued before that for <a href="/2026/04/backlog-contract-for-ai-agents/">AI agents this has to be explicit</a>;
for humans, direction beats a script.)</p>

<p><strong>Opportunity backlogs over feature backlogs.</strong> Stop listing things to build.
Start listing outcomes you’re trying to move. A feature list assumes building was
the hard part. It isn’t anymore.</p>

<p><strong>Value metrics over velocity.</strong> Velocity measured how fast you converted the
scarce resource. Nobody cares now. Measure adoption, measure realized impact,
measure whether the thing you shipped last month is load-bearing in someone’s
work today.</p>

<p><strong>A thin spine, thick edges.</strong> Keep the central process light enough that
learning at the edge compounds instead of waiting on a committee. Empower teams,
hold them to outcomes, and resist the urge to re-add a gate every time something
goes sideways.</p>

<p>None of this is permission to abandon rigor. It’s a relocation of it — from
controlling input to being honest about output.</p>

<h2 id="which-job-is-worth-absorbing">Which job is worth absorbing?</h2>

<p>Two of those shifts — opportunity backlogs and goal-driven work — quietly lean on
a muscle most teams never had to build. Rationing scarce engineering, you mostly
needed to know what to build <em>next</em>. When building is nearly free, you need to
know what’s worth building <em>at all</em> — and the sharpest name for that skill is
Clayton Christensen’s Jobs to be Done.</p>

<p>The premise is relentlessly demand-side: people don’t buy products, they hire
them to make progress in a particular circumstance. Nobody wants a quarter-inch
drill; they want a quarter-inch hole, and really they want the shelf up before
the in-laws arrive. When building was the expensive part, you could start from
the drill and survive. When building is free, the only scarce thing left is
knowing which job is worth doing — and whether your shiny new capability is a
better hire than whatever the person is using today, switching costs included.</p>

<p>It’s also the cleanest explanation I’ve found for the prototype graveyard.
Christensen frames every switch as a tug-of-war: the <em>pull</em> of the new thing
against two forces of inertia — the anxiety of trying it and the habit of what’s
already there. Most dead pilots had plenty of pull and made no accounting for the
inertia. The job was never really hired, so the capability never got absorbed.</p>

<p>I’d be honest about the limit, though. Jobs to be Done is a targeting system, not
a throughput one. It tells you which job to aim abundant capability at; it does
nothing on its own to raise how much change an organization can stomach in a
quarter. That ceiling is a different problem, and pretending one framework solves
both is how you get a tidy theory and the same graveyard. Where it pays off twice
is measurement: Tony Ulwick’s outcome-driven spin turns a job into the
<em>measurable</em> outcomes people judge progress by — a far better source for those
value metrics than velocity ever was, and the same instinct as writing acceptance
you can actually run. Define done as the job getting done.</p>

<h2 id="forward-deployed-because-the-value-is-at-the-edge">Forward-deployed, because the value is at the edge</h2>

<p>The pattern that keeps proving itself here is forward-deployed engineering:
putting engineers right at the point where the capability meets a real user, a
real workflow, a real customer. It’s an old idea. It’s newly essential, because
the gap that matters now is the one between <em>built</em> and <em>used</em>, and that gap is
only visible from the edge.</p>

<p>You cannot close an adoption gap from the center of the org chart. You close it
by standing next to the person who’s supposed to be getting value and watching
where it falls apart.</p>

<h2 id="the-real-work-now">The real work now</h2>

<p>I don’t think the teams that win the next few years will be the ones that build
the most. Building is becoming table stakes. The ones that win will have built
something harder to copy: a system for continuously absorbing new capability into
evolving human work — and the honesty to keep asking <em>who’s actually using it</em>
until the room stops going quiet.</p>

<p>Agile was always about responding to change over following a plan. The change
showed up. It just landed one step downstream of where we were looking.</p>

<hr />

<p><em>This post was sparked by Scrum.org’s
<a href="https://www.scrum.org/resources/blog/ai-didnt-kill-agile-it-moved-bottleneck">AI Didn’t Kill Agile. It Moved the Bottleneck</a>
— worth reading in full. The argument here is my own take on the same idea.</em></p>]]></content><author><name>Rōger Nōden</name></author><category term="Technology" /><category term="Agile" /><category term="AI" /><category term="Agile" /><category term="Software Engineering" /><category term="Leadership" /><category term="Product Management" /><summary type="html"><![CDATA[Agile was built to ration scarce engineering. AI made building cheap, so the bottleneck moved downstream — to whether anyone can actually absorb what we ship. The gates we built to protect capacity are now just drag.]]></summary></entry><entry><title type="html">Camping at Lake Winni Dam — Memorial Day Weekend 2026</title><link href="https://rogernoden.com/2026/05/camping-lake-winni-dam/" rel="alternate" type="text/html" title="Camping at Lake Winni Dam — Memorial Day Weekend 2026" /><published>2026-05-25T00:00:00-05:00</published><updated>2026-05-25T00:00:00-05:00</updated><id>https://rogernoden.com/2026/05/camping-lake-winni-dam</id><content type="html" xml:base="https://rogernoden.com/2026/05/camping-lake-winni-dam/"><![CDATA[<p>Hey folks — welcome to what I’m hoping will be a regular thing around
here. I do a fair amount of camping and overlanding in the R1T with the
dogs, and I figured it was about time I started writing some of these
trips up. Expect campground reviews, gear notes (what’s earning its spot
in the truck and what isn’t), meal plans that worked, and the inevitable
“things I forgot at home” lists. If you want the shorter, more
in-the-moment version of these trips, follow me on Mastodon at
<strong><a href="https://woof.group/@w0ger">@w0ger@woof.group</a></strong> — that’s where I post
the photos and quick takes while I’m out.</p>

<p>Alright, on to the trip.</p>

<h2 id="the-weekend">The Weekend</h2>

<p><img src="/images/posts//2026-05-25-camping-lake-winni-dam/roger-and-echo.png" alt="Echo and Roger at the campground" /></p>

<p>Three nights at Lake Winni Dam, and I have to say — this is hands down
one of the nicest Corps of Engineers campgrounds I’ve stayed at. The
sites are spacious and well laid out, each with electric hookup, a fire
pit, and a picnic table. Some sites even have a clothesline, which is a
nice touch I don’t see often. The restrooms were spotless and well kept
the entire weekend, and you’re within easy walking distance of both the
river and the lake. One small heads-up: there’s no firewood sold at the
campground itself, but there’s a place about two miles down the road
where you can grab a bundle on your way in. Quiet and peaceful the whole
time. Highly recommend it.</p>

<p>Friday and Saturday were both rainy — not a washout, but enough to keep
us under the awning more than I’d have liked. Saturday morning we got a
quick thunderstorm that rolled through fast and loud, and then mellowed
back into steady drizzle. Sunday and Monday are looking sunny and a lot
drier, which I’m here for.</p>

<p>Echo and I did sneak in a hike over to the lake between the rain bands.
Lots of fishermen out in boats — I counted at least a dozen at one
point, all spread out across the water doing their thing. There’s
something really calming about watching boats from shore on a gray
morning. Echo was less calm about it. He wanted to swim.</p>

<h2 id="whats-working-well">What’s Working Well</h2>

<p><strong>The R1T as basecamp.</strong> Having electric at the site means I can keep
the truck topped up overnight, and the truck in turn keeps the BougeRV
fridge’s battery topped up during the day. (And yes, every single time I
type “BougeRV” I crack up. Whoever named that company — bless you.) It’s
a really nice closed loop.</p>

<p><strong>BougeRV Rocky 41 QT mobile fridge.</strong> Game-changer over a traditional
cooler. Stuff stays dry, temperature is rock-solid, and I’m not draining
meltwater every morning. The internal battery lasts about 10 hours
before it needs a recharge, but that’s easy thanks to the power outlet
in the R1T’s bed. If you’ve been on the fence about ditching the cooler,
this is your sign.</p>

<p><strong>iKamper SkyCamp Mini.</strong> Setup is genuinely fast — I had it deployed
before Echo had finished his perimeter sniff. Slept great. The one thing
I’d flag is that I think I inflated the mattress a touch too much this
time. It felt firmer than it did on the Colorado trip, and I noticed it.
Easy fix next time: less air.</p>

<p><strong>Blackstone 22” griddle.</strong> This thing absolutely earned its keep.
Burgers came out perfect, did fajitas one night, pancakes for breakfast,
and shrimp tacos that I’m still thinking about. The flat-top is so much
more versatile than I thought it would be when I bought it.</p>

<h2 id="what-could-be-better">What Could Be Better</h2>

<p><strong>Forgotten items.</strong> Two this trip: the micro USB cable for Echo’s
light-up collar (which is genuinely useful at night and useless without
juice), and a dog brush. Siberian Huskies do not stop shedding. Ever.
The truck is going to need a serious vacuum when I get home.</p>

<p><strong>An outdoor blanket for the dogs.</strong> Right now they kind of just flop
wherever, which is fine in dry conditions but less fine when the ground
is wet. I want something dedicated — durable, washable, ideally
quick-drying — that I can throw down outside the tent or under the
awning.</p>

<p><strong>The tent-stairs sand/dirt problem.</strong> I tried putting a blanket at the
bottom of the ladder to keep grit from getting tracked up into the tent.
With the rain, the blanket got soaked through and became part of the
problem instead of the solution. I need a better idea here. Maybe an
actual outdoor mat with drainage, or one of those folding step platforms.
Open to suggestions if anyone has solved this.</p>

<p><strong>The Blackstone’s footprint.</strong> As much as I love it, the 22” griddle
takes up a <em>ton</em> of space in the R1T bed. With the full camping load,
it’s a real Tetris challenge. I think it’s going to become a
special-occasions piece of kit — group trips, longer stays, anything
where griddle cooking is the point — rather than something I bring every
time.</p>

<h2 id="the-menu">The Menu</h2>

<p>Three dinners, three breakfasts, two lunches. Brought it all from home,
no resupply.</p>

<p><strong>Friday</strong></p>

<ul>
  <li><em>Dinner</em> — Hamburgers and BBQ beans</li>
</ul>

<p><strong>Saturday</strong></p>

<ul>
  <li><em>Breakfast</em> — Cast iron pancakes with breakfast sausage</li>
  <li><em>Lunch</em> — Italian sandwich on sourdough (provolone, mayo, pepperoni,
salami, ham)</li>
  <li><em>Dinner</em> — Steak fajitas (sliced ribeye, peppers, onions, flour
tortillas)</li>
</ul>

<p><img src="/images/posts//2026-05-25-camping-lake-winni-dam/lake-winni-dam-fajitas-on-the-grill.png" alt="Steak fajitas on the Blackstone griddle" /></p>

<p><strong>Sunday</strong></p>

<ul>
  <li><em>Breakfast</em> — Steak and eggs (using the leftover ribeye from Saturday)</li>
  <li><em>Lunch</em> — Steak quesadilla (more leftover ribeye, plus cheese)</li>
  <li><em>Dinner</em> — Garlic butter shrimp tacos</li>
</ul>

<p><strong>Monday</strong></p>

<ul>
  <li><em>Breakfast</em> — Cereal with milk</li>
</ul>

<p>The big win this trip was cooking the full pound of ribeye on Saturday
and stretching it across three meals. Saved a ton of time and fuel. The
shrimp tacos on Sunday were the standout — easily my favorite meal of
the weekend.</p>

<h2 id="who-i-missed">Who I Missed</h2>

<p>Two notable absences this weekend: Dee OhGee, our other Husky, who
stayed home, and my husband Jayson, who’s in Chicago with friends. Echo
and I had a great time, but the crew wasn’t complete. Looking forward to
having everyone back together for the next one.</p>

<hr />

<p><img src="/images/posts//2026-05-25-camping-lake-winni-dam/echo-in-background-of-campfire.png" alt="Echo by the campfire" /></p>

<p>That’s the trip. More to come — both here and on Mastodon. Thanks for
reading.</p>]]></content><author><name>Rōger Nōden</name></author><category term="Camping" /><category term="Outdoors" /><category term="Camping" /><category term="Overlanding" /><category term="Rivian R1T" /><category term="Gear" /><category term="Dogs" /><summary type="html"><![CDATA[Three nights at Lake Winni Dam with the R1T and Echo — one of the best Corps of Engineers campgrounds I've visited, plus gear notes and a menu built around one pound of ribeye.]]></summary></entry><entry><title type="html">Your Backlog Is a Conversation. Your AI Agents Need a Contract.</title><link href="https://rogernoden.com/2026/04/backlog-contract-for-ai-agents/" rel="alternate" type="text/html" title="Your Backlog Is a Conversation. Your AI Agents Need a Contract." /><published>2026-04-21T00:00:00-05:00</published><updated>2026-04-21T00:00:00-05:00</updated><id>https://rogernoden.com/2026/04/backlog-contract-for-ai-agents</id><content type="html" xml:base="https://rogernoden.com/2026/04/backlog-contract-for-ai-agents/"><![CDATA[<p>Last month I watched an autonomous coding agent pick up a ticket that read, in
full: <em>“As a customer, I want saved searches so I can return to my favorite
filters later.”</em> Thirty minutes later it had cheerfully rewritten the session
middleware, invented a new database table, and opened a pull request with a
confident title and a test suite that passed against the code it had just made
up.</p>

<p>It was, technically, a working implementation. It was also completely wrong.</p>

<p>The ticket wasn’t bad. A human engineer on the team would have glanced at it,
walked to the next desk (or opened a Slack DM), confirmed three unspoken
assumptions, and shipped something reasonable by lunch. The story assumed a
conversation. The agent didn’t have one.</p>

<p>This is the problem that catches most teams off guard when they bring AI agents
into real delivery work. The backlog we’ve spent fifteen years refining is a
beautifully human artifact. It rewards empathy, tolerates ambiguity, and leaves
space for tacit knowledge. Drop an autonomous agent into the middle of that same
pipeline and every helpful ambiguity turns into a failure mode.</p>

<h2 id="the-hidden-contract-of-a-user-story">The hidden contract of a user story</h2>

<p>A well-written user story is less a specification than an invitation. <em>“As a
user, I want…”</em> is a prompt for a conversation between the developer, the
product owner, and whatever stakeholder is about to be inconvenienced by an
ill-considered implementation. The story carries maybe twenty percent of the
information; the other eighty lives in the heads of the people working on it.</p>

<p>Humans are exceptional at reading that eighty percent from context. We know
which module owns the authentication path. We’ve been burned before by the ORM’s
quirks. We remember that the CTO has Strong Opinions about rate limiting. Agents
know none of this. They have a context window and whatever you put in it.</p>

<p>So the first shift is an uncomfortable one: for work an agent will pick up, the
ticket has to stop being a conversation starter and start being an actual
contract.</p>

<h2 id="what-a-machine-ready-ticket-looks-like">What a machine-ready ticket looks like</h2>

<p>The tickets I’ve seen work best for agents share a few structural traits.</p>

<p><strong>A concrete interface.</strong> Not <em>“the API should return the user’s saved
searches”</em> but the exact request and response shapes, field names and types
included. If it’s a database change, the table and column. If it’s a UI change,
the component file and the props it accepts. The agent cannot ask what you mean.</p>

<p><strong>An explicit blast radius.</strong> A short list of files or modules the agent is
allowed to modify, and — more importantly — a list of ones it must not touch.
Without this, agents have a habit of “improving” things while they’re in the
neighborhood. Last week I saw one refactor an entire logging utility because it
thought it could be cleaner. It could be. That wasn’t the ticket.</p>

<p><strong>The context, inline.</strong> If the work depends on a specific doc, the relevant
section goes in the ticket. If it depends on a library version, the version goes
in the ticket. The agent won’t wander off to Confluence to check. Whatever’s not
in the context window might as well not exist.</p>

<p><strong>Acceptance in executable form.</strong> Tests, cURL commands, or a short script that
can be run to verify the change. Pass/fail is the kind of signal agents can
actually work with. “Looks good to me” is not.</p>

<p>None of this is especially novel — a rigorous human engineer would welcome the
same artifact. The difference is that for humans it’s a nice-to-have, and for
agents it’s the difference between shipping and an expensive PR full of
confident nonsense.</p>

<h2 id="refinement-with-a-machine-in-the-loop">Refinement, with a machine in the loop</h2>

<p>Backlog refinement has always been the place where tickets get sharp enough to
work on. The interesting move some teams are making is putting a model in that
loop <em>before</em> the humans get there.</p>

<p>The pattern is simple: a cheap model reads every new ticket and flags the ones
that are missing the things agents need — no schema, no explicit scope, no
verifiable acceptance criteria. It doesn’t write the ticket. It just refuses to
let a fuzzy one through the gate, with a note like <em>“no defined response
schema; an agent cannot execute this safely.”</em></p>

<p>This catches problems that would otherwise surface as a failed agent run three
days later. And, almost as a side effect, it tends to make the tickets better
for the humans too. Turns out precision scales.</p>

<h2 id="estimation-when-the-worker-bills-per-token">Estimation, when the worker bills per token</h2>

<p>Story points were always a proxy — a way to talk about complexity and risk
without pretending we could predict wall-clock time. They work because humans
share a rough intuition for what “a 3” feels like.</p>

<p>Agents don’t have that intuition, and their costs are structured completely
differently. A ticket that would take a senior engineer an hour might cost ten
cents or ten dollars for an agent to run, depending almost entirely on how much
context has to be loaded and how many tool calls are needed to converge on an
answer.</p>

<p>Teams running hybrid workflows are starting to estimate two things on a ticket:
the human complexity (still useful, still fuzzy) and the agent cost envelope, in
tokens or dollars or compute minutes. The second number unlocks a call that
didn’t exist before — is this ticket worth $30 of agent time, or is it better
handled by a human while the bot works on something higher-leverage? That
tradeoff is a real one now, and it belongs on the ticket.</p>

<h2 id="pinning-the-strategy-to-the-agent-itself">Pinning the strategy to the agent itself</h2>

<p>Here is the trickiest part. A good human engineer carries the product’s strategy
around in their head. They won’t build the feature the right way if they don’t
know what “the right way” means for <em>this</em> product, this quarter, this company.
That intuition shapes a thousand small decisions that never show up in a ticket.</p>

<p>Agents start every task fresh. Unless you put the strategy into their context,
they don’t have one.</p>

<p>The teams doing this well are treating the product direction — the current
quarter’s goal, the architectural guardrails, the non-negotiables — as something
they inject into every agent prompt via retrieval. Not as a slogan pinned above
the coffee machine, but as literal text the model sees before it writes a single
line of code. <em>“This quarter we’re optimizing for latency over throughput”</em>
stops being a Notion page and starts being a constraint the model is measured
against on every pull request.</p>

<p>When you do this, the strategy stops being decorative. It becomes load-bearing.</p>

<h2 id="the-backlog-is-the-interface">The backlog is the interface</h2>

<p>The throughline in all of this is that the backlog has quietly changed jobs. It
used to be a shared to-do list. Now, for any team with agents in the mix, it’s
the primary interface between human intent and machine execution. It’s where
ambiguity is either resolved or becomes a bug. It’s where strategy either shows
up in the work or doesn’t.</p>

<p>That’s not a small shift, and I suspect most teams will make it by accident, one
painful PR at a time. The ones that make it deliberately — treating tickets as
contracts, refinement as a pipeline with both human and machine gates,
estimation as a real cost question, and strategy as something the agents can
actually see — are the ones who’ll get real leverage from autonomous tools
instead of just faster ways to generate confident nonsense.</p>

<p>The backlog was always supposed to be the source of truth. It just has to earn
the title now.</p>]]></content><author><name>Rōger Nōden</name></author><category term="Technology" /><category term="Development" /><category term="AI" /><category term="Agile" /><category term="Software Engineering" /><category term="Backlog" /><category term="Product Management" /><summary type="html"><![CDATA[User stories assume humans will fill in the gaps. Autonomous agents don't. Here's how to turn tickets into machine-ready contracts — and why the backlog is becoming the real interface between intent and execution.]]></summary></entry><entry><title type="html">Introducing Lamplit: A Word Puzzle Game from Alpine Blue</title><link href="https://rogernoden.com/2026/03/lamplit/" rel="alternate" type="text/html" title="Introducing Lamplit: A Word Puzzle Game from Alpine Blue" /><published>2026-03-02T23:00:00-06:00</published><updated>2026-03-02T23:00:00-06:00</updated><id>https://rogernoden.com/2026/03/lamplit</id><content type="html" xml:base="https://rogernoden.com/2026/03/lamplit/"><![CDATA[<p>Most of what I write here is about software leadership — building teams,
navigating organizations, thinking about how engineers grow. Today is
different. Today I want to tell you about something I’m <em>building</em>.</p>

<p>Over the past several months, my company Alpine Blue has been working on
<a href="https://lamplit.games">Lamplit</a> — a daily acrostic puzzle game for iPhone
and iPad. We’re in early beta, and I wanted to share what it is, why we
built it, and a few of the decisions that shaped it.</p>

<h2 id="whats-an-acrostic">What’s an acrostic?</h2>

<p>If you’ve never encountered the form, an acrostic is a word puzzle where
you solve a series of clues — each answer is a word or phrase — and then
the <em>first letter</em> of every answer, read top to bottom, spells a hidden
word. That hidden word is the “spine.”</p>

<p>The double acrostic variant goes further: both the <em>first and last</em> letters
of each answer contribute — spelling two words simultaneously, one down
each edge of the grid. If you’ve ever solved one in The Atlantic or the
Sunday newspaper, you know the particular satisfaction of watching a mystery
word emerge letter by letter as you work through the clues.</p>

<p>Acrostics have a long history. The Victorian era loved them — they were a
parlor game, a literary form, a way to hide messages in plain sight. We
wanted to bring that warmth and wordplay to a modern mobile game.</p>

<h2 id="what-is-lamplit">What is Lamplit?</h2>

<p>Lamplit is a daily acrostic puzzle game with a warm, unhurried aesthetic.
Each day there’s one puzzle: single acrostics on weekdays, double acrostics
on weekends. You solve it at your own pace — there are no timers, no
streaks that punish a missed day, no ads.</p>

<p>The game ships with two clue modes:</p>

<ul>
  <li><strong>Modern mode</strong> gives you clean, direct clues. Clear, fair, and
accessible.</li>
  <li><strong>Classic mode</strong> reaches back to the Victorian tradition — cryptic,
allusive, sometimes delightfully oblique. It unlocks after you’ve
completed about 25 puzzles, which felt like the right moment: once you’ve
internalized the structure of the puzzle, the puzzle itself can become
more interesting.</li>
</ul>

<p>The UI is dark-mode only, built around an amber and cream palette with New
York serif typography throughout. The name comes from that aesthetic — the
feeling of solving a puzzle by lamplight. Warm, focused, a little out of
time.</p>

<p>The business model is a one-time purchase (roughly $4.99) rather than a
subscription. We think word game fans are tired of paying indefinitely for
content that should just <em>be there</em>. Optional themed puzzle packs and small
consumable bundles (hint tokens, streak shields) let players support the
game beyond the initial unlock, but nothing is gated behind a paywall that
degrades the core experience.</p>

<p>Lamplit works fully offline. No account required to play.</p>

<h2 id="a-few-decisions-worth-explaining">A few decisions worth explaining</h2>

<p><strong>Why dark-mode only?</strong> It was an aesthetic choice first. The amber-on-dark
palette is central to the feeling we wanted — something that genuinely
looks and feels like lamplight. We didn’t want to compromise that with a
light mode that would need its own palette design and feel like a different
product. We may revisit this, but for now the constraint is also the
identity.</p>

<p><strong>Why Classic mode unlocks gradually?</strong> Victorian cryptic clues are
genuinely harder. Not harder in a punishing way — harder in the way that a
crossword clue with wordplay requires more fluency with the form than a
straight definition. We didn’t want new players encountering Classic clues
before they’d built up comfort with acrostics as a format. The unlock
threshold is an invitation, not a gate.</p>

<p><strong>Why SwiftUI and Swift 6?</strong> Partly because it’s the right tool for a new
iOS app in 2026 — the framework has matured considerably and the
concurrency model in Swift 6 is genuinely good. Partly because I find it
interesting to work close to the platform when building something from
scratch. SwiftData handles local persistence cleanly, and StoreKit 2 makes
the in-app purchase flow about as simple as it can be.</p>

<h2 id="where-things-stand">Where things stand</h2>

<p>Lamplit is in early beta. The core puzzle engine works. Daily delivery
works. The purchase flow works. What we’re refining: puzzle content, clue
quality, onboarding, and a handful of polish items that need more time in
real players’ hands.</p>

<p>We’re not ready to announce a launch date. What we’re ready to do is start
building a list of people who want to be notified when we go live.</p>

<h2 id="sign-up-for-early-access">Sign up for early access</h2>

<p>If any of this sounds like something you’d enjoy — or if you know a word
game enthusiast who might — head to <strong><a href="https://lamplit.games">lamplit.games</a></strong>
and leave your email. We’ll reach out when the game is ready for the App
Store.</p>

<p>I’ve spent a lot of years thinking about software from the outside.
Building Lamplit has been a good reminder of why I got into this in the
first place. I hope it’s something word game fans love.</p>

<p>If you have questions about the game, the tech, or the design decisions,
leave a comment below — I’d enjoy the conversation.</p>]]></content><author><name>Rōger Nōden</name></author><category term="Projects" /><category term="Games" /><category term="Indie Dev" /><category term="Alpine Blue" /><category term="iOS" /><summary type="html"><![CDATA[Alpine Blue is building Lamplit — an acrostic puzzle game for iOS rooted in the Victorian tradition of wordplay. We're in early beta, and here's what we've been making.]]></summary></entry><entry><title type="html">Building with AI Without Drowning in Technical Debt</title><link href="https://rogernoden.com/2025/09/building-with-ai/" rel="alternate" type="text/html" title="Building with AI Without Drowning in Technical Debt" /><published>2025-09-18T00:00:00-05:00</published><updated>2025-09-18T00:00:00-05:00</updated><id>https://rogernoden.com/2025/09/building-with-ai</id><content type="html" xml:base="https://rogernoden.com/2025/09/building-with-ai/"><![CDATA[<p>If you’ve built anything meaningful with AI at your side, you’ve probably felt
the rush: prompts fly, code appears, tests turn green, dopamine hits. Then
reality shows up—small changes start touching too many files, abstractions
multiply, and what felt like momentum becomes molasses. I’ve seen this across
teams and my own projects. The speed is real. So is the debt.</p>

<p>Andrew Stellman captured this dynamic well in his piece on AI-resistant
technical debt: “vibe coding”—rapid prompt → generate → run → paste errors →
regenerate—can turn exploration into accidental architecture if we don’t check
it. The result is familiar: over-coupling, god objects, needless layers, and
eventually shotgun surgery for simple changes. The trap isn’t that AI is wrong.
It’s that AI is convincing. It compiles, it passes tests, it feels done. But
design debt accrues silently. See the original commentary here:
<a href="https://www.oreilly.com/radar/building-ai-resistant-technical-debt/">Building AI-Resistant Technical Debt</a>.</p>

<h2 id="my-stance">My stance</h2>

<p>AI is a great accelerator for working software. It is a terrible decider of
design. I treat it like a pair who can type at 300 WPM, not a lead architect.
That mindset shift keeps me fast without locking bad decisions into the
foundation.</p>

<h2 id="the-failure-modes-i-watch-for">The failure modes I watch for</h2>

<ul>
  <li>Over-engineered indirection for simple I/O</li>
  <li>Hidden coupling (helper classes reaching into internals)</li>
  <li>Abstractions created to satisfy tests instead of improving design</li>
  <li>Test pain as an early warning system
(if adding a test feels hard, the design is hard)</li>
</ul>

<h2 id="guardrails-that-actually-work-in-practice">Guardrails that actually work in practice</h2>

<ol>
  <li>
    <p>Trust, then verify (quickly)</p>

    <p>Let AI draft. Then I do a 5–10 minute design pass: responsibilities,
boundaries, and names. If I can’t describe each unit’s single responsibility
in one sentence, I refactor before merging.</p>
  </li>
  <li>
    <p>Prefer simpler seams over frameworks</p>

    <p>Instead of wrapping I/O in a mini-architecture, pass inputs as parameters and
return values. Push complexity to the edges only when genuinely needed.</p>
  </li>
  <li>
    <p>Tests as design feedback, not just safety nets</p>

    <p>When a test is hard to write, I stop and adjust the API or dependency
direction. Pain here is a feature; it points to structure that wants to change.</p>
  </li>
  <li>
    <p>Time-boxed exploration, deliberate consolidation</p>

    <p>I allow messy exploratory branches. But I always follow with a consolidation
commit: rename for clarity, inline accidental abstractions, extract true seams,
delete dead code.</p>
  </li>
  <li>
    <p>Naming is a design act</p>

    <p>I take an explicit naming pass. Clear names reduce the surface area of
confusion more than another layer of code ever will.</p>
  </li>
</ol>

<h2 id="a-lightweight-working-checklist">A lightweight working checklist</h2>

<p>Use this when accepting AI-generated code:</p>

<ul>
  <li>Single responsibility per module or class?</li>
  <li>Dependencies point inward (domain) vs. outward (frameworks)?</li>
  <li>Input/Output handled at edges, not sprinkled through core logic?</li>
  <li>Tests easy to write without elaborate scaffolding?</li>
  <li>One level of abstraction per function? If not, split.</li>
  <li>Names read like documentation? If not, rewrite.</li>
</ul>

<h2 id="patterns-i-reach-for-instead-of-over-architecture">Patterns I reach for instead of over-architecture</h2>

<ul>
  <li>Data-in, result-out functions for core logic</li>
  <li>Ports-and-adapters only where boundaries are real (DB, network, UI)</li>
  <li>Composition over inheritance</li>
  <li>Feature flags and strangler patterns for incremental change</li>
</ul>

<h2 id="team-habits-that-prevent-ai-accelerated-debt">Team habits that prevent AI-accelerated debt</h2>

<ul>
  <li>Short design reviews for AI-heavy PRs (10 minutes, 3 questions:
responsibilities, coupling, testability)</li>
  <li>“Consolidation Fridays”—dedicated time to rename, simplify, and pay back
tiny debts before they grow</li>
  <li>Metrics that reward clarity (diff readability, test friction reduced) not
just throughput</li>
</ul>

<h2 id="final-thought">Final thought</h2>

<p>AI makes starting easy and finishing tempting. Craft lives in the middle—where
we decide what stays, what goes, and what gets clearer. Move fast, but edit
harder.</p>

<p>If this topic resonates, the O’Reilly piece is a solid read:
<a href="https://www.oreilly.com/radar/building-ai-resistant-technical-debt/">Building AI-Resistant Technical Debt</a>.
And if you try the checklist above, I’d love to hear what changed in your code
reviews.</p>

<p>— Roger</p>]]></content><author><name>Rōger Nōden</name></author><category term="Technology" /><category term="Development" /><category term="AI" /><category term="Software Engineering" /><category term="Technical Debt" /><category term="Architecture" /><category term="Practices" /><summary type="html"><![CDATA[AI makes it fast to ship—but just as fast to harden bad design. Here’s a practical approach I use to keep speed without compounding debt.]]></summary></entry><entry><title type="html">Measuring Success as a Scrum Team: Beyond Outcomes</title><link href="https://rogernoden.com/2025/07/measuring-scrum-master-success/" rel="alternate" type="text/html" title="Measuring Success as a Scrum Team: Beyond Outcomes" /><published>2025-07-01T00:00:00-05:00</published><updated>2025-07-01T00:00:00-05:00</updated><id>https://rogernoden.com/2025/07/measuring-scrum-master-success</id><content type="html" xml:base="https://rogernoden.com/2025/07/measuring-scrum-master-success/"><![CDATA[<p>In the complex world of agile project management, measuring the success of a Scrum
Team presents unique challenges. Unlike traditional projects with clear
deliverables and linear metrics, Scrum Teams operate in dynamic environments where
success is multifaceted and often emergent. This comprehensive guide explores a
nuanced approach to evaluating Scrum Team effectiveness that goes beyond simple
outcome-based measurements.</p>

<h2 id="the-challenge-of-measuring-scrum-team-success">The Challenge of Measuring Scrum Team Success</h2>

<p><strong>Here’s the hard truth: You cannot control outcomes in complex, unpredictable
environments.</strong> Even the most skilled Scrum Team cannot guarantee that
stakeholders will respond positively to change, that customers will embrace new
features, or that external market forces won’t disrupt carefully laid plans.</p>

<p>This reality creates a fundamental challenge in measuring Scrum Team success.
Traditional metrics focused solely on outcomes—like sprint goal achievement,
velocity, or customer satisfaction—tell only part of the story. They fail to
capture the nuanced ways a Scrum Team develops capabilities, adapts to change,
and builds sustainable practices that enable long-term success.</p>

<h2 id="a-three-lens-framework-for-success">A Three-Lens Framework for Success</h2>

<p>To develop a more comprehensive view of Scrum Team success, we need to examine
performance through three distinct but interconnected lenses:</p>

<h3 id="1-outcomes-still-matter-but-theyre-not-everything">1. Outcomes Still Matter (But They’re Not Everything)</h3>

<p>While we can’t control outcomes, they remain an important indicator of overall
team effectiveness. A successful Scrum Team should consistently:</p>

<ul>
  <li><strong>Deliver value incrementally</strong>: Teams consistently deliver usable product
increments every sprint</li>
  <li><strong>Meet sprint goals regularly</strong>: High success rate in achieving sprint
objectives</li>
  <li><strong>Improve predictability</strong>: Better estimation accuracy and delivery consistency
over time</li>
  <li><strong>Increase customer satisfaction</strong>: Positive feedback and reduced support issues</li>
</ul>

<p><strong>Key Questions to Ask:</strong></p>

<ul>
  <li>Are we delivering working software that customers actually use?</li>
  <li>How often do we meet our sprint goals?</li>
  <li>Is our velocity becoming more predictable over time?</li>
  <li>What does customer feedback tell us about the value we’re creating?</li>
</ul>

<h3 id="2-behaviors-the-leading-indicators">2. Behaviors: The Leading Indicators</h3>

<p>Behaviors are often the most reliable indicators of Scrum Team effectiveness
because they represent the day-to-day actions that lead to better outcomes. Focus
on these behavioral patterns:</p>

<h4 id="team-response-to-challenges">Team Response to Challenges</h4>

<ul>
  <li><strong>Early problem detection</strong>: Does the team identify impediments quickly?</li>
  <li><strong>Collaborative problem-solving</strong>: How does the team work together when issues
arise?</li>
  <li><strong>Resilience and adaptability</strong>: How well does the team handle setbacks?</li>
</ul>

<h4 id="learning-and-adaptation">Learning and Adaptation</h4>

<ul>
  <li><strong>Feedback loops</strong>: How quickly does the team learn from mistakes?</li>
  <li><strong>Continuous improvement</strong>: Is there evidence of evolving practices and
processes?</li>
  <li><strong>Retrospective effectiveness</strong>: Are action items from retrospectives actually
implemented?</li>
</ul>

<h4 id="communication-and-conflict-resolution">Communication and Conflict Resolution</h4>

<ul>
  <li><strong>Open dialogue</strong>: Are team members comfortable sharing concerns and ideas?</li>
  <li><strong>Constructive conflict</strong>: Does the team engage in healthy debates about
solutions?</li>
  <li><strong>Psychological safety</strong>: Do team members feel safe to take risks and make
mistakes?</li>
</ul>

<h4 id="scrum-values-in-action">Scrum Values in Action</h4>

<p>Observe how well the team embodies the five Scrum values:</p>

<ul>
  <li><strong>Courage</strong>: Willingness to tackle difficult problems and have tough
conversations</li>
  <li><strong>Focus</strong>: Ability to concentrate on sprint goals and minimize distractions</li>
  <li><strong>Commitment</strong>: Dedication to achieving goals and supporting each other</li>
  <li><strong>Respect</strong>: Valuing diverse perspectives and treating everyone with dignity</li>
  <li><strong>Openness</strong>: Transparency about work, challenges, and feelings</li>
</ul>

<h3 id="3-growing-team-maturity-the-deeper-layer">3. Growing Team Maturity: The Deeper Layer</h3>

<p>This is perhaps the most important but least discussed aspect of Scrum Team
success. It involves developing the collective capacity to:</p>

<h4 id="collective-emotional-intelligence">Collective Emotional Intelligence</h4>

<ul>
  <li><strong>Team emotional regulation</strong>: Managing collective stress and maintaining
composure during challenges</li>
  <li><strong>Mutual support</strong>: Team members actively supporting each other through
difficult periods</li>
  <li><strong>Shared resilience</strong>: Bouncing back from setbacks as a unified team</li>
</ul>

<h4 id="collaborative-learning-culture">Collaborative Learning Culture</h4>

<ul>
  <li><strong>Growth mindset</strong>: Approaching challenges as collective learning opportunities</li>
  <li><strong>Knowledge sharing</strong>: Freely sharing expertise and insights across the team</li>
  <li><strong>Experimentation</strong>: Willingness to try new approaches and learn from failures</li>
</ul>

<h4 id="systems-thinking-and-alignment">Systems Thinking and Alignment</h4>

<ul>
  <li><strong>Holistic perspective</strong>: Understanding how team actions affect the broader
organization</li>
  <li><strong>Pattern recognition</strong>: Collectively identifying recurring issues and root
causes</li>
  <li><strong>Strategic alignment</strong>: Connecting team work to organizational goals and
customer value</li>
</ul>

<h2 id="practical-measurement-strategies">Practical Measurement Strategies</h2>

<h3 id="1-team-health-metrics">1. Team Health Metrics</h3>

<p>Implement regular team health assessments that measure:</p>

<ul>
  <li><strong>Team satisfaction scores</strong>: Regular anonymous surveys about job satisfaction
and team dynamics</li>
  <li><strong>Psychological safety index</strong>: Measure how safe team members feel to speak up
and take risks</li>
  <li><strong>Collaboration effectiveness</strong>: Assess how well team members work together</li>
  <li><strong>Learning velocity</strong>: Track how quickly the team adopts new practices and
improves</li>
</ul>

<h3 id="2-behavioral-indicators-tracking">2. Behavioral Indicators Tracking</h3>

<p>Create a simple tracking system for key behaviors:</p>

<ul>
  <li><strong>Retrospective action item completion rate</strong>: What percentage of improvement
actions are actually implemented?</li>
  <li><strong>Impediment resolution time</strong>: How quickly are blockers identified and
resolved?</li>
  <li><strong>Cross-functional collaboration</strong>: Frequency and quality of interactions with
other teams</li>
  <li><strong>Self-organization maturity</strong>: How independently can the team operate?</li>
</ul>

<h3 id="3-team-maturity-assessment">3. Team Maturity Assessment</h3>

<p>Evaluate team maturity development through:</p>

<ul>
  <li><strong>360-degree team feedback</strong>: Gather input from stakeholders, other teams, and
leadership</li>
  <li><strong>Team reflection sessions</strong>: Regular collective assessment of growth areas and
team dynamics</li>
  <li><strong>Peer development effectiveness</strong>: Measure how well team members develop each
other</li>
  <li><strong>Change adaptability</strong>: Assess the team’s ability to navigate transitions and
challenges</li>
</ul>

<h2 id="common-questions-and-answers">Common Questions and Answers</h2>

<h3 id="q-how-do-we-measure-success-when-our-teams-outcomes-are-poor-despite-following-scrum-practices">Q: How do we measure success when our team’s outcomes are poor despite following Scrum practices?</h3>

<p><strong>A:</strong> This is exactly why the three-lens approach is crucial. Poor outcomes
don’t necessarily indicate poor team performance. Look at:</p>

<ul>
  <li>Are team behaviors improving even if outcomes aren’t yet?</li>
  <li>Is the team learning and adapting faster than before?</li>
  <li>Are external factors (market conditions, organizational constraints) impacting
outcomes?</li>
  <li>Is team maturity and collective capability growing?</li>
</ul>

<p>Focus on what the team can influence and measure progress in those areas.</p>

<h3 id="q-what-if-our-organization-only-cares-about-delivery-metrics">Q: What if our organization only cares about delivery metrics?</h3>

<p><strong>A:</strong> Start by connecting behavioral improvements to delivery outcomes. For
example:</p>

<ul>
  <li>Show how improved retrospective practices led to faster impediment resolution</li>
  <li>Demonstrate how better team communication reduced rework</li>
  <li>Highlight how increased psychological safety improved innovation and
problem-solving</li>
  <li>Present data showing correlation between team behaviors and delivery performance</li>
</ul>

<p>Gradually educate stakeholders about leading vs. lagging indicators.</p>

<h3 id="q-how-often-should-we-measure-these-different-aspects">Q: How often should we measure these different aspects?</h3>

<p><strong>A:</strong> Use different cadences for different measurements:</p>

<ul>
  <li><strong>Outcomes</strong>: Monthly or quarterly reviews</li>
  <li><strong>Behaviors</strong>: Weekly team observations and monthly assessments</li>
  <li><strong>Team maturity</strong>: Quarterly deep dives with annual comprehensive reviews</li>
</ul>

<h3 id="q-what-if-were-not-seeing-improvement-in-any-of-these-areas">Q: What if we’re not seeing improvement in any of these areas?</h3>

<p><strong>A:</strong> This signals a need for deeper investigation:</p>

<ul>
  <li>Are there organizational impediments preventing the team’s progress?</li>
  <li>Does the team need additional coaching, training, or resources?</li>
  <li>Are there unaddressed team dynamics issues?</li>
  <li>Is the team ready for the level of change being attempted?</li>
  <li>Are expectations realistic given the team’s current context and constraints?</li>
</ul>

<h2 id="the-sustainability-factor">The Sustainability Factor</h2>

<p>A truly successful Scrum Team creates sustainable practices and continuous
improvement. Ask yourselves:</p>

<ul>
  <li><strong>Can the team function effectively when any individual member is absent?</strong></li>
  <li><strong>Are team members developing coaching and facilitation skills to support each
other?</strong></li>
  <li><strong>Is the team’s improvement trajectory continuing even during challenging
periods?</strong></li>
  <li><strong>Are other teams seeking to learn from this team’s practices and approaches?</strong></li>
</ul>

<h2 id="moving-beyond-traditional-metrics">Moving Beyond Traditional Metrics</h2>

<p>Success isn’t about checking boxes or achieving perfect velocity. It’s about
<strong>direction</strong>, <strong>discernment</strong>, and <strong>depth</strong>. It’s about creating a culture
where the team can thrive, learn, and adapt to whatever challenges come their
way.</p>

<p>Just as a surfer works with the ocean’s energy rather than trying to control it,
a successful Scrum Team learns to work with the complex dynamics of their
environment, creating conditions for success rather than trying to force specific
outcomes.</p>

<h2 id="your-team-success-reflection-framework">Your Team Success Reflection Framework</h2>

<p>To implement this approach, regularly ask yourselves these three key questions as
a team:</p>

<ol>
  <li><strong>What outcomes are we influencing and how?</strong>
    <ul>
      <li>Focus on the team’s sphere of influence rather than control</li>
      <li>Look for patterns in team performance over time</li>
      <li>Connect team actions to observable results</li>
    </ul>
  </li>
  <li><strong>What behaviors are we improving—individually and collectively?</strong>
    <ul>
      <li>Observe daily interactions and team dynamics</li>
      <li>Track improvements in communication and collaboration</li>
      <li>Notice changes in how the team handles challenges</li>
    </ul>
  </li>
  <li><strong>How are we expanding our collective capability and maturity?</strong>
    <ul>
      <li>Assess the team’s growth in skills and effectiveness</li>
      <li>Measure how well team members are developing each other</li>
      <li>Evaluate the sustainability of changes and improvements</li>
    </ul>
  </li>
</ol>

<h2 id="conclusion">Conclusion</h2>

<p>Measuring Scrum Team success requires a sophisticated understanding of complex
systems, human behavior, and organizational dynamics. By using the three-lens
framework of outcomes, behaviors, and team maturity, teams can develop a more
complete picture of their effectiveness and impact.</p>

<p>Remember: <strong>Your team’s worth is not defined by any single metric or
measurement.</strong> A team’s value extends far beyond what can be captured in
traditional performance indicators.</p>

<p>The goal isn’t perfection—it’s progress. Focus on creating conditions where the
team can flourish, learn, and adapt. Measure success by the collective growth,
resilience, and capability the team develops together. That’s how we measure
success in complex and unpredictable environments. That’s how effective Scrum
Teams thrive.</p>

<h2 id="key-takeaways">Key Takeaways</h2>

<ul>
  <li>Team success measurement should encompass outcomes, behaviors, and team maturity
development</li>
  <li>Behaviors are often better leading indicators than outcomes alone</li>
  <li>Psychological safety and team health are crucial metrics for long-term success</li>
  <li>Sustainable change requires developing the collective capability of all team
members</li>
  <li>Regular reflection and multi-dimensional assessment provide the most complete
picture of team effectiveness</li>
</ul>

<p><em>Have you implemented any of these measurement approaches in your Scrum Team?
What challenges have you faced in defining and measuring team success? Share your
experiences in the comments below.</em></p>]]></content><author><name>Rōger Nōden</name></author><category term="Agile" /><category term="Leadership" /><category term="Scrum" /><category term="Agile" /><category term="Leadership" /><category term="Project Management" /><category term="Team Development" /><summary type="html"><![CDATA[Discover a comprehensive framework for measuring Scrum Team success that goes beyond traditional outcomes to include behaviors, leadership capacity, and team sustainability]]></summary></entry></feed>