# A sub-agent that ships PRs

Web page: https://academy.memberpress.ai/courses/code-agents/l7/

Lesson 7 of 10 in [Claude Code Agents — Sub-Agents, Tools, and MCP](https://academy.memberpress.ai/courses/code-agents/), 50 min.

Video: https://www.youtube.com/watch?v=O35NCPjVpA4

A sub-agent that ships PRs is not a toy. It is a junior engineer that reads a ticket, writes code, runs tests, and opens a PR — without asking clarifying questions. Getting there requires the brief to be written at the same quality as a good engineering spec. The brief is the lesson. The merged PR is the proof.

The gap between "dispatching an agent" and "having an agent ship production-quality PRs" is almost entirely in the brief. Weak briefs produce agents that ask questions, loop on errors, commit to the wrong branch, or open PRs with no relation to the ticket. Every failure mode below can be traced back to a gap in the brief.

**A working brief template**

The gaps in angle brackets are what you fill in:

```
Repository: /Users/seth/projects/<repo>
Working directory: /Users/seth/projects/<repo>-agent-<ticket-id>
Branch: agent/<ticket-id>-<short-description>
Ticket: <ticket text embedded in full — do not make the agent fetch it>

Phase 1 — Understand
Read the files mentioned in the ticket plus any files they import that
are relevant to the change. When complete: write a one-paragraph summary
of what you understand the change to be. If the change requires touching
files not mentioned in the ticket, list them.

Phase 2 — Branch
Confirm your working directory: run `git branch --show-current`.
It must return `agent/<ticket-id>-<short-description>`.
If it returns anything else, stop and return: "Wrong branch: <actual>."

Phase 3 — Implement
Make the changes described in the ticket.
Completion signal: `<specific test command>` exits 0.
Do not consider Phase 3 complete until the test exits 0.
If the test does not exit 0 after three attempts, stop and return
the full test output. Do not attempt a fourth fix.

Phase 4 — Commit
Stage only the files you changed: `git add <specific files>`.
Do not use `git add .` or `git add -A`.
Commit message format: `<type>(<scope>): <description>`

Phase 5 — PR
`gh pr create --title "<title>" --body "Closes <ticket-id>. <one sentence of what changed and why.>"`
Return: the PR URL.

Constraints:
- Do not modify files outside <list of allowed paths>.
- Do not install new dependencies without stating why.
- If a dependency is needed, state the package name and reason before installing.
```

Every line addresses a specific failure mode. Phase 2's branch verification prevents commits to main. Phase 3's three-attempt limit prevents the "almost done" loop (described below). Phase 4's explicit staging prevents accidental inclusion of debug files, `.env` changes, or generated artifacts. The embedded ticket prevents the agent from fetching a URL that resolves to a login page.

**The "almost done" loop**

Long-running agents develop a characteristic failure mode: they get close to a working state, encounter one remaining error, attempt a fix, introduce a new error, fix that one, and cycle. From the outside it looks like progress. From the inside the agent is stuck. The loop can run for thirty turns, burning context, before the session times out or you intervene.

The fix is a hard stop condition in the brief — not "keep trying until it works" but "stop after N failed attempts and return the error." Three attempts is usually the right limit. An agent that cannot solve a problem in three attempts is encountering something outside its scope: a missing test fixture, a misconfigured environment, a schema conflict. The error output will tell you. You fix the external issue and re-dispatch.

**Running the brief**

Start with a real ticket. Not a toy. A real ticket with real acceptance criteria and a verifiable completion signal. Create the worktree (l3). Dispatch the agent. Do not interrupt it while it works.

When it returns, read the diff before merging. The agent's code is a first draft, not a signed review. Your job after dispatch is the code review, not the implementation.

The first run will almost certainly surface something wrong with the brief — a file the agent needed to read that was not mentioned, an ambiguous completion signal, a constraint that was too narrow. Fix the brief, run it again. After two or three iterations, the brief template will produce mergeable PRs consistently.

**If you get stuck**

The agent returns "Wrong branch" in Phase 2. The worktree was not created before dispatch, or it was created on the wrong branch. Run `git worktree list` to see what exists. Create the correct worktree, confirm the branch, then re-dispatch.

The agent loops in Phase 3 past your attempt limit. Your completion signal was not specific enough. "All tests pass" is not a signal — it is a hope. Specify the exact command: `npm test -- --testPathPattern=auth/session`. An ambiguous signal lets the agent decide what "done" means. It will choose wrong.

The PR opens but references the wrong ticket. The ticket text was not embedded in the brief — you gave the agent a URL and it fetched a redirect, a login page, or a stale cache. Embed the full ticket text. The brief is a self-contained document.

**Cross-reference**

l3 covers worktree creation — Phase 2 assumes a worktree exists and is correctly branched. l8 covers what to do when the agent crashes mid-run on a long ticket. If the PR command syntax is unclear, the form above uses the minimum viable flags for `gh pr create`.

**Deliverable**

Fill in the template above for one open ticket in your tracker. Create the worktree. Dispatch the agent. When it returns, review the diff and either merge or close the PR with a comment explaining why it did not merge. Return the PR URL. Open, merged, and closed are all valid outcomes for this lesson. The invalid outcome is not running the agent.

**Further reading**

- ["Building in the Age of AI"](https://sethshoultes.com/blog/building-in-the-age-of-ai.html) — a four-day build where the PR-shipping pattern in this lesson is the unit of work, scaled across an entire site.

## Try these prompts

- Fill in the Phase 2 branch verification block from the PR-shipping brief template for a ticket named auth-session-fix on branch agent/auth-session-fix. Include the hard stop condition.
- Write the Phase 3 completion signal for a ticket that requires passing a specific Jest test file at src/auth/session.test.ts. Include the three-attempt limit and the stop instruction.
- Write a one-paragraph PR description for a fix that changed localStorage token storage to httpOnly cookies to prevent XSS exposure.

Next: [Long-running agents and recovery](https://academy.memberpress.ai/courses/code-agents/l8/)
