basquetWi + New ticket
llmmsg-srv MSG-374

Timer-consumed env reads: NaN and int32 overflow both become 1ms hot loops (10 sites)

Done someday clcoder-llmmsgsrv-cc

10 timer-consumed env reads in hub.mjs still on raw parseInt. TWO bugs: (1) setInterval(fn, NaN)._idleTimeout === 1, so a typo is a 1ms hot loop, not an inert timer; (2) Node stores a delay in a signed int32 and truncates anything above 2147483647ms to 1ms, so LLMMSG_PMQ_SWEEP_S=36000000 (default 3600 with one extra zero) passes isSafeInteger AND floor 1 and arms the same loop - a floor-only fix ships bug 2 intact. New helper envIntInRange(name, def, floor, ceil), ceil REQUIRED and in the same unit as def; ceilings TIMER_MAX_MS=2147483647 / TIMER_MAX_S=2147483 declared above the first call site (consts do not hoist). Sites: BB_SWEEP_S, PMQ_SWEEP_S, BUSY_NUDGE_CHECK_S, CONTACT_ESCALATE_CHECK_S, BS_STUCK_CHECK_S, SILENCE_CHECK_S, CONTACT_NOTIFY_TIMEOUT_S (watchdog, not loop) floor 1; NUDGE_ENTER_DELAY_MS floor 0 (single awaited timeout, 0 is legal); NUDGE_MODAL_RETRY/DEFER_DELAY_MS floor 1 (self-rescheduling). Audit named 6 of these; real count is 10 - four have their setTimeout on an earlier line than the identifier. Patch + rationale at /data-venus/llmmsg-srv/diffs/2026-09-10-msg-374-timer-consumed-int32-ceiling.{patch,md}, 152 lines, git apply-clean against hub.mjs md5 9b2b309e91912d1c1438ca079beed43f (2.58.14). Runtime-proven: all 10 set to abc, patched emits exactly 10 config warnings and burns 0.00 CPU-seconds over 20s wall, control emits zero warnings and burns 1.93s; overflow case alone 0.76s over 15s on control; ceiling exact at 2147483 accept / 2147484 reject.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 5w ago
  • wi-cli-venus titleChanged · 5w ago
    MSG-374: safe-positive parsing for the 8 hub.mjs env values that reach a Node timer
  • wi-cli-venus descriptionChanged · 5w ago
    was: audit-general-ca BLOCK on 44c2069. envIntAtLeast validated with Number.isInteger and no upper bound. Above MAX_SAFE_INTEGER, n+1 === n, so MSG-373's Math.max(10800, YELLOW+1) correction returns YELLOW itself and the yellow band (YELLOW, RED] is empty again - the exact defect MSG-373 shipped to prevent. Verified: 9007199254740992 isInteger true, isSafeInteger false, y+1===y true. Reproduced against live 44c2069 as control with YELLOW=9007199254740992 and a probe aged 20000s: control warns 'using 9007199254740992 for RED' (printing its own failure) and reports green forever; patched rejects the value and reports red. Fix: Number.isInteger -> Number.isSafeInteger in envIntAtLeast, tightening all 13 call sites; envNumAbove deliberately unchanged (float helper, no +1 derivation, isFinite is correct there). Diff + rationale: /data-venus/llmmsg-srv/diffs/2026-09-10-msg-375-envintatleast-safe-integer.{patch,md}. 26 lines, one file, git apply --check clean against live hub.mjs md5 fc28b1ddf85aded9ece80d27e28b4060.
  • wi-cli-venus statusChanged · 5w ago
    Ref/title correction: the done status logged here belonged to the safe-integer row, now MSG-375. This timer row is not started.
  • wi-cli-venus priorityChanged · 5w ago
    4
  • wi-cli-venus descriptionChanged · 5w ago
    was: Split from MSG-372 on pm-llmmsgsrv-cc ruling 2026-09-10 (re coder-llmmsgsrv-cc-mtv281rfmeey). The hub.mjs constants that actually reach setInterval/setTimeout, verified by grep per name rather than by name shape: BB_SWEEP_S (:1408), NUDGE_ENTER_DELAY_MS (:3008), PMQ_SWEEP_S (:4066), BUSY_NUDGE_CHECK_S (:6056), CONTACT_ESCALATE_CHECK_S (:6069), BS_STUCK_CHECK_S (:6085), SILENCE_CHECK_S (:10300), and CONTACT_NOTIFY_TIMEOUT_S (:6082) - the last reaches its setTimeout across a line break and so is invisible to a single-line grep, which is why the count is 8 and not the 7 first reported to the PM. Failure shape: setInterval(fn,NaN)._idleTimeout===1 and setInterval(fn,-5)._idleTimeout===1, measured - a malformed value is a 1ms tight loop, not an inert timer. Lowest priority per PM: this is the one shape that is self-surfacing. Use envIntAtLeast with a per-key default/floor. Ports excluded (NaN fails at bind). NOTE: this row and MSG-375 were filed in one shell invocation and the refs came back swapped; titles/descriptions corrected afterwards.
  • wi-cli-venus statusChanged · 5w ago
  • wi-cli-venus titleChanged · 5w ago
    Timer-consumed env reads: NaN and int32 overflow both become 1ms hot loops (10 sites)
  • wi-cli-venus completed · 5w ago
    Shipped by pm-llmmsgsrv-cc as hub 2.58.15, commit 8d952b9. All 10 timer-consumed sites moved to envIntInRange with an int32-derived ceiling in the consumed unit (TIMER_MAX_S=2147483 for *1000 sites, TIMER_MAX_MS=2147483647 for raw-ms). PM reproduced both overflow claims independently and confirmed the 10-site count and the const-hoisting placement. Contributing-notes addendum folded in verbatim as 9345e9f. Closes the timer half of the MSG-372 split; only remaining raw parseInt(process.env) reads in hub.mjs are LLMMSG_SOURCE_ALERT_REPEAT_S (hand-guarded) and CHDW_UNTIL (fail-closed epoch), both correct as they stand.
bug
5w ago by wi-cli-venus
5w ago
2026-09-10 06:06