From cbc8f4f7a880bf5741069eaf2e505b19c51ec80a Mon Sep 17 00:00:00 2001 From: dan-claude-bot Date: Mon, 20 Jul 2026 16:29:59 +0000 Subject: [PATCH] =?UTF-8?q?test(labels):=20pin=20the=20reverse=20direction?= =?UTF-8?q?=20=E2=80=94=20a=20run=20that=20finished=20after=20an=20in-flig?= =?UTF-8?q?ht=20entry=20settles=20the=20context?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The supersede fixtures pinned "an in-flight re-run is the newer word". Nothing pinned the converse: a run that FINISHED after an earlier in-flight entry is also the newer word, so the context is settled and reads SUCCESS rather than staying PENDING. That is the assertion that catches an over-correction — widening "an undateable entry sorts last" into "an in-flight entry always wins". Verified it fails under exactly that mutation and that nothing else in the suite does. Also corrects the comment above the undateable fixture: that case is guarded by the sort tiebreak, not by the dating expression, so the two changes are now separately pinned. Reverting only the dating expression fails 2 fixtures (the two zero-sentinel ones), not 3. 48 -> 49. Reconciler unchanged. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 6 ++++-- test/labels-reconcile.sh | 10 +++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19980be..f2654c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -126,8 +126,10 @@ which records not just what changed but what each drill run proved. only **clears** it the moment the PR stops being mergeable-by-a-human, which is precisely the staleness that made `needs-human` untrustworthy. Both live shapes, the mixed round, the whole check-outcome enum, and the in-flight - re-run superseding both a green and a cancelled predecessor are pinned in - `test/labels-reconcile.sh` (19 fixtures → 48). + re-run superseding both a green and a cancelled predecessor — in both + directions, since a run that *finished* after an earlier in-flight entry + settles the context — are pinned in `test/labels-reconcile.sh` + (19 fixtures → 49). - **CI's shellcheck sweep never lints `.github/scripts/*.sh`** (#116) — `globstar` makes `**` descend into subdirectories, but a glob still does diff --git a/test/labels-reconcile.sh b/test/labels-reconcile.sh index 86be743..7a532ed 100644 --- a/test/labels-reconcile.sh +++ b/test/labels-reconcile.sh @@ -277,11 +277,19 @@ expect "a replacement in flight for a CANCELLED run is pending, not failed" PEND "$(rollup "[$(run_ build CANCELLED 2026-07-20T15:00:00Z),\ $(inflight_ build 2026-07-20T15:10:00Z)]" | checks_state)" # an entry carrying no usable timestamp is treated as newest, not oldest — -# ambiguity resolves toward "not settled" rather than toward a stale success +# ambiguity resolves toward "not settled" rather than toward a stale success. +# Guarded by the sort tiebreak rather than the dating expression: reverting +# only `at:` leaves this passing, so the two changes are separately pinned. expect "an undateable in-flight run is not discarded for a stale success" PENDING \ "$(rollup "[$(run_ build SUCCESS 2026-07-20T15:00:00Z),\ $(jq -n '{__typename:"CheckRun",workflowName:"ci",name:"build",conclusion:"",startedAt:null,completedAt:null}')]" \ | checks_state)" +# ...and the reverse direction, which stops "in flight sorts last" being +# widened into "in flight always wins": a run that FINISHED after an earlier +# in-flight entry is the newer word, and the context is settled. +expect "a finished re-run supersedes an earlier in-flight run" SUCCESS \ + "$(rollup "[$(inflight_ build 2026-07-20T15:19:00Z),\ + $(run_ build SUCCESS 2026-07-20T15:19:45Z)]" | checks_state)" # -- the classifier feeds the state machine: a cancelled required check must # take the PR off the human's plate, which is the whole point of #136.