# UFP reputation — records and verdicts

UFP carries reputation as protocol objects: **factual review records and
per-spec reliability facets**. How they are produced and weighted is each
network's own business. Anyone can render a `ReviewRecord`; only a network
that witnessed (or verified) the transaction can mint one.

The canonical spec is code:
[`packages/protocol/src/reviews.ts`](../packages/protocol/src/reviews.ts)
and the `VendorRatingSchema` in
[`offer.ts`](../packages/protocol/src/offer.ts). This document is the
human-readable rendering.

## ReviewRecord — the normalized factual record

No raw prose travels on the wire. `summary` is an emotionless one-line
account produced by the network's normalization pipeline — what happened,
not how anyone felt about it:

```jsonc
{
  "id": "rev_8kq2…",
  "vendor": "acme-print",
  "process": "fdm_print",
  "stars": 4,
  "facets": { "quality": 4, "timeliness": 5 },   // 1-5, only facets the buyer scored
  "summary": "1 of 10 brackets warped; vendor reprinted at no charge",
  "spec_digest": { "material": "petg", "quantity": 10 },  // what was made — powers
                                                          // per-spec reliability
  "verification": "verified_purchase",   // or "attested_transaction"
  "timeliness_check": "corroborated",    // corroborated | contradicted | unverifiable
  "order_completed_at": "2026-07-02T19:20:00Z",
  "created_at": "2026-07-05T14:11:00Z"
}
```

**Verification provenance is first-class.** `verified_purchase` means the
network witnessed the money move. `attested_transaction` means the vendor
reported an off-network sale and the buyer confirmed it (see
[ATTESTATIONS.md](ATTESTATIONS.md)). The two are never blended: a consumer
can always tell which kind of record it is holding.

**Timeliness verdicts are stamped, not self-reported.** A network checks a
buyer's "arrived late" claim against the quoted ETA the network itself
served, and stamps `timeliness_check: corroborated | contradicted |
unverifiable`. The verdict is protocol; the method behind it is not.

## VendorRating v2 — reliability facets

Every offer a network returns carries a `vendor_rating`. v0.2 adds
`reliability`: per-process/material track records with **honest sample
sizes** — `orders` is always the real count, and a consumer decides what
counts as proven:

```jsonc
"vendor_rating": {
  "stars": 4.6,
  "review_count": 31,              // honest count — a vendor with zero reviews shows 0
  "facets": { "quality": 4.5, "timeliness": 4.8, "accuracy": 4.7 },
  "reliability": [
    { "process": "fdm_print", "material": "pc",  "orders": 14,  "stars": 4.9, "on_time_rate": 0.93 },
    { "process": "fdm_print", "material": "pla", "orders": 212, "stars": 4.6, "on_time_rate": 0.97 },
    { "process": "fdm_print", "orders": 240, "stars": 4.6 }   // process-level rollup
  ]
}
```

A facet with `orders: 14` and a 4.9 is a different claim than a 4.9 over
two orders — the protocol never hides the denominator.

## Stars for subprocesses — `spec_path` drill-downs

Beyond the material facet, an entry may carry a **`spec_path`**: an
ordered chain of subprocess segments, broad → niche, derived from the
resolved spec of the work actually performed. Sheet metal example — a
vendor that folds beautifully, powder coats well, but whose flat black
comes back shiny:

```jsonc
"reliability": [
  { "process": "sheetmetal", "orders": 57, "stars": 4.9 },
  { "process": "sheetmetal", "spec_path": ["folding"], "orders": 31, "stars": 4.6 },
  { "process": "sheetmetal", "spec_path": ["folding", "powder_coat"], "orders": 12, "stars": 4.4 },
  { "process": "sheetmetal", "spec_path": ["folding", "powder_coat", "flat_black"],
    "orders": 6, "stars": 3.1, "recent_stars": 2.6 }   // the niche on a niche on a niche
]
```

Every prefix of a chain is its own honestly-sampled group; an entry
carries `material` or `spec_path`, never both. Segments are normalized
tokens; **how a network derives them from specs is its own business**
(this network curates per-process dimension tables the same way it
curates the requirements ontology). `recent_stars` — the plain average
of the group's most recent reviews, present only when the group holds
more reviews than the network's window — is the trend signal: a
`recent_stars` sitting under `stars` is a niche drifting down over time,
the fact a vendor most needs to hear about the niche it is servicing.

Offers also carry `vendor_rating.spec_track`: the same entries narrowed
to THIS offer's resolved spec, broad → niche (process rollup, material
facet, then each subprocess rung) — a display-ready view so every
consumer can show the vendor's overall rating AND its rating for exactly
what is being bought, without re-deriving the chain.

## The reliability constraint — "prints PC reliably"

The `reliability` constraint turns the track record into a filter. Ask for
a polycarbonate print from a vendor that has demonstrably done this
before:

```jsonc
// POST /v1/quotes
{
  "process": "fdm_print",
  "spec": { "file_id": "f_abc123", "material": "pc", "quantities": [10] },
  "constraints": {
    "ship_to_zip": "78701",
    "reliability": {
      "min_stars": 4,          // displayed rating floor — vendors with no
                               // reviews are excluded once a floor is set
      "min_reviews": 10,       // at least 10 verified-purchase reviews
      "proven_spec_orders": 10 // ≥10 completed orders for THIS process+material
    }
  }
}
```

What a network filters, in order: vendors whose displayed rating is below
`min_stars` (a vendor with no reviews yet cannot clear any floor — the
filter demands demonstrated quality, not the absence of complaints);
vendors with fewer than `min_reviews` verified-purchase reviews; and — the
sharp one — vendors without at least `proven_spec_orders` completed orders
for the **exact process+material being quoted**. A shop with 500 flawless
PLA orders and zero PC orders does not pass `proven_spec_orders` on a PC
request. Like every constraint, `reliability` narrows the offer set; it
never widens it.

## The boundary: what is protocol, what is not

The protocol carries records and verdicts — `ReviewRecord`,
`VendorRating`, `VendorReliability`, the `reliability` constraint, and the
verification/timeliness enums. Everything that produces them is a
network's own: how stars are aggregated and smoothed, how a timeliness
claim is corroborated, how reviews are solicited, how attested records are
weighted against verified ones. Two networks can rank the same vendor
differently and both be conformant; what they cannot do is misstate a
sample size, blend attested records into verified-purchase stars, or mint
a record for a transaction they neither witnessed nor verified.
