Framing and solving diverge-converge exercises

There’s this fairly common technique: the diverge-converge exercise. I first heard about it when learning about design thinking, and now recognize it in other places. The gist of it is fairly simple: break down your thinking process into two distinct phases. In the first phase, encourage divergence of ideas to broaden the space of possibilities. In the second phase, study this space to converge on one artifact that best satisfies the intended objective of the exercise.

When working on a decision-making framework, I realized that there are two distinct kinds of this diverge-converge exercise, each with a different goal. I am going to call them “framing” and “solving”. As I implied before, the first one roughly maps into the Complex Cynefin space, and the second one into the Complicated.

The solving diverge-converge exercise is the one that I see described most commonly. Invest a bit of time in the “diverge” phase to generate a rich pool of possible alternatives, then compare them to pick the one that works best in the “converge” phase. A typical engineering doc that’s an outcome of the solving diverge-converge exercise has several alternatives listed with pros and cons, and a discussion followed by a decision to pick one of these alternatives. This kind of diverge-converge exercise is very much about finding the best fit, and it benefits from having a strong fitness function that guides the process of making the pick.

The framing diverge-converge exercise might seem similar, but has an entirely different mindset. Here, the “diverge” phase is meant to collect perspectives that all describe something that’s difficult to see from just one side. When framing, the “converge” phase is no longer about picking the best fit. Instead, it’s the process to see the larger picture, incorporating all perspectives, studying the differences and similarities between them to synthesize a larger perspective. A typical artifact here is a problem statement doc, describing multiple perspectives of the stakeholders and outlining how they relate to — and interact with — each other, along with the outline of the synthesized larger perspective. In the framing diverge-converge exercise, the choices aren’t narrowed down. Instead, they are used to improve the understanding of the space.

When trying to compare the two kinds, the blind men and the elephant parable comes to mind. When applying the solving diverge-converge exercise, the big question will be whether it’s a fan, a snake, a tree, or a wall: we have to pick one. When applying the framing diverge-converge exercise, we might actually see the elephant.

The story of agency

Another kind of story that I’ve encountered in my exploration of coherence narratives is the story of agency. Again, it’s loosely borrowed from the Four Needs Framework and plays a catalytic role similar to that of the story of belonging.

The story of agency is all about going it alone. It’s about striking out on my own, finding our own path, independence, and self-sufficiency. It can also be about perseverance, toughing it out, defending, and standing tall.  The story of agency is deeply woven into American culture, celebrated on July 4, in remembering the Alamo, and oh so many movies with a lone heroic protagonist.

Just like the other catalyst story, the story of agency leans on the structure of another story. Combined with the story of an opportunity, it celebrates uniqueness and breaking with convention as the precious ingredient. Mixed into the story of a threat, it uses the same qualities to draw the bright line between life and death.

Looking at various organizations, I am picking out two distinct patterns. First, the story of agency often plays a role in diminishing coherence. It is the story of break-ups, of abandoning the common goal, of “this is not working out.” Behind every tense conversation, irreconcilable disagreements, and teams deciding not to collaborate lurk stories of agency.

Second, the stories of agency and belonging tend to blend into this curious nested-doll relationship that increases coherence. The story of agency provides the lens to evaluate the external environment, while the story of belonging sets the tone for internal: “we come together to be unique and different from others.” This is also a very common strategy in marketing. Apple’s “Think Different” poster immediately pops to mind when looking for an example of such a nested doll. I buy your product to stand out, while at the same time becoming part of a group.

Through this symbiotic relationship of two stories, organizations and any groups of individuals create boundaries. The story of belonging is what defines the in-group, and the story of agency — the out-group. The story of a threat, catalyzed by the in-group’s story of belonging, is often based on the story of agency: the threat from whom? — the out-group, of course.

For example, a team’s narrative might be about building something truly revolutionary (story of agency + story of opportunity) while persevering in a rapidly shifting, or even hostile conditions (story of a threat + story of belonging). If such a narrative is particularly resonant and crisp, it tends to live for a very long time, sustaining coherence of a group and becoming this group’s identity.

The language frames the story

Suppose you’ve said to me that “the falling maple leaves whirl in a delicate dance with the gentle breeze.” It’s late fall, so it feels like a reasonable thing to say. The trouble is, my language only has words like “eat, fight, run, here, that, there, now, later.” I might be fascinated by what you’ve said, but get very little out of it — and even less to pass on to others. At best, I will point at the sky and say “that!” and bulge my eyes meaningfully.

This might seem like one of those — duh! — obvious observations. Of course the language frames the story. However, I am finding that I easily forget this in the contexts of teams and how they are organized. To communicate with each other, teams establish a common language, a set of semantic shortcuts that allow them to work together effectively. This is where the non-obvious bits hide. This common language also frames what is being communicated.

For example, let’s imagine a hypothetical organization where communicating strategy across teams is done through a list of annual objectives and key results (OKRs). There is a process to assemble them into a coherent whole. When it’s all said and done, the story written in the language of OKRs tells where we will go next year.

However, some of our desired destinations take longer than a year to reach. To communicate these destinations, we need a language that can describe ideas that last longer than a year. Can you guess what happens when we try to express them in the language that only speaks in year-long sentences? Sure, within teams there might be long-term thinking and sound strategic artifacts. However, given the pidgin of annual OKRs that prevails outside, it is unlikely that these artifacts survive cross-team communication. The multi-year ideas will be neatly chopped or scrunched into the one-year box — rendering them as useful as my eye-bulging-while-pointing.

If I am lucky enough to work in an organization full of brilliant individuals, I will also start seeing these folks adapt to the common language. More and more, I will see how they pick out ideas that fit within the language to reduce the friction, making sure that only year-long journeys are those that count, whether in impact or attention of leads. Sure, there will still be the linguistic idealists who rail helplessly trying to overcome the limits of the OKR pidgin, but those will eventually give up and leave.

While the organization wonders why it struggles to think strategically, it might be worth it to examine the language it uses to organize itself. Is the language flexible enough to accommodate both short-term and long-term destinations? Are all ideas that matter expressible in the semantic shorthand that everyone is expected to speak?

The developer funnel

If I ever chatted with you about developer experience in person, I’ve probably drawn the developer funnel for you on the whiteboard. For some reason, I always draw it as a funnel — but any power-law visualization can suffice. As an aside, I do miss the whiteboards. 

At the bottom of the funnel, there are a rare few who know how to speak to computers as directly as humans can. Their perspective on writing data to storage involves programming a controller. As we travel a bit higher, we’ll find a somewhat larger number peeps who write hardcore code (usually C/C++, and more recently, Rust)  that powers operating systems. Higher still, the power law kicks into high gear: there are significantly more people with each click. Developers who write system frameworks are vastly outnumbered by developers who consume them, and there are orders of magnitudes more of those who write Javascript. They are still entirely eclipsed by the number of those who create content.

With each leap in numbers, something else happens — the amount of power passed upward diminishes. Each new layer of abstraction aims to reduce the underlying complexity of computing and in doing so, also collapses the number of choices available to developers who work with that layer. Try to follow the rabbit trail of setting a cookie value, a one-liner in Javascript — and a massive amount of work in the browser that goes into that. Reducing complexity makes the overall mental model of computing simpler and easier to learn, which helps to explain the growing number of developers.

This funnel can be a helpful framing for a conversation about desired qualities of the API. Do we want to have rapid growth? Probably want to be aiming somewhere higher in the funnel, designing convenient, harder to mess up APIs. Want to introduce powerful APIs and not worry about the sharper edges? Expect only a small number of consumers who will understand how to use them effectively.

Developer surface

I mentioned this concept before, and I feel like it’s worth expanding on a little bit. If we are in the business of making a product that developers rely on to create user experiences, the developer surface of this product is the union of all means through which developers create these experiences. 

Let’s unpack this, starting with a simple case. Suppose you and I decided to ship a library that has one function. Applying the definition, that library is the product and its developer surface is the function. Easy, right? As our product becomes popular, we start noticing something weird. Remember that one-line file where we track the version of the library, just for ourselves? Well, turns out some developers started using its contents in their build. So when we thought — “oh hey, let’s just delete that file, we don’t need it anymore” — all hell broke loose? That file became developer surface, too!

In mature developer-facing products, the developer surface becomes far more than just the API. Shipping samples along with the library? Yep, these are part of the developer surface, too. Got some clever heuristics deep in your code? Or maybe just bugsHyrum’s Law captures beautifully the spirit of this phenomenon: 

With a sufficient number of users of an API,
it does not matter what you promise in the contract:
all observable behaviors of your system
will be depended on by somebody.

This sufficiently high number of API users can truly mess with what is or is not a developer surface. While we imagine the contract with developers as a crisp document of high transparency and clarity, we are usually mesmerized by the messy innards that are the outcome of developers just trying to get things to work. Even messier in comparison will be our attempts to convince developers to use the APIs the way we intended.

When we embark on a project that intends to ship a developer-facing product, it’s worth planning the work and structuring the team in a way that anticipates this messiness. We are not writing the developer contract. Developers write the contract with us, and frequently, their contributions carry more weight. Walking this line of carrying our original intention while having awareness of where the developers want to take is not something that comes intuitively or easily.

The story of belonging

Next in my adventure across the coherence narrative realm is the story of belonging. It sort of maps into one of the fundamental needs from the Four Needs Framework, but plays a subtly different role here.

The story of belonging is also something that is easy to spot as a felt experience. Someone wise suggested that humans are wired for connection, and the web of these connections is what creates the gravitational pull in the story of belonging. There’s something about being together with others, being part of the group, next to those who consider you kin, being loved, included, and understood.

When I try to examine stories of belonging, I notice something interesting. They usually contain the words “we,” “community,” “together,” “teamwork,” “alignment,” “unity,” and so on, but structurally, it’s almost always not a standalone story. Instead, the story of belonging acts as a powerful catalyst, laced into the story of a threat or the story of an opportunity. Just milling around together is one thing, but something magical happens when the “we are”  is combined with “under attack” or “the future”: the capacity for coherence shoots up like a rocket. No matter what kind of compounding loop we might face, it seems that doing it as a tightly knit group feels natural and right to us humans. 

To add to the weirdness, the loss of belonging is a common story of a threat — and finding it a common story of an opportunity. In our interconnected world, this kind of ouroboros is in itself an abundant source of compounding loops. It’s one reason why teams tend to form boundaries and organizations grow silos. It is also the undercurrent behind the craving to gain more likes or followers and many similar societal dynamics. 

Considering the story of belonging as means to improve organizational coherence, a couple of thoughts come to mind. First, the stories of belonging are quite inert by themselves. The need to combine with compounding-loop stories to get traction. Second, we live and tell multiple stories of belonging simultaneously. Navigating all these stories is tricky, and growing new stories of belonging (“we are a team!”) is a careful, finicky process that often bumps against all the participants’ stories, taking patience and time to develop. Maybe this is why we use the word “culture” to describe a mature organization’s story of belonging?

Veering toward first-order effects

Have you ever driven a car that pulls to one side? It’s often subtle, but after a while, the counter-steering effort becomes impossible to ignore. This metaphor comes to my mind whenever I encounter a common developer experience pattern: the veering toward first-order effects.

To set the context a bit more, let’s arrange the effects of producing developer surfaces in two orders. The first-order effects relate to producing the developer surface. When we ship an API, we want it to be adopted, to be used broadly. Thus, when we measure first-order effects of our efforts, we look at the API adoption rate, developer satisfaction, etc.

The second-order effects relate to developers producing user experiences using our developer surface. At the end of the day, an organization that invests into shipping APIs does so — intentionally or not — to influence the overall state of user experience in some way. When we measure second-order effects, our metrics will likely track changes in the user experience. Does using our APIs result in products that are more secure, performant, accessible, etc. for the user?

Based on what I’ve seen working with developer experience teams throughout my career, there’s a pronounced pull toward first-order effects. They are easier to measure, have a shorter feedback loop, and are more familiar to folks accustomed to shipping consumer products. Even if a team sets out to influence the state of user experience at the beginning of their journey, the appeal of relative immediacy of first-order effects is so strong that the original intention often gets left behind.

A common symptom of forgetting to counter-steer toward second-order effects is the loss of strategic flexibility within a larger organization. When the first-order effects become the means onto themselves, they tend to get entrenched in a local maxima of developer expectations, stuck in an optimizing loop. An organization that contains teams stuck in that particular way feels like it is unable to do anything about it: everyone is seemingly doing “the right thing,” and prioritization exercises quickly devolve into peanut buttering. When something like this is happening, it’s a good hint that the concept of second-order effects got rolled into a dusty corner of the team’s shared mental models space, or ejected altogether. 

To counter-steer, organizations must exert conscious effort to keep second-order effects in the shared mental model space. Whether it’s constantly pointing at them during the all-hands, setting up the metrics structure to reflect user experience shifts, or even just reminding about the unyielding force that — like that darned car — never quits pulling, it’s an investment that’s well-worth the price.

Cutting or highlighting?

Talking with one of my wise colleagues, we arrived at this neat framing around making decisions. “Decision” is a weird word. My friend Neel tells me that its Latin root is literally “to cut away,” and that recognition that a decision is always about narrowing the list of available options can be both liberating and anxiety-inducing. The interesting bit is that sometimes, decisions aren’t meant to cut away.

As it often happens in larger organizations, we tend to live in the swirl of the short-term and long-term objectives. And it is definitely a swirl: the art of leadership is picking out the right mix. Blend in too much short-term, and we’ll find the team stuck in the corner of a local maxima, overconstrained by its previous choices. Blend in too much long-term, and the team fails to make progress that’s necessary to keep that motor running.

To adjust the mix, leaders decide. A common mechanism here is prioritization: picking a shorter list of things that the team needs to focus on. One approach to prioritization is to apply the cutting mindset, as in cutting the list in half: keep what’s above the line and discard the rest. For example, let’s suppose I want to build an app that is available on both Android and iOS phones, but I want to prioritize iOS users. Applying this cutting mindset, I just forget about Android for a while, break out my XCode and start typing some Swift. Only after the iOS version is shipping do I start looking at the rest of the list. Given how many unexpected turns a typical software project takes, will I ever get to do that? Maybe. Will this approach result in a painful migration or two — or worse yet, the “release polka” where my app always looks out-of-date on one platform compared to the other? Probably.  

The cutting mindset is straightforward and clarifying. Yet, in situations where the rest of the list is still a thing we want to do later, it often leads to inferior choices. In these situations, we need something different. Instead of cutting the list, we want to highlight the items on which we want to focus — while still keeping the rest of the list in mind. With this highlighting mindset, the choices we make take on a different spin. Instead of asking “what’s the next step to deliver <prioritized item>?” we ask “how can we take a step toward delivering <prioritized item> that also takes us closer to completing the whole list?” The thing is, the items on our lists are rarely orthogonal and live in clean separate boxes. More often than not, considering them as a whole reveals opportunities for advancing toward completion of multiple items simultaneously. In my app example, while still focused on the iOS release first, I might consider picking a UI framework that also runs on Android, or at least build my middleware in a way that is portable.

When making prioritization decisions, it’s worth being explicit about the mindset with which you’re approaching, discussing with the team the reason you chose one over the other. Otherwise, despite your desire to highlight, an eager PM might swiftly cut your long-term objectives out of the mix. Or conversely, the team will continue to swirl aimlessly in the ideals you have already forgotten about, from back when you thought you cut them away.

Making cross-cutting investments

Over the last few weeks, I’ve been thinking about approaches to influencing projects and teams across a large organization. I framed the exercise like this: suppose I have some organizational currency (headcount!) to invest. How do I nudge project trajectories in the most effective way?

Then, I talked to a bunch of peeps, looking for forces present in this problem space. There are probably many more, but these two piqued my attention. The first one has to do with the term of the investment: do I want to invest in several different things over time or do I mostly want to keep investing into the same thing? The second one has to do with how much control I want to have over the structure of investment: how much steering do I want to do with my investment? Mapping these two forces into thinking space, a few recognizable clusters emerge. 

A good example of low-control, permanent investment is donation. I find a team, recognize that it is doing important work and decide to help them by adding to their capacity to hire new folks. Based on my experience, this is more or less a permanent investment. Withdrawing donated headcount tends to be painful for all parties involved. Nevertheless, if the team’s goals are largely aligned with mine over the long term, and I have no qualms with their strategy, it’s a pretty good fit.

If I want a more temporary engagement, I need a different approach. One is to temporarily augment a team with a group of folks to accelerate a particular aspect of work. It’s exciting to imagine that such a team will drop in and race forth with uncanny precision. However, in orgs that have strong engineering practices and structures, augmentation is first and foremost a matter of learning to follow those practices and fitting into existing structures. “Who will review your CLs?” is the question to contemplate when considering the augmentation setup. They work well in homogenous organizations, when the members know the engineering practices well and are the people who can review CLs. Otherwise, this investment tends to offer less control than anticipated.

To gain a bit more control without permanence, I will likely try to incubate a team: seed it with good peeps, set up a resilient structure to help it stay on course, get it past the early growing pains, and let it go. Variants of this approach are found in research organizations and idea incubators, and I’ve seen it work. In the couple of times that I participated in the process, the biggest challenge was finding the right fit for the graduating team and then shepherding the team through often painful reintegration. At least to me, incubation felt more like an art rather than a repeatable process, but that just might be the lack of experience.

Finally, if I am seeking to invest in the long term while retaining high control, I am probably productizing, or reframing my desire to help in terms of a developer-facing product: a tool, a library/framework, an SDK, etc. This product must be good enough for the teams to want to rely on — and to get results that I want them to get. Note that this end result is a second-order effect (first, they want to use it, second, they produce desired outcomes), which is what makes this approach so challenging. On the other hand, precisely because of the indirection, this approach has something that no other approaches offer: the ability to influence multiple teams. Productizing is typically more demanding compared to others. It takes more effort and capacity to build an effective team that reliably ships a successful developer product and have the resilience to keep an eye on the outcomes I need. That last one is important. It takes just a little bit of stress and firefighting to fall back into the “let’s make developers happy” mode and forget the whole point of the exercise.

Heuristics will be discerned and codified

Here’s another developer experience pattern that I’ve noticed. When designing APIs, we are often not sure how they will be used (and abused), and want to leave room for maneuvering, to retain a degree of agency after the API is in widespread use. One tempting tool we reach for is the use of heuristics: removing the explicit levers to switch on and off  or knobs to turn from the developer surface and instead relying on our understanding of the situational context to make decisions ourselves. Unfortunately, when used with developer surfaces, heuristics tend to backfire. Developers who want those levers and knobs inevitably find ways to make them without us. And in doing so, they remove that agency that we were seeking in the first place.

Because heuristics are so tempting, this pattern is very common. Here’s the most recent example I’ve stumbled upon. Suppose you are a Web developer who wants to create an immersive experience for their users and for that, you want to make sure that their device never goes to sleep while they are in this experience. There’s an API that enables that, called the Wakelock API. However, let’s imagine that I am a browser vendor who doesn’t want to implement this API because I might be worried that the developers will abuse it. At the same time, I know that some experiences do legitimately call for the device screen to stay awake. So I introduce a heuristic: stay awake if the Web site contains a playing video. Great! Problem solved. Except… You want to use this API in a different scenario. So what do you do? You discern the heuristic, of course! Through careful testing and debugging, you realize that if you put a tiny useless looping video in the document, the device will never go to sleep. And of course, now that you’ve discerned the heuristic, you will share it with the world by codifying it: you’ll write a tiny hosted API library that turns your hard-earned insight into a product. With the Web ecosystem being as large as it is, the library usage spreads and now, everyone uses it. Woe to me, the browser vendor. My heuristic is caught in the amber of the Web. Should I try to change it, I’ll never hear the end of it from angry developers whose immersive experiences suddenly start napping.

It’s not that heuristics are a terrible tool we should never use. It’s that when we decide to rely on them in lieu of developer surface, we need to anticipate that they will be discerned and codified — sometimes poorly. This means that if we wanted to rely on heuristics for some extra flexibility in our future decisions, we’re likely to get the opposite outcome — especially in large developer ecosystems.