Look, I’ve been in this game long enough to know that most software disasters aren’t caused by bad code. They’re caused by the 47-minute Zoom call that happened three weeks before a single line was typed. The one where someone said, “Let’s circle back on the requirements,” and everyone nodded like dashboard bobbleheads. That conversation? That’s where the dysfunction planted its flag.

Engineering dysfunction isn’t a technology problem. It’s a people problem wearing a Jira hoodie. And until we start treating cultural rot with the same rigor we apply to a database migration, we’ll keep shipping garbage and calling it agile.
The Pre-Code Graveyard
Walk into any engineering org and you’ll find the same damn pattern. The project kicked off six months ago. The roadmap looked gorgeous. The kickoff meeting had snacks. But now, two sprints before launch, the team is paralyzed. The backend team hates the frontend team. The product manager is rewriting user stories at 10 p.m. And nobody can explain what “MVP” means anymore, because it’s changed twelve times.
You know what went wrong? Nothing happened during development. Everything went wrong before it. The code is just the corpse.
The Blame-Sharing Ceremony
Every organization has a ritual I call the Blame-Sharing Ceremony. It usually starts with a stakeholder saying, “We need to move fast.” What they mean is, “I already promised this to a customer, so your estimates are now my hostage.” The engineering manager, terrified of looking “not technical enough,” commits to a deadline that was pulled from a motivational poster. Then the senior dev, who saw this coming a mile away, says nothing because they’re busy updating their LinkedIn profile.
This is not a communication breakdown. It’s a cowardice pipeline. And the output is a codebase that smells like fear.
The Architecture Astronaut Landing
Then comes the architecture review. Someone who hasn’t written production code since the Obama administration slides into the meeting with a diagram that looks like a plate of spaghetti and says, “We should consider an event-driven microservices approach.” For a cron job. For a single script. That sends one email a week.
The team, now trapped in a sunk-cost fallacy, spends three weeks building infrastructure that will never scale because the product won’t survive long enough to need it. The dysfunction here isn’t the complexity. It’s the total detachment from business reality. Engineers love to build engines, but nobody asked if the car needs to move yet.

The Real Technical Debt Is Behavioral
We love to talk about technical debt like it’s some inevitable byproduct of speed. But most technical debt isn’t from rushing. It’s from deciding things badly when you had all the time in the world. Choosing a NoSQL database because it was trendy, not because you needed flexible schemas. Splitting into microservices because Netflix does it, not because your team of four can operate them. Writing an abstraction layer so generic it can “support any future use case”—and then never having a second use case.
Those decisions weren’t made in a coding frenzy. They were made in a conference room with a projector and too much confidence.
The “Yes” Culture Tax
One of the most expensive words in engineering is “yes.” Yes, we can add that feature. Yes, we can hit that date. Yes, we can support that edge case. Every “yes” without a corresponding “no” is a withdrawal from the team’s credibility account. Over time, you end up bankrupt. The product becomes a feature junkyard. The team burns out. And management wonders why velocity dropped.
It didn’t drop. It was never real to begin with. The estimates were fiction. The commitments were political theater. The dysfunction was hiding behind a burndown chart that lied as smoothly as a sales deck.
How to Smell the Fire Before the Smoke
The good news? This stuff is detectable. If you know what to sniff for, you can spot a doomed project before the repository is even created. Here’s my personal checklist of pre-code red flags:
- The requirements document is over 20 pages. Nobody read it. Everyone skimmed it and nodded. You’re building on quicksand.
- “We’ll figure out the details in the sprint.” Translation: we haven’t done the thinking, but we’re already late, so let’s pretend agility is the plan.
- No single person can describe the user’s problem in two sentences. If the problem isn’t sharp, the solution will be a blob. A very expensive blob.
- Estimates are given in hours, not days. That level of false precision means someone is trying to control something they don’t understand.
- The word “just” appears in every planning meeting. “We’ll just add a flag.” “We’ll just refactor that later.” “Just” is a four-letter word for “I don’t want to think about it.”
The Meeting That Should Have Been an Email (But Wasn’t)
Here’s a classic scenario. A stakeholder wants a “simple dashboard.” The product manager says, “Sure, we’ll scope it.” They call a meeting. In that meeting, someone mentions “real-time updates.” Another person says, “We should probably support mobile too.” By the end of the hour, the “simple dashboard” is now a cross-platform analytics suite with role-based access control. Nobody asked if the user actually needs any of that. Nobody asked what problem it solves. The scope expanded because people were in a room and felt they needed to contribute something.
This is how projects die before a line of code. The meeting wasn’t a planning session. It was a brainstorming epidemic. And the cure is someone saying, “Stop. What is the one thing that would make this useful?” That person? Usually not in the room.

Fixing It Before It’s Broken
So how do you kill dysfunction before it hatches? You don’t need a workshop or a framework. You need to act like an engineer even when you’re not in front of a keyboard.
First, make decisions reversible. If a choice can be undone easily, don’t spend two weeks debating it. Pick one and move. The real damage comes from locking yourself into a bad choice because you treated it like a permanent tattoo.
Second, ban vague nouns. “Performance,” “scalability,” “quality”—these mean nothing without a number. If someone says, “We need it to be fast,” ask: “What is the acceptable response time under what load?” If they can’t answer, they don’t know what they want. Don’t build it yet.
Third, reward the person who kills bad ideas early. Most cultures celebrate the hero who ships a messy feature on time. Celebrate the person who says, “This feature doesn’t make sense,” in week one. That person saved you months of pain. Buy them a coffee. Give them a raise.
Writing Code Is the Last Resort
I’ve come to believe that writing code should be a last resort, not a first reflex. If you can solve the problem with a conversation, a configuration change, or by simply deciding not to do something, do that. The best engineering I’ve ever done involved deleting requirements, not implementing them. That’s not laziness. It’s discipline.
When you treat code as precious, you treat the decisions around it as critical. And you make sure those decisions aren’t made by a room full of people who are afraid to sound stupid.
FAQ
Why do teams keep falling into these pre-code traps even with experienced engineers?
Because experience doesn’t inoculate you against social pressure. It’s easier to nod along in a meeting than to be the one who says, “This doesn’t make sense.” That takes emotional energy, and most people run out of it by 2 p.m.
What’s the single biggest predictor of project failure before coding starts?
Ambiguous ownership. If you can’t name the one person who will be dragged out of bed at 3 a.m. when the thing breaks, you don’t have a team. You have a committee. And committees don’t ship, they socialize.
Can this cultural dysfunction be fixed from the bottom up, or does it require leadership buy-in?
Leadership buy-in accelerates everything, but bottom-up change is possible if you’re stubborn. Start with your own projects. Ask obnoxiously clear questions in planning meetings. Refuse to estimate until you understand the problem. People will either follow you or get out of the way. Either outcome is progress.