fix(ai): park a Codex sign-in the issuer refused until the next sign-in

A dead refresh token was asked again on every hop of every run: the
proactive refresh failed and was swallowed, the request 401'd, the on-401
refresh failed again, and the nightly warm repeated that for the briefing
and every card. A refusal that proves the grant dead now flips the
connection to the existing expired state (compare-and-set on the refused
token, one signal per transition), so the chain, the presence probe and
the AI capabilities stop counting it. A new device-code sign-in clears the
refused credential's ledger rows so the fresh one resumes in place.
This commit is contained in:
Marc-André Bombeck committed 2026-10-20 20:04:21 +02:00
1 parent 5502342ec5
commit 07d70cd275
6 files changed
+437 -11

No files matched your search

@@ -9,6 +9,7 @@ import { auditLog } from "@/lib/auth/audit";
import { getClientIp, apiSuccess, apiError } from "@/lib/api-response";
import { annotate } from "@/lib/logging/context";
import { INSIGHTS_CACHE_CLEARED } from "@/lib/insights/cached-text-cipher";
import { forgetProviderHealth } from "@/lib/ai/provider-health-ledger";
/**
* v1.4.7.1: Device-code flow polling endpoint.
@@ -88,6 +89,9 @@ export const POST = apiHandler(async (request: NextRequest) => {
});
cookieStore.delete("codex_device");
// A new sign-in: whatever the ledger held against the old one no longer
// describes this credential.
await forgetProviderHealth({ userId: user.id, providerType: "codex" });
await auditLog("codex.oauth.connected", {
userId: user.id,