1Overview
A coding agent that runs as a CI job — triggered by a repository event rather than by you opening an editor — and delivers its work as a pull request.
Every coding assistant in this course so far waits for you to open it. This chapter is about the other mode: an agent that wakes on a label, an issue or a pull request, does the work while nobody is watching, and hands back a diff for review. → The tools are first-party and live — Anthropic's claude-code-action and the open-source OpenHands — but the chapter is mostly about the part that is not the tool: what an unattended agent is allowed to touch, what it costs when it loops, and who reviews what it produces. → An interactive agent that makes a bad call wastes a minute of your attention. An unattended one merges it.
Coding agents you do not sit in front of: triggered by an issue or a label, running in CI, opening a pull request when they are done. The mechanics are ten minutes of YAML; the chapter is about permissions, cost ceilings and the review gate that decides whether this is leverage or a very fast way to merge nonsense.
1.2After this chapter you can
→Trigger a coding agent from an issue label or a pull-request comment
→Give it the narrowest set of permissions that still lets it finish the job
→Cap what a runaway loop can spend before it spends it
→Decide what an unattended agent may merge on its own and what always needs a human
→Read the run log of a failed agent job and tell a bad prompt from a bad permission
→Say honestly which tasks are worth automating this way and which are not
1.3When to reach for it
Repetitive, well-specified, reviewable work: dependency bumps, test backfill, mechanical refactors, first-pass triage of a bug report. Not open-ended design.
1.4Key parts
A trigger (label, issue, comment), a runner with a scoped token, the agent itself, a spend ceiling, and a human review gate before merge.
1.5Free vs paid
The runner and the action are free and open; the model tokens are not. An unattended agent bills whether or not it succeeded, which is why the ceiling comes before the first run.
1.6Watch out
The default token is usually far broader than the job needs, and an agent that can push to main is a security boundary you removed by accident.
2Lessons 7
2.1 Run Claude Code via an issue comment or label
Wire a GitHub Action so an agent responds to an @‑mention or a label instead of waiting for you to open an editor
- Add the required secret via Settings → Secrets and variables → Actions → New repository secret
- Install the Claude GitHub App on the repository from its marketplace page
- Create a workflow file by copying
examples/claude.yml into .github/workflows/claude.yml in your repo - Commit the new workflow file to the default branch using the Commit changes button
- Post a comment containing
@claude … on an issue or pull request and watch for the app’s reply - Apply a label (e.g.,
claude-fix) to an issue after configuring label_trigger in the workflow
- You'll see A comment from the “Claude” GitHub App appears on the issue or PR within roughly a minute, then edits itself in place as the agent reads the repository, makes changes, and (if it succeeds) links a new branch or pull request
- Takeaway The workflow file decides what event starts a run; the GitHub App decides what the agent is allowed to touch once it starts; you need both installations
- Check What determines whether an issue comment or label will trigger the Claude Code agent?
- Cost Free to set up. Running it spends two separate things: GitHub Actions minutes (billed by GitHub) and API tokens (billed by Anthropic, or drawn from your Claude subscription if you used an OAuth token instead of an API key). Neither is metered by "success" — a run that fails still spent both.
2.2 Verify a tool’s current repository and endpoint
Confirm the live name, organisation and API URL of an open‑source coding agent before using any tutorial that references it
- Open your web browser and paste the legacy URL https://github.com/All-Hands-AI/OpenHands into the address bar, then press Enter
- Observe the GitHub redirect banner that appears, confirming the repository now lives at https://github.com/OpenHands/OpenHands
- Navigate to the new repository’s README and locate the usage snippet that still references uses: All-Hands-AI/openhands-github-action@v1 and the endpoint https://app.all-hands.dev
- Visit the OpenHands Cloud sign‑in page at https://cloud.openhands.ai, click the Sign in button, and connect your GitHub account to a repository
- Add the label
openhands to an issue or comment @openhands on a pull request; watch OpenHands create a new pull request automatically
- You'll see A GitHub banner stating “This repository has moved” when you visit the old All‑Hands‑AI/OpenHands address
- Takeaway Always check the URL and publication date before trusting a setup guide
- Check How can you confirm that the OpenHands repository has moved to a new URL before following its setup guide?
- Cost Free — this is a five-minute verification habit, not a tool.
2.3 Limit an agent's permissions to only what it needs
Scope the token used by an unattended Claude Code Action so it can only read and write the repository elements required for its job
- Create a personal GitHub App that requests only Contents, Issues, and Pull requests permissions
- In your workflow file, set the github_token input to the token generated by your own app instead of the shared Claude GitHub App
- Add a permissions: block to the job definition and list exactly the scopes needed, e.g.
contents: write, issues: write, pull-requests: write (plus any required id-token or actions reads) - Commit the updated workflow and run it on a test branch
- Observe the Actions log; if the job attempts an operation not listed in permissions: it fails with a 403 error
- You'll see The run aborts with an HTTP 403 in the Actions log when it tries to act outside the declared permissions block
- Takeaway Both the App or PAT supplied via github_token and the job‑level permissions: block default to broad scopes, so you must tighten each before any real execution
- Check Which part of the workflow file must list specific scopes to prevent the agent from performing unauthorized actions?
- Cost Free. Scoping a custom GitHub App or a
permissions: block takes longer to set up than accepting the default (maybe twenty extra minutes once), and costs nothing to run.
2.4 Limit costs of an unattended agent
Workflow cost‑limit settings (timeout‑minutes, max‑turns, concurrency)
Set three limits that stop an unattended agent from overspending time and money on a single run
- Edit the workflow file and add timeout-minutes to the job definition to bound wall‑clock execution
- Add a claude_args input to the Claude Code Action step with
--max-turns set to the desired limit - Insert a concurrency block with a group name so overlapping triggers are queued or cancelled
- You'll see The Actions run stops when the turn limit is reached and logs a message indicating the max‑turns cap was hit
- Takeaway Wall‑clock time, token usage and concurrent runs each need their own cap to prevent runaway bills
- Check What three settings can you add to a workflow to stop an unattended agent from exceeding time, token usage, or concurrent runs?
- Cost The ceilings themselves are free lines in a YAML file. What they cap is real spend: GitHub Actions minutes at GitHub's published per-minute rate, and API tokens at Anthropic's published per-token rate (or your Claude subscription's included usage, if you authenticated with an OAuth token instead of an API key).
2.5 Choose which changes can auto‑merge
Set up repository rules so only safe agent output merges automatically while other output requires human review
- Open your repository on GitHub and navigate to Settings
- Select Branches, then click Add rule under Branch protection rules
- Enable Require pull request reviews before merging and Require status checks to pass in the new rule
- Make sure the agent’s token does not have Write permission on the protected branch
- When an agent creates a PR, open the PR and examine the Files changed tab before approving or merging
- You'll see A pull request from the Claude or OpenHands bot appears like any other PR and stays pending until a human reviews and merges it
- Takeaway The decision to auto‑merge is controlled by your branch‑protection settings, not by the agent itself
- Check Which repository configuration ensures that only reviewed pull requests created by the agent can be merged automatically?
- Cost Free — this is a policy decision and a branch-protection setting, not a paid feature.
2.6 Identify why an unattended run failed
Determine whether a failed unattended run was caused by a misunderstanding of the task or by a permission block
- Open the repository’s Actions tab
- Select the relevant workflow run and view its log
- Look for an early HTTP 403 or 404 status line in the log
- Open the issue or pull request and locate the agent’s comment thread (the conversation)
- Compare the comment content with the log to see if it stopped abruptly or produced a result
- Trigger a small test run that requests a disallowed permission and another that asks an ambiguous question, then observe both failure patterns
- You'll see The Actions run log shows either an early HTTP 403/404 status or a complete execution ending with a result comment
- Takeaway Early 403/404 indicates a permission issue, while a full run that produces the wrong output signals a prompt or scope problem
- Check In diagnosing a failed unattended run, what log evidence indicates a permission problem versus a task‑understanding issue?
- Cost Free to read. Reproducing a failure to practice on it costs one more run — a few cents of tokens and a minute of Actions time at most, if you keep the test task small.
2.7 Decide when not to automate a task
Choose tasks that should remain manual because the risk of unattended execution outweighs any time saved
- Read the full task description and ask whether you can express the required outcome in one clear paragraph
- Check if the task’s difficult part is defining correctness rather than performing a known action
- If the answer requires judgement or design decisions, mark the task as unsuitable for an unattended agent
- You'll see No new artefact appears; you simply have confidence that the task cannot be safely specified for an autonomous run
- Takeaway Automate only well‑specified, cheap‑to‑verify work and keep a human in the loop whenever deciding what “correct” looks like is the hard part
- Check What question should you ask about a task’s outcome description to decide it is unsuitable for automation?
- Cost Free, and arguably the cheapest lesson in the chapter — the cost of skipping it shows up later, as a merged pull request nobody meant to approve.