The AwkEng and the Shipping Mindset

Hi all,

Probably one of my longer blog posts to date, as this is really a book chapter. This one is about broad principles and mindset I apply while making things. Feedback I'm looking for:

  • Were any points confusing?
  • Have you been in situations where these break down?
  • Do you think anything is missing?
  • Any other broad feedback?

The Shipping Mindset

This chapter is about the "shipping" mindset, and a set of principles and mental models that I use to chart the course through large, complicated projects.

In many ways, this mindset is an extension, or reinterpretation of the Agile Manifesto. Agile isn't a new idea any more (as of this writing, it's over 25 years old) and over the years, as it's grown more widespread, there's been confusion over specific practices, like Scrum or Kanban, and the original Agile values and principles. In this chapter, I'll focus on broad principles, and not on how to run a sprint planning meeting.

The most misunderstood portion of the Manifesto.

The Manifesto lists as a value "Working software over comprehensive documentation" and as a principles "Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale." and "Working software is the primary measure of progress."

This is at the absolute core of the shipping mindset, and yet it breaks down completely for hardware. The physical world requires fabrication, shipping, and assembly. Working hardware in a "couple of weeks" is often infeasible.

Similarly, for large, complicated software projects, shipping "working software" in weeks when you have large, cross enterprise integrations and dependencies can also be impossible.

The shipping mindset is a reinterpretation and clarification of what "working software" means, in a way that it can be applied to both hardware and software products. It's a relentless focus on making progress, solving the right problems, in the right order, while keeping an eye to the view of the whole system. It leads to successful delivery, on teams with high morale, where it feels like the team is making continuous progress, because it is.

The three principles of the shipping mindset are:

  1. Do the smallest thing to show indisputable progress.
  2. Do the uphill problems before the downhill problems.
  3. Build the whole journey.

Do the smallest thing to show indisputable progress.

If you're building a complicated electromechanical system, it's simply unlikely that you'll have a fully working, commercially scalable product faster than 9 months. I'm sure there are exceptions, and there are many projects that run on 18 month cycles and longer, but suffice it to say, there won't be an equivalent to "working software" that can be sold in exchange for money for a lengthy period of time.

Which brings me to the first principle.

Do the smallest thing to show indisputable progress.

Indisputable progress means two things to me. First, there's the term "indisputable." For something to be indisputable, there will be some sort of tangible artifact to point to. That doesn't necessarily mean a physical object. (Although it is satisfying, and also inarguable, when you're holding parts in hand.) It can mean a demonstration, a test report, a measurement, a document, an analysis, etc. In the formal and documentation heavy worlds of spaceflight and medical device, evidence of these articles would be entered into a formal record. In less formal environments, simple "show and tell" will do. But you're still looking for proof, i.e. system power up, demonstration of end to end messaging, or a simple measurement.

One of my mentors had a way of expressing this, that I often come back to, that "there is no 70% done." He'd go on to point out that "It's done or it's not. The goal was to land a man on the moon and return him safely to Earth. Not to go 70% of the way there."

The second thing that "indisputable progress" means is that you're not just doing work for work's sake. The work has to move you forward. This is where the three principles work together. Because all work isn't created equally, and the order you do it matters. Progress means you're working on the uphill problems before the downhill problems and building the whole journey. More on these in a moment, in the next section, and after an example.

This example comes from a product manager at Stripe, talking about development of their Atlas product. Atlas is used for incorporating businesses, and one of its important features is that it files a particular regulatory document (called an 83b Election) on your behalf. At that time, the document had to be filed via paper mail. If the document wasn't filed within 30 days, it created enormous tax consequences.

In developing this product, the ability to programmatically send a message to a vendor, then have the vendor place a letter in the mail and track its delivery was a milestone. In this example, the letter didn't contain any significant content, it wasn't a real regulatory filing, it was only delivered to Stripe's office. But the ability to press a button on a laptop and then have a letter arrive in the mail the next day was indisputable proof that they could connect their computer systems to snail mail in the physical world.

There wasn't "working software" in the sense that they could sell a thing to a customer for money, but it showed that programmatic communication with an outside vendor was working.

Do the Uphill Problems before the Downhill Problems

This brings us to our next principle.

Do the uphill problems before the downhill problems

Successful practitioners of the shipping mindset have an instinct for distinguishing between what I will call "uphill problems" and "downhill problems." Uphill problems are things that you've never done before, things that you don't know if they're possible, and things that are out of your complete control, like dependencies or integrations with other teams. Downhill problems, in contrast, are simply a matter of time and effort, and give you the opportunity to control your own destiny.

You do the uphill problems first to drive out risk, and because often, the solution to the uphill problem will dictate architecture, or change the nature of the downhill problems.

Uphill problems also tend to cluster around the things you need to get "right," or the core features of a product. In my experience, the downhill problems are where there's room to cut scope or change the feature set. The uphill problems tend to be non-negotiable. Solving the uphill problems first typically enables greater flexibility later on.

Enabling flexibility gives you true agility, not just the Agile value of "embracing change over following a plan." I emphasize the value of flexibility, because no matter how "fixed scope" you may think your project is, change is inevitable. That's because scope can be ambiguous, it can be misinterpreted, or it can be outright incorrect. And even if the scope is clear, correct, and understood, it can still be changed anyway.

With the shipping mindset, order matters.

In the physical letter example, connecting to a physical vendor and mailing a letter on a tight timeline was the uphill problem, because it was an unknown. Stripe had never done it before. After that, creating customer accounts, creating the content of the pdf that would go in the letter... that was all within their control and it was all work that was well within their wheelhouse. Those were downhill problems.

The most technical way I've ever heard of thinking about this is that there are many risks that can kill a product or a project. Driving out those risks requires work, but some things are riskier and more likely to kill you, and some risks take less work to manage or mitigate. Similar to the Weighted Shortest Job First scheduling algorithm, which prioritizes by value relative to effort, an "effort-adjusted riskiest thing first" approach is optimal. Do the simplest thing that could kill the project first.

Build the Whole Journey

OK. So to recap, you're making indisputable progress, you're making progress on the uphill problems, but now we need to step back and look at the big picture. Which brings us to the next principle.

Build the whole journey.

What I mean is this: get one end-to-end path working as early as you can, at whatever fidelity you can. Don't wait to integrate everything at the end. The faster you have a path through the whole thing, even if it's manual, or hard-coded, the better. Building the whole thing is what drives out unknown unknowns. And driving out unknown unknowns is itself an uphill problem. The principles reinforce each other.

What counts as "the whole thing" depends on what you're building. For a project, the path is usually through the technical system: a physical build, or signal in/signal out, or data flowing from one end to the other. (I'll touch more on integration risk and iterative system development in later chapters.)

For a product, the path can be that technical flow, but it can also mean the full customer experience: learning about the product, deciding to buy it, getting started, using it, finishing with it. A product isn't just what's in the box, or in the app; it's the entire journey.

Here are several examples of what a working "whole journey" can mean:

  • Hardcoded messages and function calls passing through an entire system
  • "Wizard of Oz" demonstrations with a person behind the curtain, pulling the levers
  • "Works like" and "Looks like" models. In hardware, the "works like" model decouples technical problems from the "looks like" human factors problems, and each one delivers enough of a whole journey to drive out unknown unknowns.

In the physical letter example, sending a letter was one kind of whole journey: the integration path from their systems to the physical world. That's not the only path that matters for Stripe. The full, scalable product would eventually involve marketing, landing pages, signup, account management, paperwork filing, tracking, billing, payment; the full customer experience from "hear about it" to "incorporated."

But in the early stages, you can build that full path cheaply and manually. The marketing campaign doesn't have to be a nationwide thing. Posting in a forum or calling friends counts. A Google Form instead of a landing page counts. Collecting payment via Venmo counts. Sending thank you emails by hand counts. Getting even one customer through the whole journey of actually incorporating through Stripe, however manual, is indisputable proof that the whole system can work. Improving and automating it then becomes running downhill.

The above isn't necessarily the path Stripe followed. But depending on your specific uphill problems, you can choose to tackle parts of the journey in sequence. You can tackle technical integration first, or one slice of the full experience, but you always need to keep the whole journey in view and get through it. Until you have indisputable proof, you still don't know what you don't know.

Differences Between Hardware and Software

I follow these principles and apply this mindset for both hardware and software. I even apply similar high level planning techniques for both (see this blog post.) Operationally, software teams tend to split up work into 1 or 2 weeks sprints, which doesn't necessarily fit hardware timelines, but I'll still adapt a regular meeting / status cadence for hardware work. In other words, if the smallest thing to show indisputable hardware progress is 3 weeks away, that's fine, and I'm still pushing for it.

The key difference between hardware and software is really around launch. With software, it's easy to continue to add features. With hardware, it becomes prohibitively expensive to add features after the prototyping stage and the feature set gets locked down. But I still apply the same principles to both types of development. The mindset remains the same.

Cheering the Wins

While not necessarily a principle, I did want to conclude by saying how important it is to cheer the wins. For many people and many teams, Agile has been so misunderstood, that they've never been asked to build anything this way.

Cheering the wins is a way to reinforce positive behaviors and teach the team the right ways to think about building.

It also forms a virtuous cycle. Making progress gives a sense of satisfaction and is a leading indicator to team happiness and job satisfaction. A team with high morale will then be more engaged to make more progress.

Cheering indisputable progress means you're also not cheering for arbitrary reasons, you're cheering for specific, indisputable things, which makes it easy to get excited over little wins, and create a positive environment. I worked on a system once, where we connected a physical PCB with a sensor, over ethernet, to a centralized single board computer, where an ethernet message was sent to yet another PCB, where we controlled a lighting display. Being able to send messages through the whole system and getting the light to blink, even if it wasn't doing anything else useful or important, was HUGE. It showed that at least three systems (more if you count the physical hardware this was all mounted in), were functioning and interoperable. But when I saw it I still pumped my fist in the air, because I knew a major integration risk had been addressed and it'd be downhill running from here.

Final Thoughts: Shipping Mentality As Identity

If there's one last thought to share as part of the shipping mentality, it's that as far as these principles will take you, you will still encounter challenges with whatever you build. If you're working on difficult problems, its inevitable. Committing to an identity as a maker and a builder, and a steadfast refusal to ship vaporware, can be a well of strength to get through the hard parts. Just keep shipping.

thanks for reading!

Sam Feller
aka THE Awkward Engineer


Leave a comment

Please note, comments must be approved before they are published