semantic bufo search find-bufo.com
bufo
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor(bot): make cooldown tuning configurable via env vars

COOLDOWN_SCALE_FACTOR (default 400) and LENGTH_MULTIPLIER (default 6)
are now env vars so we can tune without redeploying code. also update
dashboard to reflect current multipliers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

zzstoatzz 232133ab 1717a491

+13 -10
+4
bot/src/config.zig
··· 7 7 min_phrase_words: u32, 8 8 posting_enabled: bool, 9 9 cooldown_minutes: u32, 10 + cooldown_scale_factor: u32, 11 + length_multiplier: u32, 10 12 exclude_patterns: []const u8, 11 13 stats_port: u16, 12 14 backend_url: []const u8, ··· 19 21 .min_phrase_words = parseU32(getenv("MIN_PHRASE_WORDS"), 3), 20 22 .posting_enabled = parseBool(getenv("POSTING_ENABLED")), 21 23 .cooldown_minutes = parseU32(getenv("COOLDOWN_MINUTES"), 120), 24 + .cooldown_scale_factor = parseU32(getenv("COOLDOWN_SCALE_FACTOR"), 400), 25 + .length_multiplier = parseU32(getenv("LENGTH_MULTIPLIER"), 6), 22 26 .exclude_patterns = getenv("EXCLUDE_PATTERNS") orelse "what-have-you-done,what-have-i-done,sad,crying,cant-take,knife,what-are-you-doing-with-that,\\brip\\b,fire,ventilator,carnage,riot,grenade,pitchfork,sobbing,breakdown,meltdown,panic,pleading,cry,call-for-help", 23 27 .stats_port = parseU16(getenv("STATS_PORT"), 8080), 24 28 .backend_url = getenv("BACKEND_URL") orelse "https://find-bufo.com",
+7 -8
bot/src/cooldown.zig
··· 8 8 9 9 const std = @import("std"); 10 10 11 - /// Quadratic scale factor for match frequency. 12 - /// At 5% of matches: ~2x. At 20%: ~17x. At 33%: ~44x. 13 - const SCALE_FACTOR: f64 = 400.0; 14 - 15 11 /// Ratio threshold for the rare-bufo exemption (0.5%). 16 12 const RARE_THRESHOLD: f64 = 0.005; 17 13 ··· 20 16 /// phrase_len: number of words in the bufo's matching phrase 21 17 /// ratio: this bufo's match count / total match count (0.0 to 1.0) 22 18 /// base_secs: base cooldown from config (e.g. 7200 for 120 minutes) 23 - pub fn getCooldownSeconds(phrase_len: u32, ratio: f64, base_secs: u64) u64 { 19 + /// scale_factor: quadratic frequency scale (e.g. 400) 20 + /// length_mult_num: numerator for length multiplier (e.g. 6 → 3-word gets 6/3=2x) 21 + pub fn getCooldownSeconds(phrase_len: u32, ratio: f64, base_secs: u64, scale_factor: u32, length_mult_num: u32) u64 { 24 22 // rare-bufo exemption: specific phrases (4+ words) with negligible match share 25 23 if (phrase_len >= 4 and ratio < RARE_THRESHOLD) return 0; 26 24 27 - // length multiplier: 1-word → 6x, 2-word → 3x, 3-word → 2x, 4+ → 1.5x 25 + // length multiplier: shorter phrases → longer cooldowns 28 26 const clamped: f64 = @floatFromInt(@min(phrase_len, 4)); 29 - const length_mult = 6.0 / clamped; 27 + const length_mult = @as(f64, @floatFromInt(length_mult_num)) / clamped; 30 28 31 29 // frequency multiplier: quadratic scaling for dominant bufos 32 - const freq_mult = 1.0 + SCALE_FACTOR * ratio * ratio; 30 + const sf: f64 = @floatFromInt(scale_factor); 31 + const freq_mult = 1.0 + sf * ratio * ratio; 33 32 34 33 const base_f: f64 = @floatFromInt(base_secs); 35 34 return @intFromFloat(base_f * length_mult * freq_mult);
+1 -1
bot/src/main.zig
··· 162 162 // per-bufo cooldown (scaled by phrase length + match frequency) 163 163 const base_secs: u64 = @as(u64, state.config.cooldown_minutes) * 60; 164 164 const ratio = state.stats.getMatchRatio(match.name); 165 - const cooldown_secs: i64 = @intCast(cooldown.getCooldownSeconds(match.phrase_len, ratio, base_secs)); 165 + const cooldown_secs: i64 = @intCast(cooldown.getCooldownSeconds(match.phrase_len, ratio, base_secs, state.config.cooldown_scale_factor, state.config.length_multiplier)); 166 166 167 167 if (state.stats.getLastPosted(match.name)) |last_posted| { 168 168 if (now - last_posted < cooldown_secs) {
+1 -1
bot/src/stats_template.zig
··· 249 249 \\ 250 250 \\<div class="strategy"> 251 251 \\ <h2 style="margin-top:0">posting strategy</h2> 252 - \\ <p>shorter phrases get longer cooldowns (1-word: 4x base, 2-word: 2x, 3-word: 1.3x). 252 + \\ <p>shorter phrases get longer cooldowns (1-word: 6x base, 2-word: 3x, 3-word: 2x, 4+: 1.5x). 253 253 \\ rare bufos (4+ words, &lt;0.5% of matches) post immediately. frequent bufos get 254 254 \\ quadratic frequency scaling (a bufo at 20% of matches waits ~17x the base cooldown).</p> 255 255 \\ <div class="strategy-rates" id="strategy-rates"></div>