This is a follow-up to two earlier pieces: Why This Time Is Different: Following the Chain of Consequences and Learning to Build Without a Ladder.
In the first one, I listed the assumptions that let the tech industry recover from past downturns. The last one was the easiest to miss: there was a way in. Someone outside the industry could still reach a person who would let them in, and open source was one of the places where that still worked. I wrote about how automated gates on both sides are closing that door.
This week I found an example that shows the door can close without any automation at all. A person closed it, with a quick look and one word. Human judgment is still one of the biggest gates in front of people who already have the skills, and a quick human check can fail in exactly the same way an automated filter does.
So I want to follow this one the same way I followed the chain in that article: one link at a time, looking at what each step actually cost.
I'm not naming the project or the people involved. Its maintainers do real, careful work, much of it for the public good, and nothing here is meant as a pile-on. I'll call the project SkyRelay. It's an open-source network of volunteer satellite ground stations, the kind of project I love, and one I was seriously considering contributing to.
What happened
At the end of February 2026, a contributor opened a merge request to speed up one of SkyRelay's busiest pages. The page was slow to load, and the change went after the reasons why.
A maintainer marked it as a draft. The comment said that a quick check showed signs the merge request was AI-produced, and that it was being set aside "in order to avoid spending review time for AI nonsense."
To be fair to the maintainer, the comment didn't stop there. It apologized in case the guess was wrong, and asked for three things: describe the planned optimization on the related issue, make sure nothing that already works stops working, and run the pipeline checks locally first.
The next day, the contributor closed the merge request. They also closed a second, much smaller fix they had opened the same day, which nobody had raised any concern about. They haven't opened another merge request in the project since.
What was actually in the change
I wanted to know whether the label fit, so I went through the diff file by file with my AI assistant.
It was a real fix for a real problem. The page got its data from a list of satellites that made a separate database query for every single satellite, just to check one flag. The change replaced those thousands of queries with one. It also changed a large table so it loaded its rows on demand, instead of building every row into the page up front.
It also had noise around it, the kind that needs tidying before anything is merged:
- A code style rule was switched off, instead of the new code being changed to follow it.
- A few package lock entries appeared that had nothing to do with the change.
- The pipeline failed.
- It changed how the page loads without that approach being agreed on the issue first.
All of that deserves a review comment. None of it is unusual. It's what a merge request looks like when someone is working fast, on their own machine, without asking first. A reviewer could reasonably have said "this needs work before it can be merged." That is a very different sentence from "this is nonsense."
Then I found something I hadn't expected. This wasn't a newcomer at all. The same person had more than twenty merged contributions across the project's organization a few years earlier, including an earlier speed-up of this very page. A quick check didn't show that. Only a closer look did.
Mine had signs too
I recognized that merge request, because I've sent one like it.
That same week, I was finishing a documentation contribution to GitLab. I was teaching myself Git from the command line, and I was working on three issues at the same time. Changes from my other issues kept slipping into the merge request. I couldn't see it from the terminal. It only showed up in the merge request's diff, after I had already pushed. It happened three pushes in a row.
On top of that, my editor, Zed, quietly reformatted lines I had never touched whenever I saved a documentation file. I didn't see that coming at all, and I had to work out on my own where the extra changes were coming from.
From a quick check, my merge request had signs too: unrelated files, formatting churn, a messy history. My reviewer looked past them. He stayed kind and waited for my final version, even though I could tell his patience was wearing thin, and I don't blame him for that. In the end I closed the merge request myself and opened a brand-new one with only the change I meant to make. It was merged a few days later and shipped in GitLab 18.10.
The only real difference between my story and the SkyRelay contributor's is what the reviewer did with the signs. Mine read them as a person still learning. Theirs read them as a reason to stop reading.
When the door stays open
A few weeks later, I had the opposite experience, in a much harder spot.
I was adding Kroki support to the GitLab Terraform provider, so teams who manage GitLab as code could switch on diagram rendering in their configuration instead of by hand. The provider is written in Go, a language I was still finding my feet in, and it took me three merge requests to get it right.
The hardest part wasn't the code. My laptop at the time had 8 GB of RAM. Docker crashed it, WSL wouldn't start, and the project expects its documentation to be regenerated by a tool, not written by hand. I tried writing the docs manually anyway, and the pipeline kept failing, as it should.
So I said exactly that, in the merge request. I explained my machine's limits, said I believed the implementation itself was complete, and asked whether someone could run the generation step for me or suggest another way.
They did both. One maintainer explained that the docs step didn't need Docker at all, and pointed me to the command contributors are meant to run before opening a merge request. Another ran it for me, pushed the result, and suggested a remote development environment for next time. Later, when my diffs looked odd, they asked me to run Go's formatter, because my tabs and spaces were mixed up. Formatting again!
With that help, I fixed a state drift problem that the acceptance tests showed, added a small safety check I noticed along the way, and traced the last pipeline failure to a mismatched file name in the CI setup rather than my change. In April 2026 it went onto the merge train and was merged. The request for that feature had been open for more than two years.
I was so happy that I drew Kroki as a little crocodile riding the merge train, and shared it in the thread. Both of my Kroki drawings are in my writeup of the contribution. And someone who had been waiting for the feature thanked me for my persistence and said they were looking forward to the release. I still smile about that.
Nothing about that merge request was tidy. It took three attempts, it had a failing pipeline and mixed-up formatting, and I said openly that I couldn't run the project's own tooling. From a quick check, it had more signs than either of the other merge requests in this article. What it also had was transparency in both directions: I was honest about my limits, and the maintainers were honest about what I needed to do. That's all it took.
That is the nature of this work. Technology moves fast, tools change, environments fail, and troubleshooting takes time, whether you started last month or twenty years ago. Most of software engineering is exactly this: troubleshooting, debugging, and trying again. A messy merge request isn't evidence that someone doesn't belong. It's evidence that they're doing the job.
And a reviewer can't see who is on the other side of a merge request. It might be a newcomer, someone with years of history in the project, someone on an 8 GB laptop, or someone learning a new language or a new tool. That's exactly why the change is the right thing to look at. Nothing about what happened in SkyRelay was personal to the contributor. The label is what made it personal.
The same chain, in one merge request
Here is how I see the steps link together.
A quick check stands in for a review. Maintainers are flooded, and a fast filter feels like self-defense. But a quick check is a classifier, and like any classifier it has false positives. The signs it looks for (noise, unrelated files, a failing pipeline) are exactly the signs of someone learning, someone in a hurry, someone on limited hardware, or someone whose tools did something they didn't expect.
The label lands on the person, not the change. "This needs work" tells you what to fix. "AI nonsense" tells you what someone thinks of you. Only the first one gives you anything to act on.
The person leaves, quietly. Nobody argued and nobody complained. The merge request was simply closed, and nothing anywhere records that a working fix walked out the door. In the first article I called this Link 6: failure goes quiet. It's the same silence, just in a review thread instead of on a dashboard.
The problem stays, and costs more later. In October 2026, seven months on, another maintainer opened a new merge request for the same page's slow loading. It's careful, well-measured work, and I'm glad it's happening. One of the causes it names is that same per-satellite query, and the part it doesn't cover yet is listed as a follow-up, measured at over nine seconds on production-sized data. The closed merge request had already offered an answer to that query. A review would have been a chance to learn from it, or to explain why it didn't fit. That's Link 7: the correction comes late, and it costs more.
The way in narrows. Every newcomer who reads that thread learns something before they write a single line: the first response here might be a label. I know, because I read it, and I decided not to contribute. That's assumption F failing, one person at a time.
Notice that no step in this chain needed bad intentions. Each one makes sense on its own. That's exactly why it's worth writing down.
"No capacity" is a complete answer
I understand where maintainers are. Many of them work unpaid, or look after far more code than any one person should. Reviewing a large change properly takes real time, and nobody is owed that time.
So here is what I'd ask for instead, and it's small: if there isn't capacity to review, say that. It's honest, it's kind, and it's a complete answer. Something like:
We don't have review capacity for a change this size right now. Could you describe the plan on the issue first, so we can agree on the approach before you spend more time on it?
That reply takes the same few seconds as a label. It keeps the person, keeps the fix, and keeps the door open. And the second half of the SkyRelay comment was already most of the way there. If those three requests had been the whole comment, I don't think this article would exist.
Since then, SkyRelay has published an AI policy for contributors. It says plainly that the project can't police how a merge request was written, so it doesn't try. It allows AI-assisted contributions, as long as a person understands the change and takes full responsibility for it, and it's firm about repeated low-quality submissions, which is fair. I think that's the right answer. It moves the question from "how was this written?" to "do you understand it, and do you stand behind it?", and the second question is one a person can actually answer. A first response built on that question would have gone very differently.
What a review gives that a label can't
In Learning to Build Without a Ladder, I wrote that open source still works as an apprenticeship. You send something small, someone reviews it and tells you plainly what is wrong, and you improve. For a lot of us, that loop is how we became engineers after the junior roles disappeared.
A label skips the one step that makes the loop work. A review tells you the truth about your code. A label tells you someone's guess about you.
For people who learn the way I do, self-taught, neurodivergent, building our own apprenticeship in public, early merge requests are often noisy. That noise is what learning looks like from the outside. If the first response to it is a label, the people who most need that apprenticeship are the first ones it turns away.
I also wrote that judgment is the skill that matters now: can a person understand, test, and improve what a tool produced. I still believe that, and I've realized it applies to reviewers as much as to contributors. What a reviewer can answer is whether the change works, and whether the person behind it can explain it. Whether a tool was involved is something nobody can see from a diff, and it was never the most useful question to ask.
Closing
I build my work around one line: software should never fail a person in silence. A merge request closed under a label is a quiet failure of exactly that kind. Nobody sees an error message. A person just stops coming back, and the problem they solved waits seven months for someone else.
I've seen both sides of that door this year. When a maintainer reads the change and asks what the person needs, a feature people waited two years for gets merged. When a label comes first, a working fix walks away.
Reviewing the change instead of the person isn't glamorous, and it isn't free. But it's the cheapest way I know to keep the door open, for the next contributor, and for the people who will look after these projects once today's maintainers step back.
Top comments (0)