1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
//! Default values and operator-facing validation messages for the server config.
//!
//! This module holds the pure constants that back the config surface: the
//! compile-time default listener addresses, every `DEFAULT_*` tuning-knob
//! default, and the `*_REQUIRED` / `*_EMPTY` / `*_INVALID` operator-facing
//! validation messages. They are re-exported from the `config` module so every
//! existing `crate::config::X` path resolves identically.
use SocketAddr;
pub const DEFAULT_HTTP_ADDRESS: SocketAddr =
new;
pub const DEFAULT_GRPC_ADDRESS: SocketAddr =
new;
/// Default SS-5b failover poll interval (milliseconds) when `[store.cluster]`
/// does not set `failover_poll_interval_ms`.
pub const DEFAULT_FAILOVER_POLL_INTERVAL_MS: u64 = 500;
/// Default SS-5b debounce count when `[store.cluster]` does not set
/// `failover_confirmations`.
pub const DEFAULT_FAILOVER_CONFIRMATIONS: u32 = 3;
/// Generous platform default for `[namespaces] max_in_flight_activities`: the
/// cluster-wide concurrent in-flight-activity ceiling applied to a namespace
/// that sets no explicit override. A generous power-of-two (Control-Plane
/// Phase 2 §6.1 / Open Decision 4) so the default is HEADROOM, not a low hard
/// cap — a tenant only ever hits a ceiling it (or the operator) raised. Nothing
/// enforces it yet (P2-Q1 is config + record field only).
pub const DEFAULT_MAX_IN_FLIGHT_ACTIVITIES: u32 = 1024;
/// Default `event_broadcast_capacity` applied when omitted, so a minimal/empty
/// config boots without forcing the operator to size a tuning knob. Sized for
/// global event volume across namespaces; override for high-throughput fleets.
pub const DEFAULT_EVENT_BROADCAST_CAPACITY: usize = 256;
/// Default `cluster_broadcast_capacity` applied when omitted. Cluster topology
/// events are low-rate, so a small lag buffer is ample.
pub const DEFAULT_CLUSTER_BROADCAST_CAPACITY: usize = 64;
/// Operator-facing message for an explicitly zero `event_broadcast_capacity`
/// (omitting the key uses [`DEFAULT_EVENT_BROADCAST_CAPACITY`]; an explicit zero
/// is a genuine misconfiguration — a zero-capacity channel streams nothing).
pub 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";
/// Operator-facing message for an explicitly zero `cluster_broadcast_capacity`
/// (omitting the key uses [`DEFAULT_CLUSTER_BROADCAST_CAPACITY`]).
pub 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";
/// Default `deploy.max_archive_bytes` applied when omitted and deploy is
/// enabled. A conservative 64 MiB upload ceiling: large enough for real
/// workflow packages, small enough to bound a single upload. Overridable.
pub const DEFAULT_DEPLOY_MAX_ARCHIVE_BYTES: u64 = 64 * 1024 * 1024;
/// Default `deploy.max_inflated_bytes` applied when omitted and deploy is
/// enabled. A conservative 256 MiB decompressed-contents ceiling (4x the
/// archive ceiling) that still hard-caps DEFLATE-bomb inflation. Overridable.
pub const DEFAULT_DEPLOY_MAX_INFLATED_BYTES: u64 = 256 * 1024 * 1024;
/// Operator-facing message for an explicitly zero `deploy.max_archive_bytes`
/// (omitting the key uses [`DEFAULT_DEPLOY_MAX_ARCHIVE_BYTES`]; an explicit zero
/// is a genuine misconfiguration — a zero ceiling refuses every upload).
pub 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";
/// Operator-facing message for an explicitly zero `deploy.max_inflated_bytes`
/// (omitting the key uses [`DEFAULT_DEPLOY_MAX_INFLATED_BYTES`]; an explicit
/// zero is a genuine misconfiguration — a compressed upload under
/// `deploy.max_archive_bytes` can inflate ~1000:1).
pub 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";
/// Default `query_timeout_ms` applied when omitted, so a minimal/empty config
/// boots with a sane workflow-query reply deadline instead of failing startup.
pub const DEFAULT_QUERY_TIMEOUT_MS: u64 = 10_000;
/// Operator-facing message for an explicitly zero `query_timeout_ms` (omitting
/// the key uses [`DEFAULT_QUERY_TIMEOUT_MS`]; an explicit zero is a genuine
/// misconfiguration — a zero deadline would fail every query immediately).
pub 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";
/// Default `outbox.poll_interval_ms` applied when omitted and the dispatcher is
/// enabled. A tight 20ms claim cadence keeps fan-out latency low; raise it for
/// lower-rate, larger-batch sweeps.
pub const DEFAULT_OUTBOX_POLL_INTERVAL_MS: u64 = 20;
/// Default `outbox.batch_size` applied when omitted and the dispatcher is
/// enabled: rows claimed per sweep.
pub const DEFAULT_OUTBOX_BATCH_SIZE: u32 = 16;
/// Default `outbox.max_attempts` applied when omitted and the dispatcher is
/// enabled: dispatch attempts before a row is dead-lettered to `failed`.
pub const DEFAULT_OUTBOX_MAX_ATTEMPTS: u32 = 5;
/// Default `outbox.backoff_base_ms` applied when omitted and the dispatcher is
/// enabled: the first retry's backoff, in milliseconds.
pub const DEFAULT_OUTBOX_BACKOFF_BASE_MS: u64 = 50;
/// Default `outbox.backoff_multiplier` applied when omitted and the dispatcher
/// is enabled: geometric growth factor per prior attempt (must be >= 1).
pub const DEFAULT_OUTBOX_BACKOFF_MULTIPLIER: u32 = 2;
/// Default `outbox.backoff_max_ms` applied when omitted and the dispatcher is
/// enabled: the per-retry backoff ceiling, in milliseconds.
pub const DEFAULT_OUTBOX_BACKOFF_MAX_MS: u64 = 1_000;
/// Operator-facing message for an explicitly zero `outbox.poll_interval_ms`
/// (omitting the key uses [`DEFAULT_OUTBOX_POLL_INTERVAL_MS`]).
pub 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";
/// Operator-facing message for an explicitly zero `outbox.batch_size`
/// (omitting the key uses [`DEFAULT_OUTBOX_BATCH_SIZE`]).
pub 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";
/// Operator-facing message for an explicitly zero `outbox.max_attempts`
/// (omitting the key uses [`DEFAULT_OUTBOX_MAX_ATTEMPTS`]).
pub 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";
/// Operator-facing message for an explicitly zero `outbox.backoff_base_ms`
/// (omitting the key uses [`DEFAULT_OUTBOX_BACKOFF_BASE_MS`]).
pub 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";
/// Operator-facing message for an explicitly zero `outbox.backoff_multiplier`
/// (omitting the key uses [`DEFAULT_OUTBOX_BACKOFF_MULTIPLIER`]).
pub 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";
/// Operator-facing message for an explicitly undersized `outbox.backoff_max_ms`
/// (omitting the key uses [`DEFAULT_OUTBOX_BACKOFF_MAX_MS`]; an explicit value
/// must be at least `outbox.backoff_base_ms`).
pub 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";
/// Operator-facing message for an absent or zero `outbox.reconcile_interval_ms`.
pub 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";
/// Operator-facing message for an absent or zero `outbox.reconcile_stale_after_ms`.
pub 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";
/// Operator-facing message for an absent or empty `authoring.gleam_path` value.
pub 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";
/// Operator-facing message for an absent `authoring.project_root` when the
/// authoring surface is commissioned.
pub 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)";
/// Default `observability.max_event_bytes`: the ceiling on one persisted
/// transcript event's serialized size. 256 KiB comfortably holds real
/// tool-result payloads while bounding what one hostile/verbose harness line
/// can write to the durable `O` keyspace. Overridable per deployment.
pub const DEFAULT_OBSERVABILITY_MAX_EVENT_BYTES: usize = 256 * 1024;
/// Default `observability.max_stream_events`: the ceiling on retained events
/// per `(workflow, activity, attempt)` transcript stream. Past it one marker
/// record is retained and further events stay live-only. Overridable.
pub const DEFAULT_OBSERVABILITY_MAX_STREAM_EVENTS: u64 = 20_000;
/// Operator-facing message for an explicitly zero `observability.max_event_bytes`
/// (omitting the key uses [`DEFAULT_OBSERVABILITY_MAX_EVENT_BYTES`]; a zero
/// ceiling would truncate every transcript event to nothing).
pub 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";
/// Operator-facing message for an explicitly zero `observability.max_stream_events`
/// (omitting the key uses [`DEFAULT_OBSERVABILITY_MAX_STREAM_EVENTS`]; a zero
/// cap would retain no transcript at all).
pub 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";
/// Child directory below Aion home used by the default haematite store.
///
/// The complete default is `<AION_HOME>/data`; it is resolved dynamically after
/// file and environment overlays so an explicit `store.data_dir` always wins.
pub const DEFAULT_HAEMATITE_DATA_DIR: &str = "data";
/// Child directory below Aion home used by the out-of-box AWL studio.
///
/// The complete default is `<AION_HOME>/authoring`; it is resolved dynamically
/// after file and environment overlays so an explicit
/// `authoring.workspace_dir` always wins. This does not commission the separate
/// Gleam authoring loop, which still requires an explicit
/// `authoring.gleam_path`.
pub const DEFAULT_AUTHORING_WORKSPACE_DIR: &str = "authoring";
/// CWD-relative store default used before Aion home existed.
pub const LEGACY_HAEMATITE_DATA_DIR: &str = "aion-data";
/// CWD-relative studio default shipped by the first out-of-box authoring round.
pub const LEGACY_AUTHORING_WORKSPACE_DIR: &str = "aion-authoring";
/// Operator-facing message for an empty or malformed `cors_allowed_origins`
/// entry.
pub 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";