Skip to content

Stop raising a scheduled failure a later run recovered from (#127) - #128

Merged
iderex merged 1 commit into
mainfrom
work/af106-sweep-latest
Aug 22, 2026
Merged

Stop raising a scheduled failure a later run recovered from (#127)#128
iderex merged 1 commit into
mainfrom
work/af106-sweep-latest

Conversation

@iderex

@iderex iderex commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Closes #127.

Select took every ended scheduled run of a watched workflow on the default
branch that did not succeed, whether or not a later scheduled run of the same
workflow had succeeded since. A failure therefore stayed selectable for as long
as it sat inside the window github.go fetches, so the tracking issue for it
was raised again on the next sweep after somebody closed it, under the same
key. The loop ended when the evidence scrolled out rather than when anything
was repaired.

The change

Select now derives the newest scheduled run of each watched workflow on the
default branch that ended in success, and drops any failure at or below it. Run
numbers are per workflow and increase, so that is the line a failure has to be
newer than to still be worth raising.

A recovery has to be a scheduled run of the default branch, because that is the
population this reports on. A run somebody asked for has somebody in front of
it and clears nothing here, which is the same reason the existing filters give
for leaving such a run out.

The recovery cannot be outside the window while the failure is inside it: the
window holds the newest runs, and the recovery is the newer of the two.

Why this reading rather than another

Two sentences already in the tree say it, which is why this is a repair and not
a new policy. The raised body prints

`%s` runs on a schedule, and its last run on the default branch ended in %s.

and the comment on Recent gives the window its reason, "because the question
is whether the thing is failing now". Neither was what Select answered.

The guard, shown refusing

Run at 5c6d7b6056867c90d6304421faae08b31c3527fe with the two filter lines
deleted from Select and nothing else changed:

go test ./internal/sweep -count=1
--- FAIL: TestAFailureALaterScheduledRunRecoveredFromIsNotSelected (0.00s)
    sweep_test.go:194: a failure a later scheduled run recovered from is still selected, so closing its issue raises the same one again: [{Workflow:.github/workflows/nightly.yml Conclusion:failure Runs:[{Workflow:.github/workflows/nightly.yml Number:18 Event:schedule Status:completed Conclusion:failure Branch:main URL:https://example.com/run StartedAt:2026-08-10T05:17:00Z}]}]
FAIL
FAIL	flowfin.dev/hub/internal/sweep	1.340s
FAIL

Restored:

go test ./internal/sweep -count=1
ok  	flowfin.dev/hub/internal/sweep	1.505s

The same test also covers three near misses that must not be read as a
recovery, and each of them passes against the unpatched Select as well, so
none of them is what the new filter is carrying: a success older than the
failure, a success somebody asked for, and a success off the default branch.

The gate

Run at the head being pushed:

go run . gate
gate examined 14 of 14 legs.
  build                            passed
  test                             passed
  format                           passed
  editorconfig                     passed
  tests-reach-nothing              passed
  no-hardcoded-names               passed
  site-fetches-nothing-outside     passed
  site-links-resolve               passed
  coverage                         passed
  site-declares-its-language       passed
  install-address-is-answered      passed
  colour-stands-off-every-surface  passed
  page-matches-the-token-file      passed
  pr-hygiene                       passed

The means

Go, unchanged from the rest of this tree, in the package that already holds the
judgement being corrected. decisions/means.md is the argument, and this adds
no dependency: go.mod is byte-identical to origin/main.

git diff --stat origin/main...HEAD -- go.mod ; echo "exit=$?"
exit=0

What this does not do

It does not touch the sentence the raised body prints. That sentence says "its
last run", while a failure is still grouped with every other failing run in the
window that shares its verdict, so a workflow whose newest run was cancelled
and whose run before that failed still raises a body saying its last run failed.
That is a second topic and it is not repaired here.

It also changes nothing about a failure nothing has recovered from. Such a
failure is selected exactly as before, and the first assertion in the new test
is there so that a filter which quietly reported nothing at all could not pass.

No second reader saw this before it landed.

Select took every ended scheduled run on the default branch that did not
succeed, whether or not a later scheduled run of the same workflow had
succeeded since. A failure therefore stayed selectable for as long as it sat
inside the window github.go fetches, so the tracking issue for it was raised
again on the next sweep after somebody closed it, under the same key, and the
loop ended when the evidence scrolled out rather than when anything was
repaired. It happened on this board: #126 was raised against a failing run from
2026-08-21 after #120 was closed for it, and the newest scheduled run of that
workflow on the default branch had already succeeded.

Select now carries the newest scheduled run of each watched workflow that
reported the schedule working again, and drops any failure at or below it. That
is the sentence the raised body already prints, that its last run ended in the
verdict being reported, and the reason the comment on Recent gives for the
window, that the question is whether the thing is failing now.

The test is red without the filter and green with it, and it covers three near
misses that must not be read as a recovery: a success older than the failure, a
success somebody asked for rather than one the schedule reached, and a success
off the default branch.

Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
@iderex
iderex merged commit a716464 into main Aug 22, 2026
36 checks passed
@iderex
iderex deleted the work/af106-sweep-latest branch August 22, 2026 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stop raising a scheduled failure that a later run has already recovered from

1 participant