From eea27775fd0887d906097a48f57fa454ea522c7e Mon Sep 17 00:00:00 2001 From: tinyopsstudio Date: Wed, 27 May 2026 19:31:55 -0400 Subject: [PATCH 01/11] Ignore native bounty ids in queue refs Bounty #427: scripts/pr_queue_health.py --- scripts/pr_queue_health.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/pr_queue_health.py b/scripts/pr_queue_health.py index e96ed86d..2c072e1b 100644 --- a/scripts/pr_queue_health.py +++ b/scripts/pr_queue_health.py @@ -8,7 +8,10 @@ from collections import defaultdict from typing import Any -BOUNTY_REF_RE = re.compile(r"\b(?:bounty|refs?|fixes|closes|claims?)\s+#(\d+)", re.IGNORECASE) +BOUNTY_REF_RE = re.compile( + r"(?:(? dict[str, Any]: _issue( pr, "missing_bounty_reference", - "No Bounty #, Refs #, or /claim # found", + "No Bounty #, Issue #, Refs #, or /claim # found", ) ) for ref in pr["refs"]: From 67e738a9c443e0969dc5795ea4ba6c2f7deb547a Mon Sep 17 00:00:00 2001 From: tinyopsstudio Date: Wed, 27 May 2026 19:32:04 -0400 Subject: [PATCH 02/11] Cover native bounty id queue refs Bounty #427: tests/test_pr_queue_health.py --- tests/test_pr_queue_health.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tests/test_pr_queue_health.py b/tests/test_pr_queue_health.py index 58ff8fbe..a02f8ec6 100644 --- a/tests/test_pr_queue_health.py +++ b/tests/test_pr_queue_health.py @@ -127,6 +127,38 @@ def test_pr_queue_health_accepts_claim_command_reference() -> None: assert report["missing_bounty_references"] == [] +def test_pr_queue_health_ignores_native_bounty_ids_when_issue_ref_is_present() -> None: + report = analyze_queue( + { + "bounties": [{"number": 406, "state": "OPEN", "awards_remaining": 16}], + "pull_requests": [ + { + "number": 524, + "title": "Refs #406: Reject malformed IPv4 public URLs", + "body": ( + "Focused #406 small fix. Evidence: live bounty #66 / issue #406 " + "preflight returned status=open." + ), + "merge_state": "clean", + "labels": [], + }, + { + "number": 525, + "title": "Guard another #406 edge case", + "body": "MRWK bounty #66 maps to issue #406.", + "merge_state": "clean", + "labels": [], + }, + ], + } + ) + + assert report["summary"]["closed_bounty_references"] == 0 + assert report["summary"]["missing_bounty_references"] == 0 + assert report["closed_bounty_references"] == [] + assert report["missing_bounty_references"] == [] + + def test_pr_queue_health_markdown_report_includes_required_sections() -> None: report = analyze_queue( { @@ -183,7 +215,8 @@ def test_pr_queue_health_markdown_report_includes_required_sections() -> None: assert "### Missing bounty references" in markdown assert ( "- [PR #2](https://github.com/ramimbo/mergework/pull/2): " - "Improve bounty filters (No Bounty #, Refs #, or /claim # found)" + "Improve bounty filters " + "(No Bounty #, Issue #, Refs #, or /claim # found)" ) in markdown assert "### Dirty or unstable merge state" in markdown assert "Merge state is dirty" in markdown From 0c3f7073c63699370b536b669354eefea9d7df62 Mon Sep 17 00:00:00 2001 From: tinyopsstudio Date: Wed, 27 May 2026 20:02:42 -0400 Subject: [PATCH 03/11] Ignore native bounty ids in queue refs --- scripts/pr_queue_health.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/pr_queue_health.py b/scripts/pr_queue_health.py index 2c072e1b..4fbc6cbe 100644 --- a/scripts/pr_queue_health.py +++ b/scripts/pr_queue_health.py @@ -9,7 +9,8 @@ from typing import Any BOUNTY_REF_RE = re.compile( - r"(?:(? Date: Wed, 27 May 2026 20:02:51 -0400 Subject: [PATCH 04/11] Cover native bounty id queue refs --- tests/test_pr_queue_health.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_pr_queue_health.py b/tests/test_pr_queue_health.py index a02f8ec6..58cf6df0 100644 --- a/tests/test_pr_queue_health.py +++ b/tests/test_pr_queue_health.py @@ -149,6 +149,22 @@ def test_pr_queue_health_ignores_native_bounty_ids_when_issue_ref_is_present() - "merge_state": "clean", "labels": [], }, + { + "number": 526, + "title": "Ignore native #406 evidence ids", + "body": ( + "Evidence: native bounty #66 / issue #406 preflight returned status=open." + ), + "merge_state": "clean", + "labels": [], + }, + { + "number": 527, + "title": "Ignore internal #406 evidence ids", + "body": "Evidence: internal bounty #66, issue #406 is the GitHub bounty.", + "merge_state": "clean", + "labels": [], + }, ], } ) From a1eee392756fcc7f167ad59f514a786e44d978c3 Mon Sep 17 00:00:00 2001 From: tinyopsstudio Date: Wed, 27 May 2026 20:12:34 -0400 Subject: [PATCH 05/11] Ignore native bounty ids in queue refs --- scripts/pr_queue_health.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scripts/pr_queue_health.py b/scripts/pr_queue_health.py index 4fbc6cbe..5c9ff38f 100644 --- a/scripts/pr_queue_health.py +++ b/scripts/pr_queue_health.py @@ -9,8 +9,11 @@ from typing import Any BOUNTY_REF_RE = re.compile( - r"(?:(?bounty|issues?|refs?|fixes|closes|claims?)\s+#(?P\d+)", + re.IGNORECASE, +) +NATIVE_BOUNTY_PREFIX_RE = re.compile( + r"(?:^|[^A-Za-z0-9_])(?:live|mrwk|native|internal)\s+$", re.IGNORECASE, ) NOISY_TITLE_PREFIX_RE = re.compile(r"^\s*(?:\[[^\]]+\]\s*)+") @@ -59,7 +62,14 @@ def _bounty_refs(raw: dict[str, Any]) -> list[int]: for key in ("title", "body", "description") if raw.get(key) is not None ) - return sorted({int(match) for match in BOUNTY_REF_RE.findall(text)}) + refs: set[int] = set() + for match in BOUNTY_REF_RE.finditer(text): + if match.group("keyword").lower() == "bounty" and NATIVE_BOUNTY_PREFIX_RE.search( + text[: match.start()] + ): + continue + refs.add(int(match.group("number"))) + return sorted(refs) def _is_open_bounty(raw: dict[str, Any]) -> bool: From 2ed82bd29cbc64f13aae6736305a3835402b6760 Mon Sep 17 00:00:00 2001 From: tinyopsstudio Date: Wed, 27 May 2026 20:12:42 -0400 Subject: [PATCH 06/11] Cover native bounty id queue refs --- tests/test_pr_queue_health.py | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/test_pr_queue_health.py b/tests/test_pr_queue_health.py index 58cf6df0..aa15a45b 100644 --- a/tests/test_pr_queue_health.py +++ b/tests/test_pr_queue_health.py @@ -175,6 +175,47 @@ def test_pr_queue_health_ignores_native_bounty_ids_when_issue_ref_is_present() - assert report["missing_bounty_references"] == [] +def test_pr_queue_health_does_not_accept_native_only_bounty_id() -> None: + report = analyze_queue( + { + "bounties": [{"number": 406, "state": "OPEN", "awards_remaining": 1}], + "pull_requests": [ + { + "number": 530, + "title": "Fix edge case", + "body": "Evidence: live bounty #66 preflight check passed.", + "merge_state": "clean", + "labels": [], + } + ], + } + ) + + assert report["summary"]["missing_bounty_references"] == 1 + assert report["missing_bounty_references"][0]["reason"] == "missing_bounty_reference" + assert report["closed_bounty_references"] == [] + + +def test_pr_queue_health_keeps_non_native_bounty_words() -> None: + report = analyze_queue( + { + "bounties": [{"number": 66, "state": "OPEN", "awards_remaining": 1}], + "pull_requests": [ + { + "number": 531, + "title": "Fix relive wording", + "body": "Evidence: relive bounty #66 still names a GitHub bounty issue.", + "merge_state": "clean", + "labels": [], + } + ], + } + ) + + assert report["summary"]["missing_bounty_references"] == 0 + assert report["summary"]["closed_bounty_references"] == 0 + + def test_pr_queue_health_markdown_report_includes_required_sections() -> None: report = analyze_queue( { From da80b9e1190dad74b948f3cc8a5dc1ed48dbd4ae Mon Sep 17 00:00:00 2001 From: tinyopsstudio Date: Wed, 27 May 2026 20:13:13 -0400 Subject: [PATCH 07/11] Ignore native bounty ids in queue refs --- scripts/pr_queue_health.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/scripts/pr_queue_health.py b/scripts/pr_queue_health.py index 5c9ff38f..1e74bc28 100644 --- a/scripts/pr_queue_health.py +++ b/scripts/pr_queue_health.py @@ -9,11 +9,8 @@ from typing import Any BOUNTY_REF_RE = re.compile( - r"\b(?Pbounty|issues?|refs?|fixes|closes|claims?)\s+#(?P\d+)", - re.IGNORECASE, -) -NATIVE_BOUNTY_PREFIX_RE = re.compile( - r"(?:^|[^A-Za-z0-9_])(?:live|mrwk|native|internal)\s+$", + r"\b(?:(?Plive|mrwk|native|internal)\s+)?" + r"(?Pbounty|issues?|refs?|fixes|closes|claims?)\s+#(?P\d+)", re.IGNORECASE, ) NOISY_TITLE_PREFIX_RE = re.compile(r"^\s*(?:\[[^\]]+\]\s*)+") @@ -62,11 +59,9 @@ def _bounty_refs(raw: dict[str, Any]) -> list[int]: for key in ("title", "body", "description") if raw.get(key) is not None ) - refs: set[int] = set() + refs = set() for match in BOUNTY_REF_RE.finditer(text): - if match.group("keyword").lower() == "bounty" and NATIVE_BOUNTY_PREFIX_RE.search( - text[: match.start()] - ): + if match.group("native_prefix") and match.group("keyword").lower() == "bounty": continue refs.add(int(match.group("number"))) return sorted(refs) From ae621671071caf3cb44f4bae03e3ea2c3946a3f5 Mon Sep 17 00:00:00 2001 From: tinyopsstudio Date: Wed, 27 May 2026 20:13:21 -0400 Subject: [PATCH 08/11] Cover native bounty id queue refs --- tests/test_pr_queue_health.py | 47 ++++++++++++++++------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/tests/test_pr_queue_health.py b/tests/test_pr_queue_health.py index aa15a45b..c374e29d 100644 --- a/tests/test_pr_queue_health.py +++ b/tests/test_pr_queue_health.py @@ -149,6 +149,15 @@ def test_pr_queue_health_ignores_native_bounty_ids_when_issue_ref_is_present() - "merge_state": "clean", "labels": [], }, + { + "number": 528, + "title": "Ignore spaced live bounty evidence ids", + "body": ( + "Evidence: live bounty #66 and live\tbounty #67 both map to issue #406." + ), + "merge_state": "clean", + "labels": [], + }, { "number": 526, "title": "Ignore native #406 evidence ids", @@ -175,45 +184,31 @@ def test_pr_queue_health_ignores_native_bounty_ids_when_issue_ref_is_present() - assert report["missing_bounty_references"] == [] -def test_pr_queue_health_does_not_accept_native_only_bounty_id() -> None: +def test_pr_queue_health_requires_issue_ref_when_only_native_bounty_id_is_present() -> None: report = analyze_queue( { - "bounties": [{"number": 406, "state": "OPEN", "awards_remaining": 1}], + "bounties": [{"number": 406, "state": "OPEN", "awards_remaining": 16}], "pull_requests": [ { - "number": 530, - "title": "Fix edge case", - "body": "Evidence: live bounty #66 preflight check passed.", + "number": 529, + "title": "Needs GitHub issue reference", + "body": "Evidence: live bounty #66 returned status=open.", "merge_state": "clean", "labels": [], - } - ], - } - ) - - assert report["summary"]["missing_bounty_references"] == 1 - assert report["missing_bounty_references"][0]["reason"] == "missing_bounty_reference" - assert report["closed_bounty_references"] == [] - - -def test_pr_queue_health_keeps_non_native_bounty_words() -> None: - report = analyze_queue( - { - "bounties": [{"number": 66, "state": "OPEN", "awards_remaining": 1}], - "pull_requests": [ + }, { - "number": 531, - "title": "Fix relive wording", - "body": "Evidence: relive bounty #66 still names a GitHub bounty issue.", + "number": 530, + "title": "Longer words still count as bounty refs", + "body": "Evidence: relive bounty #406 returned status=open.", "merge_state": "clean", "labels": [], - } + }, ], } ) - assert report["summary"]["missing_bounty_references"] == 0 - assert report["summary"]["closed_bounty_references"] == 0 + assert report["summary"]["missing_bounty_references"] == 1 + assert report["missing_bounty_references"][0]["pull_request"] == 529 def test_pr_queue_health_markdown_report_includes_required_sections() -> None: From 918d029145865f5f1dcf253c49655b5df6d3e51a Mon Sep 17 00:00:00 2001 From: tinyopsstudio Date: Thu, 28 May 2026 06:34:39 -0400 Subject: [PATCH 09/11] Ignore native bounty ids in queue refs --- scripts/pr_queue_health.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/pr_queue_health.py b/scripts/pr_queue_health.py index 1e74bc28..7017ddf1 100644 --- a/scripts/pr_queue_health.py +++ b/scripts/pr_queue_health.py @@ -51,15 +51,15 @@ def _scope_key(raw: dict[str, Any]) -> str: def _bounty_refs(raw: dict[str, Any]) -> list[int]: explicit = raw.get("bounty_refs") if isinstance(explicit, list): - refs = [item for item in explicit if isinstance(item, int)] - if refs: - return sorted(set(refs)) + explicit_refs = [item for item in explicit if isinstance(item, int)] + if explicit_refs: + return sorted(set(explicit_refs)) text = "\n".join( str(raw.get(key) or "") for key in ("title", "body", "description") if raw.get(key) is not None ) - refs = set() + refs: set[int] = set() for match in BOUNTY_REF_RE.finditer(text): if match.group("native_prefix") and match.group("keyword").lower() == "bounty": continue From 024371fb2c0a10be2b407369e6bccdb369745578 Mon Sep 17 00:00:00 2001 From: tinyopsstudio Date: Thu, 28 May 2026 06:41:41 -0400 Subject: [PATCH 10/11] Ignore native bounty ids in queue refs --- scripts/pr_queue_health.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/pr_queue_health.py b/scripts/pr_queue_health.py index 7017ddf1..4eafcc5a 100644 --- a/scripts/pr_queue_health.py +++ b/scripts/pr_queue_health.py @@ -51,7 +51,9 @@ def _scope_key(raw: dict[str, Any]) -> str: def _bounty_refs(raw: dict[str, Any]) -> list[int]: explicit = raw.get("bounty_refs") if isinstance(explicit, list): - explicit_refs = [item for item in explicit if isinstance(item, int)] + explicit_refs = [ + item for item in explicit if isinstance(item, int) and not isinstance(item, bool) + ] if explicit_refs: return sorted(set(explicit_refs)) text = "\n".join( From dcf8b6b6dcd0c5edc134e95e008c63282185f9ee Mon Sep 17 00:00:00 2001 From: tinyopsstudio Date: Thu, 28 May 2026 06:41:50 -0400 Subject: [PATCH 11/11] Cover native bounty id queue refs --- tests/test_pr_queue_health.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/test_pr_queue_health.py b/tests/test_pr_queue_health.py index c374e29d..67be0ece 100644 --- a/tests/test_pr_queue_health.py +++ b/tests/test_pr_queue_health.py @@ -127,6 +127,36 @@ def test_pr_queue_health_accepts_claim_command_reference() -> None: assert report["missing_bounty_references"] == [] +def test_pr_queue_health_ignores_boolean_explicit_bounty_refs() -> None: + report = analyze_queue( + { + "bounties": [{"number": 406, "state": "OPEN", "awards_remaining": 1}], + "pull_requests": [ + { + "number": 531, + "title": "Boolean refs are not issue refs", + "body": "", + "bounty_refs": [True, False], + "merge_state": "clean", + "labels": [], + }, + { + "number": 532, + "title": "Valid explicit issue ref still counts", + "body": "", + "bounty_refs": [True, 406], + "merge_state": "clean", + "labels": [], + }, + ], + } + ) + + assert report["summary"]["missing_bounty_references"] == 1 + assert report["missing_bounty_references"][0]["pull_request"] == 531 + assert report["closed_bounty_references"] == [] + + def test_pr_queue_health_ignores_native_bounty_ids_when_issue_ref_is_present() -> None: report = analyze_queue( {