BotBouncer — Source Code Analysis

Date: 2026-08-12 Purpose: Detailed analysis of BotBouncer’s actual detection logic, based on reading the source code of both the main app (fsvreddit/bot-bouncer) and the evaluation engine (fsvreddit/bot-bouncer-evaluation). Sources: All claims in this document are from actual source code read from GitHub raw URLs on Aug 12, 2026. No inference from filenames alone.


1. Architecture Overview

BotBouncer is a Reddit Dev Platform app (not a standalone bot). It runs inside Reddit’s infrastructure and responds to platform events (post creation, comment creation, comment edits). It has two repos:

RepoPurpose
fsvreddit/bot-bouncerMain app — event handling, reporting, banning, post creation, AI summaries
fsvreddit/bot-bouncer-evaluationEvaluation engine — all bot detection logic lives here

How it works at a high level:

1. A subreddit installs BotBouncer from the Dev Platform app directory
2. BotBouncer watches ALL new posts and comments on that subreddit
3. When a new post/comment is created:
   a. Check if the author is already classified as "banned" → if yes, ban + remove immediately
   b. If unknown, run through ALL evaluators (see §3) to check if the content looks bot-like
   c. If an evaluator flags it as a possible bot → auto-submit to r/BotBouncer for evaluation
4. On r/BotBouncer, the account goes through full evaluation:
   a. All evaluators run against the user's full history (100 most recent items)
   b. If evaluators match AND can auto-ban AND meet content threshold → auto-ban
   c. If evaluators match but can't auto-ban → flag for manual review
   d. If no evaluators match → needs manual review
5. OpenAI summary is generated for moderators to review (see §5)
6. Once classified as "banned":
   a. Account is banned from the reporting subreddit
   b. Account is banned from ALL participating subreddits where it has content in the past week
   c. A public "Overview for <username>" post is created on r/BotBouncer

2. Two Detection Modes

Mode 1: Reactive (Human-Triggered)

A subreddit moderator or user manually reports an account:

StepWhat HappensSource File
1Mod clicks “Report to /r/BotBouncer” on a comment/posthandleReportUser.ts
2Form asks: “Why is this a bot?” (optional context) + “Show publicly?” + “Notify me?”handleReportUser.ts:reportFormDefinition
3Submission is queuedexternalSubmissions.ts:addExternalSubmissionFromClientSub
4Post is created on r/BotBouncer with the reporter’s contextpostCreation.ts
5Full evaluation runs (all evaluators against user’s history)handleControlSubAccountEvaluation.ts:evaluateUserAccount
6If evaluators auto-ban → flair set to “Banned”handleControlSubAccountEvaluation.ts:handleControlSubAccountEvaluation
7If no auto-ban match → “Needs manual review” + OpenAI summary generatedcreateAISummary.ts:generateOpenAISummary

Key detail from handleReportUser.ts: The reporting user can add context text. This context is shown publicly on the BotBouncer post if they choose “Show publicly” (default: true). This is exactly what we saw in our BotBouncer reports — the reporter wrote “asking a question and not directly answering the post.”

Mode 2: Proactive (Automated Bot Hunting)

BotBouncer actively scans known karma-farming subreddits for new accounts:

StepWhat HappensSource File
1Scheduled job runs periodicallykarmaFarmingSubsCheck.ts:evaluateKarmaFarmingSubs
2Fetches the 100 newest posts from each karma-farming subkarmaFarmingSubsCheck.ts:getAccountsFromSub
3Extracts unique authors from those postskarmaFarmingSubsCheck.ts:getDistinctAccounts
4Filters out accounts already known to BotBouncerkarmaFarmingSubsCheck.ts:queueKarmaFarmingSubs
5Queues unknown accounts for evaluationkarmaFarmingSubsCheck.ts:queueKarmaFarmingAccounts
6Evaluates each account using all evaluatorskarmaFarmingSubsCheck.ts:evaluateAndHandleUser
7If evaluators match + can auto-ban + meet threshold → auto-bankarmaFarmingSubsCheck.ts:evaluateAndHandleUser

The list of karma-farming subs is configurable — it’s stored in evaluator variables (generic:karmafarminglinksubs and generic:karmafarminglinksubsnsfw) which are loaded from wiki pages on r/BotBouncer. The list is NOT hardcoded in the source code — it’s maintained as a wiki configuration that can be updated without redeploying.

Key detail from karmaFarmingSubsCheck.ts:

  • Checks up to 200 subs per run
  • Checks subs that haven’t been checked in the last 25 minutes
  • Processes accounts in cohorts (evens/odds) for load balancing
  • Processes 10 accounts per batch
  • If >3 failures in a batch, enters a 2-minute cooldown

Mode 3: Real-Time Content Detection (On Client Subreddits)

When ANY user posts or comments on a subreddit that has BotBouncer installed:

StepWhat HappensSource File
1Post or comment is created on a client subreddithandleContentCreation.ts
2. If author already classified as banned → ban + remove immediatelyhandleClientPostOrComment.ts:handleContentCreation
3. If author unknown → run ALL evaluators’ preEvaluatePost or preEvaluateCommenthandleClientPostOrComment.ts:handleClientCommentCreate
4. If any evaluator’s pre-check triggers → run full evaluationhandleClientPostOrComment.ts:checkAndReportPotentialBot
5. Full evaluation fetches user’s 100 most recent items and runs all evaluatorshandleClientPostOrComment.ts:checkAndReportPotentialBot
6. If any evaluator returns isLikelyBot = true → auto-submit to r/BotBouncerhandleClientPostOrComment.ts:checkAndReportPotentialBot
7. Rate limited: re-checks a user at most once per 15 minuteshandleClientPostOrComment.ts:handleClientCommentCreate

Key detail: The preEvaluateComment and preEvaluatePost methods are FAST pre-checks — they decide whether to trigger the full evaluation. Each evaluator has different pre-check logic (see §3). The full evaluation fetches the user’s complete history and runs all evaluators in depth.


3. The 24 Evaluators (Actual Detection Logic)

From allEvaluators.ts, these are ALL the evaluators, in the order they run:

Tier 1: Account-Only Evaluators (Fastest — no history needed)

#EvaluatorWhat It DetectsPre-Check LogicFull Check Logic
1EvaluateBadUsernameBot-like username patternsChecks username against regex patterns from configIf username matches banned patterns
2EvaluateBioTextBot text in user bio/profile descriptionChecks if bio text matches banned regex patternsChecks bio against bantext regex list; skips if comment karma > 2000 AND link karma > 2000
3EvaluateBioTextDefinedHandlesSpecific bio text patterns (configurable handles)Same as BioText but with defined handle patternsSame
4EvaluateBadDisplayNameBot display name patternsChecks display name against regexIf display name matches banned patterns
5EvaluateBadDisplayNameDefinedHandlesSpecific display name patternsSame with defined handlesSame
6EvaluateObfuscatedBioKeywordsObfuscated keywords in bio (e.g., using symbols to bypass filters)Checks bio for obfuscated versions of banned keywordsDetects keyword obfuscation patterns
#EvaluatorWhat It DetectsPre-Check LogicFull Check Logic
7EvaluateDomainSharerAccounts sharing a specific domain across postsChecks if post URL matches watched domainsChecks if user has multiple posts sharing the same domain
8EvaluatePinnedPostTitlesBots with identical pinned posts on their profileChecks if pinned post title matches known patternsChecks for specific pinned post title patterns
9EvaluateSelfCommentAccounts commenting on their own postsChecks if comment is on own postChecks for self-comment patterns
10EvaluatePostTitlePosts with titles matching known bot patternsChecks post title against bantext regex listChecks NSFW posts from last week against banned title regexes; skips if comment karma > 2000 AND link karma > 5000
11EvaluatePostTitleDefinedHandlesSpecific post title patterns (configurable)Same with defined handlesSame
12EvaluatePostTitleMultiMultiple post titles matching bot patternsChecks against multiple regex patternsChecks for posts matching multiple criteria
13EvaluateSuspiciousFirstPostFirst post is suspicious (image/video on specific subs)Checks if post is on a watched subreddit AND is an i.redd.it/v.redd.it/gallery postChecks if account has exactly 1 post (on watched sub, image/video), ≤1 comment, and the comment came before the post; pre-check: account <14 days old AND comment karma <50
14EvaluateInconsistentAgeBotNSFW accounts with inconsistent ages in post titlesChecks if NSFW post title contains an age numberChecks if user has ≥4 NSFW posts in last 2 weeks with ≥3 different ages found in titles; pre-check: comment karma <50
15EvaluateInconsistentGenderBotNSFW accounts with inconsistent gender in post titles (M4F, F4M, etc.)Checks NSFW post title for gender markersChecks for inconsistent gender markers across NSFW posts
16EvaluateWorldTravellerAccounts posting in unrelated geo-subreddits (e.g., posting in r/London AND r/NYC AND r/Sydney)Checks if post is on a geo-subChecks if user posts across multiple unrelated geographic subreddits
17EvaluateCommentPhraseComments containing specific bot phrasesChecks if comment body matches a regex from phrases configChecks if user has ≥1 comment matching a phrase regex; pre-check: account <60 days old AND comment karma <100
18EvaluateTGGroupTelegram group spam botsChecks for Telegram links in contentChecks for Telegram promotion patterns
#EvaluatorWhat It DetectsPre-Check LogicFull Check Logic
19EvaluateWarmupBotModerator accounts that are warmup botsChecks if post title matches postTitleRegexesChecks if user is a mod of a subreddit matching subredditRegexes AND has posts matching postTitleRegexes
20EvaluateSocialLinksAccounts with suspicious social links (OnlyFans, Instagram, etc.)Checks if any social link matches badlinks configChecks social links AND post URLs for bad domains; pre-check: (comment karma <500 AND account <2 months old) OR account >5 years old OR NSFW
21EvaluateBotGroupAdvancedThe most powerful evaluator — flexible rule-based bot detectionDepends on group configSee §4 below
22EvaluateTitleCopyBotBots whose comments copy the post title verbatimChecks if comment body === post titleChecks if the 5 most recent comments all copy their respective post titles exactly, user has 0 posts, and all comments are single-line; pre-check: account <180 days old
23EvaluateTextInNsfwImagesNSFW bots with text/watermarks on images (social handles)Checks NSFW image postsAnalyzes NSFW images for embedded text/watermarks
24EvaluateBotGroupAdvancedInternalSame as BotGroupAdvanced but with experimental features enabledSameSame as BotGroupAdvanced but can use new features

4. EvaluateBotGroupAdvanced — The Most Dangerous Evaluator

This is the most sophisticated and flexible evaluator. It’s a rule-based system that can be configured via wiki pages to detect virtually any bot pattern — without code changes.

How it works:

From EvaluateBotGroupAdvanced.ts (54,586 characters of source — the largest evaluator by far):

  1. Bot Groups are defined in evaluator variables (configurable via wiki). Each group has:

    • name — group identifier
    • submitterName — optional, only trigger if reported by specific submitter
    • Account criteria (age, karma, bio text, display name, social links, etc.)
    • History criteria (posts/comments matching specific patterns)
    • Social link criteria
  2. Account Matching (accountMatchesGroup):

    • Checks account age (max/min in days, or date range)
    • Checks comment karma and link karma thresholds
    • Checks bio text against regexes
    • Checks display name against regexes
    • Checks if account is NSFW
    • Checks social links against patterns
  3. History Matching (historyMatchesCriteriaGroup):

    • Can match posts or comments with criteria like:
      • subredditName — must be in specific subreddits
      • notSubredditName — must NOT be in specific subreddits
      • bodyRegex — comment/post body must match regex
      • titleRegex — post title must match regex (for posts)
      • minBodyLength / maxBodyLength — body length constraints
      • minParaCount / maxParaCount — paragraph count constraints
      • minKarma / maxKarma — score constraints
      • isTopLevel — for comments, must be top-level
      • isCommentOnOwnPost — comment on own post
      • postAuthorNameRegex — parent post’s author matches regex
      • postTitleRegex — parent post’s title matches regex
      • postBodyRegex — parent post’s body matches regex
      • postUrlRegex — parent post’s URL matches regex
      • age — content age constraints
      • edited — whether content was edited
      • matchesNeeded — minimum number of matching items
      • distinctSubsNeeded — minimum number of distinct subreddits
  4. Logical Operators: Criteria can be combined with:

    • some — OR logic (any sub-criteria must match)
    • every — AND logic (all sub-criteria must match)
    • not — negation
  5. hasMoreThanOneCommentOnPosts: Can check if the user has multiple comments on the same post (detecting double-commenting behavior)

What this means for us:

BotBouncer operators can create a custom bot group that matches our exact behavior pattern without writing any code. For example, they could configure a group that matches:

  • Accounts <180 days old
  • Comment karma <250
  • Has ≥3 comments in bodyRegex matching “what’s.*underrated|what’s.*discovered|what.*you.*think”
  • Comments in ≥2 of: NoStupidQuestions, AmItheAsshole, CasualConversation, TheTopicOfTheDay
  • isTopLevel: true

This would catch our exact “question-back” pattern. The config is on a private wiki page — we can’t see what groups are currently defined.


5. OpenAI Integration — AI-Assisted Detection

What the aiAnalysis/ module actually does:

From the source code, BotBouncer uses OpenAI in two ways:

5a. OpenAI Summary Generation (createAISummary.ts)

When an account is submitted to r/BotBouncer, an OpenAI summary is generated to help moderators review:

StepWhat HappensSource
1Gathers user info: 100 most recent posts/comments, social links, account propertiesgatherUserDetailsForOpenAI.ts:getUserInfoForOpenAI
2For each comment, also fetches the parent post title and URLgatherUserDetailsForOpenAI.ts:getUserInfoForOpenAI
3Includes initial evaluator results (which evaluators matched)createAISummary.ts:generateOpenAISummary
4Includes moderator notes about the usercreateAISummary.ts:generateOpenAISummary
5Sends all this to OpenAI via a prompt templatecreateAISummary.ts:generateOpenAISummary
6OpenAI model: gpt-5.4-mini (default)openAI.ts:callOpenAI
7Temperature: 0.7 (default)openAI.ts:callOpenAI
8Result is posted as a comment on the BotBouncer tracking post (removed, not public)createAISummary.ts:createResponse
9Cached for 1 day per usercreateAISummary.ts:getCacheKeyForUserSummary

Minimum requirements for AI summary (from createAISummary.ts):

  • Account must be ≥30 days old (openAIMinimumAccountAgeInDays)
  • User must have ≥25 content items (openAIMinimumContentCount)

What data is sent to OpenAI:

{
  "userInfo": {
    "username": "...",
    "commentKarma": 216,
    "linkKarma": 1,
    "hasVerifiedEmail": true,
    "isModerator": false,
    "createdAt": "2026-03-12...",
    "socialLinks": [{"title": "...", "url": "..."}]
  },
  "history": [
    {
      "type": "comment",
      "content": "love how this lets us share everything from books to music...",
      "karma": 1,
      "subredditName": "TheTopicOfTheDay",
      "createdAt": "2026-08-10...",
      "isTopLevel": true,
      "edited": false,
      "parentPostInfo": {
        "title": "The topic of the day is... Media Monday!",
        "createdAt": "2026-08-10...",
        "url": "..."
      }
    },
    ...
  ]
}

This means OpenAI sees: full comment text, subreddit, score, timestamp, whether it’s top-level, whether it was edited, AND the parent post’s title and URL. The AI can then judge whether the comment is relevant to the post, answers the question, or sounds AI-generated.

5b. Ask AI Feature (askAI.ts)

Moderators can type !askai <question> in modmail to ask OpenAI a specific question about a user. This sends the same user data to OpenAI along with the moderator’s specific question.

5c. OpenAI for Evaluation

From settings.ts, there are THREE separate OpenAI API keys:

  • OpenAIKey — for general AI summaries
  • OpenAIEvaluationKey — for evaluation (used in checkAndReportPotentialBot)
  • OpenAIAdminKey — for admin operations

From handleClientPostOrComment.ts:checkAndReportPotentialBot:

if (evaluator.needsOpenAiKey && openAIEvaluationKey) {
    evaluator.setOpenAiKey(openAIEvaluationKey);
}

This means some evaluators use OpenAI as part of the automated detection logic — not just for summaries. The needsOpenAiKey flag on UserEvaluatorBase is false by default, but can be overridden by evaluators that need AI analysis.


6. The User Summary — What BotBouncer Knows About Each Account

From userSummary.ts, when an account is evaluated, BotBouncer generates a detailed summary including:

Data PointHow It’s ComputedWhy It Matters
Account ageTime since createdAtYoung accounts are more suspicious
Comment karmaFrom profileLow comment karma + high activity = bot pattern
Post karmaFrom profileLopsided post/comment ratio is suspicious
Verified emailFrom profileUnverified email = lower trust
Is moderatorFrom profileMods are exempt from banning
Social linksFrom profileSuspicious links (OnlyFans, Instagram, etc.)
Display nameFrom profileBot display name patterns
Bio textFrom profile, with banned domains redactedBot bio text patterns
Original bioStored separately, compared to currentDetects bio changes after detection
Comment subredditscountBy of subreddits in comment historyShows karma-farming sub concentration
Comments per postcountBy of postId countsDetects multiple comments on same post
First comment timeTime between account creation and first commentBots often comment immediately after creation
Time between commentsMin, 10th percentile, max, average, medianUniform timing = automation
Time between postsSame metrics for postsSame
Edited posts %Percentage of posts that were editedBots rarely edit; humans often do
Activity by time of dayHistogram of activity by hourShows timezone mismatch or 24/7 automation
Post subredditscountBy of subreddits in post historyShows targeting
First post timeTime between account creation and first postSame as first comment

Key insight: BotBouncer explicitly computes timing metrics — min/10th-percentile/max/average/median time between comments and posts. This is exactly the kind of analysis that would detect our RPA pipeline’s regular 7-second delays and scheduled commenting windows.


7. What BotBouncer Does NOT Do

Based on reading the actual source code, here’s what BotBouncer cannot detect:

What It Doesn’t CheckWhy
IP addressesNo IP checking in any evaluator — that’s Reddit’s admin-level system, not BotBouncer
Browser fingerprintsNo fingerprint checking — same reason
Cookie/session linkingNo cookie analysis
Cross-account timing correlationEvaluators run per-account, not across accounts
Vote manipulationNo vote analysis in any evaluator
Direct AI-text detection (per-comment)The aiAnalysis module uses OpenAI for summaries, not for per-comment AI detection. The CommentPhrase evaluator checks for specific regex patterns, not general AI-ness. However, OpenAI could flag AI patterns in the summary it generates for moderators.
Account creation IPNo IP analysis at all

Important clarification: BotBouncer is a subreddit-level tool, not a platform-level tool. It does NOT do IP analysis, fingerprinting, or network-level detection. That’s Reddit’s “anti-evil” system. BotBouncer only analyzes publicly visible account behavior: post titles, comment text, bio text, social links, display name, username, and timing patterns.


8. Ban Message — The Exact Text

From settings.ts:CONFIGURATION_DEFAULTS.banMessage:

Bots and bot-like accounts are not welcome on /r/{subreddit}.
[I am a bot, and this action was performed automatically](/r/BotBouncer/wiki/index).
**If you wish to appeal the classification of the /u/{account} account, please
/message /r/BotBouncer rather than replying to this message.**

This is the default ban message. Subreddits can customize it. The “I am a bot, and this action was performed automatically” line is what we saw in our ban messages.


9. Exemptions — How to Not Get Banned

From the source code, these accounts are exempt from BotBouncer:

ExemptionSourceHow It Works
Approved SubmittershandleClientPostOrComment.ts:handleContentCreationIf exemptApprovedUsers setting is true (default) and user is an approved contributor of the sub, skip ban
ModeratorshandleClientPostOrComment.ts:handleContentCreationIf user is a mod of the sub, skip ban
Proof flairhandleClientPostOrComment.ts:handleContentCreationIf user has a flair with CSS class ending in proof (e.g., botbustproof), skip ban
Previously unbannedhandleClientPostOrComment.ts:handleContentCreationIf autoWhitelist is true (default) and user was previously unbanned, skip ban
High karma (BioText)EvaluateBioText.ts:preEvaluateUserIf comment karma > 2000 AND link karma > 2000, skip bio text check
High karma (PostTitle)EvaluatePostTitle.ts:preEvaluateUserIf comment karma > 2000 AND link karma > 5000, skip post title check
High karma (CommentPhrase)EvaluateCommentPhrase.ts:preEvaluateUserIf comment karma ≥ 100 OR account age > 60 days, skip comment phrase check
High karma (SuspiciousFirstPost)EvaluateSuspiciousFirstPost.ts:preEvaluateUserIf comment karma ≥ 50 OR account age > 14 days, skip suspicious first post check
High karma (SocialLinks)EvaluateSocialLinks.ts:preEvaluateUserIf comment karma ≥ 500 AND account > 2 months old, skip social links check (unless account > 5 years old or NSFW)
Old account (InconsistentAge)EvaluateInconsistentAgeBot.ts:preEvaluateUserIf comment karma ≥ 50, skip inconsistent age check
Old account (TitleCopyBot)EvaluateTitleCopyBot.ts:preEvaluateUserIf account > 180 days old, skip title copy check
Service botshandleReportUser.ts:reportFormHandlerBots that respond to user commands (e.g., RemindMeBot) are out of scope

Key pattern: Most evaluators have karma thresholds that exempt high-karma accounts. The thresholds vary:

  • Bio text: 2000 comment + 2000 link karma
  • Post title: 2000 comment + 5000 link karma
  • Comment phrase: 100 comment karma OR 60 days account age
  • Suspicious first post: 50 comment karma OR 14 days account age
  • Social links: 500 comment karma AND 2 months age
  • Title copy: 180 days account age

For our accounts: Most of our banned accounts had <250 comment karma, so they were NOT exempt from any evaluator. If we had built accounts to 2000+ comment karma before farming in BotBouncer-monitored subs, most evaluators would have skipped them.


10. The canAutoBan and banContentThreshold System

Each evaluator has two flags that determine whether a match leads to automatic ban:

FlagDefaultPurpose
canAutoBantrueIf true, this evaluator’s match can trigger an automatic ban without human review
banContentThreshold10Minimum number of content items (posts+comments) the user must have for an auto-ban

From handleControlSubAccountEvaluation.ts:evaluateUserAccount:

const metThreshold = itemCount >= bot.banContentThreshold;

If a user has fewer items than the threshold, the evaluator match is logged but doesn’t trigger auto-ban — it goes to manual review instead.

Thresholds by evaluator (from source code):

EvaluatorbanContentThresholdNotes
BioText0Any match = auto-ban
SocialLinks0Any match = auto-ban
WarmupBot0Any match = auto-ban
CommentPhrase1Just 1 matching comment needed
SuspiciousFirstPost1Just 1 suspicious post needed
PostTitle1Just 1 matching post title needed
TitleCopyBot55 comments copying post titles needed
InconsistentAgeBot66 NSFW posts with inconsistent ages needed
BotGroupAdvanced10 (default)10 content items needed (configurable per group)

11. How Our Accounts Got Caught — Mapping to Source Code

Based on the actual source code, here’s what likely happened to our accounts:

The Trigger Chain:

StepWhat HappenedSource File/Function
1Our account commented on r/TheTopicOfTheDay (which has BotBouncer installed)handleContentCreation.ts:handleCommentCreate
2BotBouncer checked if the author was already classified → NohandleClientPostOrComment.ts:handleClientCommentCreate
3BotBouncer ran preEvaluateComment on all evaluatorshandleClientPostOrComment.ts:handleClientCommentCreate
4CommentPhrase evaluator’s preEvaluateComment may have triggered — if our “question-back” phrases are in the configured phrases regex listEvaluateCommentPhrase.ts:preEvaluateComment
5OR: No pre-check triggered, but the comment was visible to a human moderatorN/A — human detection path
6The human moderator clicked “Report to /r/BotBouncer”handleReportUser.ts:handleReportUser
7Moderator added context: “asking a question and not directly answering the post”handleReportUser.ts:reportFormDefinition
8Submission queued + post created on r/BotBouncerexternalSubmissions.ts:addExternalSubmissionFromClientSub
9Full evaluation ran: all 24 evaluators against the user’s 100 most recent itemshandleControlSubAccountEvaluation.ts:evaluateUserAccount
10BotGroupAdvanced may have matched — if a bot group is configured for accounts that comment on karma-farming subs with question-back patternsEvaluateBotGroupAdvanced.ts:evaluate
11CommentPhrase may have matched — if question-back phrases are in the configEvaluateCommentPhrase.ts:evaluate
12OR: No evaluator auto-banned, so it went to manual reviewhandleControlSubAccountEvaluation.ts:handleControlSubAccountEvaluation
13OpenAI summary generated for the moderatorcreateAISummary.ts:generateOpenAISummary
14OpenAI received our comment text + parent post title + full history and may have flagged the AI patterngatherUserDetailsForOpenAI.ts:getUserInfoForOpenAI
15Human moderator reviewed → classified as “Banned”Manual action
16Account auto-banned from r/TheTopicOfTheDay + ALL participating subs where it had content in the past weekhandleClientPostOrComment.ts:handleContentCreation (retroactive)
17”Overview for hailybarnes37” post created on r/BotBouncerpostCreation.ts

Why Small-Location7862 survived sitewide but hailybarnes37 didn’t:

BotBouncer only bans at the subreddit level. The escalation to sitewide suspension is done by Reddit’s own systems (not BotBouncer). From the BotBouncer docs: “Bot accounts should be reported to Reddit as Spam → Disruptive use of bots or AI. Reddit’s spam detection is getting better all the time and in many cases, the bot’s account will be shadowbanned immediately.”

BotBouncer explicitly recommends that moderators also report the account to Reddit — this is the path to sitewide suspension. The difference between hailybarnes37 (sitewide banned) and Small-Location7862 (not sitewide banned) may simply be whether the reporting moderator also filed a Reddit spam report.


12. What We Can’t See (And Why It Matters)

The most critical detection logic is in the evaluator variables — the configuration that defines what patterns to look for. These are stored on private wiki pages on r/BotBouncer that we cannot read:

Hidden ConfigWhere It’s StoredWhat It Contains
generic:karmafarminglinksubsr/BotBouncer wiki (evaluator-config/evaluatorvars)List of subreddits BotBouncer proactively scans
generic:karmafarminglinksubsnsfwSame wikiNSFW karma-farming subs list
commentphrase:phrasesSame wikiRegex patterns for bot comment phrases
botgroupadvanced:*Same wikiBot group definitions (account criteria + history criteria)
biotext:bantextSame wikiRegex patterns for banned bio text
posttitle:bantextSame wikiRegex patterns for banned post titles
generic:sitewidebanneddomainsSame wikiDomains that trigger automatic evaluation

This means we don’t know:

  • Which subreddits are on the karma-farming list (but r/TheTopicOfTheDay clearly is, since that’s where our reports came from)
  • What comment phrases trigger the CommentPhrase evaluator
  • What bot groups are configured in BotGroupAdvanced
  • Whether our specific commenting patterns are explicitly targeted

What we DO know from behavior:

  • r/TheTopicOfTheDay is on the karma-farming list (our accounts were proactively scanned there)
  • NoStupidQuestions, AmItheAsshole, CasualConversation, Advice, TheTopicOfTheDay are likely all on the list (our accounts got banned from all of them simultaneously)
  • The “question-back” pattern was noticed by human moderators, which means it’s likely also in the CommentPhrase regex config

13. Implications for Avoiding Detection

Based on the actual source code, here’s what would and wouldn’t help:

What Would Help:

StrategyWhy It Works (from source code)Source Evidence
Build comment karma to 2000+ before farmingBioText and PostTitle evaluators skip accounts with >2000 comment + >2000 link karmaEvaluateBioText.ts:preEvaluateUser, EvaluatePostTitle.ts:preEvaluateUser
Build comment karma to 100+CommentPhrase evaluator skips accounts with ≥100 comment karma OR >60 days oldEvaluateCommentPhrase.ts:preEvaluateUser
Don’t comment on known karma-farming subsProactive scanning only covers subs on the karmafarminglinksubs listkarmaFarmingSubsCheck.ts:getDistinctAccounts
Vary timing between commentsUserSummary explicitly computes min/10th-percentile/max/average/median time between commentsuserSummary.ts:getCommonEntriesForContent
Edit some commentsUserSummary tracks edited post percentage; bots rarely edituserSummary.ts:getSummaryForUser
Have posts, not just commentsTitleCopyBot explicitly checks if (this.getPosts().length > 0) return false — having posts exempts youEvaluateTitleCopyBot.ts:evaluate
Don’t comment on the same post twiceBotGroupAdvanced can check hasMoreThanOneCommentOnPostsEvaluateBotGroupAdvanced.ts:evaluate
Match comment content to post contentOpenAI summary sends parent post title + comment body — AI can judge relevancegatherUserDetailsForOpenAI.ts:getUserInfoForOpenAI
Don’t use question-back patternsCommentPhrase can regex-match specific phrases; BotGroupAdvanced can match bodyRegex patternsEvaluateCommentPhrase.ts, EvaluateBotGroupAdvanced.ts
Be active for >14 days before posting on watched subsSuspiciousFirstPost evaluator skips accounts >14 days oldEvaluateSuspiciousFirstPost.ts:preEvaluateUser
Have >50 comment karma before posting on watched subsSuspiciousFirstPost and InconsistentAge skip accounts with ≥50 comment karmaEvaluateSuspiciousFirstPost.ts:preEvaluateUser, EvaluateInconsistentAgeBot.ts:preEvaluateUser

What Would NOT Help (Myth Busting):

StrategyWhy It Doesn’t WorkSource Evidence
Change IP addressBotBouncer does NOT check IP addresses at allNo IP checking in any evaluator
Change browser fingerprintBotBouncer does NOT check fingerprintsNo fingerprint checking in any evaluator
Use different proxiesBotBouncer does NOT check network infoNo network analysis in any evaluator
Deliberate typosBotBouncer doesn’t check spelling — it checks structural patterns via regex and OpenAIEvaluateCommentPhrase uses regex on phrases, not spelling
Post at “human-like” intervals onlyWhile timing IS analyzed, it’s in the summary for human review, not an automatic ban criterion (except via BotGroupAdvanced config)userSummary.ts computes timing for the summary, not for auto-ban

14. Source Code References

FileRepoKey Function
karmaFarmingSubsCheck.tsbot-bouncerProactive scanning of karma-farming subs
handleClientPostOrComment.tsbot-bouncerReal-time content detection on client subs
handleReportUser.tsbot-bouncerHuman moderator reporting flow
handleControlSubAccountEvaluation.tsbot-bouncerFull account evaluation on r/BotBouncer
handleContentCreation.tsbot-bouncerEvent router for content creation
handleControlSubComment.tsbot-bouncerComment handling on r/BotBouncer itself
handleControlSubSubmission.tsbot-bouncerPost/submission handling on r/BotBouncer
externalSubmissions.tsbot-bouncerExternal submission queue system
createAISummary.tsbot-bouncerOpenAI summary generation
gatherUserDetailsForOpenAI.tsbot-bouncerData collection for OpenAI
openAI.tsbot-bouncerOpenAI API wrapper (gpt-5.4-mini)
askAI.tsbot-bouncerModmail !askai command
userSummary.tsbot-bouncerDetailed user summary with timing analysis
settings.tsbot-bouncerApp settings, ban message, action types
constants.tsbot-bouncerJob names, flair IDs, evaluator imports
types.tsbot-bouncerUserStatus enum (pending/banned/service/organic/purged/retired/inactive)
evaluatorVariables.tsbot-bouncerWiki-based evaluator config system
allEvaluators.tsbot-bouncer-evaluationComplete evaluator list and order
UserEvaluatorBase.tsbot-bouncer-evaluationBase class for all evaluators
EvaluateBotGroupAdvanced.tsbot-bouncer-evaluationFlexible rule-based bot detection (54K chars)
EvaluateCommentPhrase.tsbot-bouncer-evaluationComment phrase regex matching
EvaluateWarmupBot.tsbot-bouncer-evaluationModerator warmup bot detection
EvaluateBioText.tsbot-bouncer-evaluationBio text pattern detection
EvaluateTitleCopyBot.tsbot-bouncer-evaluationTitle-copying bot detection
EvaluateSuspiciousFirstPost.tsbot-bouncer-evaluationFirst post suspicious pattern detection
EvaluateInconsistentAgeBot.tsbot-bouncer-evaluationInconsistent age in NSFW posts
EvaluateSocialLinks.tsbot-bouncer-evaluationSuspicious social link detection
EvaluatePostTitle.tsbot-bouncer-evaluationPost title pattern detection
changelog.mdbot-bouncerVersion history of detection additions