Arbiter Documentation

Arbiter is an autonomous GitHub issue solver that uses AI to automatically find, implement, and submit solutions to issues in your repositories.

Autonomous Workflow

Finds issues, creates branches, implements solutions, and opens PRs automatically.

Multiple AI Workers

Supports Claude Code, Codex, OpenCode, Ollama, LM Studio, and Cursor Agent for flexibility.

Built-in Validation

Runs tests, validates diffs, and optionally reviews code with AI before creating PRs.

Real-time Monitoring

Web dashboard with live logs, configuration management, and work history.

Quick Start

Get Arbiter up and running in minutes.

Prerequisites

  • Node.js 18+ with native fetch support
  • GitHub Personal Access Token with repo access
  • Git configured with credentials
  • An AI worker (Claude Code, Codex, OpenCode, Ollama, LM Studio, or Cursor Agent)

Installation Options

Choose your preferred installation method:

Option 1: Homebrew (macOS/Linux)

Terminal
brew install git-arbiter/tap/arbiter
arbiter --version

Option 2: npm (All Platforms)

Terminal
npm install -g @git-arbiter/arbiter
arbiter --version

The npm package automatically downloads the appropriate binary for your platform.

Option 3: Docker

Terminal
docker pull gitarbiter/arbiter:latest

docker run -d \
  -p 3927:3927 \
  -v ~/.arbiter:/home/arbiter/.arbiter \
  --name arbiter \
  gitarbiter/arbiter:latest

Access the UI at http://localhost:3927 after starting the container.

Docker Compose with Host CLI Tools (Recommended for Docker)

Mount your host machine's AI CLI tools (Claude, Cursor, Codex, OpenCode, Ollama) into the container:

Terminal
curl -LO https://github.com/Git-Arbiter/arbiter-releases/releases/latest/download/docker-compose.yml

# Edit and uncomment the CLI tools you have installed
nano docker-compose.yml

# Start Arbiter
docker-compose up -d

This allows Docker users to leverage existing AI tool installations without installing them inside the container.

Option 4: Direct Download

Download pre-built binaries from GitHub Releases:

  • macOS ARM64 (Apple Silicon): arbiter-macos-arm64
  • macOS Intel: arbiter-macos-x64
  • Linux x64: arbiter-linux-x64
  • Linux ARM64: arbiter-linux-arm64
  • Windows x64: arbiter-windows-x64.exe
Example: macOS ARM64
curl -L -o arbiter https://github.com/Git-Arbiter/arbiter-releases/releases/latest/download/arbiter-macos-arm64
chmod +x arbiter
sudo mv arbiter /usr/local/bin/

Initial Configuration

After installation, initialize your configuration:

Terminal
arbiter init
nano ~/.arbiter/config.yaml

At minimum, configure:

~/.arbiter/config.yaml
github:
  token: ghp_xxxxx
repos:
  owner/repo:
    enabled: true
    allowPush: true
    allowOpenPr: true

Verify Setup

Terminal
arbiter doctor

Run Your First Task

Terminal
# CLI mode
arbiter run

# Or start the web UI
arbiter ui
# Then open http://127.0.0.1:3927

Configuration

Arbiter is configured via ~/.arbiter/config.yaml. Here's a complete reference.

GitHub Settings

config.yaml
github:
  token: ghp_xxxxx                    # Personal access token
  repos:                              # Repos to monitor
    - owner/repo1
    - owner/repo2
  requiredLabel: agent-ok             # Only process issues with this label
  username: null                      # Filter by assignee (null = any)
  skipLabels:                         # Skip issues with these labels
    - wontfix
    - duplicate
  priorityLabels:                     # Prioritize issues with these labels
    - high-priority
    - urgent
  clone:
    method: https                     # or 'ssh'
    useTokenAuth: true                # Embed token in HTTPS URLs

Runner Settings

config.yaml
runner:
  workdir: ~/.arbiter/workspaces      # Root dir for clones
  baseBranch: main                    # Base branch name

  behavior:
    dryRun: false                     # Skip GitHub write operations
    allowLocalCommits: true           # Create local commits
    enableWorker: true                # Run AI worker
    failIfNoChanges: false            # Error if no changes made

  limits:
    maxChangedFiles: 50               # Max files changed
    maxChangedLines: 2000             # Max total lines changed
    maxRuntimeMinutes: 25             # Worker timeout

  policy:
    forbiddenPaths:                   # Block changes to these
      - .github/workflows/**
      - package-lock.json
    allowedCommands:                  # Allowlist for checks
      - npm test
      - npm run *
      - pnpm *
      - yarn *
    checkTimeoutMinutes: 10           # Timeout per check

  labels:
    prCreated: Arbiter-created        # Label to add to PRs

Auto-Run Scheduler

config.yaml
autoRun:
  intervalMinutes: 60                 # Run every N minutes (0 = disabled)
  enablePrIterations: true            # Process /arbiter-change commands
  prioritizePrIterations: true        # Handle PR iterations first

Worker Types

Arbiter supports multiple AI workers. Choose the one that best fits your needs.

Worker Cost Speed Quality Setup
Claude Code Paid Fast ⭐⭐⭐⭐⭐ Easy
Codex Paid Fast ⭐⭐⭐⭐⭐ Easy
OpenCode Flexible Fast ⭐⭐⭐⭐⭐ Easy
Ollama Free Medium ⭐⭐⭐⭐ Medium
LM Studio Free Medium ⭐⭐⭐⭐ Medium
Cursor Agent Paid Fast ⭐⭐⭐⭐ Easy

Claude Code (Recommended)

Official Anthropic CLI with the best quality and reliability.

config.yaml
worker:
  type: claude-code
  claudePath: claude                  # Path to Claude Code CLI
  model: sonnet                       # sonnet | opus | haiku | opus-4.5
  maxTurns: 50                        # Max conversation turns
  dangerouslySkipPermissions: false   # Skip permission prompts

Codex

OpenAI's Codex CLI for advanced code generation.

config.yaml
worker:
  type: codex
  codexPath: codex                    # Path to Codex CLI
  model: gpt-5.2                      # Model to use
  maxTurns: 50                        # Max conversation turns

OpenCode

Open-source CLI with support for both free and paid models. Works with OpenAI, Anthropic, and local models.

config.yaml
worker:
  type: opencode
  opencodePath: opencode              # Path to OpenCode CLI
  model: gpt-4                        # Model to use (supports OpenAI, Anthropic, local)
  maxTurns: 50                        # Max conversation turns

Note: OpenCode is free and open-source, but costs depend on which model provider you choose. You can use free local models or paid API models.

Ollama (Local & Free)

Run models locally on your machine. Requires GPU for good performance.

Setup
# Install Ollama
curl -fsSL https://ollama.com/install.sh | sh

# Pull a model with tool-calling support
ollama pull llama3.1:8b-instruct-q8_0

# Start Ollama server
ollama serve
config.yaml
worker:
  type: ollama
  url: http://localhost:11434         # Ollama server URL
  model: llama3.1:8b-instruct-q8_0    # Model name
  maxTurns: 30                        # Max conversation turns
  temperature: 0.7                    # Optional: sampling temperature
  topP: 0.9                           # Optional: nucleus sampling

Recommended models: llama3.1:8b-instruct-q8_0, llama3.1:70b-instruct-q8_0, qwen2.5-coder:7b-instruct

LM Studio (Local & Free)

User-friendly local model runner with a GUI.

Setup
1. Download and install LM Studio from https://lmstudio.ai/
2. Download a model with function-calling support
3. Load the model in LM Studio
4. Start the local server (Developer → Local Server)
5. Use the model discovery feature in Arbiter UI
config.yaml
worker:
  type: lmstudio
  url: http://localhost:1234          # LM Studio server URL
  model: model-name                   # Model identifier
  maxTurns: 30                        # Max conversation turns
  temperature: 0.7                    # Optional: sampling temperature
  topP: 0.9                           # Optional: nucleus sampling

Cursor Agent

Cursor's agent CLI for AI-powered code generation.

config.yaml
worker:
  type: cursor-agent
  agentPath: agent                    # Path to agent executable
  model: claude-sonnet-4-5            # Model to use
  maxTurns: 30                        # Max conversation turns

Database Setup

Arbiter supports PostgreSQL and Elasticsearch for persistent log storage. By default, logs are stored in-memory and lost on restart.

PostgreSQL

Best for most users. Simple setup with full-text search.

Setup PostgreSQL
# Install PostgreSQL (macOS)
brew install postgresql
brew services start postgresql

# Create database
createdb arbiter

# Get connection string
# postgresql://username:password@localhost:5432/arbiter
config.yaml
postgres:
  connectionString: postgresql://user:pass@localhost:5432/arbiter

Arbiter will automatically create the necessary tables on first run.

Elasticsearch

Best for large-scale deployments with advanced querying needs.

Setup Elasticsearch
# Install Elasticsearch (macOS)
brew tap elastic/tap
brew install elastic/tap/elasticsearch-full
brew services start elasticsearch-full

# Test connection
curl http://localhost:9200
config.yaml
elasticsearch:
  url: http://localhost:9200
  apiKey: xxx                         # Optional: for authentication
  indexName: arbiter_logs             # Index name

Arbiter will automatically create the index with proper mappings on first run.

How It Works

Understanding Arbiter's workflow helps you use it effectively.

The Run Lifecycle

  1. Check for In-Progress Work

    Arbiter first checks if there's unfinished work from a previous run. If a worker hit turn limits before completing, it resumes from the same workspace.

  2. Fetch Candidate Issues

    Queries GitHub for open issues matching your filters (label, assignee, skip labels). Issues are prioritized by labels and creation date.

  3. Prepare Workspace

    Clones or updates the repository, creates a feature branch (arbiter/issue-{number}-{slug}), and writes task files:

    • ARBITER_TASK.md - Human-readable issue description
    • arbiter.task.json - Structured metadata and checks
  4. Invoke AI Worker

    Spawns the configured worker (Claude Code, Codex, OpenCode, Ollama, etc.) with a specialized prompt. The worker reads the task files, implements the solution, and writes ARBITER_RESULT.json when complete.

  5. Run Validation Pipeline

    If work is complete, Arbiter runs:

    • Validate - Checks diff size and forbidden paths
    • Run Checks - Executes test commands from config
    • Commit - Creates a git commit
    • AI Review (optional) - Second AI instance reviews the code
    • Push (optional) - Pushes branch to remote
    • Open PR (optional) - Creates GitHub pull request
  6. Save State

    Updates state file with outcome. If work is incomplete, it's marked for continuation on the next run.

Continuation Logic

Smart Resumption

If the AI worker runs out of turns before completing work, Arbiter doesn't start over. Instead, it:

  • Preserves the workspace and branch
  • Saves state with status: in_progress
  • On next run, resumes from the same workspace
  • Adds a continuation note to the prompt
  • Increments attempt count

Special Commands

Arbiter recognizes special commands in GitHub issue and PR comments.

#arbiter-note

Add additional context or instructions to an issue that will be included in the worker's prompt.

Example GitHub Comment

What to do:

#arbiter-note Make sure to update both the API endpoint and the frontend component. The validation logic should match the backend schema exactly.

All comments containing #arbiter-note will be extracted and added to the task description under "Additional Notes". This is perfect for:

  • Clarifying ambiguous requirements
  • Pointing to relevant code files
  • Specifying implementation preferences
  • Adding testing instructions

/arbiter-change

Request changes to an existing Arbiter-created PR. This triggers a PR iteration where the AI worker modifies the existing code.

Important: Your comment must start with /arbiter-change followed by your request.

Example PR Comment

/arbiter-change Please refactor the validation function to use a switch statement instead of if-else chains. Also add JSDoc comments to all exported functions.

When you comment /arbiter-change on a PR created by Arbiter:

  1. Arbiter detects the comment on its next run
  2. Clones the repo and checks out the PR branch
  3. Provides the AI worker with the change request and current code
  4. Worker makes the requested changes
  5. Changes are validated, committed, and pushed
  6. Arbiter reacts to your comment with 👀 (eyes) when started, ✅ (checkmark) when complete

PR Iterations Requirement

To use /arbiter-change, you must enable PR iterations in your config:

autoRun:
  enablePrIterations: true
  prioritizePrIterations: true

/arbiter-review

Request an AI code review on any open PR. Unlike automatic reviews, this can be triggered manually on any PR at any time.

Important: Your comment must start with /arbiter-review. You can add additional context after the command if needed.

Example PR Comment

/arbiter-review

When you comment /arbiter-review on any open PR:

  1. Arbiter detects the comment on its next run (highest priority)
  2. Fetches the PR diff and details
  3. Runs AI code review using your repo's configured settings
  4. Posts a detailed review comment with verdict and feedback
  5. Reacts to your comment with 👀 when acknowledged

Works on Any PR

Unlike /arbiter-change, the /arbiter-review command works on any open PR, not just Arbiter-created ones. It uses your repo's AI reviewer settings (mode and worker) if configured.

Review Settings (config.yaml)
repos:
  owner/repo:
    aiReviewer:
      mode: normal              # lax | normal | hyper-critical
      worker: claude-code       # claude-code | codex | opencode | cursor-agent

Review Modes

  • lax - Focus on critical bugs only
  • normal - Balanced review (default)
  • hyper-critical - Strict senior engineer review

Repository Policies

Configure per-repository settings to control Arbiter's behavior for each repo.

config.yaml
repos:
  owner/repo1:
    enabled: true                     # Enable/disable this repo
    baseBranch: main                  # Override default base branch
    allowPush: true                   # Allow pushing branches
    allowOpenPr: true                 # Allow opening PRs
    allowIssueComments: true          # Allow posting comments
    allowRequestReviewers: true       # Allow requesting PR reviews
    openPrAsDraft: true               # Open PRs as drafts
    reviewers:                        # Auto-request reviewers
      - username1
      - username2
    checks:                           # Commands to run before commit
      - npm test
      - npm run lint
      - npm run type-check
    additionalContext: |              # Extra context for AI worker
      This repo uses TypeScript strict mode.
      All components must have prop types defined.
      Follow the existing file structure in src/.
    aiReviewer:                       # AI code review settings
      enabled: true
      mode: normal                    # lax | normal | hyper-critical

Policy Fields Explained

enabled
Set to false to temporarily disable Arbiter for a repo without removing it from the config.
allowPush / allowOpenPr
Control whether Arbiter can push branches and open PRs. Set to false for testing or manual PR creation.
openPrAsDraft
Open PRs as drafts by default. Recommended for safety - review before marking ready.
checks
Commands to run before committing. Arbiter will retry failed checks up to 2 times. If checks still fail, the run is marked as failed.
additionalContext
Free-form text added to every task prompt. Use this to teach Arbiter about your codebase conventions, patterns, and best practices.
aiReviewer.mode
  • lax - Only flag critical issues (security, bugs)
  • normal - Balanced review (bugs, style, edge cases)
  • hyper-critical - Strict review (everything including nitpicks)

PR Iterations

Request changes to Arbiter-created PRs using the /arbiter-change command. The command must be at the start of your comment.

How It Works

  1. Create a PR Comment

    On any Arbiter-created PR, add a comment that starts with /arbiter-change followed by your change request.

  2. Arbiter Detects the Comment

    On the next auto-run (or manual run), Arbiter finds PRs with comments starting with /arbiter-change.

  3. Processing

    Arbiter checks out the PR branch, provides the change request to the AI worker, and the worker implements the changes.

  4. Push Updated Code

    Changes are validated, committed, and pushed to the same branch. The PR is automatically updated.

  5. Notification

    Arbiter adds a 👀 (eyes) reaction when it starts processing, and ✅ (checkmark) when complete.

Best Practices

  • Be specific - Clear instructions get better results
  • One request per comment - Multiple changes in one comment is fine, but separate concerns are easier to track
  • Review the changes - PR iterations can create new commits, so review the diff
  • Set prioritization - Use prioritizePrIterations: true to handle change requests before new issues

Configuration

config.yaml
autoRun:
  enablePrIterations: true            # Enable /arbiter-change processing
  prioritizePrIterations: true        # Process PR changes before new issues

AI Code Review

Enable a second AI instance to review code before opening PRs.

How It Works

When enabled, a separate AI instance reviews the diff and provides feedback:

  • Checks for logic errors and bugs
  • Identifies security vulnerabilities
  • Validates style and conventions
  • Flags missing edge cases
  • Suggests improvements

Review Outcomes

Approve
Code looks good. PR is created and optionally merged.
Request Changes
Issues found. PR is created with review comments listing specific problems. The PR is marked as "Changes Requested".
Comment
Unclear or needs human review. PR is created and labeled with "Human needed" for manual review.

Configuration

config.yaml
repos:
  owner/repo:
    aiReviewer:
      enabled: true                   # Enable AI code review
      mode: normal                    # lax | normal | hyper-critical

Review Modes

  • lax - Only flags critical bugs and security issues
  • normal (recommended) - Balanced review covering bugs, style, and common issues
  • hyper-critical - Strict review including style nitpicks and optimization suggestions

Cost Consideration

AI review requires an additional API call per PR (~$0.10-0.50 depending on diff size and model). Budget accordingly when using paid workers.

Self-Learning Mode

Arbiter can learn from its successful PRs and accumulate codebase knowledge over time.

How It Works

  1. Automatic Extraction

    After each successful PR, Arbiter analyzes the diff and extracts 2-5 key learnings about patterns, conventions, and architecture.

  2. Human Review

    Learnings are stored as "pending" and shown in the Learnings tab for review.

  3. Approval

    You can approve, reject, or edit learnings before they're added to the context.

  4. Context Integration

    Approved learnings are appended to the repo's additionalContext field.

  5. Auto-Consolidation

    After N approved learnings (default: 10), Arbiter consolidates them into a well-organized context document.

Example Learnings

Extracted Learnings
  • All API routes follow REST conventions with /api/ prefix
  • Use Zod schemas for input validation and type inference
  • Database operations use better-sqlite3 with prepared statements
  • UI components use CSS custom properties for theming
  • Error handling includes user-friendly toast notifications

Benefits

  • Faster Onboarding - New runs have access to accumulated knowledge
  • Consistent Patterns - AI learns and follows established conventions
  • Reduced Errors - Learns from past mistakes and edge cases
  • Knowledge Base - Builds a living document of codebase insights
  • Team Alignment - Captures tribal knowledge and best practices

Cost Consideration

Each successful run makes an additional API call to extract learnings (~$0.05-0.15 per run with paid models).

Security

Arbiter executes AI-generated code and interacts with your repositories, so multiple layers of protection are built in to keep your projects safe.

Comment Author Authorization

All GitHub comment commands (/arbiter-change, /arbiter-review, #arbiter-note) require the comment author to have write access or higher on the repository. This prevents unauthorized users from triggering Arbiter in open-source repos.

Permission Checks

Every comment is verified against GitHub's collaborator API. Only write, maintain, and admin roles are authorized.

Fail-Closed

If the permission check fails (API error, network issue), access is denied by default. Arbiter never assumes trust.

Clear Feedback

Unauthorized comments receive a confused reaction so users know their command was rejected.

Cached Lookups

Permission results are cached per polling cycle to minimize API calls while staying up to date.

Execution Sandboxing

Arbiter applies strict limits to all AI-generated changes:

  • Diff Validation — Configurable limits on changed files and lines prevent runaway modifications
  • Forbidden Paths — Block changes to sensitive files like .github/workflows/** and package-lock.json
  • Command Allowlisting — Only pre-approved commands can run as checks
  • Check Timeouts — All check commands have configurable timeouts to prevent hangs
  • Draft PRs — PRs open as drafts by default so humans review before merging

AI Code Review

When enabled, a second AI instance independently reviews every PR for security vulnerabilities, logic errors, and code quality issues before the PR is posted. This acts as an automated second pair of eyes on all generated code.

Token Security

  • Your GitHub token is stored locally in ~/.arbiter/config.yaml — it is never sent anywhere other than the GitHub API
  • Use clone.useTokenAuth: true to embed the token in HTTPS clone URLs rather than relying on system credentials
  • Arbiter never logs or exposes your token in worker output

Defense in Depth

No single security measure is perfect. Arbiter layers authorization checks, execution sandboxing, AI review, and human-in-the-loop PR review to minimize risk. We recommend keeping openPrAsDraft: true and enabling AI code review for maximum safety.

CLI Reference

Complete reference for Arbiter's command-line interface.

Global Commands

Terminal
# Initialize configuration
arbiter init

# Check system health
arbiter doctor

# Start web UI
arbiter ui [--port 3927]

Run Commands

Terminal
# Run once (find issue, solve it, create PR)
arbiter run

# Run with custom config
arbiter run --config /path/to/config.yaml

Workspace Commands

Terminal
# Validate workspace changes
arbiter validate <workspace>

# Commit changes
arbiter commit -m "message" <workspace>

# Push branch
arbiter push <workspace>

# Open PR
arbiter pr <workspace>

Common Workflows

Manual Workflow (No Worker)
# 1. Run Arbiter without worker to create workspace
arbiter run  # with enableWorker: false

# 2. Make changes manually in the workspace
cd ~/.arbiter/workspaces/owner__repo/arbiter-issue-123-...

# 3. Validate changes
arbiter validate ~/.arbiter/workspaces/owner__repo/arbiter-issue-123-...

# 4. Commit
arbiter commit -m "Fix issue #123" ~/.arbiter/workspaces/owner__repo/arbiter-issue-123-...

# 5. Push and create PR
arbiter push ~/.arbiter/workspaces/owner__repo/arbiter-issue-123-...
arbiter pr ~/.arbiter/workspaces/owner__repo/arbiter-issue-123-...

Troubleshooting

Common Issues

"GitHub token invalid"

Problem: Your GitHub token is missing or lacks required permissions.

Solution:

  • Generate a new Personal Access Token at github.com/settings/tokens
  • Required scopes: repo (full control of private repos)
  • Update github.token in your config

"No issues found"

Problem: No issues match your filters.

Solution:

  • Check that issues have the requiredLabel (e.g., "agent-ok")
  • Verify issues are open (not closed)
  • Check skipLabels isn't excluding all issues
  • Confirm github.repos contains the right repos

"Worker failed to start"

Problem: The AI worker couldn't be initialized.

Solution for Claude Code:

  • Verify Claude Code is installed: claude --version
  • Check authentication: claude auth status
  • Update worker.claudePath if not in PATH

Solution for Ollama:

  • Verify Ollama is running: curl http://localhost:11434
  • Check model is pulled: ollama list
  • Ensure model name matches exactly

"Checks failed"

Problem: Test commands failed after implementation.

Solution:

  • Review check output in workspace logs (ARBITER_WORKER.log)
  • Verify check commands are correct and dependencies installed
  • Check allowedCommands whitelist includes your commands
  • Increase checkTimeoutMinutes for slow tests

"Diff validation failed"

Problem: Changes exceed limits or touch forbidden paths.

Solution:

  • Increase maxChangedFiles or maxChangedLines in limits
  • Review forbiddenPaths - remove patterns if needed
  • Check workspace for unintended file changes

"Database connection failed"

Problem: Can't connect to PostgreSQL or Elasticsearch.

Solution for PostgreSQL:

  • Verify PostgreSQL is running: pg_isready
  • Test connection string: psql "postgresql://user:pass@host:5432/arbiter"
  • Check firewall rules if remote database

Solution for Elasticsearch:

  • Verify Elasticsearch is running: curl http://localhost:9200
  • Check authentication if using apiKey
  • Verify index name doesn't conflict

Debug Mode

Enable verbose logging for troubleshooting:

Terminal
# Set environment variable
export DEBUG=arbiter:*

# Run Arbiter
arbiter run

Getting Help

  • Check workspace logs: ~/.arbiter/runs/{runId}/run.log
  • Check worker logs: {workspace}/ARBITER_WORKER.log
  • Run doctor: arbiter doctor
  • Review configuration: Use the Advanced tab in the UI
  • GitHub Issues: Report bugs and request features