# =============================================================================
# Mnemosyne — docker compose interpolation template
# =============================================================================
# This file is consumed by `docker compose` as the source for `${VAR}`
# interpolations in docker-compose.yaml. In production it is generated from
# a Jinja2 template by an Ansible role, with secrets pulled from the Ansible
# vault — do not commit a populated copy.
#
# Copy to `.env` (at the repo root, NOT inside `mnemosyne/`) and fill in the
# blanks before running `docker compose up -d`. The in-tree `mnemosyne/.env`
# file (used by bare-Python development on caliban) is a separate concern
# and is NOT read by the compose stack.
#
# Every variable below is referenced by at least one service in
# docker-compose.yaml. Per-service scoping (which container sees which var)
# is defined by the `environment:` blocks in that file; this template just
# provides the values.
# =============================================================================

# --- Django core ------------------------------------------------------------
# Consumed by: app, mcp, worker
SECRET_KEY=change-me-to-a-real-secret-key
DEBUG=False
TIME_ZONE=UTC
LANGUAGE_CODE=en-us

# --- HTTP surface -----------------------------------------------------------
# Consumed by: app (CSRF_TRUSTED_ORIGINS: app only; ALLOWED_HOSTS: app + mcp)
# Include every hostname HAProxy routes to this stack, plus localhost for the
# inter-container health probes.
ALLOWED_HOSTS=localhost,127.0.0.1,mnemosyne.ouranos.helu.ca
CSRF_TRUSTED_ORIGINS=https://mnemosyne.ouranos.helu.ca

# --- PostgreSQL (Portia) ----------------------------------------------------
# Consumed by: app, mcp, worker
APP_DB_NAME=mnemosyne
APP_DB_USER=mnemosyne
APP_DB_PASSWORD=change-me
DB_HOST=portia.incus
DB_PORT=5432

# --- Neo4j (Umbriel — dedicated Mnemosyne instance) -------------------------
# Consumed by: app, mcp, worker
# Umbriel MUST be dedicated to Mnemosyne; do not share with Spelunker or any
# other graph workload. See README.md for the full rationale.
NEOMODEL_NEO4J_BOLT_URL=bolt://neo4j:change-me@umbriel.incus:7687

# --- Memcached --------------------------------------------------------------
# Consumed by: app, mcp, worker
# Must resolve from inside containers — 127.0.0.1 will NOT work.
KVDB_LOCATION=oberon.incus:11211
KVDB_PREFIX=mnemosyne

# --- S3 / MinIO (Nyx) — Mnemosyne's own bucket ------------------------------
# Consumed by: app, mcp, worker
# Mnemosyne writes chunk text and item files here. Set USE_LOCAL_STORAGE=False
# in production so the S3Boto3Storage backend is used instead of the local
# FileSystemStorage fallback.
USE_LOCAL_STORAGE=False
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_STORAGE_BUCKET_NAME=mnemosyne-content
AWS_S3_ENDPOINT_URL=https://nyx.helu.ca:8555
AWS_S3_USE_SSL=True
AWS_S3_VERIFY=False
AWS_S3_REGION_NAME=us-east-1

# --- Daedalus S3 (cross-bucket reads for ingest) ----------------------------
# Consumed by: worker only
# Mnemosyne's ingest Celery task reads files from Daedalus's bucket and
# copies them into AWS_STORAGE_BUCKET_NAME for processing. These creds
# should be scoped read-only to the Daedalus bucket in your secret manager.
DAEDALUS_S3_ENDPOINT_URL=https://nyx.helu.ca:8555
DAEDALUS_S3_ACCESS_KEY_ID=
DAEDALUS_S3_SECRET_ACCESS_KEY=
DAEDALUS_S3_BUCKET_NAME=daedalus
DAEDALUS_S3_REGION_NAME=us-east-1
DAEDALUS_S3_USE_SSL=True
DAEDALUS_S3_VERIFY=True

# --- Spelunker S3 (cross-bucket reads for ingest, source="spelunker") ---
# Consumed by: worker only
# Spelunker scrapes web/git documents into its own bucket and posts ingest
# requests with source="spelunker". These creds should be scoped read-only
# to the Spelunker bucket in your secret manager.
SPELUNKER_S3_ENDPOINT_URL=https://nyx.helu.ca:8555
SPELUNKER_S3_ACCESS_KEY_ID=
SPELUNKER_S3_SECRET_ACCESS_KEY=
SPELUNKER_S3_BUCKET_NAME=spelunker
SPELUNKER_S3_REGION_NAME=us-east-1
SPELUNKER_S3_USE_SSL=True
SPELUNKER_S3_VERIFY=True

# --- Celery / RabbitMQ (Oberon) ---------------------------------------------
# Consumed by: app (producer), worker (consumer). NOT mcp.
# Remember to percent-encode any password characters that have meaning in a
# URL (`@ : / # % + ? & =` and space). Kombu's AMQP URL parser is strict —
# an unencoded password is the most common cause of PLAIN 403 failures when
# the bare-Python client happens to connect fine.
CELERY_BROKER_URL=amqp://mnemosyne:change-me@oberon.incus:5672/mnemosyne
CELERY_RESULT_BACKEND=rpc://
CELERY_TASK_ALWAYS_EAGER=False

# --- Worker tuning ---------------------------------------------------------
# Consumed by: worker only (read by entrypoint.sh → `celery -A mnemosyne worker`)
# Override per host if you want to dedicate a worker to a single queue.
CELERY_QUEUES=celery,embedding,batch
CELERY_CONCURRENCY=2

# --- SSO / Casdoor ----------------------------------------------------------
# Consumed by: app only
# Set CASDOOR_ENABLED=True in production to activate OIDC login. All other
# CASDOOR_* vars are required when enabled. CASDOOR_SSL_VERIFY should always
# be true in production; set to false only in sandboxes with self-signed certs.
CASDOOR_ENABLED=False
CASDOOR_ORIGIN=https://casdoor.example.com
CASDOOR_ORIGIN_FRONTEND=https://casdoor.example.com
CASDOOR_CLIENT_ID=
CASDOOR_CLIENT_SECRET=
CASDOOR_ORG_NAME=
CASDOOR_SSL_VERIFY=true
ALLOW_LOCAL_LOGIN=False

# --- MCP server -------------------------------------------------------------
# Consumed by: mcp only
MCP_REQUIRE_AUTH=True

# --- LLM API encryption -----------------------------------------------------
# Consumed by: app (admin pages), worker (ingest vision pass). NOT mcp.
# Generate once per deployment, store in the vault, never rotate without
# re-encrypting every stored provider key first.
# python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
LLM_API_SECRETS_ENCRYPTION_KEY=

# --- Email (smtp4dev on Oberon) --------------------------------------------
# Consumed by: app only
EMAIL_HOST=oberon.incus
EMAIL_PORT=22025
EMAIL_USE_TLS=False

# --- Embedding pipeline -----------------------------------------------------
# Consumed by: worker only
EMBEDDING_BATCH_SIZE=8
EMBEDDING_TIMEOUT=120

# --- Search & re-ranker -----------------------------------------------------
# Consumed by: app, mcp. Not worker (workers never serve queries).
SEARCH_VECTOR_TOP_K=50
SEARCH_FULLTEXT_TOP_K=30
SEARCH_GRAPH_MAX_DEPTH=2
SEARCH_RRF_K=60
SEARCH_DEFAULT_LIMIT=20
RERANKER_MAX_CANDIDATES=32
RERANKER_TIMEOUT=30

# --- Logging ----------------------------------------------------------------
# Consumed by: app, mcp, worker (each picks the levels it cares about)
LOGGING_LEVEL=INFO
CELERY_LOGGING_LEVEL=INFO
DJANGO_LOGGING_LEVEL=WARNING
