HyphaeConfig::from_env_and_file. Environment variables take precedence, so you can ship a base
config file and override per-deployment values from the environment.
This page lists the environment surface, then explains which settings are structural (fixed for
the life of the process) versus non-structural (reloadable with SIGHUP).
Environment variables
Contradiction detection (see the concept page) is configured
through the config file’s
contradiction section rather than env vars: enabled (default
false), the Stage-1 cosine band and Stage-2 confidence threshold, the classifier selection
(nli — requires a build with the NLI feature — or llm_judge, unavailable in V1), and
max_concurrent_checks (default 4 — a store burst beyond it skips detection for the excess
stores rather than queueing). Enabling detection without a constructible classifier is a
boot error, never a silent no-op. The trust consequences of a detection are tunable through
the trust section below.
On an empty registry the server fails closed without
HYPHAEDB_BOOTSTRAP_ADMIN — it refuses to
start rather than run with no administrator. Once an admin exists, the variable is no longer
required on subsequent boots.The trust section
The mesh trust tunables live in the config file’s trust section. Each is validated at boot
(the score-shaped keys must be in [0.0, 1.0]):
See Trust and provenance for what these control.
The a2a section
The A2A surface is configured through the config file’s a2a section. It is
off by default: serving requires a2a.enabled = true and a2a.public_url set —
enabled = true without a public_url is a boot error. In the production deployment profile
public_url must be https (http is permitted in Dev only).
A worked example
This starts the server in daemon mode against a local PostgreSQL instance and creates the first admin:0.0.0.0:50051 and REST/WebSocket on 0.0.0.0:8080.
Structural versus non-structural config
Some settings define the shape of the in-memory mesh and the stored vectors. Changing them invalidates the existing graph, so they are fixed for the process lifetime:- HNSW dimensions
- The embedding model and provider
- The storage backend
SIGHUP (the reloader re-reads the
same config file the process booted with — pass one with --config):
Two more tunables are in the spec’s reloadable set but have no live consumer in this build yet —
the log filter and the trace sample ratio. A
SIGHUP that changes one is rejected with an
explicit “no live consumer — restart to apply” message rather than silently accepted, so you are
never misled into thinking an inert change went live.
The anti-entropy sweep interval (sweep.interval_seconds) does have a live consumer — the
sweep loop — but it reads the value once at boot, so changing it is restart-required (a
SIGHUP is rejected with that message). Setting it to 0 disables the sweep loop entirely
(logged at boot); eventual consistency then rests on gossip propagation alone.
The reload is all-or-nothing: the reloader re-runs the exact boot-time config load (so a config
that would not boot never replaces the running one), diffs every field, and if any changed field
falls outside the reloadable set it applies nothing — structural fields get a
migrate-and-restart message, everything else a plain restart-required message. Reject messages name
config paths only, never values, so a database DSN can never leak into logs.
Signals
For the full drain sequence and the operational model around it, see
/operations/deployment-operations.