Inspiration
When Reddit's tooling transition deprecated Toolbox and RES for many subreddits, moderators lost basic capabilities like tracking repeat offenders. A sub with 10 removals per week translates to over 500 violations to track per year — by hand. OffenseLog automates that workflow and adds capabilities the old tools never had.
What it does
OffenseLog logs every moderator removal against the user in real time. When active violations cross configurable thresholds, it automatically escalates: warning DM → 14-day temp ban → permanent ban. Violations decay after 30 days (configurable) so a single bad day doesn't follow a user forever. Per-rule weighting lets mods say, "harassment counts triple" or "wrong flair doesn't count at all." A dry-run mode previews a week of behavior with zero enforcement so mods can tune thresholds before going live.
How I built it
Devvit (Reddit's developer platform) on a Hono server, Redis sorted sets for time-ordered violation records, TypeScript in strict mode throughout, Vitest for testing. The escalation pipeline uses an atomic Redis SET NX lock to prevent concurrent mod actions from double-escalating the same user. Per-rule scoring is split into pure functions (parseWhitelist, parseWeights, computeWeightedScore, computeNewTier) so the heart of the system is fully testable without mocking Devvit. A daily cron task handles violation decay.
Challenges I ran into
Devvit triggers fire removelink and addremovalreason as separate events, so the violation's rule field isn't known at the moment the tier is computed — required re-evaluating tier on the rule-attach event. Concurrent removals of the same user could double-escalate, solved with a SETNX claim key released in a try/finally. The Devvit modlog API field shapes vary between versions, so the backfill handler uses a defensive ModLogAction interface with all-optional fields. A subtle Windows-only bug: the lint script's single-quoted glob pattern works in bash but not in cmd.exe — fixed by switching to double quotes.
Accomplishments that I'm proud of
A complete moderation workflow that runs autonomously once configured — mods set thresholds and walk away. Dry-run mode that lets even cautious teams adopt the tool with zero risk: a full week of preview behavior with no DMs or bans actually sent. Per-rule weighting that handles the real-world reality that "harassment" and "wrong flair" shouldn't count the same — a capability Toolbox never had. A backfill flow that turns a brand-new install from "blind to the past week" to "fully aware of repeat offenders" in one click. And complete operator visibility through modmail notifications, an at-a-glance dashboard, and per-user history with permalinks back to the original removed content.
What I learned
Triggers are powerful but Devvit's modlog API surface is inconsistently typed across versions - defensive interfaces with optional fields are a must. Redis sorted sets are the right primitive for time-windowed counting (O(log N) range queries for the decay window). Testing pure functions buys far more confidence than testing route handlers with mocked Devvit context. And: a feature isn't done until you've considered the "2 AM on a busy sub" failure modes — race conditions, dry-run safety, modmail volume control, content-key cleanup on decay.
What's next for OffenseLog
A custom-post webview dashboard so top offenders are visible in the sub feed without opening a menu. Slack/Discord webhook integration for high-severity escalations. Per-modmail-level decay notifications. A sample-policy preset library ("small sub" / "medium sub" / "high-volume") so new installs can pick a starting config in one click. And first-class support for the Devvit modlog API once the field shape stabilizes — currently behind a defensive interface.
Built With
- devvit
- hono
- node.js
- redis
- typescript
- vite
- vitest
Log in or sign up for Devpost to join the conversation.