# x402 economy

ADapptive sells fast, trusted human judgment and pays the humans who provide
it. x402 — the HTTP-native payment protocol stewarded by the x402 Foundation —
is the rail for both sides because it is machine-payable (agents can buy
without accounts), settles in stablecoins in seconds, supports per-request
recipients, and comes with a discovery layer (Bazaar) that lets agents find
payable endpoints.

This document is the design and the rollout plan. Points remain non-monetary
until a campaign has a funded budget; nothing here changes that until the
stated gates are passed.

## Model

```
Developer or agent ──pay-in──► RewardBudget (per campaign)
                                    │  PayoutPolicy converts outcomes to credits
Tester contribution ──cleared──► RewardLedger (+points) ──► credits
                     ──deployed──► RewardLedger (+points) ──► credits
                     ──confirmed─► RewardLedger (+points) ──► credits
credits ──eligible tier + verified wallet──► Payout (x402 dynamic payTo) ──► tester wallet
```

### Data model (additive)

| Model | Fields | Notes |
|---|---|---|
| `RewardBudget` | `campaignId`, `currency`, `totalCents`, `reservedCents`, `spentCents`, `source` (CARD/INVOICE/X402), `externalRef` | one active budget per campaign |
| `PayoutPolicy` | `campaignId`, `perAcceptedCents`, `perDeployedCents`, `perConfirmedCents`, `voterShareCents`, `minTierWeight`, `maxPerTesterCents` | developer-controlled |
| `TesterWallet` | `testerId`, `chain` (CAIP-2), `address`, `verifiedAt`, `proofSignature` | one per chain |
| `Payout` | `testerId`, `budgetId`, `ledgerEntryIds`, `amountCents`, `asset`, `network`, `payTo`, `status` (PENDING/SETTLED/FAILED/REVERSED), `facilitatorRef`, `txHash` | idempotent per ledger entry set |

Credits are derived: `credits = Σ policy rate × ledger events` bounded by the
budget's remaining funds; the ledger already exists (`RewardLedger`).

## Pay-in (agents and developers buy feedback)

Endpoints under `/x402/` (feature flag `X402_ENABLED`):

| Endpoint | Price unit | Fulfils |
|---|---|---|
| `POST /x402/campaigns` | per campaign window | creates a PUBLIC campaign in the buyer's (or a provisioned) workspace, funds its `RewardBudget` |
| `POST /x402/feedback-requests` | per requested item | bounty for N cleared items on a URL |
| `GET /x402/campaigns/:id/results` | per pull | cleared, redacted results |

Handshake (x402 V2):

1. Unpaid request → `402` with `PAYMENT-REQUIRED` header: base64 JSON
   `{ x402Version: 2, accepts: [{ scheme: "exact", network: "eip155:8453", asset: <USDC>, amount, payTo: <platform treasury>, maxTimeoutSeconds, extra }], resource: { url, description, mimeType }, extensions: { bazaar: { ... input schema, output schema ... } } }`.
2. Client pays and retries with `PAYMENT-SIGNATURE` (base64 payload).
3. Server calls the facilitator `/verify`, fulfils the request, then `/settle`;
   response carries `PAYMENT-RESPONSE`.

Implementation: `platform/backend/api/src/lib/x402/` (requirements builder,
header codec, facilitator client, Fastify hook) with a mocked facilitator in
tests. Configuration: `X402_FACILITATOR_URL`, `X402_PAY_TO`, `X402_NETWORK`,
`X402_ASSET`, `X402_PRICES_JSON`.

Bazaar: the `extensions.bazaar` block in the 402 body is what facilitators
index, so agents can find "human feedback on a URL" by natural-language query
and pay for it without an account.

## Pay-out (testers get paid)

- **Eligibility:** tier weight ≥ policy `minTierWeight`, `TesterWallet`
  verified by signature, account older than 30 days, no BLOCKED submissions in
  the last 90 days, anti-sybil score above threshold.
- **Trigger:** operator- or schedule-run `POST /api/platform-admin/payouts/run`
  batches eligible credits per tester into a `Payout`.
- **Settlement:** x402 dynamic `payTo` to the tester's wallet through the
  facilitator; `txHash` recorded; failures retried with backoff; reversals
  are compensating ledger entries, never deletions.
- **Fiat option:** facilitators that bridge to fiat rails can be added without
  changing the model.

Gate: **legal and tax review** before `X402_PAYOUTS_ENABLED=true` (money
transmission, KYC thresholds, 1099/DAC7 reporting). Until then payouts are
computed and displayed as "pending eligibility".

## Mechanisms to test with real data

| Mechanism | Hypothesis | Metric |
|---|---|---|
| Bounty per zone | Clear, bounded incentive raises submission quality | cleared/submitted ratio |
| Reputation-weighted votes (current) vs quadratic credits per campaign | Quadratic resists bloc voting on public campaigns | share of THRESHOLD_MET later REJECTED |
| First-finder bonus | Rewards discovery over pile-on | unique bugs per tester |
| Streak multiplier | Weekly participation retention | 4-week retention |
| Reputation slashing (not funds) for BLOCKED items | Deters injection attempts | BLOCKED rate over time |
| Dispute flow (7-day developer response) | Fairness increases retention | disputes resolved in favour of tester |

## Guardrails

- No custody of tester funds; settlement at payout time.
- Every payout idempotent (unique per ledger entry set), audited, reversible
  by compensating entry.
- Budgets can never go negative; reservations are made when an item flips to
  THRESHOLD_MET and released on REJECTED.
- Public copy (`/pricing`, `/terms`) keeps saying points are not money until
  the first funded campaign.

## Rollout

| Stage | Flag | Deliverable |
|---|---|---|
| 1 Budgets and credits | none | models, policy UI on the campaign Pipeline tab, credits shown in the Tester Hub |
| 2 Pay-in + Bazaar | `X402_ENABLED` | 402 handshake with facilitator, Bazaar block, docs |
| 3 Payouts | `X402_PAYOUTS_ENABLED` | wallet verification, batch run, statement export |
