From 6748f87d591923be65df1b7601add85f2f6d20a6 Mon Sep 17 00:00:00 2001 From: Jon Bailey <297513015+Pitchfork-and-Torch@users.noreply.github.com> Date: Tue, 8 Sep 2026 19:09:02 -0400 Subject: [PATCH] Stop POSSIBLY_NSFW_ACCOUNT from requiring 11 matches in a window of 10. The default post-to-user rule asked for more matching posts than the window can hold, so the account label never applied. Clamp the required count to the window and set the default to 10 of 10. --- safety-label-user-agg/postToUserLabelRules.strato | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/safety-label-user-agg/postToUserLabelRules.strato b/safety-label-user-agg/postToUserLabelRules.strato index 59ed4bcc..f489fcb5 100644 --- a/safety-label-user-agg/postToUserLabelRules.strato +++ b/safety-label-user-agg/postToUserLabelRules.strato @@ -263,6 +263,14 @@ def matchesPostLabelSelector( hasConfiguredLabels && validAnyOf && validAllOf && matchesAnyOf && matchesAllOf } +def requiredMatchingPosts(condition: PostLabelCountCondition): Int = { + if (condition.windowSize > 0 && condition.minimumMatchingPosts > condition.windowSize) { + condition.windowSize + } else { + condition.minimumMatchingPosts + } +} + def matchesPostLabelCount( condition: PostLabelCountCondition, posts: Seq[PostLabelData] @@ -273,14 +281,14 @@ def matchesPostLabelCount( posts } condition.windowSize > 0 && - condition.minimumMatchingPosts > 0 && + requiredMatchingPosts(condition) > 0 && windowPosts .take(condition.windowSize) .filter { post => isRecentPost(post.tweetId, condition.maxPostAgeDays) && matchesPostLabelSelector(post.labels, condition.postLabels) } - .size >= condition.minimumMatchingPosts + .size >= requiredMatchingPosts(condition) } def matchesRule(rule: UserLabelRule, posts: Seq[PostLabelData]): Boolean = { @@ -371,7 +379,7 @@ val defaultRulesJson = "allOf": [ { "windowSize": 10, - "minimumMatchingPosts": 11, + "minimumMatchingPosts": 10, "maxPostAgeDays": 60, "mediaOnly": false, "postLabels": { @@ -440,6 +448,7 @@ val export = { needsMediaLookup = needsMediaLookup, matchingOutputs = matchingOutputs, validRules = validRules, + requiredMatchingPosts = requiredMatchingPosts, evaluateForTest = evaluateForTest, maxScanSizeForTest = maxScanSizeForTest, defaultRulesJson = defaultRulesJson,