fix(review): never let an inconclusive linked-issue recheck downgrade a propagated label - #4816
Merged
Merged
Conversation
… a propagated label A merge-time (or later sweep/webhook) recheck of a PR's linked-issue label propagation could not distinguish "the recheck genuinely couldn't be verified this pass" (a transient GitHub fetch/rate-limit failure) from "the issue confirms no propagation applies" -- both fell through to the blunt title heuristic and silently overwrote whatever correct label a prior pass had already applied. Confirmed live: 118 PRs mislabeled across gittensory and metagraphed in a 2-day sample, including contributor-reported PRs #4716 and #4783. - linked-issue-label-propagation-fetch.ts: fetchLinkedIssueLabelsForPropagation now returns {labels, inconclusive} instead of a bare label list; isRepoMaintainerLogin distinguishes a confirmed permission result from an errored (inconclusive) one, and logs the error instead of swallowing it. - processors.ts: the type-label block skips the mutation entirely (leaving existing labels untouched) when the recheck was inconclusive rather than confirmed-negative, and now claims the existing per-PR actuation lock so two concurrent passes for the same PR can no longer race each other here. - client.ts: excludes the two trust-deciding endpoints (linked-issue reads, collaborator-permission checks) from cross-caller request coalescing, so one caller's transient failure can no longer become a different concurrent caller's answer. - public.ts / rag-index.ts / grounding-wire.ts: three GitHub callers were computing their rate-limit admission key before a token fallback was applied (or never attributing one at all for a high-volume caller), which is what buried the live incident in an unattributed metric bucket. Full regression coverage added, including an end-to-end reproduction of the exact PR #4716/#4783 race in queue.test.ts.
…el tests Rebased onto main's gateCheckMode-deprecation migration (#4618); the two new regression tests added alongside it still need reviewCheckMode set directly, matching every sibling test in the same describe block.
Contributor
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
JSONbored
added a commit
that referenced
this pull request
Jul 11, 2026
JSONbored
added a commit
that referenced
this pull request
Jul 11, 2026
JSONbored
added a commit
that referenced
this pull request
Jul 11, 2026
JSONbored
added a commit
that referenced
this pull request
Jul 11, 2026
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4816 +/- ##
=======================================
Coverage 94.22% 94.23%
=======================================
Files 441 441
Lines 38745 38766 +21
Branches 14106 14111 +5
=======================================
+ Hits 36508 36530 +22
Misses 1577 1577
+ Partials 660 659 -1
🚀 New features to boost your workflow:
|
JSONbored
added a commit
that referenced
this pull request
Jul 11, 2026
…es (#4814) * test(unit): split queue.test.ts and backfill.test.ts into smaller files queue.test.ts (33,461 lines / 810 tests) and backfill.test.ts (6,874 lines / 236 tests) each ran as one atomic unit under a single vitest worker -- queue.test.ts alone accounted for ~282s (roughly half the wall-clock) of the full coverage run's ~565s duration, since vitest schedules whole test files to workers and can't parallelize within one file. Split each into several files along safe, verified boundaries (no shared mutable state crosses a file boundary; hoisted helper functions used across sections were promoted into each file's shared header). Test count and pass/fail results are identical before and after (810 and 236 tests respectively, all passing) -- verified via `vitest run` on the full old-vs-new file sets. Also fixes two stale comments in src/queue/processors.ts that named the old monolithic queue.test.ts file for a test that moved. * fixup: port #4757's e2e-test-gen changes into split queue-5.test.ts Rebasing onto main picked up #4757 (feat(review): decouple e2e-test-gen auto-trigger and widen checkbox auth), which touched the monolithic queue.test.ts before it was split. That content now lives in queue-5.test.ts, so port the same test changes there: the new autoTrigger opt-in on seedAutoTriggerPr, its three new/updated tests, and the [BETA] badge text update. Verified against main's actual source change (src/queue/processors.ts already carries the [BETA] label) and a full run of all 6 split queue files: 813 tests passing (810 + 3 new). * fixup: port #4732, #4659, #4816 test changes into split queue files * fixup: port #4732 and #4816 test changes into split queue files * fixup: port latest main's queue.test.ts changes into split queue-4.test.ts
This was referenced Jul 11, 2026
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
#regression-safe-propagationdoc comments in each file for the specific mechanism each one closes):linked-issue-label-propagation-fetch.ts:fetchLinkedIssueLabelsForPropagationnow returns{labels, inconclusive}instead of a bare label list;isRepoMaintainerLogindistinguishes a confirmed permission result from an errored (inconclusive) one and logs the error instead of silently swallowing it.processors.ts: the type-label block now skips the mutation entirely (leaving existing labels untouched) when the recheck was inconclusive rather than confirmed-negative, and claims the existing per-PR actuation lock (claimPrActuationLock, already used elsewhere under fix(queue): concurrent webhook and sweep jobs for the same PR are not mutually excluded #2129) so two concurrent passes for the same PR can no longer race each other here.client.ts: excludes the two trust-deciding endpoint shapes (bare linked-issue reads, collaborator-permission checks) from cross-caller request coalescing, so one caller's transient failure can no longer become a different concurrent caller's answer.public.ts/rag-index.ts/grounding-wire.ts: three GitHub callers were computing their rate-limit admission key before a token fallback was applied (or never attributing one at all for a high-volume caller) — this is what buried the live incident in an unattributedkey_scope="unknown"metric bucket instead of a diagnosable one.Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally — 100% line/branch coverage on every changed line across all 6 changed source files (verified directly againstcoverage/lcov.infofor the diff's exact line ranges, not just the repo-wide trend number)npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderate— 0 vulnerabilitiesqueue.test.tsreproducing the exact PR feat(ui): check-run details-page readiness table (#2216) #4716/Multi-tenant hosted architecture spec #4783 race (inconclusive-skip-never-downgrades, lock-contention-skip, and a rewrite of a test that previously asserted the old buggy behavior)Full
npm run test:ci(all 27 steps, includingtest:engine-parity/test:driver-parity/the engine's own suite/test:workers/build:miner/test:miner-pack/rees:test/everyui:*check/ui:build) run twice end-to-end locally under Node 22 (per.nvmrc) with a clean exit both times.Safety
ui:openapi:checkconfirms no drift).UI Evidencesection — N/A, backend-only change.Notes
#regression-safe-propagationcomments in each changed file for the specific confirmed mechanism (a Grafana alert/runbook that queries the rate-limit-responses metric bykey_scopespecifically depends on the "unknown" bucket staying visible for diagnosing exactly this class of bug in the future, which is why the metric-emission gating considered during development was reverted in favor of fixing the callers' own attribution instead — see the code comment onfetchWithGitHubRetryinclient.ts).