Field surprises
Now and then, after you log an observation, Rastrum may show you a small card: a fact, a rare-species call-out, or how many other observers were active today in your region. This page explains exactly how that is decided — and how to turn it off.
Why this exists
B.J. Fogg describes in Persuasive Technology (ch. 9) that hidden variable rewards — slot-machine style — are a dark pattern. But transparent variable rewards, where you know the rules, are not manipulation: they are surprise-and-delight. This page exists so Rastrum stays on the right side of that line.
The catalog is FIXED in the code (no surprise type can be added without a PR). The daily cap is FIXED. The toggle is OFF by default.
The catalog (3 kinds)
dato_curioso — did you know?
- When it fires: random, ~10 % of synced observations that have an identified species with a curated fact available in your locale.
- Randomness: the dice roll is made with a PRNG seeded by the observation ID, so re-opening the app does not change the outcome.
- Facts: hand-curated per species in src/lib/surprise-facts.ts. When no fact is on file for that species we use a generic pool.
rarito — rare find
- When it fires: deterministic. If the identified species lands in the "rare" bucket of the nightly rarity recompute (top ~5 %), this card shows. No randomness.
- Priority: rarito wins over the others when it fires — it is the most informative of the three.
comunidad_activa_hoy — community active today
- When it fires: deterministic, max once per day. Only when there are 2 or more active observers in your country today.
- How it is computed: the SQL function community_active_observers_today() counts unique observers with synced observations today in your country (ISO-3166), excluding profiles that opted out of leaderboards.
Daily cap
At most ONE surprise per day, no matter how many observations you log. The cap is enforced in two places: browser localStorage (fast cap) and the SQL function record_surprise_event() in Postgres (race-proof across tabs).
Privacy
- The surprise_events table is RLS read-own. Only you see your own rows.
- Nothing is sent to sponsors, third parties, nor ever published on your profile.
- The active-observers count is computed from already-public data (same source as the community directory).
How to turn it off
Go to Profile → Settings → Preferences → "Field surprises" and uncheck the box. The change takes effect immediately.
What this is NOT
- Not loot. There are no unlockables, currencies, or "surprise streaks". A surprise is a message, not a redeemable prize.
- Does not replace badges. Achievements and streaks remain independent. Surprises do not affect your karma, streak, or dex.
- Not advertising. No surprise kind promotes products, sponsors, or an upcoming event.
Issue: #727 · Code: src/lib/surprises.ts