You're Probably Solving the Wrong Problem

Bryan Finster's profile picture
Bryan Finster
Engineer

Information supply chain

"If you don't know where you are going, you'll end up someplace else."

– Yogi Berra

So much effort is wasted in the software industry on "agile transformation" initiatives and arguments about frameworks and methodologies. The reason is pretty mundane: people have created an industry providing stock answers to people who don't know what questions to ask. The problem is that most of the answers are useless or even damaging because they are based on "I learned this in my certification class" or "This solution worked once in an entirely different context."

Even the good answers can appear suspect if the question isn't understood. If I tell you the answer is 42, but you don't know the question…

We need to ask the right questions to filter the useful answers from those based on faith and dogma. Step one is understanding the problem we need to solve.

Supply Chain 101

I worked on supply chain software for the first two decades of my career. The main job of a supply chain system is to manage inventory and optimize how that inventory flows through the supply chain. Inventory is never a good thing because you're spending money to handle and store aging products. As it ages, it becomes less valuable. It will also likely require more handling. Anytime we handle inventory, we incur additional costs and risk damaging the product.

To optimize our supply chain, we want to balance intake and demand as closely as possible to minimize inventory. We also want to minimize touchpoints between creation and delivery. An example of this is Just In Time (JIT) manufacturing, where components arrive at the factory as close to when they will be used as possible. To make that possible requires removing friction and uncertainty from the process of creating and delivering those components.

When building software, we work within an information supply chain. Our inventory is proposed work and undelivered code change. All of the above concepts apply.

Understand The Supply Chain

The first step in optimizing our supply chain is understanding software development. I know that sounds basic, but it's amazing how many people think software development is just coding and shipping features. This creates dysfunction that harms outcomes.

Fundamentally, software development is about identifying a need and creating new capabilities to fulfill that need. Developing new capabilities always means overcoming uncertainty. A common mistake is believing that we can remove uncertainty if we spend enough time defining all the work to be done. However, when we do this, we are growing an inventory of unknowns.

  • Will this capability fit the need?
  • Have we identified the need correctly?

The more we work to perfect our plan, the more uncertainty we create. This is the perfect way to spend money and effort without generating value.

The alternative? We need to minimize the amount of detailed planning we do before getting feedback. Yes, we need a plan, but we must understand that the plan will probably change. We need to ship something small that can give us information about our plan, measure the impact, and adjust our plan instead of polishing it until we believe it's perfect. It isn't.

We also want to keep our inventory of undelivered code changes low. Not only do they represent delayed feedback on our ability to fulfill the need, but they also represent unidentified defects. Optimizing our quality processes to eliminate handoffs and reduce processing time is critical to improving outcomes because it allows us to lower inventory levels.

fig1

How quickly and efficiently we can close this loop directly impacts the investment in time and resources required to solve the problem and, ultimately, the delivered value. We can improve our ability to do this using the same principles we would use for physical supply chains.

Minimize touch points

With physical inventory, every time a human touches it, there is cost and risk of damage. The same applies to software.

Having a backlog of work means we must keep reviewing the backlog for accuracy, duplication, and relevance as time goes on. The larger the backlog, the more effort this requires. How many times have you seen long backlogs of refined stories? Simply by existing, they add cost to our process. Also, I've never seen a backlog where every story resulted in a code change.

Once we begin executing against the backlog, we need to execute in a way that minimizes human touches after coding.

In a previous role, I helped teams learn continuous delivery. Step one was to map their current process. Here's a real-life example of a bad software supply chain.

Value stream map

Because of the functional silos and lack of teamwork between the product owner, developers, and QA, there is information degradation happening at every step in the process with long wait times and extensive rework. Note that the QA team's test suite found issues 60% of the time, but only 25% were due to coding errors. The remaining were due to test data setup issues or the testing team misunderstanding the requirements. However, a failure triage meeting between the development and test team leads was required to determine why the test failed. If they disagreed on who had the correct requirements, they had to schedule a meeting with the product owner. It commonly required two days of waiting to get that meeting.

To fix this, we reduce the touch points.

  • Bring the PO, developers, and QA together to define the acceptance tests before coding begins. This ensures everyone has a shared understanding of exactly how the feature should function.
  • Eliminate the independent testing team so that all required tests are implemented during development to eliminate the wait for testing.
  • Eliminate the manual testing. Developers implement test automation during development and automate all validations required to certify that an artifact can be delivered to remove variability from testing and delivering.
  • Eliminate the duplicate code review. Implement continuous integration so that very small changes are reviewed and integrated several times per day. The review should either be done synchronously or while coding with paired programming.

We move all human activity to the front of the process, remove the handoffs, and automate everything downstream of development.

Quality control

Remember that we are doing product development, not manufacturing. We can only pre-determine the quality of things we have already delivered. For everything else, we focus on rapid feedback.

First, we ensure that all known quality issues have automation in place to ensure we do not cause regression by breaking working capabilities. We need this automation to be very fast. Then, we optimize for fast feedback from as close to the end-user as possible by streamlining our development processes to remove handoffs and wait times.

In the example above, it took the team 1.5 days of actual activity to deliver a change after the feature was refined. However, it also required more than 17 days of waiting for handoffs. Therefore, getting feedback on new features took more than three weeks. By implementing only the suggested improvements, the team could remove nearly 50% of the time required to deliver on the happy path. However, the actual improvement is more than that because the improved communication would also reduce/remove the rework loops that double or triple some of the wait times.

The impact of this is faster feedback with less effort and risk.

Efficient Inventory Management

Do you know where your inventory is? Every place in the value stream where people wait for another process to begin is collecting inventory. The longer the wait, the larger the amount that collects and the higher the risk that it's not valuable when delivered. Unlike physical goods, we cannot liquidate our inventory and partially recoup expenses. We either deliver it and see whether it's valuable or not or let it age in our warehouse until it's unlikely to be valuable.

A frequently seen pattern is a team working on a long feature branch and then warehousing that code until another team is ready to integrate. Then priorities shift, and by the time the team returns to that code, it cannot be delivered because there has been too much drift in the code due to other changes. They also wasted the opportunity to have their feature running quietly and producing performance and stability information. We need to keep our inventory low. SHIP IT!

Responsiveness

In physical supply chains, we design our distribution around meeting the customer's needs. With software, we do the same. We design our development processes to enable us to respond to the unexpected. We practice delivering small changes frequently because it allows us to find and remove friction in our supply chain. This, in turn, allows us to lower the cost of change so we can afford to run experiments. It also enables us to respond to emergencies quickly and confidently or exploit unexpected value from a delivered feature at the speed of relevance.

Continuous improvement

We can measure the efficiency of our software supply chain, and we should. We can measure effectiveness, too, but that's a trailing indicator, and without improving efficiency, we cannot improve effectiveness. By continuously improving efficiency, we increase our ability to innovate, both what we deliver and how we deliver it.

  • Track the total time from when work begins until it's available to be used.
  • Focus on the kata of CI; integrate tested, non-breaking changes to the trunk at least daily.
  • Identify the issues that prevent the ability to deliver the latest change on demand and fix those.

Improving your software supply chain is not about achieving perfection overnight; it's about taking incremental steps to reduce waste, increase efficiency, and deliver value faster. Start by mapping your current processes, identifying the bottlenecks, and focusing on flow over storage. Remember, the sooner your ideas reach your users, the sooner you discover their true value.