Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions bounty-notes/issue-79-markdown-upload.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# CodeBounty issue #79 markdown/upload note

Issue: https://github.com/CodeBountyOrg/BountyTestRepository/issues/79

## Snapshot

- State: open
- Locked: false
- Assignees: none
- Labels: `enhancement`; bounty label absent in the live issue snapshot
- Visible CodeBounty amount: `$50 USD`, sourced from two CodeBounty bot announcement comments
- Required PR syntax from bot announcements: `fixes #79`
- Issue body includes bold markdown and a failed upload marker: `*Failed to upload Screenshot 2025-04-01 at 4.36.27 PM.png*`
- Collision searches run immediately before this branch: `79`, `fixes #79`, `issue 79`, and `test issue april 3 12pm`; 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, and this issue does not currently carry the `💰 Bounty Available` label. Do not treat this PR as verified-payable or paid until platform/maintainer acceptance is confirmed.

## Local validation

```bash
python3 -m py_compile scripts/validate-codebounty-issue-79.py
python3 scripts/validate-codebounty-issue-79.py test-fixtures/codebounty-issue-79-markdown-upload.json
git diff --check
```

The PR body should include `fixes #79` to satisfy the CodeBounty linkage rule and should preserve the `developer_application_required` / `bounty_label_absent` payout blockers.
114 changes: 114 additions & 0 deletions scripts/validate-codebounty-issue-79.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/usr/bin/env python3
"""Validate the CodeBounty issue #79 markdown/upload fixture.

The fixture records the live GitHub + CodeBounty snapshot used for this PR.
It keeps the payout boundary explicit: the visible amount comes from bot
announcement comments, not from a verified platform application or payment.
"""

from __future__ import annotations

import json
import sys
from pathlib import Path


EXPECTED_BOUNTY_LINKS = {
"http://localhost:3000/bounty/67f1cc90f54cb17267113c7e",
"http://localhost:3000/bounty/67f1ccb1f54cb17267113c83",
}


def fail(message: str) -> None:
raise SystemExit(f"issue-79 fixture invalid: {message}")


def main() -> None:
if len(sys.argv) != 2:
fail("usage: validate-codebounty-issue-79.py <fixture.json>")

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 {}
markdown = data.get("markdown_upload_snapshot") or {}
collision = data.get("collision_snapshot") or {}
expected_pr = data.get("expected_pr") or {}

if issue.get("number") != 79:
fail("issue number must be 79")
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 "enhancement" not in issue.get("labels", []):
fail("enhancement label missing from live snapshot")
if "💰 Bounty Available" in issue.get("labels", []):
fail("snapshot should document that issue #79 does not carry the bounty label")

body = issue.get("body", "")
if "**testing markdown**" not in body:
fail("issue body markdown sample missing")
if "failed to upload" not in body.lower():
fail("failed-upload marker missing from issue body")

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("visible_amount_source") != "bot_comments":
fail("visible amount source must stay scoped to bot comments")
if bounty.get("announcement_comment_count") != 2:
fail("expected two CodeBounty bot announcement comments")
if bounty.get("required_pr_linkage", "").lower() != "fixes #79":
fail("required PR linkage must be `fixes #79`")
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 set(bounty.get("bounty_links", [])) != EXPECTED_BOUNTY_LINKS:
fail("bounty links should match both announcement comment links")

if markdown.get("bold_markdown_preserved") is not True:
fail("markdown preservation flag must be true")
if markdown.get("failed_upload_recorded") is not True:
fail("failed upload evidence flag must be true")

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 {"79", "fixes #79", "issue 79", "test issue april 3 12pm"} - terms:
fail("collision-search terms are incomplete")

required_body = {item.lower() for item in expected_pr.get("body_must_include", [])}
for required in {"fixes #79", "codebounty", "$50", "developer_application_required", "bounty_label_absent"}:
if required not in required_body:
fail(f"expected PR body requirement missing: {required}")

print(
json.dumps(
{
"ok": True,
"issue": issue["number"],
"visible_amount_usd": bounty["visible_amount_usd"],
"visible_amount_source": bounty["visible_amount_source"],
"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()
54 changes: 54 additions & 0 deletions test-fixtures/codebounty-issue-79-markdown-upload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"issue": {
"number": 79,
"url": "https://github.com/CodeBountyOrg/BountyTestRepository/issues/79",
"title": "test issue april 3 12pm",
"state": "open",
"body": "test\n\n**testing markdown**\n\n*Failed to upload Screenshot 2025-04-01 at 4.36.27 PM.png*",
"labels": ["enhancement"],
"assignees": [],
"locked": false
},
"bounty": {
"platform": "CodeBounty",
"visible_amount_usd": 50,
"visible_amount_source": "bot_comments",
"status_at_snapshot": "announced_by_two_bot_comments_bounty_label_absent",
"announcement_comment_count": 2,
"announcement_comments": [
"https://github.com/CodeBountyOrg/BountyTestRepository/issues/79#issuecomment-2781152381",
"https://github.com/CodeBountyOrg/BountyTestRepository/issues/79#issuecomment-2781152397"
],
"bounty_links": [
"http://localhost:3000/bounty/67f1cc90f54cb17267113c7e",
"http://localhost:3000/bounty/67f1ccb1f54cb17267113c83"
],
"required_pr_linkage": "fixes #79",
"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. The issue itself lacks the bounty-available label, so the visible amount is sourced only from bot comments."
},
"markdown_upload_snapshot": {
"bold_markdown_preserved": true,
"failed_upload_recorded": true,
"failed_upload_filename": "Screenshot 2025-04-01 at 4.36.27 PM.png",
"note": "This fixture preserves the issue's markdown and failed-upload evidence so the PR has a deterministic validation target instead of a placeholder edit."
},
"collision_snapshot": {
"checked_at": "2026-05-13T22:43:39Z",
"repo_archived": false,
"repo_visibility": "PUBLIC",
"open_pr_search_terms": ["79", "fixes #79", "issue 79", "test issue april 3 12pm"],
"same_scope_open_pr_count": 0
},
"expected_pr": {
"title": "test: add CodeBounty issue 79 markdown fixture",
"body_must_include": [
"fixes #79",
"CodeBounty",
"$50",
"developer_application_required",
"bounty_label_absent"
]
}
}