How the Peerseal Trust Score is computed.
Portable human trust for every platform — a Trust Score built from peer vouches, verified purchases, eyewitness confirmations, and identity-verified ownership.Each post’s score is a transparent additive function over four attestation kinds — receipt, eyewitness, identity, and continuous recording — clamped to a 100-point ceiling. The math lives at src/lib/business/trust-score.ts and the same logic runs at request time on every /api/trust-score call.
01 — Formula
One additive function. Same code, every request.
The composite score is a pure function over the four attestation kinds on a post. No heuristics, no decay, no ML in v1 — the same input set always returns the same score.
score = Math.min(
MAX_SCORE,
Σ min(count_per_kind, 1) × WEIGHTS[kind]
)MAX_SCORE= the clamp ceiling (imported literal: 100).count_per_kindis capped at 1 per kind per post — multiple attestations of the same kind do not compound.WEIGHTS[kind]is the per-kind contribution table (next section).
worked example · all four kinds present
- receipt1 × 55 = 55
- eyewitness1 × 40 = 40
- identity_verified1 × 25 = 25
- continuous_recording1 × 20 = 20
Σ = 140 → Math.min(100, 140) → 100
pure function · same logic the live /api/trust-score endpoint runs · no DB read
02 — The four attestation kinds
One table. Four signals. Each adds its weight.
Every kind lives once in the engine’s WEIGHTS table. The page reads it directly — change a weight in code and this row updates next render.
- 01
receipt
Verified purchase — the strongest single signal.
A receipt-signed photo of the item, an order-ID match, or a payment processor hash.
+55pts / post - 02
eyewitness
Human "I was there" — a strong personal signal.
A named witness with a free-text statement and an occurred-at timestamp.
+40pts / post - 03
identity verified
KYC-style anchor — links the score to a real person.
An identity-verification provider report keyed to the post author.
+25pts / post - 04
continuous recording
Timed-media corroboration — points only, no badge.
A timed recording clip with a start → end window. Points add to the total, but never unlock a badge by design.
+20pts / post
03 — Per-post caps & clamp
One of each kind, then clamp.
Per post, every kind contributes at most its single weight — even if a creator attaches three receipts, only one receipt counts. This is an MVP constraint and lives in lines 66–70 of the engine.
The un-clamped sum of all four kinds is 140. Without the clamp, a post hitting all four kinds would score above the published 100-point ceiling. The clamp keeps the score a comparable unit across the network.
04 — Badges
Earned by presence, not by a threshold.
Badges are unlocked the moment any attestation of the triggering kind is present on a post. There is no numeric score cutoff for a badge — the engine emits the label iff count[kind] > 0, in the canonical BADGE_LABELS order.
| Badge label | Trigger | Pts |
|---|---|---|
| Purchased by author | receipt> 0 | 55 |
| Vouched by witnesses | eyewitness> 0 | 40 |
| Identity verified | identity verified> 0 | 25 |
Note. continuous_recording adds +20 to the score but does not unlock a badge by design — its label would only inflate the badge shelf without adding meaningful attestable signal.
05 — Freshness & decay
v1 — no decay. Freshness is a roadmap item.
Attestations are scored exactly as presented. occurredAt and verifiedAtare stored with each attestation, but the engine’s score function does not weight them yet — an attestation two years old scores identically to one from yesterday.
Time-based decay (e.g. half-life windows, dispute-rate modifiers, recency boosts) is queued for the next sprint. Until that ships, freshness affects the score only through documented human judgement on the receiving platform.
06 — Live status
Read the four kinds end-to-end today — persistence is widening.
The full four-kind model round-trips through the public /api/trust-score endpoint and the contract-verification flow. Live persistence is currently scoped to two kinds — receipt and eyewitness — per the MVP schema. identity_verified and continuous_recording land in the next sprint alongside disputes and decay.
Engine · public · contract · preview only — DB scope is narrower than the model.
07 — Try the weights
Score without posting yet.
Toggle the four attestation kinds and watch the score update live. The same math the engine runs at request time, with nothing persisted below.
trust score · preview
What does each attestation earn?
Toggle kinds to see the score + badges update. Pure-function math — nothing is saved.
scoring…