# ============================================================================= # THE UNIVERSE — LOCAL DEV # ============================================================================= # cp .env.example .env — set DATABASE_URL, OPENAI_API_KEY, and your OIDC # values (or AUTH_ENABLED=false to skip login locally). That's it. # (Production is Terraform's job — see infra/*/terraform.tfvars.example.) # ── Local development ──────────────────────────────────────────────────────── # THESE TWO GO TOGETHER. Auth is always on by default, and turning it off is # refused when the environment claims to be production — so setting only # AUTH_ENABLED=false leaves the platform correctly refusing to start, with the # two settings contradicting each other and no way out. A deployed universe sets # neither: unset means production with auth on, and Terraform never renders them. NODE_ENV=development AUTH_ENABLED=false # Postgres. A managed URL works as-is; a Postgres running on YOUR MAC needs # host.docker.internal for the same reason as Redis below — the platform runs in containers, # and localhost inside one means that container. DATABASE_URL=postgres://user:password@host.docker.internal:5432/unoverse # Local Redis. `unoverse start` launches one for you if none is running. # # host.docker.internal, NOT 127.0.0.1: the platform runs in containers, and inside a # container 127.0.0.1 means THAT CONTAINER. Redis runs on your Mac with a published port, so # this is the address that reaches it. The sample said 127.0.0.1 and every fresh universe # hit the same wall — unoverse died on boot with MaxRetriesPerRequestError while memory, # which tolerates a dead Redis, stayed up and made it look like something subtler. REDIS_HOST=host.docker.internal REDIS_PORT=6379 REDIS_PASSWORD= REDIS_TLS=false REDIS_NAMESPACE=gravity # Memory server + OpenAI nodes OPENAI_API_KEY=sk-your-key-here # REQUIRED: pulls the platform images. Without it the platform cannot start. # (Only platform-source developers building images locally can leave it empty.) DOCR_TOKEN= # Page intelligence (promote-page extraction) HYPERBROWSER_API_KEY= # Marketplace catalogue to install from (docs/architecture/authoring/MARKETPLACE.md). # Empty = local items only. No default: a URL is never hardcoded. UNOVERSE_MARKETPLACE_URL= # REQUIRED. The master key encrypting every credential saved in the database. There is # no default and no fallback: the server refuses to start without it. A default would be # a key published in the source, which is what this used to be, and encryption at rest # under a key everyone has is evidence of nothing. # # Generate: openssl rand -base64 32 (at least 32 characters) # BACK IT UP with your database. Lose it and every stored credential is unreadable, and # no backup can bring them back. `unoverse create` generates one for you. # # CHANGING IT ORPHANS EXISTING CREDENTIALS. Pointing a fresh .env at a database that # already holds credentials fails with OpenSSL "bad decrypt" on every one of them: copy # the original key across rather than generating a new one. CREDENTIAL_ENCRYPTION_KEY= # Auth is ON by default (missing flag = enabled), same as production. AUTH_ISSUER=https://your-tenant.auth0.com AUTH_CLIENT_ID=your-client-id AUTH_AUDIENCE=gravity-api # Quick no-login mode (local only — production refuses to start with it): # AUTH_ENABLED=false # Node memoization (docs/unoverseCopilot/EXECUTION_EFFICIENCY.md §3). OFF by default. # Cacheable nodes (capabilities.cacheable in the node YAML) reuse a prior run's output when # the fingerprint matches — saves re-running expensive parses/scrapes across test cycles. # WORKFLOW_NODE_MEMOIZATION=true # WORKFLOW_NODE_MEMOIZATION_TTL_MS=21600000