DEV Community

Ayoub Hammoudi
Ayoub Hammoudi

Posted on AI-assisted

How I got seven fixes merged into Prefect, SQLGlot, Apache Beam, Kafka and Microsoft by asking one question

I had seven pull requests merged upstream: one in Prefect, one in SQLGlot, one in Apache Beam, two in Microsoft PyRIT, one in Microsoft Agent Framework and one in Apache Kafka. The largest was 78 added lines. Two of them added nothing at all and only deleted. The fastest went from issue to merge in 34 minutes.

None of that came from reading code hoping something would look wrong. It came from one question, asked over and over:

Where does this project do the same thing more than once, and which one disagrees with the others?

Mature codebases are full of families. Dialect generators. Notification blocks. Scorers. Serializers. Every family is a contract implemented N times, and a contract implemented N times is a contract that drifts. When one sibling drifts, the other siblings become your oracle. You are no longer arguing about what the code should do. The project already answered that, N minus one times.

The clearest case: a seed that never reached the query

SQLGlot transpiles SQL between dialects. Databricks has a UNIFORM(min, max, seed) function. So does Snowflake. Both are generated by sibling classes.

The Databricks parser stores that third argument in the seed slot of exp.Uniform. The Snowflake generator reads both gen and seed. The DuckDB generator reads only gen.

So a query transpiled to DuckDB silently lost its seed. ABS(HASH()) hashed nothing. Seed 5, seed 99 and no seed at all produced identical SQL. No exception, no warning, and a result that looks completely plausible until you need reproducibility.

Here is the part that matters for the method. I did not have to decide what the correct output was. I wrote in the pull request:

The two expected strings are not mine: tests/dialects/test_snowflake.py:3312-3334 already asserts them for the equivalent Snowflake input.

The project had already written down the right answer for the sibling. My test asserted the same strings for the dialect that got it wrong. A reviewer does not have to trust my judgement about SQL semantics. They only have to agree that two dialects reading the same parsed expression should not disagree.

Issue opened at 15:46. Merged at 16:20. Thirty four minutes, for a three line change.

The same shape, three more times

Prefect. Notification blocks let you set a bot name. One of them, NotifyMattermost, accepted the setting and never passed it to the request. Its siblings all did. The fix was sixteen lines with a test, and the expected behaviour came from the other blocks, not from me.

Microsoft PyRIT. SubStringScorer includes its text matcher's configuration in the scorer identity. DecodingScorer holds the same kind of matcher, at the same point of the same method, and did not. The consequence is not cosmetic: two scorers that return opposite verdicts for the same input shared one identity hash, so cached evaluation metrics could be reused across different behaviour. The sibling had already been fixed in a pull request that was merged. I copied the two lines it added into the class that had been missed.

Apache Beam. This one breaks the pattern, and it is worth including for that reason. A debug log reading ### Labels arrived in the Python BigQuery connector with the commit that added BigQuery Read API support, merged on 6 October 2021. My one line removal merged on 6 October 2026. Five years to the day, in a release path, printing a dataset label dictionary at warning level on every temporary dataset setup. There was no sibling to compare against here. There was just a line that no release should have contained. Zero additions, one deletion, one approval, no requested changes.

What this method is not

It is not scanning for theoretical defects.

I learned that bluntly, and at my own expense. On another project I prepared a clean, exhaustive change that removed a parameter no code reads across seven model families. Every call site checked, every live use preserved, the project's own type checker measured at the version they pin, the full suite run. Only after all of that did I sit down and read their contributing guide properly. It says, in writing, that they will close changes like mine:

Code agents often zero in on "theoretical bugs" found by code analysis that rarely if ever cause problems in practice. These are generally not worth fixing unless they can be exploited by an attacker.

I had spent a twenty three hour test run before reading the one page that decides whether the work was admissible at all. I opened it anyway. A maintainer closed it two minutes after a bot flagged it for review, without a word, which is exactly what that page says they will do. The CI on it was entirely green: sixteen jobs, 199,469 tests, zero failures.

That is a fair outcome and I would have done the same in their position. The lesson is not that the policy is wrong. It is that reading it costs ten minutes and belongs at minute zero, not after the suite.

A maintainer of a different project put the same bar as a question on the issue tracker: Did we verify if this is a real-world scenario before drafting this PR? He was reviewing one of five pull requests, from three contributors, all proposing the same category of change to the same family of classes. None of the five has been merged, and four are still open. Correctness of an API contract is not enough. Something has to actually go wrong.

The sibling question clears that bar by construction. If one implementation out of five behaves differently with the same data in hand, the breakage is reachable by definition. Someone is on that path right now.

The five questions, in the order I ask them

  1. Where is the family? The interface, the base class, the registry, the dialect map. Anything implemented more than three times.
  2. Does the project already state the right answer? An existing test asserting it for the sibling, a docstring that promises it, a schema that declares it. If nothing in the repository states it, you are about to argue about taste with someone who has merge rights, and you will lose.
  3. Are the siblings actually in the same situation? This is where most candidates die, and it is the question people skip. If the sibling that behaves correctly never receives the data in question, it is not a witness, and you have no case at all.
  4. Does it fail before and pass after? Write the test first, run it, keep the exact failure message. It costs one command and it is the most persuasive thing you can put in front of a reviewer.
  5. Did you run what they run, at the versions they pin? Their linter version lives in .pre-commit-config.yaml, setup.py or the CI workflow, not in your head. One number produced with a newer tool invites a reviewer to dismiss the entire report.

The part nobody writes about

Everything above is the visible half. The other half is the work that produced nothing, and it is most of it.

That repository was Kafka, and I chased three separate defect families there before finding anything worth proposing. I wrote a scanner for malformed log placeholders and ran it across 3,911 production files: zero cases. I grepped the whole tree for leftover JUnit 4 imports: zero files. The third was the family of five pull requests above, already dead on a bar a maintainer had set.

What survived those three dead ends was three test dependencies declared twice in the same Gradle block. Zero lines added, three removed.

That is the method working, not failing. Seven merges did not come from being prolific. They came from killing candidates early, before writing anything, so the few that reached a maintainer were ones they could not reasonably refuse. Five of the seven were under forty lines. The effort was never in the fixing.

So if you take one thing from this: the skill being tested is not finding bugs. It is deciding, quickly and honestly, which of the bugs you found are worth another person's attention.

Everything I shipped is public and linked below. Every claim in this post can be checked against it.

I am Ayoub Hammoudi, a backend and AI platforms engineer in Paris. More of this work is at github.com/Ayoubhm07.

Top comments (0)