Skip to content

fix(checks-green): order a name's runs by when they concluded - #936

Open
wenzowski wants to merge 1 commit into
mainfrom
claude/slow-session-start-n9ittp
Open

fix(checks-green): order a name's runs by when they concluded#936
wenzowski wants to merge 1 commit into
mainfrom
claude/slow-session-start-n9ittp

Conversation

@wenzowski

Copy link
Copy Markdown
Contributor

Closes CLOUD-1662.

started_at stops tracking event order once two events for one head are in
flight together. land's pipeline pushes — firing synchronize while the PR is
still a draft, minting the skip set — then readies, firing ready_for_review and
minting the real run. Processed concurrently, the skip's job can start later
than the run it exists to be replaced by, and CLOUD-503's mechanism inverts.

Measured in both directions this can fail:

head reading cost
9ea4da6a windows failure started 04:05:37, skipped twin 04:05:39 a definitively red head read as "no verdict"; land sat on it 30 minutes holding the landing lease
9ca2b3ac one pull_request event minted two CI workflow runs at the identical run_started_at 16:10:20Z — 4986 skipped, 4987 ran and succeeded — jobs starting 16:10:30 and 16:10:26 a fully green head polled 3600 times across 72 minutes past green

On 9ca2b3ac the check-run ids were inverted against the workflow-run ids as
well, so the tie-break could not save it either.

The field

CLOUD-1662 asked whether the ordering field costs a second read per poll or is
already on the check-runs projection. Measured: completed_at is already
there.
A run that judged nothing concludes essentially when it is minted — the
twin above concluded in one second — while a run that judged concludes when the
work finished, at 16:31:39.

Nothing here is a duration, so non-negotiable rule 3 is untouched: this is an
absolute order over a fact each run carries, not a threshold on the gap.

It buys back the case CLOUD-1722 gave up

A PR readied, graded green, then re-drafted re-runs the name as a skip which
genuinely concludes after the success it supersedes, so it still speaks for the
name (CLOUD-247, CLOUD-327). By started_at alone that reading and the
concurrent twin are identical — which is why CLOUD-1722 could not tell them apart
and reversed the draft economy. By conclusion they are opposite.

That row's own reasoning records check_suite, the workflow-run id and the
check-run id as tested and rejected. completed_at is not among them and is not
an id.

What is kept

CLOUD-1722's completed-but-unanswered guard is kept, narrowed to readings
carrying no conclusion stamp — where the key still falls back to started_at and
the guard is what keeps a green head landable. A five-field reading is a live
shape rather than a legacy one: sonar-gate.sh emits precisely that. The column
is last in the TSV, so every case written before it orders exactly as it did,
which leaves them the guard on this change rather than its casualties.

A run that has not concluded sorts above every run that has — the reading, not a
sentinel: not-yet-finished is later than any finish, so a head being re-judged
holds the poll open instead of falling back to the success it is re-judging.

Verification

  • 50/50 in checks_green, including the three arms this adds and every case
    CLOUD-1722 landed.
  • The skip-outranks-a-concurrent-failure mutation — dropping the conclusion
    stamp back out of the key, which is "restore clock-ordering" — was applied and
    confirmed to redden a_concurrent_skip_does_not_bury_the_failure_it_raced.

Noted, not fixed here

git::patch_identities is bounded by Window::DEFAULT = 1000 commits, so a
duplicate that landed more than 1000 commits back is never dropped. Unrelated to
this row; wants its own.


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 53 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: b094acd7-7ed3-469c-8652-60e768bac12a

📥 Commits

Reviewing files that changed from the base of the PR and between f0ae1f3 and c2f79cf.

📒 Files selected for processing (3)
  • crates/batten/src/checks_green.rs
  • crates/batten/src/lib.rs
  • crates/batten/src/pr_watch.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@wenzowski
wenzowski force-pushed the claude/slow-session-start-n9ittp branch from 1f3d19c to 2ee918a Compare September 9, 2026 22:35
@wenzowski
wenzowski marked this pull request as ready for review September 9, 2026 22:35
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Refusing to fast-forward #936 at 2ee918a2b06371fe4996395b486ef699b9e25ce3: a required check has not answered yet. Branch protection requires only final, which fans in over 4 of the 20 names in CI_REQUIRED_CHECKS — so a green final is not a green roster (CLOUD-1570). Wait for the matrix, or let mise run land drive it.

@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Refusing to fast-forward #936 at 2ee918a2b06371fe4996395b486ef699b9e25ce3: a required check has not answered yet. Branch protection requires only final, which fans in over 4 of the 20 names in CI_REQUIRED_CHECKS — so a green final is not a green roster (CLOUD-1570). Wait for the matrix, or let mise run land drive it.

@wenzowski
wenzowski force-pushed the claude/slow-session-start-n9ittp branch from b230e62 to eedb0f0 Compare September 10, 2026 03:23
`started_at` stops tracking event order once two events for one head are
in flight together, and both directions of that have now been measured.

`land`'s pipeline pushes, firing `synchronize` while the PR is still a
draft and minting the skip set, then readies, firing `ready_for_review`
and minting the real run. Processed concurrently, the skip's job can
start LATER than the run it exists to be replaced by, and CLOUD-503's
mechanism inverts:

  9ea4da6  windows failure started 04:05:37, skipped twin 04:05:39
            -> a definitively red head read as "no verdict", and land
               sat on it 30 minutes holding the landing lease
  9ca2b3a  one pull_request event minted two CI workflow runs at the
            identical run_started_at 16:10:20Z — 4986 skipped, 4987 ran
            and succeeded — jobs starting 16:10:30 and 16:10:26, with
            the check-run ids inverted against the workflow-run ids so
            the tie-break could not save it either

CLOUD-1662 asked whether the ordering field costs a second read per poll
or is already on the check-runs projection. Measured: `completed_at` is
already there. A run that judged nothing concludes essentially when it is
minted — the twin above concluded in one second — while a run that judged
concludes when the work finished, at 16:31:39. Nothing here is a
duration, so non-negotiable rule 3 is untouched: this is an absolute
order over a fact each run carries, not a threshold on the gap.

THAT IS ALSO WHAT BUYS BACK THE CASE CLOUD-1722 GAVE UP. A PR readied,
graded green, then re-drafted re-runs the name as a skip which genuinely
concludes AFTER the success it supersedes, so it still speaks for the
name (CLOUD-247, CLOUD-327). By `started_at` alone that reading and the
concurrent twin are identical, which is why that row could not tell them
apart and reversed the draft economy; by conclusion they are opposite.

CLOUD-1722's guard is KEPT and narrowed to readings carrying no
conclusion stamp, where the key still falls back to `started_at` and the
guard is what keeps a green head landable. A five-field reading is a live
shape rather than a legacy one: `sonar-gate.sh` emits precisely that. The
column is last in the TSV, so every case written before it orders exactly
as it did — which leaves them the guard on this change rather than its
casualties.

A run that has not concluded sorts above every run that has. That is the
reading, not a sentinel: not-yet-finished is later than any finish, so a
head being re-judged holds the poll open instead of falling back to the
success it is re-judging.

Verified: 50/50 in `checks_green`, including the three arms this adds and
every case CLOUD-1722 landed. The `skip-outranks-a-concurrent-failure`
mutation — dropping the conclusion stamp back out of the key, which is
"restore clock-ordering" — was applied and confirmed to redden
`a_concurrent_skip_does_not_bury_the_failure_it_raced`.

Refs: CLOUD-1662

BREAKING CHANGE: `checks_green::Run` gains a `completed_at` field, so a
caller constructing it with a struct literal must name the new field.
`constructible_struct_adds_field`, declared rather than dodged: the field
is what carries the ordering, and a reading that cannot say when a run
concluded is the defect this closes.
@wenzowski
wenzowski force-pushed the claude/slow-session-start-n9ittp branch from eedb0f0 to c2f79cf Compare September 10, 2026 03:48
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.

1 participant