Skip to content

Flag non-live bounty references in queue health#660

Closed
Floofy6 wants to merge 1 commit into
ramimbo:mainfrom
Floofy6:codex/non-live-bounty-guard-645
Closed

Flag non-live bounty references in queue health#660
Floofy6 wants to merge 1 commit into
ramimbo:mainfrom
Floofy6:codex/non-live-bounty-guard-645

Conversation

@Floofy6
Copy link
Copy Markdown

@Floofy6 Floofy6 commented May 31, 2026

Bounty #645

Summary

  • Teach scripts/pr_queue_health.py to distinguish live bounty references from non-live proposed/pending bounty issues.
  • Require referenced live bounty issues to have both the mrwk:bounty label and an actual Reserved on MergeWork: claims-open comment when live GitHub metadata is available.
  • Report non-live bounty references in text/markdown/JSON queue-health output without auto-labeling, auto-closing, or making payment decisions.
  • Keep fixture compatibility for older/offline inputs without comment metadata, and avoid fetching all issue comments in bulk by loading comments only for issue numbers referenced by open PRs.

Why

Proposed-only issues can look like open bounty work before they are actually claimable. This guard gives maintainers a repo-native way to spot PRs that cite pending, proposed-only, closed, exhausted, missing, or unsupported bounty references before those PRs muddy the queue.

Validation

  • .venv/bin/python -m pytest tests/test_pr_queue_health.py -q -> 18 passed.
  • .venv/bin/ruff check scripts/pr_queue_health.py tests/test_pr_queue_health.py -> passed.
  • .venv/bin/ruff format --check scripts/pr_queue_health.py tests/test_pr_queue_health.py -> 2 files already formatted.
  • .venv/bin/python -m mypy scripts/pr_queue_health.py -> success.
  • git diff --check -> clean.
  • .venv/bin/python scripts/pr_queue_health.py --repo ramimbo/mergework --format markdown -> live queue report completed and identified the existing dirty/needs-info PR Add treasury proposal filters and links #639 without non-live bounty false positives.

No private data, credentials, wallet material, production mutation, price/exchange/bridge/off-ramp claims, or fabricated payout claims used.

Summary by CodeRabbit

  • New Features
    • Bounty liveness detection now incorporates multiple signals to accurately determine claimability status
    • Queue reports distinguish between closed, live, and non-live bounties with separate tracking and reporting
    • Enhanced queue analysis with improved bounty categorization, detailed state counts, and better report clarity

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 31, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

The PR extends queue health analysis to distinguish claimable bounties from non-claimable ones. It adds bounty liveness classification based on mrwk:bounty label and "Reserved on MergeWork" comment presence, categorizes PR bounty references into live/non-live/closed tracks, updates report output and issue detection, enhances live queue data loading to fetch referenced bounty comments, and validates the flow with new test cases.

Changes

Bounty Liveness Detection and Reporting

Layer / File(s) Summary
Bounty liveness classification helpers
scripts/pr_queue_health.py
Added CLAIMS_OPEN_RE regex to detect "Reserved on MergeWork" comments, _comments() helper to normalize comment data shapes, and _bounty_liveness() function to classify bounties as live (has label + comment), non-live (missing either signal), or closed/exhausted.
Queue analysis with liveness routing
scripts/pr_queue_health.py
Updated analyze_queue() to route each referenced bounty through liveness classification instead of binary open/closed check, created non_live_bounty_references accumulator, and extended report structure with live/non-live/closed count metrics.
Issue detection and report formatting
scripts/pr_queue_health.py
Expanded has_queue_issues() to flag non-live bounty references, added "Non-live bounty references" section to both text and markdown output formatters.
Live queue data loading with comment fetching
scripts/pr_queue_health.py
Refactored load_live_queue() to compute referenced bounty IDs from PR data, added _gh_bounty_issue() to normalize issue objects, and implemented two-step bounty collection: build map from matching issues then fetch comments via gh issue view for each referenced bounty ID.
Test coverage for liveness detection and data loading
tests/test_pr_queue_health.py
Updated existing test expectations for new summary metrics, added tests validating non-live bounty detection with assertion of missing label/comment details and Markdown report section presence, added test mocking gh CLI to verify live loader fetches referenced bounty comments.

Possibly related PRs

  • ramimbo/mergework#324: Main PR extends bounty reference handling and report structure introduced in this PR, which established the reusable queue health report foundation.
  • ramimbo/mergework#413: Both PRs build on Markdown report output infrastructure; this PR adds the new "Non-live bounty references" section to formatters.
  • ramimbo/mergework#476: Both PRs modify bounty reference extraction logic and what bounties are loaded for evaluation in the queue health analyzer.
🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Flag non-live bounty references in queue health' directly and specifically names the changed surface and behavior, clearly summarizing the main change in the PR.
Description check ✅ Passed The description covers all required sections: summary with concrete changes, evidence of the bug/confusion being addressed, validation with test results, and bounty reference. All test evidence items are checked off or reported as passing.
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.
Mergework Public Artifact Hygiene ✅ Passed Modified files contain no investment, price, cash-out, or security claims. All strings are technical identifiers or neutral status messages. No documentation was modified.
Bounty Pr Focus ✅ Passed Diff addresses PR objectives: non-live bounty detection via mrwk:bounty label and comment, separate tracking from closed, multi-format output, backward compatibility, and test coverage verified.

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


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

Copy link
Copy Markdown
Contributor

@Gwani-28 Gwani-28 left a comment

Choose a reason for hiding this comment

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

Reviewed PR #660 current head a7dcf2d5d849592dc6f6f948f585cc7a9549dfd5 for #645.

Evidence checked:

  • Confirmed scripts/pr_queue_health.py keeps the existing bounty-reference parser and adds a separate non-live bounty reference category instead of folding proposed-only issues into closed/exhausted or missing-reference buckets.
  • Confirmed live GitHub mode hydrates comments only for issue numbers referenced by open PRs, so the Reserved on MergeWork: signal can be checked without fetching every bounty issue's comments.
  • Confirmed the liveness check requires both the mrwk:bounty label and a claims-open Reserved on MergeWork: comment when comment metadata is present, while preserving older/offline fixture compatibility when comments are unavailable.
  • Confirmed text, Markdown, JSON summaries include non-live bounty counts and details, giving maintainers CI/report output without auto-labeling, auto-closing, accepting, or paying work.
  • Confirmed regression tests cover a live bounty, proposed/non-live references, missing claims-open comments, and live-loader comment hydration.
  • Confirmed no prior human review existed on #660 before this review; only the automated CodeRabbit in-progress comment was present.

Validation run locally:

  • .venv/bin/python -m pytest tests/test_pr_queue_health.py -q -> 18 passed.
  • .venv/bin/ruff check scripts/pr_queue_health.py tests/test_pr_queue_health.py -> passed.
  • .venv/bin/ruff format --check scripts/pr_queue_health.py tests/test_pr_queue_health.py -> 2 files already formatted.
  • .venv/bin/python -m mypy scripts/pr_queue_health.py -> success.
  • .venv/bin/python scripts/pr_queue_health.py --repo ramimbo/mergework --format markdown -> completed against the live queue; it reported zero non-live bounty references and identified only current dirty/needs-info/unstable queue state. The repository quality check was passing; CodeRabbit review was still pending at the time checked.

I did not find a code blocker in this pass. The implementation matches #645's requested maintainer-facing guard and keeps the change focused on queue-health reporting.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0cb27991-980e-4f3a-b22d-66cdd75b8a6a

📥 Commits

Reviewing files that changed from the base of the PR and between 148bcb7 and a7dcf2d.

📒 Files selected for processing (2)
  • scripts/pr_queue_health.py
  • tests/test_pr_queue_health.py

Comment on lines +108 to +109
if not labels and not comments:
return True, "open"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Edge case: empty metadata could mask non-live bounties.

When comments key is present but the list is empty (and labels is also empty), the function returns True, "open" rather than checking for the required signals. Per docs/bounty-lifecycle.md, an issue must have both the mrwk:bounty label and a "Reserved on MergeWork" comment to be claimable—empty metadata satisfies neither.

This could cause a PR referencing such an issue to skip non-live detection entirely. If this is intentional backwards compatibility for sparse live-fetched data, consider adding a clarifying comment. Otherwise, consider only applying this fallback when the comments key is absent.

Proposed clarification comment
     if "comments" not in raw:
         return True, "open"
+    # Minimal metadata (empty labels + empty comments) is treated as "open" to
+    # avoid false positives when live fetches return sparse data.
     if not labels and not comments:
         return True, "open"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if not labels and not comments:
return True, "open"
# Minimal metadata (empty labels + empty comments) is treated as "open" to
# avoid false positives when live fetches return sparse data.
if not labels and not comments:
return True, "open"

Comment on lines +362 to +370
def _gh_bounty_issue(raw: dict[str, Any]) -> dict[str, Any]:
return {
"number": raw["number"],
"title": raw.get("title"),
"state": raw.get("state"),
"labels": raw.get("labels", []),
"awards_remaining": 1 if raw.get("state") == "OPEN" else 0,
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider case-insensitive state comparison for robustness.

_is_open_bounty lowercases state before comparison, but here the check is case-sensitive (== "OPEN"). If the GitHub CLI output format varies, this could incorrectly set awards_remaining: 0 for open issues.

Proposed fix
 def _gh_bounty_issue(raw: dict[str, Any]) -> dict[str, Any]:
     return {
         "number": raw["number"],
         "title": raw.get("title"),
         "state": raw.get("state"),
         "labels": raw.get("labels", []),
-        "awards_remaining": 1 if raw.get("state") == "OPEN" else 0,
+        "awards_remaining": 1 if str(raw.get("state") or "").upper() == "OPEN" else 0,
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def _gh_bounty_issue(raw: dict[str, Any]) -> dict[str, Any]:
return {
"number": raw["number"],
"title": raw.get("title"),
"state": raw.get("state"),
"labels": raw.get("labels", []),
"awards_remaining": 1 if raw.get("state") == "OPEN" else 0,
}
def _gh_bounty_issue(raw: dict[str, Any]) -> dict[str, Any]:
return {
"number": raw["number"],
"title": raw.get("title"),
"state": raw.get("state"),
"labels": raw.get("labels", []),
"awards_remaining": 1 if str(raw.get("state") or "").upper() == "OPEN" else 0,
}

Copy link
Copy Markdown
Contributor

@goodgoodclaw goodgoodclaw left a comment

Choose a reason for hiding this comment

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

Reviewed current head a7dcf2d5d849592dc6f6f948f585cc7a9549dfd5 for #645.

Blocker found:

  • scripts/pr_queue_health.py treats an issue with live metadata shape but empty labels and empty comments as live/open. That conflicts with the PR description and #645 goal: when live metadata is available, a referenced bounty should require both the mrwk:bounty label and a Reserved on MergeWork: claims-open comment before it is considered claimable.
  • Reproduction against current head:
    • Input bounty: {"number": 645, "state": "OPEN", "awards_remaining": 1, "labels": [], "comments": []} with a PR body Refs #645.
    • Observed summary: live_bounties: 1, non_live_bounties: 0, non_live_bounty_references: 0.
    • Expected: non-live bounty and non-live reference, with missing mrwk:bounty label and missing Reserved on MergeWork comment.
  • Suggested fix: remove the if not labels and not comments: return True, "open" fallback, or limit the compatibility fallback to the existing "comments" not in raw branch only. Add a regression test for the empty-labels/empty-comments live metadata shape.

Evidence checked:

  • Inspected _comments, _bounty_liveness, analyze_queue, load_live_queue, and the new queue health tests.
  • Confirmed the live loader now fetches comments only for referenced bounty issue numbers and passes comments into the bounty map.
  • Confirmed markdown/text/json report paths include non_live_bounty_references when classification catches the issue.
  • Checked CodeRabbit's two actionable comments; the empty metadata case above is reproducible and affects the stated guard behavior. The state == "OPEN" casing note is robustness polish, not a blocker for current gh output.

Validation run locally:

  • uv run --python 3.12 --with pytest python -m pytest tests/test_pr_queue_health.py -q -> 18 passed.
  • uvx ruff check scripts/pr_queue_health.py tests/test_pr_queue_health.py -> All checks passed.
  • uvx ruff format --check scripts/pr_queue_health.py tests/test_pr_queue_health.py -> 2 files already formatted.
  • uv run --python 3.12 --with mypy python -m mypy scripts/pr_queue_health.py -> Success: no issues found in 1 source file.
  • uv run --python 3.12 python scripts/pr_queue_health.py --repo ramimbo/mergework --format markdown -> completed; live queue reported 0 non-live references, 4 dirty/unstable PRs, and 2 needs-info PRs.
  • git diff --check origin/main...HEAD -> clean.
  • git merge-tree --write-tree origin/main HEAD -> clean tree 9002ce380387fd4306061cd721d924afc22a827e.

No private data, credentials, wallet material, production mutation, price/exchange/bridge/off-ramp claims, or fabricated payout claims used.

@ramimbo
Copy link
Copy Markdown
Owner

ramimbo commented May 31, 2026

Held for #645.

This overlaps #675 and is not accepted for the single #645 award in this pass. Current blockers: requested changes found a reproducible liveness-classification problem, and the duplicate #645 lane needs one final implementation selected rather than paying or merging both PRs.

Next useful step: update the implementation against the requested-changes review or coordinate with the #675 direction, then get fresh current-head review evidence.

@ramimbo
Copy link
Copy Markdown
Owner

ramimbo commented May 31, 2026

Closing as superseded. The duplicate #645 queue-health scope was accepted through merged PR #675, and bounty #645 / bounty 93 is now paid with no awards remaining.

This PR is not accepted or paid.

@ramimbo ramimbo closed this May 31, 2026
@ramimbo ramimbo added mrwk:rejected Submission rejected and removed mrwk:needs-info More information needed labels May 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mrwk:rejected Submission rejected

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants