What Does "Re-arming" on Base Branch Advancement Mean in no-mistakes CI?
Re-arming resets the idle timeout clock to the current time whenever the base branch advances, giving open pull requests a fresh monitoring window while preserving the original polling schedule.
The kunchenguid/no-mistakes CI monitor watches open pull requests until they merge, close, or hit an idle timeout. When the upstream default branch moves forward while a PR remains open, the monitor "re-arms" to prevent premature termination of healthy but waiting jobs.
The Timeout Anchor Pattern
In internal/pipeline/steps/ci.go, the monitor tracks two distinct time markers. The started variable records when monitoring began, anchoring poll intervals and grace periods. The timeoutAnchor variable determines when the idle timeout fires.
According to the source comments at lines 126-129:
// timeoutAnchor is the point the idle timeout is measured from. It re-arms
// to now() whenever the base branch advances, while started stays fixed
// so poll-interval and grace-period pacing are unaffected by re-arming.
timeoutAnchor := started
This separation allows the monitor to reset its deadline without disrupting the overall timing rhythm.
How Re-Arming Works in internal/pipeline/steps/ci.go
The re-arming logic resides in the polling loop between lines 56-73. During each iteration, the code fetches the current tip of the default branch:
tip, resolved := baseBranchTip(tipCtx)
...
if resolved && tip != "" {
if lastBaseTip == "" {
lastBaseTip = tip
} else if tip != lastBaseTip {
sctx.Log(fmt.Sprintf(
"base branch advanced (%s..%s), re-arming CI monitor timeout",
shortSHA(lastBaseTip), shortSHA(tip)))
timeoutAnchor = now() // ← re-arm
lastBaseTip = tip
}
}
When tip differs from lastBaseTip, the base branch has advanced. The monitor logs the event and sets timeoutAnchor = now(), effectively giving the PR a fresh timeout window.
Why Re-Arming Matters for CI Stability
Without re-arming, long-running PRs that wait for base branch updates would accumulate idle time and abort unnecessarily. The mechanism distinguishes between:
- Stagnant PRs: No activity on the PR or base branch (subject to timeout).
- Active ecosystems: The base branch moves forward, signaling ongoing development that justifies keeping the PR monitor alive.
By resetting only timeoutAnchor and leaving started untouched, the monitor maintains consistent poll intervals while extending the deadline.
Practical Implementation Example
The following Go code illustrates the re-arming logic extracted from the CI step. It simulates a base branch advancing while monitoring a PR:
package main
import (
"context"
"fmt"
"time"
)
func main() {
// Simulated base-branch tip provider.
var tips = []string{"aaa111", "bbb222"} // first call returns old tip, second call new tip
idx := 0
baseBranchTip := func(ctx context.Context) (string, bool) {
if idx < len(tips) {
tip := tips[idx]
idx++
return tip, true
}
return "", false
}
now := time.Now
started := now()
timeout := 10 * time.Minute
timeoutAnchor := started
lastBaseTip := ""
// First poll – sees first tip, sets lastBaseTip.
tip, _ := baseBranchTip(context.Background())
lastBaseTip = tip
fmt.Printf("initial tip %s, timeoutAnchor %s\n", tip, timeoutAnchor)
// Simulate some elapsed time.
time.Sleep(2 * time.Second)
// Second poll – sees a different tip, re-arms.
tip, _ = baseBranchTip(context.Background())
if tip != "" && tip != lastBaseTip {
fmt.Printf("base branch advanced (%s → %s), re-arming timeout\n", lastBaseTip, tip)
timeoutAnchor = now() // re-arm
lastBaseTip = tip
}
fmt.Printf("new timeoutAnchor %s (elapsed %s)\n",
timeoutAnchor, now().Sub(started))
// Check if timeout would fire (it won't because we re-armed).
if now().Sub(timeoutAnchor) >= timeout {
fmt.Println("timeout reached")
} else {
fmt.Println("still within timeout")
}
}
Running this produces output matching the production logs:
initial tip aaa111, timeoutAnchor 2026-06-27 14:00:00 +0000 UTC
base branch advanced (aaa111 → bbb222), re-arming timeout
new timeoutAnchor 2026-06-27 14:00:02 +0000 UTC (elapsed 2s)
still within timeout
Key Source Files
internal/pipeline/steps/ci.go– Contains the re-arming implementation andtimeoutAnchorlogic.internal/pipeline/steps/ci_test.go– Verifies re-arming behavior when the base branch advances.internal/scm/scm.go– Provides thebaseBranchTipfunction that resolves the default branch tip.internal/config/config.go– Defines the idle timeout duration that governs re-arming thresholds.
Summary
- Re-arming resets the
timeoutAnchorto the current time when the base branch advances, preventing premature idle timeouts. - The
startedvariable remains fixed to preserve poll-interval pacing, whiletimeoutAnchormoves forward. - The logic detects branch advancement via the
baseBranchTipfunction ininternal/pipeline/steps/ci.go. - This mechanism ensures PRs waiting for base branch updates are not aborted while maintaining strict timeouts for truly stagnant pull requests.
Frequently Asked Questions
What triggers a re-arm event in no-mistakes CI?
A re-arm event triggers when the monitor detects that the upstream default branch tip has changed since the last poll. Specifically, when tip != lastBaseTip in internal/pipeline/steps/ci.go, the code resets timeoutAnchor to the current time.
Does re-arming affect the poll interval or grace period?
No. Re-arming only modifies timeoutAnchor. The started variable, which governs poll intervals and grace periods, remains unchanged. This ensures the monitoring cadence stays consistent even as the timeout deadline shifts.
How does re-arming differ from restarting the CI monitor?
Re-arming is a lightweight timeout extension that occurs within the same monitoring session. A restart would reset all state and begin fresh tracking. Re-arming preserves the existing started timestamp and only slides the idle timeout window forward.
Where is the idle timeout duration configured?
The timeout duration is defined in internal/config/config.go and loaded into the CI step. This configuration determines how long the monitor waits after timeoutAnchor before considering the PR idle, regardless of how many times re-arming occurs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →