Skip to main content

dynamo_runtime/config/
environment_names.rs

1// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Environment variable name constants for centralized management across the codebase
5//!
6//! This module provides centralized environment variable name constants to ensure
7//! consistency and avoid duplication across the codebase, similar to how
8//! `prometheus_names.rs` manages metric names.
9//!
10//! ## Organization
11//!
12//! Environment variables are organized by functional area:
13//! - **Logging**: Log level, configuration, and OTLP tracing
14//! - **Runtime**: Tokio runtime configuration and system server settings
15//! - **NATS**: NATS client connection and authentication
16//! - **ETCD**: ETCD client connection and authentication
17//! - **TCP Request Callback**: bidirectional request callback listener port and host
18//! - **Event Plane**: Event transport selection (NATS)
19//! - **KVBM**: Key-Value Block Manager configuration
20//! - **LLM**: Language model inference configuration
21//! - **Model**: Model loading and caching
22//! - **Worker**: Worker lifecycle and shutdown
23//! - **Testing**: Test-specific configuration
24//! - **Mocker**: Mocker (mock scheduler/KV manager) configuration
25
26/// Logging and tracing environment variables
27pub mod logging {
28    /// Log level (e.g., "debug", "info", "warn", "error")
29    pub const DYN_LOG: &str = "DYN_LOG";
30
31    /// Path to logging configuration file
32    pub const DYN_LOGGING_CONFIG_PATH: &str = "DYN_LOGGING_CONFIG_PATH";
33
34    /// Enable JSONL logging format
35    pub const DYN_LOGGING_JSONL: &str = "DYN_LOGGING_JSONL";
36
37    /// Console log format: "readable" or "jsonl"; blank uses the legacy fallback
38    pub const DYN_LOGGING_CONSOLE_FORMAT: &str = "DYN_LOGGING_CONSOLE_FORMAT";
39
40    /// Disable ANSI terminal colors in logs
41    pub const DYN_SDK_DISABLE_ANSI_LOGGING: &str = "DYN_SDK_DISABLE_ANSI_LOGGING";
42
43    /// Use local timezone for logging timestamps (default is UTC)
44    pub const DYN_LOG_USE_LOCAL_TZ: &str = "DYN_LOG_USE_LOCAL_TZ";
45
46    /// Enable span event logging (create/close events)
47    pub const DYN_LOGGING_SPAN_EVENTS: &str = "DYN_LOGGING_SPAN_EVENTS";
48
49    /// OTLP (OpenTelemetry Protocol) tracing and logging configuration
50    pub mod otlp {
51        /// Enable OTLP export for traces and logs (set to "1" to enable)
52        pub const OTEL_EXPORT_ENABLED: &str = "OTEL_EXPORT_ENABLED";
53
54        /// OTLP exporter transport protocol. Supported values: "grpc", "http/protobuf".
55        pub const OTEL_EXPORTER_OTLP_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_PROTOCOL";
56
57        /// OTLP exporter transport protocol for traces. Defaults to OTEL_EXPORTER_OTLP_PROTOCOL.
58        pub const OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL";
59
60        /// OTLP exporter transport protocol for logs. Defaults to OTEL_EXPORTER_OTLP_PROTOCOL.
61        pub const OTEL_EXPORTER_OTLP_LOGS_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL";
62
63        /// Generic OTLP exporter endpoint URL used when signal-specific endpoints are unset.
64        pub const OTEL_EXPORTER_OTLP_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_ENDPOINT";
65
66        /// OTLP exporter endpoint URL for traces
67        /// Spec: <https://opentelemetry.io/docs/specs/otel/protocol/exporter/>
68        pub const OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
69
70        /// OTLP exporter endpoint URL for logs. Falls back to OTEL_EXPORTER_OTLP_ENDPOINT or the protocol default when unset.
71        pub const OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT";
72
73        /// Trace sampling ratio used when set. Example: "0.01" samples roughly 1% of traces.
74        pub const OTEL_TRACES_SAMPLE_RATIO: &str = "OTEL_TRACES_SAMPLE_RATIO";
75
76        /// Service name for OTLP traces and logs
77        pub const OTEL_SERVICE_NAME: &str = "OTEL_SERVICE_NAME";
78
79        /// Set to "otlp" to export metrics over OTLP. Any other value disables it.
80        /// Prometheus scraping is unaffected either way.
81        pub const OTEL_METRICS_EXPORTER: &str = "OTEL_METRICS_EXPORTER";
82
83        /// OTLP exporter endpoint URL for metrics. Falls back to OTEL_EXPORTER_OTLP_ENDPOINT.
84        pub const OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT";
85
86        /// OTLP exporter transport protocol for metrics. Defaults to OTEL_EXPORTER_OTLP_PROTOCOL.
87        pub const OTEL_EXPORTER_OTLP_METRICS_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_METRICS_PROTOCOL";
88
89        /// Headers sent with every OTLP request, as `key=value` pairs separated
90        /// by commas. Used for authenticated collectors (bearer token, API key).
91        pub const OTEL_EXPORTER_OTLP_HEADERS: &str = "OTEL_EXPORTER_OTLP_HEADERS";
92
93        /// Headers for metrics specifically. Replaces OTEL_EXPORTER_OTLP_HEADERS
94        /// when set, rather than merging with it, per the OTLP exporter spec.
95        pub const OTEL_EXPORTER_OTLP_METRICS_HEADERS: &str = "OTEL_EXPORTER_OTLP_METRICS_HEADERS";
96
97        /// Headers for traces specifically. Replaces OTEL_EXPORTER_OTLP_HEADERS when set.
98        pub const OTEL_EXPORTER_OTLP_TRACES_HEADERS: &str = "OTEL_EXPORTER_OTLP_TRACES_HEADERS";
99
100        /// Headers for logs specifically. Replaces OTEL_EXPORTER_OTLP_HEADERS when set.
101        pub const OTEL_EXPORTER_OTLP_LOGS_HEADERS: &str = "OTEL_EXPORTER_OTLP_LOGS_HEADERS";
102
103        /// Resource attributes applied to every exported signal, as `key=value`
104        /// pairs separated by commas.
105        pub const OTEL_RESOURCE_ATTRIBUTES: &str = "OTEL_RESOURCE_ATTRIBUTES";
106
107        /// Metric export interval in milliseconds. Spec default is 60000.
108        pub const OTEL_METRIC_EXPORT_INTERVAL: &str = "OTEL_METRIC_EXPORT_INTERVAL";
109    }
110}
111
112/// Request-lifecycle tracing environment variables.
113pub mod lifecycle_tracing {
114    /// Enable the native request-lifecycle OpenTelemetry span convention.
115    ///
116    /// This is independent from `DYN_LOG`: lifecycle spans are exported through
117    /// the OpenTelemetry tracing layer only.
118    pub const DYN_LIFECYCLE_TRACE_ENABLED: &str = "DYN_LIFECYCLE_TRACE_ENABLED";
119
120    /// Lifecycle detail mode. Defaults to `core`.
121    pub const DYN_LIFECYCLE_TRACE_MODE: &str = "DYN_LIFECYCLE_TRACE_MODE";
122}
123
124/// Runtime configuration environment variables
125///
126/// These control the Tokio runtime, system health/metrics server, and worker behavior
127pub mod runtime {
128    /// Number of async worker threads for Tokio runtime
129    pub const DYN_RUNTIME_NUM_WORKER_THREADS: &str = "DYN_RUNTIME_NUM_WORKER_THREADS";
130
131    /// Maximum number of blocking threads for Tokio runtime
132    pub const DYN_RUNTIME_MAX_BLOCKING_THREADS: &str = "DYN_RUNTIME_MAX_BLOCKING_THREADS";
133
134    /// Maximum time to wait for graceful endpoint drain during runtime shutdown.
135    pub const DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS: &str =
136        "DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS";
137
138    /// Maximum duration for local worker inhibition after a request failure. Zero disables it.
139    pub const DYN_RUNTIME_INHIBITED_DURATION_SECS: &str = "DYN_RUNTIME_INHIBITED_DURATION_SECS";
140
141    /// Enable Tokio task poll-time histogram (calls enable_metrics_poll_time_histogram on builder).
142    /// Set to "1", "true", or "yes" to enable. Adds ~2× overhead of Instant::now() per task poll.
143    pub const DYN_ENABLE_POLL_HISTOGRAM: &str = "DYN_ENABLE_POLL_HISTOGRAM";
144
145    /// System status server configuration
146    pub mod system {
147        /// Enable system status server for health and metrics endpoints
148        /// ⚠️ DEPRECATED: will be removed soon
149        pub const DYN_SYSTEM_ENABLED: &str = "DYN_SYSTEM_ENABLED";
150
151        /// System status server host
152        pub const DYN_SYSTEM_HOST: &str = "DYN_SYSTEM_HOST";
153
154        /// System status server port
155        pub const DYN_SYSTEM_PORT: &str = "DYN_SYSTEM_PORT";
156
157        /// Use endpoint health status for system health
158        /// ⚠️ DEPRECATED: No longer used
159        pub const DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS: &str =
160            "DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS";
161
162        /// Starting health status for the system
163        pub const DYN_SYSTEM_STARTING_HEALTH_STATUS: &str = "DYN_SYSTEM_STARTING_HEALTH_STATUS";
164
165        /// Health check endpoint path
166        pub const DYN_SYSTEM_HEALTH_PATH: &str = "DYN_SYSTEM_HEALTH_PATH";
167
168        /// Liveness check endpoint path
169        pub const DYN_SYSTEM_LIVE_PATH: &str = "DYN_SYSTEM_LIVE_PATH";
170    }
171
172    /// Compute configuration
173    pub mod compute {
174        /// Prefix for compute-related environment variables
175        pub const PREFIX: &str = "DYN_COMPUTE_";
176    }
177
178    /// Canary deployment configuration
179    pub mod canary {
180        /// Wait time in seconds for canary deployments
181        pub const DYN_CANARY_WAIT_TIME: &str = "DYN_CANARY_WAIT_TIME";
182    }
183}
184
185/// Worker lifecycle environment variables
186pub mod worker {
187    /// Graceful shutdown timeout in seconds
188    pub const DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT: &str = "DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT";
189}
190
191/// NATS transport environment variables
192pub mod nats {
193    /// NATS server address (e.g., "nats://localhost:4222")
194    pub const NATS_SERVER: &str = "NATS_SERVER";
195
196    /// NATS request/reply timeout in seconds. Unset = async-nats default (10 s).
197    pub const DYN_NATS_REQUEST_TIMEOUT_SECS: &str = "DYN_NATS_REQUEST_TIMEOUT_SECS";
198
199    /// Maximum time in seconds to establish the initial NATS connection.
200    pub const NATS_STARTUP_CONNECT_TIMEOUT_SECONDS: &str = "NATS_STARTUP_CONNECT_TIMEOUT_SECONDS";
201
202    /// NATS authentication environment variables (checked in priority order)
203    pub mod auth {
204        /// Username for NATS authentication (use with NATS_AUTH_PASSWORD)
205        pub const NATS_AUTH_USERNAME: &str = "NATS_AUTH_USERNAME";
206
207        /// Password for NATS authentication (use with NATS_AUTH_USERNAME)
208        pub const NATS_AUTH_PASSWORD: &str = "NATS_AUTH_PASSWORD";
209
210        /// Token for NATS authentication
211        pub const NATS_AUTH_TOKEN: &str = "NATS_AUTH_TOKEN";
212
213        /// NKey for NATS authentication
214        pub const NATS_AUTH_NKEY: &str = "NATS_AUTH_NKEY";
215
216        /// Path to NATS credentials file
217        pub const NATS_AUTH_CREDENTIALS_FILE: &str = "NATS_AUTH_CREDENTIALS_FILE";
218    }
219
220    /// NATS stream configuration
221    pub mod stream {
222        /// Maximum age for messages in NATS stream (in seconds)
223        pub const DYN_NATS_STREAM_MAX_AGE: &str = "DYN_NATS_STREAM_MAX_AGE";
224    }
225
226    /// NATS TLS configuration
227    pub mod tls {
228        /// Path to the PEM CA certificate used to verify the NATS server's certificate.
229        /// When set, a custom TLS config with this CA is applied to the NATS connection.
230        pub const NATS_TLS_CA_CERT_PATH: &str = "NATS_TLS_CA_CERT_PATH";
231
232        /// Path to the PEM client certificate presented to the NATS server for
233        /// mutual TLS (mTLS). Must be set together with `NATS_TLS_CLIENT_KEY_PATH`.
234        pub const NATS_TLS_CLIENT_CERT_PATH: &str = "NATS_TLS_CLIENT_CERT_PATH";
235
236        /// Path to the PEM client private key for NATS mutual TLS (mTLS).
237        /// Must be set together with `NATS_TLS_CLIENT_CERT_PATH`.
238        pub const NATS_TLS_CLIENT_KEY_PATH: &str = "NATS_TLS_CLIENT_KEY_PATH";
239
240        /// Disable TLS certificate verification. Set to a truthy value to skip.
241        /// WARNING: Only for local development. Never use in production.
242        pub const NATS_TLS_INSECURE: &str = "NATS_TLS_INSECURE";
243    }
244}
245
246/// ETCD transport environment variables
247pub mod etcd {
248    /// ETCD endpoints (comma-separated list of URLs)
249    pub const ETCD_ENDPOINTS: &str = "ETCD_ENDPOINTS";
250
251    /// ETCD lease TTL in seconds (default: 30)
252    pub const ETCD_LEASE_TTL: &str = "ETCD_LEASE_TTL";
253
254    /// Maximum time in seconds to retry the initial ETCD connection (default: 120)
255    pub const ETCD_STARTUP_CONNECT_TIMEOUT_SECONDS: &str = "ETCD_STARTUP_CONNECT_TIMEOUT_SECONDS";
256
257    /// HTTP/2 keepalive ping interval in seconds for the ETCD channel (default: 15, 0 disables)
258    pub const ETCD_KEEPALIVE_INTERVAL_SECONDS: &str = "ETCD_KEEPALIVE_INTERVAL_SECONDS";
259
260    /// Seconds to wait for a keepalive ping ack before the ETCD channel is closed (default: 10)
261    pub const ETCD_KEEPALIVE_TIMEOUT_SECONDS: &str = "ETCD_KEEPALIVE_TIMEOUT_SECONDS";
262
263    /// ETCD authentication environment variables
264    pub mod auth {
265        /// Username for ETCD authentication
266        pub const ETCD_AUTH_USERNAME: &str = "ETCD_AUTH_USERNAME";
267
268        /// Password for ETCD authentication
269        pub const ETCD_AUTH_PASSWORD: &str = "ETCD_AUTH_PASSWORD";
270
271        /// Path to CA certificate for ETCD TLS
272        pub const ETCD_AUTH_CA: &str = "ETCD_AUTH_CA";
273
274        /// Path to client certificate for ETCD TLS
275        pub const ETCD_AUTH_CLIENT_CERT: &str = "ETCD_AUTH_CLIENT_CERT";
276
277        /// Path to client key for ETCD TLS
278        pub const ETCD_AUTH_CLIENT_KEY: &str = "ETCD_AUTH_CLIENT_KEY";
279    }
280}
281
282/// Key-Value Block Manager (KVBM) environment variables
283pub mod kvbm {
284    /// Enable KVBM metrics endpoint
285    pub const DYN_KVBM_METRICS: &str = "DYN_KVBM_METRICS";
286
287    /// KVBM metrics endpoint port
288    pub const DYN_KVBM_METRICS_PORT: &str = "DYN_KVBM_METRICS_PORT";
289
290    /// Enable KVBM recording for debugging.
291    pub const DYN_KVBM_ENABLE_RECORD: &str = "DYN_KVBM_ENABLE_RECORD";
292
293    /// Disable disk offload filter
294    pub const DYN_KVBM_DISABLE_DISK_OFFLOAD_FILTER: &str = "DYN_KVBM_DISABLE_DISK_OFFLOAD_FILTER";
295
296    /// CPU cache configuration
297    pub mod cpu_cache {
298        /// CPU cache size in GB
299        pub const DYN_KVBM_CPU_CACHE_GB: &str = "DYN_KVBM_CPU_CACHE_GB";
300
301        /// CPU cache size in number of blocks (override)
302        pub const DYN_KVBM_CPU_CACHE_OVERRIDE_NUM_BLOCKS: &str =
303            "DYN_KVBM_CPU_CACHE_OVERRIDE_NUM_BLOCKS";
304    }
305
306    /// Disk cache configuration
307    pub mod disk_cache {
308        /// Disk cache size in GB
309        pub const DYN_KVBM_DISK_CACHE_GB: &str = "DYN_KVBM_DISK_CACHE_GB";
310
311        /// Disk cache size in number of blocks (override)
312        pub const DYN_KVBM_DISK_CACHE_OVERRIDE_NUM_BLOCKS: &str =
313            "DYN_KVBM_DISK_CACHE_OVERRIDE_NUM_BLOCKS";
314    }
315
316    /// Object storage configuration
317    pub mod object_storage {
318        /// Enable object storage. Set to "1" to enable.
319        pub const DYN_KVBM_OBJECT_ENABLED: &str = "DYN_KVBM_OBJECT_ENABLED";
320
321        /// Bucket name for object storage cache
322        /// Supports `{worker_id}` template for per-worker buckets
323        /// Example: "kv-cache-{worker_id}"
324        pub const DYN_KVBM_OBJECT_BUCKET: &str = "DYN_KVBM_OBJECT_BUCKET";
325
326        /// Endpoint for object storage
327        pub const DYN_KVBM_OBJECT_ENDPOINT: &str = "DYN_KVBM_OBJECT_ENDPOINT";
328
329        /// Region for object storage
330        pub const DYN_KVBM_OBJECT_REGION: &str = "DYN_KVBM_OBJECT_REGION";
331
332        /// Access key for authentication
333        pub const DYN_KVBM_OBJECT_ACCESS_KEY: &str = "DYN_KVBM_OBJECT_ACCESS_KEY";
334
335        /// Secret key for authentication
336        pub const DYN_KVBM_OBJECT_SECRET_KEY: &str = "DYN_KVBM_OBJECT_SECRET_KEY";
337
338        /// Number of blocks to store in object storage
339        pub const DYN_KVBM_OBJECT_NUM_BLOCKS: &str = "DYN_KVBM_OBJECT_NUM_BLOCKS";
340    }
341    /// Transfer configuration
342    pub mod transfer {
343        /// Maximum number of blocks per transfer batch
344        pub const DYN_KVBM_TRANSFER_BATCH_SIZE: &str = "DYN_KVBM_TRANSFER_BATCH_SIZE";
345    }
346
347    /// KVBM leader (distributed mode) configuration
348    pub mod leader {
349        /// Timeout in seconds for KVBM leader and worker initialization
350        pub const DYN_KVBM_LEADER_WORKER_INIT_TIMEOUT_SECS: &str =
351            "DYN_KVBM_LEADER_WORKER_INIT_TIMEOUT_SECS";
352
353        /// ZMQ host for KVBM leader
354        pub const DYN_KVBM_LEADER_ZMQ_HOST: &str = "DYN_KVBM_LEADER_ZMQ_HOST";
355
356        /// ZMQ publish port for KVBM leader
357        pub const DYN_KVBM_LEADER_ZMQ_PUB_PORT: &str = "DYN_KVBM_LEADER_ZMQ_PUB_PORT";
358
359        /// ZMQ acknowledgment port for KVBM leader
360        pub const DYN_KVBM_LEADER_ZMQ_ACK_PORT: &str = "DYN_KVBM_LEADER_ZMQ_ACK_PORT";
361    }
362
363    /// NIXL backend configuration
364    pub mod nixl {
365        /// Prefix for NIXL backend environment variables
366        /// Pattern: `DYN_KVBM_NIXL_BACKEND_<backend>`=true/false
367        /// Example: DYN_KVBM_NIXL_BACKEND_UCX=true
368        pub const PREFIX: &str = "DYN_KVBM_NIXL_BACKEND_";
369    }
370}
371
372/// LLM (Language Model) inference environment variables
373pub mod llm {
374    /// Delay between tokens emitted by the token echo engine, in milliseconds.
375    pub const DYN_TOKEN_ECHO_DELAY_MS: &str = "DYN_TOKEN_ECHO_DELAY_MS";
376
377    /// HTTP body size limit in MB
378    pub const DYN_HTTP_BODY_LIMIT_MB: &str = "DYN_HTTP_BODY_LIMIT_MB";
379
380    /// Listen backlog of the frontend HTTP/HTTPS socket (default 4096).
381    pub const DYN_HTTP_LISTEN_BACKLOG: &str = "DYN_HTTP_LISTEN_BACKLOG";
382
383    pub const DYN_HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_SECS: &str =
384        "DYN_HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_SECS";
385
386    /// HTTP status code returned when the frontend rejects a request because
387    /// all workers are overloaded. Defaults to 529 ("Site is overloaded"); set
388    /// to 503 for Service Unavailable retry semantics. Status codes from 200
389    /// through 999 are accepted; an informational value from 100 through 199,
390    /// an unparseable value, or an out-of-range value falls back to 529. The
391    /// value is read and cached on first use.
392    pub const DYN_HTTP_OVERLOAD_STATUS_CODE: &str = "DYN_HTTP_OVERLOAD_STATUS_CODE";
393
394    /// Emit an SSE comment at this interval while a streaming response has no
395    /// data. Unset, `0`, invalid, or unrepresentable values keep SSE comments
396    /// disabled.
397    pub const DYN_HTTP_SSE_KEEP_ALIVE_INTERVAL_MS: &str = "DYN_HTTP_SSE_KEEP_ALIVE_INTERVAL_MS";
398
399    /// Enable LoRA adapter support (set to "true" to enable)
400    pub const DYN_LORA_ENABLED: &str = "DYN_LORA_ENABLED";
401
402    /// LoRA cache directory path
403    pub const DYN_LORA_PATH: &str = "DYN_LORA_PATH";
404
405    /// Enable the experimental Anthropic Messages API endpoint (/v1/messages)
406    pub const DYN_ENABLE_ANTHROPIC_API: &str = "DYN_ENABLE_ANTHROPIC_API";
407
408    /// Master switch for the `nvext` extension protocol on the frontend.
409    /// The protocol is **enabled by default**; this variable disables it.
410    /// Truthy values (`1` / `true` / `yes` / `on`, case-insensitive) cause
411    /// the frontend to drop non-salt request NvExt fields, ignore supported
412    /// routing-override headers, and silently ignore the response-side
413    /// `extra_fields` opt-in. Cache isolation is exempt: supported
414    /// `cache_salt` and `x-tenant-id` inputs remain active.
415    pub const DYN_DISABLE_FRONTEND_NVEXT: &str = "DYN_DISABLE_FRONTEND_NVEXT";
416
417    /// Ignore unknown OpenAI frontend request fields. Unknown fields are dropped,
418    /// not handled; known pass-through fields remain type-validated.
419    pub const DYN_IGNORE_OPENAI_FE_UNSUPPORTED_FIELDS: &str =
420        "DYN_IGNORE_OPENAI_FE_UNSUPPORTED_FIELDS";
421
422    /// Master switch for the frontend's HTTP admin API surface.
423    /// The admin API is **enabled by default**; this variable disables it.
424    /// Truthy values (`1` / `true` / `yes` / `on`, case-insensitive) prevent
425    /// registration of `GET` / `POST /busy_threshold`. Inference, metrics,
426    /// models, health, and liveness routes are unaffected.
427    pub const DYN_DISABLE_FRONTEND_ADMIN_API: &str = "DYN_DISABLE_FRONTEND_ADMIN_API";
428
429    /// Strip the Claude Code billing preamble (`x-anthropic-billing-header: ...`)
430    /// from the system prompt before forwarding to the target model. The preamble
431    /// varies per session and per release, wasting tokens and breaking prompt caching.
432    pub const DYN_STRIP_ANTHROPIC_PREAMBLE: &str = "DYN_STRIP_ANTHROPIC_PREAMBLE";
433
434    /// When truthy, force usage in streaming chat and text-completion responses
435    /// regardless of the request's `stream_options.include_usage` value.
436    /// Unset or false preserves request-controlled defaults.
437    pub const DYN_ENABLE_FORCE_INCLUDE_USAGE: &str = "DYN_ENABLE_FORCE_INCLUDE_USAGE";
438
439    /// Enable streaming tool call dispatch (`event: tool_call_dispatch` SSE events)
440    pub const DYN_ENABLE_STREAMING_TOOL_DISPATCH: &str = "DYN_ENABLE_STREAMING_TOOL_DISPATCH";
441
442    /// Enable streaming reasoning dispatch (`event: reasoning_dispatch` SSE events)
443    pub const DYN_ENABLE_STREAMING_REASONING_DISPATCH: &str =
444        "DYN_ENABLE_STREAMING_REASONING_DISPATCH";
445
446    /// OpenAI-compatible response field used for emitted reasoning content.
447    /// Accepted values: "reasoning_content" (default) or "reasoning".
448    pub const DYN_REASONING_FIELD_NAME: &str = "DYN_REASONING_FIELD_NAME";
449
450    /// Select the parser generation. Unset or `auto` keeps the original family defaults.
451    ///
452    /// Explicit `1` keeps the V1 parsers; explicit `2` selects a compatible unified
453    /// parser for the configured family. When both parser slots are set, their names
454    /// must resolve to the same family. Unsupported explicit selections fail during
455    /// preprocessor construction.
456    ///
457    /// Accepted values are `auto`, `1`, and `2`. Explicit
458    /// generations fail during preprocessor construction when the configured family has
459    /// no compatible parser.
460    pub const DYN_PARSER_VERSION: &str = "DYN_PARSER_VERSION";
461
462    /// Compatibility alias for `DYN_PARSER_VERSION=2` when enabled. Uses the shared
463    /// boolean parser: `1`/`true`/`on`/`yes` enable it; `0`/`false`/`off`/`no`/empty
464    /// disable it. This conflicts with `DYN_PARSER_VERSION=1`; `false` conflicts with `2`.
465    pub const DYN_ENABLE_EXPERIMENTAL_PARSERS_V2: &str = "DYN_ENABLE_EXPERIMENTAL_PARSERS_V2";
466
467    /// Rollback lever for incremental guided-tool-call streaming.
468    ///
469    /// A forced `tool_choice` (`required` or a named tool) installs a JSON grammar,
470    /// so by default the jail releases tool-call chunks as they arrive instead of
471    /// buffering the whole response. The grammar-constrained decoding itself lives
472    /// in the published `dynamo-parsers` dependency, not in this repo, so if a
473    /// backend in production doesn't correctly honor the grammar the only other
474    /// rollback is a dependency repin and a new release. On by default; set this
475    /// to a falsy value (`0`/`false`) to fall back to the old buffer-to-completion
476    /// behavior at runtime, no redeploy required.
477    pub const DYN_ENABLE_GUIDED_TOOL_STREAMING: &str = "DYN_ENABLE_GUIDED_TOOL_STREAMING";
478
479    /// Backend stream inactivity timeout in seconds.
480    ///
481    /// When set to a positive integer, the frontend will kill the engine context
482    /// and drop the inflight guard if no SSE event is received from the backend
483    /// within this many seconds. Acts as a circuit breaker for zombie workers
484    /// that hold a live TCP connection but never produce output.
485    ///
486    /// Set to `0` or leave unset to disable the timeout (default: disabled).
487    pub const DYN_HTTP_BACKEND_STREAM_TIMEOUT_SECS: &str = "DYN_HTTP_BACKEND_STREAM_TIMEOUT_SECS";
488
489    /// Pre-commit peek window in milliseconds for the streaming chat,
490    /// completions, responses, and Anthropic messages paths. Controls how long
491    /// the frontend polls the engine stream for a synchronous backend error
492    /// before committing HTTP 200.
493    /// Trades a small first-token latency budget
494    /// for the ability to surface `Backend(InvalidArgument)` and other
495    /// request-validation errors as HTTP 4xx instead of an SSE error frame.
496    ///
497    /// Default: unset → peek disabled (matches pre-fix behavior; all errors
498    /// surface as SSE frames post-HTTP-200). Set to a value ≥ observed
499    /// request-parse / admission p99 latency to opt in — request-validation
500    /// errors within the window surface as HTTP 4xx; anything past the window
501    /// stays as an SSE error frame. Setting to `0` also disables the peek.
502    ///
503    /// Read once when the HTTP service is built. A policy supplied through
504    /// `HttpServiceConfigBuilder::streaming_backend_error_check` replaces it.
505    pub const DYN_HTTP_PRE_COMMIT_ERROR_PEEK_MS: &str = "DYN_HTTP_PRE_COMMIT_ERROR_PEEK_MS";
506
507    /// Enable the LoRA allocation controller (set to "true" to enable)
508    pub const DYN_LORA_ALLOCATION_ENABLED: &str = "DYN_LORA_ALLOCATION_ENABLED";
509
510    /// LoRA allocation algorithm ("hrw", "random", or "mcf")
511    pub const DYN_LORA_ALLOCATION_ALGORITHM: &str = "DYN_LORA_ALLOCATION_ALGORITHM";
512
513    /// JSON configuration for the MCF (min-cost flow) placement solver.
514    /// Example: '{"candidate_m":16,"gamma_load":2000,"beta_keep":500}'
515    /// Omitted fields use defaults. Only relevant when algorithm is "mcf".
516    pub const DYN_LORA_MCF_CONFIG: &str = "DYN_LORA_MCF_CONFIG";
517
518    /// LoRA allocation controller recompute interval in seconds
519    pub const DYN_LORA_ALLOCATION_TIMESTEP_SECS: &str = "DYN_LORA_ALLOCATION_TIMESTEP_SECS";
520
521    /// Ticks to wait before scaling down a LoRA's replicas
522    pub const DYN_LORA_ALLOCATION_SCALE_DOWN_COOLDOWN_TICKS: &str =
523        "DYN_LORA_ALLOCATION_SCALE_DOWN_COOLDOWN_TICKS";
524
525    /// Multiplier for the load estimator's rate window relative to the controller timestep.
526    pub const DYN_LORA_ALLOCATION_RATE_WINDOW_MULTIPLIER: &str =
527        "DYN_LORA_ALLOCATION_RATE_WINDOW_MULTIPLIER";
528
529    /// Number of counter buckets per second in the BucketedRateCounter.
530    pub const DYN_LORA_ALLOCATION_BUCKETS_PER_SECOND: &str =
531        "DYN_LORA_ALLOCATION_BUCKETS_PER_SECOND";
532
533    /// Load predictor type: "none" (raw counts) or "ema" (exponential moving average).
534    pub const DYN_LORA_ALLOCATION_PREDICTOR_TYPE: &str = "DYN_LORA_ALLOCATION_PREDICTOR_TYPE";
535
536    /// EMA smoothing factor (alpha) for the EMA predictor. Range [0.0, 1.0].
537    pub const DYN_LORA_ALLOCATION_EMA_ALPHA: &str = "DYN_LORA_ALLOCATION_EMA_ALPHA";
538
539    /// Bounded startup wait, in seconds, for the KV state-agent host
540    /// advertisement before an opted-in worker gives up on KV routing.
541    /// `0` fails after a single discovery snapshot; invalid values use the
542    /// 30-second default.
543    pub const DYN_KV_STATE_AGENT_HOST_DISCOVERY_TIMEOUT_SECS: &str =
544        "DYN_KV_STATE_AGENT_HOST_DISCOVERY_TIMEOUT_SECS";
545
546    /// Progress-thread delay, in microseconds, of the frontend media loader's NIXL
547    /// agent (default 1000, range 0 to 1000000). NIXL rounds it up to whole
548    /// milliseconds; `0` makes the thread busy-poll one core. Over TCP, a read can
549    /// wait up to the full delay, so larger values add longer stalls. Values that do
550    /// not parse or are above 1000000 use the default.
551    pub const DYN_MM_NIXL_PROGRESS_DELAY_US: &str = "DYN_MM_NIXL_PROGRESS_DELAY_US";
552
553    /// Metrics configuration
554    pub mod metrics {
555        /// Custom metrics prefix (overrides default "dynamo_frontend")
556        pub const DYN_METRICS_PREFIX: &str = "DYN_METRICS_PREFIX";
557
558        /// Histogram bucket configuration prefixes. Each is suffixed with `_MIN`,
559        /// `_MAX`, or `_COUNT` to form the variable that tunes one frontend
560        /// histogram's log-spaced buckets, for example `DYN_METRICS_ITL_MAX`.
561        /// Values are read once, when the frontend builds its metrics.
562        pub const DYN_METRICS_REQUEST_DURATION: &str = "DYN_METRICS_REQUEST_DURATION";
563        /// See [`DYN_METRICS_REQUEST_DURATION`].
564        pub const DYN_METRICS_INPUT_SEQUENCE: &str = "DYN_METRICS_INPUT_SEQUENCE";
565        /// See [`DYN_METRICS_REQUEST_DURATION`].
566        pub const DYN_METRICS_OUTPUT_SEQUENCE: &str = "DYN_METRICS_OUTPUT_SEQUENCE";
567        /// See [`DYN_METRICS_REQUEST_DURATION`].
568        pub const DYN_METRICS_TTFT: &str = "DYN_METRICS_TTFT";
569        /// See [`DYN_METRICS_REQUEST_DURATION`].
570        pub const DYN_METRICS_ITL: &str = "DYN_METRICS_ITL";
571        /// See [`DYN_METRICS_REQUEST_DURATION`].
572        pub const DYN_METRICS_EMBEDDING_LATENCY: &str = "DYN_METRICS_EMBEDDING_LATENCY";
573
574        /// Deprecated prefix for the histogram bucket variables above.
575        ///
576        /// This was once prepended to prefixes that already started with
577        /// `DYN_METRICS_`, so the variables were read under doubled names such as
578        /// `DYN_HISTOGRAM_DYN_METRICS_ITL_MAX`. The doubled form is still accepted
579        /// as a fallback, with a warning, and will be removed in a future release.
580        pub const DEPRECATED_HISTOGRAM_PREFIX: &str = "DYN_HISTOGRAM_";
581
582        /// Former name of [`DEPRECATED_HISTOGRAM_PREFIX`], kept so that code outside
583        /// this workspace importing it keeps compiling. Remove together with the
584        /// doubled-name fallback.
585        #[deprecated(note = "use DEPRECATED_HISTOGRAM_PREFIX")]
586        pub const HISTOGRAM_PREFIX: &str = DEPRECATED_HISTOGRAM_PREFIX;
587    }
588
589    /// Forward-pass-metrics trace configuration.
590    pub mod fpm_trace {
591        /// Master switch. Truthy values persist locally produced FPM events.
592        pub const DYN_FPM_TRACE: &str = "DYN_FPM_TRACE";
593
594        /// Local gzip JSONL segment prefix. A sanitized producer id is appended
595        /// before the segment index so multiple producers do not share files.
596        pub const DYN_FPM_OUTPUT_PATH: &str = "DYN_FPM_OUTPUT_PATH";
597
598        /// Capture mode: `sampled` (latest event per DP rank each interval) or
599        /// `full` (every event reaching the producer-side trace tap).
600        pub const DYN_FPM_MODE: &str = "DYN_FPM_MODE";
601
602        /// Sampling interval in milliseconds when `DYN_FPM_MODE=sampled`.
603        pub const DYN_FPM_SAMPLE_INTERVAL_MS: &str = "DYN_FPM_SAMPLE_INTERVAL_MS";
604
605        /// Rotating gzip JSONL threshold in uncompressed bytes.
606        pub const DYN_FPM_JSONL_GZ_ROLL_BYTES: &str = "DYN_FPM_JSONL_GZ_ROLL_BYTES";
607
608        /// Maximum number of gzip JSONL segments retained per producer,
609        /// including the active segment.
610        pub const DYN_FPM_MAX_SEGMENTS: &str = "DYN_FPM_MAX_SEGMENTS";
611    }
612
613    /// Deprecated audit payload logging aliases. Prefer `llm::request_trace`.
614    pub mod audit {
615        /// Deprecated alias for `DYN_REQUEST_TRACE_SINKS`. Legacy values
616        /// `jsonl` and `jsonl_gz` map to the request trace `file` sink.
617        pub const DYN_AUDIT_SINKS: &str = "DYN_AUDIT_SINKS";
618
619        /// Deprecated migration shim for `DYN_REQUEST_TRACE_RECORDS=request_payload`.
620        pub const DYN_AUDIT_FORCE_LOGGING: &str = "DYN_AUDIT_FORCE_LOGGING";
621
622        /// Deprecated alias for `DYN_REQUEST_TRACE_CAPACITY`.
623        pub const DYN_AUDIT_CAPACITY: &str = "DYN_AUDIT_CAPACITY";
624
625        /// Deprecated alias for `DYN_REQUEST_TRACE_NATS_SUBJECT`.
626        pub const DYN_AUDIT_NATS_SUBJECT: &str = "DYN_AUDIT_NATS_SUBJECT";
627
628        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_PATH`.
629        pub const DYN_AUDIT_OUTPUT_PATH: &str = "DYN_AUDIT_OUTPUT_PATH";
630
631        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_BUFFER_BYTES`.
632        pub const DYN_AUDIT_JSONL_BUFFER_BYTES: &str = "DYN_AUDIT_JSONL_BUFFER_BYTES";
633
634        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_FLUSH_INTERVAL_MS`.
635        pub const DYN_AUDIT_JSONL_FLUSH_INTERVAL_MS: &str = "DYN_AUDIT_JSONL_FLUSH_INTERVAL_MS";
636
637        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_ROLL_BYTES`.
638        pub const DYN_AUDIT_JSONL_GZ_ROLL_BYTES: &str = "DYN_AUDIT_JSONL_GZ_ROLL_BYTES";
639
640        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_ROLL_LINES`.
641        pub const DYN_AUDIT_JSONL_GZ_ROLL_LINES: &str = "DYN_AUDIT_JSONL_GZ_ROLL_LINES";
642
643        /// Deprecated alias for `DYN_REQUEST_TRACE_OTEL_MAX_PAYLOAD_BYTES`.
644        pub const DYN_AUDIT_OTEL_MAX_PAYLOAD_BYTES: &str = "DYN_AUDIT_OTEL_MAX_PAYLOAD_BYTES";
645    }
646
647    /// Request trace and request payload logging configuration.
648    pub mod request_trace {
649        /// Master switch. Truthy enables request trace emission.
650        pub const DYN_REQUEST_TRACE: &str = "DYN_REQUEST_TRACE";
651
652        /// Request trace sink selection. Comma-separated values: `file`,
653        /// `stderr`, `nats`, `otel`, `s3`.
654        ///
655        /// Legacy values map as follows: `jsonl` => `file` with `jsonl` format,
656        /// `jsonl_gz` => `file` with `jsonl_gz` format, `stderr` => `stderr`,
657        /// `nats` => `nats`, and `otel` => `otel`.
658        pub const DYN_REQUEST_TRACE_SINKS: &str = "DYN_REQUEST_TRACE_SINKS";
659
660        /// Local output path for request trace file records.
661        ///
662        /// With `DYN_REQUEST_TRACE_FILE_FORMAT=jsonl`, this is the literal JSONL
663        /// path. With `jsonl_gz`, this is the segment prefix used to derive
664        /// `<prefix>.<index>.jsonl.gz` files.
665        pub const DYN_REQUEST_TRACE_FILE_PATH: &str = "DYN_REQUEST_TRACE_FILE_PATH";
666
667        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_PATH`.
668        pub const DYN_REQUEST_TRACE_OUTPUT_PATH: &str = "DYN_REQUEST_TRACE_OUTPUT_PATH";
669
670        /// Request trace file record format. Supported values: `jsonl`, `jsonl_gz`.
671        pub const DYN_REQUEST_TRACE_FILE_FORMAT: &str = "DYN_REQUEST_TRACE_FILE_FORMAT";
672
673        /// In-process trace bus capacity.
674        pub const DYN_REQUEST_TRACE_CAPACITY: &str = "DYN_REQUEST_TRACE_CAPACITY";
675
676        /// Request trace record selection. Comma-separated values: `request_end`,
677        /// `request_payload`, `tool`.
678        pub const DYN_REQUEST_TRACE_RECORDS: &str = "DYN_REQUEST_TRACE_RECORDS";
679
680        /// NATS subject the request trace sink publishes to.
681        pub const DYN_REQUEST_TRACE_NATS_SUBJECT: &str = "DYN_REQUEST_TRACE_NATS_SUBJECT";
682
683        /// Maximum serialized OTEL payload bytes. Oversized request payload
684        /// records emit an incomplete marker payload instead of the full request/response.
685        pub const DYN_REQUEST_TRACE_OTEL_MAX_PAYLOAD_BYTES: &str =
686            "DYN_REQUEST_TRACE_OTEL_MAX_PAYLOAD_BYTES";
687
688        /// Request trace file sink buffer size in bytes.
689        pub const DYN_REQUEST_TRACE_FILE_BUFFER_BYTES: &str = "DYN_REQUEST_TRACE_FILE_BUFFER_BYTES";
690
691        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_BUFFER_BYTES`.
692        pub const DYN_REQUEST_TRACE_JSONL_BUFFER_BYTES: &str =
693            "DYN_REQUEST_TRACE_JSONL_BUFFER_BYTES";
694
695        /// Request trace file sink periodic flush interval in milliseconds.
696        pub const DYN_REQUEST_TRACE_FILE_FLUSH_INTERVAL_MS: &str =
697            "DYN_REQUEST_TRACE_FILE_FLUSH_INTERVAL_MS";
698
699        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_FLUSH_INTERVAL_MS`.
700        pub const DYN_REQUEST_TRACE_JSONL_FLUSH_INTERVAL_MS: &str =
701            "DYN_REQUEST_TRACE_JSONL_FLUSH_INTERVAL_MS";
702
703        /// Gzip file sink roll threshold in uncompressed bytes.
704        pub const DYN_REQUEST_TRACE_FILE_ROLL_BYTES: &str = "DYN_REQUEST_TRACE_FILE_ROLL_BYTES";
705
706        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_ROLL_BYTES`.
707        pub const DYN_REQUEST_TRACE_JSONL_GZ_ROLL_BYTES: &str =
708            "DYN_REQUEST_TRACE_JSONL_GZ_ROLL_BYTES";
709
710        /// Gzip file sink roll threshold in record lines.
711        pub const DYN_REQUEST_TRACE_FILE_ROLL_LINES: &str = "DYN_REQUEST_TRACE_FILE_ROLL_LINES";
712
713        /// Deprecated alias for `DYN_REQUEST_TRACE_FILE_ROLL_LINES`.
714        pub const DYN_REQUEST_TRACE_JSONL_GZ_ROLL_LINES: &str =
715            "DYN_REQUEST_TRACE_JSONL_GZ_ROLL_LINES";
716
717        /// Local ZMQ PULL endpoint Dynamo binds for harness tool events.
718        pub const DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_ENDPOINT: &str =
719            "DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_ENDPOINT";
720
721        /// First-frame ZMQ topic filter override for harness tool events.
722        pub const DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_TOPIC: &str =
723            "DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_TOPIC";
724
725        /// Comma/whitespace-separated allowlist of HTTP request header names to
726        /// record in request payload records. Unset/empty captures none. Values
727        /// are recorded unredacted; avoid credential-bearing headers.
728        pub const DYN_REQUEST_TRACE_HTTP_HEADER_CAPTURE_LIST: &str =
729            "DYN_REQUEST_TRACE_HTTP_HEADER_CAPTURE_LIST";
730
731        /// S3 bucket for the S3 request-trace sink. Required when
732        /// `DYN_REQUEST_TRACE_SINKS` includes `s3`.
733        pub const DYN_REQUEST_TRACE_S3_BUCKET: &str = "DYN_REQUEST_TRACE_S3_BUCKET";
734
735        /// AWS region for the S3 request-trace sink. When unset the AWS SDK
736        /// default region resolution is used (env, profile, IMDS).
737        pub const DYN_REQUEST_TRACE_S3_REGION: &str = "DYN_REQUEST_TRACE_S3_REGION";
738
739        /// Optional object key prefix for the S3 request-trace sink. When unset
740        /// records land at the bucket root.
741        pub const DYN_REQUEST_TRACE_S3_PREFIX: &str = "DYN_REQUEST_TRACE_S3_PREFIX";
742
743        /// S3 batch roll threshold in uncompressed bytes. When the pending
744        /// batch reaches this size, it is finalized and uploaded. Default
745        /// `67108864` (64 MiB).
746        pub const DYN_REQUEST_TRACE_S3_ROLL_UNCOMPRESSED_BYTES: &str =
747            "DYN_REQUEST_TRACE_S3_ROLL_UNCOMPRESSED_BYTES";
748
749        /// S3 periodic flush interval in milliseconds. Any partial batch is
750        /// finalized and uploaded when this elapses, so low-volume traces
751        /// still land in S3. Default `10000` (10 s).
752        pub const DYN_REQUEST_TRACE_S3_FLUSH_INTERVAL_MS: &str =
753            "DYN_REQUEST_TRACE_S3_FLUSH_INTERVAL_MS";
754    }
755}
756
757/// Model loading and caching environment variables
758pub mod model {
759    /// Model Express configuration
760    pub mod model_express {
761        /// Model Express server endpoint URL
762        pub const MODEL_EXPRESS_URL: &str = "MODEL_EXPRESS_URL";
763
764        /// Model Express cache path
765        pub const MODEL_EXPRESS_CACHE_PATH: &str = "MODEL_EXPRESS_CACHE_PATH";
766
767        /// Disable shared-storage mode for the Model Express client. When set,
768        /// the client streams model files from the server over gRPC instead of
769        /// relying on a shared filesystem path. Required when the Model Express
770        /// server and worker pods do not share a filesystem (e.g. RWO PVCs,
771        /// cross-namespace deployments). Set to "1" or "true" to enable.
772        pub const MODEL_EXPRESS_NO_SHARED_STORAGE: &str = "MODEL_EXPRESS_NO_SHARED_STORAGE";
773    }
774
775    /// Hugging Face configuration
776    pub mod huggingface {
777        /// Hugging Face authentication token
778        pub const HF_TOKEN: &str = "HF_TOKEN";
779
780        /// Deprecated alias for the Hugging Face authentication token
781        pub const HUGGING_FACE_HUB_TOKEN: &str = "HUGGING_FACE_HUB_TOKEN";
782
783        /// Path to the stored Hugging Face authentication token
784        pub const HF_TOKEN_PATH: &str = "HF_TOKEN_PATH";
785
786        /// Hugging Face Hub cache directory
787        pub const HF_HUB_CACHE: &str = "HF_HUB_CACHE";
788
789        /// Hugging Face home directory
790        pub const HF_HOME: &str = "HF_HOME";
791
792        /// Override the Hugging Face Hub API endpoint
793        pub const HF_ENDPOINT: &str = "HF_ENDPOINT";
794
795        /// Offline mode - skip API calls when model is cached
796        /// Set to "1", "true", "on", or "yes" to enable
797        pub const HF_HUB_OFFLINE: &str = "HF_HUB_OFFLINE";
798    }
799}
800
801/// KV Router configuration environment variables
802pub mod router {
803    /// Scale applied to adjusted prompt-side prefill load after overlap/cache-hit credits.
804    pub const DYN_ROUTER_PREFILL_LOAD_SCALE: &str = "DYN_ROUTER_PREFILL_LOAD_SCALE";
805
806    /// Queue threshold fraction for prefill token capacity.
807    /// When set, requests are queued if all workers exceed this fraction of max_num_batched_tokens.
808    pub const DYN_ROUTER_QUEUE_THRESHOLD: &str = "DYN_ROUTER_QUEUE_THRESHOLD";
809
810    /// Scheduling policy for the router queue ("fcfs" or "wspt").
811    pub const DYN_ROUTER_QUEUE_POLICY: &str = "DYN_ROUTER_QUEUE_POLICY";
812    pub const DYN_ROUTER_POLICY_CONFIG: &str = "DYN_ROUTER_POLICY_CONFIG";
813
814    /// Stale active-request cleanup guard in seconds; this is not a request timeout.
815    pub const DYN_ROUTER_ACTIVE_REQUEST_EXPIRY_SECS: &str = "DYN_ROUTER_ACTIVE_REQUEST_EXPIRY_SECS";
816}
817
818/// Request plane transport environment variables
819pub mod request_plane {
820    /// Request-plane transport selection: `"tcp"` (default) or `"nats"`. Read by the
821    /// runtime in `distributed.rs` and by the Python launch layer.
822    pub const DYN_REQUEST_PLANE: &str = "DYN_REQUEST_PLANE";
823
824    /// Preferred payload codec advertised by every request-plane endpoint in this process.
825    /// The process-wide value is cached on first use and defaults to "msgpack". Outbound requests
826    /// use the destination endpoint's advertised codec, or "json" for a legacy destination.
827    pub const DYN_REQUEST_PLANE_CODEC: &str = "DYN_REQUEST_PLANE_CODEC";
828
829    /// Serialize `PreprocessedRequest.token_ids` as one packed little-endian int32 blob on
830    /// binary codecs instead of a sequence. Opt-in; every msgpack worker must run a release
831    /// whose readers accept the packed form.
832    pub const DYN_TOKEN_IDS_AS_BYTES: &str = "DYN_TOKEN_IDS_AS_BYTES";
833
834    /// Maximum TCP request-plane message size, in bytes.
835    pub const DYN_TCP_MAX_MESSAGE_SIZE: &str = "DYN_TCP_MAX_MESSAGE_SIZE";
836
837    /// Buffer size above which the TCP decoder shrinks an empty buffer, in bytes.
838    pub const DYN_TCP_SHRINK_MESSAGE_SIZE: &str = "DYN_TCP_SHRINK_MESSAGE_SIZE";
839
840    /// Host or interface for the TCP request-plane server.
841    /// The server resolves the value once at startup. A loopback fallback
842    /// persists until restart, and an enumeration error fails server startup.
843    pub const DYN_TCP_RPC_HOST: &str = "DYN_TCP_RPC_HOST";
844
845    /// Port for the TCP request-plane server.
846    /// If unset, the OS assigns a free ephemeral port.
847    pub const DYN_TCP_RPC_PORT: &str = "DYN_TCP_RPC_PORT";
848}
849
850/// Response plane transport configuration.
851pub mod response_plane {
852    /// Response transport used by every runtime in this process: "tcp" or "quic".
853    /// Defaults to "tcp".
854    pub const DYN_RESPONSE_PLANE: &str = "DYN_RESPONSE_PLANE";
855}
856
857/// TCP request callback listener environment variables. Names are retained for compatibility.
858pub mod tcp_response_stream {
859    /// Port shared by the TCP request callback and QUIC response listeners.
860    /// If unset or 0, the OS assigns a free ephemeral port.
861    pub const DYN_TCP_RESPONSE_STREAM_PORT: &str = "DYN_TCP_RESPONSE_STREAM_PORT";
862
863    /// Listen backlog of the TCP response stream (CallHome) listener. Defaults to
864    /// 4096, capped by the kernel at `net.core.somaxconn`. Unset, zero, negative, or
865    /// unparseable values fall back to the default.
866    pub const DYN_TCP_LISTEN_BACKLOG: &str = "DYN_TCP_LISTEN_BACKLOG";
867
868    /// Host or interface for the TCP response stream server and QUIC response listener.
869    ///
870    /// Accepts IPv4 and IPv6 literals, bracketed IPv6 literals, IPv4 or IPv6
871    /// wildcards, and interface names. Interface aliases such as `eth0:1` are
872    /// also accepted. If unset, the server selects the first usable
873    /// non-loopback IPv4 address, then IPv6, then IPv4 loopback, then IPv6
874    /// loopback. A wildcard uses a reachable address in its requested family.
875    /// If only the other family has a usable non-loopback address, the server
876    /// switches the bind wildcard to that family. The server resolves the value
877    /// once at startup. A loopback fallback persists until restart, and an
878    /// enumeration error fails server startup.
879    pub const DYN_TCP_RESPONSE_STREAM_HOST: &str = "DYN_TCP_RESPONSE_STREAM_HOST";
880
881    /// TCP request-plane TLS configuration
882    pub mod tls {
883        /// Path to the PEM certificate used by the TCP server.
884        /// When set together with DYN_TCP_TLS_KEY_PATH, TLS is enabled on the
885        /// TCP server. To enable TLS on the client side, also set
886        /// DYN_TCP_TLS_CA_CERT_PATH (or DYN_TCP_TLS_INSECURE for dev).
887        pub const DYN_TCP_TLS_CERT_PATH: &str = "DYN_TCP_TLS_CERT_PATH";
888
889        /// Path to the PEM private key for the TCP server certificate.
890        pub const DYN_TCP_TLS_KEY_PATH: &str = "DYN_TCP_TLS_KEY_PATH";
891
892        /// Path to the PEM CA certificate used by TCP clients to verify the server.
893        /// Required on the client side when the server uses a self-signed or internal CA.
894        pub const DYN_TCP_TLS_CA_CERT_PATH: &str = "DYN_TCP_TLS_CA_CERT_PATH";
895
896        /// Disable TLS certificate verification on the TCP client. Set to "true" to skip.
897        /// WARNING: Only for local development. Never use in production.
898        pub const DYN_TCP_TLS_INSECURE: &str = "DYN_TCP_TLS_INSECURE";
899
900        /// Override the TLS server name (SNI) used by TCP clients when verifying the
901        /// server certificate. When unset, the hostname extracted from the connection
902        /// address is used. Useful when connecting by IP to a server whose certificate
903        /// uses a DNS SAN.
904        pub const DYN_TCP_TLS_SERVER_NAME: &str = "DYN_TCP_TLS_SERVER_NAME";
905
906        /// Path to the PEM client certificate presented by TCP clients to the
907        /// server for mutual TLS (mTLS). Must be set together with
908        /// `DYN_TCP_TLS_CLIENT_KEY_PATH`.
909        pub const DYN_TCP_TLS_CLIENT_CERT_PATH: &str = "DYN_TCP_TLS_CLIENT_CERT_PATH";
910
911        /// Path to the PEM private key for the TCP client certificate (mTLS).
912        pub const DYN_TCP_TLS_CLIENT_KEY_PATH: &str = "DYN_TCP_TLS_CLIENT_KEY_PATH";
913
914        /// Path to the PEM CA certificate the TCP server uses to verify client
915        /// certificates. When set, the server requires clients to present a
916        /// certificate signed by this CA (mTLS is enforced).
917        pub const DYN_TCP_TLS_CLIENT_CA_CERT_PATH: &str = "DYN_TCP_TLS_CLIENT_CA_CERT_PATH";
918
919        /// TLS handshake timeout in seconds (default: 3).
920        pub const DYN_TCP_TLS_HANDSHAKE_TIMEOUT_SECS: &str = "DYN_TCP_TLS_HANDSHAKE_TIMEOUT_SECS";
921    }
922}
923
924/// Fixed-lane QUIC response transport.
925pub mod quic_response {
926    /// Bulk-lane batch interval in microseconds. Defaults to 5,000. Registration,
927    /// prologue, first-data, and priority-end frames always flush immediately.
928    pub const DYN_QUIC_RESPONSE_BATCH_INTERVAL_US: &str = "DYN_QUIC_RESPONSE_BATCH_INTERVAL_US";
929    /// Per-response frontend mailbox capacity. Defaults to 16,384 frames.
930    pub const DYN_QUIC_RESPONSE_BUFFER_CAPACITY: &str = "DYN_QUIC_RESPONSE_BUFFER_CAPACITY";
931}
932
933/// Event Plane transport environment variables
934pub mod event_plane {
935    /// Event transport selection: "zmq" or "nats".
936    ///
937    /// When unset the default depends on the discovery backend:
938    /// - `file` / `mem` backends: defaults to `zmq` (no external services required).
939    /// - `etcd` / `kubernetes` backends: defaults to `nats`.
940    ///
941    /// Set this explicitly to override the context-aware default.
942    pub const DYN_EVENT_PLANE: &str = "DYN_EVENT_PLANE";
943
944    /// Event plane codec selection: "json" or "msgpack".
945    pub const DYN_EVENT_PLANE_CODEC: &str = "DYN_EVENT_PLANE_CODEC";
946
947    /// IP address or exact interface advertised by direct ZMQ event publishers.
948    /// Unspecified addresses are rejected.
949    /// If unset, the runtime auto-detects a local IP address.
950    pub const DYN_EVENT_PLANE_HOST: &str = "DYN_EVENT_PLANE_HOST";
951
952    /// Bounded capacity of the direct ZMQ event-subscriber's merged event channel.
953    ///
954    /// Many peer publishers (e.g. every other frontend under replica-sync) feed
955    /// this single-consumer channel; an unbounded channel grows RSS without limit
956    /// when the consumer can't keep up. When the channel is full, new events are
957    /// dropped — the event plane is already best-effort/lossy (ZMQ RCVHWM), so a
958    /// dropped event costs routing-estimate freshness, not correctness.
959    /// Default: 100_000 (matches ZMQ_RCVHWM). Applies only to the direct ZMQ
960    /// subscriber path.
961    pub const DYN_ZMQ_EVENT_SUBSCRIBER_CHANNEL_CAPACITY: &str =
962        "DYN_ZMQ_EVENT_SUBSCRIBER_CHANNEL_CAPACITY";
963}
964
965/// ZMQ Broker environment variables
966pub mod zmq_broker {
967    /// Explicit ZMQ broker URL (takes precedence over discovery)
968    /// Format: `"xsub=<url1>[;<url2>...] , xpub=<url1>[;<url2>...]"`
969    /// Example: "xsub=tcp://broker:5555 , xpub=tcp://broker:5556"
970    pub const DYN_ZMQ_BROKER_URL: &str = "DYN_ZMQ_BROKER_URL";
971
972    /// Enable ZMQ broker discovery mode
973    pub const DYN_ZMQ_BROKER_ENABLED: &str = "DYN_ZMQ_BROKER_ENABLED";
974
975    /// XSUB bind address (broker binary only)
976    pub const ZMQ_BROKER_XSUB_BIND: &str = "ZMQ_BROKER_XSUB_BIND";
977
978    /// XPUB bind address (broker binary only)
979    pub const ZMQ_BROKER_XPUB_BIND: &str = "ZMQ_BROKER_XPUB_BIND";
980
981    /// Namespace for broker discovery registration
982    pub const ZMQ_BROKER_NAMESPACE: &str = "ZMQ_BROKER_NAMESPACE";
983}
984
985/// Discovery environment variables
986pub mod discovery {
987    /// Discovery backend: "kubernetes" or "etcd" (default)
988    pub const DYN_DISCOVERY_BACKEND: &str = "DYN_DISCOVERY_BACKEND";
989
990    /// Kube discovery mode: "pod" (default) or "container" (each container registers independently)
991    pub const DYN_KUBE_DISCOVERY_MODE: &str = "DYN_KUBE_DISCOVERY_MODE";
992}
993
994/// CUDA and GPU environment variables
995pub mod cuda {
996    /// Path to custom CUDA fatbin file.
997    ///
998    /// Note: build.rs files cannot import this constant at build time,
999    /// so they must define local constants with the same value.
1000    pub const DYN_FATBIN_PATH: &str = "DYN_FATBIN_PATH";
1001}
1002
1003/// Build-time environment variables
1004pub mod build {
1005    /// Cargo output directory for build artifacts
1006    ///
1007    /// Note: This constant cannot be used with the `env!()` macro,
1008    /// which requires a string literal at compile time.
1009    /// Build scripts (build.rs) also cannot import this constant.
1010    pub const OUT_DIR: &str = "OUT_DIR";
1011}
1012
1013/// Mocker (mock scheduler/KV manager) environment variables
1014pub mod mocker {
1015    /// Enable structured KV cache allocation/eviction trace logs (set to "1" or "true" to enable)
1016    pub const DYN_MOCKER_KV_CACHE_TRACE: &str = "DYN_MOCKER_KV_CACHE_TRACE";
1017
1018    /// Use the original direct() code path in the mocker request dispatch.
1019    ///
1020    /// This path is race-prone during startup; prefer leaving it unset unless you are
1021    /// explicitly trying to reproduce the original behavior.
1022    pub const DYN_MOCKER_SYNC_DIRECT: &str = "DYN_MOCKER_SYNC_DIRECT";
1023}
1024
1025/// Testing environment variables
1026pub mod testing {
1027    /// Enable queued-up request processing in tests
1028    pub const DYN_QUEUED_UP_PROCESSING: &str = "DYN_QUEUED_UP_PROCESSING";
1029
1030    /// Soak test run duration (e.g., "3s", "5m")
1031    pub const DYN_SOAK_RUN_DURATION: &str = "DYN_SOAK_RUN_DURATION";
1032
1033    /// Soak test batch load size
1034    pub const DYN_SOAK_BATCH_LOAD: &str = "DYN_SOAK_BATCH_LOAD";
1035}
1036
1037#[cfg(test)]
1038mod tests {
1039    use super::*;
1040
1041    #[test]
1042    fn test_no_duplicate_env_var_names() {
1043        use std::collections::HashSet;
1044
1045        let mut seen = HashSet::new();
1046        let vars = [
1047            // Logging
1048            logging::DYN_LOG,
1049            logging::DYN_LOGGING_CONFIG_PATH,
1050            logging::DYN_LOGGING_JSONL,
1051            logging::DYN_LOGGING_CONSOLE_FORMAT,
1052            logging::DYN_SDK_DISABLE_ANSI_LOGGING,
1053            logging::DYN_LOG_USE_LOCAL_TZ,
1054            logging::DYN_LOGGING_SPAN_EVENTS,
1055            logging::otlp::OTEL_EXPORT_ENABLED,
1056            logging::otlp::OTEL_EXPORTER_OTLP_PROTOCOL,
1057            logging::otlp::OTEL_EXPORTER_OTLP_TRACES_PROTOCOL,
1058            logging::otlp::OTEL_EXPORTER_OTLP_LOGS_PROTOCOL,
1059            logging::otlp::OTEL_EXPORTER_OTLP_ENDPOINT,
1060            logging::otlp::OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
1061            logging::otlp::OTEL_SERVICE_NAME,
1062            logging::otlp::OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
1063            logging::otlp::OTEL_TRACES_SAMPLE_RATIO,
1064            // Runtime
1065            runtime::DYN_RUNTIME_NUM_WORKER_THREADS,
1066            runtime::DYN_RUNTIME_MAX_BLOCKING_THREADS,
1067            runtime::DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS,
1068            runtime::DYN_RUNTIME_INHIBITED_DURATION_SECS,
1069            runtime::system::DYN_SYSTEM_ENABLED,
1070            runtime::system::DYN_SYSTEM_HOST,
1071            runtime::system::DYN_SYSTEM_PORT,
1072            runtime::system::DYN_SYSTEM_USE_ENDPOINT_HEALTH_STATUS,
1073            runtime::system::DYN_SYSTEM_STARTING_HEALTH_STATUS,
1074            runtime::system::DYN_SYSTEM_HEALTH_PATH,
1075            runtime::system::DYN_SYSTEM_LIVE_PATH,
1076            runtime::canary::DYN_CANARY_WAIT_TIME,
1077            // Worker
1078            worker::DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT,
1079            // NATS
1080            nats::NATS_SERVER,
1081            nats::DYN_NATS_REQUEST_TIMEOUT_SECS,
1082            nats::NATS_STARTUP_CONNECT_TIMEOUT_SECONDS,
1083            nats::auth::NATS_AUTH_USERNAME,
1084            nats::auth::NATS_AUTH_PASSWORD,
1085            nats::auth::NATS_AUTH_TOKEN,
1086            nats::auth::NATS_AUTH_NKEY,
1087            nats::auth::NATS_AUTH_CREDENTIALS_FILE,
1088            nats::stream::DYN_NATS_STREAM_MAX_AGE,
1089            nats::tls::NATS_TLS_CA_CERT_PATH,
1090            nats::tls::NATS_TLS_CLIENT_CERT_PATH,
1091            nats::tls::NATS_TLS_CLIENT_KEY_PATH,
1092            nats::tls::NATS_TLS_INSECURE,
1093            // ETCD
1094            etcd::ETCD_ENDPOINTS,
1095            etcd::ETCD_LEASE_TTL,
1096            etcd::ETCD_STARTUP_CONNECT_TIMEOUT_SECONDS,
1097            etcd::ETCD_KEEPALIVE_INTERVAL_SECONDS,
1098            etcd::ETCD_KEEPALIVE_TIMEOUT_SECONDS,
1099            etcd::auth::ETCD_AUTH_USERNAME,
1100            etcd::auth::ETCD_AUTH_PASSWORD,
1101            etcd::auth::ETCD_AUTH_CA,
1102            etcd::auth::ETCD_AUTH_CLIENT_CERT,
1103            etcd::auth::ETCD_AUTH_CLIENT_KEY,
1104            // KVBM
1105            kvbm::DYN_KVBM_METRICS,
1106            kvbm::DYN_KVBM_METRICS_PORT,
1107            kvbm::DYN_KVBM_ENABLE_RECORD,
1108            kvbm::DYN_KVBM_DISABLE_DISK_OFFLOAD_FILTER,
1109            kvbm::cpu_cache::DYN_KVBM_CPU_CACHE_GB,
1110            kvbm::cpu_cache::DYN_KVBM_CPU_CACHE_OVERRIDE_NUM_BLOCKS,
1111            kvbm::disk_cache::DYN_KVBM_DISK_CACHE_GB,
1112            kvbm::disk_cache::DYN_KVBM_DISK_CACHE_OVERRIDE_NUM_BLOCKS,
1113            kvbm::leader::DYN_KVBM_LEADER_WORKER_INIT_TIMEOUT_SECS,
1114            kvbm::leader::DYN_KVBM_LEADER_ZMQ_HOST,
1115            kvbm::leader::DYN_KVBM_LEADER_ZMQ_PUB_PORT,
1116            kvbm::leader::DYN_KVBM_LEADER_ZMQ_ACK_PORT,
1117            // LLM
1118            llm::DYN_HTTP_BODY_LIMIT_MB,
1119            llm::DYN_HTTP_LISTEN_BACKLOG,
1120            llm::DYN_HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_SECS,
1121            llm::DYN_HTTP_OVERLOAD_STATUS_CODE,
1122            llm::DYN_HTTP_BACKEND_STREAM_TIMEOUT_SECS,
1123            llm::DYN_HTTP_PRE_COMMIT_ERROR_PEEK_MS,
1124            llm::DYN_LORA_ENABLED,
1125            llm::DYN_LORA_PATH,
1126            llm::DYN_ENABLE_ANTHROPIC_API,
1127            llm::DYN_DISABLE_FRONTEND_NVEXT,
1128            llm::DYN_IGNORE_OPENAI_FE_UNSUPPORTED_FIELDS,
1129            llm::DYN_DISABLE_FRONTEND_ADMIN_API,
1130            llm::DYN_STRIP_ANTHROPIC_PREAMBLE,
1131            llm::DYN_ENABLE_FORCE_INCLUDE_USAGE,
1132            llm::DYN_ENABLE_STREAMING_TOOL_DISPATCH,
1133            llm::DYN_ENABLE_STREAMING_REASONING_DISPATCH,
1134            llm::DYN_REASONING_FIELD_NAME,
1135            llm::DYN_PARSER_VERSION,
1136            llm::DYN_ENABLE_EXPERIMENTAL_PARSERS_V2,
1137            llm::DYN_ENABLE_GUIDED_TOOL_STREAMING,
1138            llm::DYN_KV_STATE_AGENT_HOST_DISCOVERY_TIMEOUT_SECS,
1139            llm::DYN_MM_NIXL_PROGRESS_DELAY_US,
1140            llm::DYN_LORA_ALLOCATION_ENABLED,
1141            llm::DYN_LORA_ALLOCATION_ALGORITHM,
1142            llm::DYN_LORA_ALLOCATION_TIMESTEP_SECS,
1143            llm::DYN_LORA_ALLOCATION_SCALE_DOWN_COOLDOWN_TICKS,
1144            llm::DYN_LORA_ALLOCATION_RATE_WINDOW_MULTIPLIER,
1145            llm::DYN_LORA_ALLOCATION_BUCKETS_PER_SECOND,
1146            llm::DYN_LORA_ALLOCATION_PREDICTOR_TYPE,
1147            llm::DYN_LORA_ALLOCATION_EMA_ALPHA,
1148            llm::DYN_LORA_MCF_CONFIG,
1149            llm::DYN_TOKEN_ECHO_DELAY_MS,
1150            llm::DYN_HTTP_SSE_KEEP_ALIVE_INTERVAL_MS,
1151            llm::metrics::DYN_METRICS_PREFIX,
1152            llm::metrics::DYN_METRICS_REQUEST_DURATION,
1153            llm::metrics::DYN_METRICS_INPUT_SEQUENCE,
1154            llm::metrics::DYN_METRICS_OUTPUT_SEQUENCE,
1155            llm::metrics::DYN_METRICS_TTFT,
1156            llm::metrics::DYN_METRICS_ITL,
1157            llm::metrics::DYN_METRICS_EMBEDDING_LATENCY,
1158            llm::audit::DYN_AUDIT_SINKS,
1159            llm::audit::DYN_AUDIT_FORCE_LOGGING,
1160            llm::audit::DYN_AUDIT_CAPACITY,
1161            llm::audit::DYN_AUDIT_NATS_SUBJECT,
1162            llm::audit::DYN_AUDIT_OUTPUT_PATH,
1163            llm::audit::DYN_AUDIT_JSONL_BUFFER_BYTES,
1164            llm::audit::DYN_AUDIT_JSONL_FLUSH_INTERVAL_MS,
1165            llm::audit::DYN_AUDIT_JSONL_GZ_ROLL_BYTES,
1166            llm::audit::DYN_AUDIT_JSONL_GZ_ROLL_LINES,
1167            llm::request_trace::DYN_REQUEST_TRACE,
1168            llm::request_trace::DYN_REQUEST_TRACE_SINKS,
1169            llm::request_trace::DYN_REQUEST_TRACE_FILE_PATH,
1170            llm::request_trace::DYN_REQUEST_TRACE_OUTPUT_PATH,
1171            llm::request_trace::DYN_REQUEST_TRACE_FILE_FORMAT,
1172            llm::request_trace::DYN_REQUEST_TRACE_CAPACITY,
1173            llm::request_trace::DYN_REQUEST_TRACE_RECORDS,
1174            llm::request_trace::DYN_REQUEST_TRACE_NATS_SUBJECT,
1175            llm::request_trace::DYN_REQUEST_TRACE_OTEL_MAX_PAYLOAD_BYTES,
1176            llm::request_trace::DYN_REQUEST_TRACE_FILE_BUFFER_BYTES,
1177            llm::request_trace::DYN_REQUEST_TRACE_JSONL_BUFFER_BYTES,
1178            llm::request_trace::DYN_REQUEST_TRACE_FILE_FLUSH_INTERVAL_MS,
1179            llm::request_trace::DYN_REQUEST_TRACE_JSONL_FLUSH_INTERVAL_MS,
1180            llm::request_trace::DYN_REQUEST_TRACE_FILE_ROLL_BYTES,
1181            llm::request_trace::DYN_REQUEST_TRACE_JSONL_GZ_ROLL_BYTES,
1182            llm::request_trace::DYN_REQUEST_TRACE_FILE_ROLL_LINES,
1183            llm::request_trace::DYN_REQUEST_TRACE_JSONL_GZ_ROLL_LINES,
1184            llm::request_trace::DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_ENDPOINT,
1185            llm::request_trace::DYN_REQUEST_TRACE_TOOL_EVENTS_ZMQ_TOPIC,
1186            llm::request_trace::DYN_REQUEST_TRACE_HTTP_HEADER_CAPTURE_LIST,
1187            llm::audit::DYN_AUDIT_OTEL_MAX_PAYLOAD_BYTES,
1188            // Model
1189            model::model_express::MODEL_EXPRESS_URL,
1190            model::model_express::MODEL_EXPRESS_CACHE_PATH,
1191            model::model_express::MODEL_EXPRESS_NO_SHARED_STORAGE,
1192            model::huggingface::HF_TOKEN,
1193            model::huggingface::HUGGING_FACE_HUB_TOKEN,
1194            model::huggingface::HF_TOKEN_PATH,
1195            model::huggingface::HF_HUB_CACHE,
1196            model::huggingface::HF_HOME,
1197            model::huggingface::HF_ENDPOINT,
1198            model::huggingface::HF_HUB_OFFLINE,
1199            // Router
1200            router::DYN_ROUTER_PREFILL_LOAD_SCALE,
1201            router::DYN_ROUTER_QUEUE_THRESHOLD,
1202            router::DYN_ROUTER_QUEUE_POLICY,
1203            router::DYN_ROUTER_POLICY_CONFIG,
1204            router::DYN_ROUTER_ACTIVE_REQUEST_EXPIRY_SECS,
1205            request_plane::DYN_REQUEST_PLANE,
1206            request_plane::DYN_REQUEST_PLANE_CODEC,
1207            response_plane::DYN_RESPONSE_PLANE,
1208            request_plane::DYN_TCP_MAX_MESSAGE_SIZE,
1209            request_plane::DYN_TCP_SHRINK_MESSAGE_SIZE,
1210            request_plane::DYN_TCP_RPC_HOST,
1211            request_plane::DYN_TCP_RPC_PORT,
1212            // TCP Response Stream
1213            tcp_response_stream::DYN_TCP_RESPONSE_STREAM_PORT,
1214            tcp_response_stream::DYN_TCP_LISTEN_BACKLOG,
1215            tcp_response_stream::DYN_TCP_RESPONSE_STREAM_HOST,
1216            tcp_response_stream::tls::DYN_TCP_TLS_CERT_PATH,
1217            tcp_response_stream::tls::DYN_TCP_TLS_KEY_PATH,
1218            tcp_response_stream::tls::DYN_TCP_TLS_CA_CERT_PATH,
1219            tcp_response_stream::tls::DYN_TCP_TLS_INSECURE,
1220            tcp_response_stream::tls::DYN_TCP_TLS_SERVER_NAME,
1221            tcp_response_stream::tls::DYN_TCP_TLS_CLIENT_CERT_PATH,
1222            tcp_response_stream::tls::DYN_TCP_TLS_CLIENT_KEY_PATH,
1223            tcp_response_stream::tls::DYN_TCP_TLS_CLIENT_CA_CERT_PATH,
1224            tcp_response_stream::tls::DYN_TCP_TLS_HANDSHAKE_TIMEOUT_SECS,
1225            quic_response::DYN_QUIC_RESPONSE_BATCH_INTERVAL_US,
1226            quic_response::DYN_QUIC_RESPONSE_BUFFER_CAPACITY,
1227            // Event Plane
1228            event_plane::DYN_EVENT_PLANE,
1229            event_plane::DYN_EVENT_PLANE_CODEC,
1230            event_plane::DYN_EVENT_PLANE_HOST,
1231            event_plane::DYN_ZMQ_EVENT_SUBSCRIBER_CHANNEL_CAPACITY,
1232            // ZMQ Broker
1233            zmq_broker::DYN_ZMQ_BROKER_URL,
1234            zmq_broker::DYN_ZMQ_BROKER_ENABLED,
1235            zmq_broker::ZMQ_BROKER_XSUB_BIND,
1236            zmq_broker::ZMQ_BROKER_XPUB_BIND,
1237            zmq_broker::ZMQ_BROKER_NAMESPACE,
1238            // Discovery
1239            discovery::DYN_DISCOVERY_BACKEND,
1240            discovery::DYN_KUBE_DISCOVERY_MODE,
1241            // CUDA
1242            cuda::DYN_FATBIN_PATH,
1243            // Build
1244            build::OUT_DIR,
1245            // Mocker
1246            mocker::DYN_MOCKER_KV_CACHE_TRACE,
1247            mocker::DYN_MOCKER_SYNC_DIRECT,
1248            // Testing
1249            testing::DYN_QUEUED_UP_PROCESSING,
1250            testing::DYN_SOAK_RUN_DURATION,
1251            testing::DYN_SOAK_BATCH_LOAD,
1252        ];
1253
1254        for var in &vars {
1255            if !seen.insert(var) {
1256                panic!("Duplicate environment variable name: {}", var);
1257            }
1258        }
1259    }
1260
1261    #[test]
1262    fn test_naming_conventions() {
1263        // Dynamo-specific vars should start with DYN_
1264        assert!(runtime::DYN_RUNTIME_NUM_WORKER_THREADS.starts_with("DYN_"));
1265        assert!(runtime::DYN_RUNTIME_GRACEFUL_SHUTDOWN_TIMEOUT_SECS.starts_with("DYN_"));
1266        assert!(runtime::system::DYN_SYSTEM_ENABLED.starts_with("DYN_"));
1267        assert!(kvbm::DYN_KVBM_METRICS.starts_with("DYN_"));
1268        assert!(worker::DYN_WORKER_GRACEFUL_SHUTDOWN_TIMEOUT.starts_with("DYN_"));
1269
1270        // NATS vars should start with NATS_
1271        assert!(nats::NATS_SERVER.starts_with("NATS_"));
1272        assert!(nats::auth::NATS_AUTH_USERNAME.starts_with("NATS_AUTH_"));
1273
1274        // ETCD vars should start with ETCD_
1275        assert!(etcd::ETCD_ENDPOINTS.starts_with("ETCD_"));
1276        assert!(etcd::ETCD_LEASE_TTL.starts_with("ETCD_"));
1277        assert!(etcd::auth::ETCD_AUTH_USERNAME.starts_with("ETCD_AUTH_"));
1278
1279        // OpenTelemetry vars should start with OTEL_
1280        assert!(logging::otlp::OTEL_EXPORT_ENABLED.starts_with("OTEL_"));
1281        assert!(logging::otlp::OTEL_EXPORTER_OTLP_ENDPOINT.starts_with("OTEL_"));
1282        assert!(logging::otlp::OTEL_SERVICE_NAME.starts_with("OTEL_"));
1283    }
1284}