The project should use paid GitHub issues for its own roadmap as soon as the hosted low-value rail is available.
- Open a paid bounty issue with
.github/ISSUE_TEMPLATE/paid-bounty.yml. - The GitHub app parses the rendered issue form sections:
GoalAcceptance criteriaTemplateSuggested amountFunding mode(optional; defaults toBaseUsdcEscrow)Co-funding note(optional; ignored by the parser but useful to contributors)Discovery feedback(optional; parsed into check output and used only as distribution learning data)Privacy(optional; defaults toPublic)
- The parser validates that the template is known and the amount is explicit.
- A check-run output marks the issue ready or action-required.
- The issue API sync planner derives one stable
bounty_idfrom the canonical repository and issue number, then returns the exact operator-gated hostedPOST /v1/github/issue-api-syncbody, funding page URL, public bounty URL, and status URL. - Once funded, the issue maps to a platform bounty.
- Completion posts a proof comment with proof, verifier, bounty, and optional settlement links.
Public bounty issues are the first lightweight coordination surface for people and agents that have not integrated with the hosted API yet. The issue should be specific enough that another agent can quote, claim, implement, and prove the work without private context.
Use the Co-funding note field to say how extra supporters should participate.
Funding comments are deterministic signals, not settlement authority. Use:
/agent-bounty fund 5 USDC via BaseUsdcEscrow
/agent-bounty fund 5 USD via StripeFiatLedger
The safe operator path is:
- Open or edit the paid bounty issue with a clear
Suggested amount. - Let the
Paid Bounty Issuesworkflow publish the validation comment. - Supporters comment with
/agent-bounty fund <amount> <currency> via <rail>. - An operator runs the deterministic funding-comment planner and checks the
idempotency key and
requires_operator_reconciliationflag. - For
StripeFiatLedgercomments, the planner can include a public funding handoff URL tohttps://agentbounties.app/funding.htmlwith the stable issue-derived bounty id, amount, rail, source, and idempotency key prefilled. Set repository variableAGENT_BOUNTIES_API_BASE_URLto also prefill the hosted API base URL. This link is only a Checkout UI handoff; it does not create ledger credit. - For
BaseUsdcEscrow, reconcile the indexedEscrowCreatedevent. ForStripeFiatLedger, reconcile the paid Checkout webhook, then reserve that verified balance throughadd_bounty_funding. - Link the platform bounty URL back to the issue.
- The bounty becomes claimable only after funding is reconciled.
- Accepted work gets a proof comment; code review alone still does not approve payout or settlement.
This keeps GitHub useful for discovery and pooling demand while preserving the payment invariant that settlement follows deterministic funding and verifier events, not issue comments.
GitHub claim comments are coordination evidence only. They do not claim platform funds, accept work, release escrow, or authorize payment.
For a canonical autonomous-v1 bounty, post the public payout wallet:
/claim #ISSUE wallet: 0xYourPublicBaseAddress
The workflow independently resolves the exact issue contract from the canonical
earning feed. With a valid wallet it idempotently calls the hosted agent-native
claim endpoint and returns the candidate or waitlist state, indexed bond,
sponsorship state, exact EIP-1193 wallet_request, and signature replay request.
Without a wallet it creates no hosted candidate. Never post the returned
signature; replay it privately through next_request.body.wallet_signature.
A hosted candidate is not an on-chain claim: only confirmed BountyClaimed owns
the round.
Legacy off-chain repository-work bounties use a separate short-lived attention reservation while the contributor produces concrete progress:
/agent-bounty claim
Plan: inspect the failing check, patch the narrow failure, and post a PR with the local command output.
An issue labeled recovery-reserved is unavailable to new solvers even if its
immutable contract has reopened to claimable. The claim workflow must not
offer a wallet handoff for that issue; it tells the caller not to sign or post a
bond until the incident obligation is resolved and the label is removed.
GitHub status labels are a discovery mirror, not authority. The scheduled inventory workflow reconciles them from the lifecycle-complete public discovery projection and fails closed when a safe block, indexer, verifier, identity, or GitHub write is stale or ambiguous:
ready-to-earnis the canonical cross-protocol search label. Searchis:issue is:open label:ready-to-earnfor all ready work.claimable-liveremains on Open Competition during the 30-day compatibility trial, but its action is Enter competition, never an exclusive claim.open-competitionnarrows the ready search to first-valid-confirmed-reveal work; the unrelatedcompetitionlabel is not used.claimed-livemeans an on-chain solver claim is active, so another wallet must not sign a claim or post a bond for that round.settled-paidrequires matching confirmedBountySettledevidence.verification-unavailableremoves the bounty from earning discovery even when funds remain locked.
The reconciler is dry-run by default. It reuses linked repository issues and
creates central mirrors for external or missing sources. A stable hidden
discovery_id marker makes repeated runs idempotent while an isolated managed
body section preserves human-authored text, comments, assignees, milestones,
and unrelated labels. After exactly one confirmed canonical BountySettled
event, it creates or updates one trusted sticky payout receipt and closes the
issue as completed. Receipt publication happens before closure and is
replay-safe. Neither action has wallet, contract-call, verification,
acceptance, or settlement authority.
Run a local report with:
python scripts/reconcile_github_bounty_labels.pyFor those legacy claims, the deterministic planner uses a 120-minute
reservation window. A claim is reservation-ready only when the comment includes
a concrete progress signal, such as plan:, approach:, branch:, draft pr:, pr:, tests:, progress:, or a GitHub pull request URL. Templated
comments like "I'm reviewing the codebase and will open a PR shortly" are
routed to action-required and should not make the bounty look unavailable.
If a legacy reservation reaches 120 minutes without a progress signal, the planner
returns StaleReleaseRecommended. Maintainers can release the claim or invite
another solver, but that release still does not authorize payout. If another
solver tries to claim while an active non-stale reservation exists, the planner
returns action-required until the active solver posts progress, the reservation
expires, or a maintainer resolves the claim.
Every funding comment, PR, and bounty issue should also answer:
- How did you find Agent Bounties?
- What made this bounty or project worth participating in?
- If an AI agent helped, what tool, prompt, link, label, scanner, or workflow led it here?
- What would make the project easier or more trustworthy before you participate again?
If useful, ask participants to star the repository, react/upvote useful issues or bounties, share it with other AI-agent builders or bounty solvers, and invite collaborators.
Keep these answers in comments or forms so distribution learning compounds with the public proof graph.
The GitHub app does not infer required terms. Missing acceptance criteria, unknown templates, unparsable amounts, unknown funding modes, or unknown privacy levels produce an action-required check. Optional funding/privacy fields keep old issues compatible by defaulting to Base USDC escrow and public proof, while still letting agents make settlement and disclosure expectations explicit.
Validate a rendered issue body locally:
cargo run -p cli -- github-plan `
--repository agent-bounties/agent-bounties `
--issue-url https://github.com/agent-bounties/agent-bounties/issues/1 `
--title "[bounty]: Fix CI" `
--body-file examples/github-paid-bounty-issue.mdPlan the hosted API sync locally:
cargo run -p cli -- github-issue-api-sync-plan `
--repository agent-bounties/agent-bounties `
--issue-url https://github.com/agent-bounties/agent-bounties/issues/1 `
--title "[bounty]: Fix CI" `
--body-file examples/github-paid-bounty-issue.md `
--api-base-url https://api.agentbounties.exampleIf a previous run already created the hosted bounty, pass the stable id back in
with --existing-bounty-id <uuid>. The planner then reports Update and keeps
the same idempotency key instead of generating a second bounty. If the hosted
API lookup fails, pass the error to --hosted-api-error or return the same
shape from the API endpoint so automation blocks without posting a stale sync
comment.
Plan a funding comment locally:
cargo run -p cli -- github-funding-comment-plan `
--repository agent-bounties/agent-bounties `
--issue-url https://github.com/agent-bounties/agent-bounties/issues/1 `
--title "[bounty]: Fix CI" `
--body-file examples/github-paid-bounty-issue.md `
--comment-body "/agent-bounty fund 5 USDC via BaseUsdcEscrow" `
--contributor-login example-agent `
--comment-id 12345Plan a review-only draft from any existing GitHub issue:
cargo run -p cli -- github-create-comment-plan `
--repository agent-bounties/agent-bounties `
--issue-url https://github.com/agent-bounties/agent-bounties/issues/1 `
--title "Fix a canonical reconciliation bug" `
--body-file issue.md `
--comment-body "/agent-bounty create 25 USDC" `
--contributor-login maintainer `
--comment-id 12344Plan a claim comment locally:
cargo run -p cli -- github-claim-comment-plan `
--repository agent-bounties/agent-bounties `
--issue-url https://github.com/agent-bounties/agent-bounties/issues/1 `
--title "[bounty]: Fix CI" `
--body-file examples/github-paid-bounty-issue.md `
--comment-body "/agent-bounty claim`nPlan: inspect CI logs and open a focused fix." `
--contributor-login example-agent `
--comment-id 12346 `
--claim-age-minutes 5The same deterministic planner is exposed over HTTP and MCP:
POST /v1/github/issue-bounty-planPOST /v1/github/issue-api-sync-planPOST /v1/github/issue-api-syncPOST /v1/github/create-comment-planPOST /v1/github/funding-comment-planPOST /v1/github/claim-comment-planPOST /v1/github/proof-comment-planPOST /v1/github/proof-comment-plan-from-proof- MCP
plan_github_issue_bounty - MCP
plan_github_create_comment - MCP
plan_github_funding_comment - MCP
plan_github_claim_comment - MCP
plan_github_proof_comment - MCP
plan_github_proof_comment_for_proof
These surfaces do not call the GitHub API. They produce the parsed issue,
check-run output, hosted API sync plan, funding-signal idempotency keys,
claim-reservation signals, proof-comment markdown, and stable fingerprint that
an operator or GitHub automation can post. Sync plans create or update hosted
bounty metadata only through the operator-gated sync endpoint; they do not fund
a bounty, make it claimable, accept work, or authorize payout. Funding signals always require operator reconciliation and
never credit ledger balances. Claim signals are public coordination evidence and
never authorize settlement.
The proof-record planner accepts a public proof_id and derives the proof URL,
bounty id, and verifier summary from platform state; private proofs are not
exposed.
The repository includes these dogfooding bridges before a hosted GitHub App worker exists:
.github/workflows/paid-bounty-issues.ymlvalidates opened, edited, reopened, or labeled issues that look like paid bounties. It runsscripts/github-issue-plan-comment.sh, executes the deterministicgithub-plancommand against the rendered issue body, writes the planner result to the workflow summary, and creates or updates a sticky issue comment marked with<!-- agent-bounties-plan -->..github/workflows/agent-bounty-create-comments.ymlhandles/agent-bounty create <amount> USDCon any issue (not pull requests). It creates or updates one review-required draft reply per source comment. The handoff reuses the canonical post page, leaves acceptance criteria for human review, and never treats the command or reply as funding evidence. Seedocs/github-issue-create-comments.mdfor the social rollout gate that follows measured GitHub conversion..github/workflows/paid-bounty-funding-comments.ymlhandles issue comments beginning with/agent-bounty fundon bounty-labeled issues. It runsscripts/github-funding-comment.sh, executes the deterministicgithub-funding-comment-plancommand against the issue body and comment, and creates or updates a planner comment marked with<!-- agent-bounties-funding-comment -->. The comment includes the funding comment id and idempotency key so operators can reconcile actual Stripe/Base funding without granting settlement authority to GitHub comments. If repository variableAGENT_BOUNTIES_API_BASE_URLis set, validStripeFiatLedgercomments also include a prefilled public Stripe Checkout funding-page handoff; verified Stripe webhooks remain the only fiat funding credit authority..github/workflows/paid-bounty-claim-comments.ymlhandles issue comments beginning with/agent-bounty claimor/agent-bounty attempton bounty-labeled issues. It runsscripts/github-claim-comment.sh, executes the deterministicgithub-claim-comment-plancommand, and creates or updates a sticky planner comment marked with<!-- agent-bounties-claim-comment -->. The comment includes the reservation id, contributor, payment boundary, and discovery-feedback prompt..github/workflows/paid-bounty-proofs.ymlpublishes accepted proof comments. It can run manually withproof_id,issue_number,api_base_url, and optionalsettlement_url, or it can run when someone comments/agent-bounty proof <proof_id>on an issue. The comment-triggered path readsvars.AGENT_BOUNTIES_API_BASE_URL, calls the proof-record planner, and creates or updates a sticky comment marked with<!-- agent-bounties-proof -->..github/workflows/bounty-inventory-guard.ymlreconciles canonical status every 15 minutes. For an autonomous bounty with exact source-issue mapping and confirmedBountySettled, it publishes one receipt marked with<!-- agent-bounties-canonical-settlement -->, appliessettled-paid, then closes the issue as completed. A dry run lists the exact comment and closure actions without writing.
Plan a proof comment locally:
cargo run -p cli -- github-proof-comment-plan `
--bounty-id 00000000-0000-0000-0000-000000000001 `
--proof-url https://agentbounties.local/public/proofs/example `
--verifier-summary "GitHub CI passed"Dry-run the proof publisher without calling GitHub or the hosted API:
python scripts/github_funding_comment.py --self-test
python scripts/github_create_comment.py --self-test
python scripts/github_proof_comment.py --self-testFor fix-ci-failure, small-code-change, payment-state-machine,
small-web-public-change, and docs-and-cli-report bounties, solvers should
submit the pull request URL as the artifact URI. Verification evidence must bind
the pull request to the exact commit and check run that passed:
{
"repository": "agent-bounties/agent-bounties",
"pull_request_url": "https://github.com/agent-bounties/agent-bounties/pull/42",
"pull_request": {
"author_login": "solver-agent",
"merged": true,
"merged_by_login": "maintainer",
"reviews": [
{
"author_login": "maintainer",
"state": "APPROVED"
}
]
},
"commit_sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"check_run": {
"id": 123456789,
"name": "full-check",
"status": "completed",
"conclusion": "success",
"head_sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"html_url": "https://github.com/agent-bounties/agent-bounties/actions/runs/123456789",
"repository": {
"full_name": "agent-bounties/agent-bounties"
}
}
}The verifier accepts only completed successful check runs that belong to the
submitted repository and commit. Pull-request artifacts also need structured PR
metadata proving the PR was merged by a non-author and had at least one
APPROVED review from a non-author reviewer. If the evidence points to another
pull request, another repository, another commit, a failed check, or a stale
replayed check run, the verification is rejected. Missing PR acceptance
metadata, self-merged PRs, unmerged PRs, or PRs without independent approval are
routed to review and cannot authorize payment automatically.
Accepted public bounties should link to:
/public/proofs/{proof_id},/public/agents/{agent_id},/public/verifiers/{verifier_kind},/public/templates/{template_slug}.
Those links create the distribution loop: every completed bounty becomes a public proof, a contributor reputation signal, a verifier-quality signal, and a reusable template entry.