"Who designed this mess?" Every engineer has asked it. You open a pull request and see a strange workaround, or you look at an old service and wonder why anyone would split the logic that way, or you find a deployment process with three manual steps and a warning in the README that says do not run this on Fridays. The question feels earned. Hiding inside it is one of the easiest mistakes in engineering, which is the assumption that the person before you should have known better.
Sometimes that reaction is fair, and the design is bad, the code is careless, and the process is a pile of fear and habit wearing a thin coat of documentation. But a lot of the time, the thing you're looking at isn't stupidity. It's context you don't have.
Get past your own ego first
That sounds harsher than I mean it, but I think it's true. A lot of bad technical judgment starts with the quiet assumption that we know better. We look at the old decision and assume the answer is obvious because it's obvious from where we're standing. Fresh eyes catch plenty, and they still catch only part of the picture, so you can be right about the better design and wrong about the path that got the system here.
Getting past your ego still leaves room to call bad work bad. You're admitting that your first reaction is probably under-informed, and swapping "why did they do something so obviously wrong?" for "what context am I missing?" That second question has saved me from being confidently wrong more times than I like to admit.
The code did not get better, the context got wider
Every experienced engineer has lived some version of this. Someone reviews your code and asks why you didn't use the obvious pattern, and from where they're standing they have a point, because the code does look awkward. Then you explain that the obvious pattern breaks a customer workflow that was promised six months ago, or that the clean solution would have meant touching a service nobody owns anymore, or that the last production incident came from exactly the kind of change they're recommending. Suddenly the obvious answer isn't so obvious. The code didn't get any better. The context got wider.
Technical decisions happen inside deadlines, org charts, and half-finished migrations, and by the time you see the code most of that history is gone. You see the workaround without the incident that created it. You see the coupling without the customer contract that made it unavoidable at the time, and the manual process without the failed automation attempt that quietly burned the team six months earlier.
Separate judgment from diagnosis
A lot of engineering conversations fail right there. Someone walks in with fresh eyes, which is valuable, and mistakes them for complete vision. They see the local mess and assume the people closest to it were careless, the people who built the system get defensive because they know the history, and both sides stop learning.
The healthier move is to separate judgment from diagnosis. You can say a design is creating operational risk and still ask what made it look like the right call when it was built. You can say a deployment process needs automation and still ask what broke the last time someone tried. Once you understand the context you can fix the actual problem instead of attacking the symptom, and that is engineering discipline, however soft it looks from the outside.
If a system has a strange workaround for an undocumented vendor behavior, ripping out the workaround before you understand the behavior is vandalism with good intentions. If a team keeps a manual release checklist because rollback is unreliable, yelling about automation misses the point, since the better fix may start with rollback discipline, artifact promotion, environment parity, and smaller releases. Most architecture problems are ownership problems. When a service has unclear ownership because three teams depend on it and none of them fund it, rewriting the service won't change who owns it.
Context over shoes
Context belongs to the system as much as the code does, and it's the reason I find "walk a mile in my context" more useful than "walk a mile in my shoes." The shoe version is about empathy, and empathy matters, but in engineering it tends to stay vague. The context version is operational. It asks what constraints shaped the decision, what information was missing, and what pain the team was trying to avoid.
So before criticizing a design, find out what the author was working with. Ask what was on fire, who owned the system, and which deadline was real. Ask what rollback looked like and what customer commitment had already been made. You may still decide the design is wrong, and sometimes you'll be right, but you'll be wrong less often about why.
The why determines the fix
The why matters because it decides the fix. If the problem was deadline pressure, coaching the engineer who took the shortcut won't do much, and the fix is planning and scope control. Missing ownership needs a clearer service boundary. Fear of production needs better rollback and smaller changes, and incomplete context might need nothing more elaborate than decision records and more honest conversations between teams.
When we skip the context, we reach for the generic answers, like adding tests or moving it to the platform, and those can be good ideas that still miss why the system is broken.
Production reveals the context people left out
This is a big part of why I care so much about production systems, because production shows you the context people left out. The architecture diagram says the service depends on two downstream systems, and production says it depends on six, plus a nightly file and a customer-specific configuration nobody remembers. The sprint plan says the feature is done, and then support can't figure out how to troubleshoot it. The pull request says the code is clean, and the first bad deploy shows that nobody thought about rollback. The pipeline goes green, and the team still won't deploy without Sarah on the call.
Prompt engineering without context engineering
The AI conversation has gotten interesting to me for the same reason. A lot of people talk about prompt engineering as if the magic is mostly in the phrasing, the verbs and the structure and the examples. However good the phrasing is, prompt engineering without context engineering is just asking a capable system to guess well.
A model has the same basic problem people do, since it can only reason from the context it has. Give it a narrow slice of the world and it will optimize inside that slice, sometimes beautifully and sometimes with a clean, confident answer that is completely wrong for the actual situation, because the rest of the world never made it into the conversation. Engineers work the same way. Hand one only the code and they'll optimize the code, but hand them the incident history and the customer promises and they may make the opposite call.
Know which context actually matters
None of this means everyone needs every detail all the time. Teams can drown in context just as easily as they starve for it, and the skill is knowing which context matters for the decision in front of you. A formatting change doesn't need a history lesson, and a database migration probably does. A feature flag cleanup may need to know which customers are still on the old path. A rollback plan has to know what happens to in-flight messages and downstream consumers, and a refactor in a quiet utility library carries far less history than one in the middle of a production incident.
Context transfer is the job, on both sides of the review
That instinct helps on both sides of a review. When you're reviewing someone else's work, ask what you're missing before you assume the worst. When you're submitting it, give the reviewer enough that they don't have to reconstruct your world from a diff. A good pull request explains why the change looks the way it does, what was considered and rejected, and what the rollback path is if it goes wrong. Writing that down takes a few minutes, and it carries the context the diff can't.
A deployment pipeline is an organizational contract, and a pull request is a smaller one. It's a handoff between people who don't share the same history, and when the handoff lacks context the review turns into guesswork, sometimes too harsh and sometimes too generous. Nobody needs every engineer writing a novel for every change, but the diff rarely tells the whole story.
Put the memory in the system
The same thing applies at the system level, where architecture decisions need a memory. That means enough written context that the next team doesn't have to rediscover the same constraints by breaking production, which is a much smaller pile than the endless documents nobody reads. Why did we choose this queue? Why is this service still on the old runtime? Why is this one customer handled differently? Why does this API return that weird shape? If the only answer is "ask Dave," the system has already lost part of its memory.
That's how organizations end up with fragile systems protected by tribal knowledge. The context exists, but it lives in people instead of the system, and those people turn into required infrastructure. Dave can't take a vacation, and nobody else can safely change what only Dave can explain.
Where humility and responsibility meet
This is where humility and responsibility meet. Humility says I may not understand why this is the way it is, and responsibility says that once I do understand it, I'm not allowed to leave the system stuck there forever. Without the first you break things and call it improvement, and without the second you keep broken things around and call it respect for history. The better path is to learn the context, name the constraint, and then decide whether the constraint still deserves to exist.
Sometimes it does.
A workaround for a vendor limitation may still be necessary, and a manual approval on a high-risk data migration may still be appropriate. But sometimes the original constraint expired years ago and nobody noticed, because the customer moved or the vendor changed, and the manual process exists only because it always has. That's when context becomes a tool for removal. You take the workaround out once you understand the reason and can prove it no longer applies, ideally with the vendor's changelog or the customer's migration date sitting right there in the pull request.
Walk a mile, then fix what is still broken
I want engineers to be opinionated. I want them to challenge bad systems and call out fragile deploys, unclear ownership, and processes that only work when the right person is online, but I want that judgment grounded in context. Smart, motivated, and under-informed is the fastest way I know to become dangerous. The same engineer, curious about the constraints that shaped the system before they got there, becomes useful quickly, and that curiosity doesn't take forever, just enough time to avoid solving the wrong problem with confidence.
Most bad engineering decisions come from engineers working with incomplete context, under pressure, inside systems that hide the consequences until later. So the next time you catch yourself asking who designed this mess, treat it as a question you owe an answer. Find out what the author was up against, and then fix whatever is still broken, starting with that warning in the README about Fridays.
Frequently asked questions
What does “walk a mile in my context” mean?
- It is an operational version of walk a mile in my shoes. The shoe version is about empathy, which matters but tends to stay vague. The context version asks what constraints shaped a decision, what information was missing, and what pain the team was trying to avoid, so you can reconstruct the world the author was working in before you criticize the design.
Isn't a fresh perspective valuable?
- Yes, but fresh eyes see only part of the picture. A new perspective often spots real problems and just as often underestimates why those problems exist. The failure is seeing a local mess and assuming the people closest to it were careless. Keep the fresh judgment and pair it with one question: what context am I missing?
Does understanding context mean preserving bad systems?
- No. There is always a reason a system ended up the way it did, and bad reasons are still reasons, but knowing the reason is a long way from agreeing with it. You can't fix a system honestly until you understand what it was protecting itself from. Sometimes that reason still holds, and sometimes it expired years ago and nobody noticed, which is when context becomes a tool for removal.
What does this have to do with AI and prompt engineering?
- A model has the same basic problem a person does, because it can only reason from the context it has. Prompt engineering without context engineering is just asking a capable system to guess well. Give it a narrow slice of the world and it will optimize inside that slice, sometimes beautifully and sometimes with a confident answer that is wrong for the actual situation.
How should this change the way I write a pull request?
- Explain why the change looks the way it does, what was considered and rejected, and what the risk and rollback path are. A pull request is a handoff between people who don't share the same history, and without that context the review turns into guesswork, sometimes too harsh and sometimes too generous.
How do you know when a workaround is safe to remove?
- Learn the context, name the constraint, and prove it no longer applies. A workaround for a vendor limitation may still be necessary, and a manual approval on a high-risk migration may still be appropriate. Customers move, vendors change, and teams reorganize, though, so a reason that once held can quietly expire. Cleanup means you can show the original reason is gone; deleting the workaround on sight is wishful thinking.
