Opening a PR is the easy part. Any code generator can produce a diff that compiles and passes a linter. The hard part is what happens after a reviewer leaves a comment at 11 AM and expects a response by end of day. If the agent cannot handle that loop, you have not automated the work, you have just moved the first step.
This is where most autonomous coding tools stop. They generate code. They open a PR. Then a human reviewer leaves a comment that says something like "this cache invalidation logic won't work if two requests arrive within the same millisecond," and the tool goes silent. The developer has to take over, which means they were never really out of the loop.
We built the review response loop because we think an agent that cannot respond to review is only completing half the job.
What a review comment actually asks for
Review comments are not instructions. They are observations, often compressed into informal language, that imply a required change. "This won't scale" means something different from "this will throw a NullPointerException if the list is empty" and something different again from "we don't do it this way here." Each of these requires a different response, and a useful agent needs to classify the type of concern before it can address it.
We classify review comments into four categories: correctness concerns (the code has a bug), style and convention concerns (the code does not match team norms), design concerns (the approach is valid but inconsistent with architecture choices made elsewhere), and clarification requests (the reviewer does not understand what the code is doing and wants an explanation). Each category maps to a different response action.
Correctness concerns require a code change. The agent reads the comment, identifies the specific claim being made about the code's behavior, locates the relevant code, and attempts a fix. If the reviewer said "this will break under concurrent load," the agent looks for shared mutable state in the diff, checks whether there are other places in the codebase where similar state is protected with a lock or a concurrent data structure, and applies the analogous protection here.
Style and convention concerns also require a code change, but the right change is to match how the codebase does things elsewhere, not to invent a new solution. The agent looks at examples in the same module or package, finds the pattern being used, and reformats the new code to match. This is straightforward for naming conventions and import ordering. It is harder for patterns like "we always inject dependencies through the constructor here" because the agent needs to understand that the reviewer is pointing at an architectural convention, not a syntax preference.
Handling ambiguous comments
The genuinely difficult case is a comment like "this feels fragile." That is a design concern expressed with no specific technical claim. We could attempt a code change, but we do not know what change the reviewer has in mind, and making a random structural change to address a vague concern often makes things worse. Guessing at an ambiguous comment and pushing a second commit that misses the point is worse than asking for clarification.
For ambiguous comments, Pylon posts a structured response on the PR rather than pushing a code change. The response does three things: it acknowledges the concern, it states the agent's current interpretation of what the reviewer is worried about, and it offers two or three specific questions that, if answered, would let it proceed. The response is short and direct. It is not a defense of the original code. It is an honest "here is what I think you mean, am I right?"
In practice, reviewers often respond to this with a clarification that is much more specific than the original comment, which then becomes solvable. The loop takes a bit longer, but the end result is a change that actually addresses the concern rather than one that looks like it does.
The second commit problem
When an agent responds to a review comment with a code change, that change has to be correct. A second commit that partially addresses the comment, introduces a new issue, or misunderstands the reviewer's concern is a trust-eroding outcome. Two bad commits in a row and the reviewer stops treating the agent as a useful participant in the review.
We handle this by treating the review response as a new agent job with the review comment as the primary context. The agent re-reads the original job description, reads the full PR diff as context, reads the reviewer's comment with its inline location, and then runs the same pre-commit checks it runs on initial jobs: does the proposed change compile, do existing tests pass, does the change introduce any issues in the files it touches? If the change does not pass those checks, it does not get pushed. The agent posts a note on the PR explaining what it tried and why it could not complete it.
One constraint we enforce: the agent is not allowed to make scope-expanding changes in response to a review comment. If a reviewer says "this method is too long, split it," the agent splits that method. It does not also refactor the calling code, rename related functions, or restructure the module. Review-response commits are narrowly scoped to the comment they address. When the agent finishes addressing all comments, it posts a summary of what changed and requests a re-review.
Threading and multi-reviewer contexts
Real PRs have multiple reviewers who sometimes leave contradictory comments. One reviewer asks for a certain error to be thrown as a checked exception; another reviewer on the same line prefers returning an Optional. The agent needs to detect the conflict, not silently implement one of the two approaches and pretend the other comment does not exist.
When conflicting comments are detected on the same line or the same logical code block, the agent posts a comment tagging both reviewers, explains the conflict it sees between their requests, and asks for a resolution before proceeding. This is the same thing a thoughtful junior engineer would do. Choosing sides in a technical disagreement between reviewers is not the agent's call to make.
For comments that are not in conflict but address related concerns, the agent batches its response into a single commit when possible. A PR with five review comments from two reviewers should produce one response commit, not five, unless the changes are in unrelated files that have no shared context. Keeping the response commit count low makes the PR history readable and makes it easier for reviewers to see the full scope of what was addressed.
What we have not solved yet
The review response loop has clear limits. Design comments that require architectural changes, such as "this whole approach to caching should be rethought," are beyond what we handle automatically. We detect those, flag them as requiring human attention, and close the agent loop for that comment. The PR sits in a human-required state until the team decides how to proceed.
Comments that reference external context, like "see how the payments module handles this," require the agent to locate and read that referenced code. We support this when the reference is an explicit file path or module name. Implicit references, such as "we usually do this differently in the data layer," require the agent to infer which part of the codebase the reviewer is pointing at. We handle the common patterns here, but edge cases exist.
The goal is not a fully autonomous review process. It is to reduce the number of times a developer has to context-switch back to a PR because the agent could not handle a straightforward piece of review feedback. That gap, between "agent opens PR" and "PR is actually reviewed and merged without the developer picking up the work again," is where a lot of the value of autonomous coding lives or dies.