Add TOPLOC honest-noise calibration storage/dispatch and validator divergence reporting for AH-021. Add opt-in HuggingFace marketplace pricing refresh, price-change history, CLI flags, and AH-023 tracking docs. Verification: .venv/bin/python -m pytest tests/ -q -k 'not integration' => 346 passed, 2 skipped, 1 deselected; compileall packages tests passed; focused AH-021/AH-023 tests 32 passed.
5.2 KiB
meshnet-validator
Optimistic fraud detection (ADR-0003, penalty amended by ADR-0015): the validator re-runs a random ~5% sample of completed inference requests against a trusted reference node. Audit-capable events are checked by teacher-forcing the claimed token sequence through the reference node and verifying the claimed TOPLOC activation proof. Legacy events without TOPLOC metadata still fall back to text comparison until node-side proof capture lands.
Why the penalty deters cheating
There is no upfront stake. Settlement is periodic (US-033), so a node always has an unpaid pending balance — that balance is the collateral.
At a sampling rate p, a cheater who gains G per fraudulent job and loses
L when caught has expected value:
(1 - p) * G - p * L < 0
L > ((1 - p) / p) * G # p = 0.05 -> L > 19 x G
With the production settlement period of 24h, the pending balance at any moment approximates a full day's earnings — hundreds to thousands of jobs — which is far above the 19× bar. Each catch also records a strike; three strikes ban the wallet (registration rejected, excluded from routes, unpaid pending never settled), and the probationary period (first N jobs unpaid) makes re-entry with a fresh wallet costly.
TOPLOC audit contract
The validator expects audit-capable events to carry:
claimed_token_ids: the final token sequence claimed by the prover.toploc_proof: compact TOPLOC proof data built from prover activations.
On audit the validator calls the reference node's POST /v1/audit/toploc
endpoint with the original messages plus claimed_token_ids. The reference
node must run a teacher-forced prefill over exactly that token sequence and
return the activations for TOPLOC verification. It must not free-generate a
second answer for audit.
Canonical audit parameters for the current alpha preset are:
dtype = "bfloat16"
quantization = "bfloat16"
decode_batching_size = 32
topk = 8
skip_prefill = true
encoding = "base64"
verify_activation_proofs_detailed() (meshnet_validator.audit) surfaces the
raw TOPLOC divergence — exp_intersections (worst-case across chunks),
mant_err_mean, mant_err_median — alongside the pass/fail bool. This is
what the calibration corpus below is built from; existing callers that only
need the bool keep using verify_activation_proofs().
Do not enable production audit thresholds before issue 21 closes.
Production audit thresholds remain gated on the honest-noise calibration
corpus in issue 21: the tracker's POST /v1/calibration/toploc/run
(admin/validator-only, mirrors POST /v1/benchmark/hop-penalty) dispatches a
fixed prompt to every solo-capable registered node, verifies each node's
on-demand commitment against a teacher-forced reference replay, and records
the divergence into a SQLite corpus (meshnet_tracker.calibration. ToplocCalibrationStore) keyed by node wallet + GPU model + dtype.
GET /v1/calibration/toploc/results reports the corpus plus:
envelope: p99 honest-noise value per metric with a 20% safety margin — the recommended (not yet wired) tolerance constants.gate_status.ready: whether the corpus covers enough distinct hardware profiles (--toploc-calibration-gate-min-hardware-profiles, default 1). Alpha exception: with the hired-VPS-only launch fleet,readymay legitimately mean "covers every node we currently operate" — this must be revisited (raise the minimum) before a public/volunteer launch broadens the hardware mix, since a new corpus is required whenever the fleet's hardware composition changes.
Two operational notes:
- Shortening the settlement period shrinks the collateral. Period changes must weigh chain overhead against deterrence.
- A cheater immediately after a payout has little to forfeit — the strike/ban ladder covers that window.
Usage
ValidatorProcess(
contracts=contracts, # registry/validation boundary
billing=ledger, # BillingLedger — enables forfeiture
reference_node_url="http://...",
sample_rate=0.05,
)
Remote validators can instead call the tracker's privileged
POST /v1/billing/forfeit endpoint (non-empty Authorization header).
Reputation-weighted audit rate (ADR-0018 §1, §6-7)
sample_rate is a flat coin flip: every wallet audited at the same rate.
Pass audit_sampler=AdaptiveAuditSampler(...) instead to make the audit
probability a function of each wallet's tenure and reputation — newcomers
and low-reputation wallets sampled at 20–30%, veterans in good standing
floor at ≥2% — while a running budget balance keeps the fleet-wide realized
rate anchored to AuditRateConfig.target_rate (default 5%) regardless of
the wallet mix. Passive tripwires (detect_output_tripwire) bump only that
one request's odds; they never strike, ban, or affect other wallets' rates.
from meshnet_validator import AdaptiveAuditSampler, detect_output_tripwire
ValidatorProcess(
contracts=contracts,
reference_node_url="http://...",
audit_sampler=AdaptiveAuditSampler(random_seed=42),
)
When audit_sampler is set, sample_rate is ignored — the sampler decides
per event, keyed on whichever route wallet has the lowest reputation.