A tool for parsing traffic on the jetstream and applying a moderation workstream based on regexp based rules

feat: Add example rule configurations

- Added example configuration files for account age, account threshold,
global constants, handles, posts, and profiles. - Updated the CI build
to copy the example configuration files. - Removed the now redundant
rules/README.md. - Updated .gitignore to exclude all rules.

Skywatch dc8112f6 15ba5a78

+6
.github/workflows/ci.yml
··· 27 27 cp src/rules/handles/constants.example.ts src/rules/handles/constants.ts 28 28 cp src/rules/posts/constants.example.ts src/rules/posts/constants.ts 29 29 cp src/rules/profiles/constants.example.ts src/rules/profiles/constants.ts 30 + cp rules/constants.example.ts rules/constants.ts 31 + cp rules/handles.example.ts rules/handles.ts 32 + cp rules/posts.example.ts rules/posts.ts 33 + cp rules/profiles.example.ts rules/profiles.ts 34 + cp rules/accountAge.example.ts rules/accountAge.ts 35 + cp rules/accountThreshold.example.ts rules/accountThreshold.ts 30 36 31 37 - name: Run linter 32 38 run: bun run lint
-1
.gitignore
··· 7 7 src/constants.ts 8 8 constants.ts 9 9 coverage/ 10 - rules/*.ts
-42
rules/README.md
··· 1 - # Example Rules Configuration 2 - 3 - This directory contains example rule configurations for the moderation system. 4 - 5 - ## Setup 6 - 7 - 1. Copy this entire directory to create your production rules: 8 - ```bash 9 - cp -r rules.example rules 10 - ``` 11 - 12 - 2. Edit the files in `rules/` to configure your moderation rules: 13 - - `accountAge.ts` - Rules for flagging accounts based on age 14 - - `accountThreshold.ts` - Rules for flagging accounts that exceed thresholds 15 - - `handles.ts` - Pattern matching rules for handles/usernames 16 - - `posts.ts` - Pattern matching rules for post content 17 - - `profiles.ts` - Pattern matching rules for profile descriptions 18 - - `constants.ts` - Global allow lists and shared constants 19 - 20 - 3. The `rules/` directory is ignored by git to keep your moderation rules confidential. 21 - 22 - ## Rule Structure 23 - 24 - Each rule type has a specific structure. See the example files for details on required fields and options. 25 - 26 - ### Common Fields 27 - 28 - - `label` - The label to apply when the rule matches 29 - - `comment` - Internal comment/reason for the action 30 - - `reportAcct/reportPost` - Whether to create a report 31 - - `commentAcct/commentPost` - Whether to add a comment 32 - - `toLabel` - Whether to apply a label 33 - - `check` - The pattern/condition to match against 34 - 35 - ### Optional Fields 36 - 37 - - `whitelist` - Patterns that should override the main check (false positives) 38 - - `ignoredDIDs` - DIDs exempt from this specific rule 39 - 40 - ## Security 41 - 42 - Never commit the `rules/` directory to version control. Keep your moderation rules confidential.
+17
rules/accountAge.example.ts
··· 1 + import type { AccountAgeCheck } from "../src/types.js"; 2 + 3 + /** 4 + * Account age monitoring configurations 5 + * 6 + * This file contains example values. Copy to accountAge.ts and configure with your checks. 7 + */ 8 + export const ACCOUNT_AGE_CHECKS: AccountAgeCheck[] = [ 9 + // Example configuration: 10 + // { 11 + // monitoredDIDs: ["did:plc:example123"], 12 + // anchorDate: "2025-01-15", 13 + // maxAgeDays: 7, 14 + // label: "new-account", 15 + // comment: "Account created within monitored window", 16 + // }, 17 + ];
+20
rules/accountThreshold.example.ts
··· 1 + import type { AccountThresholdConfig } from "../src/types.js"; 2 + 3 + /** 4 + * Account threshold configurations for automatic labeling 5 + * 6 + * This file contains example values. Copy to accountThreshold.ts and configure with your thresholds. 7 + */ 8 + export const ACCOUNT_THRESHOLD_CONFIGS: AccountThresholdConfig[] = [ 9 + // Example configuration: 10 + // { 11 + // labels: ["example-label"], 12 + // threshold: 3, 13 + // accountLabel: "repeat-offender", 14 + // accountComment: "Account exceeded threshold", 15 + // windowDays: 7, 16 + // reportAcct: false, 17 + // commentAcct: false, 18 + // toLabel: true, 19 + // }, 20 + ];
+8
rules/constants.example.ts
··· 1 + /** 2 + * Global allowlist for accounts that should bypass all checks 3 + * 4 + * This file contains example values. Copy to constants.ts and configure with your DIDs. 5 + */ 6 + export const GLOBAL_ALLOW: string[] = [ 7 + // Example: "did:plc:example123", 8 + ];
+18
rules/handles.example.ts
··· 1 + import type { Checks } from "../src/types.js"; 2 + 3 + /** 4 + * Handle-based moderation checks 5 + * 6 + * This file contains example values. Copy to handles.ts and configure with your checks. 7 + */ 8 + export const HANDLE_CHECKS: Checks[] = [ 9 + // Example check: 10 + // { 11 + // label: "example-label", 12 + // comment: "Example check found in handle", 13 + // reportAcct: false, 14 + // commentAcct: false, 15 + // toLabel: true, 16 + // check: new RegExp("example-pattern", "i"), 17 + // }, 18 + ];
+23
rules/posts.example.ts
··· 1 + import type { Checks } from "../src/types.js"; 2 + 3 + /** 4 + * Post content moderation checks 5 + * 6 + * This file contains example values. Copy to posts.ts and configure with your checks. 7 + */ 8 + export const POST_CHECKS: Checks[] = [ 9 + // Example check: 10 + // { 11 + // label: "example-label", 12 + // comment: "Example content found in post", 13 + // reportAcct: false, 14 + // commentAcct: false, 15 + // toLabel: true, 16 + // check: new RegExp("example-pattern", "i"), 17 + // }, 18 + ]; 19 + 20 + /** 21 + * Link shortener detection pattern 22 + */ 23 + export const LINK_SHORTENER = new RegExp("", "i");
+20
rules/profiles.example.ts
··· 1 + import type { Checks } from "../src/types.js"; 2 + 3 + /** 4 + * Profile-based moderation checks 5 + * 6 + * This file contains example values. Copy to profiles.ts and configure with your checks. 7 + */ 8 + export const PROFILE_CHECKS: Checks[] = [ 9 + // Example check: 10 + // { 11 + // label: "example-label", 12 + // comment: "Example content found in profile", 13 + // description: true, 14 + // displayName: true, 15 + // reportAcct: false, 16 + // commentAcct: false, 17 + // toLabel: true, 18 + // check: new RegExp("example-pattern", "i"), 19 + // }, 20 + ];