Asymptote analysis using customer-vendor loop

Another potentially useful source of insights is using the customer-vendor loop for asymptote analysis. If we indeed desire for our loop to compound, we likely need to consider the upper limits of the compounding. Every growth has a limit, and studying the structure of the customer-vendor might help discern it.

Roughly, the idea is as follows: since the customer-vendor loop has four stocks and four flows, we start by reasoning about the limits that are imposed by each. Since compounding loops are sequences, the stock or flow whose limit we will encounter first will point at the asymptote in our growth. More than likely, there will be other factors at play, so treat this exercise more as a homemade compass rather than a precise instrument. Still, even the fact of engaging in such exercise might open up a space for building shared mental model space about limits to growth.

To look at the limits of the four stocks (Customers, Products, Vendors, Interactions), think of them in terms of capacity. Imagine them as containers. What is the size of each container? Why can’t it get larger? What are the factors that stand in the way?

One common mistake I keep making is imagining Customers as “all people”. That’s one massive container, right? Sky’s the limit. However, in reality, the slice of “all people” actually interested in my Products is typically much smaller, and is limited in many distinct ways. If I own an ice cream shop, I am limiting my Customers to those who like or can eat ice cream. I am also limited by access: how many people can see my shop and walk to it? Sometimes — and this tends to happen frequently in software adventures — I only have vague hypotheses about the existence of my Customers, in the “if you build it, they will come” fashion. In such cases, it helps to be conservative about the guesses. Keeping the sky as the limit may lead to unproductive self-delusion.

In software engineering loops, typical Vendors limits are going to orbit around budget, engineering capacity, depth of expertise, and the like. Products will bump into limits like feature richness, accessibility, stability, etc. Interactions will likely face scale as well as various conversion-related limits.

It also helps to recognize that all limits are dynamic. If another vendor opens an ice cream shop up the street from mine, my Customers limit will change accordingly. Limits are as much of a study of future trends as understanding the current situation. If we are to be strategic about our enterprise, we need to do both. This is what the continuously integrated strategy piece was hinting at.

To study the limits of the four flows (Vendors build, Products attract, Customers engage in, Interactions attract), it is helpful to imagine flows as faucets that connect the two stocks. What would it mean to open the faucet all the way up? What is the current setting? Usually, the words “friction” and “performance” enter the software engineering vocabulary when discussing limits of flows.

The “build” flow limits are typically about the effectiveness of tools and processes. Conversations around engagement flow limits will mention bandwidth and latency. Both “attract” flows will circle around incentives, compensation, recognition, and somesuch. 

Sometimes, understanding that there is a limit to the flow can lead to a candid conversation about compounding loop viability and the need to rethink the current hypothesis. I may assume that since I have a great connection to the Internet, all of my Customers will also have it. I may assume that since I have a multi-core machine that is happy to chew on any CPU load I throw at it, all of my Customers have access to the same computing bandwidth. In the long run, both of these might come true. However, my compounding loop is here and now, and making these assumptions might prevent me from seeing the flow limits, leading me to imagine a compounding loop that isn’t there.

Making sense of SWOT with customer-vendor loops

When brainstorming entries for a SWOT analysis, it might be useful to have a bit more structure. Let’s see if we can use the customer-vendor loop for that purpose.

To frame this exercise a bit, I am going to rely on the notion of stocks and flows in the loop. We have four stocks and four flows that connect these stocks. Each stock represents a value that we want the loop to compound, and each flow represents the means by which we could achieve that.

Through this lens, the strengths and weaknesses of an enterprise will be described by the state of the stocks. Similarly, the nature of the flows between these stocks will tell us about threats and opportunities. This gives us a recipe to start filling out a SWOT table. 

For each stock (Vendors, Products, Customers, Interactions), we can ask questions that produce strengths and weaknesses entries. Put very simply, high values are strengths and low values are weaknesses. Just like stocks, strengths and weaknesses are static qualities – these are the things we have or hold.

For each flow (Vendors build, Products attract, Customers engage in, Interactions attract), we ask questions that produce entries for opportunities and threats. Threats attenuate flows and opportunities accelerate them. Flows are dynamic, and so are the threats and opportunities. They increase or decrease the value of stocks over time.

In addition to producing SWOT entries, this exercise can be very useful for getting a better sense of the examined customer-vendor loop. If it produces nonsensical entries, chances are the loop doesn’t actually represent our aspirations. 

For example, one common mistake I kept making was failing to recognize that the notion of value is relative to the other components in the loop. To make this more concrete, let’s imagine that one of our friends (Vendor) made a really cool klaxon sound mobile app (Product) that has tons of Users (Customers) — who doesn’t want a klaxon on their phone?! — and these users mash the titular button multiple times per day (Interactions). We might conclude that the high number of Interactions signifies significant value of the corresponding stock. Unfortunately, this app is free, and so is its key interaction, which means that there’s no value attached to it. Any multiplier of zero is zero. Despite a large number of interactions intuitively seeming like a valuable thing, it is their relative value that matters within the loop.

In such cases, it might be worth looking into motivations and/or considering that maybe we’ve got some parts of the loop wrong. What if the main reason our friend made this app was to showcase their programming skills? In this case, the value of Interactions is primarily in the “shipped an app that has X million active users” line in their resume. Though the Klaxon app customer-vendor loop is unlikely to be compounding, it might get our friend a great next gig.

Such seemingly non-compounding loops are found quite often in the wild. They exist as tools, as flow accelerants or stock accumulators for some other loops. They may appear as useless or incomplete when viewed in isolation. However, when combined with another loop, they suddenly sparkle compounding magic. A large part of strategy is about discerning the combination of incomplete loops that form a thriving, symbiotic relationship. From this perspective, a business is a large collection of incomplete loops striving to form into a single something that generates value. Whether or not they succeed defines the viability of the business.

Zooming back into the local perspective, it might be helpful for a team to recognize when their customer-vendor loop is incomplete and stay conscious of it. Even if they are an effective tool for another loop, incompleteness is still a weakness and a source of potential future threats and opportunities. Loop dependencies are dynamic in nature. They shift and change.

Customer-Vendor Loop

I’ve been sketching a bunch of compounding loops this week, and wondering if I am seeing a pattern. I am calling this figment of my imagination the Customer-Vendor Loop. I am not great at clever names. I briefly named it Maker-Taker loop, but after sleeping on it, decided to go with something more prosaic.

Before the pattern jumped out at me, I was playing with a convention for drawing a compounding loop. This convention insisted that when we document a loop, we draw it as a causal chain that contains the alternating sequence of nouns and verbs. I drew nouns as boxes and verbs as arrows. It’s that far from how we describe causal chains in English. “A confectioner makes ice cream, which attracts customers” follows the convention above quite nicely.  Some of these nouns are people and others are things that people produce. Following this convention, we can now string more causal chains like “customers pay money, which supports the confectioner”. 

Ka-blam! The money that the confectioner collects closes the feedback loop. However, whether or not this loop is compounding is not yet unknown. What would make this loop compound? Well, if the ice cream turns out exceptionally delicious, it attracts more customers, and perhaps the customers would be willing to pay more money, allowing the confectioner to make more ice cream. Every iteration of the loop begins to compound value and the cycle becomes virtuous.

Loops like this are always interesting, because each of their components tends to interact with another. If the ice cream is not that great, there will be fewer customers, attracting fewer customers, bringing less money to the confectioner, thus turning the cycle vicious. The causality remains the same, but the loop is no longer compounding. There’s still feedback, but it doesn’t accumulate value.

As I mentioned earlier, drawing a few of these revealed a general pattern. There are usually two parties: Customers and Vendors, who each produce two artifacts, each potentially interesting to the other party. In the case of our ice cream parlor, the two parties are 1) the confectioner and 2) the customers. The two artifacts are 1) ice cream and 2) the payment of money. Each artifact is produced by one party and is attractive to another party.

To turn it into a template, visualize a loop that consists of four boxes: Vendors, Products, Customers, Interactions. There are four arrows that connect them: Vendors make Products, Products attract Customers, Customers engage in Interactions, Interactions attract Vendors. This template basically asks four questions:

  1. Who are the Vendors?
  2. What are the Products they make?
  3. Who are the Customers?
  4. What are the Interactions that they engage in?

In different environments, the boxes and arrows will have different names. In a marketplace, it might be Sellers, Listings, and Buyers. When applied to services, it could be Provides, Services, and Consumers. For the software engineering team, I will use Developers, Products, Users, and Interactions, though the pattern remains the same. 

For a typical engineering product team setup, filling out this template should be fairly straightforward. Our team is the Developers. Our shipping product is the Product we make. Our product’s users are obviously Users, and the Interaction is the outcome of our users’ engagement with the product, which will depend on the nature of the product.

The customer-vendor loop contains a few useful insights. First, it asks us to separate nouns and verbs, because action is something that can be influenced, while the noun is the outcome of the action. In the language of System Dynamics, verbs are flows and nouns are stocks.

To understand the state of the loop, we look at stocks (nouns). To find ways to influence the loop, we look at flows (verbs). For example, DAU will tell us about the state of the Users stock. To improve the quality of the product we ship, we must change the way we build it. If you are familiar with the OKR system, you can view Os (objectives) as our tactics to influence flows (verbs) and KRs (key results) as our means to measure stocks (nouns).

Second, Developers have direct agency only over the verbs adjacent to them: “attract” and “build”.  There are two other verbs that can only be influenced indirectly. When a team commits to building great software, they assert that they will do their best to accelerate the flows they have agency over. This may or may not be enough to turn the customer-vendor loop into a compounding one.

Third, the two “attract” arrows are significant. The one that points at Users makes intuitive sense. After all, the whole notion of attracting users is fairly familiar to us. We promote our software, make it seem cool in commercials, we build reputation, and/or make onboarding as easy as possible  – these are all familiar methods by which we attract users.

The arrow that points at the Developers needs a bit more discussion. How do Interactions attract Developers? In the simplest scenario, an interaction is a purchase of some sort, which makes the attraction obvious: revenue from purchases supports developers and funds further development. 

However, there are many teams where the presence of this arrow is not as clear. What is the nature of the attraction for peeps who contribute to open source projects in their free time? If a team ships a free library, how does it close the loop? What is the source of energy that keeps them going? Answering these questions seems important, since if there is nothing that keeps developers coming back for the next iteration of the loop, there’s no feedback loop. Yet somehow, they continue to exist. What’s happening?

Puzzling over this often hard-to-see closure has been a really a really fun challenge, and I’ll keep you in the loop (ha!) on what I learn from the adventure.

Continuously Integrated Strategy

Here’s a possibly useful analogy when talking about strategy work with engineering leads. 

It is considered a poor practice to write code without testing. No matter how brilliant we are as engineers, the bugs we produce will sooner or later have to be addressed. There’s even a practice of continuous integration, which encourages that every change, no matter how small, is to be tested as part of being accepted into the shared code repository. As engineers, we write code all the time – and continuous integration helps us account for all the intended and unintended behavior changes we cause while doing so.

Somehow, these amazing ideas don’t seem to extend to strategy. In the same engineering organizations, we appear stuck somewhere at the late stage of the waterfall model. There are annual cycles of strategic planning that march forward for a few months, culminating with docs and slide decks that inform organization’s leaders on where to focus and what investments to prioritize. Don’t get me wrong – these are often useful exercises. I remember the first earnest SWOT analysis I’ve gone through with my colleagues and the (alarming) clarity it brought. However, don’t they seem a bit like a throwback to the early days of software engineering? You know, the time when we still believed that we can ship perfect software if we just planned it hard enough?

Putting it somewhat bluntly, the brief annual focus on strategy feels awfully similar to New Year’s resolutions – all but forgotten by mid-January. Worse yet, the annual cycle naturally confines the perspective. Why think a few years forward when we’ll be doing this again next year? And who has the time? So, our strategic foresight ends up being crimped to a year – if that.

Lastly, the environment around us rarely stays in place. Even though our intentions may remain firm, how we see problems ahead of us changes all the time. When we sketch out our first draft of strategy, we actually know very little. Every step we take teaches us new things, and potentially – no, definitely – affects how we approach the situation. Just like in writing code, every action we take contains unexpected side effects. If we only account for them once a year, our strategies are unlikely to be useful. They aren’t just limited in time – they are also frozen in it. So we engineers just whiff on strategy work. Why waste any more time than absolutely necessary on a useless artifact? No wonder strategic planning exercises are usually just planning.

Perhaps we could choose to do something different? What if, borrowing from our well-learned engineering tricks, we reframed strategy as something that is practiced continuously, and developed a habit for that? Strategy is like writing code. It’s just a guess that mutates as soon as it begins interacting with reality. Why not give our strategy the same respect that we give to our code? What might a continuously integrated strategy look like?

These are the questions I am looking to answer. Take the same SWOT analysis as an example. I am playing with the idea of a “SWOT garden”, where SWOT is no longer something we do as a one-time thing, but rather keep updating as we recognize new threats, opportunities, weaknesses, or strengths. SWOT gardens live and are cultivated. When a new threat is encountered, we add it to the matrix and check to see how it fits with other threats, and reframe them as necessary. We also evaluate to see if the newest addition sheds light on other bits: what are our strengths and weaknesses that make up a threat? What are the opportunities that might exist alongside it? 

I hope the SWOT garden concept makes sense. As a benefit, we get to have a continuously improving picture of the key challenges that our organization faces. And once we understand these challenges, we are in a much better position to make proper diagnosis, which will in turn help us iterate on our guiding policies and coherent sets of actions that follow.

Midjourney

I recently got an invite to play with Midjourney, one of the AI-generated art tools out there. It has been a fun adventure, and I am learning a lot. Here are some insights that goofing around with Midjourney produced.

First, I am very impressed with how they leaned into the power of Discord. Until this point, I suspected, but didn’t fully grok the importance of Discord as a developer platform. Midjourney relies on it for authentication/authorization, key workflows, cross-ecosystem reach, and obviously, community-organizing.

When I joined Midjourney, I was dropped into a Discord server alongside other newbies. Operating Midjourney is super-simple: just type the “/imagine” command with a prompt of your choosing into the channel. The result is a four-panel set of choices, arranged in a 2×2, with choices (as buttons) to create more variations for each choice or upscale them. This creates a rather simple, yet effective mechanism of steering: I can either tweak my prompt or iterate on the variation.

I found myself swimming in generated art, prompts constantly produced by my fellow mid-journeyers. The creativity was all abuzz and inspiring, with some folks trying to prevent their “Kermit meets the Governator” from melting , and others zeroing on just the right kind of perfect dystopian landscape. For some reason, Midjourney excels with post-apocalyptic and gothic art, as well as other kinds of unsettling visage.

Once I used up my allotted free computing power, I decided to subscribe, and found that once I became a paid user, I gained my personal Midjourney bot to interact with privately. That was a rather clever move: using Discord infrastructure to create tiers within the community. All in all, the way Midjourney uses Discord has that “just enough” kind of feel for this sort of a project. I can easily imagine myself trying to write a standalone PWA (or cross-platform app), struggle with authentication and ACL design, etc. It sounds like Midjourney folks asked a reasonable question: “do I need any of that?” – and gained strong community management tools in the process.

Second, after running up quite a bill with different prompts and steering the variants, I am hopeful that this kind of generative art is on its way to be the new creative medium. With Midjourney, I have this intuition that I am witnessing the birth of the next TB-303, a crappy toy bass synth that redefined dance music. It is usually these simple toys that dramatically lower the threshold of entry for people to create new, interesting things – and serve as catalysts for the new wave of cool stuff that inspires generations to come. 

It is not a stretch to imagine that muzak and clipart will be generated using this method in the near future. “Want 5 hours of chill lobby jazz? Here it is.” It only takes a bit of squinting to see tools like Midjourney do a half-decent job here. What also seems likely is that in addition to prompt-tweaking and choosing four variants, there will be demand for more nuanced sculpting and crafting, guiding the generated art tooling. And once that becomes available, it is inevitable that new forms of art will emerge. I can’t help but be excited about the possibilities here.

To convey what I was seeing, here are some actual journeys to give you a sense of this tool. I asked Midjourney to imagine “What Dimitri Learned”. Initially – and somewhat in line with my expectations of its biases – Midjourney went straight into the Game of Thrones fanfiction territory:

Umm… Maybe save that one for when I decide to write a young adult novel? Imagine that, “What Dimitri Learned” is a fantasy novel about a forlorn young protagonist with a budding fire-starting superpower. Yeah. So I tweaked the prompt to be a bit more upbeat. Here’s the “What Dimitri Learned, optimistic” outcome:

Nice! But still, the 18th century Eastern Europe feel was not quite what I was looking for. After playing quite a bit, I ended up with this second-generation variant of “What Dimitri Learned, futuristic, optimistic”:

Alright, this I can get behind. A bit too techno-futuristic for my taste, but I’ll take it. To give you a sense of how this particular journey in the visual eigenspace progressed, here’s a handy chart:

The whole experience felt like a glimpse of something much bigger. There are definitely terrible downsides, and even thinking about them makes the hair on my neck rise. There are also possibilities for something beautiful. It is so uncanny how these two always come in pairs. 

Blueprint, Compass, and Remodeling

Reflecting on some vision work that I’ve been doing recently, I am realizing that I can inhabit two different perspectives, two different mindsets to approach a vision: vision as a blueprint and vision as a compass.

With vision as a blueprint mindset, I tend to treat the imagined future as a sort of grand schematic of what needs to be created, an architectural plan to be executed on. Taking this mindset feels very clarifying. I can start staking out the ground and budgeting resources, I can plan timelines and craft processes around it. Vision as a blueprint can be an amazing source of organizational coherence. Provided the communication limits have been overcome, it can serve a clear intention that the team checks their work against. Metrics are easier, because they measure completion of the work, captured by the blueprints.

With vision as a compass mindset, my perspective shifts. I no longer see the vision as a grand plan, but rather as one potential future among many other possibilities. The only thing differentiates this particular potentiality from others is that it has some properties that I hold as valuable. These properties can come together in other combinations, forming a different vision, but this is the one I was able to discern while staring into the future. This mindset encourages me to remain open to the outcomes and allows a lot of flexibility in how to get there. Compass points toward something, but doesn’t plot the path. It is okay to deviate from where the compass arrow points for a little while, to walk around obstacles or explore unexpected treasure troves. When in this mindset, I tend to seek “preferred adjacent possible”: what is the change I can make today to things I am doing now to orient toward the vision?

Both mindsets have unproductive extremes. When in the blueprint mindset, I can fall into the NIH trap (or its cousin, “second system” trap), deciding that it will be easier to just start making the future from scratch. As an engineering lead, I might be tempted to start a new team that follows the vision’s blueprints, separating it from the team that maintains the boring old present. This can work pretty well in environments where the blueprints can predict the future with reasonable accuracy. After all, many engineering artifacts are based on blueprints. However, the environments that shift and change can invalidate the blueprints mid-build, turning the whole enterprise moot. By assuming predictability of the environment, viewing vision as a blueprint can lead to blind spots that doom it.

On the other side of what increasingly looks like a spectrum, the compass mindset can get me in trouble with its flexibility. Especially in large organizations, if everyone is walking around obstacles and exploring interesting caves, the path to vision may fail to converge. Worse yet, the sense of divergence itself can get rather uncomfortable. With the answer to “where is this all going?” getting blurry and anxiety rising, the organization may tip into the traps of adversarial adaptation variety. By assuming unpredictability of the environment, viewing vision as a compass can doom it by decohering the organization.

To help navigate this spectrum of mindsets while avoiding the extremes, I came up with this analogy of remodeling. Think of it as a third mindset that straddles the other two. Remodeling a house is usually a rather weird hybrid of the certainty of knowing what we want and the unpredictability of what will be uncovered during the remodeling process. The wall we thought was load-bearing may turn out to be free-standing, the beams in the attic may have all rotted out (true story!), yet tearing out the scuffed and dented linoleum reveals beautiful hardwood floors. When we remodel, we have to dart back and forth between the blueprint and the compass mindsets. We have to continuously reinterpret the vision as new evidence is uncovered. 

Additionally, we are rooted in what’s possible. When we commit to a remodel, we don’t start from scratch. We think in diffs. Where will this beam have to move? What additional foundation will have to be poured? Where will the new window be cut in? When we think in diffs, we need to also consider what stays the same. Which parts will we find unchanged after our vision comes true?

My intuition is that this combination of thinking in diffs and reinterpreting the vision creates a bit more space for thriving in uncertainty while still imposing the boundaries of the blueprints. I’ve been looking for an example of a remodel mindset, and found myself coming back to the I/O talk that year that my colleague Alex Komoroske and I gave back in 2012. We pretended to come from the future, describing how the Web development will look like. Now that that future is in the past, it is easy to see that the vision was reinterpreted throughout the journey. Most of the technology bits we demonstrated evolved significantly in their syntax and names. However, if you look at them now as they ship in all browsers, you can clearly see the ancestral resemblance. Similarly, we thought in diffs. The talk didn’t propose a brand new language or dramatically different new ways of building Web applications. We just moved some walls and added a kitchen nook, leaving most of the sound foundation intact – making the vision more relatable and easier to reason about.

Stakes

This is not as well-formed as it could be, but felt worth capturing. I’ve been struggling to describe the limit of attachment in various ways, and the concept of “stakes” seems like such a good topic to explore.

There’s something about the phrase “a high-stakes situation” that paints a vivid picture of a stressful encounter. When stakes are high, we are alert, anxious, and ready to act. When stakes are low, we’re relaxed, chill, and maybe even bored. But what are these “stakes”? Where do they come from?

Trying to orient the concept within the problem understanding framework, I characterized stakes as the degree of our attachment to an intention. I am loading a few things into this burrito of a definition, so let me try to unroll it.

First, stakes are associated with an intention. In a world without intentions, there aren’t stakes. This seems important somehow, given that every intention represents a problem.  Stakes are how we measure the significance of us finding a solution to this problem. It doesn’t matter if we find solutions to low-stakes problems. It matters a lot for the high-stakes problems.

Second, my use of the word “attachment” indicates a particular kind of limit of understanding being tested. The higher the stakes, the less likely we are to incorporate disconfirming evidence into our model and adjust it. When stakes are low, our limit of attachment is no longer impacting our process of understanding. For example, a brainstorming session or a generative meeting usually requires a low-stakes setting.

Why is it that we are attached more to some intentions and not others? Let me introduce a kind of intention that I’ve touched on briefly when discussing homeostasis: the intention to exist. The existential intention is something that comes built-in with our wetware. Even before we are capable of forming a coherent thought, we already somehow have the most primitive mental model that includes a “what is” with us in it, and “what should be” with us continuing to be in it. We are born into solving our existential problem.

My guess is that this existential intention is something that undergirds most of our intentions. Put differently, stakes rise when any of the mental models we contain start predicting outcomes with us not existing. Remember the predator wanting to eat me in one of the earlier posts? That’s a high-stakes situation. One of those “what should to be” outcomes had “me” replaced with “meal”.

Existential intentions have a firmly fixed “what should be” that is non-negotiable, which makes them a source of distortions to the rest of our mental models. Bumping into the limit of attachment will tend to do that. Especially in the early stages of our development, this can lead to our mental models getting to seriously weird states. A way to think of psychology might be as the entire discipline dedicated to untangling of the mental models tied in vicious loops of adversarial adaptation within one person’s mind.

Because of these distortions, existential intention often gets in the way of living joyfully. For example, whenever I feel nervous before speaking to a large audience, I am likely experiencing some entanglement with existential intention. Somewhere in the depth of my brain, there’s a mental model in my mind that is making a literal existential-scale prediction: that perhaps I may be mauled to death by the audience or some absurdity of the sort. Usually, the mental model takes several hoops before arriving at “and then I will die!” and may include classics like “everyone will laugh at me” and “this will be the end of my career” and “my family will disown me and kick me out to the street” so on. It may be only a teensy-weensy part of the overall mental model, a part that is easily overwhelmed by other, more mature and confident mental models. But the mere fact of me feeling nervous tells me that it’s there – freaking out and trying to avert my imminent demise.

Because our mental models are developed individually, we all have our own unique configurations of existential intention entanglements. Situations that are high-stakes for some may be totally chill for others. Though socialization brings a degree of sameness, our evaluation of stakes remains deeply personal. For example, when creating a low-stakes environment for a generative conversation, we may mistakenly presume that an environment works for us will for all of the participants. I’ve made this mistake a whole bunch of times. The best approach I know is to manage the stakes dynamically, staying aware of the participant’s engagement and helping them navigate their tangles of existential intentions.