"Bring me solutions, not problems"
There’s a classic piece of advice for managing upwards: “bring solutions, not problems.” The simple explanation is that your manager hired you to solve their problems, so if you’re just bringing their problems back to them then you aren’t providing any value. Instead, value comes from you spending energy thinking deeply about their problems and identifying a handful of solutions along with a recommendation. That lets them think about three options rather than having to reason through a potentially infinite greenfield, and spares them from context-switching into your problem space. Like all good advice (for example, “don’t reinvent the wheel”), I both theoretically agree with it and practically hate it.
My primary complaint is that it misses the importance of context, and I wish it was instead phrased as “bring me context and then your solutions, not problems.” Context is hard to define because everything is context and yet most context doesn’t matter. Some irrelevant context for this post is that I forgot to eat breakfast this morning. Does that help your understanding of my writing? Probably not. On the other hand, all of your implicit requirements are highly relevant context. When someone brings a solution without the context I am immediately distrustful. Yes, they brought me a solution. But is it the right solution? Context typically is what will differentiate the two.
Suppose you are making a new frontend. What language should you write the server in? Engineers have argued for a millennia about this, but for most software engineers literally none of those arguments matter. What is the rest of your codebase written in? What languages do the other software engineers know? Will this server have substantial code in common with other servers in your organization? Those are all relevant context. When everything else is Python and someone brings me a solution starting with “hey I’m going to write a Typescript server because Fast seems like a nice framework and it can do what we need to do” I will immediately worry that they’ve forgotten where they work and have become a cowboy. Why are they focusing on language when it’s the least important thing? On the other hand, if someone gives me the context and a solution it can build tremendous credibility. “Everything here is in Python, but this new server will never have code in common with that existing code, we use Bazel so we can build Typescript fairly trivially, we need a reactive client but also want to pull latency down as much as possible so server-side rendering is attractive, and we’ve chosen to avoid tests but rely on static type-checking and Python’s type-checking is (at best) unreliable. Therefor we should make a new Typescript server.” Many of these, for example the ability of the build system to handle Typescript, aren’t requirements (imagine the bullet point: “requirement 3: the code builds”) but it’s a fundamental part of the decision for whether to do this. In the end, I signed off on it.
There are a million decisions like this. Suppose you’re making an API for developers to call into, should you have them authenticate with API keys? It’s what every SaaS company offers so it must be good, and yet anyone who comes to me with that solution will immediately be branded with an A (for apostate.) What credentials do the clients already have? Are they Kubernetes pods, in which case you can use a JWT-based pod-identity? Are they humans in a large corporation, where they might have their own OIDC provider that we could integrate with? Even if someone comes to me with that context and solution (“our users are humans so we’ll offer per-customer OIDC”), which I love and would be over-the-moon to see a junior engineer come up with, is allowing one OIDC provider the right solution? It depends. Can we foresee a case where we need to accept both their human OIDC credentials and calls coming from pods in the Kubernetes clusters? That’s context but it drives the requirement that we need to support multiple OIDC providers per customer. And if someone tells me that all of our users are academics and they’ll never accept anything more complicated than an API key, which would break my heart and everything I stand for, I would accept it without protest because it’s clear they thought about the alternatives.
Providing your context can also help others identify gaps in your understanding. Every once in a while someone proposes a solution that is completely, wildly wrong. Is it because they’re bad engineers? Absolutely not. Typically it’s because they understand the written requirements (eg build a service that allows users to create and destroy resources) but miss some context (we must require authentication on this service because we plan to open it up to the public in the future.) From a managerial perspective I can course correct people’s solutions one at a time (no, do X not Y), but it’s far more effective to shape the context they think in.
Circling back, even a decision to reinvent the wheel can be very reasonable in the right context. At a previous company (four engineers!), we wrote our own federated OIDC provider and swapped oauth2-proxy for an in-house alternative, wrote our own (simpler) versions of Ray and Runhouse, had our own Bazel rules for building Podman containers, and a whole host of other bespoke nonsense. It sounds insane without the context, but knowing the context I would passionately argue for all of them. That’s the power of context. A good solution without context may be indistinguishable from a bad solution, but when you put it in context the difference is stark.