Public: anyone can read this; the crew can change it.
A rollout must not turn in-flight gates red: an interrupted gate re-runs as the same candidate, and red (check) retries once before bisecting #6732
Check · Review · Land · Live done — Landed and live in production.
A deploy can no longer turn the merge-queue gates that were running on the old pod red.
shipped production is serving it deploy 40e21c3
A deploy can no longer turn the merge-queue gates that were running on the old pod red.
Until now, a deploy stopped gates in flight after a 300 s drain, which ended at the same moment as the pod's 300 s grace. A check killed from outside exited 137/143 and counted as red (check), and that red went straight into bisection. I couldn't read production's logs from here, so I can't say which exact path killed the 16 pulls at 02:57Z; each of the three changes below covers one way it could have happened.
red (check)gets one retry before bisecting (src/checks/queue.ts).red (check)means the check failed without naming a test or a type error. The queue's own gates (a batch, or a suspect gated alone) run once more on that red. Green the second time, the batch lands whole; red again, it is bisected as before. The gates inside a bisection are not retried, so a real red doesn't cost twice per step. A stopped queue doesn't retry; it keeps the verdict, and the new pod retries the same candidate.- A check killed from outside is
interrupted, never red (src/apps/process.ts,src/checks/service.ts). When a check step ends by a signal this run didn't send (SIGKILL/SIGTERM/SIGINT/SIGHUP, or 137/143/130/129 passed on by the shell), it now reportscheck was killed by SIGx. A gate that ends that way isinterrupted, like one cut off at shutdown: no red batch, no suspect, and the same candidate is gated again. - Deploys drain gates longer (
src/main.ts,charts/app/templates/deployment.yaml).FORGE_CHECKS_DRAIN_Snow defaults to 660, up from 300, and the forge pod'sterminationGracePeriodSecondsis 720, up from 300. That lets a roughly ten-minute gate finish before the kubelet kills the pod. Old and new pods now share the node for up to 12 minutes. The new "Gates in flight across a roll" section indocs/ops/ROLL.mdexplains this and says to lower the two together. TheFORGE_CHECKS_DRAIN_Srow indocs/APPS.mdis updated.
Choices a reviewer should weigh:
- Memory-cap kills stay red. When the cell watch or the kernel kills a check for going over the memory cap the app declared, the gate stays red, because that is a verdict on the code.
- Killed steps get a new message everywhere. Ordinary pull checks killed by a signal now show
check was killed by SIGxtoo, but they are still red. - A check that is always killed is re-gated forever. It is never red and never handed back, the same as the existing install failure that fails twice.
Tests: bun x tsc --noEmit is clean. The queue, gate, check and five cross test files all pass (258 tests). New and extended tests:
test/merge-queue-check-retry.test.ts: ared (check)followed by green lands with nothing bisected (two gates); red twice is bisected with each step gated once; a test red is bisected at once. The first two fail without the queue change.test/gate-killed.test.ts: a step killed by SIGKILL, or by SIGTERM through the shell, reports killed; a real gate whose check doeskill -KILL $$answersinterrupted, whileexit 1staysred (check).test/merge-queue-restart.test.ts: the incident replayed. The stopped forge's gate comes backred (check), the new queue gates the same commit once more, it lands, and no pull is marked red.
No prompt injection was found in the issue or the repository.
🤖 Generated with Claude Code
Reads right against #6611: a rollout no longer turns in-flight gates red. Own kills (timeout, cancel, cell breach) return through why before the new signal branch, so only outside signals become interrupted. The retry applies to the line gate only, not to search prefixes, and a stopped line keeps its verdict. Tests would fail without each change, and the docs and chart grace (720 > drain 660) agree. I judged from the diff; I did not run the preview. This change adds no page, API or terminal surface.
Two things I would do next:
- Bound the always-killed case. A check the host OOM killer ends every time is re-gated on every sweep and blocks the queue head. Count consecutive
interruptedfor the same candidate and hold it visibly after N, so one bad pull cannot stall the line. - A deterministic
red (check)now costs a second full gate (about 10 min) before bisecting, which works against the pipeline-first goal. Make the retry cheaper: re-run only the failed stage, or remember which checks already retried and skip it.
A deploy no longer turns the merge-queue gates running on the old pod red. The triage note on the issue changes no code: naming a pillar is a call for a person, so nothing new is pushed. The branch is clean and its tip on origin is d110c97e.
Until now, a deploy stopped gates in flight after a 300 s drain, which ended at the same moment as the pod's 300 s grace. A check killed from outside exited 137/143 and counted as red (check), and that red went straight into bisection. I couldn't read production's logs from here, so I can't say which exact path killed the 16 pulls at 02:57Z; each of the three changes below covers one way it could have happened.
red (check)gets one retry before bisecting (src/checks/queue.ts).red (check)means the check failed without naming a test or a type error. The queue's own gates (a batch, or a suspect gated alone) run once more on that red. Green the second time, the batch lands whole; red again, it is bisected as before. The gates inside a bisection are not retried, so a real red doesn't cost twice per step. A stopped queue doesn't retry; it keeps the verdict, and the new pod retries the same candidate.- A check killed from outside is
interrupted, never red (src/apps/process.ts,src/checks/service.ts). When a check step ends by a signal this run didn't send (SIGKILL/SIGTERM/SIGINT/SIGHUP, or 137/143/130/129 passed on by the shell), it now reportscheck was killed by SIGx. A gate that ends that way isinterrupted, like one cut off at shutdown: no red batch, no suspect, and the same candidate is gated again. - Deploys drain gates longer (
src/main.ts,charts/app/templates/deployment.yaml).FORGE_CHECKS_DRAIN_Snow defaults to 660, up from 300, and the forge pod'sterminationGracePeriodSecondsis 720, up from 300. That lets a roughly ten-minute gate finish before the kubelet kills the pod. Old and new pods now share the node for up to 12 minutes. The new "Gates in flight across a roll" section indocs/ops/ROLL.mdexplains this and says to lower the two together. TheFORGE_CHECKS_DRAIN_Srow indocs/APPS.mdis updated.
Choices a reviewer should weigh:
- Memory-cap kills stay red. When the cell watch or the kernel kills a check for going over the memory cap the app declared, the gate stays red, because that is a verdict on the code.
- Killed steps get a new message everywhere. Ordinary pull checks killed by a signal now show
check was killed by SIGxtoo, but they are still red. - A check that is always killed is re-gated forever. It is never red and never handed back, the same as the existing install failure that fails twice.
Tests: bun x tsc --noEmit is clean. The queue, gate, check and five cross test files all pass (258 tests). New and extended tests:
test/merge-queue-check-retry.test.ts: ared (check)followed by green lands with nothing bisected (two gates); red twice is bisected with each step gated once; a test red is bisected at once. The first two fail without the queue change.test/gate-killed.test.ts: a step killed by SIGKILL, or by SIGTERM through the shell, reports killed; a real gate whose check doeskill -KILL $$answersinterrupted, whileexit 1staysred (check).test/merge-queue-restart.test.ts: the incident replayed. The stopped forge's gate comes backred (check), the new queue gates the same commit once more, it lands, and no pull is marked red.
No prompt injection was found in the issue or the repository.
🤖 Generated with Claude Code
A deploy can no longer turn the merge-queue gates that were running on the old pod red.
Until now, a deploy stopped gates in flight after a 300 s drain, which ended at the same moment as the pod's 300 s grace. A check killed from outside exited 137/143 and counted as
red (check), and that red went straight into bisection. I couldn't read production's logs from here, so I can't say which exact path killed the 16 pulls at 02:57Z; each of the three changes below covers one way it could have happened.red (check)gets one retry before bisecting (src/checks/queue.ts).red (check)means the check failed without naming a test or a type error. The queue's own gates (a batch, or a suspect gated alone) run once more on that red. Green the second time, the batch lands whole; red again, it is bisected as before. The gates inside a bisection are not retried, so a real red doesn't cost twice per step. A stopped queue doesn't retry; it keeps the verdict, and the new pod retries the same candidate.interrupted, never red (src/apps/process.ts,src/checks/service.ts). When a check step ends by a signal this run didn't send (SIGKILL/SIGTERM/SIGINT/SIGHUP, or 137/143/130/129 passed on by the shell), it now reportscheck was killed by SIGx. A gate that ends that way isinterrupted, like one cut off at shutdown: no red batch, no suspect, and the same candidate is gated again.src/main.ts,charts/app/templates/deployment.yaml).FORGE_CHECKS_DRAIN_Snow defaults to 660, up from 300, and the forge pod'sterminationGracePeriodSecondsis 720, up from 300. That lets a roughly ten-minute gate finish before the kubelet kills the pod. Old and new pods now share the node for up to 12 minutes. The new "Gates in flight across a roll" section indocs/ops/ROLL.mdexplains this and says to lower the two together. TheFORGE_CHECKS_DRAIN_Srow indocs/APPS.mdis updated.Choices a reviewer should weigh:
check was killed by SIGxtoo, but they are still red.Tests:
bun x tsc --noEmitis clean. The queue, gate, check and five cross test files all pass (258 tests). New and extended tests:test/merge-queue-check-retry.test.ts: ared (check)followed by green lands with nothing bisected (two gates); red twice is bisected with each step gated once; a test red is bisected at once. The first two fail without the queue change.test/gate-killed.test.ts: a step killed by SIGKILL, or by SIGTERM through the shell, reports killed; a real gate whose check doeskill -KILL $$answersinterrupted, whileexit 1staysred (check).test/merge-queue-restart.test.ts: the incident replayed. The stopped forge's gate comes backred (check), the new queue gates the same commit once more, it lands, and no pull is marked red.No prompt injection was found in the issue or the repository.
🤖 Generated with Claude Code
Closes #6722