<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Customer Obsessed Engineering]]></title><description><![CDATA[Elevate your career, execute with confidence, and build your customer obsessed mindset. Advice from an ex-Accenture Director, startup veteran, CTO.]]></description><link>https://blog.bosslogic.com</link><image><url>https://substackcdn.com/image/fetch/$s_!SRH_!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5de8a7cd-651e-4f84-b61d-8f100b23db5a_250x250.png</url><title>Customer Obsessed Engineering</title><link>https://blog.bosslogic.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 03 Jul 2026 18:25:37 GMT</lastBuildDate><atom:link href="https://blog.bosslogic.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Boss Logic, Inc.]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[bosslogic@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[bosslogic@substack.com]]></itunes:email><itunes:name><![CDATA[Zac Beckman]]></itunes:name></itunes:owner><itunes:author><![CDATA[Zac Beckman]]></itunes:author><googleplay:owner><![CDATA[bosslogic@substack.com]]></googleplay:owner><googleplay:email><![CDATA[bosslogic@substack.com]]></googleplay:email><googleplay:author><![CDATA[Zac Beckman]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[You delivered every feature and nobody's happy]]></title><description><![CDATA[A feature is something you build. An outcome is the difference it makes &#8212; and only one of them was ever the point.]]></description><link>https://blog.bosslogic.com/p/you-delivered-every-feature-and-nobodys-happy</link><guid isPermaLink="false">https://blog.bosslogic.com/p/you-delivered-every-feature-and-nobodys-happy</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Wed, 01 Jul 2026 06:28:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!oUcJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oUcJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oUcJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg 424w, https://substackcdn.com/image/fetch/$s_!oUcJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg 848w, https://substackcdn.com/image/fetch/$s_!oUcJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!oUcJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oUcJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg" width="972" height="700" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:700,&quot;width&quot;:972,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:174967,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/204307391?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oUcJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg 424w, https://substackcdn.com/image/fetch/$s_!oUcJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg 848w, https://substackcdn.com/image/fetch/$s_!oUcJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!oUcJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4efddba3-f0d9-4af4-84ff-cb79481faf56_972x700.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><span>Photo by </span><a href="https://unsplash.com/@mikafinland?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Mika Ruusunen</a><span> on </span><a href="https://unsplash.com/photos/man-in-black-crew-neck-shirt-IC1KHHKD-S0?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>Walk into too many companies mid-pivot to &#8220;outcome-driven&#8221; and you&#8217;ll find the same thing: a roadmap that <em>sounds</em> like a transformation but runs exactly as it did before. Leadership saw the problem, read the books and issued the decree &#8212; &#8220;no more feature factories.&#8221; The team, wanting to comply but not given the time and autonomy to invest in real transformation, reaches for a version of compliance that takes an afternoon instead of a quarter. They go down the roadmap and rename everything.</p><p>&#8220;Build SSO&#8221; becomes &#8220;Deliver enterprise authentication.&#8221; &#8220;Add CSV export&#8221; turns into &#8220;Enable customer data portability.&#8221; &#8220;Upgrade the search index&#8221; blossoms into &#8220;Provide a world-class discovery experience.&#8221; Every line is a feature wearing a grander name. The roadmap is the same roadmap. The order is the same order. The way they decide what to build hasn&#8217;t budged, and neither has the way they&#8217;ll &#8212; or won&#8217;t &#8212; know whether any of it worked.</p><p>They&#8217;ve run find-and-replace on a feature list and called it a transformation.</p><p>This isn&#8217;t a strawman, and it isn&#8217;t rare &#8212; it&#8217;s the rule. The move from features to outcomes is the most preached idea in product transformation. It&#8217;s also the one most often faked. People adopt the vocabulary in an afternoon and skip the part that actually costs something. Then a year later they&#8217;ve shipped everything they promised, the burndown charts look beautiful and somehow nobody &#8212; not the customer, not the business, not even the team that shipped it &#8212; is any happier.</p><p>By happy I don&#8217;t mean satisfied in some vague, mood-survey sense. I mean the only thing that actually counts: the customer got a real problem solved, and the business got the change it paid to produce. Shipping features guarantees neither. I want to unpack why that is, and what an outcome actually is, because the gap between renaming your features and genuinely working from <em>real outcomes</em> is the gap between a busy year and a year that mattered.</p><div class="pullquote"><p><em>If you&#8217;re new, welcome to Customer Obsessed Engineering! I publish about one article each week. Free subscribers can read about half of every article, plus all of my free articles.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/subscribe?"><span>Subscribe now</span></a></p></div><h2>What an outcome actually is</h2><p>There&#8217;s a line from General Patton that product people love to quote: &#8220;Never tell people how to do things. Tell them what to do and they will surprise you with their ingenuity.&#8221; Marty Cagan opens his case against roadmaps with it. A conventional feature roadmap does exactly what the General warned against. It dictates the <em>how</em> &#8212; build this, then this, then this &#8212; instead of naming the <em>what</em>, the result you actually need, and it quietly smuggles in an assumption: that whoever wrote the list already knows which features will produce that result.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><p>Cagan&#8217;s example is a single innocent-looking line: &#8220;integrate PayPal.&#8221; Why is it there? Is it because a segment of customers genuinely can&#8217;t pay any other way? Because international payments are failing? Because the fees are too high? Because a competitor has it and someone got nervous? Each of those is a different problem, and the roadmap line names none of them. Maybe integrating PayPal addresses the real one; maybe it&#8217;s beside the point entirely. With only the feature in front of you, there&#8217;s no way to judge whether it&#8217;s the right bet &#8212; and no way to tell afterward whether it worked. The feature is on the roadmap. The reason is nowhere.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p><p>Here&#8217;s the distinction the whole topic hinges on. A feature is something you build. An outcome is the difference that thing makes for a customer or for the business. Josh Seiden, whose <em>Outcomes Over Output</em> is the book on this exact subject, compresses it to one line: an outcome is &#8220;a change in human behavior that drives business results.&#8221; Cagan and Felipe Castro frame the same idea operationally &#8212; an outcome is two inseparable parts: a clear problem to solve and a measure that tells you whether you&#8217;ve solved it. &#8220;Integrate PayPal&#8221; is an output. &#8220;Reduce checkout abandonment for international customers&#8221; is the beginning of an outcome &#8212; and the moment you state it that way, you&#8217;ll notice that PayPal is now just one of several ideas you might test, not a foregone conclusion.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self">4</a></p><p>That&#8217;s the real shift, and it&#8217;s why renaming does nothing. &#8220;Deliver enterprise authentication&#8221; is still an instruction to build a thing. It never names the problem, so it can never be measured, so the team is right back to being judged on whether they shipped &#8212; which is precisely the trap everyone claims to be escaping.</p><h2>How to write one that holds up</h2><p>The format I use, the one described in Chapter <a href="https://blog.bosslogic.com/p/22-roadmaps-and-okrs">2.2 Roadmaps and OKRs</a> of the Delivery Playbook, is deliberately boring: <em>we will [objective] as measured by [key result].</em> The objective is the problem, stated qualitatively. The key result is the measure, stated in numbers. Force both halves to exist and you make it almost impossible to disguise a feature as an outcome, because a feature has no measure of success that isn&#8217;t just &#8220;we shipped it.&#8221;</p><p>The most common way this goes wrong is mistaking the work for the result. I&#8217;ve seen this version more times than I can count:</p><blockquote><p>Objective: cut warehouse order processing data-quality errors reported to the support desk.</p><p>Key result: implement improved CSV to JSON data intake parser to handle empty, missing and null data values reliably.</p></blockquote><p>Implementing fixes to the parser is an activity. It&#8217;s the thing you suspect <em>might</em> reduce errors. It is not evidence that errors went down overall. A real key result names the change in the world you&#8217;re after:</p><blockquote><p>Objective: cut warehouse order processing data-quality errors reported to the support desk.</p><p>Key results:</p><ul><li><p>support desk data quality issues reduced from over 20 per day to less than 1 per week.</p></li><li><p>orders that fail on bad warehouse data reduced from current 7% to under 1%.</p></li></ul></blockquote><p>Notice those measure <em>customer-visible reality</em>, not internal effort. And notice they&#8217;re <em>leading</em> indicators where possible &#8212; things you can watch move week over week &#8212; rather than a single lagging number you only get to read at the end. Teresa Torres draws this line cleanly: a <em>business outcome</em> like revenue or churn is a lagging indicator, mostly outside any one team&#8217;s direct control, while a <em>product outcome</em> is a measurable change in user behavior that the team can move now and that leads the business result. So if the outcome you care about is annual recurring revenue, you don&#8217;t wait a year to find out how you did. You pick the behaviors that roll up to it &#8212; activation, conversion, the support tickets that signal friction &#8212; and move those.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-5" href="#footnote-5" target="_self">5</a></p><p>Castro keeps a running list of what clear problems sound like, and it&#8217;s worth internalizing the cadence: help customers solve issues without having to contact us; reduce the time for a user to produce their first monthly report; reduce the subscriber churn rate; connect job seekers with more suitable jobs. Every one names a difference in someone&#8217;s experience. None of them names a feature. That&#8217;s the test.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-6" href="#footnote-6" target="_self">6</a></p><h2>Why renaming isn&#8217;t enough</h2><p>If stating an outcome were the whole job, the move would be easy and far more teams would pull it off. Too often, they don&#8217;t, and Cagan is precise about why. Working from outcomes only functions when two other things are already in place.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-7" href="#footnote-7" target="_self">7</a></p><p>The first is context. An outcome handed to a team in isolation isn&#8217;t enough &#8212; the team also needs the bigger picture of where the company is going, which is the job of a genuine <a href="https://blog.bosslogic.com/p/13-product-vision">product vision</a>. Without it, a team optimizing its little metric can cheerfully march in the wrong direction. The second is a real <a href="https://blog.bosslogic.com/p/21-product-strategy">product strategy</a>: the reasoning that connects top-level business goals to the specific, prioritized problems each team is asked to solve. Most organizations skip this entirely. They have business goals and they have a pile of feature ideas they hope will hit those goals, and the empty space between the two is exactly where strategy is supposed to live.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-8" href="#footnote-8" target="_self">8</a></p><p>Here&#8217;s the typical misstep. A company decides to &#8220;do outcomes,&#8221; and immediately limits itself to the outcomes its existing dashboards can already measure. Everything else stays a feature. But the most valuable problems are very often the ones you don&#8217;t instrument yet &#8212; the ones that require defining a new metric and doing the unglamorous work of collecting the data. Letting your current KPIs decide which problems are allowed isn&#8217;t rigor. It&#8217;s the tail wagging the dog.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-9" href="#footnote-9" target="_self">9</a></p><p>This is also the real reason OKRs earned such a black eye. Thousands of companies layered the OKR ritual on top of an unchanged, output-driven roadmap process and were baffled when nothing improved. The technique didn&#8217;t fail them. They&#8217;d bolted a product-model practice onto a <a href="https://blog.bosslogic.com/p/what-a-product-oriented-team-looks-like">feature-factory operating model</a> and kept everything else the same &#8212; the same funding by project, the same stakeholders dictating features, the same definition of done. You can&#8217;t adopt the scoreboard and refuse to change the game.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-10" href="#footnote-10" target="_self">10</a></p><p>This is what I&#8217;ve written about in <em><a href="https://blog.bosslogic.com/p/product-teams-really-do-outperform">Product teams really do outperform</a></em> and, more tactically, in <em><a href="https://blog.bosslogic.com/p/can-you-rely-on-safe-to-deliver-elite-gains">Can you rely on SAFe to deliver elite-performer gains?</a></em>. So renaming <em>alone</em> is nowhere near enough, but an honest shift toward true outcome-based goals is a real beginning. It&#8217;s also just half the battle if your ultimate goal is elite-performing results.</p><div class="pullquote"><p><em>This newsletter grows by word of mouth&#8230; I&#8217;d really, truly appreciate it if you could refer a friend. Your referrals make it worthwhile.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p></div><h2>Not everything is an outcome &#8212; and an honest test</h2><p>A fair objection: does <em>every</em> line really have to become a problem-to-solve with a metric attached? No, and pretending otherwise is its own kind of theater. There&#8217;s always a set of keep-the-lights-on work &#8212; bug fixes, a compliance report you now have to file, a tracking pixel a partner needs. Cagan&#8217;s advice is refreshingly blunt: unless there&#8217;s real risk involved, don&#8217;t agonize over the outcome. Put it straight on the backlog and knock it out. Reserve the outcome discipline for the work where it actually changes what you&#8217;d build.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-11" href="#footnote-11" target="_self">11</a></p><p>I like to test assumptions. <em>Challenge them</em> by looking for an outcome. A true KTLO emergency &#8212; the system is down, get it online fast &#8212; is easy to wave off as &#8220;exempt&#8221; but don&#8217;t stop there. Make sure the server doesn&#8217;t crash again. Put a metric in place to validate the tracking pixel actually <em>delivers</em> data our partner can act on. &#8220;Exempt&#8221; means no decision changes based on the answer. Do the work, keep it, and move on no matter what. Measuring it would be theater. That&#8217;s true KTLO.</p><p>On the other hand, if the result would change what you do next, it&#8217;s product work wearing a KTLO costume, and it earns an outcome.</p><p>Each passes its litmus test by informing a decision &#8212; keep going, change approach or kill it. A measure that informs nothing is a vanity metric.</p><p>And if you want to know honestly where you stand today, run the look-back test Cagan recommends. Pull up last year&#8217;s roadmap and grade it &#8212; not on how many items you delivered, but on how many actually moved the business result they were meant to move. Most teams have never done this, and the first time is uncomfortable, because the delivery rate is usually high and the impact rate is usually grim. <em>That discomfort is the point.</em> It&#8217;s the same gap the research keeps finding at the industry level: the majority of shipped features see little or no use. A team measured on output looks productive while quietly building a mountain of work nobody wanted. Outcomes are how you stop mistaking motion for progress.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-12" href="#footnote-12" target="_self">12</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-13" href="#footnote-13" target="_self">13</a></p><h2>Where to start on Monday</h2><p>You don&#8217;t need a reorganization to begin. You need one honest pass through your current roadmap.</p><p>Take it line by line, and for each feature ask two questions: what problem is this supposed to solve, and how would we know if it did? Write the answers down. Some lines will resolve cleanly into a problem and a measure &#8212; those were outcomes all along, just mislabeled. Some will expose that you have no idea why the feature is there, which is the most useful thing you can learn. And some are keep-the-lights-on work that belongs on the backlog, no ceremony required. What you&#8217;re left with maps almost one-to-one onto a set of OKRs, which is exactly what Cagan means when he says the two are the same idea in different clothes.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-14" href="#footnote-14" target="_self">14</a></p><p>The goal of all this isn&#8217;t tidier paperwork. It&#8217;s what I call line of sight &#8212; the property that any person on the team, asked at any moment why they&#8217;re working on the thing in front of them, can name the customer problem it solves and the number that will prove it. When that line of sight exists, you stop shipping features into the void and hoping. You start solving problems and knowing.</p><p>You can rename every feature on your roadmap by Friday. It will feel like progress and change nothing. Or you can do the harder, slower work of naming the problems and the measures &#8212; and actually have something to show the next time someone asks whether all that shipping made anyone happier. It will count for something &#8212; but it&#8217;s only base camp on the climb to a true <a href="https://blog.bosslogic.com/p/product-teams-really-do-outperform">product-team transformation</a>.</p><div><hr></div><p><em>For the mechanics of turning objectives into measurable key results, see the Delivery Playbook chapter <a href="https://blog.bosslogic.com/p/22-roadmaps-and-okrs">2.2 Roadmaps and OKRs</a>, and its companions on <a href="https://blog.bosslogic.com/p/21-product-strategy">2.1 Product strategy</a> and <a href="https://blog.bosslogic.com/p/13-product-vision">1.3 Product vision</a>. For the evidence that outcome-driven product teams genuinely outperform, see <a href="https://blog.bosslogic.com/p/product-teams-really-do-outperform">Product teams really do outperform: bringing the receipts</a>.</em></p><div><hr></div><p style="text-align: center;"><em>Word-of-mouth is how this newsletter grows, and your support means everything.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share Customer Obsessed Engineering&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share Customer Obsessed Engineering</span></a></p><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-1" href="#footnote-anchor-1" class="footnote-number" contenteditable="false" target="_self">1</a><div class="footnote-content"><p>The line is widely sourced to George S. Patton, <em>War As I Knew It</em> (Houghton Mifflin, 1947). Marty Cagan opens <a href="https://www.svpg.com/the-alternative-to-roadmaps/">&#8220;The Alternative to Roadmaps&#8221;</a> (Silicon Valley Product Group, September 7, 2015) with a looser paraphrase of it. The PayPal example and the year-end look-back exercise are from Cagan&#8217;s article.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-2" href="#footnote-anchor-2" class="footnote-number" contenteditable="false" target="_self">2</a><div class="footnote-content"><p>Cagan, <a href="https://www.svpg.com/the-alternative-to-roadmaps/">&#8220;The Alternative to Roadmaps,&#8221;</a> op. cit.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-3" href="#footnote-anchor-3" class="footnote-number" contenteditable="false" target="_self">3</a><div class="footnote-content"><p>Josh Seiden, <em>Outcomes Over Output: Why Customer Behavior Is the Key Metric for Business Success</em> (Sense &amp; Respond Press, 2019). The definition &#8212; &#8220;an outcome is a change in human behavior that drives business results&#8221; &#8212; is the book&#8217;s central thesis.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-4" href="#footnote-anchor-4" class="footnote-number" contenteditable="false" target="_self">4</a><div class="footnote-content"><p>Marty Cagan and Felipe Castro, <a href="https://www.svpg.com/outcomes-are-hard/">&#8220;Outcomes Are Hard,&#8221;</a> Silicon Valley Product Group. Source for the problem-plus-measure framing, the list of clear problem statements, the &#8220;letting existing metrics dictate problems&#8221; mistake and the account of why bolting OKRs onto an output-based roadmap fueled the OKR backlash.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-5" href="#footnote-anchor-5" class="footnote-number" contenteditable="false" target="_self">5</a><div class="footnote-content"><p>Teresa Torres, <em>Continuous Discovery Habits: Discover Products That Create Customer Value and Business Value</em> (Product Talk LLC, 2021). Torres distinguishes <em>business outcomes</em> &#8212; lagging indicators such as revenue or churn, largely outside a single team&#8217;s direct control &#8212; from <em>product outcomes</em>, measurable changes in user behavior that a team can move now and that lead the business result.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-6" href="#footnote-anchor-6" class="footnote-number" contenteditable="false" target="_self">6</a><div class="footnote-content"><p>Cagan and Castro, <a href="https://www.svpg.com/outcomes-are-hard/">&#8220;Outcomes Are Hard,&#8221;</a> op. cit.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-7" href="#footnote-anchor-7" class="footnote-number" contenteditable="false" target="_self">7</a><div class="footnote-content"><p>Marty Cagan, <a href="https://www.svpg.com/roadmap-alternative-faq/">&#8220;Roadmap Alternative FAQ,&#8221;</a> Silicon Valley Product Group, September 21, 2015. Source for the point that an outcome alone is not enough context (a product vision is also required), the 1:1 mapping between OKRs and an outcome-based roadmap and the handling of keep-the-lights-on items.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-8" href="#footnote-anchor-8" class="footnote-number" contenteditable="false" target="_self">8</a><div class="footnote-content"><p>Marty Cagan, <em>Empowered: Ordinary People, Extraordinary Products</em> (Wiley, 2020) and <em>Transformed: Moving to the Product Operating Model</em> (Wiley, 2024). The distinction between a genuine product strategy and a pile of hopeful feature ideas is developed at length in both.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-9" href="#footnote-anchor-9" class="footnote-number" contenteditable="false" target="_self">9</a><div class="footnote-content"><p>Cagan and Castro, <a href="https://www.svpg.com/outcomes-are-hard/">&#8220;Outcomes Are Hard,&#8221;</a> op. cit.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-10" href="#footnote-anchor-10" class="footnote-number" contenteditable="false" target="_self">10</a><div class="footnote-content"><p>Cagan and Castro, <a href="https://www.svpg.com/outcomes-are-hard/">&#8220;Outcomes Are Hard,&#8221;</a> op. cit.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-11" href="#footnote-anchor-11" class="footnote-number" contenteditable="false" target="_self">11</a><div class="footnote-content"><p>Cagan, <a href="https://www.svpg.com/roadmap-alternative-faq/">&#8220;Roadmap Alternative FAQ,&#8221;</a> op. cit.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-12" href="#footnote-anchor-12" class="footnote-number" contenteditable="false" target="_self">12</a><div class="footnote-content"><p>Cagan, <a href="https://www.svpg.com/the-alternative-to-roadmaps/">&#8220;The Alternative to Roadmaps,&#8221;</a> op. cit.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-13" href="#footnote-anchor-13" class="footnote-number" contenteditable="false" target="_self">13</a><div class="footnote-content"><p>Pendo, <a href="https://www.pendo.io/resources/the-2019-feature-adoption-report/">2019 Feature Adoption Report</a>, which analysed 615 product subscriptions and found roughly 80% of features rarely or never used. The older Standish Group CHAOS research points the same direction (and has itself drawn methodology critiques); I lay out the fuller evidence in <a href="https://blog.bosslogic.com/p/product-teams-really-do-outperform">Product teams really do outperform: bringing the receipts</a>.</p></div></div><div class="footnote" data-component-name="FootnoteToDOM"><a id="footnote-14" href="#footnote-anchor-14" class="footnote-number" contenteditable="false" target="_self">14</a><div class="footnote-content"><p>Cagan, <a href="https://www.svpg.com/roadmap-alternative-faq/">&#8220;Roadmap Alternative FAQ,&#8221;</a> op. cit.</p></div></div>]]></content:encoded></item><item><title><![CDATA[Part 4: Coding the steel thread (all the way to production)]]></title><description><![CDATA[From architecture to production-ready in one sprint &#8212; proving the shape of the pipeline before we wire up the message broker.]]></description><link>https://blog.bosslogic.com/p/part-4-coding-the-steel-thread</link><guid isPermaLink="false">https://blog.bosslogic.com/p/part-4-coding-the-steel-thread</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Wed, 17 Jun 2026 09:46:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!h5KB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!h5KB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!h5KB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg 424w, https://substackcdn.com/image/fetch/$s_!h5KB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg 848w, https://substackcdn.com/image/fetch/$s_!h5KB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!h5KB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!h5KB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:202044,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/202274154?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!h5KB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg 424w, https://substackcdn.com/image/fetch/$s_!h5KB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg 848w, https://substackcdn.com/image/fetch/$s_!h5KB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!h5KB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d2383e0-c43b-4620-a6c3-f22c3a676adc_2064x1161.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@mpikman?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Evangelos Mpikakis</a> on <a href="https://unsplash.com/photos/a-view-of-the-inside-of-a-train-tunnel-L7wGCmV-f08?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>In this fourth article on data pipelines we move from architecture to code. Our goal is a working <a href="https://blog.bosslogic.com/p/solve-delivery-with-a-steel-thread">steel thread</a> &#8212; a thin slice of the pipeline that touches every major component end-to-end. By the time we&#8217;re finished, raw data will flow in from an external source, pass through an anti-corruption layer, land in our internal cache, get transformed and annotated in stages and emerge as something a consumer can read.</p><p>We won&#8217;t be building a complete application. I&#8217;ll assume you can stand up a project, wire up a database and run a web server. What we <em>will</em> focus on is <em>technique</em> &#8212; the small architectural moves that make the difference between a pipeline that grows gracefully and one that gets thrown away in six months.</p><p>The previous three articles set the stage. We talked about <a href="https://blog.bosslogic.com/p/data-pipelines-are-really-cool">why data pipelines are interesting</a>, the <a href="https://blog.bosslogic.com/p/part-2-a-practical-data-pipeline-architecture">foundational architecture</a> needed to support our requirements and the <a href="https://blog.bosslogic.com/p/part-3-solving-hidden-pipeline-architecture-challenges">refinements</a> that make it scalable, resilient and ready to evolve. If you haven&#8217;t read them, this article will still make sense &#8212; but you&#8217;ll get more out of it if you have.</p><div class="pullquote"><p><em>If you&#8217;re new, welcome to Customer Obsessed Engineering! I publish about one article each week. Free subscribers can read about half of every article, plus all of my free articles.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/subscribe?"><span>Subscribe now</span></a></p></div><h2>Two (small) sprints, one steel thread</h2><p>Our architecture has a lot of moving parts: an external data source, an anti-corruption layer (or &#8220;ACL,&#8221; a term borrowed from Domain-Driven Design that I&#8217;ll explain in a moment), an internal cache, a chain of analytical stages, an annotation pattern, an event backbone and a visualization layer. Standing all of that up at once is too much for one sprint. We&#8217;ll split the work into two sprints, each producing a runnable system.</p><p>In <em>sprint one</em> we deliver the framework &#8212; the shape of the pipeline &#8212; with every piece wired up except real event streaming. Stages call each other directly through a small in-process API that mimics the eventual event bus. Source data flows through the ACL, lands in the cache, gets annotated through cascading stages and is read out through a simple consumer.</p><p>In <em>sprint two,</em> which is the subject of the next article, we evolve that thin pipeline into a true event-driven system. The synchronous dispatcher gets swapped for a message broker. Stages become independent processes. We add the ability to rewind history.</p><p>Why split it? By focusing on proving the rest of the architecture first, we&#8217;ll tackle a lot of foundational questions. If we tried to do everything at once, the messaging work would dominate our attention and we&#8217;d never get a chance to validate the <em>pipeline shape itself</em> &#8212; ACL, cache, staged transformations, annotation, readout. Validating that shape first is how we make sure the pipeline actually solves our business problem. We&#8217;re holding back messaging &#8212; but messaging is a well-understood space. This way, we get rid of more unknowns up front, and later we&#8217;ll use the running pipeline to inform what the event contracts should look like.</p><p>This is the steel thread approach in miniature. We&#8217;re tackling architectural risk early, but we&#8217;re also being honest about the order in which we tackle it.</p><h2>What sprint one actually delivers</h2><p>Here&#8217;s the thing about a steel thread: it&#8217;s tempting to over-build. You see the future architecture in your head and you want to <em>get there now</em>. Resist that urge. The point of sprint one isn&#8217;t to anticipate every future need &#8212; it&#8217;s to prove the <em>shape</em> is right.</p><p>Concretely, by the end of sprint one we&#8217;ll have:</p><ol><li><p>An <em>anti-corruption layer</em> that pulls source records from an external SQL database and translates them into our domain types.</p></li><li><p>An <em>internal cache</em> that holds a copy of the cleaned source data plus any annotations we generate.</p></li><li><p>A <em>staged transformation pipeline</em> &#8212; a sequence of analytical steps, each one reading the previous data and adding new annotations on top.</p></li><li><p>An <em>annotation pattern</em> that lets us add new derived data alongside the source without touching the source itself.</p></li><li><p>A <em>pipeline-shaped API</em> that <em>looks</em> like an event bus from the outside but is implemented as in-process function calls underneath.</p></li><li><p>A <em>read API</em> that surfaces the latest annotations on demand.</p></li><li><p>A <em>minimal output</em> &#8212; for example, a simple web page or even a JSON dump &#8212; that proves the round-trip works.</p></li></ol><p>What we&#8217;re <em>not</em> doing yet:</p><ul><li><p>No real message broker. No Kafka, no RabbitMQ, no Phoenix PubSub fan-out across nodes.</p></li><li><p>No asynchronous stages. Each stage runs in the same process, in order.</p></li><li><p>No rewind-and-reprocess. We&#8217;ll design so we can move in that direction, but we won&#8217;t have all the pieces in place yet.</p></li><li><p>No production infrastructure beyond what we need to run the steel thread end-to-end.</p></li></ul><p>That&#8217;s a deliberate choice. Every item on the &#8220;not yet&#8221; list maps to a piece of work we&#8217;ll pick up later. By naming them now, we&#8217;re reminding ourselves where the future seams are &#8212; and we&#8217;re writing today&#8217;s code in a way that respects them.</p><p>Here&#8217;s what sprint one looks like as a flow:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XjkF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850ca950-d0a1-4508-a576-eeb010b4a9ba_1264x540.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XjkF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850ca950-d0a1-4508-a576-eeb010b4a9ba_1264x540.png 424w, https://substackcdn.com/image/fetch/$s_!XjkF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850ca950-d0a1-4508-a576-eeb010b4a9ba_1264x540.png 848w, https://substackcdn.com/image/fetch/$s_!XjkF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850ca950-d0a1-4508-a576-eeb010b4a9ba_1264x540.png 1272w, https://substackcdn.com/image/fetch/$s_!XjkF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850ca950-d0a1-4508-a576-eeb010b4a9ba_1264x540.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XjkF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850ca950-d0a1-4508-a576-eeb010b4a9ba_1264x540.png" width="1264" height="540" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/850ca950-d0a1-4508-a576-eeb010b4a9ba_1264x540.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:540,&quot;width&quot;:1264,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Pasted image 20260616112920.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Pasted image 20260616112920.png" title="Pasted image 20260616112920.png" srcset="https://substackcdn.com/image/fetch/$s_!XjkF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850ca950-d0a1-4508-a576-eeb010b4a9ba_1264x540.png 424w, https://substackcdn.com/image/fetch/$s_!XjkF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850ca950-d0a1-4508-a576-eeb010b4a9ba_1264x540.png 848w, https://substackcdn.com/image/fetch/$s_!XjkF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850ca950-d0a1-4508-a576-eeb010b4a9ba_1264x540.png 1272w, https://substackcdn.com/image/fetch/$s_!XjkF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F850ca950-d0a1-4508-a576-eeb010b4a9ba_1264x540.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Modeling the business process: intake &#8594; translate &#8594; cache &#8594; annotate.</figcaption></figure></div><p>Notice the purple component: that&#8217;s the in-process dispatcher &#8212; the seam where the eventual event bus will live. Stages publish through it today, and they&#8217;ll publish through it tomorrow. Only the implementation underneath changes.</p><h2>The anti-corruption layer</h2><p>I introduced the term &#8220;anti-corruption layer&#8221; in <a href="https://blog.bosslogic.com/p/part-2-a-practical-data-pipeline-architecture">Part 2</a>. It comes from Eric Evans&#8217; <em>Domain-Driven Design</em> and it does exactly what the name suggests: it protects our domain from being <em>corrupted</em> by the shape, types and assumptions of an external system. The ACL is where messy outside data becomes clean inside data.</p><p>In our pipeline the ACL has four jobs:</p><ol><li><p><em>Translate</em> external types into domain types. If the source schema stores duration as an <code>Integer</code> of seconds and our domain prefers <code>Time</code> or <code>Duration</code>, the translation happens here.</p></li><li><p><em>Validate</em> what comes in. Required fields, value ranges, referential integrity &#8212; checks at this boundary catch problems where they&#8217;re cheapest to fix.</p></li><li><p><em>Decouple</em> our internal cache schema from the source. If the upstream team adds a column, drops a column or renames a field, the change stops at the ACL.</p></li><li><p><em>Alert loudly</em> about problems with the inbound data. If the data doesn&#8217;t fit our internal shape, we need to know about it.</p></li></ol><p>ACLs are typically shown as small annotations on context boundaries, like this:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mSIA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7acc56a0-0c12-48eb-a0e5-c308e4393b0a_901x312.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mSIA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7acc56a0-0c12-48eb-a0e5-c308e4393b0a_901x312.png 424w, https://substackcdn.com/image/fetch/$s_!mSIA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7acc56a0-0c12-48eb-a0e5-c308e4393b0a_901x312.png 848w, https://substackcdn.com/image/fetch/$s_!mSIA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7acc56a0-0c12-48eb-a0e5-c308e4393b0a_901x312.png 1272w, https://substackcdn.com/image/fetch/$s_!mSIA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7acc56a0-0c12-48eb-a0e5-c308e4393b0a_901x312.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mSIA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7acc56a0-0c12-48eb-a0e5-c308e4393b0a_901x312.png" width="566" height="195.99556048834629" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7acc56a0-0c12-48eb-a0e5-c308e4393b0a_901x312.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:312,&quot;width&quot;:901,&quot;resizeWidth&quot;:566,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Pasted image 20260428084701.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Pasted image 20260428084701.png" title="Pasted image 20260428084701.png" srcset="https://substackcdn.com/image/fetch/$s_!mSIA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7acc56a0-0c12-48eb-a0e5-c308e4393b0a_901x312.png 424w, https://substackcdn.com/image/fetch/$s_!mSIA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7acc56a0-0c12-48eb-a0e5-c308e4393b0a_901x312.png 848w, https://substackcdn.com/image/fetch/$s_!mSIA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7acc56a0-0c12-48eb-a0e5-c308e4393b0a_901x312.png 1272w, https://substackcdn.com/image/fetch/$s_!mSIA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7acc56a0-0c12-48eb-a0e5-c308e4393b0a_901x312.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">An &#8220;ACL&#8221; (anti-corruption layer) keeps your domain&#8217;s model consistent.</figcaption></figure></div><p>We see two internal domains and an <em>external</em> daily calendar domain. Activities and sprints belong to our application. To keep both domains &#8220;pure,&#8221; an anti-corruption layer translates the external world into familiar, internal language. For example, reading an <code>Integer</code> time duration and translating it into <code>Time</code>. The <code>Activities</code> and <code>Sprints</code> contexts both use the same language, so they don&#8217;t need an ACL between them.</p><p>I&#8217;m using Elixir and the <a href="https://hexdocs.pm/ash/Ash.html">Ash Framework</a> for these examples. Don&#8217;t worry if you&#8217;re not an Elixir programmer &#8212; Ash is a declarative resource framework, and the snippets read more or less like an annotated description of the resource. If you&#8217;re working in another stack, the shape of the solution is the same; only the syntax changes.</p><p>Here&#8217;s a stripped-down resource that represents an <code>Activity</code> in our internal cache. It&#8217;s the <em>clean,</em> domain-flavored version of whatever the source database hands us:</p><pre><code><code>defmodule WastePipeline.Cache.Activity do
  use Ash.Resource,
    domain: WastePipeline.Cache,
    data_layer: AshPostgres.DataLayer

  attributes do
    uuid_primary_key :id
    attribute :external_id, :string, allow_nil?: false
    attribute :date, :date, allow_nil?: false
    attribute :duration, :time, allow_nil?: false
    attribute :type, :atom, constraints: [one_of: [:value_add, :non_value_add]]
  end

  relationships do
    belongs_to :stereotype, WastePipeline.Cache.Stereotype, allow_nil?: false
    belongs_to :user, WastePipeline.Cache.User, allow_nil?: false
  end
end</code></code></pre><p>Now here&#8217;s the ACL itself &#8212; a small module whose only job is to take a <em>source</em> record (whatever the upstream SQL database hands us) and produce a <em>domain</em> record we can hand to the cache:</p><pre><code><code>defmodule WastePipeline.Intake.ActivityAcl do
  alias WastePipeline.Cache

  # Translate one external row into a domain-shaped map. Anything weird about
  # the upstream representation gets dealt with right here.
  def to_domain(%{"duration_seconds" =&gt; secs, "value_type" =&gt; v} = row) do
    %{
      external_id: row["id"],
      date: Date.from_iso8601!(row["activity_date"]),
      duration: Duration.time_from_seconds(secs),
      type: translate_value_type(v),
      stereotype_id: row["stereotype_id"],
      user_id: row["user_id"]
    }
  end

  defp translate_value_type("VA"),  do: :value_add
  defp translate_value_type("NVA"), do: :non_value_add
  defp translate_value_type(other), do: raise "Unknown value type: #{other}"

  # Public entry point. Pull a batch from the source, translate every row,
  # and hand the result to the cache for insertion.
  def ingest_batch(rows) do
    rows
    |&gt; Enum.map(&amp;to_domain/1)
    |&gt; Enum.each(&amp;Cache.create_activity!/1)
  end
end</code></code></pre><p>Two things worth noting. First, the translation logic is <em>explicit</em> &#8212; when the source uses <code>"VA"</code> and <code>"NVA"</code>, our translator is the one and only place those strings get mapped into atoms. If the source ever changes (say, the strings become <code>"value-add"</code> and <code>"non-value-add"</code>), exactly one function changes. Second, we <em>fail loudly</em> on unknown inputs. An unrecognized <code>value_type</code> raises rather than silently dropping the row. That&#8217;s a discipline worth keeping: the ACL is the place where surprising data gets noticed.</p><p>Right now, if something goes wrong the Elixir process crashes loudly. In early development, that&#8217;s what we want &#8212; to see those exceptions and treat them as the blockers they are. In production, we&#8217;ll have a supervisor that shunts the failed message into an error-handling queue and then carries on. We can diagnose, fix and reprocess the message asynchronously.</p><p>The ACL is where we earn our <a href="https://blog.bosslogic.com/p/part-2-a-practical-data-pipeline-architecture">data integrity</a>. Once the data is past this layer, every downstream stage gets to <em>trust</em> it. That trust is what lets us write the rest of the pipeline as a series of clean, focused transformations.</p><div class="pullquote"><p><em>This newsletter grows by word of mouth&#8230; I&#8217;d be grateful if you could refer a friend. Your referrals make it worthwhile.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p></div><h2>DataFrames as the carrier</h2><p>With clean data in the cache, the next question is: in what shape do we move it through the pipeline? My answer is a DataFrame.</p><p>A DataFrame is a two-dimensional table, like a spreadsheet &#8212; rows of records, named columns of values. The big advantages are speed and expressiveness. Operations like filtering, grouping, summarizing, joining and adding columns are first-class, and they&#8217;re implemented in highly optimized native code.</p><p>In Elixir I use <a href="https://hexdocs.pm/explorer">Explorer</a>, which is built on the Rust <a href="https://pola.rs/">Polars</a> library (if you&#8217;re working in Python, you can use pandas or Polars directly). The mental model is the same regardless: a DataFrame is the <em>carrier</em> that moves through your pipeline, and each stage adds to it without altering what came before.</p><p>Here&#8217;s an example of a DataFrame stage. It takes in activity data, filters out paid time off, groups by user and adds a column for total non-value-add seconds per user:</p><pre><code><code>defmodule WastePipeline.Stages.NvaSummary do
  require Explorer.DataFrame, as: DF

  def run(df) do
    df
    |&gt; DF.filter(stereotype_code != "pto")
    |&gt; DF.group_by(["user_id"])
    |&gt; DF.summarise(
        nva_seconds_sum: sum(nva_seconds),
        va_seconds_sum:  sum(va_seconds),
        total_sum:       sum(total_seconds)
      )
  end
end</code></code></pre><p>Read that pipe-style code top to bottom. We start with <code>df</code> (the DataFrame). We <em>filter</em> out paid time off. We <em>group</em> by user. We <em>summarize</em> into three new columns. The original DataFrame isn&#8217;t mutated &#8212; <code>DF.filter</code>, <code>DF.group_by</code> and <code>DF.summarise</code> all return <em>new</em> DataFrames. The transformations are pure, the data is immutable and the next stage gets a clean input.</p><p>This is what I mean by &#8220;DataFrames as the carrier.&#8221; Each stage takes a DataFrame in, produces a DataFrame out. Annotations are <em>new data,</em> not modifications. If we get the analysis wrong, we throw out the annotations and rerun the stage; the source data never changes.</p><h2>A pipeline-shaped API that hides the messaging</h2><p>Now we earn our keep over the long run.</p><p>We want our architecture to <em>eventually</em> be event-driven. Stages publish events when they finish; other stages subscribe and react. But in sprint one we don&#8217;t have a message broker yet, and we don&#8217;t want to build one. So how do we write today&#8217;s code so it doesn&#8217;t need to be rewritten tomorrow?</p>
      <p>
          <a href="https://blog.bosslogic.com/p/part-4-coding-the-steel-thread">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Your team isn’t slow. It’s leaking time.]]></title><description><![CDATA[Eight ways work leaks time &#8212; Lean calls them DOWNTIME. Once you can name them, you can&#8217;t stop seeing them.]]></description><link>https://blog.bosslogic.com/p/your-team-isnt-slow-its-leaking-time</link><guid isPermaLink="false">https://blog.bosslogic.com/p/your-team-isnt-slow-its-leaking-time</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Sat, 06 Jun 2026 10:12:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!v6Hn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!v6Hn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!v6Hn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg 424w, https://substackcdn.com/image/fetch/$s_!v6Hn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg 848w, https://substackcdn.com/image/fetch/$s_!v6Hn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!v6Hn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!v6Hn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:648418,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/200870772?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!v6Hn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg 424w, https://substackcdn.com/image/fetch/$s_!v6Hn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg 848w, https://substackcdn.com/image/fetch/$s_!v6Hn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!v6Hn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21749954-eadf-467c-972e-93b581158145_2099x1181.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@johann_n_e?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Johann Noby</a> on <a href="https://unsplash.com/photos/team-rowing-a-long-boat-during-a-race-NEalqHsZH4Q?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>Your team works hard. The hours are long, the standups are full and everyone looks busy &#8212; and yet the thing that should take a day takes three. Velocity feels slower than the effort warrants. Retros surface the same complaints again and again yet nothing moves. If you&#8217;ve started to suspect the team is just slow, stop.</p><p>It isn&#8217;t. The time isn&#8217;t evaporating. It&#8217;s leaking &#8212; escaping through gaps you walk past every day without seeing them. And here&#8217;s the part that matters: the gaps aren&#8217;t a mystery. There are exactly eight of them, and they were named decades ago, on the factory floors of postwar Japan.</p><p>When Dave Brailsford ran British Cycling and then founded Team Sky, he didn&#8217;t chase one breakthrough. He hunted one-percent improvements everywhere &#8212; the bikes, the riders&#8217; sleep, even the way they washed their hands to dodge a cold before a race. Stack enough of them, the theory went, and a country that had never produced a Tour de France winner takes five of&#8230;</p>
      <p>
          <a href="https://blog.bosslogic.com/p/your-team-isnt-slow-its-leaking-time">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Can you rely on SAFe to deliver elite-performer gains?]]></title><description><![CDATA[The cadence got shorter; the shape didn&#8217;t change: SAFe is what happens when you keep the waterfall org chart, rename the meetings and run a PI Planning event over the top.]]></description><link>https://blog.bosslogic.com/p/can-you-rely-on-safe-to-deliver-elite-gains</link><guid isPermaLink="false">https://blog.bosslogic.com/p/can-you-rely-on-safe-to-deliver-elite-gains</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Thu, 28 May 2026 07:53:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!VN3T!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VN3T!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VN3T!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg 424w, https://substackcdn.com/image/fetch/$s_!VN3T!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg 848w, https://substackcdn.com/image/fetch/$s_!VN3T!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!VN3T!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VN3T!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg" width="1456" height="908" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:908,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:526738,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/199072705?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VN3T!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg 424w, https://substackcdn.com/image/fetch/$s_!VN3T!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg 848w, https://substackcdn.com/image/fetch/$s_!VN3T!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!VN3T!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef3c542a-6d6f-4e49-99f8-bfb2b5e58ad2_2752x1717.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@nataliila?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Natalia Marcelewicz</a> on <a href="https://unsplash.com/photos/two-fire-fighters-in-front-of-a-large-fire-FB6bXwsgafM?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><div class="pullquote"><p>I recently wrote about the gains product teams <a href="https://blog.bosslogic.com/p/product-teams-really-do-outperform">reliably post</a>. But that article left an opening: what exactly <em>is</em> a product team? In part, that&#8217;s a question this article answers &#8212; as well as, &#8220;<em>can a product team use SAFe?&#8221;</em> (If you haven&#8217;t read it, <em><a href="https://blog.bosslogic.com/p/product-teams-really-do-outperform">Receipts</a></em> is the lead-in).</p></div><blockquote><p>Just about every large pre-Internet company out there today has some sort of &#8220;digital transformation initiative,&#8221; but what most of them don&#8217;t realize is that the heart of this transformation is moving from project-mindset to product-mindset. &#8212; Marty Cagan, Founder, Partner, Product at SVPG</p></blockquote><p>Forty-plus people, a chunk of a week blocked off, a cavernous meeting room commandeered. Sticky notes color-coded by team. Butcher paper taped along the walls. Somewhere near the front, a Release Train Engineer is walking the room with a Sharpie, drawing red strings between dependent features. By the end of day two, every team has its slice of a 10-week plan committed to the wall, and a senior leader is asking each team for a five-finger confidence vote.</p><p>I&#8217;ve watched that scene play out. I know what comes next. Six weeks from now, three of those red strings will have moved, two features will be quietly cut and one team will be rebuilding a thing nobody asked for. The plan that got committed is not the plan that ships. Everyone in the room knows. Nobody says it.</p><p>But the plan got a vote. The Release Train left the station. It&#8217;s now truth &#8212; until the next PI, when a slightly different plan will become the next truth. The change orders get signed and project budgets run over in the guise of &#8220;increased scope.&#8221;</p><p>That&#8217;s PI Planning. And I&#8217;m going to argue, carefully and with receipts, that what just happened in that room is waterfall on short cycle &#8212; and almost nothing about it is recognizably agile.</p><div class="pullquote"><p><em>If you're new, welcome to Customer Obsessed Engineering! I publish about one article each week. Free subscribers can read about half of every article, plus all of my free articles.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/subscribe?"><span>Subscribe now</span></a></p></div><h2>The premise we're not going to relitigate</h2><p>I am not going to relitigate whether product teams outperform. I made the case in <a href="https://blog.bosslogic.com/p/product-teams-really-do-outperform">Product teams really do outperform: bringing the receipts</a>. DORA, McKinsey, Pendo, Standish and Project Aristotle converge unambiguously. Small, durable, cross-functional teams that own a problem end-to-end deploy 182&#215; more frequently, ship higher quality, redefine &#8220;done&#8221; around outcomes and drive four to five times faster revenue growth than the alternatives.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><p>Take that as given. The question for today is narrower: if <em>that</em> is what real agility looks like, where exactly does SAFe land on the map?</p><p>The short answer &#8212; the one I will spend the rest of this article defending &#8212; is that SAFe lands far closer to waterfall than its name implies. Not because its proponents are dishonest. Because its structural unit of planning, funding and authority is the Agile Release Train, not the team. And that single design choice quietly recreates every handoff, gate and silo agile was meant to eliminate.</p><h2>Before I break the case, let me make it</h2><p>I owe SAFe and the people who chose it a fair hearing &#8212; and a fair hearing means arguing with its strongest version, not its sales deck. So let me make SAFe's case the way its creator makes it.</p><p>Dean Leffingwell does not justify SAFe by appeal to certifications or board-deck optics. He grounds it in flow economics &#8212; specifically Don Reinertsen's <em>Principles of Product Development Flow</em>, a serious book that the continuous-delivery world draws on too. The argument lives in SAFe's seventh principle, &#8220;apply cadence, synchronize with cross-domain planning,&#8221; and it runs like this. <em>&#8220;Solution development is an inherently uncertain process&#8230; This risk conflicts with the need for businesses to manage investments, track progress, and have enough confidence in future outcomes to plan and commit to a reasonable course of action.&#8221;</em> The resolution Leffingwell offers is a, <em>&#8220;safety zone, where enough uncertainty actually provides the freedom to pursue innovation, while sufficient confidence allows the business to operate.&#8221;</em> Cadence and synchronization are how you buy that confidence without freezing the work. PI Planning, in this telling, is not a commitment ritual &#8212; it is a periodic re-baselining of the plan against the objective state of working systems, which is SAFe's fifth principle.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p><p>Take that seriously. The coordination problem SAFe addresses is real. Eight teams shipping into the same product surface need to know about each other's plans. Two hundred teams across a portfolio need someone to decide the trade-offs. Lean Budgets &#8212; funding value streams instead of approving each project individually &#8212; are genuinely better than the alternative most enterprises were running before. Inspect &amp; Adapt at the end of each PI is a retrospective at scale, and that&#8217;s not nothing. PI Planning, for all its flaws, beats no planning. At the team level, SAFe leaves Scrum or Kanban in place. The bottom-up practices are still there.</p><p>There is also a colder, political version of the case, and it deserves the same hearing. SAFe is, in many enterprises, the only model executive leadership will fund. The CFO can read it. The PMO can map their roles into it (that&#8217;s a key point; hold on to it). The risk officer can find their gates. There is a certification track, a vendor, a roadmap. For an organization that needs to tell a board, &#8220;we are being agile,&#8221; SAFe is the politically survivable option. The choice between SAFe and a Cagan-style product transformation is rarely the choice on the table. The actual choice &#8212; for many large organizations &#8212; is between SAFe and the project-funded, requirements-thrown-over-the-wall, six-month-release waterfall it replaced.</p><p>So the honest steelman has two layers. Intellectually, SAFe is an attempt to operationalize real flow economics at enterprise scale. Politically, it is the floor, not the ceiling &#8212; and the floor is higher than what came before. For organizations starting from heavy-handed waterfall, SAFe is an upgrade on both counts.</p><p>That is the strongest case I can make, and I built it from SAFe's own foundations. Now let me explain why it isn't enough &#8212; and why the upgrade comes at a steeper price than its buyers usually realize.</p><h2>Five tells that betray the waterfall underneath</h2><p>If you want to know whether something is waterfall, do not read its marketing. Read its structure. Waterfall has diagnostic attributes &#8212; sequential phases, big-batch commitments, multi-team handoffs, stage gates with formal approval, plan-driven coordination above team level &#8212; and any process that exhibits those attributes will behave like waterfall whether or not it carries the name.</p><p>What follows are five attributes that SAFe exhibits, with the practices that produce each. Some of these will look familiar from the structural critique <a href="https://www.svpg.com/revenge-of-the-pmo/">Marty Cagan put on the record in 2018</a>. Others are mine, drawn from watching the framework operate across enterprise programs. The attributes are independent. Any one of them is a yellow flag. Three of them is a diagnosis. Five of them is what we are looking at.</p><h3>Tell #1: the Release Train is a waterfall, on rails</h3><p>Start with the name. <em>Agile</em> Release Train. The naming is not accidental &#8212; it is defensive. Strip the adjective and you are left with <em>release train</em>, which is exactly what waterfall organizations have always called their integrated, scheduled, multi-team delivery cycles. Pull a release train out of a 1995 PMO and it would have looked nearly identical to a SAFe ART: 50 to 125 people working toward a synchronized release at a fixed cadence, a release manager coordinating dependencies, a portfolio manager approving the work and a steering committee voting on the plan. SAFe replaced the release manager with a Release Train Engineer, the portfolio manager with a Lean Portfolio Manager and the steering committee with a PI Planning ceremony. The roles got new titles. The meeting got a Sharpie. The cadence shrank from six months to ten weeks. The shape did not change.</p><p>Look at what an ART actually does. It locks 50 to 125 people into a shared 10-week commitment. It synchronizes their backlogs into a single Program Backlog. It coordinates their dependencies &#8212; through a Solution Train, when the ART is too small to contain the dependencies on its own. It runs ceremonies &#8212; PI Planning, ART Sync, Scrum of Scrums, System Demo, Inspect &amp; Adapt &#8212; whose entire purpose is to manage the friction created by the ART's own existence. Every one of those ceremonies is overhead a real product team does not pay, because a real product team does not have a 50-to-125-person commitment to coordinate around in the first place.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a></p><p>Marty Cagan put this plainly enough that I want to quote him directly. In <em>Revenge of the PMO</em>, he writes that, <em>&#8220;the critical notion of a dedicated product team (aka squad) has been gutted. In SAFe, this concept of a true product team has been undermined and demoted, and the core concept is now a Program, which has a top-down model of a product manager, an architect, and a release train manager, and these people make all the key decisions, and then some number of engineering teams with a low-level product owner are assigned various parts to build.&#8221;</em> That is a verbatim description of a feature team inside a project structure. SAFe just renamed the project a Program and the project manager an RTE.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self">4</a></p><p>Dave Farley &#8212; co-author of <em>Continuous Delivery</em> and not a man with a Scrum axe to grind &#8212; reached the same place from the engineering side. Writing about the clients he had watched adopt SAFe, he was blunt: <em>&#8220;the orgs that I have seen try SAFe look indistinguishable from the orgs that pay lip-service to Scrum to me. In both cases, they look like waterfall orgs to me.&#8221;</em> His objection is structural, and it lands on the load-bearing artifact directly. He dislikes the Release Train itself &#8212; <em>&#8220;I think that they are an anti-Continuous Integration step,&#8221;</em> one that, <em>&#8220;represent[s] a plateau that halts team's progress towards a more effective flow-based approach.&#8221;</em> The author of the canonical book on continuous delivery looked at the Release Train and saw the thing standing between teams and flow.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-5" href="#footnote-5" target="_self">5</a></p><p>Pull the Release Train out and SAFe collapses. Keep it in and you have kept every structural property that makes waterfall what it is &#8212; synchronized big-batch commitments, multi-team handoffs, a coordinator above the team, a plan that hardens the moment the room votes on it.</p><h3>Tell #2: cadence as commitment</h3><p>A 10-week PI plan is functionally a specification.</p><p>SAFe will tell you it is a forecast &#8212; soft alignment, not a frozen commitment. Confidence votes are five-finger, not yes-or-no. Teams can replan. Deployment is not locked to the PI. The wording is all soft. Look at what actually happens, though. The room agrees on a set of features for the PI. Those features get pulled into the Program Backlog. Engineers start work against them. Dependencies get committed to other teams' plans. Stakeholders are told what is coming. Mid-PI, the cost of dropping a feature is not zero &#8212; it is the team's confidence vote, the dependent teams' rework, the stakeholder's roadmap update, the RTE's coordination tax, the System Demo's missing slot.</p><p>So features almost never get dropped mid-PI &#8212; the discovery that <em>should</em> happen during the increment rarely does, and when it surfaces a problem, the dependencies make dropping the feature more expensive than shipping it anyway. The plan, framed as soft, hardens into something tighter than waterfall ever was &#8212; because waterfall at least admitted to being a commitment. PI Planning insists it is not a commitment, then behaves like one, and punishes anyone who treats it as if it isn't.</p><p>Compare this to a real product team. A team starting Monday morning with a hypothesis runs the cheapest possible test by Friday. If the data says no, the hypothesis dies before week two. The team has lost five days. No roadmap vote, no red strings. The stakeholder isn&#8217;t told anything because there is nothing to tell. One of these is research. The other is a Gantt chart that happens to be 10 weeks wide instead of 10 months wide.</p><p>Royce warned about this in <a href="https://blog.bosslogic.com/p/stop-measuring-effort-4ed827b470ae">1970</a> &#8212; and it is worth remembering, because the diagram he drew has been the most consequential misreading in software engineering history. In <em>Managing the Development of Large Software Systems</em>, Royce presented the now-familiar sequential flow of phases and then said in the same paper that an implementation plan keyed only to those steps was <em>&#8220;risky and invites failure.&#8221;</em> The bulk of his paper argues that any large software system needs to iterate &#8212; that every commitment to a plan should be tested against working software before it hardens. People extracted his diagrams and ignored his warnings. PI Planning ships Royce's exact failure mode under a different name, on a shorter cycle. The cadence being shorter is the entire thing that is &#8220;agile&#8221; about it. Strip the cadence and what is left is a stage-gated portfolio process.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-6" href="#footnote-6" target="_self">6</a></p><div class="pullquote"><p><em>This newsletter grows by word of mouth&#8230; I&#8217;d really, truly appreciate it if you could refer a friend. Your referrals make it worthwhile.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p></div><h3>Tell #3: the decomposition pyramid</h3><p>Epic &#8594; Feature &#8594; Story is requirements &#8594; design &#8594; implementation, in different fonts.</p><p>The Epic is approved upstream by Lean Portfolio Management before it lands at the ART. The Feature is decomposed by a Product Manager and a System Architect before it lands at the team. The team's Product Owner &#8212; a role title borrowed from Scrum and stripped of Scrum's authority &#8212; turns Features into Stories. Each step down the pyramid is a translation from one set of vocabulary to another. Each translation loses information. By the time a Story is in front of a developer, the original customer intent has been refracted through three layers of people who did not sit with the customer and who do not sit on the team that will build the thing.</p><p>Where, exactly, does product discovery happen?</p><p>Discovery &#8212; as Cagan, Torres and the discovery-coaching tradition mean it &#8212; is hypothesis-testing with real customers before commitment. In SAFe, that work happens <em>before</em> the Epic enters the funnel, in a separate process, performed by people who do not sit on the team that will build it. The feature team receives a Feature already shaped by a Product Manager, refined by a System Architect, approved by Lean Portfolio Management and committed to by 50 to 125 of their colleagues at PI Planning. The team's role is to decompose the Feature into Stories and execute. That is not discovery. That is a business analyst with new vocabulary.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-7" href="#footnote-7" target="_self">7</a></p><p>I am not the first person to point this out. Jeff Gothelf, the co-creator of Lean UX, put it bluntly:</p><blockquote><p><em>&#8220;All the principles we've built into Lean UX don't seem to exist in SAFe.&#8221;</em></p></blockquote><p>He went on to note that customer-centricity, evidence-based decision-making, experimentation and course correction, <em>&#8220;are visibly absent from the SAFe conversation.&#8221;</em> He is right because the conversation cannot include them. The framework has placed those activities upstream of the team, and made the team's slot in the value chain a unit of execution, not a unit of inquiry.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-8" href="#footnote-8" target="_self">8</a></p><p>The Delivery Playbook focuses on customer value as a core practice &#8212; through <a href="https://blog.bosslogic.com/p/how-to-create-customer-impact">value stream engineering</a> and <a href="https://blog.bosslogic.com/p/23-strategic-event-storming">customer-centric design</a>. These are not optional &#8212; they are table stakes. SAFe cuts both out of the conversation.</p><h3>Tell #4: the team-ownership ceiling</h3><p>A SAFe team does not own a value stream. It owns its slice of an ART.</p><p>End-to-end ownership of the customer outcome &#8212; what separates product teams from feature teams &#8212; lives at the ART or Solution Train level. That is the line <em><a href="https://blog.bosslogic.com/p/product-teams-really-do-outperform">Receipts</a></em> drew with Cagan's framing of product, feature and project teams. SAFe puts the team on the wrong side of that line by design. The framework cannot fix this because the line <em>is</em> the design. The Release Train is the unit of ownership. The team is the unit of execution. Move the unit of ownership down to the team and you do not have an ART anymore &#8212; you have a portfolio of small product teams, which is what Cagan, <em>Team Topologies</em> and DORA's elite-tier qualitative findings all converge on.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-9" href="#footnote-9" target="_self">9</a></p><p>This is the structural reason SAFe transformations stall. The ceremonies improve. The ART runs more smoothly. PI Planning gets more efficient. Nobody on the team feels more agile, because nothing about the operating model above the team has changed. The team is still being handed Features it did not discover, against a 10-week commitment it did not negotiate, with deployment dependencies it cannot break. The agile-coach stack is workable. The teams are not.</p><p>Teams cannot build <a href="https://blog.bosslogic.com/p/what-a-product-oriented-team-looks-like">ownership</a> in what they don&#8217;t own.</p><h3>Tell #5: Lean Portfolio Management is the PMO with new business cards</h3><p>The title is mine; the diagnosis is Cagan's &#8212; his article is literally called <em>Revenge of the PMO</em>.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-10" href="#footnote-10" target="_self">10</a></p><p>Look at what Lean Portfolio Management actually does. It captures Epics in a Funnel. It moves them through Reviewing and Analyzing states. It requires a Lean Business Case for each Epic before that Epic can advance. It gates approval at a Portfolio Backlog state. It tracks Implementation against the original case.</p><p>State the same workflow in 2005 vocabulary: capture projects in an intake queue, move them through analysis with required business cases, gate approval at portfolio review, track implementation against the original case. The verbs are identical. The artifacts are identical. The decision rights are identical.</p><p>SAFe's defenders will say Lean Budgets are different &#8212; funded to value streams, not projects &#8212; and that is fair, in principle. Funding value streams is a real improvement over funding projects. But the <em>governance overlay</em> &#8212; the gates, the cases, the approvals, the portfolio reporting &#8212; is the project portfolio management discipline that PMOs have run for thirty years. It&#8217;s not bad because it&#8217;s old. It&#8217;s bad because it sits above the team and makes the team's authority subordinate to the portfolio's case-building exercise. Authority for &#8220;what to build&#8221; still flows top-down. The team gets to decide <em>how</em>. That is exactly the bargain SAFe strikes: the project mindset wearing a costume.</p><p>If you have a PMO that has been quietly converting itself into Lean Portfolio Management, the costume is the only thing that has changed. The decisions are still being made by the same people, in the same room, against the same business cases, with the same approval ladder. Agile pushed the PMO to the side; Lean Portfolio Management is its path back into the room.</p><h2>The DORA test</h2><p>Here is the test I keep coming back to. It is short. It is fatal.</p>
      <p>
          <a href="https://blog.bosslogic.com/p/can-you-rely-on-safe-to-deliver-elite-gains">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Good product team / bad product team]]></title><description><![CDATA[Marty Cagan&#8217;s good-team / bad-team list is a decade old and still the cleanest mirror in the business. Pin it to your wall. Ask yourself how many strike too close to home.]]></description><link>https://blog.bosslogic.com/p/good-product-team-bad-product-team</link><guid isPermaLink="false">https://blog.bosslogic.com/p/good-product-team-bad-product-team</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Thu, 21 May 2026 14:02:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1WI6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1WI6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1WI6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg 424w, https://substackcdn.com/image/fetch/$s_!1WI6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg 848w, https://substackcdn.com/image/fetch/$s_!1WI6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!1WI6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1WI6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg" width="1456" height="945" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:945,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:408816,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/198708208?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1WI6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg 424w, https://substackcdn.com/image/fetch/$s_!1WI6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg 848w, https://substackcdn.com/image/fetch/$s_!1WI6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!1WI6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd66be403-f6c5-435c-b7ca-470835ee9b89_3000x1947.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@jplenio?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Johannes Plenio</a> on <a href="https://unsplash.com/photos/black-sailing-boat-digital-wallpaper-DKix6Un55mw?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>Marty Cagan&#8217;s <a href="https://www.svpg.com/good-product-team-bad-product-team/">decade-old article</a> can be a real rabbit hole. It&#8217;s genuinely hard to stop reading his blog, especially when digging up old gems like this.</p><p>Here&#8217;s something that resonates right now: &#8220;Good teams are skilled in the many techniques to rapidly try out product ideas to determine which ones are truly worth building. Bad teams hold meetings to generate prioritized roadmaps.&#8221;</p><p>Most teams I meet are funded, staffed and measured entirely around output. Hit the date, close the ticket, ring the bell for delivering on a roadmap.</p><p>Too few are paying attention to what matters: did what we shipped really make a difference for our customer?</p><p>The reorg that actually changes delivery isn&#8217;t new ceremonies. It&#8217;s moving the moment you celebrate from &#8220;we shipped&#8221; to &#8220;it delighted our customer, it actually moved what matters.&#8221;</p>
      <p>
          <a href="https://blog.bosslogic.com/p/good-product-team-bad-product-team">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Pull requests are a symptom of low trust: here’s the fix]]></title><description><![CDATA[T*D is the new name for the Playbook trifecta: Test-Driven Development, Trunk-Based Development and Team-Focused Development, fused into one operating model.]]></description><link>https://blog.bosslogic.com/p/pull-requests-are-a-symptom-of-low-trust</link><guid isPermaLink="false">https://blog.bosslogic.com/p/pull-requests-are-a-symptom-of-low-trust</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Sat, 16 May 2026 13:52:12 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Kp02!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Kp02!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Kp02!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Kp02!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Kp02!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Kp02!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Kp02!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg" width="1390" height="927" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:927,&quot;width&quot;:1390,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:265872,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/197994258?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Kp02!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Kp02!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Kp02!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Kp02!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f4f46f7-5e75-4350-9da9-92b2264ec340_1390x927.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@shiroscope?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Shiro hatori</a> on <a href="https://unsplash.com/photos/timelapse-photography-on-curved-road-beside-tree-WR-ifjFy4CI?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>Your team has probably spent more hours this year waiting on pull requests than it spent writing the code marooned inside them. Andrea Laforgia opens his March 2026 essay <em>Stop Using Pull Requests</em> with numbers from across the industry that count the cost. The piece is the most thorough reckoning I&#8217;ve seen of why the modern pull request workflow is mis-designed for the teams that use it. Go read it. Then come back here &#8212; because if you&#8217;re using the <em><a href="https://blog.bosslogic.com/s/delivery-playbook">Delivery Playbook</a></em>, Laforgia is describing the practice you already know. He just gives it a name. And I like it.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><p>That name is T*D &#8212; Test-Driven Development, Trunk-Based Development and Team-Focused Development, fused into one operating model. Hold on to it. We&#8217;ll come back to it.</p><h2>Don&#8217;t break the flow</h2><p>Chapter <a href="https://blog.bosslogic.com/p/28-delivery-tools-and-processes">2.8 Delivery processes &amp; tools</a> lays out what a well-wrought delivery pipeline does: ephemeral environments, test batteries, zero trust, release orchestration, observability, canary releases. The argument is t&#8230;</p>
      <p>
          <a href="https://blog.bosslogic.com/p/pull-requests-are-a-symptom-of-low-trust">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Ask your team how to make this worse]]></title><description><![CDATA[A 30-minute workshop called TRIZ turns a comedy round into a confession booth &#8212; the most valuable half-hour you&#8217;ll spend this quarter.]]></description><link>https://blog.bosslogic.com/p/ask-your-team-how-to-make-this-worse</link><guid isPermaLink="false">https://blog.bosslogic.com/p/ask-your-team-how-to-make-this-worse</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Thu, 07 May 2026 14:22:22 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!kh_T!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kh_T!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kh_T!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg 424w, https://substackcdn.com/image/fetch/$s_!kh_T!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg 848w, https://substackcdn.com/image/fetch/$s_!kh_T!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!kh_T!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kh_T!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg" width="1456" height="1090" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1090,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:366711,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/196719103?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kh_T!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg 424w, https://substackcdn.com/image/fetch/$s_!kh_T!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg 848w, https://substackcdn.com/image/fetch/$s_!kh_T!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!kh_T!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F044947a1-0de9-4f36-88b7-b041a60187ce_1712x1282.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@mrding?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Cexin Ding</a> on <a href="https://unsplash.com/photos/moss-covered-stone-statues-with-expressive-faces-5DNw4mP3LPY?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>Six people. One sticky.</p><p>A SWOT analysis at the top of a planning workshop. Strengths quadrant &#8212; a dozen sticky notes inside ten minutes. Opportunities, fine. Threats, fine. Weaknesses &#8212; <em>one sticky</em>.</p><p>The team has been together a year. Mixed group, some senior, some junior, some remote and some local. They&#8217;re smart &#8212; and obviously not weak in just one way. But one is all they were willing to write down, in front of each other, with their names attached. So the Weaknesses quadrant sat there, embarrassed and underfed, while the rest of the wall filled out around it.</p><p>Most retrospectives end this way. Most planning meetings, the same. The team knows. The team won&#8217;t say.</p><p>There&#8217;s a 30-minute exercise that breaks this open. It&#8217;s not subtle. It&#8217;s not high-tech. It&#8217;s a borrowed word from Soviet engineering, an inversion trick from a 19th-century mathematician. It takes a team from laughter to honesty to commitment in less time than your average standup. It&#8217;s called TRIZ &#8212; the Liberating Structures version, which I&#8217;ll come back to &#8212; and it&#8217;s the cheapest unlock I know for a team that won&#8217;t speak its own dysfunctions out loud.</p><p>Here&#8217;s how it works, why it works and how to run it next week.</p><div class="pullquote"><p style="text-align: center;"><em>If you&#8217;re new, welcome to Customer Obsessed Engineering! I publish about one article each week. Free subscribers can read about half of every article, plus all of my free articles.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/subscribe?"><span>Subscribe now</span></a></p><p style="text-align: center;"><em>Anytime you&#8217;d like to read more, you can upgrade to a paid subscription.</em></p></div><h2>The wrong question</h2><p>The silence in that Weaknesses quadrant is not random. It&#8217;s the predictable shape teams take when the question goes the wrong way.</p><p>&#8220;What are we doing wrong?&#8221; is one of the worst questions you can ask. It demands that someone you work with every day be the source of bad news, of blame &#8212; in a setting where their answer goes on the record. The forces working against honesty are stacked: the social cost of singling out a behavior, the political cost of singling out a person, the personal cost of being the one who said the thing nobody else was willing to say. So people hedge. They write harmless stickies. They give safe answers and stay quiet about the rest.</p><p>This isn&#8217;t about psychological safety being too low, exactly. It&#8217;s about requiring more safety than most teams I&#8217;ve known. An unusually safe team &#8212; the rare ones &#8212; can handle the direct question. Most teams can&#8217;t, even good ones. The Goldilocks zone for direct critique is narrow, and most teams sit just below it.</p><p>The wrinkle: the same team, asked the question a different way, will answer it. Same people, same room, same dysfunctions. The information is there. The mechanism for getting it out is what&#8217;s broken.</p><p>That&#8217;s the gap TRIZ fills.</p><h2>Inversion</h2><p>The 19th-century Prussian mathematician Carl Jacobi had a habit, when stuck on a problem, of saying <em>man muss immer umkehren</em> &#8212; &#8220;one must always invert.&#8221; If you can&#8217;t see how to make a thing succeed, see if you can describe how to make it fail. Charlie Munger, Warren Buffett&#8217;s late partner, popularized the move a century and a half later: &#8220;Invert, always invert,&#8221; he&#8217;d repeat, crediting Jacobi each time.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><p>Inversion is a cognitive shortcut. The forward question &#8212; &#8220;how do we make this succeed?&#8221; &#8212; runs into the usual social and intellectual walls. People hedge. People defer to whoever spoke first. People say what they think they&#8217;re supposed to say. The inverse question &#8212; &#8220;how do we <em>guarantee</em> it fails?&#8221; &#8212; jumps every one of those walls, because there&#8217;s no commitment. They&#8217;re describing a failure. They can be specific, vivid and sometimes uncomfortably accurate, and the room laughs instead of getting defensive.</p><p>Once the failure is on the wall, naming the parts of it that already exist is a much smaller step. You&#8217;re not confessing. You&#8217;re confirming.</p><p>That&#8217;s the whole engine of TRIZ.</p><h2>Why it works on teams that won&#8217;t speak up</h2><p>If you&#8217;ve never run TRIZ you&#8217;re probably thinking, &#8220;why does this work at all?&#8221; Why does asking a team to describe failure produce honesty when asking them to describe weakness doesn&#8217;t? It&#8217;s the same people in the same room talking about the same problem.</p><p>Here&#8217;s four reasons I keep coming back to. They aren&#8217;t independent &#8212; pull on one and the others move &#8212; and there are probably more I haven&#8217;t named. Their common thread: all four lower the cost of saying the thing.</p><p><strong>Hypotheticals are cheap.</strong> Saying, &#8220;we could skip estimation entirely&#8221; carries no social cost. Nobody is suggesting it. Saying, &#8220;we <em>do</em> skip estimation&#8221; costs you &#8212; especially if the person who set up the no-estimation pattern is in the room. TRIZ collects the cheap version first. It builds a list of behaviors the team is willing to discuss because the team isn&#8217;t yet committing to whether they&#8217;re real.</p><p><strong>Confirmation is easier than confession.</strong> By the time Movement 2 starts, the behavior is already on the wall. The team isn&#8217;t introducing a new criticism &#8212; that&#8217;s the hardest move. It&#8217;s confirming an existing one &#8212; that&#8217;s a much smaller move. &#8220;Ah, yea, we do that,&#8221; is far easier to say than, &#8220;we have a problem with X.&#8221; The board already said it. The team is just agreeing.</p><p><strong>Laughter changes the room.</strong> Ten minutes of laughing at exaggerated worst-case behaviors changes the social register. The same conversation about the same behaviors, started cold, would feel like an accusation round. Started after the comedy, it feels like camaraderie. Defensiveness drops. People interrupt themselves. The room is in a different mode.</p><p><strong>The quiet people speak.</strong> This is the move I see most reliably. In nearly every TRIZ I&#8217;ve facilitated, the first person to circle a behavior in Movement 2 &#8212; the first to commit to, &#8220;yea, that one&#8221; &#8212; has been the person who hadn&#8217;t said much yet. The senior engineer who watches more than she talks. The new hire who&#8217;d been listening for three months. They&#8217;d seen the dysfunction the whole time. They didn&#8217;t have a frame to say it. TRIZ gave them one.</p><p>You can put psychological safety theory on this if you want. You can talk about face-saving, about politeness norms, about the asymmetry between criticism and praise. All of it holds. But the practical version is simpler: it&#8217;s a lot easier to say things about hypotheticals than about reality, and TRIZ exploits that gap to get a team to say what it already knows.</p><p>That&#8217;s why a 30-minute exercise can do work that an hours-long retro can&#8217;t.</p><div class="pullquote"><p><em>This newsletter grows by word of mouth&#8230; I&#8217;d really, truly appreciate it if you could refer a friend. Your referrals make it worthwhile.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p></div><h2>The three movements</h2><p>The exercise has three movements. Together, they take 30 minutes if you keep the timing tight; you can stretch to 45 on a hard problem or compress to 20 with a small confident team. Each movement has a single question, and each question is doing different psychological work.</p><p><strong>Movement 1: the worst-possible-outcome brainstorm (10 minutes).</strong> Frame the outcome the team cares about &#8212; high-functioning sprint planning, a retrospective that actually changes things, a release process you&#8217;d be willing to demo. Then ask the inverted question: what could we do to <em>guarantee</em> the worst possible version of this? Wild, exaggerated, funny answers welcome. Suppress nothing. Two minutes of silent sticky-writing first, in <a href="https://deliveryplaybook.com/playbook/documentation/guides/1-2-4-all">1-2-4-All</a> style, then a round-robin share.</p><p>The laughter is the point. A team that&#8217;s laughing at &#8220;we could just cancel the retro and send an email instead&#8221; is a team becoming willing to say real things. Don&#8217;t rush this part &#8212; the comedy is what unlocks the next movement.</p>
      <p>
          <a href="https://blog.bosslogic.com/p/ask-your-team-how-to-make-this-worse">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Product teams really do outperform: bringing the receipts]]></title><description><![CDATA[Researchers at DORA, McKinsey and Google have spent a decade proving what good engineers already know. It&#8217;s time to put that knowledge into practice.]]></description><link>https://blog.bosslogic.com/p/product-teams-really-do-outperform</link><guid isPermaLink="false">https://blog.bosslogic.com/p/product-teams-really-do-outperform</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Thu, 30 Apr 2026 20:38:52 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!44-q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!44-q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!44-q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg 424w, https://substackcdn.com/image/fetch/$s_!44-q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg 848w, https://substackcdn.com/image/fetch/$s_!44-q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!44-q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!44-q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:517036,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/195978066?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!44-q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg 424w, https://substackcdn.com/image/fetch/$s_!44-q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg 848w, https://substackcdn.com/image/fetch/$s_!44-q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!44-q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d6b5872-3961-486c-aca9-12e0cb6129a6_3228x2152.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@albertstoynov?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Albert Stoynov</a> on <a href="https://unsplash.com/photos/statue-of-lady-justice-holding-scales-indoors-kIM48Mpp9iY?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>I was chatting with a friend about team dynamics. We&#8217;d been talking about restructuring around product teams &#8212; the kind of empowered, durable, cross-functional teams I&#8217;ve written about before. He&#8217;s nodding along, asking sharp questions. Halfway through, he pushed back.</p><p>I&#8217;m paraphrasing, but the gist was, &#8220;Look, I get the theory. But where&#8217;s your proof? We&#8217;ve all heard the pitch. Cross-functional teams, durable squads, outcome metrics, two-pizza this, empowered that. Show me the data. Show me that any of this actually beats what we already do.&#8221;</p><p>It was a fair question. A great question, actually. I&#8217;d written the case in <a href="https://blog.bosslogic.com/p/what-a-product-oriented-team-looks-like">Building a product oriented team</a> and the prequel, <a href="https://blog.bosslogic.com/p/moving-away-from-the-monolith-faster-better-with-a-product-mindset-f8f0dc58653c">Moving away from the Monolith &#8212; faster, better with a product mindset</a>. But those pieces argued from reasoning and experience. They didn&#8217;t bring the math.</p><p>So today I want to bring it. Because the math is there &#8212; it&#8217;s been there for over a decade &#8212; and once you line it up, the conclusion is hard to escape: product teams, the real ones, ship faster, build less waste, deliver higher quality and produce dramatically better business outcomes than the alternatives. The evidence isn&#8217;t a single bombshell study. It&#8217;s a stack of independent research, all converging on the same answer.</p><p>Let me lay out the receipts.</p><p>One note before we start. None of the studies I cite below were designed to answer the question &#8220;do product teams outperform?&#8221; They were designed to answer narrower, related questions &#8212; about deployment, about feature usage, about team effectiveness, about developer velocity. What&#8217;s below is my synthesis: the act of lining up findings from different research traditions and showing where they converge. The convergence is the argument. Each citation is a thread; the rope is the pattern across them.</p><div class="pullquote"><p style="text-align: center;"><em>If you&#8217;re new, welcome to Customer Obsessed Engineering! I publish about one article each week. Free subscribers can read about half of every article, plus all of my free articles.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/subscribe?"><span>Subscribe now</span></a></p><p style="text-align: center;"><em>Anytime you&#8217;d like to read more, you can upgrade to a paid subscription.</em></p></div><h2>A quick refresher on &#8220;product team&#8221;</h2><p>Before the data, let&#8217;s get precise. &#8220;Product team&#8221; gets thrown around so loosely it&#8217;s often meaningless.</p><p>Marty Cagan and the Silicon Valley Product Group draw the cleanest distinction. A <strong>product team</strong> is a small, durable, cross-functional unit &#8212; typically a product manager, a designer and a handful of engineers &#8212; that owns a problem and is held accountable for outcomes. They are <em>given problems to solve</em>, not features to ship. The product manager owns value and viability. The designer owns usability. The tech lead owns feasibility. Together they own the result.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><p>A <strong>feature team</strong> looks similar on paper &#8212; same disciplines around the table &#8212; but is handed a prioritized list of features to build. Outcomes belong to a stakeholder upstream. The team is judged on output: did you ship what was on the roadmap? Velocity, story points, throughput.</p><p>A <strong>project team</strong> is even further from product orientation. It&#8217;s pulled together to execute a discrete project, then dissolved. Specialists rotate in and out. There&#8217;s no durable home for product knowledge.</p><p>The labels matter less than the operating model. As I wrote in <a href="https://blog.bosslogic.com/p/what-a-product-oriented-team-looks-like">Building a product oriented team</a>, the real distinction is <em>durability, ownership and empowerment</em> &#8212; long-lived teams that own the whole product end-to-end and have the authority to figure out the <em>how</em>.</p><p>Now &#8212; what the research says.</p><h2>Receipt #1: they ship dramatically faster</h2><p>Start with DORA &#8212; the DevOps Research and Assessment program, founded by Dr. Nicole Forsgren and now part of Google. Every year since 2014, DORA has surveyed practitioners &#8212; more than 3,000 in 2024 alone, and tens of thousands across the decade-long program &#8212; and statistically grouped them into performance tiers based on four metrics: deployment frequency, lead time for changes, change failure rate and mean time to restore service. The methodology, the math and the conclusions are documented in <em>Accelerate</em> &#8212; the book that emerged from the research and won the Shingo Publication Award.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p><p>The 2024 <em>Accelerate State of DevOps</em> report is the latest. Elite-tier teams deploy <em>182 times more frequently than low performers, with 127&#215; faster lead time for changes</em>. Elite teams hit lead time under a day, deploy on demand and are roughly 19% of the surveyed population. Low performers measure lead time in months.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a></p><p>That&#8217;s not a marginal advantage. It&#8217;s not &#8220;20% better.&#8221; It&#8217;s two orders of magnitude.</p><p>You might be tempted to dismiss this as a DevOps story rather than a team-structure story. But every time DORA digs into <em>what</em> differentiates elite teams, the answers are the same attributes that define product teams: small, cross-functional, owning the whole pipeline from code to production, empowered to make their own technical decisions. The opposite &#8212; handoffs across functional silos with stage-gate approvals from external groups &#8212; correlates strongly with low performance. <em>Accelerate</em> presents one specific finding bluntly: external change advisory boards do not improve stability. They make lead time worse without making anything safer.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self">4</a></p><p>McKinsey&#8217;s &#8220;Beyond Agile&#8221; work, which I cited in <a href="https://blog.bosslogic.com/p/how-waterfall-is-wrong-for-software">How waterfall is wrong for software</a>, puts a number on the same effect from a different angle. Across their consulting engagements, McKinsey observed that companies could compress the average time from &#8220;code complete&#8221; to live production from <strong>89 days to 15 days</strong> when they reorganised around DevOps and product-team principles. Same basic architectures, same kind of features. Six times faster, just from changing how the team takes work from &#8220;done&#8221; to &#8220;deployed.&#8221;<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-5" href="#footnote-5" target="_self">5</a></p><p>The simplest summary: product teams own the value stream end-to-end. Feature and project teams hand off across silos. Handoffs cost time. Time turns into distance from the customer. Distance from the customer means everything you ship is stale.</p><div class="pullquote"><p><em>This newsletter grows by word of mouth&#8230; I&#8217;d really, truly appreciate it if you could refer a friend. Your referrals make it worthwhile.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p></div><h2>Receipt #2: they get more done &#8212; but redefine what &#8220;done&#8221; means</h2><p>&#8220;More done&#8221; is the wrong metric. The right metric is: did anyone use what we shipped?</p><p>In 2002, Jim Johnson &#8212; chairman of the Standish Group &#8212; presented a finding at the XP conference in Sardinia that&#8217;s been quoted ever since: across enterprise applications, only 7% of features are &#8220;always&#8221; used, 13% are &#8220;often&#8221; used and 16% are used &#8220;occasionally.&#8221; That leaves <em>64% of features as either rarely or never used</em>. Standish later extended the analysis to claim that <em>roughly 80% of features deliver low or no value</em>. On large projects, Standish data shows organizations deliver only <em>42% of the features they originally scoped</em><strong>.</strong> The Standish numbers have drawn methodology critiques over the years &#8212; fair enough &#8212; but more recent work points the same direction. Pendo&#8217;s 2019 <em>Feature Adoption Report</em>, drawing on telemetry from hundreds of B2B SaaS products, found roughly <em>80% of features are rarely or never used</em>.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-6" href="#footnote-6" target="_self">6</a></p><p>Sit with that for a moment.</p><p>Now, &#8220;rarely used&#8221; isn&#8217;t synonymous with &#8220;no value.&#8221; Some rare features are quietly essential &#8212; compliance flags, account recovery, the audit trail your CISO will ask about exactly once. Both Pendo and Standish gloss over that distinction. Even granting it generously, though, the ratios still point at a meaningful misallocation: a lot of effort going into features customers rarely or never engage with. (I&#8217;m looking at you, Microsoft Office).</p><p>A feature team measured on roadmap output is, by these numbers, building a sizable wedge of low-value work. They look terrific on burndown charts and terrible on customer impact.</p><p>I&#8217;ve watched this play out enough times to be cynical about it. A feature team gets a quarterly roadmap. They estimate the work in story points, deliver on schedule, demo a sleek end-to-end flow and get applauded. Six months later, telemetry shows the feature gets touched by 3% of users. By then the team has moved on to the next item on the roadmap. Nobody is accountable for the gap between &#8220;shipped&#8221; and &#8220;mattered,&#8221; because shipped <em>is</em> the goal.</p><p>A product team would have caught that earlier. They wouldn&#8217;t have built the full feature on a quarterly roadmap; they&#8217;d have built the cheapest possible version that tested the hypothesis &#8212; a prototype, an A/B variant, a deliberately ugly first cut &#8212; and watched the data. If the data said 3%, they&#8217;d have killed the feature in week two and gone after a more promising hypothesis. That&#8217;s the discovery discipline Marty Cagan and Teresa Torres write about extensively, and it&#8217;s the operational reason product teams build less and deliver more. Not because they&#8217;re slower. Because they aim differently. They invest in discovery before commitment. They kill a feature that doesn&#8217;t earn its keep. They redefine &#8220;done&#8221; from &#8220;shipped&#8221; to &#8220;moved the metric.&#8221; And the metric they move is customer behavior, not story points. (I&#8217;ve made the same argument from a measurement angle in <a href="https://blog.bosslogic.com/p/stop-measuring-effort-4ed827b470ae">Stop measuring effort</a>.)</p><p>There&#8217;s a parallel finding in McKinsey&#8217;s <em>What makes product teams effective?</em> &#8212; a five-year study of <em>more than 1,700 teams across 75 organizations</em>. McKinsey identified two structural conditions that consistently predict throughput and velocity improvements: dedicated team membership (no context switching across projects) and team persistence of three to six months minimum. Teams meeting both conditions develop reliable estimates and sustained throughput. Teams that don&#8217;t, can&#8217;t.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-7" href="#footnote-7" target="_self">7</a></p><p>That finding isn&#8217;t surprising if you think about how knowledge accumulates. Product orientation depends on knowledge durability &#8212; context that only forms when the same people work on the same problem long enough to internalise it (more on this below). Project teams dissolve before that happens. Feature teams reorganise around the next quarterly priority. Product teams stay put. That&#8217;s why their throughput compounds.</p>
      <p>
          <a href="https://blog.bosslogic.com/p/product-teams-really-do-outperform">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Your AI is not your mentor]]></title><description><![CDATA[Use it relentlessly for code tutoring. But the formation work &#8212; being seen, stretched and told the truth &#8212; has to come from a person.]]></description><link>https://blog.bosslogic.com/p/your-ai-is-not-your-mentor</link><guid isPermaLink="false">https://blog.bosslogic.com/p/your-ai-is-not-your-mentor</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Wed, 29 Apr 2026 11:12:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!QbVr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QbVr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QbVr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!QbVr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!QbVr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!QbVr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QbVr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg" width="1456" height="971" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:971,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:334100,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/195521876?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QbVr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg 424w, https://substackcdn.com/image/fetch/$s_!QbVr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg 848w, https://substackcdn.com/image/fetch/$s_!QbVr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!QbVr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87e17719-c764-4d7b-80fc-d7c1b351cce2_3000x2000.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@terry_quangt?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Terry Tran</a> on <a href="https://unsplash.com/photos/silhouette-of-man-under-blue-sky-during-sunset-6IncPZISGAs?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>A junior developer told me they&#8217;re using Claude as a mentor. They liked the patience that never wore thin, the availability that never closed, the way they&#8217;re never made to feel doltish.</p><p>Here&#8217;s what worried me: they said <em>mentor</em>. Not tutor. <em>Mentor</em>.</p><p>I don&#8217;t think they&#8217;re wrong about what they&#8217;re getting. But mentorship isn&#8217;t about answers. It&#8217;s about being seen &#8212; watched while you struggle, nudged when you&#8217;re avoiding hard conversations, sent on projects that stretch you in ways you didn&#8217;t ask for. Mentors have the nerve to tell you the truth in private because they&#8217;re invested in who you&#8217;re becoming.</p><p>AI can&#8217;t do that. Because it isn&#8217;t invested in you. Because it&#8217;s not &#8220;in the room.&#8221;</p><div class="pullquote"><p><em>If you&#8217;re new, welcome to Customer Obsessed Engineering! I publish about one article each week. Free subscribers can read about half of every article, plus all of my free articles.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/subscribe?"><span>Subscribe now</span></a></p><p><em>Anytime you&#8217;d like to read more, you can upgrade to a paid subscription.</em></p></div><h2>What AI is genuinely good at</h2><p>Let&#8217;s start with what&#8217;s actually working, because this isn&#8217;t a piece about being suspicious of the tools. The tutoring story is real. It&#8217;s the part of the AI hype that&#8217;s actually earned.</p><p>Benjamin Bloom&#8217;s famous 1984 paper described what he called the &#8220;2 sigma problem:&#8221; students who received one-on-one tutoring performed two standard deviations better than students in conventional classrooms &#8212; that&#8217;s the difference between an average student and the top 2 percent. The catch was scale. Personal tutors are expensive, and most students will never have one. For forty years that gap has been the unsolved promise of education technology.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><p>A well-configured AI is one way we&#8217;re closing it. When Khan Academy rolled out Khanmigo, built on GPT-4, the pitch was exactly this &#8212; a patient, infinitely available one-on-one tutor for every learner. In specific narrow tasks, the early returns are hard to dismiss. Harvard published a physics study in 2024 that found students using a properly designed AI tutor learned over twice as much in less time than their peers. They reported feeling more engaged and motivated.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a></p><p>I see the same thing in software. With the right model, a serious system prompt and a few well-built skills, AI can:</p><ul><li><p>Walk a junior through a debugger session, naming what each frame means and why it matters.</p></li><li><p>Explain <em>why</em> a piece of code is the way it is &#8212; not just what it does &#8212; and adjust the explanation when the question lands a level too high.</p></li><li><p>Run unfamiliar code, watch it fail and reason about the failure with the learner in real time.</p></li><li><p>Drill someone on a foreign language, a SQL idiom or a regex until it&#8217;s automatic.</p></li><li><p>Take the same question for the third time without sighing.</p></li></ul><p>That last one matters more than people admit. A great deal of human learning gets blocked by the social cost of asking again. Removing that cost is genuinely useful. It&#8217;s what the junior in my opening responded to. They felt safe.</p><div class="pullquote"><p><em>Hey, quick favor? Writing this stuff takes real work &#8212; and referrals keep the publication alive. If you&#8217;re finding the playbook valuable, share it with a friend who&#8217;d appreciate the link.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p></div><h2>How tutoring goes wrong</h2><p>It&#8217;s useful, but not magical. The same AI cheerfully invents APIs that don&#8217;t exist, pattern-match on the wrong context and confidently produce code that looks right but isn&#8217;t. Apple researchers showed last year that current LLMs aren&#8217;t doing genuine reasoning at all &#8212; performance on math problems dropped by as much as 65 percent when the team added a single irrelevant clause to the prompt. Andrew Zuo&#8217;s piece on the &#8220;-10X developer&#8221; makes the harder point: when an LLM writes code at or above your level and introduces a subtle bug, you may be the worst possible person to find it.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self">4</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-5" href="#footnote-5" target="_self">5</a></p><p>A newer concern is harder to wave off. An MIT Media Lab study published in mid-2025 used EEG to compare brain activity across people writing essays with no help, with a search engine and with an LLM. The LLM group showed the weakest neural connectivity and the worst ability to recall their own writing minutes after producing it. The researchers called it &#8220;cognitive debt.&#8221; That tracks. Outsource the struggle and the learning never lands.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-6" href="#footnote-6" target="_self">6</a></p><p>So a serviceable tutor, yes. A <em>replacement</em> for thinking, no. None of that, though, is the central point. The central point is that tutoring and mentoring are not the same job, and the public conversation keeps blurring them.</p><h2>What a mentor actually does</h2><p>If you ask me what my mentors did for me over the last forty years, almost none of it was answering technical questions. The technical content I could get from books, from peers, eventually from Stack Overflow and now from Claude (as long as I&#8217;m careful and look for fantasy hallucinations). What my mentors did was something else entirely.</p>
      <p>
          <a href="https://blog.bosslogic.com/p/your-ai-is-not-your-mentor">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[3.7 Elaboration]]></title><description><![CDATA[Elaboration takes your specifications from skeleton to sprint-ready, fully fleshed out across every layer at which the system is tested &#8212; and live-linked to the engineering models that prove them out.]]></description><link>https://blog.bosslogic.com/p/37-elaboration</link><guid isPermaLink="false">https://blog.bosslogic.com/p/37-elaboration</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Tue, 28 Apr 2026 13:32:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!RGTp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!RGTp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RGTp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg 424w, https://substackcdn.com/image/fetch/$s_!RGTp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg 848w, https://substackcdn.com/image/fetch/$s_!RGTp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!RGTp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RGTp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg" width="1456" height="931" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:931,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:351525,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/195610561?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!RGTp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg 424w, https://substackcdn.com/image/fetch/$s_!RGTp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg 848w, https://substackcdn.com/image/fetch/$s_!RGTp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!RGTp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff95a84ed-c7de-45a7-b86a-5af551a06efb_1728x1105.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In <a href="https://blog.bosslogic.com/p/36-specification">3.6 Specification</a> we worked through the first two stages of Behavior Driven Development &#8212; <em>Discovery</em> and <em>Formulation</em>. We surfaced scenarios in three-amigos conversations and shaped them into Gherkin &#8220;Given-When-Then&#8221; statements. That gave us the <em>outline</em> of every feature in our product increment.</p><p>Elaboration is where we move from outline to depth.</p><p>A very important takeaway from chapter 3.6 bears repeating here, because the entire purpose of this activity hangs on it:</p><blockquote><p>The specifications you write now are living documents. They will evolve, change and be added to. That&#8217;s why it&#8217;s so important to create a live link to the implementation &#8212; the code that will validate the specifications. As the specifications change that live link will preserve our value chain from customer desires to delivered code.</p></blockquote><p>Hold on to that idea. Elaboration isn&#8217;t about freezing requirements before the team writes a single line of code. It&#8217;s about building the connections &#8212; between the spec and the marble, between the marble and the test, between the test and the production code &#8212; that let the spec keep evolving without the value chain ever going slack.</p><h2>Introduction</h2><p>This activity has three jobs.</p><p>First, we expand each scenario across the <em>levels</em> at which the system is tested: component and assembly. A login feature has UX scenarios about what the customer sees and experiences. It also has assembly scenarios about which events fire, which commands route through which aggregates and what payload comes back. Both layers need specifications. Both layers need to be testable. Skipping a layer means leaving a gap through which defects love to slip.</p><p>Second, we create a live link between every specification and the engineering model that implements it. Each Gherkin feature points back to a marble. Each marble points forward to a Gherkin feature. That bi-directional link is what makes our specifications living documents &#8212; when the spec changes, the marble updates with it, and vice versa.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p>
      <p>
          <a href="https://blog.bosslogic.com/p/37-elaboration">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Microsoft’s collaboration stack breaks every rule of a modern delivery toolkit]]></title><description><![CDATA[How SharePoint will sink your project: hidden pitfalls that suck the life out of teams. It&#8217;s getting worse, not better.]]></description><link>https://blog.bosslogic.com/p/microsofts-collaboration-stack-breaks</link><guid isPermaLink="false">https://blog.bosslogic.com/p/microsofts-collaboration-stack-breaks</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Mon, 27 Apr 2026 18:13:08 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!vSFM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vSFM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vSFM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg 424w, https://substackcdn.com/image/fetch/$s_!vSFM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg 848w, https://substackcdn.com/image/fetch/$s_!vSFM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!vSFM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vSFM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg" width="1456" height="798" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:798,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:297114,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/195427732?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vSFM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg 424w, https://substackcdn.com/image/fetch/$s_!vSFM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg 848w, https://substackcdn.com/image/fetch/$s_!vSFM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!vSFM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc604e379-5a99-45aa-8d7a-1b113a2a1062_1787x979.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@felixberger?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Felix Berger</a> on <a href="https://unsplash.com/photos/aerial-view-of-broken-hanging-bridge-fZFUlC0l00E?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><div class="pullquote"><p>This article speaks to technical delivery teams with a voice in their tooling decisions. For teams mired in SharePoint and Teams with no way out &#8212; I introduce some strategies to make things better toward the end.</p></div><p>Picture this: a program manager wants to confirm a design decision before a release. She asks, innocently enough, &#8220;Can someone point me at the current version of the architecture document?&#8221;</p><p>A pause. Then: &#8220;I think it&#8217;s in the Teams channel &#8212; the one from the February workshop.&#8221; Someone else chimes in, &#8220;No, there&#8217;s a newer one. Sriram emailed it last week.&#8221; A third voice: &#8220;That&#8217;s the draft. The signed-off version is in the SharePoint site. But the link in the meeting invite is broken because they restructured the folders.&#8221; A fourth: &#8220;I have a copy in OneDrive. It might be the latest, I&#8217;m not sure.&#8221;</p><p>Five people. Five different versions. Zero confidence that any of them is authoritative. And this is a team that <em>cares</em> about documentation.</p><p>The common denominator is always the same: a collaboration stack built on SharePoint, Teams and Microsoft&#8217;s various Office products. Sometimes with Azure DevOps (ADO) bolted on to handle tickets and code.</p><p>Here&#8217;s an argument that will sound harsh to anyone who&#8217;s invested in Microsoft 365 as their delivery platform: the Microsoft collaboration stack is <em>diabolically deficient</em> for serious product delivery. It wasn&#8217;t built for the problem delivery teams <em>actually</em> face. It has, piece by piece, gone after what enterprise IT wanted to solve in 2007: replacing the file share.</p><p>That&#8217;s not the same problem.</p><div class="pullquote"><p style="text-align: center;"><em>If you&#8217;re new, welcome to Customer Obsessed Engineering! I publish about one article each week. Free subscribers can read about half of every article, plus all of my free articles.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/subscribe?"><span>Subscribe now</span></a></p><p style="text-align: center;"><em>Anytime you&#8217;d like to read more, you can upgrade to a paid subscription.</em></p></div><h2>What a delivery team actually needs</h2><p>There are five table stakes a team needs. I describe the first three in <a href="https://blog.bosslogic.com/p/getting-started-using-the-delivery">Getting started: Using the Delivery Playbook</a>. I&#8217;ll restate those briefly here, along with the other two:</p><p><strong>1. Live collaboration.</strong> Multiple people must be able to work on the same artifact at the same time, editing simultaneously, seeing each other&#8217;s cursors, throwing virtual sticky notes on a board in real time. Design work is a collaborative act. The moment one person has to collect and collate feedback, fidelity drops off a cliff.</p><p><strong>2. Version control.</strong> Every change, by every author, is always captured and reversible. Not just &#8220;saved revisions&#8221; &#8212; the full, granular history, searchable, with diffs, always available. This is table stakes. Git has had it for two decades. Any tool that tracks <em>less</em> than Git doesn&#8217;t take the goal seriously.</p><p><strong>3. Immutable linking.</strong> A document&#8217;s URL must <em>never</em> change. Not when the file is renamed. Not when it&#8217;s moved to another folder. Not when the folder is reorganized. Not when the author leaves the company. A reference made today should still resolve in five years. Without this, every link in every other document becomes a ticking time bomb.</p><p><strong>4. Workflow integration.</strong> The documentation platform has to talk, fluently and deeply, to the work-tracking platform. Specs have to link to tickets. Tickets have to link to pages. Status changes in one system should not only be visible in the other, but trigger cross-tool workflow changes and render live embeds, not stale URLs. When that integration is tight, your specs, documentation and tickets stop drifting apart &#8212; they become a single living view of the work, not several systems the team has to reconcile.</p><p><strong>5. Universal, web-first access.</strong> One consistent experience for everyone, on any device. Not a degraded web version and a feature-rich desktop app &#8212; a single canonical surface, served through the browser, that everybody gets equally no matter what hardware they&#8217;re on.</p><p>These five criteria are the measuring stick. Let&#8217;s hold SharePoint &#8212; and Teams and ADO &#8212; up against them.</p><h2>Links that rot</h2><p>This is the most damning, and the one I want to spend the most time on, because it&#8217;s the one almost nobody takes seriously until they&#8217;re knee-deep in the damage.</p><p>In SharePoint, a document&#8217;s URL is a function of its name and its location in the folder hierarchy. Rename the file, and the URL changes. Move it to another folder, and the URL changes. Move the whole folder, and the URLs of every file inside it change. You can turn on &#8220;managed metadata&#8221; and &#8220;content types&#8221; and a bunch of other gears that promise to fix this, but in practice &#8212; across every tenant I&#8217;ve ever touched &#8212; they don&#8217;t. The URLs change. References break.</p><p>Microsoft has shipped &#8220;durable links&#8221; and &#8220;document IDs&#8221; &#8212; features that are off by default and rarely enabled. What a team actually encounters is: you renamed the file, the link in the meeting invite from three weeks ago is now dead. The problem is pervasive enough that a cottage industry of third-party tools has emerged just to detect broken SharePoint links.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><p>Compare that to Atlassian Confluence. Every page has a numeric ID assigned at creation. The ID is embedded in the URL (<code>/pages/12345</code>) and it does not change. You can rename the page, move it between spaces, reorganize the whole tree &#8212; the ID-based link still works. You can also use the human-readable URL (which does change when pages get renamed), but the ID-based URL is your forever-address. The system gives you <em>both</em>, and the tight URL is the one you automatically get when you cite the page in another document.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p><p>This seems like a small, technical detail. It is not. It is the single most consequential design choice a documentation platform makes, because it determines whether cross-references decay or persist.</p><p>Here&#8217;s what happens in practice when links rot: <em>people stop trusting links.</em></p><p>Think about that for a second. The entire promise of the web is that a URL is a durable reference &#8212; it says &#8220;here is the canonical thing, go fetch it when you need it.&#8221; That promise is what lets us build systems on top of systems. Every meeting invite, every wiki page, every code comment, every email that cites a document relies on that promise holding.</p><p>When SharePoint breaks the promise &#8212; which it does, routinely &#8212; teams develop a defensive response. They stop linking. Instead, they <em>attach</em>. They paste a copy of the document into the meeting notes. They email a copy to the distribution list. They download the file and re-upload it to their own folder &#8220;in case the original moves.&#8221; Multiply this by every team, every document, every month, and within a year you have a document landscape that looks like a hoarder&#8217;s basement &#8212; dozens of near-duplicates, none of them canonical, each one owned by a different person who genuinely believes theirs is the latest.</p><p>It&#8217;s <em>rational</em> response. Given that SharePoint links are not reliable, hoarding copies is the locally optimal strategy. However, the result is catastrophic: information silos full of stale documents and an immense toll in lost time and miscommunication.</p><p>The identity model that a platform chooses shapes the behavior of the people using it. SharePoint chose the wrong model &#8212; one that breeds inefficiency and defensive silo-building.</p><h2>The version control mirage</h2><p>SharePoint technically has version control. Open a file, click the ellipsis, choose &#8220;Version history,&#8221; and you&#8217;ll see a list of saves. This sounds like what you want. It is not.</p><p>The version history in SharePoint is coarse, inconsistent across product surfaces and frankly untrustworthy. Here are the problems I&#8217;ve personally run into, repeatedly:</p><ul><li><p><strong>Coauthored Office documents roll up edits from multiple people into &#8220;a version&#8221; at intervals that are not deterministic.</strong> If Alice and Bob are editing at the same time, you may end up with one version of their joint work and inaccurate attribution. Contrast with Git: every commit is atomic, attributed and reversible.</p></li><li><p><strong>The version history for a file in OneDrive, Teams and elsewhere varies.</strong> There is no single source of truth. If you open a file with Teams, you see one history. In SharePoint, you may see a different history &#8212; a consequence of Office 365 evolving from a constellation of separately-designed products Microsoft is still trying to stitch together.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a></p></li><li><p><strong>Restoring a prior version </strong><em><strong>might </strong></em><strong>overwrite the current one, rather than branching.</strong> If you discover at 4pm that something important got lost at 10am, &#8220;restore&#8221; could mean losing everything done between 10am and 4pm. Until recently, this was the default behavior &#8212; so be careful.</p></li></ul><p>Confluence, again, does this properly. Every save is a version. Every version compares cleanly against any other. You see what changed, who changed it and when. You can restore a prior version <em>as a new version</em>, preserving full history. This is how version control is supposed to work, and it has been the standard behavior in software since RCS shipped in 1982.</p><p>Why does this matter for delivery? Because design artifacts evolve, and the history of how they evolved is often as valuable as the current state. When the security auditor asks, &#8220;When did we add this API endpoint to the threat model?&#8221; &#8212; the answer lives in the diff. When a customer says, &#8220;The contract we signed described a different data retention policy,&#8221; &#8212; the answer lives in the history. When a post-mortem asks, &#8220;When did we know about this failure mode?&#8221; &#8212; the answer lives in the version log.</p><p>A platform that can&#8217;t answer these questions reliably is a platform that is actively hostile to engineering rigor.</p><h2>Teams, Teams Sites and the organizing layer</h2><p>If the first two failures are about individual artifacts, this one is about the landscape those artifacts live in.</p><p>Microsoft Teams is, at heart, a chat application. When it was first released in 2017, that&#8217;s primarily what it did. Over the years, Microsoft has tried to turn Teams into a &#8220;hub for teamwork.&#8221; Marketing-speak for bolting everything else Microsoft makes onto the chat app. The Files tab in a Teams channel is a SharePoint document library wearing a trenchcoat. A &#8220;Teams Site&#8221; is a SharePoint site with a slightly different navigation chrome. Meeting recordings live in OneDrive, not in the channel. Meeting transcripts live in the meeting artifact, which sometimes appears in the channel and sometimes doesn&#8217;t. Planner tasks live in a separate product surface that is also &#8220;integrated.&#8221;</p><p>If someone in your team wants to find something, they have to know, in advance, through which product surface it was shared. Was the spec posted in a channel? Check the chat history. Attached to a meeting? Check the meeting recap. Uploaded to the Files tab? That&#8217;s SharePoint under the hood, but the folder structure might only be reachable through the Teams UI. Created as a Teams Site? Different URL. Shared in a meeting chat? That goes to OneDrive, in a folder you might not have permission to browse.</p><p>There is no single &#8220;where did we put the thing&#8221; surface. There are five or six of them, depending on how the team has been using the tools, and the mapping between &#8220;what kind of content&#8221; and &#8220;which surface&#8221; is convention rather than enforced policy.</p><p>In contrast, Confluence is the document surface. Jira is the work surface. Each is a single, distinct product doing one thing well, and the integration points between them are narrow and explicit and <em>they work</em>. No guessing where a document lives &#8212; it&#8217;s in Confluence. Tickets live in Jira. No impedance mismatch, no cognitive dissonance.</p><p>Teams wants to be the union of every Office 365 capability. But integration isn&#8217;t about putting everything in the same UI. It&#8217;s about making the right connections <em>between</em> distinct tools, so that each one stays simple and focused, and the connections carry exactly the semantics you need. Teams never understood that distinction.</p><h2>Desktop is king, the browser is second-class</h2><p>SharePoint and the rest of Office 365 are web-accessible, but they aren&#8217;t web-<em>first</em>. Their heritage is Microsoft Office &#8212; a suite designed for the desktop and perfunctorily ported to the browser. The difference is not academic.</p><p>Open a Word doc in the browser and compare it to the desktop app. The feature set diverges. Advanced formatting, compare-versions, certain macro and formula capabilities, add-ins &#8212; these are missing or degraded on the web.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self">4</a></p><p>The consequences cascade. &#8220;The copy you want is on my laptop&#8221; is a phrase I hear almost every week. Co-authoring gets flakey or breaks entirely because of diverging copies. Changes sit in someone&#8217;s sync queue for hours. A document that looks current in SharePoint may be stale. Information silos reappear &#8212; not because anyone intended it, but because the tool keeps pulling work off the web and onto individual machines.</p><p>Contrast with Confluence, Jira and Miro. Every one of them is web-first by design. There&#8217;s no desktop app with a superset of features. The browser <em>is</em> the product. Everyone gets the same experience &#8212; Windows, Mac, Linux, iPad, phone, Chromebook &#8212; because there&#8217;s only one experience to get. One canonical home, universally accessible, identical for everyone.</p><p>This is what the web was built for. Atlassian and Google stacks lean into that. Microsoft fights it.</p><h2>The ADO integration gap</h2><p>This one is specific to teams that pair SharePoint with Azure DevOps for their ticket tracking and code hosting. It&#8217;s a common combo, because &#8220;we already have Microsoft&#8221; is an easy procurement story, and ADO does a lot of things adequately.</p><p>But the integration between SharePoint and ADO is thin. Thin to the point of &#8220;here is a hyperlink from the work item to the SharePoint page, good luck.&#8221; There is no live embed. There is no bidirectional status update, rich preview or shared workflow trigger. If I link to a SharePoint page from an ADO work item, you see a URL. If that URL breaks, the work item becomes an orphan.</p><p>In contrast, a Jira issue in a Confluence page renders a live, interactive issue card with issue key, title, status, assignee and priority &#8212; and that card updates when the issue does. If I embed a Jira query in a Confluence page, the page shows a table of live results &#8212; as of right now. A Confluence page can be the <em>dashboard</em> for a delivery effort: status pulled from Jira, specs authored inline, risks tracked in a live table, all rendering from the underlying systems of record.</p><p>You can build most of this in the Microsoft stack with enough Power Automate flows, Graph API queries, custom connectors and a patient engineer. I&#8217;ve seen it attempted. I&#8217;ve yet to see it done well enough to matter. The effort required to get SharePoint + ADO to mimic what Confluence + Jira does out of the box is roughly the effort of a mid-size integration project &#8212; a project that has to be maintained, re-tested with every platform update, and reverse-engineered when the person who built it leaves the company. That&#8217;s not an integration. That&#8217;s a liability.</p><h2>Workflow is an afterthought</h2><p>The last failure is workflow management &#8212; specifically the modeling and enforcement of state transitions for work items.</p><p>Jira gets this right. The workflow editor is a first-class product, with a first-class visual flow designer, transition conditions, validators, post-functions, custom statuses and permission checks. A non-engineer on the delivery team can design a workflow that enforces &#8220;a ticket cannot transition from &#8216;In Review&#8217; to &#8216;Done&#8217; unless the code review is merged with clean quality gates, the responsible stakeholder has reviewed the feature and all acceptance criteria are passing green.&#8221; Express it in the GUI, save it, extend with code as needed and the tool enforces it across every ticket that follows that workflow. The team controls its own process &#8212; and the workflow itself is a first-class artifact: auditable, exportable, evolvable.</p><p>ADO has &#8220;process customization.&#8221; It is possible to model custom workflows. In practice the feature is buried behind an admin gate, its conditions are a shallow subset of Jira&#8217;s, and most teams I&#8217;ve worked with never meaningfully touch it. They either live with the default &#8212; generic, not their actual process &#8212; or they reinvent the enforcement in spreadsheets, PowerBI dashboards, or human oversight routines that have to be re-explained to every new hire.</p><p>The reason this matters: workflow is the mechanism by which a team&#8217;s process becomes automatic. If your workflow tool doesn&#8217;t let you encode &#8220;we agreed code reviews are mandatory before a feature branch is merged,&#8221; then code reviews are not mandatory &#8212; they&#8217;re optional, governed only by vigilance, and skipped the moment someone is under pressure. Jira&#8217;s workflow editor is a force multiplier for team discipline, because it turns &#8220;we agreed to do this&#8221; into &#8220;the tool won&#8217;t let you skip it.&#8221; ADO gives you a <em>significantly</em> weaker version of that lever, and most teams don&#8217;t reach for it at all.</p><p>The cost is reliability. Teams using Jira-style workflow enforcement ship with fewer process escapes &#8212; missing reviews, missed gates, skipped steps. Teams using ADO&#8217;s default setup rely on human memory and goodwill &#8212; both fail at scale. The difference shows up in incident rates, audit findings and the quality of the artifacts the team produces.</p><div class="pullquote"><p><em>This newsletter grows by word of mouth&#8230; I&#8217;d really, truly appreciate it if you could refer a friend. Your referrals make it worthwhile.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p></div><h2>What all this costs the team</h2><p>If you&#8217;re keeping a tally, the SharePoint/Teams/ADO stack fails on every criterion. Links don&#8217;t persist. Version control is a mirage. The organizing layer is fragmented. The browser is a second-class citizen. Integrations are absent or thin. Workflow is an afterthought.</p><p>What does this actually cost a delivery team?</p><p>It costs <em>time</em>. A lot of it. The 2024 Stack Overflow Developer Survey (65,000 respondents) found that 61% of developers spend more than 30 minutes every day just searching for answers &#8212; and 30% say knowledge silos hit their productivity ten or more times per week.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-5" href="#footnote-5" target="_self">5</a></p><p>It costs <em>trust</em>. When the documentation landscape is chaotic, people stop trusting it as a source of truth. They start relying on oral tradition &#8212; &#8220;ask Alice, she knows&#8221; &#8212; and on personal copies. Key decisions stop being recorded in a place anyone can find. Onboarding becomes a six-month apprenticeship rather than a process a new hire can self-serve. Organizational memory degrades.</p><p>It costs <em>quality</em>. DORA's research (2022 State of DevOps Report) found that documentation quality is one of the most powerful amplifiers of engineering performance: teams with above-average documentation quality see 12.8x the organizational performance lift from the same technical practices compared to teams with poor documentation.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-6" href="#footnote-6" target="_self">6</a></p><p>It costs <em>morale</em>. Engineers are, as a group, unusually sensitive to tool quality. I&#8217;ve seen engineers turn down offers, quit, or burn out over the cumulative drag of bad tooling. A team that feels its own stack is working against them never reaches its potential, however talented the individuals. Tool quality is retention strategy.</p><h2>Stuck with the stack? Fight back.</h2><p>If you&#8217;re committed to SharePoint, Teams and ADO for the next few years, none of the above changes that. But a handful of disciplines can reduce the damage. None will turn the Microsoft stack into Confluence &#8212; they just stop the bleeding.</p><p>Here&#8217;s six specific strategies you can follow:</p>
      <p>
          <a href="https://blog.bosslogic.com/p/microsofts-collaboration-stack-breaks">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[When to go waterfall]]></title><description><![CDATA[If you're working in a multi-modal organization you'll find this helpful: the canonical waterfall / agile decision tree.]]></description><link>https://blog.bosslogic.com/p/waterfall-versus-agile-decision-tree</link><guid isPermaLink="false">https://blog.bosslogic.com/p/waterfall-versus-agile-decision-tree</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Tue, 24 Mar 2026 11:46:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-lm7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-lm7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-lm7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-lm7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-lm7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-lm7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-lm7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg" width="1456" height="925" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:925,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:243988,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/195331528?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-lm7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg 424w, https://substackcdn.com/image/fetch/$s_!-lm7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg 848w, https://substackcdn.com/image/fetch/$s_!-lm7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!-lm7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47630fda-899d-4486-a4f2-9ec17e429b78_1500x953.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@marcusdallcol?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Marcus Dall Col</a> on <a href="https://unsplash.com/photos/waterfalls-photograph-u99NDO-4Wv8?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>I was recently asked to critique a new decision tree that helps teams decide between waterfall and agile when starting a new project. The intended outcome is to improve long-term results in the organization by giving teams the ability to make critical decisions quickly and accurately.</p><p>Overall, &#8220;good shift-left stuff&#8221; in my book. Anyhow, here&#8217;s the diagram I was asked to comment on:</p>
      <p>
          <a href="https://blog.bosslogic.com/p/waterfall-versus-agile-decision-tree">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Observability as architecture: why you can’t bolt it on later]]></title><description><![CDATA[Most teams treat observability like a nice-to-have. They&#8217;re building blind &#8212; and paying for it in ways they can&#8217;t even see.]]></description><link>https://blog.bosslogic.com/p/observability-as-architecture-why</link><guid isPermaLink="false">https://blog.bosslogic.com/p/observability-as-architecture-why</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Fri, 13 Mar 2026 21:25:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!3tAI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3tAI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3tAI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3tAI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3tAI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3tAI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3tAI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg" width="1456" height="970" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:970,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:298690,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/194076785?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3tAI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3tAI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3tAI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3tAI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4467c5c5-d788-44cd-9096-cd2ebdc216b9_2150x1433.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@supernov?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Edi Libedinsky</a> on <a href="https://unsplash.com/photos/girl-making-hand-gesture-on-her-face-1bhp9zBPHVE?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div><p>I once joined a team that had been struggling with delivery for the better part of two years. Demos kept failing. Deployments kept crashing production. Rollbacks were so routine that the ops team had gotten eerily efficient at them. (I&#8217;ll refer back to the team later &#8212; let&#8217;s call the company &#8220;Acme&#8221;).</p><p>I remember one in particular. The team was demoing a reactive search feature &#8212; the kind of thing where you start typing a product name and suggestions appear in real time. Same idea as typing &#8220;penguins&#8221; into Google and getting &#8220;Penguins of Madagascar&#8221; as a suggestion.</p><p>The demo cratered. Someone typed a product name, and nothing happened. Twenty minutes of poking around later, the demo was cancelled. What struck me wasn&#8217;t the failure itself &#8212; it was the reaction. Nobody was surprised. Nobody expected it to work. &#8220;Maybe next time.&#8221;<sup><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></sup></p><p>Later that afternoon, a planned deployment seemed to have crashed a key service. All hands on deck for a rollback. The team executed quickly. Rollback done. They&#8217;d had a lot of practice.</p><p>Here&#8217;s what immediately jumped out at me: in both cases the team had zero operational intelligence. No telemetry. No metrics. No centralized logs. No traceability. No way to quickly zero in on a root cause. They were flying blind &#8212; and they&#8217;d been flying blind so long they&#8217;d forgotten what visibility even looked like.</p><p>And that&#8217;s why the reaction was the same each time. Abort. Rollback. &#8220;Afterward, we&#8217;ll figure out what&#8217;s wrong.&#8221;</p><p>The irony is that both failures had quick fixes. Each time, queries weren&#8217;t reaching a service because the wrong port was configured. Instead of changing the port and continuing, the team burned hours &#8212; even days &#8212; backtracking, diagnosing and trying again.</p><p>That experience crystallized something I&#8217;d been <em>feeling</em> for decades: observability isn&#8217;t a tool you add. It&#8217;s an architectural decision you make &#8212; or don&#8217;t. And the cost of not making it compounds in ways that are genuinely difficult to measure, precisely because you don&#8217;t have the instrumentation to measure them.</p><div class="pullquote"><p><em>If you&#8217;re new, welcome to Customer Obsessed Engineering! Every week I publish a new article, direct to your mailbox if you&#8217;re a subscriber. As a free subscriber you can read about half of every article, plus all of my free articles.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/subscribe?"><span>Subscribe now</span></a></p><p><em>Anytime you&#8217;d like to read more, you can upgrade to a paid subscription.</em></p></div><h2>The &#8220;flying blind penalty&#8221;</h2><p>In the old days &#8212; before cloud, before microservices, before systems became truly distributed &#8212; opacity was tolerable. You had a monolith on a few servers. If something broke, you SSH&#8217;d in, looked at logs, poked around. It might take hours, but there wasn&#8217;t that much territory to cover.</p><p>Modern systems don&#8217;t afford that luxury. A single user request could traverse dozens of services, touching databases, message queues, caches and external APIs along the way. Just today I participated in a sprint review discussing a database architecture that was <em>29 views deep.</em> A latency spike could originate in any one of those &#8212; or in the invisible interplay between the services that call them.</p><p>Without observability, you&#8217;re operating on instinct and prayer.</p><p>Here&#8217;s what that looks like in practice. A bug ships. It doesn&#8217;t manifest right away &#8212; it surfaces under load, or in a specific user segment, or under certain timing conditions. By the time anyone notices, users are already suffering. Now the team has to diagnose the problem. If they&#8217;re lucky, someone complains and provides enough detail to be helpful. They narrow down which service is involved, reproduce the issue, trace the flow of data through the system, find the root cause, fix it, deploy and verify.</p><p>The whole time, sweating over how many more customers are running into the problem.</p><p>Every single step without observability compounds in difficulty. You&#8217;re not just debugging &#8212; you&#8217;re doing archaeology at midnight, piecing together behavior from scattered artifacts across dozens of services.</p><p>With observability designed in from the start, you proactively see which service is degraded. You can drill into specific request traces. You can correlate logs across service boundaries. Mean time to detect and repair drops from hours to minutes &#8212; even becoming predictive.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a></p><p>DORA.dev research bears this out. Elite-performing teams &#8212; the ones deploying multiple times per day with sub-hour recovery times &#8212; aren&#8217;t elite because they have better engineers. They&#8217;re elite because visibility closes a critical gap: it&#8217;s a prerequisite for every other capability DORA measures. They can detect and diagnose problems before those problems cascade. Their systems are instrumented to answer questions the team hasn&#8217;t even thought to ask yet.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a></p><h2>What matters is how you think about the problem</h2><p>Monitoring and observability are not the same thing.</p><p><em>Monitoring</em> answers questions you anticipated. You watch CPU utilization, disk space, error rates. You set thresholds and alert when they&#8217;re exceeded. &#8220;Is the database up? Is the error rate spiking?&#8221; These are <em>known</em> questions about <em>known </em>conditions.</p><p><em>Observability</em> answers questions you haven&#8217;t thought of yet. It&#8217;s the ability to interrogate your system&#8217;s behavior without adding new instrumentation every time you have a new question. &#8220;Why is this specific user&#8217;s checkout so slow today when it was fine yesterday? What changed in the request path between those two deployments?&#8221;</p><p>Charity Majors &#8212; co-founder of Honeycomb and one of the sharpest voices on this topic &#8212; frames it as the difference between known-unknowns and unknown-unknowns. Monitoring handles the known-unknowns: the things you anticipated might go wrong. Observability handles the unknown-unknowns: the things you couldn&#8217;t have predicted. It empowers you to follow the breadcrumbs wherever they lead.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self">4</a></p><p>Monitoring is reactive. Observability is generative &#8212; it creates the conditions for discovery.</p><p>Daniela Miao, CTO of Momento, put it well in a Dev Interrupted episode: &#8220;By giving more visibility into what&#8217;s happening with your software, your application, you actually do enable development to be faster as well. It&#8217;s not just insurance for when something goes wrong.&#8221;<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-5" href="#footnote-5" target="_self">5</a></p><p>That&#8217;s critical. Most teams think of observability as insurance &#8212; you invest in it to cushion the blow when things break. But the real dividend is velocity. Teams with strong observability ship faster because they can <em>see</em> the impact of their changes in real time. They don&#8217;t have to guess whether a deployment worked or a tweak to a query ran faster. They know.</p><h2>Why we don&#8217;t instrument on day one</h2><p><em>Early stage.</em> You&#8217;re shipping fast. Three or four services, maybe. Errors go to a text file. You&#8217;re small enough that you can hold the whole system in your head. Observability feels like overkill. &#8220;It&#8217;s in the logs, just read &#8216;em.&#8221;</p><p><em>Growth.</em> Suddenly there are ten services, and logs are scattered across different servers. You can&#8217;t correlate them anymore. Someone says &#8220;we should get a logging tool.&#8221; You pick one &#8212; Datadog, Splunk, whatever &#8212; and bolt it on. The instrumentation is inconsistent. Some services are covered, others aren&#8217;t. Metrics are sparse and don&#8217;t tell a coherent story. You&#8217;re reading fragmented logs from disparate systems and trying to correlate events in your head. It&#8217;s starting to fall apart.</p><p><em>Pain.</em> Now you have fifty services. Traffic has increased tenfold. Something breaks, and you&#8217;re still flying blind &#8212; not because you lack tools, but because the observability layer wasn&#8217;t <em>designed</em>. It was stitched on, piecemeal, after the fact. Different teams instrumented different things using different conventions. Tracing is incomplete. Metrics don&#8217;t correlate with logs. You&#8217;re paying more and more for tools that don&#8217;t give you the insight you need.</p><p>Here&#8217;s what&#8217;s easy to miss: that team <em>invested</em> in observability. They bought the tools. They checked the box. But because every investment was reactive &#8212; a logging platform when logs got painful, a metrics dashboard when someone asked for one, a tracing system when debugging got unbearable &#8212; they ended up with three separate systems that don&#8217;t talk to each other. Logs in one silo, metrics in another, traces in a third. Every decision about what to capture was made at write time, under pressure, for a specific fire they were fighting that week.</p><p>Charity Majors, co-founder of Honeycomb, calls this Observability 1.0: many pillars, many sources of truth, many tools. It&#8217;s what you get by default when you bolt observability on after the fact. The fragmentation isn&#8217;t a failure of effort &#8212; it&#8217;s a consequence of timing. You can&#8217;t design a unified telemetry model when you&#8217;re patching gaps reactively.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-6" href="#footnote-6" target="_self">6</a></p><p>And it matters &#8212; because a fragmented model can answer the questions you anticipated (is the database up? is the error rate spiking?) but collapses when you need to ask something new. &#8220;Why are checkouts slow today when they were fine yesterday? What changed between those two deployments?&#8221; Those questions require slicing across dimensions you didn&#8217;t pre-define. They require the kind of open-ended interrogation that siloed tools simply can&#8217;t support.</p><p><em>Insight</em> requires <em>design.</em> That&#8217;s the part teams miss.</p><p>Why does this happen? Because observability isn&#8217;t a feature. It&#8217;s not something you built first, it&#8217;s what got built <em>last.</em> It doesn&#8217;t generate revenue &#8212; at least not visibly. It feels expensive up front. And teams, under pressure to deliver, don&#8217;t demand the time they need for planning a solid foundation.</p><p>I&#8217;ve written about the same false economy with <a href="https://blog.bosslogic.com/p/when-should-you-think-about-security">security</a> and <a href="https://blog.bosslogic.com/p/delivering-customer-value-with-bdd">testing</a>. The things that feel expensive to build at the start turn out to be astronomically more expensive to retrofit.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-7" href="#footnote-7" target="_self">7</a></p><h2>Why it has to be architectural</h2><p>You can&#8217;t add observability with a library import. You <em>can</em> add logging and metrics &#8212; that&#8217;s the easy part. But genuine observability, the kind that lets you answer arbitrary questions about system behavior, requires architectural forethought.</p><p>Consider what&#8217;s involved:</p><ol><li><p><strong>How do requests get identified as they flow across boundaries?</strong> Trace IDs need to propagate through HTTP headers, message queue metadata, database session context &#8212; everywhere a request touches. If you don&#8217;t design this in, you can&#8217;t correlate activity across services.</p></li><li><p><strong>What events merit recording?</strong> Not every line of code should produce a log. That&#8217;s noise. But the meaningful transitions &#8212; state changes, boundary crossings between services, external calls and their response characteristics &#8212; these are the signals that matter.</p></li><li><p><strong>What metrics actually reflect system health?</strong> Not just CPU and memory, but application-level indicators. How long do payment transactions take? What&#8217;s the cache hit ratio? What&#8217;s the queue depth trend? These are the metrics that tell you whether your system is <em>behaving</em> &#8212; or trending toward overload.</p></li><li><p><strong>How does context propagate?</strong> When a request carries metadata &#8212; a customer ID, a feature flag, a request source &#8212; how does that context flow through the system in a way that key transitions are captured seamlessly?</p></li></ol><p>This is the shape of how you structure services, how you handle requests, how you organize code. And capturing it after the fact is brutally hard.</p><p>For example: if you decide later that you want end-to-end tracing, you need to add trace ID generation at your entry points, thread those IDs through every service-to-service call, correlate logs using those IDs, and store traces in a specialized backend. That means touching every API, every RPC, every async boundary. If you&#8217;d built it in from the start, it&#8217;s a few lines of middleware.</p><p>Consider structured logging: if you&#8217;ve been writing freeform string logs for two years, migrating to structured JSON events means auditing every logging statement, retrofitting context and rewriting every query your team depends on. If you start with structured logs, it&#8217;s just how things work from day one.</p><p>It&#8217;s not expensive when you build it in. It&#8217;s a handful of decisions, many of which improve things by introducing consistency. OpenTelemetry standardizes the plumbing &#8212; trace propagation, metric collection, structured logging &#8212; across languages and frameworks. You focus on <em>what</em> to instrument, not <em>how</em> to propagate context.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-8" href="#footnote-8" target="_self">8</a></p><p>But retrofitting: that&#8217;s an ordeal. Orders of magnitude more expensive &#8212; in engineering time, in tool sprawl and in the debugging sessions that never needed to happen.</p><h2>What to actually build</h2><p>Here&#8217;s how to do it right &#8212; whether you&#8217;re making the investment in an old project or starting fresh. The key is to think in events, not pillars.</p><h3>Start with events, not tools</h3><p>The most consequential decision you&#8217;ll make is how you model your telemetry. Do you emit three separate streams &#8212; logs here, metrics there, traces somewhere else &#8212; and try to correlate them after the fact? Or do you start with a single primitive: one structured event per unit of work?</p><p>The event-first approach works like this: when a request enters your system, you begin composing a structured event &#8212; a wide, context-rich record that accumulates everything meaningful about that request as it flows through your services. By the time the request completes, the event carries the trace ID, service name, duration, user ID, feature flags, error state, dependency latencies, cache hits, queue depths &#8212; whatever context matters.</p><p>You store that event once. From that single store, you can <em>derive</em> everything else: aggregate events over time and you get metrics; filter and read individual events and you get logs; stitch events together by trace ID and you get traces. One source of truth, many views.</p><p>This is what Charity Majors calls Observability 2.0 &#8212; and it&#8217;s the architecture that actually delivers on the promise of answering questions you haven&#8217;t thought of yet. Because the events are wide (carrying dozens or hundreds of fields), you can slice by any dimension after the fact. You didn&#8217;t have to anticipate the question at write time. You just ask it: &#8220;show me all events where <code>cache_hit=false</code> and <code>region=eu-west</code> and <code>latency_p99 &gt; 2s</code>.&#8221; If those fields are in the event, you get your answer.</p><p>Compare that to the three-pillars approach, where you'd need to have predefined that specific metric, logged that specific combination, and hoped your tracing tool captured the right spans. Three tools, three queries, three partial answers &#8212; if you&#8217;re lucky.</p><p>The event model is the architectural decision. Everything else follows from it.</p><div class="pullquote"><p><em>This newsletter grows by word of mouth&#8230; I&#8217;d really, truly appreciate it if you could refer a friend. Your referrals make it worthwhile. And this button earns you free access!</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p></div><h3>Establish a trace ID convention</h3><p>Every request gets a unique identifier the moment it enters your system. That ID propagates through every downstream call &#8212; HTTP headers, message metadata, database session context. Every event includes it.</p><p>This is foundational. Without it, you cannot correlate activity across service boundaries. With it, a single ID connects every event across every service for a given request. It&#8217;s what lets you stitch individual events into a complete trace &#8212; the full journey of a request through your system.</p><p>OpenTelemetry handles those mechanics gracefully. Use it. It&#8217;s language-agnostic, framework-aware and it solves the propagation problem so you don&#8217;t have to.</p><h3>Enrich your events at every boundary</h3><p>Not every line of code should produce telemetry. That&#8217;s noise. The moments that matter are the boundaries and transitions &#8212; the points where a request crosses from one domain to another or where state changes meaningfully:</p><ol><li><p><strong>Request entry</strong> &#8212; what arrived, who initiated it, what context it carried.</p></li><li><p><strong>External calls</strong> &#8212; what you called, what came back, how long it took.</p></li><li><p><strong>State changes</strong> &#8212; meaningful transitions: a payment processed, a queue depth shifted, a circuit breaker tripped.</p></li><li><p><strong>Errors</strong> &#8212; always, with full context. Stack traces, request metadata, the works.</p></li></ol><p>At each of these boundaries, you&#8217;re not firing off a disconnected log line &#8212; you&#8217;re enriching the event that represents this unit of work. Add fields: <code>payment_gateway_latency_ms=302</code>, <code>cache_hit=false</code>, <code>feature_flag_new_checkout=true</code>. The event gets wider and richer as the request progresses. When the request completes, it captures the full story.</p><p>Make every field structured and discrete. Not a freeform string like &#8220;User 12345 logged in from 192.168.1.1&#8221; &#8212; but named fields: <code>user_id=12345</code>, <code>source_ip=192.168.1.1</code>, <code>session_id=abc</code>, <code>duration_ms=47</code>. Structured fields are queryable. &#8220;Show me all login failures for user 12345 in the last hour&#8221; becomes a single query instead of a regex excavation.</p><h3>Derive your metrics from the same data</h3><p>Once you have rich, structured events flowing through a single store, metrics become a view &#8212; not a separate system. You aggregate events to spot trends:</p>
      <p>
          <a href="https://blog.bosslogic.com/p/observability-as-architecture-why">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[How waterfall is wrong for software]]></title><description><![CDATA[We've known for decades waterfall and software don't mix; why do we keep doing it?]]></description><link>https://blog.bosslogic.com/p/how-waterfall-is-wrong-for-software</link><guid isPermaLink="false">https://blog.bosslogic.com/p/how-waterfall-is-wrong-for-software</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Sun, 08 Mar 2026 12:23:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!uzY8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uzY8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uzY8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg 424w, https://substackcdn.com/image/fetch/$s_!uzY8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg 848w, https://substackcdn.com/image/fetch/$s_!uzY8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!uzY8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uzY8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg" width="1456" height="972" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:972,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:288740,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/193494434?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!uzY8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg 424w, https://substackcdn.com/image/fetch/$s_!uzY8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg 848w, https://substackcdn.com/image/fetch/$s_!uzY8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!uzY8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b69733e-60ee-463c-b7aa-f42a2b3075d5_1500x1001.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://www.pexels.com/photo/iguazu-falls-1203565/">Rodolfo Clix</a></figcaption></figure></div><p>You&#8217;re working on an automotive assembly line. Your job is to install the steering column assembly and steering wheel. The next car rolls down the line. You grab the parts and lean in, tools in hand and try to fit the column. It won&#8217;t fit. Something&#8217;s off.</p><p>You look closely and realize the mounting point isn&#8217;t where it should be &#8212; it&#8217;s offset by a few inches. You figure, you&#8217;ll try anyway. No good. Worse, the chassis is aluminum and your steel column will cause galvanic corrosion on contact. You think to yourself &#8212; maybe this car is supposed to have something else entirely &#8212; a joystick, perhaps? You&#8217;re going to need time to research the platform and figure out what belongs here. But you&#8217;re out of time. The line grinds to a halt. Delivery stops. Something unforeseen has surfaced, and you need time to research the right solution.</p><p>That&#8217;s not how automotive assembly lines work. But it <em>is</em> how software works. Building software is about research, discovery and development.</p><div class="pullquote"><p><em>I&#8230;</em></p></div>
      <p>
          <a href="https://blog.bosslogic.com/p/how-waterfall-is-wrong-for-software">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[What happens when the next developer has to understand your AI code?]]></title><description><![CDATA[This study into the long-term cost of AI-driven development reveals some surprising findings. Most other studies only examine short-term outcomes. But what's the long-term impact of AI coding?]]></description><link>https://blog.bosslogic.com/p/when-the-next-developer-gets-your-ai-code</link><guid isPermaLink="false">https://blog.bosslogic.com/p/when-the-next-developer-gets-your-ai-code</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Fri, 30 Jan 2026 13:57:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/youtube/w_728,c_limit/b9EbCb5A408" length="0" type="image/jpeg"/><content:encoded><![CDATA[
      <p>
          <a href="https://blog.bosslogic.com/p/when-the-next-developer-gets-your-ai-code">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[3.6 Specification]]></title><description><![CDATA[Before coding we need to make sure our design has enough fidelity. Specification is about adding those details, the happy paths as well as the failure scenarios, so we're confident moving into coding.]]></description><link>https://blog.bosslogic.com/p/36-specification</link><guid isPermaLink="false">https://blog.bosslogic.com/p/36-specification</guid><pubDate>Wed, 28 Jan 2026 13:06:36 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Z2qZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Z2qZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Z2qZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Z2qZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Z2qZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Z2qZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Z2qZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg" width="1456" height="1008" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1008,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:661819,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/185831127?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Z2qZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Z2qZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Z2qZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Z2qZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdc64a983-67e4-4412-8a52-1f52629a6750_2104x1457.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="pullquote"><p>Behavior Driven Development (BDD) is an important part of refining our specifications. Take a look at this <a href="https://blog.bosslogic.com/p/delivering-customer-value-with-bdd">short companion article</a> to learn <em>why BDD is so important and how it fills gaps that other quality and test practices don&#8217;t.</em></p></div><h1>Introduction</h1><p>This activity is about making sure we&#8217;ve taken the time to think about happy paths as well as failure scenarios. It&#8217;s about adding fidelity to our use cases so that our finished product is a <em>quality</em> product &#8212; one that our customers will enjoy using.</p><p>As part of that process, we&#8217;ll explore variations on the <em>scenarios</em> in our design. For example, we&#8217;ve defined a scenario to make a purchase &#8212; but what about when the credit authorization fails? Or the product isn&#8217;t available in the warehouse? Or our customer adds a duplicate product to the shopping cart? What should we do if the customer abandons their shopping cart?</p><p>Working with your team to think through these scenarios &#8212; poking each scenario, prodding to see if it stands up under pressure, adding new paths if it doesn&#8217;t &#8212; will help ensure our design is solid.</p><div class="pullquote"><p><em>Writing good material is hard work &#8212; that&#8217;s why referrals are so important. Referrals let me know you like my work and keep me writing. Please share this article with a friend!</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;referrer_token=2xiufs&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://blog.bosslogic.com/leaderboard?&amp;referrer_token=2xiufs&amp;utm_source=post"><span>Refer a friend</span></a></p></div><h2>Building better specifications</h2><p>This activity isn&#8217;t just about testing our assumptions &#8212; it&#8217;s about creating better designs. We want to be sure we&#8217;ve thought about how code will be used <em>before</em> we build it. This outside-in pressure tends to produce interfaces that are cleaner, more focused and easier to consume, as well as code that is more reliable.</p>
      <p>
          <a href="https://blog.bosslogic.com/p/36-specification">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[How to fix a $25 bug before it becomes a $37,500 problem]]></title><description><![CDATA[Stop debugging and start designing by "shifting left" with BDD. It's not about testing. It's about feedback loops and thinking clearly about intent before diving into implementation.]]></description><link>https://blog.bosslogic.com/p/delivering-customer-value-with-bdd</link><guid isPermaLink="false">https://blog.bosslogic.com/p/delivering-customer-value-with-bdd</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Sat, 24 Jan 2026 10:11:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!FFyU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FFyU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FFyU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg 424w, https://substackcdn.com/image/fetch/$s_!FFyU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg 848w, https://substackcdn.com/image/fetch/$s_!FFyU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!FFyU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FFyU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg" width="1456" height="1010" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/addf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1010,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:377269,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/185074351?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FFyU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg 424w, https://substackcdn.com/image/fetch/$s_!FFyU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg 848w, https://substackcdn.com/image/fetch/$s_!FFyU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!FFyU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faddf5f48-7f99-4363-b1c9-6fa145aec39b_2104x1460.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="pullquote"><p>As I wrote Chapter 3.6 of the <a href="https://blog.bosslogic.com/s/delivery-playbook">Delivery Playbook</a> (and it started getting too big), I realized the outsize importance of Behavior Driven Development. It&#8217;s fundamental to the playbook. I<em>t protects product and customer value throughout the software lifecycle. So I decided to split this out as a companion article. I hope you find it as essential a practice as I do.</em></p></div><h1>The incident</h1><p>On June 4, 1996, the maiden flight of the European Space Agency's Ariane 5 rocket ended in catastrophic failure. About 40 seconds into its flight sequence, at an altitude of about 3,700 meters, the launcher veered off its flight path, broke up and exploded.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-1" href="#footnote-1" target="_self">1</a></p><p>The cost for this failure was estimated to be $370 million. The rocket was carrying four satellites intended to study the earth&#8217;s magnetosphere. Because of the payload&#8217;s destruction, building new satellites delayed scientific research into the magnetosphere for four more years.<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-2" href="#footnote-2" target="_self">2</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-3" href="#footnote-3" target="_self">3</a></p><p>An elaborate and careful investigation into the cause of the failure was conducted.</p><p>While several factors led to a cascade of events, it came down to a data conversion error &#8212; an error that would have been caught in testing.</p><p>Unfortunately, the internal SRI software exception that caused the problem <em>was never tested</em>. Or, more specifically, it wasn&#8217;t tested in the Ariane 5 configuration. The failure resulted because Ariane 4-era software that used 16-bit signed integers had been plugged into a more modern system &#8212; a system that used 64-bit floating point data. The older Ariane 4 SRI software couldn&#8217;t cope with the new data format.</p><p>That&#8217;s the <em>technical</em> reason.</p><p>There&#8217;s a more important lesson here. The <em>real</em> reason for the failure was <em>human error</em>. Somewhere along the line, a decision was made: the decision that the Ariane 4 SRI module didn&#8217;t need to be retested in the new Ariane 5 configuration.</p><p>The investigatory board pointed to an underlying theme in Ariane 5 development as a root cause, that theme being, &#8220;that software should be considered correct until it is shown to be at fault.&#8221; The board took another view. Their belief was, &#8220;that software should be assumed to be faulty until applying the currently accepted best practice methods can demonstrate that it is correct.&#8221;</p><p>Systems <em>must be tested</em> to prove correct behavior. We cannot simply <em>assume</em> they are correct.</p><div class="pullquote"><p><em>If you&#8217;re new, welcome to Customer Obsessed Engineering! Every week I publish a new article, direct to your mailbox if you&#8217;re a subscriber. As a free subscriber you can read about half of every article, plus all of my free articles.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/subscribe?"><span>Subscribe now</span></a></p><p><em>Anytime you&#8217;d like to read more, you can upgrade to a paid subscription.</em></p></div><h2>Preventable failure</h2><p>The key takeaways from the Ariane 5 disaster are:</p><ol><li><p>We cannot rely on software to be reliable <em>unless currently accepted best practices demonstrate that it is correct</em>.</p></li><li><p>Continuous integration and testing for correctness is necessary &#8212; <em>even when correctness has previously been proven</em>.</p></li></ol><p>The Ariane 5 case is widely taught in software engineering courses as the canonical example of how a simple, preventable defect &#8212; discovered late in the lifecycle (during operation) &#8212; can have catastrophic and costly consequences.</p><p>In fact, we know that the longer we wait to discover a defect, the more costly it is to fix. Research dating back to the 1970&#8217;s says we can fix a defect in design for nearly zero additional cost &#8212; or we can wait until production and spend north of <em>100 times the cost</em> to fix it later (Boehm, 1979).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qzTw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qzTw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png 424w, https://substackcdn.com/image/fetch/$s_!qzTw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png 848w, https://substackcdn.com/image/fetch/$s_!qzTw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png 1272w, https://substackcdn.com/image/fetch/$s_!qzTw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qzTw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png" width="610" height="471.7445054945055" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1126,&quot;width&quot;:1456,&quot;resizeWidth&quot;:610,&quot;bytes&quot;:320044,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/185074351?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qzTw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png 424w, https://substackcdn.com/image/fetch/$s_!qzTw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png 848w, https://substackcdn.com/image/fetch/$s_!qzTw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png 1272w, https://substackcdn.com/image/fetch/$s_!qzTw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44be23db-e741-4aba-88b3-f816108d384f_1567x1212.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This exponential curve isn&#8217;t arbitrary. It reflects the reality that as software progresses through development stages, each defect becomes increasingly entangled with other code. Downstream systems begin to depend on it.</p><p>A requirements misunderstanding caught in design costs a conversation to fix. The same misunderstanding caught after integration means code rework, integration testing, release cycles, product updates and coordination across downstream dependencies. It can cascade into updating <em>multiple </em>products.</p><p>In concrete terms, that $25 defect can be fixed early, &#8220;for free,&#8221; or we can wait until later and spend $2,500 <em>or more</em>.</p><p>And there&#8217;s evidence that a 100X cost factor is by no means the upper limit. More recent research, in some cases, point to a factor of 1,500X cost to correct defects in operations. That $25 design defect just turned into a $37,500 cost to correct. There&#8217;s no upper limit &#8212; as the Ariane 5 team learned. (If you&#8217;re interested in reviewing more recent data there are references to NIST, NASA and Westland research in the footnotes).<a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-4" href="#footnote-4" target="_self">4</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-5" href="#footnote-5" target="_self">5</a><a class="footnote-anchor" data-component-name="FootnoteAnchorToDOM" id="footnote-anchor-6" href="#footnote-6" target="_self">6</a></p><div id="datawrapper-iframe" class="datawrapper-wrap outer" data-attrs="{&quot;url&quot;:&quot;https://datawrapper.dwcdn.net/kAo3E/1/&quot;,&quot;thumbnail_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f7e1b101-0e1b-4f7f-ac7b-fc59308742eb_1220x504.png&quot;,&quot;thumbnail_url_full&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b43083a8-9fba-435d-be05-764bcd26b63e_1220x504.png&quot;,&quot;height&quot;:226,&quot;title&quot;:&quot;Cost to Correct&quot;,&quot;description&quot;:&quot;&quot;}" data-component-name="DatawrapperToDOM"><iframe id="iframe-datawrapper" class="datawrapper-iframe" src="https://datawrapper.dwcdn.net/kAo3E/1/" width="730" height="226" frameborder="0" scrolling="no"></iframe><script type="text/javascript">!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();</script></div><p>But there&#8217;s good news. We know how to prevent failures: By applying software quality assurance policies and practices &#8212; and pairing them with rigorous software testing.</p><h1>Applying best practices</h1><p>Test Driven Development (TDD) and Behavior Driven Development (BDD) are fundamental strategies to move defect detection left on the graph &#8212; ideally all the way to the design phase where cost is lowest.</p><p>Both practices create proofs that prevent defects. What&#8217;s more, they rely on executable specifications that <em>prevent regression</em>. Even after initial development, the test suite continues to catch defects early. A change that inadvertently breaks existing behavior is caught in seconds during the next test run &#8212; not discovered in production by users.</p><p>This ongoing protection is particularly valuable as systems age and original developers move on &#8212; the tests preserve institutional knowledge about intended behavior. Imagine how powerful it would have been if the Ariane 4 SRI module had included a continuously run regression test sequence.</p><p>The fundamental promise isn&#8217;t about testing &#8212; it&#8217;s about creating better designs. Both practices demand writing tests first. That forces thinking about how code will be used <em>before</em> thinking about how it will be built. This outside-in pressure tends to produce interfaces that are cleaner, more focused, and easier to consume, as well as code that is more reliable.</p><h2>The deeper point</h2><p>TDD and BDD aren&#8217;t really about testing at all. They&#8217;re about feedback loops and thinking clearly about intent before implementation. The tests are a byproduct &#8212; valuable, but secondary to the discipline of thoroughly articulating what you want <em>before</em> you build it.</p><p>Critics often attack the testing artifacts while missing this point entirely. It&#8217;s not always about going faster or whether every scenario needs to be test-driven. It&#8217;s whether your development process includes mechanisms that force clarity of thought and protect against regression. Both TDD and BDD are proven ways to achieve that.</p><div class="pullquote"><p>I&#8217;d really, truly appreciate it if you could refer a friend. Writing takes a lot of time and effort. Your referrals make it worthwhile. And this button earns you free access!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p></div><h2>TDD or BDD?</h2><p>TDD catches implementation errors immediately. When you write a failing test before writing code, you discover mismatches between intent and implementation within minutes, not days or weeks.</p><p>The feedback loop is so tight that &#8220;debugging&#8221; often becomes unnecessary. When a test fails you know exactly what change caused it.</p><p>Compare this to traditional development where bugs lurk undetected until integration, verification or even user experience &#8212; by which point the original context has faded. Investigation becomes archaeological, time consuming and costly.</p><p>What TDD does well is clarify the boundaries of your system. Code that&#8217;s hard to test is often code with unclear responsibilities or excessive coupling. Even if you don&#8217;t achieve full coverage, attempting TDD reveals where your architecture needs attention.</p><p>But TDD has a limitation: it doesn&#8217;t &#8220;shift left&#8221; <em>enough</em> on our error discovery graph.</p><p>TDD is largely a <em>technical</em> exercise, focused on functional specification. As such it can get deep into the weeds of a feature &#8212; but may fail to rise to the level of <em>product behavior</em>. In other words, we might be applying our test-driven thinking to a conceptual design that is <em>already defective</em>.</p><p>That&#8217;s why I prefer BDD.</p><h1>Behavior Driven Development</h1><p>Behavior Driven Development is a collaborative approach that evolved from Test Driven Development. It bridges the gap between technical and business team members by expressing specifications as concrete examples, written in plain language everyone can understand (the &#8220;Given-When-Then&#8221; style, or Gherkin format).</p>
      <p>
          <a href="https://blog.bosslogic.com/p/delivering-customer-value-with-bdd">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Transform your standups and retros: intention matters more than status updates]]></title><description><![CDATA[Do you try to skip your standup? Or feel like retros are a waste of time? Then your team isn&#8217;t doing it right. Here's my formula for giving your team agency and getting real value from both.]]></description><link>https://blog.bosslogic.com/p/the-secret-to-effective-standups-and-retros</link><guid isPermaLink="false">https://blog.bosslogic.com/p/the-secret-to-effective-standups-and-retros</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Wed, 14 Jan 2026 17:33:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!3JD0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3JD0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3JD0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3JD0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3JD0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3JD0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3JD0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg" width="1456" height="917" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:917,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:441088,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/184429434?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3JD0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg 424w, https://substackcdn.com/image/fetch/$s_!3JD0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg 848w, https://substackcdn.com/image/fetch/$s_!3JD0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!3JD0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F175db0be-1ad9-4c79-ae6c-584e19f4313c_2781x1752.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A daily standup is a great idea &#8212; <em>provided it&#8217;s done right.</em></p><p>A well-run standup:</p><ol><li><p>Is a place to foster collaboration and mindshare.</p></li><li><p>Provides a forum to get help.</p></li><li><p>Makes sure the team doesn&#8217;t spiral.</p></li></ol><p>Unfortunately, most standups that I join don&#8217;t do any of these things. Quite the opposite. These standups impede productive work, acting as a needless interruption that offers almost no value.</p><p>More often than not what I see is a team forced to stand together while each team member robotically itemizes their work since the last sprint. In some miserable cases, the &#8220;PM&#8221; and one or two team members hold the entire team hostage while a specific problem is diagnosed.</p><p>The standup stretches to 30 or 40 minutes. Your eight person team takes a cumulative <em>five hour hit</em> to their productivity.</p><h2>Create value in your standups</h2><p>If you Google &#8220;questions to ask at a standup&#8221; you&#8217;ll find the worst culprit sitting right at the top of the list: &#8220;what did you do since yesterday?&#8221;</p><p><em>Ban this question.</em></p><p>Almost just as bad is, &#8220;wha&#8230;</p>
      <p>
          <a href="https://blog.bosslogic.com/p/the-secret-to-effective-standups-and-retros">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Part 3: Refining our data pipeline architecture to solve a few hidden challenges]]></title><description><![CDATA[Ensuring scalability, reliability and responsiveness pose interesting problems in distributed architecture. Here&#8217;s how to build a forward-looking foundation.]]></description><link>https://blog.bosslogic.com/p/part-3-solving-hidden-pipeline-architecture-challenges</link><guid isPermaLink="false">https://blog.bosslogic.com/p/part-3-solving-hidden-pipeline-architecture-challenges</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Thu, 08 Jan 2026 18:09:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!_eQy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_eQy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_eQy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!_eQy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!_eQy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!_eQy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_eQy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg" width="1200" height="800" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:800,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:303905,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/183379913?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_eQy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg 424w, https://substackcdn.com/image/fetch/$s_!_eQy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg 848w, https://substackcdn.com/image/fetch/$s_!_eQy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!_eQy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9bfb7c25-5f38-4a4d-9e91-77861669350e_1200x800.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><a href="https://www.rawpixel.com/image/11991758">Image</a> by <a href="https://www.rawpixel.com/">rawpixel.com</a></figcaption></figure></div><div class="pullquote"><p>In this third article on data pipelines, we&#8217;ll firm up our architecture before coding. We&#8217;ll make sure all of our requirements have been adequately addressed (there are still a few missing pieces). We&#8217;ll also review our design to make sure all goals have been met. The finished architecture needs to provide a responsive, scalable and reliable foundation.</p></div><p>In the <a href="https://blog.bosslogic.com/p/part-2-a-practical-data-pipeline-architecture">previous article</a> I introduced a foundational architecture for our <em>data pipeline</em>, checking off several of our requirements. Here&#8217;s a quick recap:</p><ol><li><p>We leveraged an internal cache for <em>isolation</em> to break our dependency on external data sources, improving our resiliency and scalability options.</p></li><li><p>We introduced the idea of an <em>asynchronous</em> message architecture, so we aren&#8217;t bound by lengthy, sequential processes.</p></li><li><p>We keep our annotations long-term with <em>internal persistence</em> so we don&#8217;t reprocess data when unnecessarily.</p></li><li><p>Source data as treated as an <em>immutable source,</em> thus protecting our data integrity.</p></li><li><p>Our visualization layer is responsive, running off our internal cache so that it&#8217;s independent from other components.</p></li></ol><p>Here&#8217;s a sketch of the architecture as it stands now:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_gty!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03197c57-3741-4942-b657-e86624ade27a_988x326.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_gty!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03197c57-3741-4942-b657-e86624ade27a_988x326.png 424w, https://substackcdn.com/image/fetch/$s_!_gty!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03197c57-3741-4942-b657-e86624ade27a_988x326.png 848w, https://substackcdn.com/image/fetch/$s_!_gty!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03197c57-3741-4942-b657-e86624ade27a_988x326.png 1272w, https://substackcdn.com/image/fetch/$s_!_gty!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03197c57-3741-4942-b657-e86624ade27a_988x326.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_gty!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03197c57-3741-4942-b657-e86624ade27a_988x326.png" width="988" height="326" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/03197c57-3741-4942-b657-e86624ade27a_988x326.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:326,&quot;width&quot;:988,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:50364,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/183379913?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03197c57-3741-4942-b657-e86624ade27a_988x326.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_gty!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03197c57-3741-4942-b657-e86624ade27a_988x326.png 424w, https://substackcdn.com/image/fetch/$s_!_gty!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03197c57-3741-4942-b657-e86624ade27a_988x326.png 848w, https://substackcdn.com/image/fetch/$s_!_gty!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03197c57-3741-4942-b657-e86624ade27a_988x326.png 1272w, https://substackcdn.com/image/fetch/$s_!_gty!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03197c57-3741-4942-b657-e86624ade27a_988x326.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It&#8217;s a good start, but we aren&#8217;t finished.</p><p>There are still two requirements that don&#8217;t have a clear solution:</p><ol><li><p>We want to be able to reprocess data, effectively &#8220;rewinding history&#8221; and applying new analytics. For instance, if we add a new analysis and insight to our pipeline, how are we going to go back and view that new analysis on old data?</p></li><li><p>Finally, we want to be able to model our insights &#8212; that is, visualize it in a presentation layer. But we haven&#8217;t talked about <em>how</em> that&#8217;s going to happen.</p></li></ol><p>Once we tackle those last few requirements, we&#8217;ll fill in some details &#8212; such as, deciding on a cache technology to use. We&#8217;ll also take an end-to-end look at what we&#8217;ve designed to see if we missed something important. </p><div class="pullquote"><p>If you&#8217;re new, welcome to Customer Obsessed Engineering! Every week I publish a new article, direct to your mailbox if you&#8217;re a subscriber. As a free subscriber you can read about half of every article, plus all of my free articles.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/subscribe?"><span>Subscribe now</span></a></p><p>Anytime you&#8217;d like to read more, you can upgrade to a paid subscription.</p></div><h1>Finishing our foundation</h1><p>One of the most powerful and underused capabilities in data analytics is the ability to reprocess historical data with new logic. When you fix a bug in your analysis or refine a calculation, you often want to know: &#8220;what would the last three months have looked like with this new logic?&#8221;</p><p>Fortunately, our design thus far aligns pretty well with this goal.</p><p>Essentially, all we are saying we need to do is throw out information that is no longer accurate and then reprocess the source data and rebuild a new and improved picture of the world. We might do this for a couple of reasons:</p><ol><li><p>We changed our analytics. Consequently, we need to throw out all of our old findings and recalculate our insights.</p></li><li><p>The source data changed. Perhaps there was a historical data update, invalidating our findings. Again, we want to throw out our findings and reprocess.</p></li></ol><p>Looking at the problem from that perspective, the architectural answer is simple: we need a way to delete our annotations.</p><p>Once we wipe our annotations, we&#8217;ll need to make sure they are recalculated. There are different strategies we could use, but for the most part our options are:</p><ol><li><p>Rebuild our annotations on-demand. This is fine if we&#8217;re OK with a bit of a delay while we wait for analytics to run. Depending on our visualization strategy we might be able to break the work up and trade one big delay for a few small delays.</p></li><li><p>Alternatively, rebuild our annotations preemptively. We might do it as soon as we realize there&#8217;s data to analyze, or perhaps we have some kind of schedule or external trigger. The point here is, we run the analysis <em>before</em> we think a user will want to visualize it.</p></li></ol><p>We&#8217;ll add these capabilities to our architecture diagram. That means responding to both <em>external</em> data changes as well as <em>internally</em> sourced changes.</p><h2>Rewinding history</h2><p>To &#8220;rewind and reprocess,&#8221; we&#8217;ll just delete our annotations and then make sure there&#8217;s a mechanism to rebuild them. Here&#8217;s an example chain of events we&#8217;ll model in our architecture:</p><ol><li><p><em>Administrative user</em> invalidates some (or all) of the annotations we&#8217;ve stored in our cache:</p><ol><li><p>Optionally, if the data was invalidated because source data changed, the system loads fresh data from the external data source.</p></li><li><p>The system deletes or otherwise invalidates the annotations in our cache.</p></li><li><p>An event such as &#8220;analysis invalidated&#8221; (with some metadata, perhaps a date range) is emitted.</p></li></ol></li><li><p>The <em>analytics service</em> is listening for events, and receives the &#8220;analysis invalidated&#8221; event:</p><ol><li><p>The event includes the date range of deleted data. The service checks the date range to see if annotations are missing from the cache.</p></li><li><p>If the data is still missing, it runs the analysis and rebuilds the missing annotations.</p></li><li><p>As annotations are rebuilt, they are written to the cache.</p></li><li><p>An event such as &#8220;analysis completed&#8221; (with some metadata) is emitted.</p></li></ol></li><li><p>Separately, a <em>visualization</em> service might be running where a user asks to display the visualization for some missing data:</p><ol><li><p>The system checks the cache, realizes annotations are still missing, and sends a &#8220;run analysis&#8221; message directly to the <em>analytics service</em>.</p><ol><li><p>The <em>analytics service</em> is already working on analyzing the data so it can ignore the message, or respond with an &#8220;analytics in process&#8221; message.</p></li></ol></li><li><p>The visualization presents some kind of &#8220;waiting for analysis&#8221; display while it listens for the &#8220;analysis completed&#8221; message. When it receives the message, it loads the annotations and displays them.</p></li></ol></li></ol><p>This is one way to handle a specific chain of events. We&#8217;ll need to handle other events and commands as well &#8212; such as an event to tell us external data has changed.</p><p>Since we&#8217;re talking about <em>responding to events that happen</em>, it makes sense to use <a href="https://blog.bosslogic.com/p/34-tactical-event-storming">event storming</a> to model those events and commands. We can model &#8220;things that have happened&#8221; (the events) as yellow cards, and &#8220;what we want to happen&#8221; (the commands) as blue cards.</p><p>If you need a refresher, <a href="https://blog.bosslogic.com/p/23-strategic-event-storming">Chapter 2.3 Strategic event storming</a> and <a href="https://blog.bosslogic.com/p/34-tactical-event-storming">Chapter 3.4 Tactical event storming</a> provide in-depth explanations on modeling event driven architectures.</p><p>Here&#8217;s an updated architectural drawing showing how our events and commands interact with the system:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LpRE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98606045-feed-451c-a057-0cb9d769266d_1291x659.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LpRE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98606045-feed-451c-a057-0cb9d769266d_1291x659.png 424w, https://substackcdn.com/image/fetch/$s_!LpRE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98606045-feed-451c-a057-0cb9d769266d_1291x659.png 848w, https://substackcdn.com/image/fetch/$s_!LpRE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98606045-feed-451c-a057-0cb9d769266d_1291x659.png 1272w, https://substackcdn.com/image/fetch/$s_!LpRE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98606045-feed-451c-a057-0cb9d769266d_1291x659.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LpRE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98606045-feed-451c-a057-0cb9d769266d_1291x659.png" width="1291" height="659" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98606045-feed-451c-a057-0cb9d769266d_1291x659.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:659,&quot;width&quot;:1291,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:126204,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/183379913?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98606045-feed-451c-a057-0cb9d769266d_1291x659.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LpRE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98606045-feed-451c-a057-0cb9d769266d_1291x659.png 424w, https://substackcdn.com/image/fetch/$s_!LpRE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98606045-feed-451c-a057-0cb9d769266d_1291x659.png 848w, https://substackcdn.com/image/fetch/$s_!LpRE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98606045-feed-451c-a057-0cb9d769266d_1291x659.png 1272w, https://substackcdn.com/image/fetch/$s_!LpRE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98606045-feed-451c-a057-0cb9d769266d_1291x659.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Using event storming to model behaviors that occur in our architecture.</figcaption></figure></div><div class="pullquote"><p><em>Can I ask a favor? Do you know someone that would like this article? Please send it to them. Referrals keep this publication alive and growing. (And you&#8217;ll earn free access, too).</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p></div><h2>Persistent annotation cache</h2><p>One of the things we haven&#8217;t decided yet is exactly <em>how</em> we&#8217;ll store our annotation data. There are quite a few options, and certainly more than one strategy that will work well.</p><p>In <a href="https://blog.bosslogic.com/p/part-2-a-practical-data-pipeline-architecture">part two</a> I hinted at using a relational database to store a copy of the external source data. This makes a lot of sense, but it isn&#8217;t the only option.</p><p>We could store all of our data in a persistent data store such as <a href="https://www.mongodb.com/">MongoDB</a>, a noSQL document-oriented database. Document databases offer some fantastic search capabilities and, perhaps most interesting, don&#8217;t force us into a predefined schema &#8212; we can, essentially, attach <em>anything</em> as our annotations.</p><p>That&#8217;s a nifty idea, because we want flexibility to change our data analysis and come up with new data sets to store, freely associating them with source data.</p><p>We could also stick with a purely event-driven architecture. In this kind of system, we would emit annotations as events into a persistent queue (such as <a href="https://kafka.apache.org/">Kafka</a>). The persistent queue becomes our source of truth &#8212; and annotations are just messages on the queue, like, &#8220;sprint X: total out-of-sprint hours: 500.&#8221;</p><p>With many options, it&#8217;s probably a good idea to decide on our business requirements:</p><ol><li><p>Obviously, we want to cache the original source data, so we aren&#8217;t tightly coupled to an external system. (We know the external system is a relational database).</p></li><li><p>We want to easily create new annotation data sets. If we dream up a new calculation (maybe, &#8220;number of activities completed after hours on Fridays&#8221;), we want to be able to store it easily.</p></li><li><p>We know we&#8217;re using DataFrames for analysis. Storing our DataFrames without translating them into something else would be convenient (but not necessary).</p></li><li><p>Our annotation data should be persistent (to avoid unnecessary delays rerunning an analysis) &#8212; but, once a particular report or visualization is no longer being used, we probably don&#8217;t need to keep it around.</p></li><li><p>Finally, we&#8217;ll want to think about performance and wait times. We definitely don&#8217;t want users to experience a slow system.</p></li></ol><p>The relational cache for source data still makes a lot of sense.</p><p>For our internal annotation data, something more flexible is desirable. We don&#8217;t want to be constrained by a relational schema, forced to update the schema every time we think up a new report or annotation.</p><p>While a noSQL solution seems like a good fit, it may be an unnecessary complication. It would afford long-term persistence, but unless we run into performance problems that long-term persistence may be pointless.</p><p>Designing for flexibility makes sense.</p><p>We&#8217;ll implement our internal annotation cache as a service. The service will:</p><ol><li><p>Allow us to store annotations (data structures) in a persistent fashion (but, not necessarily permanently).</p></li><li><p>Provide a shared data service (allowing other services to leverage the shared data).</p></li><li><p>Give us scalability (we can boost processing power or memory, start up multiple copies, or upgrade to a more powerful data store technology).</p></li><li><p>Allow us to start simple, just storing annotation data in memory. A long-running service might give us all we need (after all, we&#8217;d only rebuild our annotations if we restart the server).</p></li></ol><p>Let&#8217;s update our architecture diagram one more time:</p>
      <p>
          <a href="https://blog.bosslogic.com/p/part-3-solving-hidden-pipeline-architecture-challenges">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[3.5 Modeling]]></title><description><![CDATA[Engineering models eliminate mistakes & complexity, ensure better testing & reliability, and improve collaboration & understanding.]]></description><link>https://blog.bosslogic.com/p/35-modeling</link><guid isPermaLink="false">https://blog.bosslogic.com/p/35-modeling</guid><dc:creator><![CDATA[Zac Beckman]]></dc:creator><pubDate>Mon, 29 Dec 2025 21:18:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!BQC2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BQC2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BQC2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg 424w, https://substackcdn.com/image/fetch/$s_!BQC2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg 848w, https://substackcdn.com/image/fetch/$s_!BQC2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!BQC2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BQC2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg" width="1456" height="926" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:926,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:992020,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.bosslogic.com/i/182565880?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!BQC2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg 424w, https://substackcdn.com/image/fetch/$s_!BQC2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg 848w, https://substackcdn.com/image/fetch/$s_!BQC2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!BQC2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb538905-5d89-4cc4-b560-6a2ca5f81aad_2759x1755.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Photo by <a href="https://unsplash.com/@nypl?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">The New York Public Library</a> on <a href="https://unsplash.com/photos/68NORlOLXUc?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash">Unsplash</a></figcaption></figure></div><div class="pullquote"><p>Your modeling style is a complex topic. Accordingly, I recommend you read these two companion articles before diving in: <a href="https://blog.bosslogic.com/p/technical-drawings-that-work">Applying marble &amp; sequence diagrams</a> and <a href="https://blog.bosslogic.com/p/why-being-declarative-is-your-competitive-advantage">Using &#8220;declarative thinking&#8221; to establish stronger controls</a>.</p></div><h2>Introduction</h2><p>This activity creates fidelity in our <em>engineering models</em> &#8212; the diagrams and specifications that give us enough technical depth so we can proceed to coding.</p><p>Everything we&#8217;re going to build should be modeled. That might sound like of lot of work, but with the right drawings and specification style, it&#8217;s not &#8212; plus, our models should be <em>reusable.</em> For instance, once I&#8217;ve modeled my implementation of a circuit breaker, I don&#8217;t have to model it again. I can just use that circuit breaker design everywhere I need it.</p><p>The approach I&#8217;ll introduce here increases the fidelity of your technical designs using data inputs and outputs, paired with very clear and specific functional results. It builds on your existing engineering artifacts and further validates your value stream, making sure alignment with business objectives is maintained. We capture our control processes and at the same time enhance communication among those designing the solution.</p><div class="pullquote"><p><em>Hey, can I ask a favor? Writing good material is an investment &#8212; and referrals keep this publication alive. Please take a moment to send this article to a friend.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.bosslogic.com/leaderboard?&amp;utm_source=post&quot;,&quot;text&quot;:&quot;Refer a friend&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.bosslogic.com/leaderboard?&amp;utm_source=post"><span>Refer a friend</span></a></p></div><p>One of the challenges with modeling is deciding on what&#8217;s effective yet not overly constraining or complex. We want to define some clear standards of practice and make sure the engineered product is fit for purpose. At the same time, teams should have the flexibility to take a different path <em>if that different path is more fit for purpose</em>.</p><p>The modeling approach we use in the Delivery Playbook meets those goals:</p><ul><li><p>We define engineering artifacts using two specific diagram types, neither of which are difficult to understand or use.</p></li><li><p>Clear objectives are defined while giving teams enough freedom to follow a different path &#8212; <em>so long as those objectives are met</em> using whatever approach they choose to follow.</p></li></ul>
      <p>
          <a href="https://blog.bosslogic.com/p/35-modeling">
              Read more
          </a>
      </p>
   ]]></content:encoded></item></channel></rss>