Environment variables
This page lists every environment variable read by the Meridian runtime processes, the process(es) that read each one, its role, and its default. It mirrors the code; where a variable's behaviour matters, the source file is cited.
The proxy reads its configuration once at boot (readApiConfig,
apps/api/src/server/config.ts), and the endpoint reads its own
(readEndpointConfig, apps/api/src/restate/config.ts). A variable that is
unset or empty takes its default. A malformed value (a port, a duration, a
boolean, a URL, an unknown mode) stops the boot with a message that names the
variable and the expected form, for example
SHUTDOWN_TIMEOUT_MS invalide : « 10s ». Attendu un nombre entier de millisecondes entre 1 et 2147483647.
The processes referred to below are:
| Process | Entry point | Log/service name | Default PORT |
|---|---|---|---|
| proxy (runtime API) | apps/api/src/server/api.ts |
meridian-proxy |
4000 |
| endpoint (Restate services) | apps/api/src/restate/server.ts |
meridian-endpoint |
9080 |
| ui (ehr-lab mini-EHR) | apps/ehr-lab (Next.js) |
— | 3000 |
| hospital-sim (simulator) | apps/hospital-sim/src/main.ts |
system:* |
SIM_PORT = 3300 |
For the deployment topology these processes form, see Topology.
.env loading
Both proxy and endpoint import apps/api/src/env.ts first. It reads a .env
file at the repository root (path resolved relative to the module) if one
exists, and copies each KEY=value line into process.env only when the key
is not already set — an explicit export FOO=bar in the shell always wins
(apps/api/src/env.ts). Lines starting with # and malformed keys are ignored;
surrounding single or double quotes on the value are stripped. There is no
dotenv dependency.
The ehr-lab app loads the same repository-root .env through its own loader
(apps/ehr-lab — src/infrastructure/env.ts).
Consequences:
- In a checkout, copy
.env.exampleto.envat the repo root and restart the process after any change. - In a container/Kubernetes deployment, inject variables through the service
environment (compose
env_file/environment, or aSecret) rather than copying a.env. Instance manifests are version-controlled and must never contain secrets — see Security posture.
Instance and plugin resolution
Read by both proxy and endpoint at boot.
| Variable | Process(es) | Role | Default |
|---|---|---|---|
INSTANCE_CONFIG |
proxy, endpoint | Path to the instance manifest. Relative paths resolve from the repo root. Absent → instance.yaml at the repo root; if that is also missing, an empty instance (all-internal/in-memory dev default). A path that is set but missing fails the boot loudly. |
instance.yaml |
PLUGINS_PATH |
proxy, endpoint | Extra roots holding external compiled plugins, split on , or the OS path delimiter. Relative entries resolve from the process cwd. |
(empty) |
MERIDIAN_REGISTRY |
proxy, endpoint | Default plugin registry used to resolve instance-declared plugins when the manifest has no registry: key. Accepts gs://bucket[/prefix], file://…, or a repo-relative directory. |
(none) |
MERIDIAN_PLUGIN_CACHE |
proxy, endpoint | Local cache directory for plugins downloaded from the registry; the resolution of the plugins: ranges reads the manifests of the versions already there before the registry. Relative paths resolve from the repo root. |
.data/plugins |
The manifest's own registry: key takes precedence over MERIDIAN_REGISTRY; a
plugin listed with a local path bypasses the registry entirely
(apps/api/src/registry.ts). A declared plugin that cannot be resolved fails the
boot. See
Set up a plugin registry,
Declare and install plugins,
and the Instance manifest reference.
Restate wiring
| Variable | Process(es) | Role | Default |
|---|---|---|---|
RESTATE_URL |
proxy | Restate ingress URL (http:// or https://). Required — the proxy throws at startup if it is unset, because execution runs through Restate. A trailing slash is stripped. |
(required) |
RESTATE_ADMIN_URL |
endpoint | Restate admin API used for auto-registration (POST {admin}/deployments), http:// or https://. A trailing slash is stripped. |
http://localhost:9070 |
RESTATE_ENDPOINT_URL |
endpoint | URI under which the Restate server reaches this endpoint (advertised at registration), http:// or https://. |
http://host.docker.internal:<endpoint PORT> |
RESTATE_AUTO_REGISTER |
endpoint | false or 0 disables auto-registration; true or 1 keeps it enabled. |
(enabled) |
API_INTERNAL_URL |
endpoint | Where the endpoint reaches the REST proxy to ingest schedule ticks (trigger.schedule, service meridianScheduler), to read agents and to read and write the workflow memory (/api/internal/memory/*, see Workflow memory storage). http:// or https://, a trailing slash is stripped. Must point at the proxy in any multi-container deployment, or planned workflows never start and memory nodes fail. |
http://localhost:4000 |
RUN_JOURNAL_FORMAT |
proxy | Journal format of the runs the proxy starts: 1 or 2, any other value throws at startup. Logged at boot and recorded per run in the run index (journal_format). Set 2 once every endpoint replica runs a release that knows format 2; set 1 again before rolling the endpoint back below it. See Upgrade the platform — Journal formats. |
1 |
AGENT_REFRESH_MS |
endpoint | Period, in milliseconds, at which the endpoint re-reads the store's agents from the proxy; on a change it rebuilds its catalogue, and a failed or empty read keeps the current list (apps/api/src/restate/endpoint.ts). An integer from 0 to 2147483647; 0 disables the refresh. |
30000 |
The endpoint (re)registers its deployment on every start, idempotently
(force: true) and with retry (up to ~3 min), so a manual registration step is
not needed and the endpoint may start before the Restate server
(apps/api/src/restate/register.ts). Registration succeeds only when Restate's discovery response contains every service
bound by this endpoint: meridianWorkflow, record, meridianScheduler,
meridianWorkflowAssist and meridianWorkflowTests. During a rolling update,
the shared endpoint address can still reach an older pod; an HTTP success with
missing services logs enregistrement incomplet (including missing) and is
retried within the same budget. Creating or editing a workflow never requires
re-registration. See
Restate integration
and Why durable execution.
Run index (run store)
Read by the proxy.
| Variable | Process(es) | Role | Default |
|---|---|---|---|
RUN_DB_URL |
proxy | Backend for the persistent run index and the credentials. sqlite:<path> (local / single node) or postgres://… / postgresql://… (deployment / multiple proxy replicas). An unrecognised prefix throws. |
sqlite:~/.meridian/runs.sqlite |
RUN_SETTLE_INTERVAL_MS |
proxy | Period, in milliseconds, of the settlement pass: the proxy reads how the invocation of each live run of the index ended in Restate, and freezes the runs of its Restate that ended — killed, or completed while nobody read them (see Run index — Final status). 0, or an integer from 1000 to 2147483647. 0 disables the pass: a killed run is then frozen only when its last state is suspended or waiting and its detail is read, a decision is sent for it or its wait is resumed; a run killed while running is never frozen. |
60000 |
DEFINITION_STORE_URL |
endpoint, proxy | Required (postgres://…): the workflow/agent definition store; the same database holds the EAI exchanges and the workflow memory. Falls back to RUN_DB_URL when that one is Postgres — the tables are disjoint, one database is enough. Boot fails with an explicit message if neither is set. See Manage workflow storage. |
|
DEFINITION_SEED_DIR |
proxy | Directory of the host's system definitions, imported as published v1 when the store is empty (default: apps/api — it carries only agent-invoke.workflow.yaml). Shipped content (demos, business workflows) is seeded through the instance manifest's seed: field instead — see Instance manifest. |
|
DEFINITION_SEED_ALWAYS |
proxy | 1 or true re-publishes the seed directory at every boot (idempotent by content hash), so editing a YAML and restarting puts it live; 0 or false keeps the default. Development only — elsewhere it would overwrite definitions edited in the console. |
false |
The default path is under the home directory of the process user, outside the
repository, so set it explicitly (absolute path / mounted volume) in a
deployment. The index only lists the runs the proxy
started; the durable source of truth is Restate, so losing the index erases no
runs (apps/api/src/server/run-store.ts). The SQLite driver
(better-sqlite3) and the Postgres driver (pg) are imported lazily, so only
the selected one is loaded. See Run store,
Use a Postgres run index, and
Back up and restore.
Event contracts
Read once at boot by the proxy (apps/api/src/server/event-contracts.ts).
| Variable | Process(es) | Role | Default |
|---|---|---|---|
EVENT_CONTRACTS |
proxy | Gate of the declared-event contracts: off, observe or enforce. observe checks every event of a declared type at ingestion, records its issues (recent events, meridian.events.contract, a warning log) and lets it through; a simulation runs and returns the issues in its report (contract). enforce refuses a non-conforming event (400, rejected) and a non-conforming simulation (400), and sources and EAI bindings filter records on their effective require. off checks nothing. An unrecognised value stops the boot. |
observe |
The check never modifies the event, and it runs before deduplication, so a redelivered event is checked again. See Event ingestion API — Contract check.
Ports and inter-process URLs
| Variable | Process(es) | Role | Default |
|---|---|---|---|
PORT |
proxy, endpoint, ui | Listening port, an integer from 0 to 65535; 0 lets the system pick a free port. |
4000 (proxy) / 9080 (endpoint) / 3000 (ui) |
API_URL |
ui | Proxy base URL used by ehr-lab for server-side requests. | (deployment-specific) |
The endpoint's PORT also feeds the default RESTATE_ENDPOINT_URL
(apps/api/src/restate/server.ts, register.ts). See
Configure ports and adapters.
Logging
LOG_LEVEL, LOG_PRETTY and SERVICE_NAME are read by both proxy and endpoint via
apps/api/src/observability/logger.ts (pino); RESTATE_LOGGING by the endpoint's
configuration (readEndpointConfig, apps/api/src/restate/config.ts).
| Variable | Process(es) | Role | Default |
|---|---|---|---|
LOG_LEVEL |
proxy, endpoint | Pino level: trace, debug, info, warn, error. |
info |
LOG_PRETTY |
proxy, endpoint | 1 forces human-readable output; 0 forces JSON. |
Pretty when stdout is a TTY and NODE_ENV !== "production", JSON otherwise |
SERVICE_NAME |
proxy, endpoint | Service field stamped on log lines. Also set by each entry point via initLogger. |
meridian |
RESTATE_LOGGING |
endpoint | Level of the Restate SDK's own console lines ([restate]…): trace, debug, info, warn or error, in any case. Read by the SDK and by the endpoint's logger transport, which writes these lines as the SDK does (apps/api/src/restate/sdk-logger.ts). Another value stops the endpoint at startup, with the SDK's own error when it loads (TypeError: unknown name <value>). |
info |
Structured logs never contain patient payloads; a redaction list additionally
censors common secret fields (*.authorization, *.apiKey, *.token, …).
Observability (OpenTelemetry)
Read by both proxy and endpoint via apps/api/src/observability/otel.ts. All
OTel export is opt-in: with no OTLP endpoint set, the SDK is not started and
the metric instruments are zero-cost no-ops.
| Variable | Process(es) | Role | Default |
|---|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT |
proxy, endpoint | OTLP/HTTP collector endpoint (e.g. http://collector:4318). Presence enables traces + metrics + log export. |
(unset → export disabled) |
OTEL_SERVICE_NAME |
proxy, endpoint | Overrides the OTel service.name resource attribute. |
meridian-proxy / meridian-endpoint |
The OTel service.version resource attribute is taken from
npm_package_version (set by the package manager), defaulting to 0.0.0. When
JSON logging is active and an OTLP endpoint is configured, logs are also shipped
over OTLP. See
Enable observability and
Observability signals.
Shutdown
Read by both entry points (apps/api/src/server/api.ts,
apps/api/src/restate/server.ts) and applied by apps/api/src/shutdown.ts.
| Variable | Process(es) | Role | Default |
|---|---|---|---|
SHUTDOWN_TIMEOUT_MS |
proxy, endpoint | Maximum time between SIGINT/SIGTERM and exit, an integer number of milliseconds from 1 to 2147483647. The proxy stops its listener, inbound reception (event sources included) and stores; the endpoint stops its agent refresh and registration, and its HTTP/2 listener closes when the process exits. Each then flushes OpenTelemetry and exits with code 0; past this delay, or when the stop fails, it exits with code 1. | 10000 |
LLM providers
The shared low-level client (libs/llm-client/src/index.ts,
@meridian/llm-client) resolves a provider's base URL and API key from the
environment. It backs both the editor's workflow-generation assistant
(llmCompletion) and the agent runner (plugin @posos/llm). A provider is
considered configured only when its API key is present; the assistant throws if
called for an unconfigured provider, and an agent falls back to a mock runner
when no key is set.
| Variable | Process(es) | Role | Default |
|---|---|---|---|
ANTHROPIC_API_KEY |
proxy, endpoint | Anthropic API key. | (none) |
ANTHROPIC_BASE_URL |
proxy, endpoint | Anthropic base URL. | https://api.anthropic.com |
OPENAI_API_KEY |
proxy, endpoint | OpenAI API key. | (none) |
OPENAI_BASE_URL |
proxy, endpoint | OpenAI base URL. | https://api.openai.com/v1 |
GEMINI_API_KEY |
proxy, endpoint | Google Gemini API key (OpenAI-compatible endpoint). Falls back to GOOGLE_API_KEY. |
(none) |
GOOGLE_API_KEY |
proxy, endpoint | Fallback key for the gemini provider. |
(none) |
GEMINI_BASE_URL |
proxy, endpoint | Gemini base URL. | https://generativelanguage.googleapis.com/v1beta/openai |
MISTRAL_API_KEY |
proxy, endpoint | Mistral API key (OpenAI-compatible). | (none) |
MISTRAL_BASE_URL |
proxy, endpoint | Mistral base URL. | https://api.mistral.ai/v1 |
AZURE_OPENAI_API_KEY |
proxy, endpoint | Azure OpenAI API key. | (none) |
AZURE_OPENAI_BASE_URL |
proxy, endpoint | Azure OpenAI deployment URL (full URL of the deployment). | (empty) |
LOCAL_LLM_API_KEY |
proxy, endpoint | API key for a local OpenAI-compatible server (Ollama / vLLM / LM Studio). | local |
LOCAL_LLM_BASE_URL |
proxy, endpoint | Base URL of the local LLM server. | http://localhost:11434/v1 |
Workflow assistant
Read once at proxy boot (apps/api/src/server/config.ts) for the editor's AI
assistant endpoint (apps/api/src/server/routes/assist.ts).
| Variable | Process(es) | Role | Default |
|---|---|---|---|
ASSIST_PROVIDER |
proxy | Provider used by the workflow-generation assistant. | anthropic |
ASSIST_MODEL |
proxy | Model used by the assistant. | claude-sonnet-4-5 |
ASSIST_MAX_ATTEMPTS |
proxy | Proposals the model may make when validation fails, each receiving the previous proposal and its errors (1 to 5). | 4 |
ASSIST_MAX_TOKENS |
proxy | Output token limit of each assistant call (1024 to 128000). Unset: 16384 on Anthropic, no limit sent to OpenAI-compatible providers. Keep it under the model's maximum. | (unset) |
ASSIST_BUDGET_MS |
proxy | Time budget of one generation, in milliseconds (10000 to 600000). No new attempt starts with less than 20 s left, and each call's timeout is capped by the remaining budget. | 150000 |
See Author an agent and Use the AI assistant.
Bundled-adapter fallbacks
These are read by adapters shipped with the bundled plugins only when the
corresponding value is absent from the instance manifest's adapter config;
config.baseUrl (etc.) in the manifest takes precedence. They apply to whichever
process resolves the port (typically the endpoint for execution ports, the proxy
for terminology). See Bundled plugins.
| Variable | Process(es) | Role | Default |
|---|---|---|---|
FHIR_BASE_URL |
proxy, endpoint | Deprecated: base URL of the FHIR R4 server used by the @posos/fhir adapters and fhir-poll when no fhir-r4 connection resolves and no config.baseUrl is set; read with a warning. Declare a connection instead (Manage connections). |
(none) |
HERMES_BASE_URL |
proxy, endpoint | Deprecated: base URL of the SNOMED CT terminology server (Hermes) used by the @posos/snomed adapter when no hermes connection resolves and no config.baseUrl is set; read with a warning. Declare a connection instead (Configure terminology). |
(none) |
NOTIFY_WEBHOOK_URL |
proxy, endpoint | Deprecated: target URL of the @posos/notify webhook adapter bound without a connection and without config.url; read with a warning. Declare a connection of type notification-webhook instead (Send notifications). |
(none — error if neither is set) |
HERMES_LANGUAGE_REFSET_ID |
proxy, endpoint | Deprecated: language reference set id used by the @posos/snomed adapter to pick display terms when neither the hermes connection's languageRefsetId parameter nor config.languageRefsetId is set; read with a warning. |
(none — Hermes default display) |
See Connect a FHIR warehouse and Configure terminology.
Posos plugin (@posos/posos)
Read by the external Posos plugin client (external-plugins/posos/lib/client.ts)
in whichever process loads it.
| Variable | Process(es) | Role | Default |
|---|---|---|---|
POSOS_API_URL |
proxy, endpoint | Deprecated: Posos edge API base URL, read with a warning when no posos-api connection resolves. Used only together with POSOS_AUDIENCE. |
(none) |
POSOS_AUDIENCE |
proxy, endpoint | Deprecated: OAuth client ID (IAP audience), with POSOS_API_URL. |
(none) |
POSOS_REGION |
proxy, endpoint | Deprecated: fr-BE selects the Belgian client, anything else fr-FR; with POSOS_API_URL. |
fr-FR |
GOOGLE_APPLICATION_CREDENTIALS |
proxy, endpoint | Google service-account key file, read by google-auth-library for IAP auth (also honours Application Default Credentials / Workload Identity Federation). |
(none) |
Inbound connections
Read by the proxy at boot and applied when it checks a connection's
configuration (apps/api/src/server/inbound-connections.ts).
| Variable | Process(es) | Role | Default |
|---|---|---|---|
INBOUND_DIRECTORY_ROOT |
proxy | Directory under which the folder of a directory-transport inbound connection must sit (previous name EAI_DIRECTORY_ROOT, still read when the new one is unset); a connection outside it is refused with Le dossier doit se trouver sous INBOUND_DIRECTORY_ROOT. |
(unset — any absolute path is accepted) |
See Connecter un EAI.
Credentials
Read by the proxy and the endpoint at boot (apps/api/src/server/config.ts,
apps/api/src/restate/config.ts, cipher in apps/api/src/server/secret-cipher.ts). The
endpoint uses it to open the secrets of the store's connections, which the proxy serves
sealed; set the same key ring on both.
| Variable | Process(es) | Role | Default |
|---|---|---|---|
MERIDIAN_SECRET_KEYS |
proxy, endpoint | Key ring that encrypts the credential store at rest: kid:base64key[,kid:base64key…], each key 32 bytes (AES-256-GCM). The first key encrypts, every key decrypts. A malformed entry stops the boot; secrets stored in cleartext or under another key are re-encrypted with the first key at boot. |
(unset — secrets stored in cleartext, with a warning at boot; a store that already holds encrypted secrets refuses to open) |
See Manage credentials.
Maintenance scripts
Read by the scripts of apps/api/scripts/, run from a checkout of the repository
with pnpm --filter @meridian/api run <script>. A relative path given to a script
is read from the directory where the command is typed.
| Variable | Script | Role | Default |
|---|---|---|---|
API_URL |
routing:audit |
Proxy base URL of the instance to audit. | http://localhost:4000 |
DEFINITION_STORE_URL |
routing:audit, definitions:export, definitions:import |
Definition store (postgres://…). routing:audit reads the order of the active set from it in a read-only transaction; the definitions:* scripts read or write the definitions. |
(none — routing:audit then assumes the order of the slugs) |
RUN_DB_URL |
routing:audit |
Run index (sqlite:<path> or postgres://…), read in a read-only transaction for the 7-day volume per event type. |
(none — volume unknown) |
See Audit event routing and Manage workflow storage.
ehr-lab (mini-EHR)
Read server-side by the ehr-lab app (apps/ehr-lab/.env.example); none are
exposed to the browser. In development the localhost defaults apply; on a remote
host they become required and must be injected through the service environment.
| Variable | Process(es) | Role | Default |
|---|---|---|---|
FHIR_BASE_URL |
ui | FHIR warehouse (Blaze) — the app's sole datastore (records, directory, messaging, audit, documents). | http://localhost:8090/fhir (dev) |
NODE_ENV |
ui, proxy, endpoint | Standard Node environment; affects the logger's pretty/JSON default and the ehr-lab runtime. | (unset) |
GOOGLE_APPLICATION_CREDENTIALS |
ui | Google service-account key (JSON) enabling Posos autocompletion, MedicalDB (BIM) dosage suggestions, Scan&Go partner-connect auth, and Google FHIR warehouse access. | (none) |
POSOS_API_URL |
ui | Posos edge API base URL (autocomplete + bim-v2 GraphQL). |
https://api.preprod.posos.co |
POSOS_AUDIENCE |
ui | IAP audience; gates drug autocompletion and BIM dosage suggestions (labelled demo mode when absent); shared fallback for SCANGO_AUDIENCE. |
(preprod) |
SCANGO_BASE |
ui | Scan&Go partner-connect base URL. | https://partner-connect.preprod.posos.co |
SCANGO_COMPLETE_ORIGIN |
ui | Expected postMessage origin for Scan&Go completion. |
https://scan-complete.preprod.posos.co |
SCANGO_AUDIENCE |
ui | IAP audience for Scan&Go. | POSOS_AUDIENCE |
SCANGO_FACILITY_SLUG |
ui | Target fhirStore in the Google warehouse. |
hopital-demo |
SCANGO_FHIR_BASE |
ui | Google Healthcare fhirStores base URL. |
(none) |
SCANGO_CREDENTIALS |
ui | Service-account key file for Scan&Go. | GOOGLE_APPLICATION_CREDENTIALS |
hospital-sim (simulator)
Read by the simulator (apps/hospital-sim/.env.example), which loads its own .env then the
repository-root one. Everything else (arrival rates, tempo, pharmacy, bus routes, faults, the
Meridian mode) is simulation configuration, edited in its dashboard and stored in its data
directory.
| Variable | Process(es) | Role | Default |
|---|---|---|---|
FHIR_BASE_URL |
hospital-sim | FHIR warehouse shared with ehr-lab (Blaze). | http://localhost:8090/fhir |
EHR_LAB_URL |
hospital-sim | ehr-lab base URL, driven by the emulated caregivers. | http://localhost:3200 |
MERIDIAN_API_URL |
hospital-sim | Platform proxy: EAI connection provisioning in hl7 mode, double-trigger detection. |
http://localhost:4000 |
POSOS_API_URL, POSOS_AUDIENCE, GOOGLE_APPLICATION_CREDENTIALS |
hospital-sim | Posos BIM, used for on-demand lookups of drug codes unknown to the pharmacy formulary (the generated formulary is always loaded); without POSOS_AUDIENCE, unknown codes are looked up in the demo set. POSOS_REGION is not read by the simulator. |
(as for ehr-lab) |
SIM_PORT |
hospital-sim | Dashboard and control API port. | 3300 |
SIM_BIND_HOST |
hospital-sim | Bind address of the dashboard and control API. | 127.0.0.1 |
SIM_MLLP_BIND_HOST |
hospital-sim | Bind address of the internal MLLP listeners (EAI channels, DPI, PUI, SIL), independent of SIM_BIND_HOST; empty means 127.0.0.1. |
127.0.0.1 |
SIM_DATA_DIR |
hospital-sim | Directory of the SQLite stores. | apps/hospital-sim/.data |
SIM_MLLP_PORT_BASE |
hospital-sim | First MLLP port (EAI channels base…base+3, listeners base+6…base+8). | 2575 |
SIM_ALLOW_FHIR_PURGE |
hospital-sim | false, 0 or no refuses a reset with FHIR purge (403); a reset without purge still works. The purge script still counts and refuses --yes unless --ignore-guard is given. Set to false on staging, where the warehouse is shared with ehr-lab and Meridian. |
(purge allowed) |
SIM_CONTROL_TOKEN |
hospital-sim | Bearer token required for state-changing routes from non-loopback clients. | (none) |
SIM_ALLOWED_HOSTS |
hospital-sim | Comma-separated host names accepted in the Host header of state-changing requests, besides loopback names, IP literals, SIM_BIND_HOST and the machine name (cross-site and DNS-rebinding protection). |
(none) |
SIM_TRUSTED_PEERS |
hospital-sim | Comma-separated CIDR blocks (or addresses, IPv4/IPv6) whose state-changing requests are treated like loopback ones; Host, Origin and JSON checks still apply. Set by docker-compose.yml to the Docker private ranges so the host's dashboard can write (the port is published on 127.0.0.1 only). An unreadable value stops the launch. |
(none); compose: 172.16.0.0/12,192.168.0.0/16,10.0.0.0/8 |
The ehr-lab app does not talk to the proxy directly: clinical validations pass
through the FHIR warehouse (a Task), and the two apps share only Blaze
(FHIR_BASE_URL). See
Connect a FHIR warehouse,
Scan&Go / FHIR mapping (apps/ehr-lab/docs/resources/reference/fhir-mapping.md), and
Set the instance locale.
Related references
- Instance manifest — non-secret, version-controlled configuration.
- Topology — how proxy, endpoint, Restate, and datastores fit together.
- Run store — the persistent run index selected by
RUN_DB_URL. - Observability signals — what the OTel exporters emit.
- Security posture — secrets vs. version-controlled config.