Configuration Reference¶
Every configuration key the Rust port reads, with its type, default, and the crate that reads
it. All keys were enumerated from this repository's source (AppConfigReader /
ConfigReader lookups across crates/*/src), so each entry is guaranteed to exist in the
running code — nothing here is inherited from the Java documentation unverified.
Applications are configured through resources/application.yml (or the equivalent
application.properties). The configuration syntax is kept verbatim from the Java
original — classpath:/ and file:/ location prefixes, ${ENV_VAR:default} environment
substitution, and dot/bracket composite keys — so configuration files port between the two
implementations unchanged.
Resolution order for any key: -Dkey=value runtime arguments (the JVM -D analog,
passed after -- on the cargo command line) win over configuration-file values, and the
files themselves merge in the manifest order described below.
Rust port
The Java configuration reference documents many keys that do not exist in this port and
are therefore absent from this page: the Spring Boot integration keys (spring.*,
server.port), TLS and server extras (rest.server.ssl*, api.origin, hsts.feature,
oversize.http.response.header, websocket.binary.size, websocket.server.port),
the service mesh / cloud connector and the twin-kafka (second cluster) keys, the scheduler,
PostgreSQL, classpath scanning
(web.component.scan, modules.autostart), threading
(kernel.thread.pool, deferred.commit.log), event-script extras
(yaml.journal, yaml.multicast),
HTTP extras (async.http.temp, stack.trace.transport.size,
protect.info.endpoints), and serialization extras (snake.case.serialization,
custom.content.types, mime.types). If a key is not on this page, the Rust port
does not read it.
Bootstrap: files, profiles, and overrides¶
app-config-reader.yml (manifest)¶
| Type | Default |
|---|---|
| resource file | built-in |
The manifest that bootstraps AppConfigReader (crates/platform-core). Its resources:
list names the base configuration files, merged in order (later files override earlier
ones); profiles: gives the location prefix for profile overlays. An application copy in
its resources/ folder overrides the built-in default:
resources:
- classpath:/bootstrap.properties
- classpath:/bootstrap.yml
- classpath:/application.properties
- classpath:/application.yml
profiles: 'classpath:/application-'
app.profiles.active¶
| Type | Default |
|---|---|
| string (comma/space-separated) | — |
Active configuration profiles. For each profile p, the overlays
application-p.properties and application-p.yml are merged over the base configuration.
Resolution precedence (read by crates/platform-core): the APP_PROFILES_ACTIVE
environment variable → the -Dapp.profiles.active=... process override → this key in the
consolidated configuration.
Rust port
Renamed from the Java original's SPRING_PROFILES_ACTIVE / spring.profiles.active —
Spring is not ported, so the port uses the generic names outright (a rename, not an
alias). The mechanism and precedence are unchanged, so profile overlay files
themselves port without modification.
yaml.preload.override¶
| Type | Default |
|---|---|
| string (comma-separated locations) | — |
Optional list of override-file locations (classpath:/... or file:/...) that rename,
fan out, or re-tune the instances of any #[preload] route at deploy time — without
recompiling (the Java operational surface, ported with identical semantics). A missing
or malformed file is logged and skipped, so a deployment can chain optional locations.
Each file carries a top-level preload list; every entry names an original route
declared in a #[preload], a routes replacement list, an optional instances count,
and an optional keep-original: true that adds the original back into the set:
preload:
- original: "hello.world"
routes:
- "hello.one"
- "hello.two"
instances: 20
keep-original: true
Across multiple files the route sets for the same original are UNIONed and the first
file to set instances wins. Applied at boot between inventory collection and
registration; env_instances resolution happens first, then a matched override replaces
the route list (sorted) and — when its instances is positive — the resolved count,
logged as Preload [original] as [routes], instances old to new. Read by
crates/platform-core (AutoStart).
Application identity¶
application.name¶
| Type | Default |
|---|---|
| string | application |
The application name (Platform::name()), shown in startup logs and the /info actuator
response. Read by crates/platform-core.
Rust port
The Java spring.application.name fallback is retired along with the other Spring
names; application.name is the only key consulted.
info.app.version¶
| Type | Default |
|---|---|
| string | the platform-core crate version |
Application version string shown in the /info actuator response. Read by
crates/platform-core (actuator).
info.app.description¶
| Type | Default |
|---|---|
| string | the application name |
Application description shown in the /info actuator response. Read by
crates/platform-core (actuator).
Server and REST automation¶
rest.automation¶
| Type | Default |
|---|---|
| boolean | false |
Enables the REST automation engine: the HTTP server starts and serves the endpoints
declared in rest.yaml. Read by crates/platform-core (application lifecycle). The HTTP
server also starts when at least one #[websocket_service] is registered, even with this
key off.
rest.server.port¶
| Type | Default |
|---|---|
| int | 8085 |
Listening port of the REST automation server. 0 binds an ephemeral port (tests and
embedders recover the assigned port through automation::server_address()). Read by
crates/platform-core; also read by crates/knowledge-graph to render the websocket
workbench page URLs.
yaml.rest.automation¶
| Type | Default |
|---|---|
| string (location) | classpath:/rest.yaml |
Location of the REST endpoint configuration file. Read by crates/platform-core
(automation server) at HTTP server start.
Rust port
A single location — the Java comma-separated multi-file merge is not ported. Static
content is always served from the application's resources/public folder (the Java
static.html.folder key is not ported), and the static-content.filter /
static-content.no-cache-pages blocks are rest.yaml sections here, not application
configuration keys.
websocket.idle.timeout¶
| Type | Default |
|---|---|
| int (seconds) | 60 |
Idle expiry for websocket connections (floor 10 seconds). A connection with no traffic for
this long is closed with code 1003. Read by crates/platform-core (websocket server).
Rust port
The unit is seconds in this port (verified against the websocket server source); the Java reference documents its key in minutes.
HTTP client¶
http.client.connection.timeout¶
| Type | Default |
|---|---|
| int (milliseconds) | 5000 |
Connection timeout of the built-in async HTTP client (async.http.request). Read by
crates/platform-core (automation). The per-request time-to-live is separate — it travels
as the x-ttl header on the request event (default 30 seconds; see
Reserved Names & Headers).
yaml.event.over.http¶
| Type | Default |
|---|---|
| text (config location) | classpath:/event-over-http.yaml |
Location of the optional declarative Event-over-HTTP routing map. Each event.http[]
entry in the file maps a route name to a peer's /api/event endpoint (with optional
per-target security headers such as authorization), and every PostOffice
send/request to that route is then forwarded over HTTP transparently — user code
cannot tell a remote route from a local one. An absent file simply disables the feature.
${...} references (environment variables, base configuration keys) resolve inside the
values. Read by crates/platform-core (automation) on first use. See the
Event over HTTP guide for the file
format and forwarding semantics.
Tracing and observability¶
http.trace.id.header¶
| Type | Default |
|---|---|
| string (header name) | X-Trace-Id |
The HTTP header recognized inbound (when no W3C traceparent is present — a well-formed
traceparent always takes precedence) and emitted outbound by the async HTTP client as
the trace id. Read by crates/platform-core (REST automation server and HTTP client). A
rest.yaml endpoint entry may override the header name per endpoint with its optional
trace.id.header key.
http.correlation.id.header¶
| Type | Default |
|---|---|
| string (header name) | X-Correlation-Id |
The HTTP header carrying the business correlation-id. Captured at the REST automation
edge (a fresh dash-less UUID is generated when absent), exposed to the target function as
the read-only my_correlation_id request header, preserved by the flow engine, propagated
on every PostOffice send/RPC inside a traced request, and emitted by the async HTTP
client on downstream calls. Read by crates/platform-core (server and HTTP client) and
crates/event-script (flow adapter). A rest.yaml endpoint entry may override the header
name per endpoint with its optional correlation.id.header key.
http.traceparent.header¶
| Type | Default |
|---|---|
| string (header name) | traceparent |
The HTTP header name carrying the W3C trace context (the full traceparent value:
trace-id, parent span-id and flags). When customized, outbound HTTP calls (the async HTTP
client and Event-over-HTTP) stamp the same W3C value under both names. Inbound, the
standard traceparent always wins — the custom name is read only when the standard
header is absent: a well-formed standard traceparent means the caller already speaks
W3C/OTel, so a proprietary header alongside it is residual and safely ignored. Read by
crates/platform-core (REST automation server, HTTP client and Event-over-HTTP client).
Overridable per endpoint with traceparent.header in a rest.yaml entry.
Our position: use the standard.
traceparentis the W3C Trace Context header that OpenTelemetry and the wider observability ecosystem interoperate on, and the framework implements it as the default with zero configuration. This optional setting exists for backward compatibility with legacy systems only — an intermediary (typically an API gateway with a header allow-list) or an upstream convention that cannot be fixed promptly. Departure from the standard is discouraged: a renamed carrier is invisible to standards-compliant tooling (OpenTelemetry SDKs, service meshes, APM agents) and every participant must be configured alike. Treat a custom name as a temporary bridge, and plan the migration back to the standard header (e.g. fixing the gateway allow-list).
skip.rpc.tracing¶
| Type | Default |
|---|---|
| string (comma/space-separated routes) | async.http.request |
Route names whose RPC calls produce no caller-side round_trip trace record — an RPC to a
listed route folds into the calling function's span (the telemetry plumbing itself is always
excluded from recording). A callback-mode execution of a listed route — the Event-over-HTTP
stream relay's client leg — still records its own span, parented onto the sender. Read by
crates/platform-core (the caller-side RPC record).
otel.forwarding¶
| Type | Default |
|---|---|
| boolean | false |
Master switch for OpenTelemetry trace forwarding. Linking the mercury-opentelemetry-forwarder
crate registers nothing: the forwarder is #[optional_service("otel.forwarding")], and the
distributed.trace.forwarder route exists only when this is true. Set it per environment in
application.yml, or at launch with the runtime override -Dotel.forwarding=true. Read by
extensions/opentelemetry-forwarder; see Observability.
otel.exporter.otlp.endpoint¶
| Type | Default |
|---|---|
| string (URL) | http://localhost:4318/v1/traces |
The OTLP/HTTP traces endpoint the forwarder exports spans to — the full URL including the
signal path (.../v1/traces; a vendor base URL alone answers 404, which the forwarder's
diagnostic says). Read by extensions/opentelemetry-forwarder.
otel.exporter.otlp.timeout¶
| Type | Default |
|---|---|
| int (ms) | 10000 |
Per-export timeout of the OTLP request. Read by extensions/opentelemetry-forwarder.
otel.exporter.otlp.headers¶
| Type | Default |
|---|---|
string (comma-separated key=value or key: value) |
— |
Request headers of every export — where the backend credential goes (Authorization: Api-Token …
for Dynatrace, X-SF-Token: … for Splunk). Source it from environment variables with no default
so no secret is hard-coded; an unset variable resolves to nothing, which parses to no headers. Each
pair is split on the first = or :; values are never logged. Re-read on every export, so a
credential published later as a runtime override takes effect without a restart. Read by
extensions/opentelemetry-forwarder.
otel.service.name¶
| Type | Default |
|---|---|
| string | application.name, else mercury |
The service.name resource attribute stamped on every exported span — how traces are grouped in
the backend. Read by extensions/opentelemetry-forwarder.
otel.exporter.otlp.compression¶
| Type | Default |
|---|---|
| string | none |
Accepted for parity with the Java module, which also offers gzip. This engine honours only
none: a gzip setting logs a warning at start-up and exports uncompressed (the payload is one
span per request). Read by extensions/opentelemetry-forwarder.
otel.exporter.otlp.connect.timeout¶
| Type | Default |
|---|---|
| int (ms) | — |
A Java-module key with no effect on this engine (a warning at start-up says so): the connect
phase of every export is governed by the platform HTTP client's http.client.connection.timeout.
Logging¶
log.format¶
| Type | Default |
|---|---|
text | json | compact |
text |
Application log output format: text is a plain console line; json pretty-prints each
record; compact emits single-line jsonl records (no CR/LF within a record). Both JSON
forms carry the application log context block (on by default — see app.log.context).
Read by crates/platform-core (logging). Switch at launch with -Dlog.format=json.
app.log.context¶
| Type | Default |
|---|---|
| boolean | true |
Turns the application log context on or
off. When on (the default), the structured JSON formats (log.format=json or compact)
stamp a context block — correlation id, trace/span ids, service name — into every log
line a traced function emits, using the built-in default-log-context.yaml template.
Provide your own app-log-context.yaml on the resource path to replace the template, or
set this key to false to opt out. Read by crates/platform-core (logging).
log.level¶
| Type | Default |
|---|---|
error | warn | info | debug | trace | off |
info |
Process log level. The RUST_LOG environment variable, when set, wins over this key. Read
by crates/platform-core (logging).
Rust port
A port addition — the Java original configures levels through log4j2 XML instead.
app-log-context.yaml (optional resource file)¶
| Type | Default |
|---|---|
| resource file | absent (the built-in default-log-context.yaml applies) |
Replaces the built-in log-context template entirely. Its context: section maps an
output key of your choice to a reserved $token ($cid, $traceId, $tracePath,
$spanId, $parentSpanId, $service, $utc — resolved live per line), a
${ENV:default} substitution (resolved once at load), or a literal. Keys that resolve to
nothing are omitted. A template that maps $utc to no key gets it added as timestamp
(utc if timestamp is taken), so the block always carries a UTC time. Business
key-values added with PostOffice::update_context join the same block — the reserved names
in both spellings (traceId / trace_id, …) are refused, and a template key is never
shadowed. When this file is absent, the built-in default template (the seven standard
trace-context keys, in snake_case: cid, trace_id, trace_path, span_id,
parent_span_id, service, timestamp) applies — see app.log.context above to switch the
feature off. Read by crates/platform-core (logging).
Actuators and health¶
show.env.variables¶
| Type | Default |
|---|---|
| string (comma-separated names) | — |
Environment variable names to expose through the /env actuator endpoint. Read by
crates/platform-core (actuator).
show.application.properties¶
| Type | Default |
|---|---|
| string (comma-separated keys) | — |
Application configuration keys to expose through the /env actuator endpoint. Read by
crates/platform-core (actuator).
mandatory.health.dependencies¶
| Type | Default |
|---|---|
| string (comma-separated routes) | — |
Route names of health-check functions that must all report healthy for /health to return
HTTP 200. Read by crates/platform-core (actuator).
optional.health.dependencies¶
| Type | Default |
|---|---|
| string (comma-separated routes) | — |
Route names of health-check functions whose failure is reported in the /health response
without failing it. Read by crates/platform-core (actuator).
Performance and back-pressure¶
worker.instances.actuator.services¶
| Type | Default |
|---|---|
| int | 5 |
Worker-instance count for the whole actuator family (/info, /info/routes, /env,
/health, /livenessprobe). The default is a rule of thumb; operations teams fine-tune
it in QA/Perf environments before promoting to production, and /info/routes displays the
effective counts. The key name is shared with the Java engine (whose actuators are one
aliased class keyed by its primary route actuator.services — that route itself is not
ported), so one runbook line tunes both engines. A non-numeric value falls back to the
default (env_instances semantics). Read by crates/platform-core at boot.
worker.instances.no.op¶
| Type | Default |
|---|---|
| int | 500 |
Worker-instance count of the built-in no.op echo function. Read by crates/platform-core
(application lifecycle).
Rust port
The Java generic worker.instances.<route> override pattern is not ported. A function's
instance count is configuration-driven through the env_instances parameter of its own
#[preload] attribute instead (see the Macros Reference).
elastic.queue.dispatch.mailbox.size¶
| Type | Default |
|---|---|
| int | 1024 |
Capacity of each route manager's inbound mailbox (floor 20). When it fills, senders await —
reactive back-pressure, not drops. Read by crates/platform-core (platform registry).
elastic.queue.segment.size.bytes¶
| Type | Default |
|---|---|
| int (bytes) | 16777216 |
Segment-file size of the elastic queue's disk spill (minimum 512). The first 20 events of a
burst are held in memory before spilling. Read by crates/platform-core (elastic queue).
transient.data.store¶
| Type | Default |
|---|---|
| string (path) | /tmp/reactive |
Base directory for the elastic-queue overflow buffer that absorbs event bursts when
consumers are slower than producers. Read by crates/platform-core (elastic queue).
running.in.cloud¶
| Type | Default |
|---|---|
| boolean | false |
When false, a per-instance subdirectory (<application.name>-<origin>) is created under
transient.data.store, removed at a graceful shutdown, and expired sibling stores are swept at
startup. When true, the path is used as-is (for ephemeral containers). Read by
crates/platform-core (elastic queue).
Serialization¶
serializer.null.transport¶
| Type | Default |
|---|---|
| boolean | false |
Null handling at every boundary — the wire (JSON HTTP responses, websocket frames,
outbound HTTP request bodies, the MsgPack envelope encoder) and every in-memory
event-bus hop. Default false: null map key-values are omitted — absent means null,
and a receiving function sees the key absent regardless of delivery path. Set true when
a downstream must distinguish "key present with null value" from "key absent". Only map
key-values are affected — array elements (including nulls) are always kept so ordering is
preserved, and an empty [] or {} is a real value, never treated as null. Read once at
startup by crates/platform-core (serializer) and cached for the process lifetime.
Port note
Since increment 58 the strip is applied deterministically on every hop, exactly like the Java engine (which serializes every bus message). Earlier Rust builds stripped only when back-pressure spilled an event to disk, so null visibility could vary with load — that nondeterminism is gone.
Event Script (flow engine)¶
yaml.flow.automation¶
| Type | Default |
|---|---|
| string (location) | classpath:/flows.yaml |
Location of the flow manifest, compiled at startup by the flow compiler (a before-application hook at sequence 5). The manifest lists the flow definition files and where to find them:
location inside the manifest defaults to classpath:/flows/. Read by
crates/event-script (compiler).
max.model.array.size¶
| Type | Default |
|---|---|
| int | 1000 |
Ceiling for a dynamically resolved array index on the right-hand side of a data
mapping (a [model.x] index) — a mapping whose resolved index exceeds it fails instead of
allocating an arbitrarily large state-machine array. Literal numeric indices are not
capped (same as the Java engine). Read once by crates/event-script (task executor).
Port note
Added in increment 52 (parity remediation): the key existed in the Java engine from the start, and the syntax guide already described it — the Rust executor now enforces it.
Kafka flow adapter and notification¶
The opt-in mercury-minimalist-kafka crate — see the Minimalist Kafka guide.
Every key is read by crates/minimalist-kafka.
yaml.kafka.flow.adapter¶
| Type | Default |
|---|---|
| string (location) | — |
Location of the inbound adapter YAML (kafka-flow-adapter.yaml: the consumer: binding list).
Unset = no adapter consumer starts. The file's values support ${ENV_VAR:default} substitution.
kafka.producer.enabled, kafka.consumer.enabled¶
| Type | Default |
|---|---|
| boolean | true |
Vetoes, not triggers: only the literal false switches a client off. A binding with dlq-topic
while the producer is off fails the deployment at startup; with the consumer off, kafka.health
probes through the producer template.
kafka.producer.properties, kafka.consumer.properties¶
| Type | Default |
|---|---|
| string (comma-separated locations) | classpath:/kafka-producer.yml, classpath:/kafka-producer.properties / the consumer twin |
The client templates: librdkafka parameter names (bootstrap.servers, security.protocol,
sasl.*, ssl.*, acks, auto.offset.reset, group.protocol), ${ENV_VAR:default}
substitution. A single location is normal; a comma-separated list is a fallback chain. JVM-only keys
are ignored with a startup log line naming each one.
kafka.dlq.timeout.ms¶
| Type | Default |
|---|---|
| integer (milliseconds) | 10000 |
Confirm-write deadline for the dead-letter publish. Flow processing has no timeout knob — the flow's
own ttl is the deadline.
kafka.flow.max.retries, kafka.flow.retry.backoff.ms¶
| Type | Default |
|---|---|
| integer | 3 / 500 |
Retry attempts before dead-lettering, and the pause between attempts. Together with the slowest
reachable flow/task ttl they derive each binding's max.poll.interval.ms.
kafka.correlation.id.header, kafka.trace.id.header, kafka.traceparent.header¶
| Type | Default |
|---|---|
| string (header name) | cid / — / traceparent |
The record headers carrying the business correlation id, an optional legacy trace id, and the W3C
trace context — both directions. Each has a per-binding override in the adapter YAML
(correlation.id.header, trace.id.header, traceparent.header).
kafka.health.timeout, kafka.health.startup.grace¶
| Type | Default |
|---|---|
| duration | 5s / 30s |
The kafka.health probe's round-trip deadline, and how long /health reports the placeholder
status while the client warms up.
schema.registry.url¶
| Type | Default |
|---|---|
| string (URL) | — |
The Confluent Schema Registry; unset = schema features off (raw bytes on the wire). The feature
switch for schema.enabled bindings and the subject header of simple.kafka.notification.
schema.registry.properties¶
| Type | Default |
|---|---|
| string (comma-separated locations) | classpath:/schema-registry.yml, classpath:/schema-registry.properties |
The registry client template: authentication (bearer.auth.*, basic.auth.*) and the Confluent
Cloud headers, interpreted by name; unknown keys are logged as ignored.
schema.registry.cache.ttl, schema.registry.version.cache.ttl¶
| Type | Default |
|---|---|
| duration | 30m / 10d |
TTLs of the id→schema cache (positive results only, cleared at startup) and of the pinned subject+version resolutions (bounded to 3000 entries).
schema.registry.serde.json.fail.invalid.schema¶
| Type | Default |
|---|---|
| boolean | false |
Validate JSON documents against their registered schema on both produce and consume (Confluent's
json.fail.invalid.schema). Other schema.registry.serde.* keys have no analog here (CSFLE is not
supported) and are logged as unsupported.
schema.registry.consumer.properties¶
| Type | Default |
|---|---|
| string (comma-separated locations) | — (the flow adapter shares the producer's codec) |
Opt-in separate Schema Registry identity for the consumer side.
When it names a registry client template, the Kafka flow adapter decodes with its own codec built under the
schema.registry.consumer prefix — the same schema.registry.url, that template, its own
schema.registry.consumer.cache.ttl — for an installation that grants registry access per direction
(separate produce and consume identity pools). The consume identity lives in the template on this engine.
Unset or blank: unchanged, one shared codec; schema.registry.url remains the feature switch.
Knowledge graph and Playground¶
app.env¶
| Type | Default |
|---|---|
| string | dev |
The environment gate for the Playground developer surface. The interactive services — the
command grammar, the graph traveler, the websocket UI, the AI-companion endpoints, uploads,
inspection, and the mock functions — are each declared with
#[optional_service("app.env=dev")] and register only when this key is dev. Any other
value (e.g. ${APP_ENV:dev} resolved to prod) runs graphs only through
POST /api/graph/{graph-id}, and the home page (get.index.html) serves the plain
/template/index.html instead of the Playground page /template/playground.html — an absent
app.env yields the plain page too, so a production deployment never shows the Playground UI.
Read by crates/knowledge-graph.
graph.model.automation¶
| Type | Default |
|---|---|
| string (comma-sep manifest paths) | — (unset = no deployed graphs) |
Location of the graph manifest — a graphs: list of graph ids plus an optional
location entry naming the deployed-graph folder (default classpath:/graph; file:/
or classpath:/, the flows.yaml convention). Since 4.12.19 the property accepts a
comma-separated list of manifests, each carrying its own location, and when two manifests
list the same graph id the later manifest wins — its copy replaces the earlier one, and if
that copy is rejected the id is not executable (a manifest that cannot be loaded is skipped
with a warning). The manifest is the CompileGraph quality gate and the only door to
deployed execution: a graph is executable at POST /api/graph/{graph-id} only when listed
AND passing the gate at startup — failed or unlisted graphs answer HTTP-404 as if they do not
exist. When unset or empty, a startup warning notes that no deployed graph models will be
executable (the Playground dry-run surface is unaffected). Set it for one run with the -D
program argument — cargo run -p minigraph-playground -- -Dgraph.model.automation='classpath:/graphs.yaml, file:/tmp/graph/deploy/graphs.yaml'
keeps the bundled graphs and deploys an exported graph from a file:/ manifest beside them
without a rebuild (the rapid-prototyping path).
Read by crates/knowledge-graph (compiler).
The former
location.graph.deployedkey is retired — the manifest carries the location of its own models. A leftover value logs an obsolete-key startup warning.
location.graph.temp¶
| Type | Default |
|---|---|
| string (path) | /tmp/graph |
The Playground draft-graph scratch folder. Must be on the local file system
(classpath: is rejected because of read/write requirements); a file: prefix is
accepted and stripped. Invalid values fall back to the default. Read by
crates/knowledge-graph (Playground commands).
graph.traversal.log¶
| Type | Default |
|---|---|
| boolean | true |
Stepwise traversal logging for deployed graph execution (graph.executor) — the same
trail the Playground dry-run narrates to its console, emitted as INFO structured
records (a JSON object as the log message). Each record carries three keys: text —
the traveler-style message (Walk to {node}, Executed {node} with skill {skill} in
{time} ms, Graph traversal completed in {time} ms, or Graph traversal aborted:
{reason}), graph — the graph id, and id — the run's trace id (fallback: the flow
instance id when tracing is off), so an OpenTelemetry dashboard can join these app-log
lines with the exported spans and metrics. With log.format=json or compact the
record embeds as a nested structure that log-analytics platforms (Dynatrace, Splunk, ...)
index as key-values; in plain text format the record prints as its compact JSON string.
Note that the executor deliberately runs zero-traced (the trace is captured once from the
initiating event, not re-spanned per node), so the app-log-context context block does
not accompany these lines in any format — the record's id key is the correlation
surface. On by default; set it to false (for example with the runtime override
-Dgraph.traversal.log=false) to reduce log volume on busy installations. Read by
crates/knowledge-graph (executor). Java parity: identical record keys and gate.
graph.max.loop.interval¶
| Type | Default |
|---|---|
| int (milliseconds) | 1000 |
The observation window of the graph traversal loop guard (floor 100). Together with
graph.node.high.frequency, it detects a runaway cycle: a node revisited too often within
the window aborts the traversal. Read by crates/knowledge-graph.
graph.node.high.frequency¶
| Type | Default |
|---|---|
| int (hits per window) | 10 |
How many visits to the same node within graph.max.loop.interval count as a runaway loop
(floor 2). Read by crates/knowledge-graph.
redis.* — the shared Redis connection namespace¶
| Key | Type | Default |
|---|---|---|
redis.host |
string | 127.0.0.1 |
redis.port |
int | 6379 |
redis.username |
string | — (blank = the default user; set for an ACL/RBAC user, e.g. ${REDIS_USERNAME:}) |
redis.password |
string | — (blank = no auth; source from the environment, e.g. ${REDIS_PASSWORD:}) |
redis.ssl |
boolean | false |
redis.database |
int | 0 (standalone only — a cluster is database 0) |
redis.timeout.ms |
long (ms) | 5000 |
redis.heartbeat.ms |
long (ms) | 1000 — the connection heartbeat of the standalone (managed) connection; 0 disables it. Rust engine only — a PING per interval that notices a lost connection and makes the client reconnect ahead of the next command, the lifecycle behind the restart-aware retry (Java's Lettuce requeues unwritten commands across a reconnect on its own) |
redis.cluster.detect |
auto | other |
auto — probe the seed at start-up (INFO cluster); anything else = decide by redis.cluster.mode |
redis.cluster.mode |
boolean | false — true = cluster client, false = standalone; also the fallback when auto-detection is inconclusive |
redis.cluster.nodes |
string | — (blank = redis.host:redis.port; else host:port,host:port seeds) |
The base namespace of the shared mercury-redis-connection foundation (extensions/redis-connection,
the Rust twin of the Java redis-connection module). It is read directly by the
distributed cache (redis.cache.* below) and by the graph suspend/resume state
store (extensions/minigraph-state-redis, lazily on the first suspend/resume, so an application boots
normally without Redis; its worker counts are ops-tunable via worker.instances.v1.redis.persist.model /
worker.instances.v1.redis.retrieve.model), and it is the per-key fallback of sync-over-async's
soa.redis.* namespace below. The username and cluster keys are read by the foundation's consumers (the
cache, the health probes); the state store reads the host/port/password/ssl/database/timeout subset.
Authentication is identical for standalone and cluster — a username selects RBAC (AUTH user pass), a bare
password the legacy form. Key names and defaults are the Java engine's.
soa.redis.* (the sync-over-async extension crate — crates.io: mercury-sync-over-async)¶
Sync-over-async's own copy of every redis.* key above — soa.redis.host, soa.redis.port,
soa.redis.username, soa.redis.password, soa.redis.ssl, soa.redis.database,
soa.redis.timeout.ms, soa.redis.cluster.detect, soa.redis.cluster.mode, soa.redis.cluster.nodes —
plus soa.redis.health.timeout (default 5s) and soa.redis.health.startup.grace (default 30s) for the
soa.redis.health probe. Each key falls back to the un-prefixed redis.* form when absent (the
redis.health.* keys for the two probe settings) — backward compatibility for deployments that predate the
namespace, and for applications running sync-over-async alone. When the distributed cache also runs, give
each module its own Redis and set the whole soa.redis.* connection set: because the fallback is per
key, a partial override inherits the cache's credentials. See
Separate Redis clients, by design. Read by extensions/sync-over-async.
redis.cache.* (the distributed-cache extension crate — crates.io: mercury-distributed-cache)¶
| Key | Type | Default |
|---|---|---|
redis.cache.enabled |
boolean | false — the master switch: true registers v1.cache.redis and redis.health |
redis.cache.instances |
int | 20 — worker instances of v1.cache.redis (function concurrency), not a connection count |
redis.cache.default.ttl |
duration | 1h — the TTL a PUT / MPUT / LIST_PUSH uses when it omits ttl |
redis.cache.key.prefix |
string | — (blank) — prepended to every key, stripped again from MGET results |
redis.health.timeout |
duration | 5s — bounds the redis.health probe |
redis.health.startup.grace |
duration | 30s — the probe's start-up placeholder window |
The cache connects through the plain redis.* namespace above, on one shared multiplexed connection
built lazily on the first call (a late-published credential is picked up on retry). See the
Distributed Cache guide. Read by extensions/distributed-cache.
Application-defined keys¶
Two framework mechanisms read keys whose names the application chooses, so any such key
in an example's application.yml is application configuration, not a framework key:
env_instances—#[preload(route = "...", env_instances = "my.pool.size")]readsmy.pool.sizeat startup for the worker count (the value may itself use${SOME_ENV:default}syntax); the literalinstancesis the fallback.#[optional_service("condition")]— the condition references any configuration key (key=value,key,!key); see the Macros Reference.
Adapted from the mercury-composable guide docs/guides/configuration-reference.md; keys/APIs enumerated from this repository's source.