Repository navigation
Keep a Check re-run going while dependent jobs await new attempts - #2137
Merged
Merged
Conversation
Once nothing else runs, a re-run job whose new attempt has not appeared gets one more grace period: then its old failed attempt counts as failed, and an absent job cannot establish green. Also consolidate the awaiting counts in RerunChecks, pin the new waiting line and split the dependent-job scenario.
JacobStephens2
marked this pull request as ready for review
November 12, 2026 19:42
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A Check re-run was abandoned when one failed job
needsanother failed job. GitHub creates the dependent job's new attempt only once what it needs has finished, often minutes later. thirdshift required every failed job's new attempt within the 60s grace period, so it reportedno re-run appearedwhile GitHub's re-run was still going (flintmark #7:verifiedneedseditors).The same watch serves the Abandoned job re-run, so that path gets the fix too. A new waiting line is
CI on <sha>: 1 still running, plus 1 awaiting new attempts, out of 1 checks listed so far. The Consequences sections of ADR-0010 and ADR-0020, and the user manual (docs/guide.md, regeneratedsite/docs/index.html), now describe the new rule. The hand-written site pages don't describe how a re-run's start is detected, so they needed no change.Closes #2098
Evidence
Execution evidence
The bug was reproduced at merge base
acd9be19by applying this branch's regression tests to a detached worktree there. The branch'ssrc/ci.rswas not applied.cargo test --bin thirdshift dependentcargo test --test ci a_check_re_run_watches_dependent_jobs(fake GitHub:editorspending_polls: 6,verifiedstale_polls: 8)cargo test --bin thirdshift ci::tests→test result: ok. 64 passed; 0 failedcargo test --test ci dependent→a_check_re_run_watches_a_dependent_job_to_its_new_success ... ok,a_check_re_run_watches_a_dependent_job_to_its_new_failure ... okConfirmed cause:
RerunChecks::new_attempts_listedneeded a new attempt of every requested failed check before the grace period ended. A dependent job can't get one until its dependencies finish.Review-raised bound (Spec finding 3): the reviewer's test
a_dependent_jobs_attempt_that_never_appears_does_not_wait_foreverfailed on the branch before this round withwatch never ended: Some(interrupted). It is now kept as two tests:a_dependent_jobs_old_attempt_still_listed_a_grace_period_after_ci_settles_is_reda_dependent_job_still_absent_a_grace_period_after_ci_settles_cannot_verify_ciBoth pass.
Final validation:
scripts/affected-tests main→PASS npm test --prefix site (33.40s),PASS cargo test (1001.23s)Review
thirdshift-code-reviewagainstrefs/remotes/origin/mainfound 8 Standards and 3 Spec findings. Fixed in this round:RerunChecks::awaiting_attempts, withis_previous_attemptandsame_workflow_checkreused and one format string.review_test is renamed.Both reviewers read every changed file except
site/docs/index.html. That file is generated, and both accepted excluding it:npm run docs:check --prefix siteexits 0 and its diff only mirrors thedocs/guide.mdsentences.Unaddressed findings
Standards
RerunChecks.observed: HashSet<usize>couples to indices ofchecks(Primitive Obsession, judgement call). Declined.checksis built once inrequest_reruns(src/ci.rs:431,checks: failed.own.iter().chain(&failed.inherited).collect()), it is a private field, and nothing pushes to, sorts or retains it afterwards, so the indices are stable for the struct's life.Review of the commits merged from
main(#2135 for #2052, #2136 for #2112), with fixed pointe6ded0af. These come from their commits. S2 (redundant blank check inresolve_recommendation) and S3 (Fleet::textrenamed toFleet::with_machine_lines) were fixed in f432785. Both reviewers read every changed file.prompts/triage-correction.md,prompts/triage-issue.md,site/prompts/index.htmlandsite/docs/index.htmlwere left unread on purpose as generated output:cargo test --bin thirdshift prompts_pagegave 14 passed,npm run docs:check --prefix siteexited 0, and both reviewers checked that the output diffs mirror the source edits.skills/thirdshift-triage/SKILL.mdandskills/thirdshift-to-questionnaire/SKILL.md, and the questionnaire skill keeps decision wording left over from ready-for-human (judgement call). Declined for now. Whether ready-for-human should carry a questionnaire is the open question in Confirm Triage should reject questionnaires on ready-for-human (reversed by #2135) #2144 (Spec P1), and pruning the skills now would pre-empt that decision. The repetition is also Treat empty-string Triage questionnaire as absent and show a ready-for-agent example in thirdshift-triage #2052's fix itself: its brief asked for a second example "reinforcing thatquestionnaireis present only when"state"is"needs-info"".Machine::textandsrc/console/metrics_fleet.html, and the label "unreadable accounts" differs from "Unreadable OS accounts" (judgement call). Declined. Fleet metrics drops unavailable_accounts from machine summaries #2112 specifies that wording: "render them insrc/console/metrics_fleet.html'sMachineslist (for example· unreadable accounts: conductor, vsto)". One renderer is Rust text and the other is browser HTML, so there is no shared code to extract.Machineis built by struct literal in four places (judgement call, mostly pre-existing). Declined. Each literal fills its fields from a different source: local, live, saved, and the test. A constructor would take all of them as parameters, and the compiler already flags any literal that misses a new field.other_accountsand the blank-questionnaire Scenarios (judgement call). Declined. The setups sit in different test binaries (tests/console/metrics.rs,tests/console/metrics_report.rs), anddocs/testing.mdhas no rule against inline Scenario setup.<p>insite/architecture/index.html(~293) sits outside.reading-content(judgement call). Declined. Three other<details>on that page use the same structure, so it follows the page's existing pattern.Spec
docs/guide.mdand pinned bya_dependent_job_absent_from_the_latest_attempt_stays_pending.filter=latest) can omit the dependent job instead of listing its old failure, and the issue's "treated as pending, not as still failed" covers that case. The reviewer called it justified.From their commits (#2135, #2136):
needs_answer, which reverses Triage run: turn a Report into triaged issues #1323's rule that ready-for-human requires a questionnaire. Declined: the Day shift must decide, so I filed Confirm Triage should reject questionnaires on ready-for-human (reversed by #2135) #2144 (needs-triage). The behaviour is deliberate in Treat blank Triage questionnaires as absent #2135 and encoded by a test:cargo test --test triage_run questionnaires_are_required_only_for_needs_infogives 1 passed. Whether ready-for-human should carry a questionnaire is a product decision about the operator workflow, so a CI-fix branch should not reverse it either way.Machine::texthand-builds the Fleet machine line instead of the generic document walk, so a futureMachinefield could be missing from text (scope/design, minor). Declined. Fleet metrics drops unavailable_accounts from machine summaries #2112 asks to "mention unreadable accounts in textMachineslines", and 7e4bce5 ("keep Fleet machine diagnostics on one text line") chose this layout on purpose. Onlymachinesis replaced. The rest of the report still goes through the shared walk (Fleet::with_machine_lines,src/logs/metrics/fleet.rs:134), and the reviewer found every current field rendered.Security review outcome
No unaddressed introduced findings.
Merge Danger
Door: two-way
A revert restores the previous strict grace check. No data, labels or GitHub state change.
Blast Radius: CI-watching
This only affects the watch after a Check re-run or an Abandoned job re-run. The worst case is a dependent job being judged one grace period after the rest of its workflow run settles.
CI notes
console-test(run 43293144147):tests/working-targets.test.cjsfailed once on a remote Fleet row's PR link (1440px remote review-pass: visible PR target). This branch changes onlysrc/ci.rs,tests/ci.rsand docs, not the console or that test. The test passed in 6 of 6 local runs at this commit, and the fullnpm test --prefix consolepassed locally, so it looks intermittent.Built with codex codex-cli 0.167.2 · gpt-6.1-sol · xhigh