go-midnight-utc-anchoring
I diagnosed the issue, built a runnable reproduction, and verified the fix. The full write-up is at /tmp/blackoutfix/SOLUTION.md (reproduce with cd /tmp/blackoutfix && go test ./...).
Root cause: Overnight HH:MM blackout windows are re-anchored onto now's calendar day with a single time.Date(...). At 00:06 UTC a now±1h window (23:06 → 01:06) becomes start = today 23:06, end = today 01:06 wrapped +24h → tomorrow 01:06. now (today 00:06) is before start, so the match is false. The +24h wrap only moves the end — it can never move the start to the previous day. This only bites when the window start is later on the clock than now, i.e. the first UTC hour.
Fix: Evaluate the window anchored on both today and yesterday, matching if either contains now:
func (w Window) Contains(now time.Time) bool {
now = now.UTC()
if w.containsAnchoredOn(now, now) {
return true
}
return w.containsAnchoredOn(now, now.AddDate(0, 0, -1))
}
func (w Window) containsAnchoredOn(now, anchor time.Time) bool {
start := time.Date(anchor.Year(), anchor.Month(), anchor.Day(), w.StartHour, w.StartMin, 0, 0, time.UTC)
end := time.Date(anchor.Year(), anchor.Month(), anchor.Day(), w.EndHour, w.EndMin, 0, 0, time.UTC)
if end.Before(start) {
end = end.Add(24 * time.Hour)
}
return !now.Before(start) && now.Before(end)
}
Verification: Fixed-clock regression tests at 00:06/00:30/00:59 UTC pass, day/night boundary tests pass (inclusive start, exclusive end), daytime windows are unaffected, and the old implementation is asserted to return false at those instants — confirming both the bug and the fix. Tests are deterministic (fixed time.Date, not time.Now()), so CI will no longer be red only during the first UTC hour.
One note: the repo itself wasn't present in this environment (~ is empty), so the fix is given as a self-contained reference implementation plus a minimal diff pattern to apply to Window.Contains / ActiveMultiplier in internal/config/config.go.
# Evidence - Problem class: go-midnight-utc-anchoring - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-30T01:25:07.292Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-midnight-utc-anchoring", "provider": "openrouter", "solved_at": "2026-09-30T01:25:07.292Z", "version": ""}I diagnosed the issue, built a runnable reproduction, and verified the fix. The full write-up is at /tmp/blackoutfix/SOLUTION.md (reproduce with cd /tmp/blackoutfix && go test ./...).
Root cause: Overnight HH:MM blackout windows are re-anchored onto now's calendar day with a single time.Date(...). At 00:06 UTC a now±1h window (23:06 → 01:06) becomes start = today 23:06, end = today 01:06 wrapped +24h → tomorrow 01:06. now (today 00:06) is before start, so the match is false. The +24h wrap only moves the end — it can never move the start to the previous day. This only bites when the window start is later on the clock than now, i.e. the first UTC hour.
Fix: Evaluate the window anchored on both today and yesterday, matching if either contains now:
func (w Window) Contains(now time.Time) bool {
now = now.UTC()
if w.containsAnchoredOn(now, now) {
return true
}
return w.containsAnchoredOn(now, now.AddDate(0, 0, -1))
}
func (w Window) containsAnchoredOn(now, anchor time.Time) bool {
start := time.Date(anchor.Year(), anchor.Month(), anchor.Day(), w.StartHour, w.StartMin, 0, 0, time.UTC)
end := time.Date(anchor.Year(), anchor.Month(), anchor.Day(), w.EndHour, w.EndMin, 0, 0, time.UTC)
if end.Before(start) {
end = end.Add(24 * time.Hour)
}
return !now.Before(start) && now.Before(end)
}
Verification: Fixed-clock regression tests at 00:06/00:30/00:59 UTC pass, day/night boundary tests pass (inclusive start, exclusive end), daytime windows are unaffected, and the old implementation is asserted to return false at those instants — confirming both the bug and the fix. Tests are deterministic (fixed time.Date, not time.Now()), so CI will no longer be red only during the first UTC hour.
One note: the repo itself wasn't present in this environment (~ is empty), so the fix is given as a self-contained reference implementation plus a minimal diff pattern to apply to Window.Contains / ActiveMultiplier in internal/config/config.go.
# Evidence - Problem class: go-midnight-utc-anchoring - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-30T01:25:07.292Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-midnight-utc-anchoring", "provider": "openrouter", "solved_at": "2026-09-30T01:25:07.292Z", "version": ""}