fix(app-config): refuse an LLM ceiling that would become a zero timeout

LLM_TIMEOUT_MS was validated as "a positive number", which lets two shapes
through that then degrade into an immediate abort rather than a long one.
A fractional value passes the check and floors to 0 in derive, which makes
the dispatcher fall back to undici's default and setTimeout(abort, 0) kill
every model call on the next tick. Anything past 2^31-1 does the same,
because Node clamps the delay to 1 ms. Both now refuse at boot, which is
what the wiki row already promised.

Also pins the seam the three deleted constants used to occupy: the clients'
abort deadline has to come from the configured ceiling. Nothing else in the
suite would have noticed a literal coming back.
This commit is contained in:
Maurice
2026-09-04 18:48:48 +02:00
committed by Maurice
parent 798859517f
commit c1d0435480
3 changed files with 50 additions and 1 deletions
+5 -1
View File
@@ -112,7 +112,11 @@ export const envSchema = z.object({
// non-http(s) entries today — left unvalidated to keep that behavior.
OVERPASS_URL: anyString,
OVERPASS_TIMEOUT_MS: positiveNumber,
LLM_TIMEOUT_MS: positiveNumber,
// Whole milliseconds, and inside setTimeout's 32-bit range. A fractional value
// would floor to 0 and abort every model call on the next tick; anything past
// 2^31-1 makes Node clamp the delay to 1 ms and do the same. Both refuse at
// boot rather than degrading into a timeout of zero.
LLM_TIMEOUT_MS: integer(1, 2_147_483_647, 'must be a whole number of milliseconds between 1 and 2147483647'),
KITINERARY_EXTRACTOR_PATH: anyString,
// The OS search path. Not configuration anybody sets for TREK — it is here so
// the kitinerary probe can resolve its binary to an absolute path itself