From 65a88c4f2e9151ba150fa3e69b312cc8b479cad5 Mon Sep 17 00:00:00 2001 From: TJCurnutte <211682330+TJCurnutte@users.noreply.github.com> Date: Wed, 13 May 2026 18:03:40 -0400 Subject: [PATCH] test: add CodeBounty issue 37 linkage fixture --- bounty-notes/issue-37-bounty-linkage.md | 27 ++++++ scripts/validate-codebounty-issue-37.py | 86 +++++++++++++++++++ .../codebounty-issue-37-bounty-linkage.json | 37 ++++++++ 3 files changed, 150 insertions(+) create mode 100644 bounty-notes/issue-37-bounty-linkage.md create mode 100644 scripts/validate-codebounty-issue-37.py create mode 100644 test-fixtures/codebounty-issue-37-bounty-linkage.json diff --git a/bounty-notes/issue-37-bounty-linkage.md b/bounty-notes/issue-37-bounty-linkage.md new file mode 100644 index 0000000..c2e4acc --- /dev/null +++ b/bounty-notes/issue-37-bounty-linkage.md @@ -0,0 +1,27 @@ +# CodeBounty issue #37 linkage note + +Issue: https://github.com/CodeBountyOrg/BountyTestRepository/issues/37 + +## Snapshot + +- State: open +- Locked: false +- Assignees: none +- Label: `💰 Bounty Available` +- Visible CodeBounty amount: `$50 USD` +- Required PR syntax from bot announcement: `fixes #37` +- Collision searches run immediately before this branch: `37`, `fixes #37`, `issue 37`, and `issue march 14 315pm`; exact same-scope open PR count was `0`. + +## Payout boundary + +This is a submitted-visible CodeBounty action only. The bot announcement says a developer must submit an application through CodeBounty to be eligible, so this PR must not be treated as verified-payable or paid until platform/maintainer acceptance is confirmed. + +## Local validation + +```bash +python3 -m py_compile scripts/validate-codebounty-issue-37.py +python3 scripts/validate-codebounty-issue-37.py test-fixtures/codebounty-issue-37-bounty-linkage.json +git diff --check +``` + +The PR body should include `fixes #37` to satisfy the CodeBounty linkage rule. diff --git a/scripts/validate-codebounty-issue-37.py b/scripts/validate-codebounty-issue-37.py new file mode 100644 index 0000000..8f8d12e --- /dev/null +++ b/scripts/validate-codebounty-issue-37.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +"""Validate the CodeBounty issue #37 bounty-linkage fixture. + +The fixture is intentionally local and deterministic: it records the live +GitHub/CodeBounty snapshot used for the PR and checks that the public PR can +carry the required `fixes #37` linkage without overstating payout certainty. +""" + +from __future__ import annotations + +import json +import sys +from pathlib import Path + + +def fail(message: str) -> None: + raise SystemExit(f"issue-37 fixture invalid: {message}") + + +def main() -> None: + if len(sys.argv) != 2: + fail("usage: validate-codebounty-issue-37.py ") + + path = Path(sys.argv[1]) + if not path.is_file(): + fail(f"missing fixture: {path}") + + data = json.loads(path.read_text(encoding="utf-8")) + issue = data.get("issue") or {} + bounty = data.get("bounty") or {} + collision = data.get("collision_snapshot") or {} + expected_pr = data.get("expected_pr") or {} + + if issue.get("number") != 37: + fail("issue number must be 37") + if issue.get("state") != "open": + fail("issue must be open at snapshot time") + if issue.get("locked") is not False: + fail("locked must be false at snapshot time") + if issue.get("assignees") != []: + fail("issue must be unassigned at snapshot time") + if "💰 Bounty Available" not in issue.get("labels", []): + fail("bounty-available label missing") + + if bounty.get("platform") != "CodeBounty": + fail("platform must be CodeBounty") + if bounty.get("visible_amount_usd") != 50: + fail("visible bounty amount must be $50") + if bounty.get("required_pr_linkage", "").lower() != "fixes #37": + fail("required PR linkage must be `fixes #37`") + if bounty.get("developer_application_required") is not True: + fail("developer application requirement must stay explicit") + if bounty.get("verified_payable_at_snapshot") is not False: + fail("fixture must not claim verified-payable payout") + + if collision.get("repo_archived") is not False: + fail("repo must be non-archived at snapshot time") + if collision.get("repo_visibility") != "PUBLIC": + fail("repo visibility must be PUBLIC") + if collision.get("same_scope_open_pr_count") != 0: + fail("same-scope open PR count must be zero at snapshot time") + terms = {term.lower() for term in collision.get("open_pr_search_terms", [])} + if {"37", "fixes #37", "issue 37"} - terms: + fail("collision-search terms are incomplete") + + required_body = {item.lower() for item in expected_pr.get("body_must_include", [])} + if "fixes #37" not in required_body or "developer_application_required" not in required_body: + fail("expected PR body requirements must preserve issue linkage and payout blocker") + + print( + json.dumps( + { + "ok": True, + "issue": issue["number"], + "visible_amount_usd": bounty["visible_amount_usd"], + "required_pr_linkage": bounty["required_pr_linkage"], + "verified_payable_at_snapshot": bounty["verified_payable_at_snapshot"], + "same_scope_open_pr_count": collision["same_scope_open_pr_count"], + }, + sort_keys=True, + ) + ) + + +if __name__ == "__main__": + main() diff --git a/test-fixtures/codebounty-issue-37-bounty-linkage.json b/test-fixtures/codebounty-issue-37-bounty-linkage.json new file mode 100644 index 0000000..12d31b2 --- /dev/null +++ b/test-fixtures/codebounty-issue-37-bounty-linkage.json @@ -0,0 +1,37 @@ +{ + "issue": { + "number": 37, + "url": "https://github.com/CodeBountyOrg/BountyTestRepository/issues/37", + "title": "issue march 14 315pm", + "state": "open", + "body": "desc", + "labels": ["💰 Bounty Available"], + "assignees": [], + "locked": false + }, + "bounty": { + "platform": "CodeBounty", + "visible_amount_usd": 50, + "status_at_snapshot": "announced", + "required_pr_linkage": "fixes #37", + "developer_application_required": true, + "verified_payable_at_snapshot": false, + "blocker": "The CodeBounty announcement requires a platform application; GitHub-only PR submission is submitted-visible, not verified-payable." + }, + "collision_snapshot": { + "checked_at": "2026-05-13T21:59:28Z", + "repo_archived": false, + "repo_visibility": "PUBLIC", + "open_pr_search_terms": ["37", "fixes #37", "issue 37", "issue march 14 315pm"], + "same_scope_open_pr_count": 0 + }, + "expected_pr": { + "title": "test: add CodeBounty issue 37 linkage fixture", + "body_must_include": [ + "fixes #37", + "CodeBounty", + "$50", + "developer_application_required" + ] + } +}