⚠ These are live. A change here re-tiers every restaurant immediately. To tune the tier cutoffs with a preview first, use the Calibrate tab.
the mappings & word-lists that turn raw signal into a score: the award classifier, the gem/nope/complaint vocabularies, which categories count as credentials, and how each category routes to a weight. Every row has a plain-English description. Edits are live — the engine reads these directly.
these are the formulas and decision rules the engine runs. They reference the editable params above by name. They're shown here so nothing that influences a rating is hidden in code — but they're the engine's shape, not numbers to tune (changing them is a redesign, done via migration).
How a fact is weighted
fact_weight = trust × recency_decay
recency_decay = min(decay_max_weight, 0.5 ^ (age_in_days / half_life)) // half_life = decay_half_life_days, or decay_half_life_credential_days for credential categories; the clamp stops future-dated facts being amplified above 1.0
trust = the outlet's trust weight from the Source-trust table above (or trust_default if the outlet isn't registered)
Confidence (how sure)
confidence = how many independent credible families back the place // awards · national critic · local editorial · chef
3+ families → 1.0 · 2 → 0.7 · 1 → 0.4 · 0 → needs facts
How the tier is decided
1. closed, or credible_facts < min_credible_facts → no tier (needs facts — a data gap to fill)
2. otherwise by absolute merit: ≥ merit_cut_5 → DAF(5) · ≥ merit_cut_4 → Delicious(4) · ≥ merit_cut_3 → Damn Good(3) · ≥ merit_cut_2 → Worth Trying(2) · else Nope-tier(1)
// cuisine, price & city are filters in Explore, never part of the math. Nope is a separate diagnostic — it never changes the tier.
Ranking basis (eff_pct)
eff_pct = a place's percentile of net merit within its cuisine cohort.
For cohorts smaller than cohort_smooth_min_n it blends pct_cohort_blend·(cuisine percentile) + (1−blend)·(global percentile).
Cohort = the restaurant's Google primary type (mapped to a cuisine); falls back to 'general' when Google has none.
Category special-cases (which signal does what)
cat 1 = Awards → the Award-classifier config · cat 5 = Local voice → the gem/nope vocabulary · cat 7 review_themes → the complaint vocabulary · cat 11 = Operational status → "closed" when business_status ≠ OPERATIONAL · all other category→weight routing is in the config tables above.
How the universe is built (which restaurants get in)
A discovered candidate is promoted into the universe only if it: resolves on Google Places · is a food/drink place · is open (not CLOSED_PERMANENTLY) · its Google match is within universe_radius_km of the city centre · and it is credentialed (an Award or Critic source) OR has ≥ universe_min_reviews Google reviews. // credentialed places skip the review floor — both gates are editable params above; the rest is identity/dedup, not tuning
Only genuine math is fixed in code: the 0.5 half-life base, the 1.0 ceilings/anchors, and the weakest-link (LEAST) combination. Everything else above is a param or a config row you can edit.