Skip to content

Latest commit

 

History

History
392 lines (334 loc) · 17.4 KB

File metadata and controls

392 lines (334 loc) · 17.4 KB

GitHub Dogfooding

The project should use paid GitHub issues for its own roadmap as soon as the hosted low-value rail is available.

Issue Flow

  1. Open a paid bounty issue with .github/ISSUE_TEMPLATE/paid-bounty.yml.
  2. The GitHub app parses the rendered issue form sections:
    • Goal
    • Acceptance criteria
    • Template
    • Suggested amount
    • Funding mode (optional; defaults to BaseUsdcEscrow)
    • 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 to Public)
  3. The parser validates that the template is known and the amount is explicit.
  4. A check-run output marks the issue ready or action-required.
  5. The issue API sync planner derives one stable bounty_id from the canonical repository and issue number, then returns the exact operator-gated hosted POST /v1/github/issue-api-sync body, funding page URL, public bounty URL, and status URL.
  6. Once funded, the issue maps to a platform bounty.
  7. Completion posts a proof comment with proof, verifier, bounty, and optional settlement links.

Public Co-Funding Loop

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:

  1. Open or edit the paid bounty issue with a clear Suggested amount.
  2. Let the Paid Bounty Issues workflow publish the validation comment.
  3. Supporters comment with /agent-bounty fund <amount> <currency> via <rail>.
  4. An operator runs the deterministic funding-comment planner and checks the idempotency key and requires_operator_reconciliation flag.
  5. For StripeFiatLedger comments, the planner can include a public funding handoff URL to https://agentbounties.app/funding.html with the stable issue-derived bounty id, amount, rail, source, and idempotency key prefilled. Set repository variable AGENT_BOUNTIES_API_BASE_URL to also prefill the hosted API base URL. This link is only a Checkout UI handoff; it does not create ledger credit.
  6. For BaseUsdcEscrow, reconcile the indexed EscrowCreated event. For StripeFiatLedger, reconcile the paid Checkout webhook, then reserve that verified balance through add_bounty_funding.
  7. Link the platform bounty URL back to the issue.
  8. The bounty becomes claimable only after funding is reconciled.
  9. 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.

Public Claim Reservations

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-earn is the canonical cross-protocol search label. Search is:issue is:open label:ready-to-earn for all ready work.
  • claimable-live remains on Open Competition during the 30-day compatibility trial, but its action is Enter competition, never an exclusive claim.
  • open-competition narrows the ready search to first-valid-confirmed-reveal work; the unrelated competition label is not used.
  • claimed-live means an on-chain solver claim is active, so another wallet must not sign a claim or post a bond for that round.
  • settled-paid requires matching confirmed BountySettled evidence.
  • verification-unavailable removes 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.py

For 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.

Deterministic Checks

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.md

Plan 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.example

If 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 12345

Plan 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 12344

Plan 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 5

The same deterministic planner is exposed over HTTP and MCP:

  • POST /v1/github/issue-bounty-plan
  • POST /v1/github/issue-api-sync-plan
  • POST /v1/github/issue-api-sync
  • POST /v1/github/create-comment-plan
  • POST /v1/github/funding-comment-plan
  • POST /v1/github/claim-comment-plan
  • POST /v1/github/proof-comment-plan
  • POST /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.yml validates opened, edited, reopened, or labeled issues that look like paid bounties. It runs scripts/github-issue-plan-comment.sh, executes the deterministic github-plan command 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.yml handles /agent-bounty create <amount> USDC on 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. See docs/github-issue-create-comments.md for the social rollout gate that follows measured GitHub conversion.
  • .github/workflows/paid-bounty-funding-comments.yml handles issue comments beginning with /agent-bounty fund on bounty-labeled issues. It runs scripts/github-funding-comment.sh, executes the deterministic github-funding-comment-plan command 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 variable AGENT_BOUNTIES_API_BASE_URL is set, valid StripeFiatLedger comments 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.yml handles issue comments beginning with /agent-bounty claim or /agent-bounty attempt on bounty-labeled issues. It runs scripts/github-claim-comment.sh, executes the deterministic github-claim-comment-plan command, 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.yml publishes accepted proof comments. It can run manually with proof_id, issue_number, api_base_url, and optional settlement_url, or it can run when someone comments /agent-bounty proof <proof_id> on an issue. The comment-triggered path reads vars.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.yml reconciles canonical status every 15 minutes. For an autonomous bounty with exact source-issue mapping and confirmed BountySettled, it publishes one receipt marked with <!-- agent-bounties-canonical-settlement -->, applies settled-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-test

GitHub CI Submission Evidence

For 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.

Public Artifacts

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.