Skip to content

Latest commit

 

History

History
178 lines (136 loc) · 6.43 KB

File metadata and controls

178 lines (136 loc) · 6.43 KB

Admin Runbook

Post a Bounty

  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 a single-award bounty.
  5. 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.

Accept Work

PR Bounties

  1. Review the submission and test evidence.
  2. Confirm the work matches the bounty acceptance text.
  3. Confirm the labeler is listed in MERGEWORK_GITHUB_ACCEPTED_LABELERS.
  4. Confirm the PR body links the bounty issue. Use Bounty #3 or Refs #3 for multi-award bounties; use Closes #3 only when the bounty issue should close after that PR.
  5. Apply mrwk:accepted to the PR.
  6. Confirm the webhook records one ledger payment to the PR author.
  7. Add mrwk:paid to the PR after the explorer/API shows the proof.
  8. Add mrwk:paid to the bounty issue only after all awards are exhausted or the bounty is intentionally closed.

To close an open bounty without paying the remaining awards, release the unused reserve:

curl -X POST https://api.mrwk.ltclab.site/api/v1/bounties/<id>/close \
  -H "content-type: application/json" \
  -H "x-mergework-admin-token: $MERGEWORK_ADMIN_TOKEN" \
  -d '{
    "reference": "https://github.com/ramimbo/mergework/issues/<issue>#close",
    "closed_by": "maintainer-login"
  }'

If the contributor linked a wallet, the payout goes directly to that mrwk1 address. If not, it goes to github:{login} and can be claimed later after GitHub OAuth and wallet-linking.

Comment or Wallet-Proof Bounties

Use the admin-token payout API when the accepted proof is a comment, wallet address, or other non-PR submission:

curl -X POST https://api.mrwk.ltclab.site/api/v1/bounties/<id>/pay \
  -H "content-type: application/json" \
  -H "x-mergework-admin-token: $MERGEWORK_ADMIN_TOKEN" \
  -d '{
    "to_account": "mrwk1...",
    "submission_url": "https://github.com/ramimbo/mergework/issues/2#issuecomment-...",
    "accepted_by": "maintainer-login"
  }'

to_account must be a registered mrwk1... wallet or github:{login}. Successful responses include submission_id, ledger_sequence, ledger_url, proof_hash, and proof_url so operators can reconcile the payment without scraping the ledger. If the same bounty/submission URL is paid twice, the API returns 409 with status: "already_paid" and the existing proof links instead of creating another ledger entry.

Manual payout checklist:

  1. Verify the public proof and wallet address.
  2. Pay through POST /api/v1/bounties/{id}/pay.
  3. Confirm the explorer/API shows the proof.
  4. Add mrwk:paid to the paid comment or submission when possible.
  5. Add mrwk:paid to the bounty issue only after all awards are exhausted or the bounty is intentionally closed.

Do not apply mrwk:accepted to maintainer-authored bounty issues for payment; those issues require the manual payout path.

Webhook Outcome Inspection

Use the admin-token webhook events API to inspect recent delivery outcomes before retrying labels or making manual payouts:

curl -s "https://api.mrwk.ltclab.site/api/v1/admin/webhook-events?status=missing_submitter" \
  -H "x-mergework-admin-token: $MERGEWORK_ADMIN_TOKEN"

The response includes delivery ID, GitHub event type, payload hash, processed status, and timestamp. This is useful for confirming duplicate deliveries, missing submitters, exhausted bounties, and already-paid submissions without guessing from GitHub labels alone. Use limit to control the number of delivery rows returned (1 to 200, default 50), for example: /api/v1/admin/webhook-events?status=missing_submitter&limit=100.

PR Queue Health

Use the queue-health script before accepting busy bounty rounds:

python scripts/pr_queue_health.py --repo ramimbo/mergework --format text

For a report that can be pasted directly into a GitHub issue, PR comment, or payment-batch note, use Markdown output:

python scripts/pr_queue_health.py --repo ramimbo/mergework --format markdown

Live mode requires an authenticated GitHub CLI with access to the repository. The command only reads PRs and issues; it does not close PRs, label issues, or post comments. It reports missing bounty references, closed or exhausted bounty references, dirty or unknown merge state, mrwk:needs-info, and likely duplicate PR scope within the same bounty issue.

For offline checks, save fixture data and run:

python scripts/pr_queue_health.py --input queue.json --format json --fail-on-issues

--fail-on-issues exits nonzero when queue-health problems are found, which lets maintainers add the check to local release or payout workflows without requiring live GitHub access.

Final Checks

  1. Confirm the webhook or admin API records one ledger payment for that award.
  2. Confirm the proof pays the intended contributor account.
  3. Add the paid bounty row to docs/paid-bounties.md and GitHub Discussions #16.

GitHub OAuth

Production GitHub OAuth is configured for https://mrwk.ltclab.site. Contributors use /me to sign in, link wallets, and claim older GitHub ledger balances. If the GitHub app is rotated later, update deployment secrets outside the repository and restart Docker Compose.

Disputes

  • Ask for concrete missing evidence with mrwk:needs-info.
  • Use mrwk:rejected only when the submission is clearly not acceptable.
  • Keep public comments short and specific.
  • For security reports, keep private details out of public comments and proofs.

Operations

  • Database: /srv/mergework/data/mergework.sqlite3.
  • Backups: /srv/mergework/backups.
  • Health check: GET /health.
  • Logs: docker compose logs -f app caddy.

Pre-Bounty Readiness

Generate MERGEWORK_GITHUB_WEBHOOK_SECRET, MERGEWORK_ADMIN_TOKEN, and MERGEWORK_COOKIE_SECRET with at least 32 random characters. Keep them outside the repository.

Run the deploy gate before posting a bounty:

docker compose run --rm app python scripts/check_deploy_ready.py

Run a staging webhook payout dry run against a staging host:

MERGEWORK_STAGING_BASE_URL=https://staging.mrwk.example.test \
MERGEWORK_DRY_RUN_REPO=ramimbo/mergework \
docker compose run --rm app python scripts/staging_webhook_dry_run.py