{"criteria_id":"payability/v1","criteria_revision":"1.0.0","family":"payability","op":"probe","ops_not_offered":[],"corpus":{"id":"railprobe-corpus/v1","sha256":"c9ffbe1b7ec012d1e093d9bdc28e4cc0299b207af9729c84b1c717cb797d340f"},"corpus_pin_definition":"The corpus pin is the SHA-256 of the corpus's canonical serialization (the corpus object excluding its sha256 field), computed and verifiable by the published harness (harness.mjs). Expected outputs inside corpus cases are derived from the criteria text by an independent implementation in gen-corpus.mjs (never the engine's code path), and each case labels its provenance (constructed from on-disk fleet records vs synthetic).","price":{"usdc_units_per_call":20000,"label":"$0.02","basis":"per endpoint"},"free_tier":{"per_day":100,"min_interval_ms":5000,"on_exhaustion":"402"},"no_funds_property":"NO-FUNDS PROPERTY: no probe this service sends can move funds, ever. Every probe payload is payment-shaped but cryptographically invalid by construction: the direct-rail probe carries the literal string PROBE-INVALID-NOT-A-REAL-TX-SIGNATURE-000000000000000000000000000000000000 in the payment-transaction header slot (not a signature, never signed by any wallet, nothing any chain will settle); the facilitator-rail probe's signature field is the literal string PROBE-INVALID-SIGNATURE (corresponds to no key, no message, no account — there is nothing to settle); the missing-memo probe deliberately omits the memo the rail requires; the bogus-header probe carries the literal string bogus-not-a-payment-header. Probes are self-identifying (the payloads name themselves as probes; every probe request carries the user-agent ExchangeRebel-RailProbe/1.0) and test fail-closed behaviour only: what a seller's gate does when presented with a payment it must not accept.","probe_inventory":[{"id":"baseline_get","method":"GET","payment_material":"none — the gate reference"},{"id":"head","method":"HEAD","payment_material":"none"},{"id":"post_unpaid","method":"POST","payment_material":"none — empty JSON body, no payment headers"},{"id":"direct","method":"POST","payment_material":"headers X-Payment-Tx carrying the literal invalid string PROBE-INVALID-NOT-A-REAL-TX-SIGNATURE-000000000000000000000000000000000000 plus X-Payment-Memo carrying the label probe-memo-not-bound-to-any-challenge — cryptographically invalid, cannot settle"},{"id":"facilitator","method":"POST","payment_material":"header PAYMENT-SIGNATURE carrying base64 JSON {x402Version:2, scheme:exact, network:solana, payload:{signature:PROBE-INVALID-SIGNATURE, authorization:{from:PROBE, to:PROBE, value:0}}} — cryptographically invalid, cannot settle"},{"id":"missing_memo","method":"POST","payment_material":"header X-Payment-Tx carrying the same literal invalid string as the direct probe, with NO memo carried anywhere (no memo header, no memo field in the body)"},{"id":"bogus","method":"POST","payment_material":"header X-PAYMENT carrying the literal string bogus-not-a-payment-header — not a payment at all"}],"input_contract":{"body":"One JSON request body: { url, caller? (free pre-check only) }. The url is the single endpoint to probe.","caps":{"body_bytes":262144},"over_cap":"A request body over 262,144 bytes is a free pre-gate refusal naming the cap.","validation":"The URL is validated FREE, before any payment: it must parse, use http/https, and carry no credentials. A malformed or policy-violating URL fails free and never consumes a payment. The probes themselves run only after payment verification."},"target_safety":"Target-URL policy (inherited exactly from A1, phase-1 SSRF discipline): the submitted URL must use http or https; must carry no embedded credentials (no userinfo); and is probed with the published 7-probe inventory only, each probe with a 5-second timeout, a response-body cap of 65,536 bytes, and redirects NOT followed (a redirect response is graded as received). Malformed URLs and policy violations are free refusals before any payment. URL validation runs free before the gate; the probes themselves run only after payment verification (or on a verified-marker resume with no second charge), so unpaid callers cannot trigger probes to arbitrary URLs. An unreachable endpoint is a paid outcome (NOT-PROBED with every grade UNGRADED), never an error or a crash.","target_fetch":{"timeout_ms":5000,"body_cap_bytes":65536,"redirects":"not followed (phase 1)","probes_per_call":7,"auth":"none — probes are self-identifying and carry only the published invalid payment material"},"grade_rule":"Grading, applied identically to the direct, facilitator, missing-memo, and bogus probes (first match wins): (1) the probe fetch failed, timed out, or its body exceeded the cap -> UNGRADED (reason probe_failed), reported as ungraded, never converted into a grade; if the baseline GET fails this way the whole call's outcome is NOT-PROBED and every grade is UNGRADED. (2) Status 200-299 -> PRESENT-FAIL-DIRTY, reason fail_open_2xx, fail_open true (the gate produced work for an invalid, memo-less, or bogus payment presentation; also a named exposure finding). (3) Status 402 with a JSON-parseable body carrying a rejection reason (a non-empty error, reason, or detail string) -> PRESENT-FAIL-CLOSED (the rail is present and rejected the invalid payment cleanly, with a reason). (4) Status 402 with a JSON-parseable body carrying NO rejection reason (a plain gate challenge) -> ABSENT, reason payment_never_evaluated — the response is indistinguishable from the unpaid gate; the payment was, as observed, never evaluated, and the report says exactly that. (5) Anything else (500 or any other status, an HTML or otherwise unparseable 402 body, any non-JSON body) -> PRESENT-FAIL-DIRTY. The three rail grades are exactly PRESENT-FAIL-CLOSED, PRESENT-FAIL-DIRTY, ABSENT; a grade is never overstated.","method_rule":"Method set: GET (the baseline probe), HEAD, and POST are each sent with no payment material; the matrix reports per method the status answered, gated (status is 402), and unpaid_2xx (status 200-299 with no payment presented). A method answering 200-unpaid is a named exposure finding (METHOD-UNPAID-2XX:<METHOD>); each garbage, missing-memo, or bogus probe answered 2xx is a named finding (FAIL-OPEN:<probe-id>). An empty exposures list means none were observed — it is never phrased as proof that no exposures exist.","grades":["PRESENT-FAIL-CLOSED","PRESENT-FAIL-DIRTY","ABSENT"],"verdict_grammar":{"line":"RAIL PROBE VERDICT — direct: <GRADE> · facilitator: <GRADE> — <check-end UTC>","vocabulary":"The line carries the two rail grades (UNGRADED when the outcome is NOT-PROBED). There is no composite score, grade, or band anywhere in this op."},"free_precheck":"The free pre-check (POST /precheck) validates the submitted URL against the published target-URL policy and returns assessability ONLY: the common signed fields, the no-funds property, the probe inventory ids, and the line that the endpoint is NOT probed and no grade is returned. Free allowance: 100 per day per caller wallet, minimum interval 5,000 ms, 402 on exhaustion.","custody":{"construction":"In-memory processing within a single request lifetime; probe responses persist nowhere, on any path including errors and timeouts. No hash of a probe response appears anywhere.","ledger_closed_fields":["payer wallet","timestamp/day","price (USDC units) with the CAD fair-market-value block (rate, rate date, basis, cad_pending, refund)","payment tx id + Solana fee (lamports)","criteria version","verdict line","direct grade","facilitator grade","exposures count","house flag"],"ledger_note":"The ledger list above is closed: adding a field is a criteria/handling version change. The ledger NEVER carries the called URL or any probe-response content, fragment, or hash.","errors":"Error handling is closed-form: static strings plus numeric facts only (lengths against caps, rule ids). No error path interpolates any part of a probe response."},"forbidden":"Forbidden in every surface of this op (report, pre-check, errors, ledger, metrics): any composite score or grade beyond the three published rail grades; any claim that an ABSENT rail was tested (it is reported as payment never evaluated); any claim that a grade proves a rail secure or a payment guaranteed; any probe-response content beyond the per-probe status, grade, and reason; any probe outside the published inventory; any payload that could settle.","boundary_statement":"Boundary vs the payability family: A1 (challenge payability verdict) grades one challenge's fields from a single plain GET; A2 grades which protocol dialect an endpoint speaks; A4 grades memo binding across two challenge fetches. This service, A3, alone sends payment-shaped but cryptographically invalid probes and grades how each rail rejects them, and which methods answer without payment. Presence across venues is Q-10 F2's ground. The fleet never sells the same check twice: field-level payability is A1's, dialect is A2's, memo binding is A4's, rail coverage and reject shape are A3's.","disclosure_sentence":"Submitting an endpoint URL to any third party, this service included, discloses that you are checking that endpoint; probe responses are processed in memory only and never stored, but the check does not undo the disclosure. The target's operator will see 7 self-identifying probe requests from this service per paid call.","honesty_line":"The grades report what each probe was answered with at check time, exactly as observed: an ABSENT rail is reported as payment never evaluated, a PRESENT-FAIL-CLOSED grade states only that this invalid probe was rejected cleanly with a reason at that moment, and no grade is a claim that a rail is secure, that a valid payment will settle, or that no other exposure exists. A target can change between checks.","retention":"Probe responses are processed in memory only and are never stored — not in KV, not in logs, not in the payments ledger, not in metrics, and not in error records. No probe-response body, fragment of it, or hash of it is recorded anywhere. Reports carry the grades, the per-probe statuses and reasons, the method matrix, the exposure findings, and the called URL only. The payments ledger records only the closed field list published in the criteria. Because nothing is kept, a paid retry re-submits the URL.","payment_includes":"$0.02 per endpoint rail-coverage and reject-shape probe report. The fee is per endpoint: each endpoint URL you submit is charged at $0.02. The payment includes: the full published 7-probe set run against that one endpoint after payment verification (baseline GET, HEAD, POST-unpaid, direct-rail garbage probe, facilitator-rail garbage probe, missing-memo probe, bogus-header probe), a grade per rail (PRESENT-FAIL-CLOSED, PRESENT-FAIL-DIRTY, or ABSENT — an ABSENT rail is reported as payment never evaluated, exactly as observed), the missing-memo and bogus-header outcomes graded by the same rules, the HEAD/GET/POST method matrix (which methods answer 402 vs 200-unpaid), every named exposure finding observed, and an as-of timestamp, in one signed report. NO-FUNDS PROPERTY: every probe payload is payment-shaped but cryptographically invalid by construction — no probe can move funds; the probes test fail-closed behaviour only. No composite score is computed. A free pre-check validates the submitted URL against the published target-URL policy only — it does not probe the endpoint and returns no grade. Probe responses are processed in memory only and are never stored; the payments ledger records only the payer, the time, the price, the two rail grades, the exposure count, and the verdict line.","kill_line":"Kill line (M-19 / A3, under the operator's 2026-11-03 build-bank-hold doctrine): build, bank, and hold; judged at the fleet's periodic reviews. There is NO demand kill line for this item. Day-0 = first outside paid settle (accounting only; house proofs never count). Tripwires, all stop-and-review: (1) refunds >5% in any 30-day window; (2) free use >10x paid use; (3) a wrong grade from undisclosed stale or partial data (the error enters the corpus first as a regression case, corrected rules publish as a new criteria version, the corpus re-passes at 100% before serving resumes; issued reports are never amended); (4) custody: any surface retaining a probe-response body or a fragment of one; (5) any probe outside the published 7-probe inventory or the published target-URL policy; (6) any probe payload that could settle — a construction change to a payload template is a criteria-version change requiring re-pinning.","never":"This op never sends a valid payment payload; never follows a redirect; never sends credentials or any header beyond the published probe inventory; never stores a probe response; never computes a composite score; never overstates a grade (ABSENT is always stated as payment never evaluated).","service":"rail-probe","version":"1.0.0","endpoints":{"criteria":"GET /criteria (free)","precheck":"POST /precheck (free, URL-policy validation + assessability only: no probes, no grade)","probe":"POST /probe (paid, $0.02 per endpoint: signed rail-coverage and reject-shape probe report)","metrics":"GET /metrics","not_offered":"Any other POST path answers NOT COVERED — this worker serves op probe only."}}