# domains
NODEDC_ENV=local
AUTH_DOMAIN=auth.local.nodedc
AUTH_ADMIN_DOMAIN=auth-admin.local.nodedc
LAUNCHER_DOMAIN=launcher.local.nodedc
TASK_DOMAIN=task.local.nodedc
BIM_DOMAIN=bim.local.nodedc
NODEDC_BIM_VIEWER_PUBLIC_URL=http://localhost:8080

# proxy
PLATFORM_HTTP_PORT=80
PLATFORM_PROXY_IMAGE=nodedc/plane-proxy:ru
LOCAL_LAUNCHER_UPSTREAM=host.docker.internal:5173
LOCAL_TASK_MANAGER_UPSTREAM=host.docker.internal:8090
LOCAL_BIM_VIEWER_UPSTREAM=host.docker.internal:8080

# authentik image
AUTHENTIK_IMAGE=ghcr.io/goauthentik/server
AUTHENTIK_TAG=2026.2.2

# authentik database
PG_DB=authentik
PG_USER=authentik
PG_PASS=change-me-generate-with-infra-scripts-init-dev-env

# authentik
AUTHENTIK_SECRET_KEY=change-me-generate-with-infra-scripts-init-dev-env
AUTHENTIK_ERROR_REPORTING__ENABLED=false

# optional first-start bootstrap
# AUTHENTIK_BOOTSTRAP_EMAIL=admin@nodedc.local
# AUTHENTIK_BOOTSTRAP_PASSWORD=
# AUTHENTIK_BOOTSTRAP_TOKEN=

# launcher oidc
LAUNCHER_OIDC_ISSUER=http://auth.local.nodedc/application/o/launcher/
LAUNCHER_OIDC_CLIENT_ID=nodedc-launcher
LAUNCHER_OIDC_CLIENT_SECRET=change-me-generate-with-bootstrap-authentik-dev
LAUNCHER_OIDC_REDIRECT_URI=http://launcher.local.nodedc/auth/callback
LAUNCHER_OIDC_LOGGED_OUT_REDIRECT_URI=http://launcher.local.nodedc/auth/logged-out

# plane oidc
PLANE_OIDC_ISSUER=http://auth.local.nodedc/application/o/task-manager/
PLANE_OIDC_CLIENT_ID=nodedc-task-manager
PLANE_OIDC_CLIENT_SECRET=change-me-generate-with-bootstrap-authentik-dev
PLANE_OIDC_REDIRECT_URI=http://task.local.nodedc/auth/oidc/callback

# security
SESSION_SECRET=change-me-generate-with-infra-scripts-init-dev-env
NODEDC_INTERNAL_ACCESS_TOKEN=change-me-generate-with-infra-scripts-init-dev-env
COOKIE_DOMAIN=.local.nodedc
COOKIE_SECURE=false

# External Data Plane — provider-neutral storage owned by the Platform. This
# password is a database credential only; never reuse NODEDC_INTERNAL_ACCESS_TOKEN.
EXTERNAL_DATA_PLANE_TIMESCALE_IMAGE=timescale/timescaledb-ha:pg16.14-ts2.28.2-all
EXTERNAL_DATA_PLANE_PG_DB=nodedc_data_plane
EXTERNAL_DATA_PLANE_PG_USER=nodedc_data_plane
EXTERNAL_DATA_PLANE_PG_PASS=change-me-generate-with-infra-scripts-init-dev-env
EXTERNAL_DATA_PLANE_HOST_BIND=127.0.0.1:18106
EXTERNAL_DATA_PLANE_DATABASE_POOL_SIZE=10
EXTERNAL_DATA_PLANE_RAW_RETENTION_DAYS=14
EXTERNAL_DATA_PLANE_MAX_BATCH_BYTES=5242880
EXTERNAL_DATA_PLANE_MAX_FACTS_PER_PUBLISH=5000
EXTERNAL_DATA_PLANE_MAX_ATTRIBUTES_BYTES_PER_FACT=65536
EXTERNAL_DATA_PLANE_MAX_PATCH_OPERATIONS=500
EXTERNAL_DATA_PLANE_MAX_PATCH_BYTES=262144
EXTERNAL_DATA_PLANE_PATCH_RETENTION_MS=3600000
EXTERNAL_DATA_PLANE_RECEIPT_RETENTION_MS=604800000
EXTERNAL_DATA_PLANE_RETENTION_DELETE_LIMIT=10000
EXTERNAL_DATA_PLANE_STREAM_HEARTBEAT_MS=20000
EXTERNAL_DATA_PLANE_STREAM_POLL_MS=1000
EXTERNAL_DATA_PLANE_MAX_READER_STREAMS=10
EXTERNAL_DATA_PLANE_WRITER_BINDING_MAX_TTL_DAYS=90
EXTERNAL_DATA_PLANE_MAX_FUTURE_SKEW_SECONDS=300
EXTERNAL_DATA_PLANE_RETENTION_SWEEP_MS=3600000
EXTERNAL_DATA_PLANE_LEGACY_INTAKE_ENABLED=false
# Internal control-plane writer/reader binding issuance; keep false until the
# atomic NDC L2 ensure-grant operation is deployed. Legacy path returns a
# plaintext capability and must never be exposed to users.
EXTERNAL_DATA_PLANE_PROVISIONING_ENABLED=false
# Digest-only managed writer-binding ensure. It accepts only signed Engine
# service requests; the legacy provisioner bearer is deliberately invalid here.
# Keep false until the matching Engine private key is provisioned. The trust
# directory is mounted read-only into EDP and contains only `public-key.pem`.
EXTERNAL_DATA_PLANE_MANAGED_PROVISIONING_ENABLED=false
EXTERNAL_DATA_PLANE_MANAGED_PROVISIONER_SERVICE_ID=nodedc-engine
EXTERNAL_DATA_PLANE_MANAGED_PROVISIONER_KEY_ID=engine-edp-managed-provisioner-v1
EXTERNAL_DATA_PLANE_MANAGED_PROVISIONER_AUDIENCE=nodedc-external-data-plane.managed-provisioning.v1
EXTERNAL_DATA_PLANE_MANAGED_PROVISIONER_MAX_SKEW_SECONDS=60
EXTERNAL_DATA_PLANE_MANAGED_PROVISIONER_REPLAY_CACHE_MAX_ENTRIES=10000
EXTERNAL_DATA_PLANE_FOUNDRY_PROVISIONING_ENABLED=true
EXTERNAL_DATA_PLANE_FOUNDRY_PROVISIONER_SERVICE_ID=nodedc-module-foundry
EXTERNAL_DATA_PLANE_FOUNDRY_PROVISIONER_KEY_ID=foundry-edp-managed-provisioner-v1
EXTERNAL_DATA_PLANE_FOUNDRY_PROVISIONER_AUDIENCE=nodedc-external-data-plane.managed-provisioning.v1
EXTERNAL_DATA_PLANE_FOUNDRY_PROVISIONER_MAX_SKEW_SECONDS=60
EXTERNAL_DATA_PLANE_FOUNDRY_PROVISIONER_REPLAY_CACHE_MAX_ENTRIES=10000

# notification core
NOTIFICATION_PG_DB=nodedc_notifications
NOTIFICATION_PG_USER=nodedc_notifications
NOTIFICATION_PG_PASS=change-me-generate-with-infra-scripts-init-dev-env
NODEDC_NOTIFICATION_CORE_URL=http://notification-core:5185

# AI Workspace Assistant shared registry/conversations
AI_WORKSPACE_PG_DB=nodedc_ai_workspace
AI_WORKSPACE_PG_USER=nodedc_ai_workspace
AI_WORKSPACE_PG_PASS=change-me-generate-with-infra-scripts-init-dev-env
AI_WORKSPACE_ASSISTANT_TOKEN=change-me-generate-with-infra-scripts-init-dev-env
NODEDC_AI_WORKSPACE_ASSISTANT_URL=http://ai-workspace-assistant:18082
AI_WORKSPACE_OPS_ENTITLEMENT_URL=http://host.docker.internal:4100/api/internal/v1/ai-workspace/entitlements
AI_WORKSPACE_OPS_ENTITLEMENT_TOKEN=replace-with-ops-agent-gateway-internal-token
AI_WORKSPACE_OPS_ENTITLEMENT_REQUIRED=false
# Add Module Foundry only after its domain, Launcher handoff and Authentik group
# are verified. Preserve existing adapters when adding this JSON member:
# {"module-foundry":{"url":"https://<foundry-domain>/api/ai-workspace/entitlements","required":false}}
# The generic adapter reuses the existing NODE.DC internal server credential;
# never define a separate Foundry token for a browser or worker.
AI_WORKSPACE_ENTITLEMENT_ADAPTERS_JSON=
AI_WORKSPACE_ASSISTANT_ACTION_RELAY_ENABLED=true
AI_WORKSPACE_ASSISTANT_ACTION_RELAY_ID=local-dev
AI_WORKSPACE_ONTOLOGY_MCP_ENABLED=true

# AI Workspace Hub for downloaded Codex workers.
# Default local development may use the deployed AI Hub only as a relay for remote Codex workers.
# Launcher/Engine/Ops/Auth downstream URLs must remain local.
# For Tailscale/ngrok-style relay URLs, set NODEDC_ENV=tunnel-local-e2e deliberately.
AI_WORKSPACE_HUB_TOKEN=change-me-generate-with-infra-scripts-init-dev-env
AI_WORKSPACE_HUB_HOST_BIND=127.0.0.1:18081
AI_WORKSPACE_HUB_PUBLIC_URL=wss://ai-hub.nodedc.ru/api/ai-workspace/hub
AI_WORKSPACE_HUB_INTERNAL_URL=https://ai-hub.nodedc.ru
AI_WORKSPACE_HUB_FALLBACK_URLS=
# The worker receives a per-run, pairing-bound read-only Ontology MCP URL through AI Hub.
# Do not put Ontology Core tokens or catalog paths in worker configuration.
AI_WORKSPACE_ONTOLOGY_MCP_PUBLIC_URL=
ONTOLOGY_CORE_HOST_BIND=127.0.0.1:18104

# Gelios Gateway — frozen legacy storage/read compatibility service. Provider
# credentials belong to the protected Engine Collector and are never configured
# in this service. Keep this contour reproducible; do not use it as a template
# for new providers.
GELIOS_TIMESCALE_IMAGE=timescale/timescaledb-ha:pg16.14-ts2.28.2-all
GELIOS_PG_DB=nodedc_gelios
GELIOS_PG_USER=nodedc_gelios
GELIOS_PG_PASS=change-me-generate-with-infra-scripts-init-dev-env
# URL-encode reserved characters in GELIOS_PG_PASS when forming this URL.
GELIOS_DATABASE_URL=postgresql://nodedc_gelios:change-me-generate-with-infra-scripts-init-dev-env@gelios-postgres:5432/nodedc_gelios
GELIOS_GATEWAY_HOST_BIND=127.0.0.1:18105
GELIOS_TENANT_ID=replace-with-tenant-id
GELIOS_CONNECTION_ID=gelios-connection-id
# `allowlist` accepts only GELIOS_ALLOWED_UNIT_IDS. `all` accepts every unit
# returned by this already-approved tenant + connection, including future units.
GELIOS_UNIT_SCOPE=allowlist
GELIOS_ALLOWED_UNIT_IDS=
GELIOS_INTAKE_ENABLED=false
GELIOS_RAW_RETENTION_DAYS=14
# Presentation state only; it does not change provider collection cadence.
GELIOS_POSITION_STALE_AFTER_MS=300000

# map gateway — keep the actual ion token only in local/staging environment files or Docker secrets.
# Never copy it into workflow metadata, Git, frontend code, or a runtime cache key.
MAP_GATEWAY_HOST_BIND=127.0.0.1:18103
MAP_GATEWAY_ALLOW_ANONYMOUS=true
MAP_GATEWAY_CORS_ORIGIN=http://127.0.0.1:3333,http://localhost:3333
MAP_GATEWAY_UPSTREAM_ALLOWLIST=api.cesium.com,assets.ion.cesium.com,tile.openstreetmap.org,dev.virtualearth.net,ecn.t0.tiles.virtualearth.net,ecn.t1.tiles.virtualearth.net,ecn.t2.tiles.virtualearth.net,ecn.t3.tiles.virtualearth.net
# Imported Engine imagery is selected through the explicit offline cache
# profile, not through a global host-side block.
MAP_GATEWAY_LEGACY_CACHE_HOSTS=
# Leave empty unless the provider/data licence explicitly permits disconnected/offline use.
MAP_GATEWAY_OFFLINE_PROVIDER_ALLOWLIST=
MAP_GATEWAY_UPSTREAM_TIMEOUT_SECONDS=30
CESIUM_ION_TOKEN=
CESIUM_ION_ASSET_ALLOWLIST=1,2,96188
MAP_CACHE_MODE=readwrite
# Mutable cache is mounted at /var/lib/nodedc-map-live-cache by compose.
# MAP_OFFLINE_SNAPSHOT_DIR is intentionally wired by compose as a read-only
# imported Engine snapshot; never place secrets or the live cache there.
MAP_CACHE_MAX_MB=20480
MAP_CACHE_MAX_OBJECT_MB=128
MAP_CACHE_DEFAULT_TTL_SECONDS=604800
