Runtime Config Baseline
Status: locked baseline for contract implementation.
Purpose: capture current runtime-config behavior before adding JSON Schema and CI gates.
Source of Truth (Current Implementation)
This baseline is derived from:
core/runtime/config.hpp(config model + defaults)core/runtime/config.cpp(loader compatibility + validation rules)core/src/main.cpp(--check-configbehavior)tests/unit/config_test.cpp(behavior coverage)
Runtime Config File Scope
This baseline applies only to runtime YAML consumed by anolis-runtime --config and --check-config.
Target patterns:
config/anolis-runtime*.yamlconfig/**/anolis-runtime*.yamlsystems/**/anolis-runtime.yaml
Out of scope:
config/**/provider-*.yamlconfig/**/telemetry-export*.yaml
Top-Level Sections
Supported top-level sections:
runtimehttpproviderspollingtelemetryloggingautomation
Unknown top-level keys are warned and ignored.
Compatibility Behavior (Locked)
Current compatibility behavior that must remain unchanged during initial contract rollout:
- Unknown keys:
- warned and ignored (top-level and most nested map sections)
- Deprecated but accepted:
automation.behavior_tree_pathalias forautomation.behavior_tree- flat telemetry keys under
telemetry.*:influx_urlinflux_orginflux_bucketinflux_tokenbatch_sizeflush_interval_ms
- Rejected legacy key:
runtime.modeis hard-failed
Defaults Snapshot
Defaults from config.hpp:
runtime.shutdown_timeout_ms = 2000runtime.startup_timeout_ms = 30000http.enabled = truehttp.bind = "127.0.0.1"http.port = 8080http.cors_allowed_origins = ["*"]http.cors_allow_credentials = falsehttp.thread_pool_size = 40polling.interval_ms = 500logging.level = "info"telemetry.enabled = falsetelemetry.influx_url = "http://localhost:8086"telemetry.influx_org = "anolis"telemetry.influx_bucket = "anolis"telemetry.batch_size = 100telemetry.flush_interval_ms = 1000telemetry.queue_size = 10000telemetry.max_retry_buffer_size = 1000automation.enabled = falseautomation.tick_rate_hz = 10automation.manual_gating_policy = BLOCK
Validation Rules Snapshot
Current loader-enforced rules:
- Runtime:
500 <= shutdown_timeout_ms <= 300005000 <= startup_timeout_ms <= 300000
- HTTP (when enabled):
1 <= port <= 65535thread_pool_size >= 1cors_allowed_originsnon-empty- wildcard origin
*forbidden whencors_allow_credentials=true
- Providers:
- non-empty
providers - unique provider
id commandrequiredtimeout_ms >= 100hello_timeout_ms >= 100ready_timeout_ms >= 1000
- non-empty
- Restart policy (when enabled):
max_attempts >= 1backoff_msnon-emptylen(backoff_ms) == max_attempts- each backoff value
>= 0 timeout_ms >= 1000success_reset_ms >= 0
- Polling:
interval_ms >= 100
- Logging:
- level in
debug|info|warn|error
- level in
- Automation (when enabled):
behavior_treerequired1 <= tick_rate_hz <= 1000- typed parameter default consistency
- numeric
min/maxonly for numeric parameter types allowed_valuesonly for string parameters- mode transition hooks:
from/toinMANUAL|AUTO|IDLE|FAULT|*(or empty)- non-empty
calls - each call requires
device_handle - each call requires one of
function_idorfunction_name
Automation Hook Arg Scalar Parsing
automation.mode_transition_hooks.*.calls[].args currently parse using loader scalar heuristics:
true|false-> bool- integer literal -> int64
- float literal -> double
- anything else -> string
Quoted numeric-like strings can be coerced by YAML scalar parsing before this logic, so fixtures must explicitly cover this edge case.
Known Baseline Quirks (Intentional for Now)
These are baseline behaviors and not changed in the first contract wave:
- Duplicate automation parameter names are accepted by config load.
- Later parameter redefinitions are ignored by
ParameterManager::definewith a warning. - Unknown keys are warnings, not hard failures.
- Unknown-key warning coverage is not fully uniform across every known section
(
pollingandloggingcurrently have no nested unknown-key warnings).
Parser Authority Note
Runtime parser behavior (yaml-cpp in core/runtime/config.cpp) is authoritative for runtime semantics.
Contract tooling must account for parser differences when running schema-layer checks from Python.
Existing Coverage Reference
Representative unit coverage in tests/unit/config_test.cpp:
- unknown key tolerance
runtime.moderejection- telemetry nested + defaults
- automation alias (
behavior_tree_path) acceptance - mode-transition hook parsing and validation
- CORS constraints
- restart policy invariants
- idempotent parsing and default reset semantics
Next Contract Step
Close out hardening items against this baseline without changing runtime behavior:
- parser-alignment guardrails (duplicate-key rejection + parser-sensitive fixtures)
- schema meta-validation gate
- documentation alignment for authoritative behavior and gate scope