Tasks are stored in a unified SQLite database (~/.orch/orch.db) and synced to GitHub Issues (when gh.enabled: true). External tasks from GitHub are ingested into the store on each sync tick, so the store always has the latest data. Orch centralizes GitHub API calls via the server and uses a native HTTP client (reqwest) or the gh CLI internally.
Setup
- Install and authenticate (preferred methods shown):
# Recommended: set a Personal Access Token (non-interactive)
export GH_TOKEN="ghp_xxxxxxxxxxxxxxxxxxxx"
# Or: configure GitHub App credentials in ~/.orch/config.ymlOptional legacy interactive flow:
gh auth login- Configure in
config.yml:
gh:
enabled: true
repo: "owner/repo"- Optionally set up a GitHub Project v2:
orch project board list # list accessible Project v2 boards
orch project board link PVT_xxx # link this repo to a board
orch project board sync # (re-)discover field/option IDs and persist to .orch.yml
orch project board info # show current board configHow It Works
Task ID = Issue Number. When you run orch task add "Fix the login bug", it creates a GitHub issue and returns the issue number.
Field → GitHub Mapping
| Task Field | GitHub Storage |
|---|---|
| title | Issue title |
| body | Issue body |
| status | Label status:new, status:routed, etc. |
| agent | Label agent:claude, agent:codex, etc. |
| complexity | Label complexity:simple/medium/complex |
| labels | Issue labels (non-prefixed) |
| parent_id | Sub-issue relationship |
| summary, response | Structured comment with <!-- orch:agent-response --> marker |
| branch, worktree | SQLite store (~/.orch/orch.db) |
Agent Response Comments
When an agent completes a task, orch posts a structured comment:
- Agent badges: 🟣 Claude, 🟢 Codex, 🔵 OpenCode
- Metadata table: status, agent, model, attempt, duration, tokens, prompt hash
- Sections: errors & blockers, accomplished, remaining, files changed
- Collapsed sections: stderr output and full prompt (with hash)
- Content-hash dedup: identical comments not re-posted
Labels
status:<status>— task status (new,routed,in_progress,done,needs_review,blocked)agent:<agent>— assigned agentcomplexity:<level>— routing complexityblocked(red) — applied when task is blocked, removed when unblockedscheduledandjob:{id}— for job-created tasks- When task is
done,auto_closecontrols whether to close the issue
Local Task State
Machine-specific fields (branch, worktree path, attempt count, agent, model, pr_number, memory) are stored in the unified SQLite database (~/.orch/orch.db). These fields are not synced to GitHub.
Backoff
When GitHub rate limits or abuse detection triggers, orch sleeps and retries with exponential backoff:
gh:
backoff:
base_seconds: 30 # initial backoff duration
max_seconds: 900 # maximum backoff durationProjects (Optional)
Link tasks to a GitHub Project v2 board:
gh:
project_id: "PVT_..."
project_status_field_id: "PVTSSF_..."
project_status_map:
backlog: "option-id-1"
in_progress: "option-id-2"
review: "option-id-3"
done: "option-id-4"Discover IDs automatically:
orch project board info # show current project field/option IDs
orch project board sync # (re-)discover and persist to .orch.ymlOwner Feedback
When the repo owner comments on a GitHub issue linked to a completed task, orch detects the feedback and re-activates the task:
- Tasks with status
done,in_review, orneeds_revieware checked for new owner comments - If new comments are found, the task is reset to
routed(keeping its agent assignment) - The feedback is appended to the task context so the agent sees it on re-run
Slash Commands
Owner comments can also start with a slash command on the first line (case-insensitive). Parsed by src/engine/commands.rs.
| Command | Action |
|---|---|
/retry | Reset task to status:new (clears agent + attempts) |
/reroute [agent] | Re-route the task (optionally forcing a specific agent) |
/unblock | Clear blocked state and reset to status:new |
/block [reason] | Mark the task blocked with an optional reason |
/close | Mark status:done and close the issue |
/review | Trigger / re-trigger the review agent on the linked PR |
To change agent or complexity without using a slash command, add the corresponding label directly on the issue (agent:claude, complexity:medium, etc.) — the engine picks up label changes on the next sync.
Notes
- The repo is resolved from
config.ymlorgh repo view - Tasks with
no_ghorlocal-onlylabels are skipped - Agents never call GitHub directly; orch handles all API calls so it can back off safely. The runner injects
GH_TOKENat spawn time for convenience, but agents should not perform repository writes or API calls — orch performs these actions to maintain a single place for backoff and rate-limit handling.