diff --git a/internal/atproto/lexicon/social/coves/community/rules.json b/internal/atproto/lexicon/social/coves/community/rules.json --- a/internal/atproto/lexicon/social/coves/community/rules.json +++ b/internal/atproto/lexicon/social/coves/community/rules.json @@ -47,10 +47,10 @@ "type": "string", "format": "did" } }, - "sortitionConfig": { - "type": "ref", - "ref": "#sortitionConfig", - "description": "Configuration for sortition-based moderation" + "moderationConfig": { + "type": "union", + "refs": ["#moderatorModeration", "#sortitionModeration"], + "description": "Configuration for community moderation" } } } @@ -78,6 +78,11 @@ "allowArticle": { "type": "boolean", "default": true, "description": "Allow Article posts" + }, + "allowMicroblog": { + "type": "boolean", + "default": true, + "description": "Allow microblog posts (federated short-form content)" } } }, @@ -126,25 +131,78 @@ } } } }, - "sortitionConfig": { + "moderatorModeration": { "type": "object", - "description": "Configuration for sortition-based moderation", + "description": "Moderation configuration for moderator-based communities", + "required": ["$type"], "properties": { - "tagThreshold": { + "$type": { + "type": "string", + "description": "Discriminator for moderator-based moderation" + }, + "negativeTags": { + "type": "array", + "description": "Default tags that count as negative", + "default": ["spam", "hostile", "offtopic", "misleading"], + "items": { + "type": "string" + } + }, + "customNegativeTags": { + "type": "array", + "description": "Community-specific tags that count as negative", + "items": { + "type": "string" + } + }, + "hideThreshold": { "type": "integer", - "minimum": 10, + "minimum": 5, "default": 15, - "description": "Number of tags needed to trigger action" + "description": "Number of negative tags needed to hide content" + } + } + }, + "sortitionModeration": { + "type": "object", + "description": "Moderation configuration for sortition-based communities", + "required": ["$type"], + "properties": { + "$type": { + "type": "string", + "description": "Discriminator for sortition-based moderation" + }, + "negativeTags": { + "type": "array", + "description": "Default tags that count as negative", + "default": ["spam", "hostile", "offtopic", "misleading"], + "items": { + "type": "string" + } + }, + "customNegativeTags": { + "type": "array", + "description": "Community-specific tags that count as negative", + "items": { + "type": "string" + } + }, + "hideThreshold": { + "type": "integer", + "minimum": 5, + "default": 15, + "description": "Number of negative tags needed to hide content" }, "tribunalThreshold": { "type": "integer", "minimum": 10, "default": 30, - "description": "Number of tags to trigger tribunal review" + "description": "Number of negative tags to trigger tribunal review" }, "jurySize": { "type": "integer", - "minimum": 9, + "minimum": 5, + "maximum": 21, "default": 9, "description": "Number of jurors for tribunal" } diff --git a/tests/lexicon-test-data/community/rules-invalid-moderation.json b/tests/lexicon-test-data/community/rules-invalid-moderation.json new file mode 100644 --- /dev/null +++ b/tests/lexicon-test-data/community/rules-invalid-moderation.json @@ -0,0 +1,9 @@ +{ + "$type": "social.coves.community.rules", + "moderationConfig": { + "negativeTags": ["spam", "hostile"], + "hideThreshold": 3, + "tribunalThreshold": 30, + "jurySize": 9 + } +} \ No newline at end of file diff --git a/tests/lexicon-test-data/community/rules-invalid-sortition.json b/tests/lexicon-test-data/community/rules-invalid-sortition.json deleted file mode 100644 --- a/tests/lexicon-test-data/community/rules-invalid-sortition.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$type": "social.coves.community.rules", - "sortitionConfig": { - "tagThreshold": 5, - "tribunalThreshold": 30, - "jurySize": 9 - } -} \ No newline at end of file diff --git a/tests/lexicon-test-data/community/rules-valid-moderator.json b/tests/lexicon-test-data/community/rules-valid-moderator.json new file mode 100644 --- /dev/null +++ b/tests/lexicon-test-data/community/rules-valid-moderator.json @@ -0,0 +1,17 @@ +{ + "$type": "social.coves.community.rules", + "postTypes": { + "allowText": true, + "allowVideo": false, + "allowImage": true, + "allowArticle": true, + "allowMicroblog": false + }, + "customTags": ["announcement", "pinned"], + "moderationConfig": { + "$type": "social.coves.community.rules#moderatorModeration", + "negativeTags": ["spam", "hostile", "offtopic", "misleading"], + "customNegativeTags": ["loweffort"], + "hideThreshold": 20 + } +} \ No newline at end of file diff --git a/tests/lexicon-test-data/community/rules-valid.json b/tests/lexicon-test-data/community/rules-valid.json --- a/tests/lexicon-test-data/community/rules-valid.json +++ b/tests/lexicon-test-data/community/rules-valid.json @@ -4,7 +4,8 @@ "postTypes": { "allowText": true, "allowVideo": true, "allowImage": true, - "allowArticle": true + "allowArticle": true, + "allowMicroblog": true }, "contentRestrictions": { "blockedDomains": ["spam.com", "malware.com"], @@ -36,8 +37,11 @@ "createdAt": "2024-01-01T00:00:00Z", "isActive": true } ], - "sortitionConfig": { - "tagThreshold": 15, + "moderationConfig": { + "$type": "social.coves.community.rules#sortitionModeration", + "negativeTags": ["spam", "hostile", "offtopic", "misleading"], + "customNegativeTags": ["lowquality", "duplicate"], + "hideThreshold": 15, "tribunalThreshold": 30, "jurySize": 9 }