`_classify_oauth_failure` joined the primary JSON-RPC error and the codex
stderr tail into one haystack and matched broad tokens ("unauthorized",
"401 unauthorized", "oauth"). codex writes independent ChatGPT plugin
prewarm failures ("HTTP 401 Unauthorized") to stderr while the core
JSON-RPC server keeps working, so any unrelated RPC error, timeout or
subprocess exit was rewritten into the `codex login` hint and the real
error plus stderr tail disappeared.
Classify by source: generic 401/unauthorized/oauth text is authoritative
only in the operation's own error; ambient stderr needs a strong
credential signal (invalid_grant, refresh/expired token, no auth profile).
Every call site (turn error, request timeout, dead subprocess, and the
compaction paths that share them) passes stderr by keyword.
Salvaged from #75182 by @cosin2077, hand-applied onto the refactored
session module (call sites collapsed into `_set_classified_error` /
`_request_for` / `_subprocess_died`).
Fixes#75167