Three providers ran out of credit in two days (zai, deepseek, opencode) and
in every case the first signal was a failed subconscious pass. Balance
exhaustion is invisible until something dies; absence of complaint reads as
health.
Sends a real one-token completion rather than checking reachability -- GET
/models on opencode returns 200 with a valid key and a bankrupt workspace.
Classifies on wording, not status code: the same condition is 429 on zai,
402 on deepseek, 401 on opencode.
Exits non-zero only when a provider backing a live role (subconscious,
reflection, archivist) cannot answer, or a role names a model absent from
[models.*].
curl rather than urllib: opencode is behind Cloudflare, which answers
Python-urllib's user-agent with 403 code 1010 -- indistinguishable from a
rejected key.