Skip to content

fix(dev-lead): stop false "rate-limited" claims; dedupe superseded check runs - #462

Merged
don-petry merged 7 commits into
mainfrom
fix/dev-lead-false-rate-limited-messaging
Jun 7, 2026
Merged

don-petry merged 7 commits into
mainfrom
fix/dev-lead-false-rate-limited-messaging

Conversation

@don-petry

@don-petry don-petry commented Jun 7, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes #461 — dev-lead told users "all AI engines are currently rate-limited" when no engine was rate-limited (PR #453 incident, comment 4642769821). Two defects combined:

1. Superseded cancelled check runs counted as permanent Tier-1 blockers

fetch_pr_context built CI_STATUS_JSON from GET /commits/{sha}/check-runs with no dedup by name. Each triggering event creates its own check suite, so the API's default filter=latest never collapses runs across suites — on PR #453, two concurrency-cancelled review runs sat forever next to their successful same-named replacement, and has_hard_blockers counted cancelled → endless 30-minute retry cycling.

Fix: dedupe check runs by name, keeping the newest (started_at, then id). This mirrors the legacy-statuses dedup already present a few lines below (same rationale, same function), and matches GitHub's own merge semantics — branch protection keys required checks by name. A lone cancelled run (genuinely the latest of its name) still blocks.

2. The hard-blocker backoff path reused the rate-limit messaging verbatim

The "engine ran fine, no changes, but hard blockers remain" path called post_reviews_rate_limited and posted the literal "all AI engines are currently rate-limited" ack with a fabricated now+30min "reset" time.

Fix: post_reviews_rate_limited gains a reason param (rate-limit default | blocked). The blocked path now posts "waiting on PR blockers" marker wording and an honest review-changes ack ("no code changes were needed, but it still has blocking checks or reviews…"). The machine-readable status=rate-limited marker token is unchanged — dev-lead-retry.sh keys its re-dispatch scan on it — and a new informational reason= field records the real cause. The +30min backoff write moves from the two duplicated call sites into the function.

Compatibility verified

  • dev-lead-retry.sh marker patterns are substring test() matches ending at status=rate-limited; the reset= capture is position-independent — both parse the new reason=-tagged format (verified directly).
  • e2e scenario 07 fixtures/assertions are loose greps and old-format synthetic markers — both formats remain valid inputs.
  • dev-lead-fix-ci.sh markers untouched (it never scans/classifies the commit's check-run list).

Tests

  • New: superseded cancelled run is not a hard blocker (exact PR fix(dev-lead): hold auto-merge while working a PR + push defensively (#452) #453 shape: 2 cancelled + newer same-named success).
  • New: lone cancelled run still blocks (regression guard against over-eager dedup).
  • Extended: both hard-blocker tests now pin reason=blocked, the "waiting on PR blockers" wording, the kept status=rate-limited token, and assert the false "all AI engines…" claim is gone; genuine rate-limit test pins reason=rate-limit and unchanged wording.
  • bats tests/dev-lead/unit/ — 295/295 pass; shellcheck --severity=warning clean; both CI integration tests pass.

Known limitation (pre-existing, out of scope)

A lone cancelled check (nothing newer of the same name) still cycles 30-minute retries without anything re-triggering the cancelled workflow — the retry re-runs the engine, not the check. Pre-dates this change (#426); this PR shrinks its blast radius to genuinely-latest cancellations only.

🤖 Generated with Claude Code

Summary by CodeRabbit

Bug Fixes

  • Concurrent CI check-runs are now deduplicated by name and GitHub App ID, preventing canceled runs from being incorrectly flagged as persistent blockers. This improves blocker accuracy.
  • Rate-limit and PR blocker messages are now differentiated. When held up by PR blockers, notifications now display "waiting on PR blockers" with updated backoff timing.

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 7, 2026 13:53
@don-petry
don-petry requested a review from a team as a code owner June 7, 2026 13:53
@coderabbitai

coderabbitai Bot commented Jun 7, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@don-petry, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 57 minutes and 26 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 319b7def-4e8f-4583-b78f-166ae43fd3d2

📥 Commits

Reviewing files that changed from the base of the PR and between 7290be6 and 16da10c.

📒 Files selected for processing (2)
  • scripts/dev-lead-fix-reviews.sh
  • tests/dev-lead/unit/test_fix_reviews.bats
📝 Walkthrough

Walkthrough

The PR refines CI blocker detection and retry messaging in the dev-lead automation script. Check-run deduplication now groups by check name and GitHub App id to avoid treating cancelled-then-replaced runs as persistent blockers. The rate-limited marker function is extended with a reason parameter to distinguish "blocked by PR checks" from "rate-limited engines", each producing distinct user-facing text and reset-time behavior. Call sites updated to pass reason=blocked for hard-blocker cases.

Changes

Blocker deduplication and signaling

Layer / File(s) Summary
Check-run deduplication by name and app.id
scripts/dev-lead-fix-reviews.sh
CI check-run aggregation in fetch_pr_context now groups by (check name, app.id) instead of name alone, selecting the newest run per pair by started_at then id, preventing concurrency-cancelled runs with newer replacements from being treated as persistent blockers.
post_reviews_rate_limited extended with reason parameter
scripts/dev-lead-fix-reviews.sh
post_reviews_rate_limited accepts an optional reason parameter (default rate-limit). When reason=blocked, the function computes and persists a fixed 30-minute UTC reset time for downstream retry backoff.
Marker token and message generation with conditional reason
scripts/dev-lead-fix-reviews.sh
The marker token and user-visible body now include reason=... and conditionally include reset=... when blocked. Heading and retry messages switch based on reason value and intent type, producing distinct messaging for blocked-by-pr-checks vs rate-limited-engines cases. For review-changes, acknowledgment text varies to avoid falsely claiming engine rate limiting when PR blockers are the cause.
Call sites updated to pass reason=blocked for hard blockers
scripts/dev-lead-fix-reviews.sh
In fix-reviews and review-changes failure paths where hard blockers remain, call sites now invoke post_reviews_rate_limited with reason=blocked instead of generic rate-limit handling.
Test updates and regression coverage for dedup and reason logic
tests/dev-lead/unit/test_fix_reviews.bats
Existing rate-limited marker test is strengthened to assert reason=rate-limit and correct wording. Hard-blocker tests are updated to assert reason=blocked, "waiting on PR blockers" messaging, and non-claims of engine rate limiting. New regression tests verify check-run deduplication: superseded cancelled runs must not block, lone cancelled runs must still block, and same-named runs from different GitHub Apps must not be collapsed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • petry-projects/.github-private#435: Both PRs modify blocker/marker logic in scripts/dev-lead-fix-reviews.sh, including check-run deduplication for hard-blocker detection and changes to post_reviews_rate_limited behavior in the retry flow.

Suggested labels

needs-human-review

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the two main fixes: stopping false rate-limited claims and deduplicating superseded check runs, directly matching the core changes in the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/dev-lead-false-rate-limited-messaging

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 and usage tips.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@don-petry
don-petry enabled auto-merge (squash) June 7, 2026 13:53

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request addresses issue #461 by implementing name-level deduplication for GitHub check runs, preventing superseded concurrency-cancelled runs from acting as permanent blockers. It also refactors the rate-limiting logic to distinguish between genuine rate limits and PR blockers, providing more accurate user-facing messages and a 30-minute backoff retry. A critical issue was identified in the jq filter used for deduplication, where composite sorting keys were separated by a comma instead of being wrapped in an array, which leads to incorrect sorting behavior.

Comment thread scripts/dev-lead-fix-reviews.sh Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 7, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes dev-lead’s incorrect “all AI engines are currently rate-limited” messaging when the real cause is PR hard blockers, and improves CI blocker detection by deduplicating superseded check runs (by name) so stale concurrency-cancelled runs don’t cause endless retry loops.

Changes:

  • Deduplicate commit check-runs by check name (keeping the newest) when building CI context for blocker detection.
  • Extend post_reviews_rate_limited to accept a reason (rate-limit vs blocked) so user-facing messaging is accurate while preserving the status=rate-limited marker token for retry automation.
  • Expand unit coverage in test_fix_reviews.bats for both messaging correctness and the new check-run dedupe behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
scripts/dev-lead-fix-reviews.sh Adds check-run dedupe logic and improves rate-limit/backoff marker posting to distinguish genuine rate limits from PR blockers.
tests/dev-lead/unit/test_fix_reviews.bats Adds/extends tests to validate correct marker tagging/wording and dedupe behavior for superseded vs lone cancelled check runs.

Comment thread scripts/dev-lead-fix-reviews.sh Outdated
donpetry-bot
donpetry-bot previously approved these changes Jun 7, 2026

@donpetry-bot donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated review — APPROVED ✓

Risk: LOW
Reviewed commit: 9460e2a34108acb702282d73210ae28ac7c2b165
Review mode: triage-approved (single reviewer)

Summary

Targeted, well-scoped fix for the two defects described in issue #461:

  1. Check-run dedup by name in fetch_pr_context — [.check_runs[]?] | group_by(.name) | map(sort_by(.started_at // "", .id // 0) | last | …) collapses across check suites so a concurrency-cancelled run is no longer left sitting next to its successful same-named replacement. Mirrors the legacy-statuses dedup already present in the same function. A lone cancelled run (genuinely the latest of its name) still blocks — covered by a dedicated regression test.
  2. Honest blocked-retry messaging — post_reviews_rate_limited gains a reason param (rate-limit default | blocked). The blocked path posts ## Dev-Lead — waiting on PR blockers and a candid review-changes ack instead of falsely claiming the engines are rate-limited. The machine-readable status=rate-limited marker token is preserved (the retry cron keys on it); a new informational reason= field is appended. The +30min backoff write is hoisted from the two duplicated call sites into the function.

Linked issue analysis

Fixes #461 — addresses both root causes the issue identified (the false "all AI engines are currently rate-limited" ack on the hard-blocker backoff path, and the superseded-cancelled check-run accumulation). The PR description also acknowledges the known limitation around a lone cancelled check still cycling — left out of scope as pre-existing (#426).

Findings

No blocking issues.

One prior comment investigated and dismissed. @gemini-code-assist flagged the jq composite sort as critical, claiming sort_by(.started_at // "", .id // 0) should be wrapped in an array (sort_by([…])) to sort correctly. This is wrong: jq evaluates the comma-separated stream inside sort_by as a multi-key tuple, and the two forms produce identical orderings. Verified directly against jq 1.7 with the test fixture (three same-named runs, two cancelled, one newer success): the PR's filter correctly returns only the newest successful run. The bats test superseded cancelled check run is not a hard blocker pins this end-to-end.

Minor observations (non-blocking):

  • Marker compatibility claims in the PR description (dev-lead-retry.sh substring match on status=rate-limited, e2e scenario 07 loose greps, dev-lead-fix-ci.sh markers untouched) match the change shape — the reason= field is appended after status=rate-limited, so existing scanners that key on the status token are unaffected.
  • The 30 minutes backoff value moves into post_reviews_rate_limited but stays a hard-coded literal; centralizing it is the right call, parameterizing further is out of scope here.

CI status

All required checks passing — bats (295/295 per PR description), shellcheck, ShellCheck, Lint, unit-tests, validate-agent-profiles, gh-aw-compile, Compile agentic workflows, CodeQL, Agent Security Scan, Secret scan (gitleaks), AgentShield, SonarCloud, dependency-audit. SonarQube Cloud quality gate passed (0 new issues, 0 security hotspots). Mergeable; BLOCKED only on the org-leads review requirement.


Reviewed automatically by the PR-review agent (single-reviewer mode: opus 4.7). Reply if you need a human review.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-reviews (applied)

Changes committed and pushed.

@don-petry
don-petry dismissed stale reviews from donpetry-bot and coderabbitai[bot] via c8e8774 June 7, 2026 13:56

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9460e2a341

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/dev-lead-fix-reviews.sh Outdated
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (applied)

Changes committed and pushed.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 7, 2026
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-bot-comment (no-changes)

Agent reasoning
Issues addressed: 0
Files changed: none
Skipped (informational): 0
No actionable findings. SonarCloud Quality Gate passed with 0 new issues and
0 security hotspots. No open review threads from sonarqubecloud[bot] to resolve.
Zero Tier 1 blockers in CI or reviews. No changes needed.
```

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — waiting on PR blockers (intent: review-changes)

PR: #462
No changes were committed, but the PR still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews). The retry cron will re-attempt automatically. Next attempt after: 2026-06-07T17:26:46Z

@don-petry

Copy link
Copy Markdown
Collaborator Author

Note

@don-petry I reviewed this PR and no code changes were needed, but it still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews), so I cannot mark it done yet. I'll re-check automatically.
Next attempt after: 2026-06-07T17:26:46Z

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7290be6c7a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/dev-lead-fix-reviews.sh Outdated
Comment thread scripts/dev-lead-fix-reviews.sh Outdated
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-reviews (applied)

Changes committed and pushed.

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 559d868d74

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/dev-lead-fix-reviews.sh
@don-petry
don-petry enabled auto-merge (squash) June 7, 2026 18:25
@don-petry
don-petry requested a review from donpetry-bot June 7, 2026 22:01
@donpetry-bot

Copy link
Copy Markdown
Contributor

@don-petry assigned me as reviewer — starting a fresh review now. Results will appear in a few minutes.

@don-petry
don-petry disabled auto-merge June 7, 2026 22:10
@don-petry
don-petry merged commit 9ede0ca into main Jun 7, 2026
31 of 32 checks passed
@don-petry
don-petry deleted the fix/dev-lead-false-rate-limited-messaging branch June 7, 2026 22:10
don-petry added a commit that referenced this pull request Jun 8, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Jun 12, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Jun 13, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Jun 13, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Jun 14, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Jun 15, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Jun 21, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Jun 23, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Jun 23, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Jun 25, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Jun 25, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 2, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 3, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 3, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 7, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 8, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
don-petry added a commit that referenced this pull request Aug 8, 2026
…eck runs (#462)

* fix(dev-lead): honest blocked-retry messaging and check-run dedup

Fixes #461 — two defects that combined to falsely tell users "all AI
engines are currently rate-limited" (PR #453 incident):

1. fetch_pr_context now dedupes check runs by name, keeping the newest
   (started_at, then id). Each triggering event creates its own check
   suite, so the API's filter=latest never collapses runs across suites:
   a concurrency-cancelled run sat forever next to its successful
   same-named replacement and registered as a permanent Tier-1 blocker.
   Mirrors the legacy-statuses dedup a few lines below. A lone cancelled
   run (latest of its name) still blocks.

2. post_reviews_rate_limited gains a reason param (rate-limit|blocked).
   The hard-blocker backoff path now posts "waiting on PR blockers"
   wording and an honest review-changes ack instead of claiming the
   engines are rate-limited. The machine-readable status=rate-limited
   marker token is unchanged (dev-lead-retry.sh keys on it); a new
   reason= field records the real cause. The +30min backoff write moves
   from the two call sites into the function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(reviews): address review comments [skip ci-relay]

* chore: apply manual instructions [skip ci-relay]

* fix(reviews): address review comments [skip ci-relay]

* docs(dev-lead): document deliberate cross-suite Stage-2 dedup + pin with test

Addresses the cycle-2 review finding (Codex P2, scripts/dev-lead-fix-reviews.sh
Stage 2 key wider than Stage 1): the asymmetry is intentional and load-bearing.
A concurrency-cancelled run is always superseded from a different check suite
(the PR #453 incident shape), so requiring suite equality in Stage 2 would
never drop anything and would reintroduce issue #461's endless retry loop.

The check-runs API exposes no workflow identity, so a cancelled check from a
sibling workflow sharing name+app with a newer success is also dropped —
accepted trade-off matching GitHub's own required-check gate, which keys on
the latest same-named run (PR #453 merged with stale cancelled runs still on
its head SHA). Failures remain exempt from Stage 2.

Adds the missing test the review called out: cancelled across distinct suites
of the same app with a newer same-named success → dropped, no blocker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: donpetry-bot <{}+donpetry-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: donpetry-bot <281750570+donpetry-bot@users.noreply.github.com>
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.

dev-lead falsely reports "all AI engines are currently rate-limited" when the real cause is stale cancelled check runs

3 participants