> ## Documentation Index
> Fetch the complete documentation index at: https://internal.september.wtf/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment variables

> Every environment variable the Engine reads, what it does, and what it defaults to.

This page is the authoritative reference for every environment variable the
Engine reads. Variables are loaded from a `.env` file or the OS environment
(OS takes precedence). All feature-flag values are the lowercase strings
`"true"` or `"false"` — not `"1"` / `"0"`, not booleans, not numbers.

If a variable is marked **required** and is missing at startup, the Engine
fails to boot.

## LLM provider and models

| Name             | Required | Default  | Purpose                                                                      |
| ---------------- | -------- | -------- | ---------------------------------------------------------------------------- |
| `LLM_PROVIDER`   | yes      | `openai` | Which LLM to use: `anthropic`, `openai`, or `gemini`.                        |
| `LLM_API_KEY`    | yes      | —        | API key for the selected provider.                                           |
| `LLM_MODEL`      | yes      | `gpt-4o` | Model identifier (e.g. `claude-sonnet-4-20250514`).                          |
| `MAX_TOKENS`     | no       | `4096`   | Max output tokens per call.                                                  |
| `GEMINI_API_KEY` | no       | —        | Google Gemini API key (required if provider is `gemini`).                    |
| `PLANNER_MODEL`  | no       | —        | Model override for the planner sub-agent. Use a cheaper/faster model if set. |
| `LIGHT_MODEL`    | no       | —        | Model override for lightweight tasks (compaction, summarization).            |
| `FALLBACK_MODEL` | no       | —        | Model used if the primary model fails.                                       |

## Embeddings

Embeddings always route to OpenAI in the current implementation, regardless
of the chat-completion provider. You need an OpenAI key even if you're
using Anthropic or Gemini for chat.

| Name                 | Required | Default                  | Purpose                                                    |
| -------------------- | -------- | ------------------------ | ---------------------------------------------------------- |
| `OPENAI_API_KEY`     | yes      | —                        | OpenAI key, used for embeddings.                           |
| `EMBEDDING_PROVIDER` | no       | `openai`                 | Provider for embeddings. Only `openai` is supported today. |
| `EMBEDDING_MODEL`    | no       | `text-embedding-3-small` | Embedding model identifier.                                |
| `EMBEDDING_DIM`      | no       | `1536`                   | Embedding dimension. Must match the model's output.        |

## Web search (optional)

| Name             | Required | Default | Purpose               |
| ---------------- | -------- | ------- | --------------------- |
| `BRAVE_API_KEY`  | no       | —       | Brave Search API key. |
| `TAVILY_API_KEY` | no       | —       | Tavily fallback key.  |

## Storage and catalogs

| Name             | Required | Default              | Purpose                                                                |
| ---------------- | -------- | -------------------- | ---------------------------------------------------------------------- |
| `SQLITE_DB_PATH` | no       | `/data/brain.sqlite` | Path to the per-user brain database.                                   |
| `CATALOG_DIR`    | no       | —                    | Path to the platform catalog (agents, skills, tools, core\_soul.json). |
| `MIGRATIONS_DIR` | no       | —                    | Path to migration files. Auto-discovered when empty.                   |

## Asset Directory (MCP)

| Name                      | Required | Default | Purpose                                                                                                             |
| ------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------- |
| `AD_ENCRYPTION_KEY`       | no       | —       | Fernet key (base64-encoded 32 bytes) for encrypting MCP credentials at rest. Required if you use any MCP connector. |
| `OAUTH_REDIRECT_BASE_URL` | no       | —       | Base URL for OAuth redirects (e.g. `https://engine.example.com`).                                                   |

## Learning Centre

| Name                      | Required | Default        | Purpose                                |
| ------------------------- | -------- | -------------- | -------------------------------------- |
| `LC_BATCH_INTERVAL_HOURS` | no       | `6.0`          | Hours between automated batch runs.    |
| `LC_PROVIDER`             | no       | `openai`       | Embedding provider for batch encoding. |
| `LC_MODEL`                | no       | `gpt-5.4-mini` | Model for batch consolidation.         |

## Channel state and activity

These control how long execution checkpoints survive and how user activity
state transitions.

| Name                            | Required | Default         | Purpose                                                     |
| ------------------------------- | -------- | --------------- | ----------------------------------------------------------- |
| `CHANNEL_STATE_TTL_ACTIVE`      | no       | `10800` (3 h)   | Seconds. Lifetime of checkpoints for active sessions.       |
| `CHANNEL_STATE_TTL_HITL`        | no       | `259200` (72 h) | Seconds. Lifetime of checkpoints for HITL-blocked sessions. |
| `ACTIVITY_IDLE_TIMEOUT_S`       | no       | `300` (5 m)     | Seconds before active → idle.                               |
| `ACTIVITY_AWAY_TIMEOUT_S`       | no       | `1800` (30 m)   | Seconds before idle → away.                                 |
| `ACTIVITY_DISCONNECT_TIMEOUT_S` | no       | `3600` (1 h)    | Seconds before away → disconnected.                         |

## Permissions and sandboxing

| Name                        | Required | Default   | Purpose                                                                   |
| --------------------------- | -------- | --------- | ------------------------------------------------------------------------- |
| `ASSET_DIRECTORY_SANDBOXED` | no       | `"true"`  | When `"true"`, Asset Directory tools run inside `bwrap`.                  |
| `ALLOWED_ROOTS`             | no       | —         | Comma-separated absolute paths. Restricts file operations to these paths. |
| `SUBPROCESS_SCRUB_MODE`     | no       | `default` | Env scrub level for subprocesses: `off`, `default`, or `strict`.          |

## Server configuration

| Name                                   | Required | Default   | Purpose                                                                         |
| -------------------------------------- | -------- | --------- | ------------------------------------------------------------------------------- |
| `ENGINE_API_KEY`                       | no       | —         | Static API key. Use for development. Production should rotate.                  |
| `ENGINE_KEY_HASH`                      | no       | —         | SHA-256 hash of `ENGINE_API_KEY`. Validated at startup.                         |
| `ENGINE_LOG_LEVEL`                     | no       | `INFO`    | Log verbosity: `DEBUG`, `INFO`, `WARNING`, `ERROR`.                             |
| `CORS_ORIGINS`                         | no       | —         | Comma-separated origins (e.g. `http://localhost:3000,https://app.example.com`). |
| `BAP_KEY_ROTATION_MIN_OVERLAP_SECONDS` | no       | `0`       | Minimum overlap window (seconds) when rotating API keys.                        |
| `BAP_KEY_ROTATION_MAX_OVERLAP_SECONDS` | no       | `300`     | Maximum overlap window (seconds) when rotating API keys.                        |
| `CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY` | no       | `10`      | Max concurrent tool calls in the streaming executor.                            |
| `INDUSTRY`                             | no       | —         | Industry scoping for catalog loading. Empty loads everything.                   |
| `PERSISTENCE_RETRY`                    | no       | `"false"` | Retry persistent operations on transient failures.                              |

## Feature flags

All values are the strings `"true"` or `"false"` (case-insensitive).

### Agent loop

| Name                          | Default   | Purpose                                      |
| ----------------------------- | --------- | -------------------------------------------- |
| `TOKEN_BUDGET_ENABLED`        | `"false"` | Token budget continuation loop in execution. |
| `STOP_HOOKS_ENABLED`          | `"true"`  | Run stop-hooks at turn boundaries.           |
| `PRE_TOOL_HOOKS_ENABLED`      | `"true"`  | Run hooks before tool calls.                 |
| `POST_TOOL_HOOKS_ENABLED`     | `"true"`  | Run hooks after tool returns.                |
| `HOOKS_SETTINGS_LOAD_ENABLED` | `"true"`  | Load hooks from settings files.              |
| `REACTIVE_COMPACT_ENABLED`    | `"true"`  | Recover from context overflow by compacting. |
| `CACHE_HIT_MONITOR_ENABLED`   | `"true"`  | Monitor prompt cache hit ratio.              |

### Media handling

| Name                               | Default   | Purpose                                             |
| ---------------------------------- | --------- | --------------------------------------------------- |
| `MEDIA_ERROR_RECOVERY_ENABLED`     | `"false"` | Strip problematic media blocks and retry on errors. |
| `MEDIA_PRESEND_VALIDATION_ENABLED` | `"false"` | Validate media (size, content) before send.         |
| `MEDIA_IMAGE_RESIZE_ENABLED`       | `"false"` | Resize oversized images before send.                |
| `CONTENT_INGESTION_ENABLED`        | `"false"` | Chunk and store large media in `ingestion_chunks`.  |

### Memory and compaction

| Name                                 | Default  | Purpose                                                               |
| ------------------------------------ | -------- | --------------------------------------------------------------------- |
| `USE_INMEMORY_WM`                    | —        | Use in-memory working memory backend instead of SQLite. Test/CI only. |
| `FEATURE_CACHED_SNIP_PREPASS`        | —        | Pre-pass snip computation for caching.                                |
| `FEATURE_POST_COMPACT_HARDENED`      | `"true"` | Hardened post-processing after compaction.                            |
| `FEATURE_STRUCTURED_FILE_EXTRACTION` | `"true"` | Extract structured file references during compaction.                 |

### Sandbox

| Name                           | Default  | Purpose                                                     |
| ------------------------------ | -------- | ----------------------------------------------------------- |
| `FEATURE_WINDOWS_PATH_EVASION` | `"true"` | Detect Windows-style path-evasion attempts.                 |
| `FEATURE_DONT_ASK`             | —        | Disable permission prompts. Set only in trusted automation. |
| `FEATURE_SED_VALIDATION`       | `"1"`    | Validate `sed` commands before running.                     |
| `FEATURE_DANGEROUS_REMOVAL`    | `"true"` | Detect and gate `rm` / `shred` of high-value paths.         |
| `FEATURE_TREE_KILL`            | `"true"` | Kill the entire process tree on task termination.           |
| `FEATURE_BG_WATCHDOG`          | `"true"` | Watchdog for orphaned background processes.                 |

### Other

| Name                           | Default   | Purpose                                         |
| ------------------------------ | --------- | ----------------------------------------------- |
| `ENABLE_SIGINT_INTERRUPT`      | `"false"` | Install SIGINT handler. Disable in server mode. |
| `QUERY_CHAIN_TRACKING_ENABLED` | `"false"` | Trace query chains for observability.           |

## Conventions

* **Booleans are strings.** Always `"true"` or `"false"`. Never `1` / `0`,
  never bare `true` / `false`, never `yes` / `no`. The Engine's loader is
  strict about this on purpose — typos become loud errors instead of silent
  defaults.
* **Paths are absolute.** Anything that takes a path expects an absolute
  path inside the container.
* **Secrets never go in code.** They go in `.env`, in your secret manager,
  or in environment variables passed at runtime.

## See also

* [Local development quickstart](../local-dev/quickstart) — minimal `.env`
  to get the Engine running.
* [Production deploy](../deploy/prod-deploy) — secret rotation, key
  rotation, hardened defaults.
* [Feature flags catalog](./feature-flags) — the same flags grouped by
  feature with rollout history.
