The Responsible Designer

Critical Software Redesign: Creating the Environment for Large Scale Change


There’s a moment where it’s too soon to invest in a radical new software design for your system. And then you reach a moment where it’s too late, too expensive to change it. Is there a sweet spot in between, a point where pivoting the software design is the right choice, at the right time?

As a leader, you are constantly resolving problems involving the software architecture, making technical decisions, meeting customer needs, and shipping product features.

It’s easy to see all these problems as isolated challenges, that you deal with one after the other. You’re making a lot of decisions, but are you thinking about your overall software design?

We’ll discuss how all of these challenges, the solutions you pick for them, and the impacts of those solutions can be treated as signals, both positive and negative. These signals show where the external environment repeatedly puts stress on your system’s current design.

By paying attention to these signals over time, you can figure out what changes your system’s design needs. You can use the signals to trigger experiments. Besides buying you information about the viability of a major redesign, you use experiments to build the culture and support for it.

A Tax Calculation Product

To see how a design might evolve, let’s dive into the example of TaxGlobe. It’s a startup that builds a product for the global supply chain.

TaxGlobe’s product calculates taxes for shipping goods. Shipping routes have legs, and at each transit point of a leg, authorities charge taxes on the goods that move through them. Not only can a particular locale have taxes, it could have multiple taxes. There may even be multiple tax authorities in the same hub, such as state, county, and city taxes, with different precedence rules. These tax rules can also be interdependent: for example, different tax rates apply but the total tax may not exceed a certain percentage of the total value of the goods. Goods are taxed depending on their type, and of course the quantities.

TaxGlobe’s customers are multinational companies that manufacture equipment such as cars or electronics, and who ship globally at scale. The TaxGlobe product is used by their tax accountants and tax lawyers who need to accurately compute and pay taxes to the various authorities.

The tax rules in TaxGlobe’s product have to change whenever the tax laws change. Tax authorities publish rule changes in advance. These might be a simple percentage change, a move from a flat rate to a graduated tax, new classifications for goods, different tax rates, or a completely new algorithm or calculation method.

The product’s Unique Selling Point (USP) is that it can handle all these rules across many international markets. TaxGlobe’s own tax lawyers keep up to date with changes to tax rules, and work with the developers to update the code.

Tax Law Interpretations

TaxGlobe’s product had its niche in the market precisely because it could handle international tax rules. Initially the rules were hardcoded. But there’s an inherent problem in this design approach: tax rules are open to interpretation. Tax rules aren’t like physical laws. Instead, like all legal documents, tax laws are open to different interpretations. But what was hardcoded was only the interpretation of the rules by TaxGlobe’s tax lawyers. The software reliably gave the same outputs for the same inputs, but soon it became obvious that this was insufficient. Their customers wanted more.

Because tax rules are open to interpretation, some customers asked to be able to change the rules to their advantage. A different interpretation might save them millions in taxes. So they wanted their interpretations to be applied instead of TaxGlobe’s rules. As long as they could document how they calculated their tax and defend it to the tax authorities, they could save. A tax lawyer worth their salt would find an optimal set of interpretations that are legally sound and save money. Not only that, the larger companies picked the right combo of a shipping route and tax law interpretations to reduces overall taxes paid, similar to solving a traveling salesman problem. TaxGlobe’s interpretations were perfectly sensible, but not optimised for each customer’s individual situation. Still, support for multiple interpretations is an essential aspect of the domain of taxes.

Customizations

When TaxGlobe had their first big customer asking for different interpretations, they found that they could easily make some adjustments to the code (read: hacks) to handle these special interpretations.

However, the sales people caught on, and started using this easy customization feature to win over new customers. Sales used it as a small upsell, by charging extra for custom calculations. TaxGlobe started advertising customizability on their website, so even more customers asked for it. But every time developers added these custom changes, their code became more complex. A single hack doesn’t impact your design much, but they accumulate when you have a lot of them. The lead times for shipping a customization became increasingly longer, and after a while, the price charged for customizations was insufficient to cover the development cost.

Gradually, TaxGlobe added more solutions: code changes for specific customers, code changes for multiple customers, configuration options, and plugins.

Initially, it’s TaxGlobe writing these customizations, but that didn’t scale well. Customization requests got put onto the backlog, and important customers got priority over other customer requests.

So eventually, TaxGlobe built a small Domain-Specific Language (DSL) for some of the tax laws. This allowed customers to create their own interpretations of rules. It looked somewhat like a spreadsheet, and the customer-created code was stored in the database.

Technical Debt

Over time, TaxGlobe’s product acquired a lot of technical debt.

The product had multiple ways to deal with the varying interpretations of the tax law:

It was never very clear which rules overrode which other rules. The customers weren’t sure if their customizations were applied correctly. And customer support couldn’t answer how the rules were overridden either.

This complexity affected the code. For example, there was a massive class called TaxAuthority. For each transit point, you had to ask the TaxAuthority object for the right taxes. The getTaxes() method alone had 3000 lines of code. It was passed the locale and bill of goods, and would give you back objects that you then invoked to calculate the taxes.

It wasn’t just the TaxAuthority code that was hard to understand, but also all the tax algorithms, riddled with special cases and overrides. Only the person who wrote the tax calculation code could understand how things worked, and they couldn’t explain it to others.

Market Pressure

The original Unique Selling Point (USP) was that TaxGlobe could calculate port, shipping, and import taxes around the world.

But the major ERP behemoths started building competing products and using their market dominance to gain customers. So merely offering international tax calculations didn’t make TaxGlobe’s product that unique anymore. What does make TaxGlobe unique is its ability to support their customers’ different interpretations of the tax laws.

But thinking more strategically, TaxGlobe has an opportunity to move their USP from being a customisable Tax Calculation product, to being a Tax Law Interpretation product. This changes everything, from the product’s value proposition, to the design choices, to their mission statement. The shift needs to be profound: it can only happen if it happens simultaneously in engineering, in product, and in the business vision.

What’s special about this, is that the catalyst for this shift originates in engineering, rather than in product leadership. When experiencing market pressure, companies often only focus on increasing marketing efforts, and on differentiating on price, features, or services. Here, it’s a more fundamental pivot. This opportunity to pivot exists because engineering built some small affordances for interpreting tax.

If TaxGlobe’s product marketing or project management had been more controlling about what to build, there never would have been different interpretations, let alone something as technical as a DSL. But here, engineering built these solutions, and these in turn allowed the shift to emerge. The shift is serendipitous. The insights that come from engineering should be an integral part of the product design discourse.

We now have a classic challenge. The product’s new USP shifts to tax law interpretability. On the one hand, the current software design enables this shift, thanks to some of the features it already offers. On the other hand, the current design with its crippling technical debt prevents the company from driving this shift to its full potential:

Signals

So far, we’ve described:

We will now tell the story again, from a different angle. We’ll highlight each individual signal, that is, anything that an observant leader at TaxGlobe could have noticed. Each signal is insufficient to change course. And yet by the end, the cumulation of all signals shows that TaxGlobe should have changed course much earlier.

We invite you, our reader, to consider each signal below as if you were an architect or engineering leader at TaxGlobe.

You have the benefit of hindsight, because we already told you about the shift from Tax Calculation to Tax Law Interpretation. But as you read through these signals, try to consider how you would have reacted to each one, if these happened over a two-year period, and without knowing what comes next:

  1. A customer tells us one of our calculations is wrong. Our tax lawyer looks into it, and gets a developer to fix the bug.
  2. Another customer tells us that a calculation is wrong, but our tax lawyers believe it’s correct. The customer is a bit annoyed about it.
  3. Another customer asks us to “reinterpret” a calculation because they think the tax law could be interpreted differently, to their advantage.
  4. We add a few customer-specific interpretations of the tax law into the code, using a conditional to switch between the normal calculation and modified one. We’re using hardcoded customer IDs to do the branching.
  5. Sales catches on that we can do custom interpretations. They’re also aware that it’s pretty easy to branch on customer ID, so they use it in their sales pitch.
  6. As we get more of them, doing these customizations becomes harder. We need to be more careful about not breaking the regular flow. And the code becomes harder to understand.
  7. Management complains that we spend more and more time on each customization, and that lead time is becoming very unpredictable.
  8. Sales is still offering these customizations as a cheap upsell, but in reality, we lose money on them as the cost increases.
  9. The testers are finding it difficult to keep up with testing the customizations.
  10. We do a small refactor where a bit of code in our 3000 line getTaxes() method is extracted into a calculateRule12() method. Occasionally more of these small refactors happened, but there was never time to do major untangling of the code. If something worked, it was rarely refactored.
  11. As we expand into more countries, our own tax lawyers ask for more time to learn the intricacies of the country-specific tax rules. They now understand better how much a different interpretation of a rule can impact the total tax cost.
  12. Production for one of our major customers has moved to Brazil, so they want us to handle Brazil tax law in more depth than we do now. But we have difficulty recruiting tax law experts there, and our existing lawyers admit they underestimated the complexity of those laws.
  13. Eventually, one of the developers builds a small DSL that allows customers to change the interpretations of some of the rules in Brazil. Customers love it and ask us to make the DSL more powerful.
  14. Later, the customer asks for a similar DSL for their other locales.
  15. A customer requests a custom engineering effort: They want to recompute taxes for the prior year (based on their own interpretations of several tax rules). They’re willing to pay really good money for it, so we assume they expect to save a lot of money this way.
  16. Because sales now has learned that we can charge high prices for these large customizations, they are putting more focus on this and the tax savings it can bring.
  17. Engineers complain that the current design isn’t very nice to work with. They want to move to a new tech stack.
  18. There’s disagreement in TaxGlobe on whether we should go back to offering a single one-size-fits-all product (and potentially sacrificing a few large customers), or whether we should be fully focused on customized implementations. Right now, we get a lot of revenue from custom work, but we also provide a DSL. Both sides of the argument feel that this contradiction amounts to shooting ourselves in the foot. The DSL steals business from custom work, and custom work takes away focus on and incentive for building a truly powerful DSL.
  19. People in engineering are advocating that there should be “standard” rules, and rules that are open to customization, just so they can keep things straight.
  20. Customers are reporting more bugs. The support people have difficulty evaluating the bugs, because they don’t understand which rules are being applied at which time.
  21. The market leader for ERP releases a competing product called ShipTax3000. So far we’re not losing customers to them, as it doesn’t have the same amount of customizability. Still, they are gaining market share quickly because of their existing dominance.
  22. Some customers complain about the performance. It is taking longer to process tax calculations, especially if there are a lot of custom variations — even if that specific customer doesn’t use the variations.
  23. Customers are still willing to pay well for customized interpretations, but we can’t deliver them fast enough anymore. The customers are on a deadline to submit taxes, and they have no use for interpretations that are already outdated by the time they get them.
  24. The customers don’t just want us to hardcode their interpretations any more. What they want, is to be able to simulate the calculations with a different set of interpretations, and only if the interpretations save them money, they want to commit to them.

Recognizing Signals

The main idea here is to recognize and respond to signals. As a leader, part of your job is to notice signals, and have the right attitude towards them. Signals can be weak but important, or loud but irrelevant. Some can be frequent, but that doesn’t make them more important than infrequent ones. Everybody could be talking about them, or just a lone voice in your team trying to draw your attention.

On top of all these properties of the signals themselves, you have to deal with your own biases. You may be more attuned to signals in your area of expertise (say, database performance or customer experience) and less to signals outside of your skills (say, security, or developer happiness).

There’s also institutional bias: signals from customer support don’t often reach engineering management—after all, customer struggles are the support team’s daily environment, they don’t stand out. Similarly, signals that the engineers are struggling are often discounted. Engineers are always asking for more time and resources anyway, so when they do, managers may not treat them as important signals.

At the very least, it’s important to understand that all of these factors will impact how well you recognize signals. It’s up to you decide to take weak or intermittent signals seriously. You need to deliberately keep an attitude of being open to receiving signals.

You, in your environment, look at the world from within a box, from within a mental model. A lot of learning and noticing happens when you deliberately try to recognize your box and break out of it. As we discussed in “Critically Engaging with Models”, you need to actively look for alternative models, explore them, understand their underlying belief systems, and adapt their building blocks to your advantage.

Often individual signals don’t indicate an urgent need for a change. And yet at some point, it becomes overwhelmingly clear that you should have reacted much sooner. But there is rarely a clear switchover point; a single signal to cross the boundary from irrelevant to imperative. Our usual modus operandi is to react to the daily urgent signals, and to wait too long to react to the significant ones.

What Is a Signal?

So, what exactly is a signal? We have avoided formulating a precise definition, because any definition will exclude things that might be valuable signals. Intuitively, a signal is anything that is worth noticing, worth considering, and potentially worth reacting to. Sometimes it’s something that breaks out of the ordinary. But at other times, the fact that a regular pattern keeps repeating predictably, is a signal. Sometimes a huge incident is a blaring signal, but sometimes a small change in someone’s body language is a signal. And sometimes the lack of a signal is a signal in itself.

Imagine you’re in a meeting in which people are hesitant to volunteer to tackle some important technical work. Maybe the work is too complex. Or just really boring. Maybe they lack skills or knowledge? Maybe there’s a blame culture in your organization, and people feel they’d be blamed for a mistake. Or maybe it’s just Friday afternoon.

We can’t define signals because anything could be a signal. In this situation, it’s going to be your ability to notice, and your judgement to decide to act, that makes something important.

Signals Trigger Experiments

Looking for a magic switchover point is a mistake. Signals should trigger us to run experiments. For example, when someone says we should improve, say, the architecture of a component, we don’t have to jump into a costly and unpredictable refactoring project. Instead, we should run a quick experiment to learn how hard it would be to improve the component, if the proposed changes are feasible, and if they actually do improve the component. How frequently should you run experiments? All the time.

Experiments shouldn’t be rare occurrences. They should form the backbone for learning anything that can’t be googled.

If you don’t have the time or get the time, then make the time or take the time.

Experiments Are Not Projects

Too often, we treat experiments as small projects, with a purpose and an ideal end state. Projects come with the assumption that they must be completed and put in production. Instead, it should be perfectly acceptable that we stop the experiment, and that none of the changes make it to production. The goal of the experiment is to learn; treating them as projects with predictable outcomes gets in the way.

True experiments are liberating. A project comes with responsibilities, such as delivering it within time and budget, and meeting all standards of quality, security, performance, user experience, documentation, etc. An experiment that we plan to remove, doesn’t need any of those.

The only measure of its success is whether we learn anything. Removing those constraints lets us move faster, and try more experiments.

Experiments should not be open-ended. Stop when you’ve learned something. If what you’ve learned leads you to ask another question, start another experiment. We don’t even have to finish any experiment: as soon as we have learned enough, we can abandon it. If then, based on what we learned, we decide to move forward, we can redo the work to meet our quality standards. People may complain that it’s rework, but it’s much better than doing a large project and failing for lack of knowledge.

Reversible Experiments

Create an environment where you can learn from running many experiments. To do so, look for these properties:

Your Project Manager Thinks You’re Crazy

Run experiments where you don’t know the outcome. You have to challenge your own beliefs, and push yourself. If an experiment isn’t a little uncomfortable, isn’t challenging the status quo, isn’t shining a light on your blind spots, then you’re not learning.

Signals should frequently trigger experiments. Explore alternative designs early and regularly, and find ways to make small steps towards a better design. That kind of experimentation, without immediate results, may look like waste to us and to others. But in exchange for these small bits of “wasted” effort, you learn what works and what doesn’t, and what might be possible with more concerted effort. The most valuable artefact is not always changes in the system, but newly discovered knowledge.

Experiments can maximize the work not done. They prevent throwing resources at a doomed project.

You’ll face adversity. To an outside observer, all the supposed waste looks crazy. If that observer is a project manager, whose sworn duty is to deliver on time and on budget, everything that can’t be ticked off on a burndown chart, is a personal failure. Even as you experiment, make sure you keep putting agreed upon work into production regularly. Just keep in mind that the kind of experimentation and design work we are talking about here, is not easily explained in terms of incremental progress. When you’re in a company culture that only values visible progress, it’s better to keep talk of this work out of daily standup meetings, and out of regular ticket trackers. Instead, keep it amongst your design-minded colleagues. Be advised that doing anything in the dark is risky and can backfire. Do so sparingly. And work on building a culture where experiments can be done in the open!

The Loudest Customer

Here’s an example of using a signal to trigger a small experiment: One of the customers of the tax calculation product wanted us to build a particular change. They would ask us repeatedly, and they’d often add social proof: “All your customers would benefit highly from this feature”; “We talked to customer XYZ, they are also interested.” The customer was very vocal about it, which created a sense of urgency in TaxGlobe to build it. Still, a signal like that should trigger experiments, and those should be small and reversible. Building the feature the customer asked for, even as a minimal viable product (MVP), would be costly. But not all experiments need to involve building something. In this case, sending out a survey is an experiment that is a lot smaller than building an MVP. The results from the survey showed that no other customers whatsoever were really interested in the feature.

Customers are like baby birds: They’re in a nest, asking for food, and the loudest gets the most. You do want to feed them all, to ensure survival of your species (or your company). But you can’t expect them to be sophisticated designers that balance the needs of all your stakeholders.

We need to listen to more than just the loudest customers. And we can’t rely solely on input from our sales people either: they are strongly influenced by what the most vocal customers tell them. We need to listen across the spectrum of our customers, and have strategic discussions with them. It can be difficult, because you need to balance short term gains with a longer-term payoff.

Eat Your Own Dog Food

Here’s an example of responding to a signal by extending an experiment: One day, a customer needed another interpretation. The task was given to the developer who had originally written the DSL for the Brazilian tax rules. Instead of simply adding the custom rule in the rules database as they usually did, that developer extended the DSL with a new feature. Using the improved DSL, developers could write new interpretations that overrode existing rules. From the DSL, these overrides were generated and written to the rules database.

This experiment worked out nicely: it showed that it was possible to have the DSL act as a higher abstraction layer for specifying interpretations.

And then, the developer had another idea: Maybe we could use this DSL to generate all our standard tax calculation rules. As a second experiment, they wrote a few specifications for some of the simple tax rules in the DSL, just to see how that might work. It showed that we didn’t need to hardcode any rules, and that the entire system of rules could be written in the DSL. It was just an experiment. More experiments would be needed to decide whether it was worth it to actually rewrite all the standard rules into the DSL.

Poke the Fire, Make It Spark

Sometimes you don’t have any signals, or the ones you get aren’t telling you much. How do you get signals now?

Think of experiments as attempts at triggering signals. With an experiment, you’re poking the environment. You put energy into it, and you get signals back.

If you’re not getting enough signals from your customers, you can send out a survey as we did in the earlier example. The survey is a probe, and each response we get is a new signal. As with all signals, they require interpretation. And if we don’t get any response, that too is a signal. Perhaps it can be interpreted as “the customers don’t care,” or “the customers need to be reached via another channel,” or “the survey questions were not clear.” In any case, don’t jump to conclusions. Find another experiment.

Is it worth expanding the DSL? We can show the little DSL experiment to some of our own tax lawyers. If they respond enthusiastically, that’s a signal that it could be worth building. It’s not a strong enough signal, but enough to trigger a next experiment. For example, you could now show it to a customer’s lawyer. On the other hand, if they don’t get excited for the new feature, that’s another signal, but again it’s inconclusive. Maybe this is the kind of feature that needs education before tax lawyers can see its value. And when somebody uses the word “maybe” as we just did, then treat what comes next as a hypothesis that you could test.

You can poke at code as well. Doing a short little spike, trying to code something quick and dirty, is a great example of this. Even though you throw away your changes, it gives you signals: How feasible is this? Would long would it take? How hard would it be to make the necessary refactorings? Doing these mini spikes can give you new ideas.

Succeeding With Experiments

In summary, experiments:

These aren’t scientific experiments. We aren’t trying to create laboratory conditions. We don’t have a statistically relevant sample size. We’re not trying to prove a hypothesis. We’re just trying to learn something, generate new signals, and move on to the next experiment.

Experiments Are Not Enough

Experiments give you information. Is the shift needed, is that idea valid? Is it viable? How difficult will it be to achieve? Will customers welcome it? Will they need to be trained? Is your organization aware of the need of the major shift? Can you deliver it? Is the culture there?

Experiments are catalysts for larger changes. We use them to create the environment where big changes can happen. Without that experimentation, you’re doing this big, risky project in a vacuum of uncertainty. Running safe experiments is like insurance: it’s relatively cheap compared to the risk you take on when doing a remodel.

But experiments and iterative improvements alone won’t get you through a major redesign. Sometimes you need to tear down the walls, and remodel major parts of the system. You bring in the experts for this, from inside and outside of your organization: technologists, modelers, system designers, domain experts, along with some of your customers. For all these roles, get the most eager, open minded, and innovative people you can find.

Sketching a New Model

Now let’s make a sketch of our new model. It’s not meant to be complete, but to illustrate that it’s possible to design a better model. (It’s not essential for the remaining text, so feel free to skip this section).

The new model shouldn’t have long blocks of procedural code with hardcoded rules. Instead, it makes the building blocks explicit: rules, mappings, interpretations, locales, and calculations. These are all first-class concepts in the code, which could be implemented in a functional or object-oriented style. Whether an interpretation is provided by us or by the customer, they should use the same mechanism. There is little to no distinction between our interpretations and theirs, except for that fact that ours are the defaults. Pretty much everything would be overridable.

For example, a lot of the interpretation involves classifying goods into categories which are taxed at different rates. There are multiple categories a good could be classified under, so the new model provides a default mapping of goods to categories, and allows customers to change these. Instead of hardcoded classifications, the new model keeps this map in a database, and has a mechanism to override it.

The applicable taxes are based on the locale. Sometimes the tax rules of multiple authorities have a precedence order that they are applied in, and potentially a cap on the total tax amount. The value that remains, is the value that will be taxed by the next tax authority. Some tax authorities have the option of choosing between alternate rules for calculating the tax: for example, either a percentage of the value of a good, or a flat rate. So, by cleverly choosing which tax rule to apply for each authority, you can save money. Moving goods through different warehouses under different authorities also impacts your total tax. It’s a traveling salesman problem, you find the combination of locales and rules that yields the smallest cost.

There are more building blocks like these. They are organized by locale, but they’re also versioned: at least per year, but occasionally tax rules might change during the year. The customer changes could also be versioned, so that they can compare multiple sets of interpretations and choose the most advantageous one. They can even go back and recalculate historical tax submissions, to see how those would turn out using the current set of interpretations. This allows much for more experimentation by the customer.

From this sketch, we can tell that this new model is quite different from the old. It’s so different that it would be difficult to get there purely through incremental changes. Instead, new systems will need to be built, old ones will need to be taken down, and customers will need to be migrated.

Three Angles

It’s not sufficient to be able to come up with that better model. To make major shifts happen, you need buy-in. As engineers, we often falsely believe that if we have a better solution, people will automatically accept that solution. All we need to do is to explain it to them, and they’ll buy in to it.

Instead, three things need to happen:

  1. You’ll need to manage upwards, and get support from your managers. Whenever you observe a signal, use it to raise awareness. A rule of thumb in marketing is that people need seven contact points before making a buying decision. It’s the same for adopting changes: you can’t just raise an issue once and expect people to get it. Even when you get buy-in, you won’t be given space and authority right away. You have to carve these out for yourself. Take authority, and then demonstrate that you are using that authority responsibly.
  2. You’ll need to manage downwards as well. Inspire the people who will need to do the work, show them it’s valuable, and show them that they will get the support required to get it done. Find the people who are most eager to improve things. Manage them the way you want to be managed: give them a vision, trust, authority, resources, and time.
  3. Manage yourself. If you’re the one who understands what the new system remodel should be like, it’s your responsibility to get it there, even when others don’t acknowledge that. Be open to the fact that people may want to improve things differently than you would. Getting any improvement is better than holding out until you get the specific improvement you want. Treat other people’s ideas and opinions as important signals as well. Don’t shy away from large, ambitious initiatives, but do reduce the risk by running small experiments and chopping the work into smaller increments that you deliver. Managing yourself requires intellectual honesty: Am I doing this because I want to, or because it really is better?

Use new signals to get buy-in for your next experiment, and use the signals that your experiment generates to get buy-in for the design shift. Collect enough evidence for the technical viability, the value to the customer, your ability to explain to them how this feature gives them that value, your ability to educate the customers on using it successfully, and your own organisational capability to deliver all of that. Repeatedly bring increasingly strong evidence to your management to warm them up to bigger design initiatives. Simultaneously, use the signals to motivate the people who’ll do the work. The evidence is also for you: don’t filter evidence to confirm your idea, but allow evidence to change your mind.

Designers Need Agency

Start pushing for a shift in the design while others still think YAGNI (“You’re Not Going to Need It”).

Don’t defer every idea to product and marketing. You have an equally valid seat at the table.

As a software design leader, you need a sense of agency. A belief that you can change things, and that it will be worth it eventually, even though you’re doing it with no guarantee that you will come up with something. You cannot be a timid software design leader. Be curious. Be excited by new ideas and change. Your excitement and curiosity will rub off on people.

You can’t be complacent about your system design and the increasing complexity that is thrown upon it. Don’t settle for complaining about things not going the way they should. Don’t wait for permission. What’s really stopping you from acting? Be bold. Whatever your position, be a leader. Earn respect for your agency. If that doesn’t happen, (and personal circumstances afford it) move elsewhere.

Experiments can only teach you so much, and you’ll still have to make decisions based on incomplete knowledge. There’s going to be uncertainty. You need to start pushing before you know exactly what direction your design should go.

Whenever you push at something, there’s risk. But when you’ve been at the company long enough and have accomplished things, you’ve built up credibility. Perhaps more than you think. They’re not going to fire a skilled engineer or architect very easily. Credibility is leverage: use it to gain agency.

Make the Shift

Making lots of small design improvements has a generative quality: each iteration of the design enables new improvements faster, and these in turn make the next changes easier. It compounds. You get out of firefighting mode, and instead create space to do new things.

And yet, iterative design alone can’t always cut it. You need to come up with a fresh model. You need to make a shift that can’t be done incrementally. But that’s ok: you can build on this solid foundation of improvements and experiments.

When you need to make the decision to shift, you will never have 100% of the information. But you don’t need all the information, if you have created an environment that can deal with the challenges of a shift:

Now you push, and keep pushing. Your organization can now take on product design innovations that people couldn’t imagine doing before. Inspire them to go into that mode where fearless decisions get made.