Skip to content

feat(bounty): ServiceBounty + evaluator market — demand-side bounties with commit-reveal evaluation#634

Open
bussyjd wants to merge 2 commits into
mainfrom
feat/servicebounty-eval-market
Open

feat(bounty): ServiceBounty + evaluator market — demand-side bounties with commit-reveal evaluation#634
bussyjd wants to merge 2 commits into
mainfrom
feat/servicebounty-eval-market

Conversation

@bussyjd

@bussyjd bussyjd commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Stack position

PR 1 of 2 in the ServiceBounty stack. The real-money escrow leg follows in a stacked PR based on this branch. Independent of #632/#633 (skill marketplace / smoke agent) except for shared additive internal/erc8004 calldata builders — whichever merges second rebases trivially.

What

A demand-side marketplace primitive: a poster publishes a ServiceBounty CR ("do X for reward R"), a fulfiller agent claims and submits, and an evaluator market decides whether the work passes — with payment held in an escrow seam until the verdict.

Core pieces:

  • ServiceBounty CRD + controller (internal/serviceoffercontroller/bounty*.go): lifecycle Open → Claimed → Submitted → Evaluating → Paid/Rejected, driven by annotation write-channels so agents interact with plain kubectl RBAC, never controller credentials.
  • Verification by default: spec.eval.mode gates payout on an evaluator verdict; opting out requires the explicit --dangerously-skip-verification flag.
  • Commit-reveal evaluation: a panel of k evaluators commits sha256(score|salt|address) hashes, then reveals; median-of-k is the verdict; non-reveals are penalized as outliers. Quorum, reveal windows, and outlier bands are spec'd per bounty with sane defaults.
  • Evaluator ladder (EvaluatorEnrollment CRD): Shadow → Probation → Full progression — shadow evaluators score without weight, probation carries a value cap and half pay, divergence from the median sets careers back. No staking, no slashing; sybil cost comes from the unpaid shadow period and self-bonds.
  • Self-bonds: fulfillers attach a bond forfeited on rejected work (escrowed alongside the reward).
  • A2UI reports: bounty results render as structured agent-to-UI report documents (v1.0-candidate schema) incl. a bounty_report MCP tool over the existing paid-MCP seam.
  • Task-type registry: dynamic, versioned task packages (benchlocal@v1 enabled; finetune@v1 staged behind enabled:false).
  • ERC-8004 wiring (internal/erc8004/{reputation,validation}.go): calldata builders + readers for the Reputation/Validation registries — evaluator verdicts can be grounded on-chain (operator-submitted; the controller never signs).
  • Poster/fulfiller/evaluator CLI: obol bounty create|claim|submit|eval commit|eval reveal|status|... plus calldata derivation commands.

Security invariants (test-pinned)

  • Bounty reconcile creates no HTTPRoute/Middleware/ReferenceGrant/Secret/Namespace — the controller's blast radius doesn't grow.
  • Controller is read-only on evaluator enrollment specs.
  • Agent RBAC additions are namespace-scoped; admission hardening pins what agent SAs may write.
  • CRD ↔ Go parity test (caught a real pruning bug during development — kept as regression).
  • Escrow URL/credentials reach the controller via env only, never via CR spec/annotations.

Why a squash commit

This squashes a 15-commit development series (list in the commit message) so the PR reviews as one coherent unit. Granular history is preserved locally and can be pushed on request.

Validation

Full unit + controller-test suite green (panel selection determinism, commit-reveal verdicts, ladder transitions, parity, admission). Design docs included under plans/ (bounty-ane-marketplace-design.md, evaluator-market-research-notes.md). The escrow PR stacked on top carries the end-to-end money-leg validation.

🤖 Generated with Claude Code

… with commit-reveal evaluation

Squash of the eval-market series for review as one unit. Original commits
(granular history available on request):
  dd8006e docs(plans): ServiceBounty + ANE marketplace design (no-slashing escrow)
  bd83124 feat: scaffold ServiceBounty v1 + dynamic task-type registry
  fab3737 fix: review fixes — reward payment envelope + CLI conventions
  e84b77f feat: servicebounty-controller reconcile + escrow seam + lifecycle CLI
  2c75ea0 docs(plans): canonical evaluator-market section + research notes
  132e65f feat: evaluator-ladder schema + spec.eval.mode verification gate
  45e12ea feat: A2UI report variants + catalog negotiation in deliverable schema
  b295a8b feat: A2UI v1.0-candidate across the board
  3889955 feat: admission hardening + poster-side CLI completeness
  ef55ae8 test: CRD<->Go parity test — and the pruning bug it caught
  b63a72d feat: benchlocal@v1 package + finetune@v1 staged (enabled:false)
  7cb07a7 feat: bounty_report MCP tool — A2UI reports over the x402mcp seam
  466671d feat: eval-market controller slice — commit-reveal quorum + self-bond
  9af37c5 feat: evaluator enrollment + panel selection + OBOL eval-payment leg
  cfce4f3 feat: ERC-8004 Validation/Reputation wiring — calldata builders + reveal provenance
…lenames in justfile

The generate target's singularization fallback turned 'servicebounties'
into 'servicebountie-crd.yaml'; add explicit case entries so controller-gen
output lands on the canonical filenames. Regenerated manifests pass the
CRD<->Go parity and admission tests unchanged.
@OisinKyne

Copy link
Copy Markdown
Contributor

We don't have any buyers with unfilled demands. What types of services do you anticipate here?

I don't think any of our buyers and sellers need an escrow and evaluator yet. I suggest leaving this unmerged until I have a better understanding of who needs this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants