Brand Programs
Phase 2 + 2.5 update (May 2026): the docs below were authored for Phase 1. Phase 2 added Activity Score (per-event-family weekly velocity, 25% rollover), Weekly Bounty (Mon 00:00 UTC payout from a per-brand pool —
partners.bounty_pool_pct), and a redesigned Charge Pack + Amplifier. Phase 2.5 added the universal reward formula (per-brand opt-in viapartners.use_universal_formula). Resonance Official is on the universal formula since 2026-05-07 and has bounty enabled at 5%. The member-facing surface is summarized in Earning in Resonance Official. Deeper integrator docs for Phase 2 mechanics: see Activity Score & Weekly Bounty and Universal Reward Formula sections at the bottom of this page.
A brand program is the bundle of rules that defines how participation in your community earns rewards. Concretely, it is three things working together:
- Monitoring rules — the catalogue of event types your brand recognizes (
quality,gm_checkin,thread_starter, etc.), how much RSNC each pays, what cooldowns and per-user caps apply, and any per-event configuration (strictness, reaction thresholds, anchor requirements). - A Tune-In ladder — a per-event progression where the same
event_typeexists at severalmin_tune_leveltiers. As a member's tune level rises, the event-handler automatically picks the highest-tier rule they qualify for. Rewards and caps grow as tune climbs, but the kind of activity rewarded stays the same. - Unlock events — separate event types that only become claimable once a member crosses a tune-level gate. These add new kinds of participation to the program — hosting a stage, replying to newcomers, sustaining voice presence — rather than inflating the rewards on the events members already had.
Every brand defines its own program. Resonance Official is the canonical reference: a fully populated ladder built around four core events with ten supersession tiers each, ten unlock events spanning Tune-In L0 through L90, and a tightened quality gate. Use it as the model when you copy template.yml into your own brand's monitoring_rules rows.
Three design maxims
The Phase 1 rebalance that produced the reference program was built around three commitments. Hold to these when you design your own program and the same anti-farm, anti-noise properties carry over.
1. Earn from substance, not signal
The quality gate prefers messages that anchor to ongoing community activity — replies to other members, mentions, links to *.rsnc.network content, or words that overlap the channel's recent topic — over messages that merely look well-formed. A 200-word essay about "the essence" posted at 3am into a quiet #general is rejected; a four-sentence reply to a newcomer's question in an active conversation passes. Form is a guardrail, not the reward.
2. Progression unlocks access, not multipliers
Tune-In gates new event types rather than inflating existing numbers. At L10 you unlock stage_host. At L20, deep_reply. At L60, traffic_director. The per-claim RSNC on existing events still grows modestly tier-over-tier (the supersession ladder), but the headline value of leveling up is the new toolkit of activities you can earn from — not a +147% vanity multiplier on a cap nobody hits.
3. Supersession over sprawl
When the same event type pays differently at different tune levels, those rates live as multiple rows of the same event_type in monitoring_rules, distinguished only by min_tune_level. The event-handler's get_effective_rules_for_user RPC selects the highest-matching tier per user. This keeps the rule catalogue small (one event type, ten tiers) instead of sprawling (ten event types named quality_l0, quality_l10, …) — and it means your /cooldowns display, your analytics, and your migration paths only have to know about one logical event.
Where to go next
- Core Events & Supersession — the supersession pattern, with the four Resonance Official core events worked through tier-by-tier.
- Unlock Events — all ten Phase 1 unlock events, their tune-level gates, trigger criteria, and the Discord gateway signals each consumes.
- Quality Gate — composite scoring, strictness levels, and the H1/H3/H4 heuristics that select for engagement over form.
- Reference — Resonance Official Program — the canonical program rendered end-to-end, with all tier values, unlock events, and pointers into the source code.
template.yml— copy-paste skeleton for a new brand program.- Migration Notes — how to migrate an existing flat program onto the tiered structure without breaking your members' progression.
- FAQ — common questions for both members and brand admins.
Activity Score & Weekly Bounty (Phase 2)
Phase 2 layers a velocity stat on top of the per-event reward — Activity Score (AS). It exists to reward sustained, broad participation rather than one-event monomaniacs.
Mechanics
- Per-event-family scoring. AS is bucketed by
event_families.family_id(defined in mig 057). Quality-flavored events all roll into one family bucket; unlock events into another; etc. The bucket id is stored as a JSONB key ondiscord_user_stats.week_as_by_family. - Awarded by
awardActivityScoreForEventin the bot's reward path (discord-bot/src/services/activity-score.js). Fires after a successful reward; failures are fail-OPEN at the network layer (the reward already minted, AS is best-effort). - Per-event AS values live in the
event_familiestable — change them via SQL once you have a comms plan with members. - Weekly cap per family prevents within-week farming. Once you hit the family cap, no more AS for that family until next week.
- 25% rollover Mon 00:00 UTC. Last week's score multiplied by 0.25 carries into this week as a head start. Computed by mig 059's
weekly_rollover_activity_score()RPC. week_isocolumn ondiscord_user_statsdelineates the active week. The first event in a new ISO week clears the JSONB and re-seeds with the rollover.
How to enable Weekly Bounty for your brand
- Set
partners.bounty_pool_pctto your desired share (spec values: 0.000 off, 0.05 low/recommended, 0.10 medium, 0.20 high). The percentage is taken off the brand's total reward emission for the week. - Set
partners.notification_channel_idto a Discord channel where the bounty cron will post the winner announcement. Required — without this, the cron has no place to post. - The PR5 cron at
discord-bot/src/cron/weekly-bounty.jsruns Mon 00:00 UTC, computes per-user share via Activity Score-weighted division of the pool, insertsreward_distributionsrows for each winner, and posts the public announcement. - The bounty payout is excluded from the +6% Signal subscription multiplier (anti-farm against subscribe-then-cancel exploitation of the Mon cron).
Family taxonomy
The default families seeded in mig 057 are a reasonable starting point for most communities. To customize, INSERT into event_families and UPDATE monitoring_rules.family_id to point your event types at the new family. Don't fragment too granularly — the velocity signal is more useful with broader families that capture meaningful activity types (e.g. "messaging" vs splitting "thread_starter" + "conversation_starter" + "deep_reply" into three separate families that each fragment the score).
Operations checklist
The full operator runbook is at discord-bot/docs/PHASE-2-DEPLOY-CHECKLIST.md and covers:
- Workers EFFECT_REGISTRY pre-flight (register
as_yield_boost+direct_yield_boostin workers BEFORE flippinguse_universal_formula) - migration_audit_log RLS check
- Per-brand opt-in templates for
bounty_pool_pct+use_universal_formula+notification_channel_id - Cron schedule verification (
["*/5 * * * *", "0 0 * * 1"]inwrangler.toml)
Universal Reward Formula (Phase 2.5)
Phase 2.5 introduces a per-brand opt-in formula that replaces the legacy monitoring_rules.reward_amount × multipliers pipeline with a single derivation:
base = legacyReward × (1 + level / EVENT_DIVISOR) × (1 + min(AS / 500, 0.5)) × localMultiplier
Where:
legacyReward— themonitoring_rules.reward_amountvalue (still the per-event-type baseline)level— the user's Tune-In levelEVENT_DIVISOR— per-family scaling constant (default 100; tunable viaevent_families.event_divisor)AS— the user'sweek_as_by_family[familyId]valuelocalMultiplier—monitoring_rules.local_multiplier(per-rule fine-tuning, default 1.0)
The downstream stack (role multiplier, streak, server multiplier, Signal subscription) applies on top of base exactly as it did before the formula. Tune scaling is no longer applied separately when the formula path runs — it's baked into the base — so if you opt in, the legacy tuneMultiplier step is automatically skipped.
Opt-in mechanics
partners.use_universal_formulais a boolean defaulted to false (mig 063). Brands stay on legacy until you explicitly flip them.- The bot computes BOTH the legacy and formula values for every event and emits a
[FormulaDelta]log line so operators can compare before flipping. Format:brand=… server=… event=… family=… source=… legacy=N formula=N delta_pct=N. - When you flip the column to
true, the formula becomes the source of truth on the next reward event for that brand. One UPDATE reverts. - Threading lives at
discord-bot/src/services/formula-threading.js;computeDirectRewarditself is atdiscord-bot/src/services/reward-formula.js.
Operator decision flow
- Verify the brand's
monitoring_rulesrows havefamily_idpopulated (else formula skips). - Watch
[FormulaDelta]log lines for ~1 week of normal activity. Investigate any rule whosedelta_pctexceeds ±25%. - If the delta looks acceptable, flip
use_universal_formula = true. - Monitor for the first hour post-flip; one UPDATE reverts if anything looks wrong.
Resonance Official went on the formula 2026-05-07 23:18 UTC.
Spam-gating quick reference
A few things that keep the system honest:
- Reaction dedup:
rxn:{server}:{reactor}:{message}KV key with 24h TTL prevents emoji-toggle farming. One reaction per (reactor, message) per day, regardless of how many emojis or how many toggles. - Quality gate H1 anchor: messages with no anchor signal take a -30 penalty, reliably failing the gate.
- Reactor credibility floor + burst window: only reactors with
credScore ≥ 40count towardreaction_threshold; reactions within 30s of the first one collapse to a single effective reactor. - Per-event cooldowns + max_claims on
monitoring_rulescap any individual event's per-week impact. - Activity Score weekly cap per family stops within-week velocity inflation.
- Subscription multiplier excludes weekly_bounty so subscribe-then-cancel can't milk the Monday cron.
See Quality Gate for full heuristics + worked examples.