# ═══════════════════════════════════════════════════════════════ # openvibe.run — Environment Configuration # Copy to .env for development. In production this lives at /etc/openvibe/run.env (0600). # Names only here; never commit a value. # ═══════════════════════════════════════════════════════════════ # Server PORT=4920 HOST=127.0.0.1 NODE_ENV=development BASE_URL=http://localhost:4920 TRUST_PROXY=1 # ── Data: PostgreSQL + Valkey (ADR-035) ────────────────────── # In production OpenVibe.Host writes all four (roles/data/add-service.sh run). Unset in development: # an embedded PGlite database in data/pglite (one process). Tests need neither. DATABASE_URL= DATABASE_DIRECT_URL= VALKEY_URL= VALKEY_PREFIX=ov:run: # ── Identity: OpenVibe.Network ────────────────────────────── OV_NETWORK_URL=https://openvibe.network OV_NETWORK_INTERNAL_URL=http://127.0.0.1:4000 #OV_NETWORK_ISSUER=https://openvibe.network # Optional: pin the Network's RS256 public key (PEM, \n escaped) instead of fetching the JWKS. #OV_NETWORK_PUBLIC_KEY= # Audience Run accepts on incoming service tokens; a token must also name a project (project_id). RUN_AUDIENCE=openvibe.run OV_OAUTH_CLIENT_ID=run OV_OAUTH_CLIENT_SECRET= #COOKIE_SECURE=true # ── OpenVibe.Events ───────────────────────────────────────── # Relay of Run's outbox (run.job.*); off when unset (rows wait in run_events_outbox). #EVENTS_URL=http://127.0.0.1:4300 #EVENTS_RELAY_INTERVAL_MS=2000 # ── Jobs ──────────────────────────────────────────────────── # Background jobs: the events relay and the dispatcher's poller. RUN_JOBS=off runs the API alone. #RUN_JOBS=on # ── GitHub checks on shared nodes (server/checks/) ────────── # RUN_SECRETS_KEY seals the checks App's private key, webhook secret and installation tokens at rest: # one 32-byte key, base64 (standard or URL-safe) or 64 hex characters. Unset: /admin/checks says so and # POST /webhooks/github answers 503. RUN_CHECKS_PROJECT is the project a check job belongs to. #RUN_SECRETS_KEY= #RUN_CHECKS_PROJECT= # The repositories/accounts the scheduler accepts (default OpenVibers) and the org the App is registered in. #RUN_CHECKS_OWNERS=OpenVibers #RUN_CHECKS_ORG=OpenVibers # The network owner allowed on /admin/checks: their subject (usr_…), or OWNER_USERNAME (default goosely). #RUN_CHECKS_OWNER= #OWNER_USERNAME=goosely #RUN_CHECKS=off # The repositories whose checks report live on GitHub (owner/repo, comma-separated, or *). Every other repository is # in quiet shadow: no queued or in-progress check run, and a finished check that did not succeed shows as neutral # (the node's own conclusion in its title and in the shadow table), so a shadow check never holds a merge. #RUN_CHECKS_LIVE= #RUN_CHECKS_TICK_MS=5000 #RUN_CHECKS_TIMEOUT_MS=8000 #RUN_CHECKS_GITHUB_API=https://api.github.com #RUN_CHECKS_GITHUB_WEB=https://github.com # ── Project caps on a job's limits (run.job-create-request@1); over one is 422 run.limits.exceeded ── #RUN_LIMITS_MAX_WALL_MS=3600000 #RUN_LIMITS_MAX_CPU_MS=3600000 #RUN_LIMITS_MAX_MEM_BYTES=4gb #RUN_LIMITS_MAX_TTL_MS=86400000 #RUN_LIMITS_MAX_ARGS_BYTES=512kb # ── The job stream's ticket (a two-minute single-use RS256 compact JWS Run signs) ── # A PEM in the environment, or a key file. In production with neither set, stream tickets answer 503 # (every other route still serves); in development a key is generated in memory at boot. #RUN_STREAM_PRIVATE_KEY= #RUN_STREAM_KEY_FILE=data/keys/run-stream.pem #RUN_STREAM_KEY_ID=run-stream-1 #RUN_STREAM_TTL_S=120 #RUN_STREAM_RING_BYTES=1mb #RUN_STREAM_MAX_PER_JOB=64 #RUN_STREAM_HEARTBEAT_MS=25000 # ── The dispatcher bridge to Bot (plan T14 step 6, R1c) ── # Bot holds the node link and the meter; Run places each job on a node from the Fabric offers and mirrors # what Bot answers. Needs OV_OAUTH_CLIENT_SECRET above (Run mints its token for audience openvibe.bot); # without it nothing is sent and every job stays queued. #RUN_BOT_URL=http://127.0.0.1:4630 #RUN_BOT_AUDIENCE=openvibe.bot #RUN_POLL_MS=1000 #RUN_DISPATCH_TIMEOUT_MS=8000 # How long the offers Run places from are cached (one read serves a whole tick). #RUN_OFFERS_TTL_MS=5000 # Polls Bot may answer 404 for a job Run sent before that job fails. #RUN_DISPATCH_UNKNOWN_POLLS=5 # Jobs one tick places and mirrors; the next tick takes the rest. #RUN_DISPATCH_MAX_PER_TICK=200 # Bot owns the node link and the per-second metering of the jobs it carries (plan T14 L1). # ── The managed-browser provider (plan T14 R4a) ── # Class browser jobs placed on a kind=provider offer named browser-provider go to this API instead of Bot. # Off while the URL or the key is unset (browser jobs then stay queued). The key lives here only: never in an # offer, a job or a log. Outside development the URL must be https (or loopback). #RUN_BROWSER_PROVIDER_URL=https://browser-provider.example/v1 #RUN_BROWSER_PROVIDER_API_KEY= #RUN_BROWSER_PROVIDER_TIMEOUT_MS=8000 # ── Run's usage relay to Billing (the provider's jobs only; Bot meters its own) ── # Run mints its own token for audience openvibe.billing (billing.usage.record) from OV_OAUTH_CLIENT_SECRET. # Unset: the readings wait in run_usage_outbox, nothing is sent, and the jobs still run. #RUN_BILLING_URL=http://127.0.0.1:4600 #RUN_BILLING_AUDIENCE=openvibe.billing #RUN_BILLING_INTERVAL_MS=5000 #RUN_BILLING_TIMEOUT_MS=8000 # ── The Arena's race (compare-arena-ecosystem.md §3) ── # POST /api/v1/races starts one blind child job per entrant; the judgement is a bench.match@1 recorded on # Bench (POST /api/v1/matches) with Run's Network client token. That client needs bench.judgement.cast. # Bench has no matchmaker endpoint yet, so matchmaker: true picks two entrants of different model families # from this list (comma-separated bench.entrant@1 ids). Unset: matchmaker: true answers 422. #RUN_RACE_ENTRANTS=model:gpt-5-mini,model:glm-5.3,model:deepseek-flash # The key for the keyed hash of the person in a judgement (never the person's id). Unset: Run uses its # Network client secret; set a dedicated key to rotate it without touching the Network client. #RUN_RACE_HASH_KEY= #RUN_BENCH_URL=https://bench.openvibe.services #RUN_BENCH_AUDIENCE=openvibe.bench #RUN_BENCH_TIMEOUT_MS=8000 # ── IndexNow (search engines are told when the public pages change) ── # 8-128 letters and digits. Unset: nothing is sent and GET /.txt is 404. When set, the key file is served there. #INDEXNOW_KEY=