AI Wrote the Code. The Human Asked the Right Questions.
I submitted my first pull requests to an open-source project today. The fixes were simple — 12 lines and 3 lines. Claude wrote the code. But the contribution almost went out the wrong way, and the only thing that prevented that was me asking better questions at each step.
This is a story about the PR process, not the bugs. The bugs were edge cases that might only matter to me and a few others, but real none the less, and needed to be addressed. It’s the HOW they were addressed I want to talk about here.
The bugs, briefly
I’ve been training LoRA models on ACE-Step 1.5, an open-source AI music generation model. I hit two bugs in the training pipeline: a TypeError from a missing parameter in the preprocessing step, and a RecursionError from a monkey-patch that broke on consecutive training runs. I traced both to their root causes, described the problems precisely to Claude, and Claude wrote the fixes. That part was fast.
What happened next is what this post is actually about.
Take one: ship it
Claude had both fixes ready. I knew these were something that upstream would probably want to have fixed, so I asked Claude to submit them as a Pull Request (PR). Claude pressed on as usual, doing what I asked… that is, both bugs, one commit, done. And honestly? That would have worked. The code was correct. The PR would have been mergeable.
But I paused and asked: “What are the best practices here?”
Claude knows a lot about open source. It has masive resources about what works, what doesn’t and what makes things easier for humans. You could argue that its main purpose is to make life easier for humans. But it doesn’t like to overstep. It will typically just do what you ask without offering suggestions, unless you are gossly off base. But oOnce I asked that question, its attention shifted. It responded that ideally, each fix should be its own atomic commit on its own branch, with its own PR. One fix per PR means maintainers can review, discuss, and merge each change independently. If one fix needs revision, it doesn’t block the other. If one gets rejected, the other still stands.
So we separated them. Two branches, two commits, two PRs.
Take two: where are the issues?
The PRs looked clean, but something else was bothering me, in the back of my mind. Someone else may have reported these already. And if not, they would probably want to track them more easily via an issue report. In my own work, both hobbyist and professional, I know that having a ticket reference is important if for no other reason than to track what was done when. So I asked Claude: “Is it better to have issue references? Are there existing issues for these bugs?”
It turned out that there weren’t. Maybe no one else re-runs Lora training like I do. But someone could… So we opened two new issues first — one for each bug, with reproduction steps and links to the specific lines of code where the disconnect lived. Then we linked each PR to its issue with Closes #833 and Closes #834. Now when the PR merges, the issue closes automatically. The fix has context. The history is traceable.
Take three: what am I doing wrong?
The PRs were submitted. The issues were filed. Everything was linked. I could have stopped there. But I know how I want people to contribute to MY projects, so instead I asked Claude one more question: “I haven’t made many issues or PRs. Any criticism of the approach or improvements to make me a better contributor?”
Claude came back with specifics. Things I’d done right:
- Fork-then-PR model — I’d tested everything in my own fork before upstreaming. That’s the ideal workflow.
- One PR per fix — atomic, reviewable in isolation, auto-closes its issue.
- Clean branches — single commit off
upstream/main, no unrelated changes.
And things to level up:
- Pin the version — add the exact commit hash to issue descriptions so maintainers can confirm the bug exists at that point in the codebase.
- Link to specific lines — GitHub renders permalink line references as inline code snippets. Instead of describing where the bug is, show it.
- Add reproduction steps — even pseudocode helps. A
curlsequence that triggers the error makes the bug undeniable. - Follow up — stale PRs get closed. Watch for comments and respond promptly.
So I went back and improved both issues. Added version info. Added permalink references to the exact lines of code. Added reproduce steps. The issues went from “good enough” to genuinely helpful for whoever triages them.
The compounding question
Here’s what I want you to notice about the sequence:
- “Ship it” → Claude submits one PR with both fixes. Functional, but sloppy.
- “What are best practices?” → Two separate PRs, one per fix. Clean, but no context.
- “Should we have issues?” → Issues filed, PRs linked. Traceable, but thin.
- “What am I doing wrong?” → Version pins, permalinks, reproduction steps. Contributor-quality.
Each question didn’t just improve the output — it reframed the problem. The first question turned a code dump into a structured contribution. The second added documentation. The third invited critique. None of these questions were about code. They were about process, standards, and craft.
AI didn’t know to do any of this on its own. Left to its defaults, Claude would have submitted a single PR with a generic description and moved on. Every improvement came from a human asking a better question.
The skill that matters
There’s a narrative that AI makes human skill irrelevant. Paste in your error, get back your fix, who needs expertise? But expertise isn’t knowing the answer. It’s knowing what question to ask next.
I’m not a professional software developer. I don’t maintain open-source projects. But I know how to ask “is this the right way to do this?” and “what am I missing?” — and then act on the answer. That loop — ask, learn, refine, ask again — is the thing that turns AI from a shortcut into a multiplier.
The code was the easy part. The questions were my personal, human contribution.