The cloud agent is the one where nobody is watching.
You assign an issue or describe a task. GitHub provisions an environment, the agent works, and a pull request appears. The first time it happens it feels like a step change. The second time you read the diff carefully and discover it is a contribution from a competent stranger who did not ask any questions — which is exactly what it is, and a much more useful frame than the first one.
What it is
Section titled “What it is”GitHub’s asynchronous coding agent. It runs in a GitHub-hosted environment powered by GitHub Actions, works on a branch, and returns a pull request.
The documented operating limits, which shape how you use it:
| Limit | Consequence for you |
|---|---|
| One branch per session | It works in one place; parallel work needs parallel sessions |
| One pull request per task | The output is a single, reviewable unit |
| One repository per session | Cross-repository changes need coordination outside the agent |
| A session time limit (currently 59 minutes) | Tasks must be completable in that window |
The one-repository limit is the one that most often reshapes a plan. A change spanning a service and its client library is two sessions and two pull requests, which is usually better anyway — but it has to be designed that way from the start.
Assigning work
Section titled “Assigning work”Two routes, and the difference is mostly about where the task text lives.
Assign an issue. Assign it to Copilot the way you would assign it to a person. The issue body is the task, which means an issue written for a human is usually a reasonable brief — and an issue written as “see thread” is not.
Describe a task directly. From the Copilot surface in GitHub, without an issue. Fine for one-off work; worse for anything you will want a record of.
Prefer the issue route for anything non-trivial. It gives you a durable statement of what was asked, links the resulting pull request to it, and lets somebody six months later understand why the change exists. The task description is the specification, and specifications belong in the repository’s history rather than in a chat box.
Everything in writing a task an agent can do applies directly here, and applies harder, because nobody is present to clarify. The five components — observable behaviour, known cause, intended fix with a pattern to follow, verification, and explicit out-of-scope — are the difference between a useful pull request and a confused one.
What happens in the session
Section titled “What happens in the session”-
The environment is provisioned. Ephemeral, GitHub-hosted, Actions-powered. It exists for the session and is discarded.
-
The repository is cloned and the agent begins reading — searching, opening files, building an understanding of the code it is about to change.
-
Setup runs. Dependencies install, the project builds. This step fails more often than people expect, and when it does the agent works without a verification signal.
-
It works the loop. Edit, run, read the result, correct. Commits land on its branch as it goes.
-
It opens a pull request describing what it did, and stops.
You can watch the session log while it runs, and reading a few in full early on is the fastest way to calibrate how much to trust the output. The log shows what it read, what it ran, and where it changed direction — including the moments where it went down a wrong path and recovered, which the final diff does not show.
The environment
Section titled “The environment”Understanding what the agent can reach explains most of what it can and cannot do.
Ephemeral. Provisioned per session, destroyed after. Nothing persists between sessions except what was committed.
Network-restricted by default. It can reach what it needs to work with the repository. Broad outbound access is not the default, and that is a security property rather than an inconvenience.
Configurable through Actions. Because the environment is Actions-powered, you can pre-install dependencies, warm caches and set up services the way you would for a CI job. This is how you fix the “setup failed” problem, and it is worth doing for any repository you will delegate to repeatedly.
Whatever credentials you gave it, and no more. The environment holds what was configured. If it has no cloud credentials, the agent cannot touch cloud infrastructure regardless of what the task says.
That last point deserves emphasis. Do not put production credentials in the agent’s environment. Not deployment keys, not cloud administrator credentials, not production database access. If a task appears to require them, the task is wrong for this tool — route the privileged step through a reviewed pipeline that runs after a human approved the change.
Configuring the environment properly
Section titled “Configuring the environment properly”The difference between a repository that delegates well and one that does not is usually setup, and it is entirely within your control.
The problem. The agent provisions a fresh environment, clones the repository, and tries to make it
work. In a project with a straightforward npm ci that succeeds. In a project needing a specific runtime
version, a database, environment variables or a private registry, it does not — and the session continues
without tests.
The fix. Because the environment is Actions-powered, you can prepare it the same way you prepare CI. A setup step that installs the right runtime, brings up the services the test suite needs, and populates non-secret configuration turns a session with no verification signal into one with a full test suite.
What to include:
The runtime version you actually use. Not the environment’s default.
Dependency installation, cached. A session that spends eight minutes of its window installing packages has eight fewer minutes to work.
Services the tests need. A database, a cache, a message broker — as service containers, populated with fixtures.
Non-secret configuration. Test database URLs, feature flags, anything the suite reads from the environment. Non-secret is doing load-bearing work in that sentence.
What not to include:
Real credentials of any kind. Production, staging, cloud, third-party API keys with billing attached. The test suite should run against local services or recorded fixtures.
Anything that reaches outside the session. A setup step that deploys, writes to a shared bucket, or mutates a shared database has given a session with no supervision a way to affect things outside itself.
The check that tells you it worked: look at a session log and confirm the test command ran and reported. If it did not, everything downstream is unverified, and fixing setup is a higher-value hour than any amount of prompt tuning.
Permissions and identity
Section titled “Permissions and identity”The agent acts as a distinct identity, and its permissions are the real boundary.
Give it strictly less than a human contributor has. Enough to read the repository, push to its own branch and open a pull request. Nothing more.
Never grant it the ability to:
- Merge to a protected branch
- Modify branch protection or rulesets
- Dismiss reviews
- Administer the organisation
- Access production systems
Its pull requests are subject to your rules. Required checks run. Required approvals apply.
CODEOWNERS requests the right reviewers. This is the property that makes the whole arrangement safe,
and it holds only as long as nobody has carved out an exception for the agent.
Untrusted input
Section titled “Untrusted input”A delegated agent reads content other people wrote. That is the security model to reason about.
Where it comes from: issue bodies and comments, pull request descriptions, repository content including dependencies, and anything a configured MCP server returns.
On a public repository, anyone can open an issue. If issues can be assigned to the agent, the task text is attacker-influenceable.
The defence is bounded authority, not filtering. The agent works on a branch. Its output is a pull request. It cannot merge, cannot alter protection, and holds no production credentials. Text that persuades it to do something unhelpful produces a bad pull request, which your review catches — the same outcome as a bad pull request from any other source.
The practical control: be deliberate about who can assign work to the agent, and treat agent pull requests originating from externally-filed issues with the scepticism you would give any external contribution. See secure AI code review for the same trust model applied to review.
The session log
Section titled “The session log”The artefact people ignore, and the one that answers most questions about what actually happened.
The final diff shows the destination. The log shows the route, and the route contains information the destination does not:
Whether setup succeeded. Already covered, and the single most important thing in the log.
What it read before deciding. An agent that opened three files and started editing understood less than one that explored for ten minutes. The confidence of the pull request description does not vary with either.
Where it changed direction. A session that tried one approach, found it did not work, and started again produced a diff that looks clean and a decision that was harder than it appears. Worth knowing when you are deciding how carefully to read.
What it could not do. Blocked network calls, missing tools, permission denials. These often explain an odd choice in the diff — it worked around something rather than solving it.
Whether the tests passed on the first attempt or the fifth. Five attempts means five changes to make a signal go green, and at least one of those is worth looking at.
How to use it in practice. Read the first few sessions in full to calibrate. After that, skim for three things: did setup run, did tests run, and did it change direction. Those three take a minute and tell you how much scepticism the pull request deserves.
Keep it for the record. When somebody asks in three months why a change was made this way, the log plus the linked issue is the answer. This is the auditability that supervised sessions get for free from somebody having watched.
Reading the pull request
Section titled “Reading the pull request”The session is over and the diff is all you have. Read it in this order.
The file list, before any code. Does the scope match the task? A bug fix touching fourteen files including a workflow and a lockfile is scope drift, and it is visible in three seconds.
Anything under .github/. Workflow changes, instruction files, agent definitions. Almost never
legitimate for a feature task, and the highest-consequence thing an agent can touch.
New dependencies. A package added is a supply-chain decision. Was it necessary? Is it maintained? See dependency review.
The tests, against the requirement. Not against the implementation. Agent-written tests frequently assert what the code does rather than what it should do, and that distinction is invisible unless you go back to the task.
Whether setup actually succeeded. From the session log. If it did not, the change has not been verified by anything.
The code itself, last, with the failure modes from coding agents in mind — symptom fixes, confident incompleteness, and the cascade from a wrong early step.
Then the question no automated layer answers: is this the change we wanted? The agent produced something consistent with its reading of the task. Whether that reading was yours is the human’s call.
Iterating
Section titled “Iterating”The pull request is a starting point, not a delivery.
Comment on the pull request. The agent can pick up review feedback and push follow-up commits, which works well for bounded corrections — “use the existing helper”, “this needs the error case”.
Know when to stop iterating. Three rounds of feedback on the same misunderstanding means the task was wrong, not the execution. Close it, rewrite the issue, and start again. Iterating on a bad specification is the most reliable way to waste an afternoon.
Take it over locally when the remaining work is judgement. Check out the branch and finish it. The agent got you to a starting point; there is no obligation to keep it in the loop for the part that needs a person.
Delegating at team scale
Section titled “Delegating at team scale”One person assigning one issue is a demonstration. A team routing part of its backlog through the agent is an operating model, and it has different problems.
Review capacity is the constraint, not agent capacity. Ten delegated tasks produce ten pull requests that need ten careful reviews from people who did not write them. Reviewing an unfamiliar change is slower than reviewing a teammate’s. Delegate no faster than you can review, and be honest about what that rate is — it is lower than the enthusiasm of the first week suggests.
Decide who owns each delegated task. A pull request with no owner sits. The person who wrote the issue owns the review and the merge, and that ownership should be explicit before the task is assigned rather than discovered afterwards.
Label them. An agent label on the pull request makes the population visible, and makes it possible
to ask questions about it later — how many, how much rework, how many merged as-is.
Watch the rework rate. Of the last twenty agent pull requests, how many merged without substantial human changes? A low number is information about your task-writing, not about the agent. It usually means the tasks were underspecified, and the fix is upstream.
Do not let it become the backlog’s dumping ground. The tasks nobody wants are frequently the ones that are hard to specify, which makes them the worst delegation candidates. The pattern to avoid is assigning the unpleasant tail of the backlog to the agent and generating a queue of pull requests nobody wants to review either.
Keep a human doing the same class of work. A team that delegates all of one category — all the test coverage, all the small fixes — loses touch with that part of the codebase. That is a real cost, paid slowly, and it is the same argument as the one about what review is for besides finding defects.
When to use it, and when not to
Section titled “When to use it, and when not to”Good fits:
- Well-specified bug fixes with a reproducing test
- Mechanical changes across many files
- Adding a feature that closely follows an existing pattern
- Test coverage for existing, stable behaviour, where the expected results are unambiguous
- Documentation that can be derived from code rather than from institutional knowledge
- Dependency updates with a test suite that means something
Poor fits:
- Anything architecturally consequential
- Work spanning repositories
- Tasks needing production access
- Anything you cannot specify without a conversation
- Work under time pressure — asynchronous means you wait, and the review is not shorter
- Repositories with no tests, where nothing verifies the output
The honest summary: it is very good at work you understand well enough to specify precisely and would rather not do. It is poor at work you were hoping it would figure out.
Comparing it to the local surfaces
Section titled “Comparing it to the local surfaces”The same task, three ways, and the differences are not about capability.
Agent mode in your IDE. You watch. Wrong turns are caught in seconds. You learn what the model understood about your codebase, which is information you keep. Cost: your full attention for the duration, and it is your machine and your credentials in reach.
Copilot CLI in your terminal. The same supervision, with the shell as the main tool. Better for anything where the work is running commands rather than editing files. Same attention cost.
The cloud agent. No attention during. Full attention at review. Your machine is not involved and your credentials are not in reach — a real security advantage that is rarely mentioned.
How to choose:
| If | Use |
|---|---|
| You are unsure what the change should be | Agent mode — you need to watch and steer |
| The task is command-heavy | CLI |
| The task is precisely specified and you have other work | Cloud agent |
| The work touches something you would not want a session to reach | Cloud agent, with a restricted environment |
| You need it in the next ten minutes | Local — asynchronous is not faster |
| You want to learn the codebase yourself | None of them |
The last row is not a joke. Delegating the work you were about to learn from is a trade, and it is worth making deliberately rather than by default.
The total-time observation. Delegating does not reduce the work; it moves it. Specification plus review is often comparable to just doing it, and the win is that specification and review happen at times you choose, while the work happens while you are doing something else. That is a genuine advantage for a queue of well-understood tasks and no advantage at all for a single task in front of you.
Common mistakes
Section titled “Common mistakes”Assigning an underspecified issue. “See thread” is not a task. The agent has no thread.
Trusting the completion summary. It says the loop ended. Check whether setup succeeded and whether the tests test anything.
Putting production credentials in the environment. There is no task worth this.
Creating a branch protection exception for the agent. Removes the layer that catches everything else.
Reviewing agent pull requests less carefully because CI is green. Nobody watched the work.
Planning cross-repository work as one session. One repository per session; design for it.
Iterating past the third round. The specification is wrong. Rewrite it.
Ignoring .github/ changes in the diff. The highest-consequence files, and easy to scroll past.
Mental model
Section titled “Mental model”A competent contributor who read your issue and nothing else.
They know the repository as well as reading it during one session allows. They followed the brief as written. They did not ask a clarifying question because there was nobody to ask. They believe they finished.
Everything about how you use the cloud agent follows from that: write the brief as if for a stranger, give them the least access that lets them work, and read what comes back the way you would read any contribution from someone who does not know what you left out.
What you learned
Section titled “What you learned”- The cloud agent runs GitHub-hosted and asynchronous, one branch and one pull request per session, one repository, within a session time limit
- Assigning an issue gives a durable specification; the issue body is the entire brief
- Setup failure silently removes the verification signal — check the session log
- The environment is ephemeral and network-restricted; never place production credentials in it
- The agent identity must have strictly fewer permissions than a human, and never a protection exception
- Untrusted input is handled by bounded authority, not filtering
- Read the file list,
.github/changes, new dependencies and the tests before the code
Exercise
Section titled “Exercise”Use a disposable repository with the coding agent enabled. No production credentials.
-
Write a precise issue with observable behaviour, intended fix, verification and out-of-scope. Assign it to the agent.
-
Watch the session log. Note where it changed direction, and whether setup succeeded.
-
When the pull request arrives, read the file list first. Predict: does the scope match?
-
Read the tests against the issue text rather than against the diff. Predict: do they test the requirement?
-
Assign a deliberately vague issue. Compare the two pull requests. Predict: how much longer does the second take to review?
-
Confirm branch protection blocks the agent’s pull request without a human approval.
-
Leave a review comment asking for a bounded change. Note how the follow-up commit compares to the original.
-
Delete the repository.