# Label a GitHub issue, your agent works it on your Prized box

> Add the prized label to a GitHub issue and the Claude Code or Codex on your Prized box works it and opens a pull request; a /prized comment on that pull request continues the same session. A small poller you run on the box, not a GitHub App.

URL: https://prized.dev/docs/github-issues
Updated: 2026-11-01

`prized_issues.py` is a small script you run on a box. It checks a repo every minute: when you add the `prized` label to an issue, it runs your own Claude Code or Codex on it in a fresh git worktree, pushes a branch and opens a pull request that closes the issue. A `/prized` comment on that pull request continues the same agent session, on the same worktree, with everything the agent already read and changed.

It is not a GitHub App: nothing is installed on GitHub, and it runs only on your box, with a GitHub token you make for one repo. The agent uses the sign-in on the box, so its runs count against your Claude or ChatGPT plan.

## 1. Make a box that stays awake [#1-make-a-box-that-stays-awake]

```bash
prized box new issues --size Nano --auto-pause off --wait
```

A paused box checks nothing, so this one stays on; [What it costs](https://prized.dev/docs/run-claude-code-on-a-schedule#what-it-costs) has a Nano awake around the clock. A box used only for this keeps your other sign-ins (the GitHub CLI, SSH keys, cloud keys) out of the agent's reach. If it isn't your first box, connect it:

```bash
prized init --box issues
```

## 2. Sign your agent in on it [#2-sign-your-agent-in-on-it]

```bash
prized --box issues agents handoff claude
```

For Codex, `prized --box issues agents handoff codex`. For runs nobody watches, a long-lived Claude Code token avoids a sign-in that expires ([Sign in first](https://prized.dev/docs/remote-agents#sign-in-first)).

## 3. Make a GitHub token for the repo [#3-make-a-github-token-for-the-repo]

Open [this link](https://github.com/settings/personal-access-tokens/new?name=prized-issues\&expires_in=90\&contents=write\&issues=write\&pull_requests=write): it fills in a fine-grained token with **Contents**, **Issues** and **Pull requests** set to read and write. Under **Repository access** pick **Only select repositories** and your repo, then generate it and copy it.

* **No Workflows permission.** GitHub then refuses any push that changes `.github/workflows`.
* **One repo.** The script refuses a classic token, which reaches every repo you can.

## 4. Start it on the box [#4-start-it-on-the-box]

```bash
prized ssh issues
```

```bash title="you@issues ~"
curl -fsSLO https://raw.githubusercontent.com/prized-dev/integrations/main/github-issues/prized_issues.py
python3 prized_issues.py watch OWNER/REPO
```

Paste the token when it asks. It creates the `prized` label, clones the repo and starts a timer that checks for new labels and comments every minute. To add teammates whose labels and comments count, or to run Codex, run it again with the change: `watch OWNER/REPO --members alice,bob`, `watch OWNER/REPO --agent codex`.

## 5. Label an issue [#5-label-an-issue]

Add the `prized` label to an issue. Within about a minute the box comments that it's working; the pull request follows, on branch `prized/issue-N`, with the agent's own summary as its description. To ask for more, comment on the pull request:

```text title="Comment on the pull request"
/prized also handle ß and ø, with a test for each
```

The same session continues on the same worktree and the new commit lands on the pull request. If anyone pushed to the branch meanwhile, the box builds on that, edits only, and holds the change for `/prized push`.

## Commands [#commands]

| On GitHub | What happens |
| --- | --- |
| Add the `prized` label | A run on the issue, then a pull request that closes it |
| `/prized <request>` on the pull request | The same session continues and pushes to the same branch |
| `/prized push` | Pushes a held change (below) and opens the pull request |
| `/prized drop` | Throws a held change away; the label then starts fresh |
| `/prized` | A short help comment |
| Remove the label and add it back | A fresh run once the issue's pull request is closed; while it's open, a pointer to it |

| On the box | What it does |
| --- | --- |
| `python3 ~/.prized-issues/prized_issues.py` | What it watches and the last 20 runs |
| `python3 ~/.prized-issues/prized_issues.py watch OWNER/REPO` | Add another repo, with its own token, or change a repo's members, agent, label or base branch; it changes only what you name (`python3 ~/.prized-issues/prized_issues.py watch --help` lists them) |
| `python3 ~/.prized-issues/prized_issues.py poll --dry-run` | Which labeled issues would run, and why the others don't |
| `python3 ~/.prized-issues/prized_issues.py off` | Stop it; `off OWNER/REPO` stops one repo |

Each run has a log in `~/.prized-issues/logs/`. A repo with `.prized/setup.sh` on its base branch gets that script run in each new worktree (installs, a build) before the agent starts.

## How long it takes [#how-long-it-takes]

Up to a minute until the next check, then the agent's own time. On a small Python repo with Claude Code, a one-function fix with a new test took 13 to 17 seconds from that check to the pull request, and a follow-up on the same session 7 to 9 seconds. Larger changes take as long as the agent works; each turn stops after 2 hours.

## Who can start a run [#who-can-start-a-run]

* **Members only.** The token's owner and anyone added with `watch OWNER/REPO --members alice,bob`. A label or `/prized` comment from anyone else is ignored, even with write access to the repo.
* **Members' text runs with full permissions** (`claude --dangerously-skip-permissions`, `codex --dangerously-bypass-approvals-and-sandbox`), so the agent can install, build and run tests. Label only issues you'd paste into the agent yourself.
* **Text anyone else wrote or edited runs edits only, with Claude Code.** The agent can read and edit files in the worktree and nothing else: no commands, no network. Its change is held on the box and the issue gets the list of changed files; nothing is pushed until a member comments `/prized push`. Follow-ups in that session stay edits only. Codex has no mode like this, so with `--agent codex` such text doesn't run.
* **A follow-up on a branch someone else pushed to runs edits only too,** and is held the same way: the box can't tell who pushed to `prized/issue-N`.
* **An issue edited after the label went on doesn't run.** Remove the label and add it back to run it as it reads now.

## Before you rely on it [#before-you-rely-on-it]

* **Every push is checked first.** It is refused, with a comment saying why, if it changes `.github/workflows`, adds a symlink, a submodule or a file over 5 MB, or holds something shaped like a key or token in a file, a file name or a commit message.
* **The token stays on the box,** readable only by your user and never handed to the agent; an edits-only run can't reach it. An agent running with full permissions could still read it, so keep it to one repo.
* **Full permissions run the repo's own code** as the base branch has it: its tests, its setup script and any agent settings in it. Protect that branch as you would for CI.
* **A held change is untested.** Read its diff on the box before `/prized push`; the comment gives the command.
* **One run at a time.** A follow-up or a new label waits for the run in progress.
* **Pull request comments only.** `/prized` in a review or an inline code comment isn't read.
* **A footer.** Pull requests end with "Opened by prized-issues" and a link to this page; edit it out if you like.

## Stop it [#stop-it]

```bash title="you@issues ~"
python3 ~/.prized-issues/prized_issues.py off
```

Then delete the token on GitHub. `rm -r ~/.prized-issues` removes the clone, the worktrees, the logs and the saved token. The script's source and tests are in [prized-dev/integrations](https://github.com/prized-dev/integrations/tree/main/github-issues).
