MethodologyTrust Score, in plain terms

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.

The math
Engineered once, reused everywhere.
score = Math.min(
  MAX_SCORE,
  Σ min(count_per_kind, 1) × WEIGHTS[kind]
)
  • MAX_SCORE = the clamp ceiling (imported literal: 100).
  • count_per_kind is 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

  1. receipt1 × 55 = 55
  2. eyewitness1 × 40 = 40
  3. identity_verified1 × 25 = 25
  4. 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.

  1. 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
  2. 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
  3. 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
  4. 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.

receipt+55 eyewitness+40 identity_verified+25 continuous_recording+20 = 140 → clamped to 100

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 labelTriggerPts
Purchased by authorreceipt> 055
Vouched by witnesseseyewitness> 040
Identity verifiedidentity verified> 025

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…