Skip to content
11 changes: 8 additions & 3 deletions .github/scripts/keepalive_loop.js
Original file line number Diff line number Diff line change
Expand Up @@ -1129,8 +1129,13 @@ async function evaluateKeepaliveLoop({ github, context, core, payload: overrideP
runId: gateRun.runId,
core,
});
// forceRetry bypasses defer/wait for cancelled gates
if (forceRetry && tasksRemaining) {
// Rate limits are infrastructure noise, not code quality issues
// Proceed with work if Gate only failed due to rate limits
if (gateRateLimit && tasksRemaining) {
action = 'run';
reason = 'bypass-rate-limit-gate';
if (core) core.info('Gate cancelled due to rate limits only - proceeding with work (rate limits are not code quality issues)');

Copilot AI Jan 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change will cause existing tests to fail. The tests at lines 423-469 in keepalive-loop.test.js expect action='defer' and reason='gate-cancelled-rate-limit' when rate limit cancellations are detected. With this new code, when tasksRemaining is true, the action will be 'run' and reason will be 'bypass-rate-limit-gate' instead. The tests need to be updated to reflect this new behavior, or new tests should be added to verify the bypass logic works as intended.

Copilot uses AI. Check for mistakes.
Comment thread
stranske marked this conversation as resolved.
Outdated
} else if (forceRetry && tasksRemaining) {
action = 'run';
reason = 'force-retry-cancelled';
if (core) core.info(`Force retry enabled: bypassing cancelled gate (rate_limit=${gateRateLimit})`);
Comment on lines +1134 to 1141

Copilot AI Jan 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new rate limit bypass logic takes precedence over the forceRetry flag. When both gateRateLimit and forceRetry are true, this code will return action='run' with reason='bypass-rate-limit-gate' instead of reason='force-retry-cancelled'. This changes the behavior for existing test case at line 493-517 in keepalive-loop.test.js which expects reason='force-retry-cancelled' when forceRetry is enabled with a rate-limited cancellation.

Consider checking forceRetry first (swap the order of these two conditions) to preserve the existing forceRetry behavior and maintain backward compatibility with the existing test expectations.

Suggested change
if (gateRateLimit && tasksRemaining) {
action = 'run';
reason = 'bypass-rate-limit-gate';
if (core) core.info('Gate cancelled due to rate limits only - proceeding with work (rate limits are not code quality issues)');
} else if (forceRetry && tasksRemaining) {
action = 'run';
reason = 'force-retry-cancelled';
if (core) core.info(`Force retry enabled: bypassing cancelled gate (rate_limit=${gateRateLimit})`);
if (forceRetry && tasksRemaining) {
action = 'run';
reason = 'force-retry-cancelled';
if (core) core.info(`Force retry enabled: bypassing cancelled gate (rate_limit=${gateRateLimit})`);
} else if (gateRateLimit && tasksRemaining) {
action = 'run';
reason = 'bypass-rate-limit-gate';
if (core) core.info('Gate cancelled due to rate limits only - proceeding with work (rate limits are not code quality issues)');

Copilot uses AI. Check for mistakes.
Expand All @@ -1139,7 +1144,7 @@ async function evaluateKeepaliveLoop({ github, context, core, payload: overrideP
reason = gateRateLimit ? 'gate-cancelled-rate-limit' : 'gate-cancelled';
}
} else {
// Gate failed - check if we should route to fix mode or wait
// Gate failed - check if failure is rate-limit related vs code quality
const gateFailure = await classifyGateFailure({ github, context, pr, core });
if (gateFailure.shouldFixMode && gateNormalized === 'failure') {
action = 'fix';
Expand Down
Loading