# End to end: from issue to merged pull request
A junior engineer who picks up a ticket, writes a fix, and opens a clean pull request without supervision is valuable. Claude Code can run that exact loop, and the skill you need is not "promptingpromptingPrompt engineering is the practice of designing and refining text inputs to guide large language models toward accurate, relevant, and reliable outputs.View full definition →" but orchestrating a disciplined developer workflow where the AI does the typing and you stay the gate.
This lesson walks one realistic issue from open to merged. We will use Claude Code, Anthropic's terminal-based coding agent, plus its GitHub integration. The mechanics generalize, but the discipline is the point.
Claude Code reads and writes your local repo. To close the loop to GitHub (issues, PRs, reviews), you connect it to your remote.
The cleanest path is the GitHub CLI (gh), which Claude Code can call directly as a tool. Authenticate once:
gh auth login
cd ~/projects/checkout-service
claudeNow Claude Code can run gh issue view, gh pr create, and friends on your behalf. There is also an official GitHub app, @claude, that you install on a repo so you can mention Claude in issue and PR comments and have it respond inside GitHub itself. See the Claude Code GitHub Actions docs for that server-side flavor. For this lesson we drive everything from the terminal so you can watch each step.
> New term: a managed agent is an Anthropic-hosted agent that runs in the cloud rather than on your laptop. The local Claude Code loop we are doing here is the same shape, just running on your machine where you can interrupt it.
Start by pulling the issue into context. Do not paste it. Let Claude fetch it so the agent owns the retrieval step.
> Read issue #214 with gh. Summarize the bug, the expected
behavior, and what files you'd likely touch. Don't write code yet.Claude runs gh issue view 214, reads it, and replies with a plan. This restatement is your first checkpoint. If the issue says "discounts apply twice on returning customers" and Claude's summary talks about tax rounding, you caught a misread before a single line changed.
This is the cheapest place to correct course. Spend time here.
A clean branch per issue is non-negotiable. It keeps your diff scoped, makes review possible, and lets you abandon work cheaply if the approach is wrong.
Tell Claude the convention explicitly the first time:
> Create a branch off main named fix/214-double-discount.
We branch from updated main, one branch per issue, never commit
to main directly.Better: encode this once so you never retype it. Claude Code reads a CLAUDE.md file at the repo root as standing instructions for every session. Put your team's rules there.
## Workflow rules
- Branch from updated `main`, one branch per issue.
- Branch names: `fix/<issue>-<slug>` or `feat/<issue>-<slug>`.
- Never commit to `main`. Never force-push shared branches.
- Keep diffs small. If a change exceeds ~150 lines, stop and ask.
- Every behavior change ships with a test.> New term: CLAUDE.md is a plain Markdown file Claude Code loads automatically as project context. Think of it as the README the agent actually obeys. It is the single highest-leverage file in an agentic repo.
The "stop and ask if the diff exceeds ~150 lines" rule matters more than it looks. Small diffs are not a style preference; they are the only diffs a human can actually review. A 600-line AI-generated PR is a rubber stamp waiting to happen.
Now let Claude work. The key move is to make tests the specification, not prose.
> Reproduce #214 with a failing test first, then make it pass.
Run the suite after each change. Show me the failing test before
you fix anything.This is test-driven development, and it is the single most effective guardrail for AI-written code. The failing test proves Claude understood the bug. The passing test proves the fix works. You review behavior, not vibes.
Claude will typically:
1. Write a test that reproduces the double-discount bug and watch it fail.
2. Edit the discount logic.
3. Re-run the suite until green.
4. Report what it changed and why.
Watch the loop run. If Claude starts editing unrelated files or "improving" things you did not ask for, interrupt it (Esc) and narrow the scope. Scope creep is how small diffs become unreviewable ones.
Before anything touches GitHub, read the diff. This is the human gate, and it is the part of the loop you must never delegate.
> Show me the full diff with git diff. Walk me through each hunk.Then actually read it. You are looking for three things:
Claude is good at producing plausible code. Plausible is not correct. The diff review is where you convert "looks right" into "is right." If you do not understand a hunk, ask Claude to explain it, then decide for yourself whether the explanation holds up.
Once the diff passes your review, commit with a message that references the issue, then open the PR.
> Commit with a conventional message referencing #214. Then open
a PR against main. In the body: a one-line summary, what changed,
how it was tested, and "Closes #214".The Closes #214 line is doing real work: GitHub will auto-close the issue when the PR merges. Claude writes a body like this:
## Summary
Returning customers no longer receive the loyalty discount twice.
## Changes
- `discount.py`: guard against re-applying loyalty tier in
`apply_discounts()` when one is already present.
- Added regression test `test_loyalty_applied_once`.
## Testing
Full suite green (142 passed). New test fails on `main`, passes here.
Closes #214Notice the body explains the *why* and the verification, not just the *what*. The diff already shows what changed. A good PR description tells the reviewer what to check.
Knowledge check
1. According to the lesson, what is the core skill needed to run the issue-to-PR loop effectively with Claude Code?
2. In the lesson, why does the author instruct Claude to fetch issue #214 with gh rather than pasting the issue text in?
3. Based on the lesson's definition, what distinguishes a 'managed agent' from the local Claude Code loop being demonstrated?
4. Select ALL correct answers about connecting Claude Code to GitHub as described in the lesson.
Sélectionnez toutes les réponses correctes.
5. Select ALL correct answers about the first step of the workflow ('make Claude restate it').
Sélectionnez toutes les réponses correctes.
The pull request is not a formality. It is where teammates and CI weigh in, and you should treat it as a second, independent gate.
If you installed the @claude GitHub app, you can ask for an AI review pass directly in the PR:
@claude review this PR for edge cases around discount stacking and
suggest any missing test cases.Claude posts review comments on the diff. This is genuinely useful as a *second pair of eyes*, but resist the temptation to let the same model that wrote the code also approve it. AI review of AI code catches mechanical issues (off-by-one, unhandled nulls, missing test branches). It does not catch "this whole approach is wrong for our domain." That judgment stays human.
Let CI run. If the pipelinepipelineAll active sales opportunities across the stages of the sales process, together with their combined potential value and probability of closing.View full definition → is red, feed the failure back:
> CI failed on the lint stage. Pull the logs with gh run view,
fix the issue, and push to the same branch.Claude amends and pushes. The PR updates in place. This is the realistic rhythm: implement, review, CI, fix, repeat, all on one tight branch.
When the diff is approved and CI is green, merge. Prefer a squash merge so the branch's messy iteration history collapses into one clean commit on main.
> Squash-merge the PR with gh, delete the remote branch, then
switch local back to main and pull.gh pr merge 214 --squash --delete-branch
git checkout main
git pullIssue #214 closes automatically thanks to the Closes #214 line. Your local main is current. The feature branch is gone, locally and remotely. You are ready for the next ticket with zero leftover state.
That final cleanup is branch hygiene's bookend. Stale branches accumulate fast when an agent can spin them up in seconds. Make deletion part of the merge, not a someday chore.
The temptation with a capable coding agent is to remove the checkpoints: one giant prompt, one giant diff, one merge. It works in a demo and fails in production, because the failure mode of LLMLLMA Large Language Model is an AI system trained on vast text data to predict and generate language, enabling tasks like writing, summarizing, and answering questions.View full definition → code is not "broken and obvious" but "plausible and subtly wrong."
The loop you just ran resists that failure with structure, not trust:
Encode these in CLAUDE.md and they apply to every session automatically. The discipline becomes infrastructure instead of willpower.
For the deeper automation patterns (running this loop unattended in CI, multi-step agents, custom tools via MCP), the Claude Agent SDK docs are the next stop. But unattended is a destination, not a starting point. Earn it by running the supervised loop until you trust each checkpoint.
@claude) do a second-pass review for mechanical issues, but never let the model that wrote the code be the one that approves it.main, so you start every ticket from a clean state.