Read + JSON-parse a config file WITHOUT applying schema defaults, so the caller can
still tell "the operator set this" from "the schema filled it in". The network resolver
needs that distinction (a defaulted web.port must not outrank an env var), and a bin
reads the file once and hands the result to both consumers.
A missing file is an honest error — a deployment that names a config file wants that
config, never a silent fallback to the bare defaults. A malformed file throws too.
Read + JSON-parse a config file WITHOUT applying schema defaults, so the caller can still tell "the operator set this" from "the schema filled it in". The network resolver needs that distinction (a defaulted
web.portmust not outrank an env var), and a bin reads the file once and hands the result to both consumers. A missing file is an honest error — a deployment that names a config file wants that config, never a silent fallback to the bare defaults. A malformed file throws too.