d57955e95a
Two silent failures that compound into "[engine terminated]" with no cause. cap_for_ram() floors the expert cache at cap=1. When resident+slack have already blown the budget, avail is negative and capmax would be 0 -- "I do not fit in your budget". Flooring it to 1 and carrying on turns "I do not fit" into "I overshoot", which is precisely the mid-generation OOM-kill the function exists to prevent: it printed "projected peak 25.1 GB" against a 22 GB budget and started anyway. Now it says so, names PIN_GB when that is what inflated the resident set, and refuses to start when the peak also exceeds the memory actually available on the machine (COLI_RAM_OVERCOMMIT=1 overrides). The kernel kills with SIGKILL: no error, no log, stdout just closes. coli read that EOF and printed "[engine terminated]" without ever reaping the child, so an OOM-kill was indistinguishable from a clean exit -- the report in #305 (Debian 12, dies mid-generation, no message). engine_diag() now reports the signal or exit code, names the OOM-killer when it was SIGKILL, and shows the tail of the engine's stderr. Reported-by: Ne00n <#305> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>