When the delivery scheduler fires for a (carer, cared-for) pair, it picks the joke's text input via this priority chain. The chain stops at the first hit; later tiers serve as fallback when earlier tiers have no eligible signal.
-
🎂 Saints name-match (highest)
— If today's Catholic/Orthodox saint name matches the cared-for's first name (case + accent insensitive), the daily
proverb_saint seed for their country wins outright. ~1-in-365 hit rate per name but the most personal signal we have. Generated daily by lolv1-saint-seeds-daily cron from saints_calendar.py. Falls through if no proverb seed exists for that country (admin should run cmd=generate_saint_seeds).
-
♈ Zodiac match
— If the cared-for's birthdate is on file (→
cared_for_zodiac), today's horoscope seed for their sign wins outright — a hard short-circuit, same strength as the name-match (it returns that seed directly, not a soft weight in the pool). Always on for the 12-sign rotation; only the personal name-day signal outranks it.
-
📨 Joke ideas from subscribers (step 2.5)
— Images forwarded to
funny@myjokes.ai are VLM-scored and written to the topical-seeds table as source=user_submitted (active subs) / user_submitted_prospect, filed under the language detected in the image (else the sender's subscription country, else USA). Once the operator approves one on view=topical_seeds (consensus_verdict=pass), it short-circuits ahead of the generic topical pool: the scheduler picks the approved subscriber joke whose language matches the cared-for's language and whose country matches the cared-for's subscription country — highest consensus_funny_mean wins, ties broken by most-recent. Only fires below the personal name-day / zodiac signals; auto-rejected / pending submissions are never eligible.
-
📰 Topical seeds (today + yesterday)
— Weighted-random pick from passing seeds for the cared-for's country, scoped to today + yesterday in UTC. Weights:
status=preferred|live → 2.0× base (admin "Boosted")
status=candidate|empty → 1.0× base
status=blocked|human_rejected → 0 (excluded)
- Each weight ×
consensus_funny_mean (clamped ≥ 0.5)
Country fallback: if zero eligible seeds for the resolved country, falls through to the default country so a French cared-for never silently no-ops.
-
📚 Joke database
— When tiers 1-4 yield nothing (e.g. all seeds rejected for the country), the scheduler falls back to a random pick from the crowdsourced jokedb pool (
pk=jokedb#… rows populated weekly by lolv1-jokedb-crawler-weekly, ~1235 jokes across 13 countries). Hard-filtered by the cared-for's language, preferring a same-country joke then any country in that language; no language match → falls through to tier 6. Reusable pool (not single-use). Delivered as source=from_scheduler_jokedb.
-
🎭 humor_category template (fallback)
— Final fallback: ChatGPT generates joke text from the cared-for's saved
humor_category (dad_jokes, puns, one_liners, knock_knock, observational, sarcasm, …). No external input; pure prompt-driven. This is the path V1 always uses; V2/V3 only land here when every earlier tier misses.
drive_jokes flag: tiers 1-5 are gated on feature_flag:topical_seeds_drive_jokes. When OFF, the scheduler bypasses tiers 1-5 and always uses tier 6 (humor_category template). Toggle from view=topical_seeds.
Daily auto-delivery: lolv1-joke-delivery-every-5-min cron evaluates every active enrollment's delivery window (joke_period) and fires lolv1_crack_a_joke_x86 with the chosen seed payload (source=from_scheduler_topical_seed, _topical_seed_id). The topical seed is marked served (served_count/last_served_at) and excluded from the pool tiers (subscriber-idea + weighted topical) on every later tick so it isn't re-delivered. The personal name-day / zodiac signals prefer an unserved seed but will reuse a served one rather than skip the personalization. jokedb (tier 5) is a reusable pool and isn't served-tracked.