Monday, February 24, 2025

The Sprint Retrospective Is Dead

Every two weeks, teams gather to perform a ritual. Someone opens the board. Three columns appear: what went well, what didn't, action items. Everyone says something polite. The action items are written down. Nobody ever looks at them again.

The sprint retrospective isn't a practice anymore. It's theater. And we all know it.

I'm not against reflection — I'm against the performance of reflection. There's a difference, and most teams are doing the second one. The evidence is everywhere: the same complaints sprint after sprint, the action items that age like milk in the backlog, the facilitator asking "anyone else?" into silence while everyone stares at their cameras.

Why did this happen? A few reasons, and none of them are anyone's fault, exactly.

First: psychological safety became a slogan instead of a practice. Every company says they want honest feedback. But the retro happens in front of the same manager who does performance reviews, and everyone in the room can do that math. So people share the safe complaints — "too many meetings," "unclear requirements" — and keep the real ones — "our tech lead doesn't listen," "this deadline was fantasy" — for the group chat. The retro gets the press-release version of the truth.

Second: the action items have no teeth. "Improve communication" is not an action item; it's a wish. Real action items have an owner, a deadline, and a way to verify they happened. Most retro action items have none of these, because assigning them would require someone to actually change something, and changing things is uncomfortable. So the board fills up with good intentions and the team learns, correctly, that nothing said in a retro matters.

Third: the cadence is wrong. Two weeks is simultaneously too often and too rare. Too often for anything meaningful to have changed — you're just re-litigating the same sprint. Too rare for the things that actually need reflection, which are usually specific moments: the deploy that went sideways, the decision made in a hurry, the week the team worked nights. By the time the retro rolls around, the moment has cooled and the learning has evaporated.

So what does honest reflection actually look like? In my experience, it's smaller, more specific, and less comfortable.

It looks like a fifteen-minute conversation right after something happens, not a scheduled ceremony two weeks later. "That deploy was rough. What did we miss?" — while everyone still remembers.

It looks like the manager going first. Not "what could the team do better" but "here's what I got wrong." The fastest way to make a retro honest is for the person with the most power in the room to demonstrate that honesty doesn't get punished. Everything else is decoration.

It looks like fewer, harder action items. One thing, with a name attached and a date. If you can't name who's doing it and when it's due, it's not an action item — it's a feeling.

And sometimes it looks like admitting the format isn't working and trying something else. A written retro. A one-on-one. A "what should we stop doing" session with no "start doing" allowed. The format is not sacred. The honesty is.

I'm not saying kill the retrospective. I'm saying kill the ritual — the empty performance of a practice that used to mean something. The teams that reflect honestly don't need a template. The teams with a template usually aren't reflecting.

The retro is dead. Long live actually talking to each other.

Monday, February 10, 2025

Your AI Wrote That Code. Who Reviewed It?

Somewhere in your organization, right now, a developer is shipping code they didn't write. Not copied from a forum — generated, in seconds, by an AI assistant that read the comment they typed and produced forty lines of working code.

This isn't a prediction. It's Tuesday. The assistants are everywhere: in the IDE, in the pull request, in the terminal. Developers love them, and honestly, for good reason. The boilerplate, the test scaffolding, the "I know what I want but not the exact syntax" moments — the machines are genuinely good at this. Velocity is up. Morale, in a lot of places, is up too.

Here's the part nobody planned for: the review bottleneck.

Code review was already the scarcest resource in most engineering orgs. Now we're generating code faster than ever, and the review capacity didn't change. Every team just quietly widened the gap between "code produced" and "code actually understood by a human." That gap has a name, and the name is risk.

And AI-generated code has a particular flavor of risk that's worth understanding. It's not that the code is bad — most of it compiles, most of it passes tests. It's that it's plausible in a way that resists review. A human junior developer writes code with tells: the awkward variable names, the over-complicated loop, the comment that doesn't quite match. You can see the thinking, including the flawed thinking. AI-generated code has no tells. It's smooth. It's confident. It's wrong in ways that look exactly like being right.

There's also the training-data problem. These models learned from the entire history of public code, which includes the entire history of public mistakes. The injection patterns of a decade ago. The crypto implementations that were state of the art years back and deprecated since. The model doesn't know what year it is. It knows what was common. "Common" and "secure" have never been the same thing.

So what's the answer? It's not banning the tools — that ship sailed, and besides, your developers are using them on their personal machines anyway. It's not blind trust either, which is just outsourcing your judgment to a statistical model trained on the public internet.

The answer is treating AI-generated code as what it is: code from a very fast, very confident junior developer who has read everything and understood nothing. You'd never let a junior's pull request merge without review. Don't let the machine's merge without review either.

Practically, that means a few things. First, the review process has to acknowledge the volume. If your team generates twice the code, "just review harder" isn't a plan. You need to be deliberate about where human review goes: authentication flows, authorization logic, data handling, crypto, anything touching money or personal data. Let the linters and the scanners have the boilerplate. Spend the humans on the blast radius.

Second, threat-model the generated code specifically. When a human writes auth logic, you review their decisions. When a machine writes it, there were no decisions — there was pattern completion. Review it accordingly. Ask "what assumption is baked in here?" instead of "what was the author thinking?" The author wasn't thinking. That's the point.

Third — and this one matters — keep humans writing the critical stuff. Not because humans are better at it (often they're not), but because the act of writing is the act of understanding. The developer who hand-writes the auth flow can debug it at 3 AM. The developer who accepted the suggestion can read it. Maybe. The understanding gap is the real vulnerability, and it compounds.

The teams that get this right won't be the ones that generate the most code. They'll be the ones that kept their judgment while everyone else automated theirs.

Your AI wrote that code. Make sure somebody — a person, with context and accountability — actually reviewed it.