Skip to content

fix(hosted-review-sitter): wait out a running GitHub workflow before rerunning it - #124

Merged
zpyoung merged 1 commit into
mainfrom
zpyoung/sitter-rerun-already-running
Oct 19, 2026
Merged

zpyoung merged 1 commit into
mainfrom
zpyoung/sitter-rerun-already-running

Conversation

@zpyoung

@zpyoung zpyoung commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner
Files Added Deleted Net
Test 2 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​301 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​301
Prod 4 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​84 $\color{#cf222e}{\Huge{\mathbf{−}}}$​17 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​67

ELI5

When a CI job fails, the PR sitter asks GitHub to rerun it. If other jobs in that same workflow run are still going, GitHub says no ("This workflow is already running"). The sitter read that "no" as "maybe it worked", then gave up on the PR for good. Now it waits for the run to finish before asking, and if GitHub still says no, it knows nothing happened and tries again later.

What Changed

Before: on #121 the sitter called rerun-failed-jobs while other jobs in the run were pending. GitHub answered 403 "already running", the attempt settled as indeterminate, and every later tick raised a landing-failed: rerun disposition never settled deviation for that head. It never retried.

After:

  • The decision step declines with a new awaiting-workflow-run reason while any other check in the same GitHub workflow run is pending. It reruns once the run settles.
  • The GitHub provider turns the "already running" 403 into a definite not-landed failure (reason workflow-run-in-progress). It only does that when no earlier workflow in the same action had already rerun, since a partial rerun really is uncertain.
  • The rerun evidence key now includes the observations of the run's other checks. The kernel gate only retries a not-landed attempt on new evidence, so this is what lets a refused rerun go again once the run moves. Without it, the 403 fix alone would swap the loud deviation for a silent hold.

Why

Waiting for the run is what GitHub requires, and it avoids burning attempts on calls that are known to fail. The 403 classification is the backstop for races the snapshot can't see, like a dependent job that hasn't been created yet. Re-keying evidence was the smallest way to make that backstop actually retry without changing the kernel's "retry needs new evidence" rule.

Not changed:

  • check-runs/{id}/rerequest has no run-level lock. Its 403/422 means the check isn't rerequestable, which is permanent, so the owner deviation is still the right surface.
  • GitLab retries individual jobs while the pipeline runs, so the wait applies to GitHub only.
  • The existing unresolved handling in decision.ts is untouched. That keeps this clear of the sibling bug-317 fix.

Compatibility: the new decline reason is a plain string with no wire schema. Only GitHub workflow-run reruns get the evidence-key change. Existing completed or in-flight attempts are looked up by their stored action, so they don't refire. A previously not-landed rerun gets one fresh retry.

Linked Issue

Orca ledger bug-318.

Visual Proof

N/A. Background watcher behavior with no UI change.

Testing

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

  • decision-workflow-run.test.ts: waits on a pending sibling in the same run (not another run), doesn't wait on GitLab, and retries a not-landed rerun with a new fingerprint once the run moves.

  • provider-github-rerun.test.ts: the "already running" 403 is not-landed, a 403 after an earlier workflow reran stays indeterminate, and other 403s stay indeterminate.

  • Watched the new assertions fail first. Then the sandbox ran src/main/fork-heimdall, src/main/fork-hosted-review-sitter and src/shared: 14,425 passed. pnpm typecheck:node and check:code-quality:changed are clean.

AI Disclosure

Claude (Opus 5.5) via Claude Code.

Review

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

All of this is fork-owned code under **/fork-hosted-review-sitter/**, so there are no manifest changes. SSH: the provider runs on the execution host, so nothing changes there.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

…rerunning it

GitHub refuses rerun-failed-jobs with "This workflow is already running
(HTTP 403)" until every job in the run finishes. The sitter fired the rerun
as soon as one job failed, the refusal settled as indeterminate, and the
decision then emitted a landing-failed deviation every tick for that head.

- Decline with awaiting-workflow-run while any other check in the same
  workflow run is pending.
- Classify the "already running" 403 as not-landed (reason
  workflow-run-in-progress), unless an earlier workflow in the same action
  already reran.
- Fold the run's other check observations into the rerun evidence key, so a
  not-landed rerun gets a fresh fingerprint once the run moves and the gate
  lets it retry.

check-runs/{id}/rerequest has no run-level lock, so it keeps its current
handling. GitLab job retries are per job and are unaffected.
Copilot AI balanced review requested due to automatic review settings October 19, 2026 16:50

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@zpyoung
zpyoung merged commit b22f023 into main Oct 19, 2026
31 checks passed
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.

2 participants