diff --git a/ISSUE-11-VALIDATION.md b/ISSUE-11-VALIDATION.md new file mode 100644 index 0000000..3cd4784 --- /dev/null +++ b/ISSUE-11-VALIDATION.md @@ -0,0 +1,25 @@ +# Issue #11 validation receipt + +- Issue: https://github.com/CodeBountyOrg/BountyTestRepository/issues/11 +- Visible amount/source: $10 USD from CodeBounty bot comment plus `💰 Bounty Available` label +- Announcement comment: https://github.com/CodeBountyOrg/BountyTestRepository/issues/11#issuecomment-2655518687 +- Platform bounty URL: https://dev.codebounty.ai/bounty/67ad8292bf2a3690859c18df +- Required linkage: `Fixes #11` +- Local fixture: `test-fixtures/codebounty-issue-11-title-test.json` +- Local validator: `scripts/validate-codebounty-issue-11.py` + +## Commands + +```bash +python3 -m py_compile scripts/validate-codebounty-issue-11.py +python3 scripts/validate-codebounty-issue-11.py test-fixtures/codebounty-issue-11-title-test.json +git diff --check +``` + +## Snapshot boundary + +Fresh pre-push triage showed issue #11 open, unlocked, unassigned, repo public/not archived, and zero same-scope open PR collisions for `11`, `#11`, `fixes #11`, `issue 11`, `Bounty Launch`, or `Issue title test`. + +## Claim boundary + +This artifact counts as submitted-visible only after a public PR exists. Verified-payable remains blocked until CodeBounty application eligibility and maintainer/platform acceptance are verified. diff --git a/bounty-notes/issue-11-title-test.md b/bounty-notes/issue-11-title-test.md new file mode 100644 index 0000000..ffdee77 --- /dev/null +++ b/bounty-notes/issue-11-title-test.md @@ -0,0 +1,21 @@ +# CodeBounty issue #11 — title-test fixture note + +This note captures the public CodeBounty evidence for issue #11 so the test repository has a small, deterministic artifact tied to the bounty flow. + +## Public evidence + +- GitHub issue: https://github.com/CodeBountyOrg/BountyTestRepository/issues/11 +- Title: `Issue title test` +- Body snapshot: `no description` +- Public label: `💰 Bounty Available` +- Announcement: https://github.com/CodeBountyOrg/BountyTestRepository/issues/11#issuecomment-2655518687 +- Visible amount: `$10 USD` +- Bot-linked bounty URL: `https://dev.codebounty.ai/bounty/67ad8292bf2a3690859c18df` + +## Public-action gate + +The pre-push snapshot found the issue open, unlocked, unassigned, and free of exact same-scope open PR collisions. The required PR body linkage is `Fixes #11`. + +## Payout boundary + +This is submitted-visible only after the PR is public. It is not verified-payable until CodeBounty platform application eligibility plus maintainer/platform acceptance are verified. No paid funds are assumed from this fixture. diff --git a/scripts/validate-codebounty-issue-11.py b/scripts/validate-codebounty-issue-11.py new file mode 100644 index 0000000..f64b871 --- /dev/null +++ b/scripts/validate-codebounty-issue-11.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +"""Validate the deterministic fixture for CodeBounty issue #11. + +This repository is a CodeBounty test surface. The validator is stdlib-only so +maintainers can verify the fixture without platform credentials or dependency +installation. +""" + +from __future__ import annotations + +import json +import sys +from pathlib import Path +from typing import NoReturn + +EXPECTED_REPO = "CodeBountyOrg/BountyTestRepository" +EXPECTED_ISSUE = 11 +EXPECTED_AMOUNT = 10 +EXPECTED_LINKAGE = "fixes #11" +EXPECTED_COMMENT = ( + "https://github.com/CodeBountyOrg/BountyTestRepository/issues/11" + "#issuecomment-2655518687" +) +EXPECTED_PLATFORM_URL = "https://dev.codebounty.ai/bounty/67ad8292bf2a3690859c18df" + + +def fail(message: str) -> NoReturn: + print(f"FAIL: {message}", file=sys.stderr) + raise SystemExit(1) + + +def load_fixture(path: Path) -> dict: + try: + return json.loads(path.read_text(encoding="utf-8")) + except FileNotFoundError: + fail(f"fixture not found: {path}") + except json.JSONDecodeError as exc: + fail(f"invalid JSON fixture: {exc}") + + +def main(argv: list[str]) -> int: + fixture_path = Path(argv[1]) if len(argv) > 1 else Path( + "test-fixtures/codebounty-issue-11-title-test.json" + ) + data = load_fixture(fixture_path) + + issue = data.get("issue") or {} + bounty = data.get("bounty") or {} + collision = data.get("collision_snapshot") or {} + linkage = data.get("pr_linkage") or {} + deliverable = data.get("deliverable") or {} + + if issue.get("repo") != EXPECTED_REPO: + fail(f"expected repo {EXPECTED_REPO!r}, got {issue.get('repo')!r}") + if issue.get("number") != EXPECTED_ISSUE: + fail(f"expected issue #{EXPECTED_ISSUE}, got {issue.get('number')!r}") + if issue.get("state_at_snapshot") != "open": + fail("issue must be open at the captured snapshot") + if issue.get("locked_at_snapshot") is not False: + fail("issue must be unlocked at the captured snapshot") + if issue.get("assignees_at_snapshot") != []: + fail("issue must be unassigned at the captured snapshot") + if "💰 Bounty Available" not in issue.get("labels_at_snapshot", []): + fail("fixture must preserve the public bounty label") + if str(issue.get("title", "")).lower() != "issue title test": + fail("fixture title should preserve the issue #11 test identity") + if issue.get("body") != "no description": + fail("fixture should preserve the no-description issue body snapshot") + + if bounty.get("amount") != EXPECTED_AMOUNT or bounty.get("currency") != "USD": + fail(f"expected {EXPECTED_AMOUNT} USD bounty, got {bounty!r}") + if bounty.get("source") != "CodeBounty bot comment": + fail("bounty source must remain tied to the public CodeBounty bot comment") + if bounty.get("announcement_comment_url") != EXPECTED_COMMENT: + fail("announcement comment URL changed or missing") + if bounty.get("platform_bounty_url") != EXPECTED_PLATFORM_URL: + fail("platform bounty URL changed or missing") + if bounty.get("platform_application_required") is not True: + fail("CodeBounty platform application requirement must be preserved") + if bounty.get("verified_payable") is not False: + fail("verified_payable must stay false until acceptance/payout is verified") + + if collision.get("repo_archived") is not False: + fail("repo must be non-archived in the collision snapshot") + if collision.get("same_scope_open_prs") != []: + fail("fixture requires zero same-scope open PR collisions at snapshot") + if "Issue title test" not in collision.get("search_terms", []): + fail("collision search terms should include the distinctive issue title") + if str(linkage.get("required_phrase", "")).lower() != EXPECTED_LINKAGE: + fail("PR linkage must include Fixes #11") + if deliverable.get("type") != "codebounty-title-test-fixture": + fail("deliverable type should identify the CodeBounty title-test fixture") + + print( + json.dumps( + { + "ok": True, + "repo": issue["repo"], + "issue": issue["number"], + "visible_amount_usd": bounty["amount"], + "required_pr_phrase": linkage["required_phrase"], + "same_scope_open_prs": len(collision["same_scope_open_prs"]), + "verified_payable": bounty["verified_payable"], + }, + sort_keys=True, + ) + ) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv)) diff --git a/test-fixtures/codebounty-issue-11-title-test.json b/test-fixtures/codebounty-issue-11-title-test.json new file mode 100644 index 0000000..b64e442 --- /dev/null +++ b/test-fixtures/codebounty-issue-11-title-test.json @@ -0,0 +1,56 @@ +{ + "issue": { + "repo": "CodeBountyOrg/BountyTestRepository", + "number": 11, + "title": "Issue title test", + "url": "https://github.com/CodeBountyOrg/BountyTestRepository/issues/11", + "state_at_snapshot": "open", + "locked_at_snapshot": false, + "assignees_at_snapshot": [], + "labels_at_snapshot": [ + "💰 Bounty Available" + ], + "body": "no description" + }, + "bounty": { + "source": "CodeBounty bot comment", + "source_confidence": "bot-comment-plus-bounty-label", + "announcement_comment_url": "https://github.com/CodeBountyOrg/BountyTestRepository/issues/11#issuecomment-2655518687", + "platform_bounty_url": "https://dev.codebounty.ai/bounty/67ad8292bf2a3690859c18df", + "amount": 10, + "currency": "USD", + "label": "💰 Bounty Available", + "platform_application_required": true, + "verified_payable": false + }, + "collision_snapshot": { + "captured_at_utc": "2026-05-14T02:45:45Z", + "repo_archived": false, + "open_pr_count_at_repo": 36, + "search_terms": [ + "11", + "#11", + "fixes #11", + "issue 11", + "Bounty Launch", + "Issue title test" + ], + "same_scope_open_prs": [] + }, + "pr_linkage": { + "required_phrase": "Fixes #11", + "case_sensitive": false + }, + "deliverable": { + "type": "codebounty-title-test-fixture", + "purpose": "Preserve deterministic evidence for the CodeBounty title-test issue so future intake can validate issue state, visible amount, required GitHub linkage, collision checks, and payout boundary without relying on platform credentials.", + "acceptance_checks": [ + "fixture issue number is 11", + "visible CodeBounty amount is 10 USD", + "public bot announcement URL is recorded", + "no same-scope open PR collision existed at snapshot", + "PR body/linkage includes Fixes #11", + "verified-payable remains false until CodeBounty application and maintainer/platform acceptance are confirmed" + ] + } +}