docs/adr/0021-task-pull-requests.md
ADR-0021: Task pull requests through the gh CLI
Status: Accepted, 2026-10-05. Spec: 020-pr-cycle.
Context
ADR-0020 deferred the PR/CI cycle: a finished task could only merge locally.
Opening a PR and reading CI and review state needs GitHub credentials. The
server runs as the user and already shells out to git.
Decision
- The server runs the user's
ghCLI (gh pr create,gh pr view --json) andgit push -u origin <branch>from the task worktree. signaltty stores no token and adds no HTTP client: auth, hosts and enterprise config are whatevergh authalready has. - Each call runs off the async runtime with a 60 s deadline. Failure records
nothing;
gh's stderr comes back indetails.stderr. - A PR is not a disposition.
Task.prsits besidedisposition, so the existing finish paths keep their meaning: discard cleans up after the PR lands, and a local merge is refused while a PR is open. - State is read on demand (
task.pr_refresh, and when the board opens), not polled. Polling, CI auto-paste andgh pr mergeare additive later.
Consequences
gh becomes an optional runtime dependency: only task.pr_* need it, and
its absence is a clean SPAWN_FAILED. Tests use a fake gh script on the
server's PATH and a local bare repository as origin.