aion_server/config/
defaults.rs1use std::net::SocketAddr;
10
11pub const DEFAULT_HTTP_ADDRESS: SocketAddr =
13 SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST), 8080);
14pub(super) const DEFAULT_GRPC_ADDRESS: SocketAddr =
15 SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::LOCALHOST), 50051);
16pub const MAX_TRANSCRIPT_WINDOW_LIMIT: u32 = 2_000;
18
19pub const DEFAULT_FAILOVER_POLL_INTERVAL_MS: u64 = 500;
22
23pub const DEFAULT_FAILOVER_CONFIRMATIONS: u32 = 3;
26
27pub const DEFAULT_MAX_IN_FLIGHT_ACTIVITIES: u32 = 1024;
34
35pub const DEFAULT_EVENT_BROADCAST_CAPACITY: usize = 256;
39
40pub const DEFAULT_CLUSTER_BROADCAST_CAPACITY: usize = 64;
43
44pub(crate) const EVENT_BROADCAST_CAPACITY_REQUIRED: &str = "websocket.event_broadcast_capacity must be a positive integer when set (the server always mounts /events/stream, so a zero-capacity channel would stream nothing); omit websocket.event_broadcast_capacity (or AION_WEBSOCKET_EVENT_BROADCAST_CAPACITY) to use the default, or set it to a positive integer";
48
49pub(crate) const CLUSTER_BROADCAST_CAPACITY_REQUIRED: &str = "websocket.cluster_broadcast_capacity must be a positive integer when set (the server always mounts the WS3 cluster subscription on /events/stream); omit websocket.cluster_broadcast_capacity (or AION_WEBSOCKET_CLUSTER_BROADCAST_CAPACITY) to use the default, or set it to a positive integer";
52
53pub const DEFAULT_DEPLOY_MAX_ARCHIVE_BYTES: u64 = 64 * 1024 * 1024;
57
58pub const DEFAULT_DEPLOY_MAX_INFLATED_BYTES: u64 = 256 * 1024 * 1024;
62
63pub(crate) const DEPLOY_MAX_ARCHIVE_BYTES_REQUIRED: &str = "deploy.max_archive_bytes must be a positive number of bytes when set (a zero archive ceiling would refuse every upload); omit deploy.max_archive_bytes (or AION_DEPLOY_MAX_ARCHIVE_BYTES) to use the conservative default, or set it to a positive number of bytes sized for the deployment's packages";
67
68pub(crate) const DEPLOY_MAX_INFLATED_BYTES_REQUIRED: &str = "deploy.max_inflated_bytes must be a positive number of bytes when set (a compressed upload under deploy.max_archive_bytes can inflate ~1000:1, so a zero inflate ceiling is incoherent); omit deploy.max_inflated_bytes (or AION_DEPLOY_MAX_INFLATED_BYTES) to use the conservative default, or set it to a positive number of bytes no smaller than deploy.max_archive_bytes";
73
74pub const DEFAULT_QUERY_TIMEOUT_MS: u64 = 10_000;
77
78pub(crate) const QUERY_TIMEOUT_REQUIRED: &str = "runtime.query_timeout_ms must be a positive integer when set (the server always mounts /workflows/query, so a zero deadline would fail every query immediately); omit runtime.query_timeout_ms (or AION_RUNTIME_QUERY_TIMEOUT_MS) to use the default, or set it to a positive number of milliseconds";
82
83pub const DEFAULT_OUTBOX_POLL_INTERVAL_MS: u64 = 20;
87
88pub const DEFAULT_OUTBOX_BATCH_SIZE: u32 = 16;
91
92pub const DEFAULT_OUTBOX_MAX_ATTEMPTS: u32 = 5;
95
96pub const DEFAULT_OUTBOX_BACKOFF_BASE_MS: u64 = 50;
99
100pub const DEFAULT_OUTBOX_BACKOFF_MULTIPLIER: u32 = 2;
103
104pub const DEFAULT_OUTBOX_BACKOFF_MAX_MS: u64 = 1_000;
107
108pub(crate) const OUTBOX_POLL_INTERVAL_REQUIRED: &str = "outbox.poll_interval_ms must be a positive number of milliseconds when set (a zero claim cadence is invalid); omit outbox.poll_interval_ms (or AION_OUTBOX_POLL_INTERVAL_MS) to use the default, or set it to a positive number of milliseconds sized for fan-out volume and latency";
111
112pub(crate) const OUTBOX_BATCH_SIZE_REQUIRED: &str = "outbox.batch_size must be a positive integer when set (a zero per-sweep claim ceiling claims nothing); omit outbox.batch_size (or AION_OUTBOX_BATCH_SIZE) to use the default, or set it to a positive integer";
115
116pub(crate) const OUTBOX_MAX_ATTEMPTS_REQUIRED: &str = "outbox.max_attempts must be a positive integer when set (a zero retry budget dead-letters before the first attempt); omit outbox.max_attempts (or AION_OUTBOX_MAX_ATTEMPTS) to use the default, or set it to a positive integer";
119
120pub(crate) const OUTBOX_BACKOFF_BASE_REQUIRED: &str = "outbox.backoff_base_ms must be a positive number of milliseconds when set (a zero first-retry backoff is invalid); omit outbox.backoff_base_ms (or AION_OUTBOX_BACKOFF_BASE_MS) to use the default, or set it to a positive number of milliseconds";
123
124pub(crate) const OUTBOX_BACKOFF_MULTIPLIER_REQUIRED: &str = "outbox.backoff_multiplier must be at least one when set so backoff never shrinks (a zero multiplier collapses the backoff curve); omit outbox.backoff_multiplier (or AION_OUTBOX_BACKOFF_MULTIPLIER) to use the default, or set it to a positive integer";
127
128pub(crate) const OUTBOX_BACKOFF_MAX_REQUIRED: &str = "outbox.backoff_max_ms must be at least outbox.backoff_base_ms when set (a ceiling below the base would cap the very first retry below its own backoff); omit outbox.backoff_max_ms (or AION_OUTBOX_BACKOFF_MAX_MS) to use the default, or set it to a positive number of milliseconds no smaller than outbox.backoff_base_ms";
132
133pub(crate) const OUTBOX_RECONCILE_INTERVAL_REQUIRED: &str = "outbox.reconcile_interval_ms is required and has no default when live outbox reconciliation is enabled: set both outbox.reconcile_interval_ms and outbox.reconcile_stale_after_ms (or AION_OUTBOX_RECONCILE_INTERVAL_MS / AION_OUTBOX_RECONCILE_STALE_AFTER_MS) to positive millisecond values, or omit both to leave reconciliation disabled";
135
136pub(crate) const OUTBOX_RECONCILE_STALE_AFTER_REQUIRED: &str = "outbox.reconcile_stale_after_ms is required and has no default when live outbox reconciliation is enabled: set both outbox.reconcile_interval_ms and outbox.reconcile_stale_after_ms (or AION_OUTBOX_RECONCILE_INTERVAL_MS / AION_OUTBOX_RECONCILE_STALE_AFTER_MS) to positive millisecond values, or omit both to leave reconciliation disabled";
138
139pub(crate) const AUTHORING_GLEAM_PATH_EMPTY: &str = "authoring.gleam_path must not be empty when set: it names the external gleam binary the authoring loop spawns; set authoring.gleam_path (or AION_AUTHORING_GLEAM_PATH) to the path of a runnable gleam binary, or remove it to leave the authoring surface dark";
141
142pub(crate) const AUTHORING_PROJECT_ROOT_REQUIRED: &str = "authoring.project_root is required and has no default when authoring.gleam_path is set: submitted Gleam source is written into and packaged from a built project, so the operator must provision and name the project root (a directory with gleam.toml, the aion_flow dependency, workflow.toml, and schemas/); set authoring.project_root (or AION_AUTHORING_PROJECT_ROOT)";
145
146pub const DEFAULT_OBSERVABILITY_MAX_EVENT_BYTES: usize = 256 * 1024;
151
152pub const DEFAULT_OBSERVABILITY_MAX_STREAM_EVENTS: u64 = 20_000;
156
157pub(crate) const OBSERVABILITY_MAX_EVENT_BYTES_REQUIRED: &str = "observability.max_event_bytes must be a positive number of bytes when set (a zero ceiling would truncate every retained transcript event to nothing); omit observability.max_event_bytes (or AION_OBSERVABILITY_MAX_EVENT_BYTES) to use the default, or set it to a positive number of bytes";
161
162pub(crate) const OBSERVABILITY_MAX_STREAM_EVENTS_REQUIRED: &str = "observability.max_stream_events must be a positive integer when set (a zero per-stream cap would retain no transcript at all); omit observability.max_stream_events (or AION_OBSERVABILITY_MAX_STREAM_EVENTS) to use the default, or set it to a positive integer";
166
167pub const STORE_NODE_CACHE_BUDGET_REQUIRED: &str = "store.node_cache_budget is required and has no default: it is the byte ceiling the haematite node caches may hold, and a cache bounded only by entry count is unbounded in bytes (a leaf reaches the ~96KB class under byte-aware chunking, so a 1,024-entry cache can hold gigabytes). Set store.node_cache_budget (or AION_STORE_NODE_CACHE_BUDGET) to either `{ bytes = <positive integer> }` or the string \"unlimited\" — `unlimited` is the pre-budget behaviour, stated out loud";
177
178pub const STORE_LOCK_ACQUISITION_REQUIRED: &str = "store.lock_acquisition_patience_ms and store.lock_acquisition_retry_cadence_ms are both required and have no defaults for the haematite backend: set both (or AION_STORE_LOCK_ACQUISITION_PATIENCE_MS and AION_STORE_LOCK_ACQUISITION_RETRY_CADENCE_MS) to positive millisecond values, with retry cadence no greater than patience";
180
181pub const OBSERVABILITY_MAX_BATCH_EVENTS_REQUIRED: &str = "observability.max_batch_events is required and has no default: it is the maximum number of transcript events the drain commits in one durable append, and one durable commit re-persists the whole containing storage leaf, so committing one event at a time is the write amplification measured on 2026-08-17 (a 136 KB status sweep left 73.7 MB of permanent store). Set observability.max_batch_events (or AION_OBSERVABILITY_MAX_BATCH_EVENTS) to a positive integer, together with observability.max_batch_hold_ms";
188
189pub const OBSERVABILITY_MAX_BATCH_HOLD_MS_REQUIRED: &str = "observability.max_batch_hold_ms is required and has no default: it is how long, in milliseconds, the transcript drain may hold a partial batch open waiting for it to fill, which bounds how much not-yet-durable transcript a crash can cost. Set observability.max_batch_hold_ms (or AION_OBSERVABILITY_MAX_BATCH_HOLD_MS) to a non-negative integer — 0 means never wait, and commit whatever is already queued — together with observability.max_batch_events";
195
196pub const DEFAULT_HAEMATITE_DATA_DIR: &str = "data";
201
202pub const DEFAULT_AUTHORING_WORKSPACE_DIR: &str = "authoring";
210
211pub(crate) const LEGACY_HAEMATITE_DATA_DIR: &str = "aion-data";
213
214pub(crate) const LEGACY_AUTHORING_WORKSPACE_DIR: &str = "aion-authoring";
216
217pub(crate) const CORS_ALLOWED_ORIGIN_INVALID: &str = "server.cors_allowed_origins entries must each be a valid HTTP origin (scheme://host[:port], e.g. http://localhost:5173) with no path or trailing slash";
220
221pub const DEFAULT_MCP_DISCOVER_TTL_MS: u64 = 60_000;
227
228pub const DEFAULT_MCP_TOOLS_LIST_TTL_MS: u64 = 300_000;
233
234pub const DEFAULT_MCP_TASK_POLL_INTERVAL_MS: u64 = 1_000;
242
243pub(crate) const MCP_TASK_POLL_INTERVAL_REQUIRED: &str = "mcp.task_poll_interval_ms must be a positive number of milliseconds when set (zero would ask every client to poll in a tight loop); omit mcp.task_poll_interval_ms to use the default, or set it to a positive value";