An issue-to-pull-request system needs more than an agent that can edit files. It needs a reliable answer to three questions: which issue is authorized, what counts as done, and who can approve delivery? Start there before choosing a model.
Make the issue executable, not vague
Write the expected behavior, boundaries, and acceptance criteria into the issue. “Fix assignment” is ambiguous. “If ticket assignment fails, keep the ticket unchanged, show an accessible error, and allow a retry” creates observable outcomes. Include the relevant command for running tests and identify changes that are out of scope.
A useful issue also describes the unhappy path. What happens when a request times out? What should a user see when they lack permission? Existing behavior is context, not permission to rewrite unrelated parts of the application. Small, complete changes are easier to evaluate than a broad prompt to improve everything.
Put an authorization step before execution
Not every new issue should trigger paid work. A label or assignment rule gives a maintainer an explicit intake decision. Keep repository installation permission separate from issue eligibility. An installed GitHub App can be authorized for a repository while an individual issue remains intentionally unassigned.
Treat a pull request as a candidate
An agent's summary is useful, but it is not a test result. A candidate PR should point to the exact tested commit, verification output, acceptance coverage, and any known limitations. If the branch changes after verification, evaluate the new state instead of inheriting confidence from an earlier diff.
A practical first rollout
- Choose one reversible change in a repository with working tests.
- Enable explicit intake and leave automatic merge off.
- Set a cost budget and a retry limit before execution.
- Inspect the diff and evidence before approving delivery.
- Record what needed human judgment, then improve the issue template.
ForgeLoop models these as distinct delivery stages. Its value is not hiding the stages; it is making the transition between them inspectable. See how the delivery loop works before enabling unattended work.