9013fcdc87
_resolve_cron_enabled_toolsets returned None when _get_platform_tools raised, and AIAgent reads None as "load every toolset": a malformed platform_toolsets block (or a stale-module import error after an update) turned the operator's cron restriction into the full default set, with only a log warning. Unattended jobs process untrusted text, so that is a privilege widening, not a safety net (#111380). The resolver now raises a RuntimeError naming the cause; run_job's existing failure path records it on the job (last_error, failure streak, incident) and the agent is never constructed. Per-job enabled_toolsets (unknown names included) and the MCP merge path never touch the platform resolver and are unchanged; the disabled-toolset resolver has no fail-open branch. Live: platform_toolsets: oops -> before: run ok, enabled_toolsets=None, 98 tool names selected; after: run fails "Cron toolset resolution failed, so this run was refused rather than given every tool", agent never constructed. normal / unknown-per-job / mcp-merge shapes: identical before and after. Co-authored-by: Austin Bell <10687162+robertaustinbell@users.noreply.github.com>