Instead of prompting an agent task by task, I designed the system that prompts it: a pipeline that finds its own work, hands it out, and only stops when a real check approves it.
How it works
-
Auditor — walks a repository looking for real correctness bugs (not style nitpicks): failures at I/O / network / DB boundaries, race conditions, security issues, missing validation. Every finding needs a concrete failure scenario with
file:line. It files one Jira ticket per finding, classified by severity and priority, with a hard per-run cap and JQL de-duplication against already-open tickets. -
Parallel resolvers — up to four concurrent runs, each with a ticket already assigned. Each resolver works in its own isolated
git worktree— never the main checkout — so two concurrent runs never clash. It implements the minimal fix, no refactors. -
Database guardrail — a mechanical rule, not a judgment call: if the diff touches migrations, ORM models, or contains DDL/DML outside tests, the resolver stops, writes the
.sqlfor human review, and flags the ticket as blocked. It never applies schema changes. -
Verification — runs the repo’s tests / analyzer and pastes the real output. If it fails, it iterates a couple of times; if it stays red, it reverts and flags the ticket with the log.
-
PR + closing the loop — opens the PR, requests a bot review, records the PR in a state file, and transitions the ticket to “in review”. A separate job closes the ticket when the PR merges — and only processes PRs that went through the pipeline, never every PR in the repo.
The underlying idea
The agent that writes the code can’t be the one that approves it. The context where the code was born is already full of the self-persuasion chain that produced it. The generator / evaluator split is structural: another agent, with instructions that assume the code is broken until proven otherwise, runs the tests and decides.
Guards against the silent costs
- PRs never auto-merge — there’s always a human door.
- Uncertain items go to an inbox, not a PR.
- Token caps per run and per day, with a max retry count before a finding goes to review.
- State lives on disk, not in the context window: every finding, its status, and the action taken are committed so tomorrow’s run can read them.
Discovery logic lives in versioned skill files, not embedded in a cron job nobody will maintain.