# ============================================================================= # RoboCo Environment Configuration # ============================================================================= # Copy this file to .env # # NOTE: No API keys needed for agents - they use your Claude Code authentication. # Run `claude` on the host to authenticate before starting RoboCo. # # Covers all three deploy shapes: local dev (plain `uv run` / `make dev`), # docker-compose.yml / .yaml (build-from-source, the NAS deploy — the two # files are kept byte-identical, see Makefile's `compose-sync` gate), and # docker-compose.registry.yml (pre-built, pull-and-run). Every var a compose # file references is listed below; unreferenced vars have no effect on that # deploy shape even if set. # ============================================================================= # Docker Deployment (NAS/Server) — host paths for Docker-in-Docker # ============================================================================= # These are REQUIRED when running via docker compose on a NAS/server. They # tell the orchestrator container where to find files on the HOST (must be # ABSOLUTE paths — the orchestrator bind-mounts them into spawned agents). # Path to the project on the host (absolute path) # ROBOCO_HOST_PROJECT_DIR=/volume1/roboco # Path to Claude Code auth directory on the host # ROBOCO_HOST_CLAUDE_DIR=/root/.claude # Claude auth directory to mount into orchestrator # CLAUDE_AUTH_DIR=~/.claude # Host dir holding the SuperGrok auth (~/.grok) for Grok-CLI agents. Read-write: # the orchestrator auto-refreshes the ~6h token in place. Run `grok login` once # on the host first. # ROBOCO_HOST_GROK_DIR=/home/youruser/.grok # Host path mirroring ROBOCO_DATA_DIR (see below), used when the orchestrator # needs the HOST-side path for a bind mount it hands to a spawned container. # ROBOCO_HOST_DATA_DIR=/volume1/roboco/data # Public base URL for commit-trailer links (e.g. LAN IP or domain) — default # 127.0.0.1 produces unusable links in commit message bodies. # ROBOCO_PUBLIC_BASE_URL=http://localhost:8000 # ============================================================================= # Container Images (docker-compose.registry.yml — pre-built deployment) # ============================================================================= # Only used by docker-compose.registry.yml, which runs the published images # instead of building from source. Defaults shown. # Registry namespace: ghcr.io/rennf93 (GHCR) or docker.io/renzof93 (Docker Hub) # ROBOCO_REGISTRY=ghcr.io/rennf93 # Image tag: latest, or a pinned release such as 0.5.0 # ROBOCO_VERSION=latest # ============================================================================= # Data Persistence # ============================================================================= # Set to a path on your NAS RAID array for durability # Path to data directory on the host (MUST be absolute for Docker-in-Docker) # ROBOCO_DATA_DIR=/volume1/roboco/data # Off-disk mirror for the daily pg_dump backups. Point at a path on a # DIFFERENT disk (external USB, or a mounted remote/cloud share) — a # same-disk mirror protects nothing. Unset = mirroring off. # ROBOCO_BACKUP_MIRROR_DIR=/mnt/external/roboco-backups # ============================================================================= # Application # ============================================================================= ROBOCO_ENVIRONMENT=development ROBOCO_DEBUG=true # ============================================================================= # API Server # ============================================================================= ROBOCO_HOST=0.0.0.0 ROBOCO_PORT=8000 # ============================================================================= # Database (PostgreSQL) # ============================================================================= # For docker compose deployment, use container name: # ROBOCO_DATABASE_HOST=roboco-postgres # For local development: ROBOCO_DATABASE_HOST=localhost ROBOCO_DATABASE_PORT=5432 ROBOCO_DATABASE_USER=roboco ROBOCO_DATABASE_PASSWORD=roboco ROBOCO_DATABASE_NAME=roboco ROBOCO_DATABASE_ECHO=false # ============================================================================= # Redis # ============================================================================= # For docker compose deployment, use container name: # ROBOCO_REDIS_HOST=roboco-redis # For local development: ROBOCO_REDIS_HOST=localhost ROBOCO_REDIS_PORT=6379 ROBOCO_REDIS_DB=0 # ROBOCO_REDIS_PASSWORD= # ============================================================================= # RAG / Local LLM (Ollama + in-house pgvector engine) # ============================================================================= # For docker compose use the container name (roboco-ollama); locally, localhost. ROBOCO_OLLAMA_BASE_URL=http://localhost:11434 ROBOCO_LOCAL_LLM_BASE_URL=http://localhost:11434/v1 ROBOCO_LOCAL_LLM_MODEL=glm-5.2:cloud ROBOCO_DEFAULT_EMBEDDING_MODEL=qwen3-embedding:0.6b # Ollama Cloud API key (optional) — only needed if you point ROBOCO_LOCAL_LLM_MODEL # at a *:cloud model and Ollama's own local auth isn't already configured. # OLLAMA_API_KEY= # ============================================================================= # Grok (xAI) Provider — optional # ============================================================================= # RoboCo can run agents on Grok Build (xAI) via xAI's official `grok` CLI on the # SuperGrok subscription, instead of Claude Code. No metered xAI API key is used: # the CLI authenticates from a mounted ~/.grok/auth.json — run `grok login` once # on the host (auth.json auto-refreshes). Every var below is optional. # (ROBOCO_HOST_GROK_DIR is set above, under Docker Deployment — same var, both # compose files mount it into the orchestrator AND hand the same host path to # each Grok agent's own bind.) # Image the orchestrator spawns for Grok agents, and the CLI model id. # ROBOCO_GROK_AGENT_IMAGE=roboco-agent-grok:latest # ROBOCO_GROK_CLI_MODEL=grok-build # Per-role tool permissions are computed as native grok flags (subagents off # except intake; edit/shell removed for non-coding roles; git network/branch/ # history mutation + rm -rf denied for coding roles; web search off for all — # gated web is via the roboco-search MCP). Credential-exfil / identity-forgery / # internal-API shell patterns are blocked by the same bash-guard the Claude path # runs, wired as a grok PreToolUse hook. Nothing to set here. # Reasoning effort for ALL Grok agents: low | medium | high | xhigh | max. Empty # keeps grok's model default for every role (parity with Claude — no per-role # cut); set this to trade quality for cost across the whole fleet. # ROBOCO_GROK_REASONING_EFFORT= # Hard ceiling on agentic turns per run (loop guard). # ROBOCO_GROK_MAX_TURNS=200 # Kill a Grok agent container after this many seconds idle (no model call / # stream) to reclaim a wedged one. Minimum 120. # ROBOCO_GROK_IDLE_KILL_SECONDS=900 # Per-agent cost ceiling (USD) before the orchestrator kills the container; # 0 disables. Backstops runaway-loop token burn. # ROBOCO_GROK_MAX_COST_USD=0.0 # ============================================================================= # Codex (OpenAI) Provider — optional # ============================================================================= # RoboCo can run agents on OpenAI's Codex CLI (ChatGPT subscription auth) via a # mounted ~/.codex/auth.json — run `codex login` once on the host. Enable it by # picking the "Codex" routing mode or a gpt-* model per agent in the panel's AI # routing card. Host dir mounted RO into each Codex agent; the orchestrator # refreshes the token before expiry (codex_auth.py). All vars optional. # ROBOCO_HOST_CODEX_DIR=/home/youruser/.codex # ROBOCO_CODEX_CLI_MODEL=gpt-5.3-codex # If the default OIDC client id is wrong for your account, override it (a bad # refresh never mutates auth.json — worst case is a parked provider): # ROBOCO_CODEX_OAUTH_CLIENT_ID= # ============================================================================= # Gemini (Google) Provider — optional # ============================================================================= # RoboCo can run agents on Google's Gemini CLI (Google-account OAuth) via a # mounted ~/.gemini — run the interactive `gemini` login once on the host. # Enable via the "Gemini" routing mode or a gemini-* model per agent. Each # container copies the RO-mounted creds to a writable local dir and refreshes # in-process (reusable refresh tokens, no orchestrator daemon). All optional. # ROBOCO_HOST_GEMINI_DIR=/home/youruser/.gemini # ROBOCO_GEMINI_CLI_MODEL=gemini-2.5-pro # Hard ceiling on agentic turns per run (loop guard, grok parity): # ROBOCO_GEMINI_MAX_TURNS=200 # Park-and-retry delays after a rate-limit / auth failure (seconds): # ROBOCO_GEMINI_RATE_LIMIT_RETRY_AFTER_SECONDS=300 # ROBOCO_GEMINI_AUTH_RETRY_AFTER_SECONDS=300 # ============================================================================= # Cost budgets — optional # ============================================================================= # Per-task (tasks.budget_usd) and per-project (projects.monthly_budget_usd) # cost caps. Default-off subsystem; also toggleable on the panel's Feature # Flags card. A breached task is BLOCKED (not silently killed) and the CEO is # notified. Build compose arms it true; registry compose leaves it false. # ROBOCO_TASK_BUDGETS_ENABLED=false # ============================================================================= # Notification re-escalation backoff — optional tuning # ============================================================================= # Expired unacked ack-required notifications re-escalate on exponential backoff # (first at expiry, then doubling from the base, capped at 24h) up to a max # count, instead of re-firing every sweep tick. No panel UI — env/compose is # the only tuning path. # ROBOCO_NOTIFICATION_REESCALATION_BASE_SECONDS=3600 # ROBOCO_NOTIFICATION_MAX_REESCALATIONS=5 # ============================================================================= # Security # ============================================================================= # Encryption key for git tokens at rest (Fernet). REQUIRED — the orchestrator # refuses to start without it. Generate with: # python -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())' ROBOCO_ENCRYPTION_KEY= # Agent auth: HMAC secret that signs X-Agent-Token. REQUIRED for docker compose. # Generate with: python -c 'import secrets; print(secrets.token_hex(32))' ROBOCO_AGENT_AUTH_SECRET= # Secure mode. On a trusted LAN you can leave this false (header-trust mode). # Set true to require every request to carry a valid token so an agent cannot # spoof another agent's role. When true you MUST also set ROBOCO_PANEL_AGENT_TOKEN. ROBOCO_AGENT_AUTH_REQUIRED=false # The control panel's CEO token, injected by nginx in secure mode so the human # UI keeps working without the browser holding the signing secret. Generate it # (after setting ROBOCO_AGENT_AUTH_SECRET above) with: make panel-token # NOTE: leave this UNSET if you arm cloud auth (below) for real remote exposure — # it is itself a valid CEO credential that would bypass the login page. ROBOCO_PANEL_AGENT_TOKEN= # DB network isolation: true when your compose topology puts postgres/redis on # a data-only network unreachable from agent containers (both docker-compose.yml # and docker-compose.registry.yml ship this true — it must always travel with # that networks: topology; flip false only if you removed the isolation). ROBOCO_DB_NETWORK_ISOLATED=true # ============================================================================= # Cloud auth (panel login, FastAPI Users) — off by default in config; # ARMED ON by default in docker-compose.yaml/.yml (NAS build compose), OFF by # default in docker-compose.registry.yml # ============================================================================= # When on, the orchestrator REFUSES TO START unless ROBOCO_CLOUD_AUTH_SECRET is # set, the panel requires a login, and the session cookie is secure-only (needs # TLS in front of nginx). # ROBOCO_CLOUD_AUTH_ENABLED=false # # To TEST-DEPLOY the NAS compose before you've set up creds + TLS, turn it off # for that run: ROBOCO_CLOUD_AUTH_ENABLED=false # # To ARM it: set all three below + terminate TLS in front of nginx + leave # ROBOCO_PANEL_AGENT_TOKEN unset. # ROBOCO_CLOUD_AUTH_SECRET — session-signing key. REQUIRED when enabled. # Generate: python -c 'import secrets; print(secrets.token_hex(32))' # ROBOCO_CLOUD_AUTH_EMAIL / _PASSWORD — the single seeded login (no signup). # ROBOCO_CLOUD_AUTH_SECRET= # ROBOCO_CLOUD_AUTH_EMAIL= # ROBOCO_CLOUD_AUTH_PASSWORD= # Session cookie lifetime in seconds (default 30 days, sliding — an active # session never expires, only genuine inactivity past this window logs out). # ROBOCO_CLOUD_AUTH_COOKIE_MAX_AGE=2592000 # ============================================================================= # Telegram notifications bridge — V1 (outbound DMs) / V2 (inbound commands) / # V3 (Mini App sign-in). The NAS compose (docker-compose.yml) arms all three # by DEFAULT per the arm-new-flags convention; set false here to opt out. # Inert without stored bot-token + chat-id credentials (set via the panel, # not env) regardless of these flags. Config-code default (no compose) is OFF. # ============================================================================= # ROBOCO_TELEGRAM_ENABLED=true # V2: inbound commands + actionable approve/reject buttons. Sub-switch on top # of ROBOCO_TELEGRAM_ENABLED above — arming this alone does nothing. # ROBOCO_TELEGRAM_INBOUND_ENABLED=true # V3: Telegram Mini App sign-in — mints a cloud-auth session cookie for the # CEO's phone. Requires ROBOCO_CLOUD_AUTH_ENABLED=true (startup fails loud # otherwise — a cloud-auth-off .env must set this false too) AND a public # HTTPS origin (Mini Apps only open over https). # ROBOCO_TELEGRAM_MINIAPP_ENABLED=true # ============================================================================= # Model routing strictness # ============================================================================= # Fail-closed routing: a spawn whose configured provider is disabled RAISES # instead of degrading to the legacy Claude path. Off (default) => graceful # degradation with a warning. Audit the model_assignments table before arming # (a stale row pointing at a disabled provider crashes that spawn). # ROBOCO_ROUTING_STRICT=false # Spawn preflight: refuse a non-gateway delivery role that would respawn # forever. Inert in practice (every real delivery role is gateway-enabled). # ROBOCO_SPAWN_PREFLIGHT_ENABLED=false # ============================================================================= # fastapi-guard HTTP security layer — v0.16.0 # ============================================================================= # Master switch + calibration knobs. Off by default; the NAS build compose # arms it in ACTIVE enforcement (passive/log-only calibration reviewed # clean — see docs/rag/architecture/http-security-guard.md). Not exposed on # the panel's Feature Flags card (compose/env-coupled, like # ROBOCO_DB_NETWORK_ISOLATED). # ROBOCO_GUARD_ENABLED=false # Detect-and-log without blocking. # ROBOCO_GUARD_PASSIVE_MODE=true # Fail CLOSED on an internal guard error (true) vs fail open (false). # ROBOCO_GUARD_FAIL_SECURE=true # Exact IP address(es), never a range, trusted as an XFF proxy hop beyond loopback # (a CIDR entry is rejected — it would readmit every sibling container). Empty = # loopback-only hop-peel. If Tailscale Serve sits behind this host's docker gateway, # set it to that gateway's exact address to keep the chain resolving (e.g. 172.18.0.1). # ROBOCO_GUARD_TRUSTED_CHAIN_PEERS=172.18.0.1 # ============================================================================= # Architectural conventions standard + agent-runtime toolchain matching # ============================================================================= # Conventions: gates where code lives per-project via .roboco/conventions.yml. # ROBOCO_CONVENTIONS_ENABLED=false # Toolchain match: provisions each agent workspace with the TARGET project's # Python (uv resolves requires-python) and blocks delivery when the suite # can't be executed, instead of passing on a source-only read. # ROBOCO_TOOLCHAIN_MATCH_ENABLED=false # ============================================================================= # External / internal PR review # ============================================================================= # External: discovers inbound external/fork PRs; the PR reviewer posts one # READ-ONLY change-request (never runs contributor code). # ROBOCO_EXTERNAL_PR_ENABLED=false ROBOCO_EXTERNAL_PR_REQUIRE_HUMAN_CONFIRM=true # ROBOCO_EXTERNAL_PR_POLL_INTERVAL_SECONDS=300 # ROBOCO_EXTERNAL_PR_AUTHOR_ALLOWLIST=["corey"] # empty = every external PR # Internal: proactive review pass over RoboCo's own internal PRs. # ROBOCO_INTERNAL_PR_ENABLED=false # ============================================================================= # Self-healing CI loop (RoboCo watching its OWN repo) # ============================================================================= # On red CI, notifies the CEO and (with originate on) opens a PENDING fix task # held for the CEO's Approve-&-Start — never self-deploys. # ROBOCO_SELF_HEAL_ENABLED=false # ROBOCO_SELF_HEAL_ORIGINATE_ENABLED=false # The registered project that IS RoboCo itself. # ROBOCO_SELF_HEAL_PROJECT_SLUG=roboco-api # Scopes the CI signal to one workflow file (RoboCo has several). # ROBOCO_SELF_HEAL_CI_WORKFLOW=ci.yml # ============================================================================= # Multi-repo CI-watch / dependency-update bot / gated release manager / # organizational memory loop / board roadmap engine — all default OFF, # per-engine bounded + CEO-gated; toggle from Settings -> Feature Flags too. # ============================================================================= # CI-watch: fan-out self-heal to every opted-in project (projects.ci_watch_enabled). # ROBOCO_CI_WATCH_ENABLED=false # Dep-update bot: weekly lockfile-diff probe -> "update dependencies" task, only # for projects with a dep_update_command set. # ROBOCO_DEP_UPDATE_ENABLED=false # Release manager: deterministic readiness sweep -> ONE release proposal HELD # for the CEO; the executor publishes only on CEO approval + green CI (reuses # ROBOCO_SELF_HEAL_PROJECT_SLUG as the RoboCo repo). # ROBOCO_RELEASE_MANAGER_ENABLED=false # Org-memory loop: distils a completion lesson + auto-injects relevant past # lessons/playbooks into each claim's briefing (local model only). # ROBOCO_ORG_MEMORY_ENABLED=false # Board roadmap engine: weekly, opens ONE held exploration task for the Product # Owner, who proposes a themed cycle of roadmap items for CEO per-item approval. # ROBOCO_ROADMAP_ENGINE_ENABLED=false # ============================================================================= # Docs-divergence sync (release -> docs-update task) # ============================================================================= # Master switch for the docs-sync engine. When on, a successful release publish # originates one bounded, deduped docs-update task against the roboco-website # project. Requires roboco-website to be registered as a project. # NAS compose defaults this to true; local-dev and registry composes default to # false. Toggle from Settings → Feature Flags. # ROBOCO_DOCS_SYNC_ENABLED=false # ROBOCO_DOCS_SYNC_MAX_OPEN_TASKS=3 # ROBOCO_DOCS_SYNC_MAX_PER_CYCLE=1 # Docs-site identity named in the write_doc(doc_type='user_facing') refusal # message (roboco/services/docs.py) — a deployer without their own docs-site # repo/URL yet can leave these unset for a generic fallback message. # ROBOCO_DOCS_SITE_PROJECT_SLUG=roboco-website # ROBOCO_DOCS_SITE_PUBLIC_URL=docs.roboco.tech # ============================================================================= # Sandboxed dev DB/Redis/Mongo (per-project opt-in via projects.sandbox_services) # ============================================================================= # On-demand throwaway sibling containers per agent spawn, replacing the legacy # prod-creds gate-env injection for an opted-in project. # ROBOCO_SANDBOX_DB_ENABLED=false # ============================================================================= # Strategy engine (proactive strategy signals) # ============================================================================= # ROBOCO_STRATEGY_ENGINE_ENABLED=false # ============================================================================= # Web research # ============================================================================= # Gives Board/PM roles web_search + web_fetch. INERT (empty results) without a # provider key — set one to make it live (Tavily / Brave / Exa, per your config). # ROBOCO_RESEARCH_ENABLED=true # tavily | brave | exa | null — provider adapter for the key below. # ROBOCO_RESEARCH_PROVIDER=tavily # ROBOCO_RESEARCH_API_KEY= # ============================================================================= # GitHub repository auto-provisioning (pitch -> approve -> auto-provision) # ============================================================================= # The only place that CREATES GitHub repos. Inert without a token/org set, # regardless of this flag. # ROBOCO_PROVISIONING_ENABLED=true # Org-scoped PAT (needs repo + org admin scope) used to create repos. # ROBOCO_PROVISIONING_TOKEN= # GitHub organization the new repos are provisioned into. # ROBOCO_PROVISIONING_ORG= # ============================================================================= # Transcript pruning (retention maintenance) # ============================================================================= # ROBOCO_TRANSCRIPT_PRUNE_ENABLED=true # ============================================================================= # Auditor scheduled sweeps # ============================================================================= # The orchestrator spawns the auditor on a periodic delivery-process review when # the interval has elapsed AND recent delivery activity exists. 0 disables. # ROBOCO_AUDIT_INTERVAL_SECONDS=21600 # ============================================================================= # Obsidian vault (org's human-readable memory palace, V1+V2) # ============================================================================= # Both compose files default vault ON (ROBOCO_VAULT_PATH bind-mounted to # ${ROBOCO_DATA_DIR}/vault). Set false to disable materialization entirely. # ROBOCO_OBSIDIAN_VAULT_ENABLED=true # Root directory the vault materializes into INSIDE the container — must match # the compose bind mount target (/app/vault); do not change without also # editing the compose volume line. # ROBOCO_VAULT_PATH=/app/vault # Watches #roboco-tagged notes in the vault inbox -> board-review drafts. # ROBOCO_VAULT_INTAKE_ENABLED=true # Move old terminal tasks' notes into RoboCo/Archive// during the weekly # drift-janitor sweep. 0 disables archival. # ROBOCO_VAULT_ARCHIVE_DAYS=30 # Weekly org-report note (metrics/usage digest) + CEO notification. # ROBOCO_VAULT_REPORT_ENABLED=true # KB ingest: embeds the CEO's own RoboCo/Notes/ into the fleet-retrievable # corpus (roboco_kb_search, claim-time briefings). Off by default in the # registry compose; the NAS compose arms it true. # ROBOCO_VAULT_KB_ENABLED=false # Comma-separated vault-relative dirs to ingest (must not overlap a reserved # projection dir — Tasks/Journals/A2A/Agents/Archive/_meta/Reports/.obsidian). # ROBOCO_VAULT_KB_DIRS=RoboCo/Notes # Seconds between vault-KB ingest scan cycles. # ROBOCO_VAULT_KB_INTERVAL_SECONDS=900 # ============================================================================= # RoboCo video engine (bespoke motion-graphics videos) # ============================================================================= # A UX/UI dev authors a HyperFrames video per release/spotlight/on-demand # trigger through the normal delivery lifecycle; nothing auto-posts — every # clip is held for CEO approval. Off by default; the NAS compose arms it. # ROBOCO_VIDEO_ENGINE_ENABLED=false # ROBOCO_VIDEO_ON_RELEASE=false # ROBOCO_VIDEO_ON_SPOTLIGHT=false # ============================================================================= # MinIO object storage for rendered videos — NAS build compose only # ============================================================================= # Decoupled, docker-managed durable copy of rendered MP4s alongside the local- # disk source of truth. Intentionally OMITTED from docker-compose.registry.yml # (NAS default-on, registry default-off — see minio-data volume + minio/ # minio-init services in docker-compose.yml). Empty endpoint = disabled (the # media route falls back to local-disk FileResponse); the NAS compose hardcodes # the endpoint to the minio container, so only these four matter there: # ROBOCO_MINIO_ACCESS_KEY=minio # ROBOCO_MINIO_SECRET_KEY=minio123 # ROBOCO_MINIO_BUCKET=roboco-video-renders # ROBOCO_MINIO_REGION=us-east-1 # ============================================================================= # Fable-mode (behavioral doctrine + turn-discipline/honesty/verification hooks) # ============================================================================= # Off by default; the NAS compose arms it as the live test bed. Bundles the # ponytail build-laziness doctrine on the same flag. # ROBOCO_FABLE_MODE_ENABLED=false # lite | full | ultra — developer ladder intensity (bundled with fable-mode). # ROBOCO_PONYTAIL_INTENSITY=full # ============================================================================= # X (Twitter) engine # ============================================================================= # The engine drafts release posts + mention replies HELD for per-post CEO # approval; it is INERT until you store the four OAuth 1.0a secrets. Those are # NOT env vars — enter them in the panel (Settings -> X credentials, stored # Fernet-encrypted): API key, API secret, access token, access token secret, # from an X developer app with read+write user-context access. # ROBOCO_X_ENGINE_ENABLED=false # Optional: pin the account's numeric user id (else it's resolved via /users/me). # ROBOCO_X_ACCOUNT_USER_ID= # ============================================================================= # CORS (comma-separated origins) # ============================================================================= ROBOCO_CORS_ORIGINS=["http://localhost:3000","http://localhost:5173"] # --- Agent tool-call budget (per session) --- # Warn/halt thresholds for an agent's tool-call count; the halt gracefully # stops the container and releases its task back to the pool. Audit-heavy # tasks (page sweeps, big refactors) need headroom — 600 clears a real # task's footprint while keeping the runaway guard. ROBOCO_AGENT_TOOL_CALL_WARN=200 ROBOCO_AGENT_TOOL_CALL_HALT=600