diff --git a/.github/ISSUE_TEMPLATE/bounty.yml b/.github/ISSUE_TEMPLATE/bounty.yml index 69600232..e252cb4f 100644 --- a/.github/ISSUE_TEMPLATE/bounty.yml +++ b/.github/ISSUE_TEMPLATE/bounty.yml @@ -1,13 +1,13 @@ name: MRWK bounty description: Propose work that may receive an MRWK bounty. -title: "[bounty] " +title: "MRWK bounty: MRWK - " labels: ["mrwk:bounty"] body: - type: textarea id: work attributes: label: Work needed - description: Describe the useful accepted work. + description: Describe the focused work, affected surface, and why it is useful. validations: required: true - type: input @@ -15,6 +15,7 @@ body: attributes: label: Proposed MRWK per award placeholder: "250" + description: Repeat the per-award amount from the issue title. validations: required: true - type: input @@ -22,6 +23,7 @@ body: attributes: label: Max awards placeholder: "1" + description: Use 1 for a single accepted submission or a higher number for distinct awards. validations: required: true - type: textarea @@ -31,3 +33,24 @@ body: description: Explain what must be true before mrwk:accepted is applied. validations: required: true + - type: textarea + id: evidence + attributes: + label: Evidence or tests + description: Name required commands, screenshots, live public URLs, or reproduction evidence. + placeholder: "Example: run python scripts/docs_smoke.py and relevant focused tests." + - type: textarea + id: out_of_scope + attributes: + label: Out of scope + description: List broad rewrites, duplicate work, style-only changes, private security detail, or unrelated work that will not qualify. + - type: textarea + id: duplicate_stale + attributes: + label: Duplicate and stale work + description: Tell contributors to check open PRs, comments, active attempts, and accepted work before submitting. + - type: textarea + id: public_artifact_hygiene + attributes: + label: Public artifact hygiene + description: Remind contributors not to include secrets, private vulnerability details, price claims, liquidity claims, exchange claims, bridge promises, off-ramp promises, or fabricated payout claims. diff --git a/docs/admin-runbook.md b/docs/admin-runbook.md index 1f270c75..2367c045 100644 --- a/docs/admin-runbook.md +++ b/docs/admin-runbook.md @@ -4,12 +4,19 @@ 1. Create or choose a GitHub issue. 2. Decide the MRWK amount using the reference tiers. -3. Add acceptance text that explains what counts as useful accepted work. -4. Set `max_awards` to the number of separate payouts allowed. Use `1` for +3. Use the maintainer bounty post template in + [bounty rules](bounty-rules.md#maintainer-bounty-post-template). The issue + title should follow `MRWK bounty: MRWK - ` so the + reward is visible in lists, notifications, the API, and MCP tools. +4. Add acceptance text that explains what counts as useful accepted work, which + evidence or tests are required, and what is out of scope. +5. Set `max_awards` to the number of separate payouts allowed. Use `1` for a single-award bounty. -5. Use `/admin` or `POST /api/v1/bounties` with an admin token. +6. Include duplicate-work, stale-work, and public artifact hygiene rules when + the bounty could attract overlapping agent submissions. +7. Use `/admin` or `POST /api/v1/bounties` with an admin token. Multi-award bounties reserve `reward_mrwk * max_awards`. -6. Add `mrwk:bounty` to the GitHub issue. +8. Add `mrwk:bounty` to the GitHub issue. ## Accept Work diff --git a/docs/bounty-rules.md b/docs/bounty-rules.md index 6950f180..19b7bc2a 100644 --- a/docs/bounty-rules.md +++ b/docs/bounty-rules.md @@ -34,6 +34,66 @@ MRWK uses work-based tiers at launch. The project does not publish a fiat peg. - `mrwk:rejected`: submission was not accepted. - `mrwk:needs-info`: maintainer needs more detail. +## Maintainer Bounty Post Template + +Use stable headings so humans, agents, the public API, and MCP tools can parse a +bounty without guessing. Put the reward in the issue title: + +```text +MRWK bounty: MRWK - +``` + +Copy this body and replace the placeholders: + +```text +## MRWK Bounty + +Reward: ` MRWK per accepted award` +Max awards: `` + +## Work Needed + +Describe the focused work, affected page, workflow, docs area, code path, or +review target. + +## Acceptance Criteria + +- List the exact conditions that must be true before work can be accepted. +- Include required commands, screenshots, links, or reproduction evidence. +- State any bounty-specific constraints such as one award per distinct scope. + +## How To Submit + +Open a focused PR, review, issue comment, or discussion post with `Bounty +#` or `Refs #` unless this bounty asks for a +different reference. + +## Evidence Or Tests + +Name the checks expected for this bounty, such as `python scripts/docs_smoke.py`, +focused tests for touched code, live public URLs checked, or screenshots for UI +changes. + +## Out Of Scope + +List work that does not qualify, including broad rewrites, typo-only edits, +style-only changes, unrelated refactors, private security details, or claims +outside the stated scope. + +## Duplicate And Stale Work + +Submissions must check current open PRs, issue comments, active attempts, and +accepted work. Duplicate, superseded, or stale work does not qualify unless the +bounty text explicitly allows a distinct follow-up. + +## Public Artifact Hygiene + +Do not include private keys, seed material, credentials, private vulnerability +details, deployment secrets, price claims, investment claims, liquidity claims, +exchange claims, bridge promises, off-ramp promises, or fabricated payout +claims. +``` + ## How Claims Are Reviewed Maintainers approve useful accepted work that matches the bounty text and has diff --git a/scripts/docs_smoke.py b/scripts/docs_smoke.py index 0871c020..72763f8c 100644 --- a/scripts/docs_smoke.py +++ b/scripts/docs_smoke.py @@ -52,10 +52,16 @@ "Smoke-check or bug-report claim:", "Discussion or decision-support claim:", "Do not describe work as accepted, merged, or paid until the public GitHub label", + "## Maintainer Bounty Post Template", + "MRWK bounty: MRWK - ", + "## Evidence Or Tests", + "## Duplicate And Stale Work", + "## Public Artifact Hygiene", ], } LINK_RE = re.compile(r"\[[^\]]+\]\(([^)]+)\)") DOCS_ISSUE_TEMPLATE = ".github/ISSUE_TEMPLATE/docs.yml" +BOUNTY_ISSUE_TEMPLATE = ".github/ISSUE_TEMPLATE/bounty.yml" PR_TEMPLATE = ".github/pull_request_template.md" @@ -105,6 +111,21 @@ def main() -> int: if "link the page, docs file, heading, command, or ui path" not in template: print("docs issue template location prompt must request actionable evidence") ok = False + bounty_issue_template = ROOT / BOUNTY_ISSUE_TEMPLATE + if not bounty_issue_template.exists(): + print(f"missing bounty issue template: {BOUNTY_ISSUE_TEMPLATE}") + ok = False + else: + bounty_template = bounty_issue_template.read_text(encoding="utf-8").lower() + for phrase in [ + "mrwk bounty: mrwk -", + "evidence or tests", + "duplicate and stale work", + "public artifact hygiene", + ]: + if phrase not in bounty_template: + print(f"bounty issue template missing required guidance: {phrase}") + ok = False pr_template = ROOT / PR_TEMPLATE if not pr_template.exists(): print(f"missing pull request template: {PR_TEMPLATE}")