Skip to content

fix(review): resolve an ambiguous null prMergedAt with a live recheck before downgrading a label - #4980

Merged
JSONbored merged 1 commit into
mainfrom
claude/gittensory-pr-mislabel-debug-c24720
Jul 11, 2026
Merged

fix(review): resolve an ambiguous null prMergedAt with a live recheck before downgrading a label#4980
JSONbored merged 1 commit into
mainfrom
claude/gittensory-pr-mislabel-debug-c24720

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

  • Fixes the third distinct mechanism behind PR type-label downgrades (see [Bug]: PR type label can silently downgrade gittensor:feature→gittensor:bug when a pull_request_review webhook races the merge webhook #4975 for the full root-cause writeup). handlePullRequestWebhookEvent treats any PR-family webhook's embedded pull_request snapshot as authoritative, including pull_request_review/pull_request_review_comment/pull_request_review_thread. When an approval fires a few ms before an "approve and merge" action, that snapshot's merged_at reads null — if the pass is then delayed behind other queued work long enough for the real merge (and the linked issue's auto-close) to land first, isLinkedIssueTrustworthy saw a closed issue with a null prMergedAt and silently treated it as a confirmed negative, downgrading a correctly-propagated gittensor:feature/gittensor:priority label to gittensor:bug.
  • Resolves the ambiguity with one fresh, live GET /pulls/{n} check of the PR's own actual merge state — only in that one narrow branch (closed issue + null prMergedAt), so the common path pays zero extra API cost. Does not change the original anti-gaming behavior: a linked issue closed independently, before the PR in question ever merged, still correctly fails to propagate.
  • Adds the logging this specific branch was missing so a future recurrence is diagnosable from structured logs alone.

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves (Closes #4975).

Validation

  • git diff --check
  • npm run actionlint
  • npm run typecheck
  • npm run test:coverage locally
  • npm run test:workers
  • npm run build:mcp
  • npm run test:mcp-pack
  • npm run ui:openapi:check
  • npm run ui:lint
  • npm run ui:typecheck
  • npm run ui:build
  • npm audit --audit-level=moderate
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

If any required check was skipped, explain why:

  • test:coverage (full unsharded): not run end-to-end locally — ran scoped vitest --coverage for the touched test file instead and confirmed via the generated lcov report that the new/changed lines in src/review/linked-issue-label-propagation-fetch.ts and the new fetchLivePullRequestMergedAt in src/github/backfill.ts are 100% line and branch covered (56/56 lines, 59/59 branches on the propagation-fetch file). Also ran npm run test:changed (the full affected-import-graph suite): 7943 tests passed, 0 failed. CI's own test:coverage/codecov/patch run is authoritative for the final number.
  • test:workers / build:mcp / test:mcp-pack / ui:openapi:check / ui:lint / ui:typecheck / ui:build: not run — this change touches only src/github/backfill.ts, src/queue/processors.ts, and src/review/linked-issue-label-propagation-fetch.ts (backend webhook/label logic), with no UI, MCP, Worker-pool, or OpenAPI-surface changes, so these are not applicable.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests. (N/A — no auth/session surface touched; the new live-fetch path has an explicit fetch-failure test asserting inconclusive: true, never a silent confirmed-negative.)
  • API/OpenAPI/MCP behavior is updated and tested where needed. (N/A — no API/OpenAPI/MCP surface changed.)
  • UI changes use live API data or real empty/error/loading states, not production mock/demo fallbacks. (N/A — no UI changes.)
  • Visible UI changes include a UI Evidence section below. (N/A — no UI changes.)
  • Public docs/changelogs are updated where needed. (N/A — internal engine behavior, no user-facing docs affected; changelog is not edited in a normal PR.)

Notes

… before downgrading a label (#4818)

A pull_request_review/_comment/_thread webhook's embedded PR snapshot can predate an
imminent merge by a few ms; if that pass then gets delayed behind other queued work
long enough for the real merge (and the linked issue's consequent auto-close) to land
first, isLinkedIssueTrustworthy saw a closed issue with a null prMergedAt and silently
treated it as a confirmed negative, downgrading a correctly-propagated
gittensor:feature/priority label to gittensor:bug. Resolve that one ambiguous case with
a fresh live check of the PR's own merge state instead of trusting whichever webhook
happened to trigger the pass.

Closes #4975
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.30%. Comparing base (5eab3e5) to head (97b7d0c).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4980   +/-   ##
=======================================
  Coverage   94.30%   94.30%           
=======================================
  Files         453      453           
  Lines       38993    39003   +10     
  Branches    14217    14221    +4     
=======================================
+ Hits        36772    36782   +10     
  Misses       1572     1572           
  Partials      649      649           
Flag Coverage Δ
shard-1 46.66% <0.00%> (-0.30%) ⬇️
shard-2 33.68% <18.18%> (+0.45%) ⬆️
shard-3 31.44% <100.00%> (-0.05%) ⬇️
shard-4 32.49% <0.00%> (-0.59%) ⬇️
shard-5 34.17% <0.00%> (+0.72%) ⬆️
shard-6 45.80% <0.00%> (+0.47%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/github/backfill.ts 97.20% <100.00%> (+<0.01%) ⬆️
src/queue/processors.ts 95.27% <ø> (ø)
src/review/linked-issue-label-propagation-fetch.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 11, 2026
@loopover-orb

loopover-orb Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Warning

🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨

⏸️ Gittensory review result - manual review recommended

Review updated: 2026-07-11 06:46:27 UTC

4 files · 2 blockers · readiness 93/100 · CI green · unstable

⏸️ Suggested Action - Manual Review

  • AI review already in progress for this PR head: Another Gittensory pass is already running the AI review for this exact PR head. This pass is skipping to avoid a duplicate LLM call.

Review summary
AI review is already running for this PR head in another Gittensory pass. Gittensory is holding this PR for manual review until that pass completes.

Nits — 1 non-blocking
  • AI review already in progress for this PR head — The gate is held for a human reviewer rather than passed automatically; it re-evaluates once the in-flight review completes or on the next update.

Concerns raised — review before merging

  • No linked issue detected — If this PR is intended to solve an issue, link it explicitly in the PR body.
  • Maintainer requires a linked issue — Link the relevant issue (for example Closes #123) before opening the PR.
Signal Result Evidence
Code review ❌ 2 blockers No AI review summary
Linked issue ⚠️ Missing No linked issue or no-issue rationale found.
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (no linked issue context).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 48 registered-repo PR(s), 40 merged, 420 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 48 PR(s), 420 issue(s).
Gate result ❌ Blocking Repo-configured hard blocker found.
Improvement ✅ Minor risk: clean · value: minor — Code changes are accompanied by test evidence.
Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 48 PR(s), 420 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Treat this as maintainer-lane context rather than normal contributor-lane activity.
  • Explain no-issue PR.
  • Link the issue being solved, or explicitly explain why this is a no-issue PR.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

  • Re-run Gittensory review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. manual-review Gittensor contributor context

Development

Successfully merging this pull request may close these issues.

[Bug]: PR type label can silently downgrade gittensor:feature→gittensor:bug when a pull_request_review webhook races the merge webhook

1 participant