Three small gaps in how the process behaves at its edges:
- An unhandled rejection or uncaught exception crashed the process with
the stack on stderr only. index.ts now logs it to trek.log and runs the
same orderly shutdown a SIGTERM gets, exiting with 1; a second fatal
error during that shutdown exits at once.
- /api/health/ready kept answering 200 while a SIGTERM was draining the
process, so an orchestrator sent traffic for another probe period. A
shutdown now marks the new ReadinessService first (and Nest's own
shutdown hook marks it too), and the probe answers 503 from then on.
- Node closes an idle keep-alive connection after 5 seconds while reverse
proxies keep upstream connections for about a minute, which shows up as
intermittent 502s. The server now keeps them for 65 seconds, configurable
through HTTP_KEEP_ALIVE_TIMEOUT_MS (owned by the httpConfig token), with
the headers timeout one second above.
Eight registerAs tokens existed while every consumer read the same values
through readEnv() instead, so the boot-stable layer the repo rules describe
was unused and nothing said which path owned a variable. FORCE_HTTPS, for
instance, was frozen by the middleware through the http token and read live
by the cookie code at the same time.
A variable is now owned by exactly one side. TRUST_PROXY and
HSTS_INCLUDE_SUBDOMAINS belong to httpConfig, which buildApp() already
injects into the pre-init middleware, and TREK_PLACE_PHOTO_DIR to the new
storageConfig, which the storage registry now injects instead of reading it
through RuntimeEnvService. Their derive functions moved to boot-derive.ts,
which deriveAll() never calls. The six tokens nothing injected are gone:
their values are needed before the container exists (config.ts, the
database, src/mcp, the SSRF guard) and stay on readEnv().
config-ownership.test.ts records the keys each side reads through a Proxy
and fails on a variable read through both, on a token nothing injects and
on a variable the schema does not validate. env-reference.test.ts holds
server/.env.example to the schema, which had drifted by 34 variables (SMTP,
WebAuthn, plugins, MCP session tuning, TREK_MANAGED and others); they are
documented now. jwt-verify.ts no longer cites a middleware file that is
gone.