GitHub Copilot Coding Agent: The Delivery Drone Test (Issue to PR)
It is Friday afternoon, and one ticket has been sitting in the backlog for three weeks: "move the auth module off callbacks." Nobody is stuck on it. It is just fiddly work spread across five files, the kind of job that eats a quiet afternoon and delivers nothing anyone will remember.
GitHub Copilot's coding agent offers a different deal. You assign the issue the way you would assign it to a teammate, it works in the cloud, and it comes back with a pull request. We tried that deal on a small Express and TypeScript project. This guide covers what came back, what we caught, and the issue template that made the second attempt far better than the first.
Should You Hand This Issue to the Agent? A 30-Second Check
Before the how-to, the decision. Most disappointing agent results come from handing it the wrong kind of task, not from the agent itself. Walk through these questions in order, and stop at the first "no."
If not, rewrite the issue first. No → stop and clarify.
Tests are the agent's only way to check itself. No → add a few tests first.
A bad PR can simply be closed. A bad payment flow cannot. No → keep a human at the keyboard.
Boundaries make the diff reviewable. No → write the boundaries down first.
Then plan to review the pull request like a colleague's work.
Our auth migration passed all four questions, which is why we picked it. The issue we wrote the first time did not, and that is the interesting part.
What the Agent Actually Is (in Three Sentences)
You assign a GitHub issue to Copilot. It opens a draft pull request on its own branch and works in a temporary cloud environment powered by GitHub Actions, not on your laptop. When it finishes, it asks you for a review. GitHub's documentation currently calls this the Copilot cloud agent in many places and the coding agent in others, so search for either name, and check your own plan and settings, because availability and entry points change.
The Delivery Drone: An Everyday Picture of the Coding Agent
Most developers already use two AI helpers without thinking about it. The coding agent is a third kind of helper, and the easiest way to feel the difference is to picture getting a package delivered.
The last sentence in the third card matters most. A drone can land the package on your porch, but you are the one who decides whether the box is damaged before you sign for it. That signature moment is the pull request review. We covered the first two helpers in our breakdown of when to use Ask, Edit, Plan, or Agent mode, and the cloud agent sits one step beyond those because the work leaves your machine entirely.
Where the Drone Picture Holds, and Where It Breaks
No analogy is perfect. This table shows the mapping and, just as usefully, the places where thinking "drone" would mislead you.
| Coding concept | Drone version | Where the picture breaks |
|---|---|---|
| The GitHub issue | The address label on the package | A drone follows the address exactly. An agent interprets a vague issue and may guess wrong. |
| The repository | The city map loaded into the drone | A drone does not rebuild streets. An agent rewrites the code it reads. |
| Changes across many files | Stops at several connected houses | Houses do not break each other. Code files do: one wrong import and the whole build fails. |
| Running the tests | The drone's own obstacle sensors | Sensors only detect what they were built to detect. Tests only catch what someone wrote a test for. |
| Pull request review | The recipient checking the box before signing | Checking a box takes seconds. Judging logic, security, and intent takes real thought. |
The Flight Path: What Happens After You Assign the Issue
Here is the route as GitHub's documentation describes it today. The exact screens and entry points (GitHub.com, mobile, the API, supported editors) shift over time, but the shape of the flight stays the same.
You assign the issue to Copilot.
A reaction appears on the issue, and a draft pull request opens on a separate Copilot branch.
An agent session reads the repository and edits code inside a temporary GitHub Actions environment.
It runs tests and linters, reads the failures, and fixes what it can.
It requests your review on the pull request.
You review, comment, and merge. Copilot does not merge its own work.
Two practical details from the documentation saved us time. First, comments added to the original issue after the agent starts are not seen by it, so new instructions belong in a comment on its pull request, where you can also mention @copilot to ask for changes. Second, by default the person who asked Copilot for a pull request cannot be the one who approves it, so plan on a second reviewer. Both behaviors can change, so check the current documentation for your plan.
Our Test: Migrating Auth From Callbacks to async/await
We wanted a task that is real, boring, and risky enough to show failure. The setup was a small Express and TypeScript app with a legacy auth module spread across five files: auth.controller.ts, user.service.ts, db.middleware.ts, auth.routes.ts, and auth.test.ts. The goal in both attempts was identical: replace the nested callback chains with async/await without changing behavior. Only the issue we wrote was different.
Attempt 1: The Vague Issue
This is what many of us would type at 4:45 on a Friday.
Title: Clean up auth module
Body: Use async/await everywhere in the auth code.
The pull request that came back looked busy and confident. It also had problems we could not have predicted from the title alone.
None of this is the agent being "bad." It did what an eager new hire does with a one-line ticket: it filled the gaps with guesses. The pull request was too wide to review with confidence, so we closed it and rewrote the issue.
Attempt 2: The Issue With a Flight Plan
The second issue answers the questions the agent would otherwise guess at: where to fly, where not to fly, what must stay the same, and how to prove it landed safely. This is the same idea we describe in our piece on giving AI the right information at the right time, applied to a ticket.
Title: Migrate auth callbacks to async/await (auth module only)
Goal: Replace the nested callback pattern in the authentication flow with async/await.
Scope: Edit only auth.controller.ts, user.service.ts, db.middleware.ts, and the mocks in auth.test.ts.
Constraints:
1. Keep every existing error status code exactly as it is today.
2. Do not edit shared database connection files or anything outside the files listed above.
3. Do not add new dependencies.
Verification: Run npm test. Fix any failing unit tests that are caused by the migration before marking the pull request ready.
Result: A pull request that touches only the files above, with a short description of what changed.
The pull request that came back was narrow: three source files plus test mocks, nothing outside the fence. The agent updated a mock in the test file that still assumed the old callback style, re-ran the suite, and described the change in the pull request text. That is the result we hoped for, but we did not stop there.
The Catch: Green Tests, Wrong Behavior
While reviewing the diff line by line, we noticed that an expired-session branch, which used to return a 401, now sat inside a broad try/catch and would return a 500. The tests were all green because none of them covered an expired session. The agent had done what the checks asked for. The checks simply had a hole.
Fixing it took one comment on the pull request, not a new issue:
@copilot The expired-session path used to return 401 and now returns 500. Please restore the 401, add a unit test for an expired session, and re-run npm test.
The agent made the fix and added the test, and the pull request was in good shape. The review step is not paperwork. It is where the real safety lives, which is the same lesson from our look at AI-assisted code review.
The Three Rounds Side by Side
| Round | What we gave it | What came back | Our verdict |
|---|---|---|---|
| 1. Vague issue | One line, no scope, no checks | Wide diff, shared code touched, behavior changed | Closed without merging |
| 2. Flight-plan issue | Goal, file list, constraints, test command | Narrow diff, mock fixed, tests green, one hidden behavior change | Close, but not safe to merge yet |
| 3. PR comment | One precise correction plus a new test | 401 restored, gap covered by a test | Reviewed and ready |
Short on time? This video replays the vague-issue vs. flight-plan-issue test in a few minutes.
What the video covers:
- The delivery-drone picture of how the coding agent works
- Vague issue vs. flight-plan issue, and the 401-to-500 bug only a human caught
- The reusable issue template and the pull request checklist
Your Reusable Flight-Plan Template
This is the shape our second issue took, boiled down so you can paste it into any repository. The fields that mattered most in our test were Scope, Constraints, and Verification.
Title: [one verb, one area, one boundary]
Goal: [what should be true when finished]
Scope: [exact files or folders it may edit]
Do not touch: [shared code, configs, schemas, dependencies]
Must stay the same: [behaviors, status codes, API shapes]
Verification: [exact test or lint commands to run]
Result: [what the pull request should contain]
If your project has the same rules every time, such as naming conventions or how to run tests, GitHub lets you store repository-level instructions so they do not have to be retyped in each issue. Check the current documentation for where those files live and how to prepare the agent's environment, because that area changes.
Landing-Zone Inspection: What We Check in Every Agent PR
Reviewing an agent's pull request is slightly different from reviewing a colleague's, because the agent never gets tired and never says "I was not sure about that part." We keep a short list. It pairs well with the habits in our guide to AI-assisted unit testing, since weak tests are the most common reason a green build is misleading.
| Check | What we look for | Red flag |
|---|---|---|
| ✅ File list | Only files named in the issue changed | Unexpected files, configs, or lockfiles |
| ✅ Error paths | Every old catch, status code, and fallback still exists | New broad try/catch blocks swallowing specific errors |
| ✅ Tests | Tests cover the changed behavior, not only the happy path | Assertions weakened or tests deleted to get green |
| ✅ Dependencies | No new packages unless requested | A helper library added "for convenience" |
| ✅ Secrets and config | No keys, tokens, or hard-coded URLs | Anything that looks like a credential |
| ✅ Pull request summary | The description matches the actual diff | Claims the diff does not support |
If the pull request ends up in your usual merge process, our walkthrough of the push, pull request, and merge workflow with Copilot covers the rest of the journey.
How Much Freedom Should the Drone Get?
The more expensive a mistake is to undo, the less autonomy a task should get. The bars below show how much human review we would plan for by task type. They are our own relative impressions and illustrative, not measured benchmarks.
Small test update
Bug fix with a clear reproduction
Small refactor inside one module (our auth test)
New feature across service and API layers
Database migration
Authentication, payments, production infrastructure
Longer bar = more human review and tighter control. Relative and illustrative.
Notice where our own test landed. Auth code is sensitive enough that we would never merge it on green tests alone, which is exactly why we picked it as the stress test and why the human catch mattered.
Security: Guardrails That Exist, and Ones That Are Still Yours
An agent that can edit code and run commands has more reach than a chat window, so it helps to separate what GitHub documents as built-in from what your team still has to do. Our overview of AI security threats goes deeper on prompt injection, which is the risk to keep in mind when an agent reads text from issues and repository files.
| Guardrail | Who provides it | Our note |
|---|---|---|
| Agent cannot merge its own pull request | Documented by GitHub | Humans stay the final gate |
| Requester cannot approve the agent's pull request by default | Documented by GitHub | Plan for a second reviewer |
| Hidden text in issue comments is filtered before reaching the agent | Documented by GitHub | Helpful, but it does not remove every injection risk |
| Works only in the repository it opens its pull request in | Documented by GitHub | Limits how far one task can spread |
| Who may assign tasks and which repos are enabled | Your team's settings | Start narrow and widen later |
| Never paste passwords, tokens, or keys into an issue | You | Use proper secret management instead |
| Read every new dependency and config change | You | The pull request is the checkpoint |
These behaviors come from GitHub's current documentation and may differ by plan or change later, so confirm them in your own settings before relying on them.
Limitations: When We Would Not Use the Agent
- Vague or exploratory work. "Make the app more secure" or "redesign the architecture" has too many valid answers. Use Chat to think first, then delegate a narrow slice.
- Code with no tests. Without tests, the agent has no way to check itself, and neither do you. Add a few first.
- Anything hard to reverse. Migrations, auth, payments, and production infrastructure deserve a human driving.
- Tasks that span several repositories. The agent works within the repository where it opens its pull request.
- Quick edits. If the change is five lines, writing it yourself is faster than writing the issue, waiting, and reviewing.
- Teams that cannot review promptly. An agent can produce pull requests faster than humans can read them. That is a bottleneck, not a win.
A Gentle Way to Start: The Trust Ladder
We would not begin with a migration. Each rung below earns the next one, and you should stay on a rung until the pull requests feel boring.
Rung 1: Add tests for one existing function
Rung 2: Fix one bug that you can reproduce
Rung 3: Small refactor inside one module with a file list
Rung 4: Small feature across two or three layers
Rung 5: Sensitive areas, with a human closely involved
For a safer ladder on older code, our notes on refactoring code with AI without breaking it pair nicely with rung 3.
Why the Agent Is a Good Example of Agentic AI
The cloud agent reads a goal, plans, uses tools, observes results, and tries again. That loop is the same one we break down in our explanation of how AI systems plan, act, and adapt. Coding is a friendly place for agents because the workspace is bounded and the tests give instant feedback. Messier real-world tasks usually offer neither.
Final Thoughts
The surprise from our test was not how much the agent could do. It was how much the quality of the issue changed the result. The same agent produced a wide, risky diff from a one-line ticket and a tidy, reviewable pull request from a ticket with a flight plan. And even the tidy one hid a changed behavior that only a human reading the diff would catch.
Treat the coding agent as a fast, tireless teammate who follows the address on the package perfectly and needs you to inspect the delivery every time. Write the issue like you mean it, keep the early tasks small, and the Friday-afternoon backlog gets a lot shorter.
Frequently Asked Questions
Is the Copilot coding agent the same as Agent mode in my editor?
No. Agent mode in an editor works inside your local environment while you watch. The cloud agent works in the background in a GitHub-hosted environment and returns a pull request.
Does the agent merge its own pull request?
No. GitHub documents that Copilot cannot merge its own pull requests, so a human always makes the final call.
What is the best way to give it a task?
Write a short issue with a goal, a list of files it may edit, things that must not change, and the exact test command. Our second attempt used exactly that structure.
Where should I put extra instructions after it starts?
On the pull request, not the original issue. At the time of writing, GitHub's documentation says later issue comments are not seen by the agent, while comments on its pull request (mentioning @copilot) are the way to request changes.
Can it run my tests?
It can run tests and linters in its cloud environment, but that depends on the environment being set up so your project's dependencies install. If the checks seem not to run, review the setup steps in the current documentation.
Which plans include it?
Availability depends on your Copilot plan and on organization settings, and both change over time. Check your own account or GitHub's current plan documentation instead of relying on any article, including this one.
Is it safe to use on a work repository?
It can be, with controls: limit who can assign tasks, start in low-risk repositories, require review, and never put secrets in issues. Your security team should approve the setup for anything sensitive.
What is a good first task?
Adding tests for one existing function. It is easy to verify, low risk, and it teaches you how the agent behaves before you give it more.
Comments
Post a Comment