Skip to main content

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 via partners.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_type exists at several min_tune_level tiers. 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 on discord_user_stats.week_as_by_family.
  • Awarded by awardActivityScoreForEvent in 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_families table — 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_iso column on discord_user_stats delineates 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

  1. Set partners.bounty_pool_pct to 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.
  2. Set partners.notification_channel_id to a Discord channel where the bounty cron will post the winner announcement. Required — without this, the cron has no place to post.
  3. The PR5 cron at discord-bot/src/cron/weekly-bounty.js runs Mon 00:00 UTC, computes per-user share via Activity Score-weighted division of the pool, inserts reward_distributions rows for each winner, and posts the public announcement.
  4. 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_boost in workers BEFORE flipping use_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"] in wrangler.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 — the monitoring_rules.reward_amount value (still the per-event-type baseline)
  • level — the user's Tune-In level
  • EVENT_DIVISOR — per-family scaling constant (default 100; tunable via event_families.event_divisor)
  • AS — the user's week_as_by_family[familyId] value
  • localMultipliermonitoring_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_formula is 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; computeDirectReward itself is at discord-bot/src/services/reward-formula.js.

Operator decision flow

  1. Verify the brand's monitoring_rules rows have family_id populated (else formula skips).
  2. Watch [FormulaDelta] log lines for ~1 week of normal activity. Investigate any rule whose delta_pct exceeds ±25%.
  3. If the delta looks acceptable, flip use_universal_formula = true.
  4. 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 ≥ 40 count toward reaction_threshold; reactions within 30s of the first one collapse to a single effective reactor.
  • Per-event cooldowns + max_claims on monitoring_rules cap 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.