# Example environment for `pr-agent` # Full catalog: docs/configuration.md # --- HTTP / process role --- # Maintainer-local Compose (docker-compose.dev.yml) sets web 7224 and worker 7225. # Production Compose pins web to 7224. Bare `node --env-file-if-exists=.env src/index.ts` without PORT is 3000. # Do not copy PORT=7224 onto two host terminals. Give each role its own port. PORT=7224 # web: /health + /ready + /webhooks (enqueue only). # worker: ack, ci-refresh, review, ask, description, triage, verification, # retention. # Primary local start is docker-compose.dev.yml (includes a Cloudflare quick tunnel). # See README Local development. ROLE=web # --- Features (the user-facing catalog: docs/features.md) --- # Describe and verification: off = disabled entirely, # manual = slash command only, auto = slash command + automatic trigger. # FEATURE_ASK and FEATURE_TRIAGE accept only off | manual. auto crashes startup. # FEATURE_REVIEW accepts manual | auto | approval. off crashes startup. # approval reviews trusted PRs on open; untrusted forks wait for maintainer approval. # Trusted fork associations: OWNER, MEMBER, and COLLABORATOR. # A past contributor on a fork waits for a pull request approval or /review. # Missing association or a deleted fork is untrusted. Already-open PRs need /review. FEATURE_REVIEW=approval # FEATURE_REVIEW_CADENCE accepts once | every_push. Default once. # every_push with FEATURE_REVIEW=manual crashes startup. FEATURE_REVIEW_CADENCE=once FEATURE_DESCRIBE=auto # auto spends tokens on every synchronize push FEATURE_VERIFICATION=auto FEATURE_ASK=manual FEATURE_TRIAGE=manual FEATURE_REVIEW_LABELS=size FEATURE_COMMIT_STATUS=false FEATURE_TITLE_REWRITE=true LOG_LEVEL=info # Pretty-print logs (default false in production, true in development). Only true/false; empty uses default. # Laptop default. On a public host set false or drop the line so NODE_ENV=production stays JSON. LOG_PRETTY=true # Redact secret-shaped substrings from logs (default true). Only true/false; empty uses default. LOG_REDACT=true # --- Postgres (required for durable agent work) --- # Host integration tests. docker-compose.dev.yml publishes 127.0.0.1:5432. # Production Compose does not publish Postgres. It rewrites web/worker to @postgres:5432. # Default password is for local use. Change it on a reachable host. # Compose also reads POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD (not loadConfig keys). # The production overlay requires those three plus a DATABASE_URL that uses hostname postgres. DATABASE_URL=postgres://pr_agent:pr_agent@localhost:5432/pr_agent # --- GitHub App --- GITHUB_APP_ID=123456 # Real PEM required. This placeholder fails crypto.createPrivateKey() and both roles exit. # Compose env_file is line-oriented. Use one-line `\n` or base64. A literal PEM block often breaks. GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----" # --- Webhooks --- WEBHOOK_SECRET=replace-with-a-strong-secret # --- Model provider (Pi Core session) --- PI_PROVIDER=openai PI_MODEL=gpt-4o-mini # Optional Review orchestrator overrides (empty inherits PI_PROVIDER / PI_MODEL) PI_ORCHESTRATOR_PROVIDER= PI_ORCHESTRATOR_MODEL= # Optional shared fallback (both required to enable; availability failures only) PI_FALLBACK_PROVIDER= PI_FALLBACK_MODEL= # Max thinking level for phase-aware thinking PI_THINKING_CEILING=high # Extra transport attempts per provider request on retryable 429/5xx/network failures; 0 disables transport retry PI_PROVIDER_RETRY_MAX=2 # Cap (ms) on a provider-requested retry delay (e.g. Retry-After); must be less than PROVIDER_PROMPT_TIMEOUT_MS PI_PROVIDER_MAX_RETRY_DELAY_MS=60000 # Local metadata audit only; PostHog is independently enabled by its token. # Only true/false; empty uses default. Legacy 1/yes/TRUE crash startup. AGENT_EVENTS_ENABLED=true # TTL delete for agent_events rows by recorded_at. Default matches work retention (30d). 0 keeps rows forever. AGENT_EVENTS_RETENTION_SECONDS=2592000 # Optional Pi models.json catalog path (default: ./models.json under process cwd; Docker: /app/models.json) MODELS_JSON_PATH= # Inactivity cap (ms) for a provider prompt: abort + fail the run only if the provider streams no # activity (message/tool/turn events) for this long. Bounds hangs without capping large reviews. PROVIDER_PROMPT_TIMEOUT_MS=300000 # Total wall-clock budget (ms) for one specialist across jitter, retries, and repair rounds. REVIEW_SPECIALIST_TIMEOUT_MS=900000 # When true, a tests coverage gap must name read paths that have a content read # in this run's evidence ledger. Path checks still apply when this is false. # Only true/false; empty defaults to false. Not a FEATURE_* mode. REVIEW_TESTS_EVIDENCE=false # Open findings at this severity or stricter fail the PR Agent Review check. # Allowed: P0, P1, P2, P3. Default P2. P3 fails only when this is P3. # Empty is invalid. Not a FEATURE_* mode. REVIEW_CHECK_FAIL_SEVERITY=P2 # --- Worker concurrency (pg-boss localConcurrency; see src/agentWork/worker.ts) --- REVIEW_CONCURRENCY=2 ASK_CONCURRENCY=1 # Durable ask admission. Outstanding limits apply at actor, repository, and installation scope. ASK_ACTOR_MAX_OUTSTANDING=2 ASK_REPOSITORY_MAX_OUTSTANDING=8 ASK_INSTALLATION_MAX_OUTSTANDING=32 # Token-bucket burst capacity and seconds per refill token. ASK_ACTOR_BURST=3 ASK_REPOSITORY_BURST=12 ASK_INSTALLATION_BURST=48 ASK_ACTOR_REFILL_SECONDS=60 ASK_REPOSITORY_REFILL_SECONDS=10 ASK_INSTALLATION_REFILL_SECONDS=1 # Zero disables the installation-wide provider token budget. ASK_PROVIDER_BUDGET_TOKENS=0 ASK_PROVIDER_BUDGET_WINDOW_SECONDS=86400 # Unknown provider usage consumes this reservation until the budget window resets. ASK_PROVIDER_RESERVATION_TOKENS=16384 DESCRIPTION_CONCURRENCY=1 TRIAGE_CONCURRENCY=1 VERIFICATION_CONCURRENCY=1 ACK_CONCURRENCY=2 # GitHub comment author associations allowed to run slash commands. Use * to allow all. # CONTRIBUTOR and NONE get webhook 200 and no reply. /help looks dead for those accounts. SLASH_ALLOWED_ASSOCIATIONS=OWNER,MEMBER,COLLABORATOR # Associations whose non-bot inline replies may support a dismissed finding. Wildcard is not allowed. MAINTAINER_DECISION_ASSOCIATIONS=OWNER,MEMBER,COLLABORATOR INSTALLATION_GROUP_CONCURRENCY=2 # PR actor lease: one active run per PR per work type (see docs/agent-work-ops.md). PR_ACTOR_LEASE_TTL_SECONDS=900 # Must stay well below the TTL so a live holder renews before the lease lapses. PR_ACTOR_LEASE_RENEWAL_INTERVAL_SECONDS=120 # --- pg-boss queue policy (see docs/agent-work-ops.md for recovery) --- QUEUE_RETRY_LIMIT=3 QUEUE_RETRY_DELAY_SECONDS=30 QUEUE_RETRY_DELAY_MAX_SECONDS=300 QUEUE_EXPIRE_IN_SECONDS=3600 QUEUE_HEARTBEAT_SECONDS=60 QUEUE_POLLING_INTERVAL_SECONDS=0.5 QUEUE_RETENTION_SECONDS=1209600 QUEUE_DELETE_AFTER_SECONDS=604800 # Graceful drain budget (s) for in-flight jobs on SIGTERM/SIGINT before pg-boss closes. # After that drain, analytics flushes and handlers settle (5s each). Compose stop_grace_period is 40s. SHUTDOWN_DRAIN_TIMEOUT_SECONDS=25 # --- App table retention (worker runs a scheduled cleanup sweep) --- WEBHOOK_EVENTS_RETENTION_SECONDS=2592000 AGENT_WORK_RETENTION_SECONDS=2592000 # Cron (server local time) for the sweep; set RETENTION_ENABLED=false to disable # Only true/false; empty uses default. Legacy 1/yes/TRUE crash startup. RETENTION_CRON=17 3 * * * RETENTION_ENABLED=true # --- PostHog (optional analytics) --- # Empty token disables capture; host empty uses posthog-node default POSTHOG_PROJECT_TOKEN= POSTHOG_HOST= # --- Model provider secrets (loaded by loadConfig(), never logged) --- # Optional at boot. Empty still starts web and worker. Reviews fail later without a key. OPENAI_API_KEY= # ANTHROPIC_API_KEY= # GOOGLE_GENERATIVE_AI_API_KEY= # --- Docker Compose --- # Production Compose loads this file by default (`env_file: .env`). # Maintainer-local Compose loads dev/mock.env (no PEM) unless you set: # PR_AGENT_ENV_FILE=/path/to/.env docker compose -f docker-compose.dev.yml up # Queue health and recovery: docs/agent-work-ops.md