fix: recover Codex rotation auth failures

- mark Codex bearer/refresh failures as terminal auth-expired states

- sync refreshed session auth back to rotation slots and revive refreshed dead_auth slots

- stop paired arbiter retry loops when Codex accounts are unavailable

- add regression coverage for rotation leases, follow-up suppression, and arbiter closure
This commit is contained in:
ejclaw
2026-06-02 00:21:16 +09:00
parent 1ff6b3434f
commit 03d4c81192
21 changed files with 1082 additions and 52 deletions

View File

@@ -3,6 +3,7 @@ import {
resolveNextTurnAction,
shouldRetrySilentOwnerExecution,
} from './message-runtime-rules.js';
import { classifyCodexAuthError } from './agent-error-detection.js';
import { parseVisibleVerdict } from './paired-verdict.js';
import type { PairedRoomRole, PairedTaskStatus } from './types.js';
export {
@@ -17,6 +18,17 @@ export {
export type PairedFollowUpQueueAction = 'pending' | 'none';
function isSilentCodexAccountFailure(summary?: string | null): boolean {
if (!summary) return false;
if (classifyCodexAuthError(summary).category !== 'none') return true;
const lower = summary.toLowerCase();
return (
lower.includes('workspace out of credits') ||
lower.includes('out of credits') ||
/all\s+codex(?:\s+rotation)?\s+accounts/i.test(summary)
);
}
export function resolvePairedFollowUpQueueAction(args: {
completedRole: PairedRoomRole;
executionStatus: 'succeeded' | 'failed';
@@ -24,6 +36,15 @@ export function resolvePairedFollowUpQueueAction(args: {
taskStatus: PairedTaskStatus | null;
outputSummary?: string | null;
}): PairedFollowUpQueueAction {
if (
args.executionStatus === 'failed' &&
args.sawOutput === false &&
(args.completedRole === 'reviewer' || args.completedRole === 'arbiter') &&
isSilentCodexAccountFailure(args.outputSummary)
) {
return 'none';
}
if (
shouldRetrySilentOwnerExecution({
completedRole: args.completedRole,