The Unspoken Rules of Software Teams
The best team I ever worked on had terrible tooling, no formal process, and met half as often as every other team in the company. We shipped features faster and with fewer bugs than anyone else. The worst team I worked on had perfect Scrum ceremonies, comprehensive documentation, and daily standups that somehow made everyone less informed than when they started.
The Mythology of Process
There’s an entire industry built around the idea that teams fail because they lack the right process. Agile consultants will tell you that if you just do Scrum correctly, everything will work. DevOps evangelists promise that the right CI/CD pipeline will solve your problems. Tool vendors claim their collaboration platform will transform how you work.
They’re all selling a comfortable lie: that teamwork can be engineered through process and tools.
The truth is messier. Teams succeed or fail based on how well people understand each other, communicate context, and handle conflict. Process can support these things, but it can never replace them.
Communication Is About Context, Not Updates
Most teams confuse information sharing with communication. They have standups where everyone recites what they did yesterday. They write status updates that nobody reads. They fill Slack channels with notifications that drown out signal with noise.
Real communication is about transferring context. When I tell you I spent three hours debugging a race condition, that’s information. When I explain that our caching layer makes assumptions about write ordering that aren’t guaranteed by the database, and here’s how I proved it, that’s context.
Context is what lets you make good decisions when I’m not around. It’s what prevents you from reintroducing the bug I just fixed. It’s what allows you to build on my work instead of working around it.
The best teams I’ve worked on had a culture of over-explaining. Not in meetings, which are terrible for context transfer, but in pull requests, design documents, and chat threads. People took the time to explain their thinking, not just their conclusions.
Trust Develops Through Small Interactions
You can’t mandate trust. You can’t build it through team-building exercises or offsites. Trust accumulates through hundreds of small interactions where people demonstrate competence and reliability.
When you say you’ll review my code today and you actually do it, that builds trust. When you find a subtle bug in my change and explain why it matters, that builds trust. When you ask good questions in code review instead of just rubber-stamping approvals, that builds trust.
The inverse is also true. When deadlines slip without warning, when code reviews sit for days, when someone agrees in a meeting but works around the decision afterward, trust erodes. You can’t repair that erosion with a single grand gesture. It has to be rebuilt through consistent, reliable behavior over time.
Conflict Is Information
Most teams avoid conflict. They have “nice” cultures where nobody challenges anything directly. Disagreements get pushed into side conversations, passive-aggressive Slack messages, or quietly ignored until they explode into crisis.
This is a mistake. Conflict is information about misalignment. When two experienced engineers disagree about an architectural decision, that disagreement is telling you something important about tradeoffs, constraints, or assumptions that aren’t shared across the team.
The goal isn’t to eliminate conflict. It’s to make conflict productive. That means creating space for people to disagree openly without it becoming personal. It means treating technical disagreements as opportunities to surface hidden assumptions, not battles to be won.
Good teams have productive arguments all the time. Someone proposes an approach, another person explains why it won’t work, and they dig into the details until they’ve both learned something. Bad teams have superficial agreement followed by months of passive resistance.
Ownership Without Gatekeeping
Code ownership is paradoxical. Systems need owners who understand them deeply and care about their long-term health. But owners can become gatekeepers who slow down everyone else.
The best owners make their systems easy for others to contribute to. They write documentation that explains not just how things work, but why they work that way. They design APIs that make the right thing easy and the wrong thing hard. They review changes quickly and use them as teaching opportunities.
The worst owners treat their systems like fiefdoms. They hold context as a form of job security. They nitpick changes from outsiders while letting their own questionable decisions slide. They optimize for control instead of velocity.
A healthy team has strong owners who are trying to make themselves less necessary, not more essential.
Asynchronous By Default, Synchronous When Needed
Remote work revealed something many teams hadn’t realized: most meetings are just expensive status updates. When forced to work asynchronously, teams discovered they could communicate more effectively through documents, pull requests, and recorded demos.
But asynchronous communication has limits. Complex design decisions benefit from real-time discussion where people can build on each other’s ideas. Conflicts are easier to resolve when you can hear someone’s tone and see their reactions. Sometimes you need to hash something out on a whiteboard.
The skill is knowing which mode to use. Status updates, progress tracking, and simple decisions should be asynchronous. Complex problems, misalignments, and creative brainstorming often benefit from synchronous collaboration.
Teams that default to meetings waste enormous amounts of time. Teams that avoid meetings entirely miss opportunities for rapid iteration and conflict resolution. The balance matters.
Technical Decisions Are Social Decisions
Every architectural choice affects how the team works. Choosing microservices over a monolith isn’t just a technical decision about scalability. It’s a decision about how teams will coordinate, who will be on call, and how complex deployments will become.
Picking a programming language isn’t just about performance or expressiveness. It’s about who you can hire, how quickly new people can contribute, and what libraries you’ll have access to.
The best technical decisions account for the team’s actual capabilities and constraints. A brilliant architecture that requires expertise your team doesn’t have is a bad architecture. A simple solution that everyone understands beats an optimal solution that only one person can maintain.
This doesn’t mean dumbing things down. It means being realistic about learning curves, knowledge transfer, and the cost of complexity. The code will outlive any individual’s tenure on the team.
The Invisible Work That Holds Teams Together
Every team has people doing work that never shows up in velocity metrics. They answer questions in Slack. They help new hires get unstuck. They notice when someone’s struggling and offer to pair. They write documentation for the weird edge cases nobody else wants to think about.
This work is often invisible to management because it doesn’t map to tickets or story points. But without it, teams grind to a halt. New people stay lost longer. Knowledge stays siloed. Small problems become crises.
The healthiest teams recognize and value this work. They don’t just reward individual feature delivery. They acknowledge when someone unblocks three other engineers, even if they didn’t ship anything themselves.
What Actually Matters
After years of working on teams of various sizes, structures, and dysfunction levels, I’ve come to believe that most of what we obsess about doesn’t matter much.
The standup format doesn’t matter. Whether you use Jira or Linear doesn’t matter. Whether you estimate in story points or t-shirt sizes doesn’t matter.
What matters is whether people communicate context effectively. Whether they trust each other to do good work. Whether they can disagree productively. Whether they help each other succeed instead of optimizing for individual output.
You can have perfect process with none of these things and your team will struggle. You can have messy process with all of these things and your team will thrive.
Build the team. The rest is just scaffolding.