MODERATION_MVP_SPEC.md (5892B)
1 # Bzl Moderation MVP Spec 2 3 ## Purpose 4 Define the minimum moderation system required for Bzl to run safely in small private communities, with clear enforcement and a permanent moderation log. 5 6 ## Scope 7 In scope: 8 - Role-based moderation permissions 9 - Report workflow for posts and chat messages 10 - Moderator actions on content and users 11 - Immutable moderation log in backend and UI 12 - Real-time moderation updates over WebSocket 13 14 Out of scope (later): 15 - Appeals workflow 16 - Automated moderation AI 17 - Cross-server federation moderation 18 19 ## Roles 20 - `owner`: full permissions, can assign/remove moderators, can ban moderators. 21 - `moderator`: can moderate content/users, cannot demote owner. 22 - `member`: default user role. 23 24 Single-owner model for MVP: 25 - First account created becomes `owner`. 26 - Owner can promote/demote users to/from `moderator`. 27 28 ## Permission Matrix 29 - `member` 30 - Create report 31 - View own report submissions 32 - `moderator` 33 - All member permissions 34 - View open/resolved reports 35 - Delete post 36 - Delete chat message 37 - Purge recent messages in a post chat 38 - Mute user (time-based) 39 - Suspend user (time-based) 40 - Ban/unban user 41 - Lock/unlock post (optional visibility control) 42 - `owner` 43 - All moderator permissions 44 - Assign/remove moderator role 45 - Override and reverse any moderation action 46 47 ## Moderation Actions (MVP) 48 Every action below requires `reason` and creates one immutable log entry. 49 50 Content actions: 51 - `post_delete` (hard remove post + chat) 52 - `post_lock` / `post_unlock` 53 - `message_delete` 54 - `message_purge_recent` (count + window, ex: last 50 in 30m) 55 56 User actions: 57 - `user_mute` (`mutedUntil`) 58 - `user_unmute` 59 - `user_suspend` (`suspendedUntil`) 60 - `user_unsuspend` 61 - `user_ban` (`banned = true`) 62 - `user_unban` 63 - `user_role_set` (owner only) 64 65 Report actions: 66 - `report_resolve` (valid report) 67 - `report_dismiss` (invalid report) 68 69 ## Behavioral Rules 70 - Muted user: cannot send chat; can still read. 71 - Suspended user: cannot post/chat/react/boost; can still sign in and read. 72 - Banned user: cannot sign in. 73 - Existing session revocation: 74 - If user becomes suspended or banned, server pushes immediate auth state update and blocks new actions. 75 - Protected posts: 76 - Moderators bypass post password access checks. 77 78 ## Data Model Additions 79 All persisted to disk with existing persistence strategy. 80 81 ### `users` additions 82 - `role: "owner" | "moderator" | "member"` 83 - `mutedUntil: number` (epoch ms, `0` for none) 84 - `suspendedUntil: number` (epoch ms, `0` for none) 85 - `banned: boolean` 86 87 ### `reports` collection 88 - `id: string` 89 - `targetType: "post" | "chat"` 90 - `targetId: string` 91 - `postId: string` (required for chat target) 92 - `reporter: string` 93 - `reason: string` 94 - `status: "open" | "resolved" | "dismissed"` 95 - `resolutionNote: string` 96 - `createdAt: number` 97 - `resolvedAt: number` 98 - `resolvedBy: string` 99 100 ### `modActions` collection (immutable) 101 - `id: string` 102 - `actionType: string` 103 - `actor: string` 104 - `targetType: "user" | "post" | "chat" | "report" | "system"` 105 - `targetId: string` 106 - `reason: string` 107 - `metadata: object` 108 - `createdAt: number` 109 110 Retention: 111 - Keep all log entries for MVP. 112 - Optional cap by count can be added later only with archival export. 113 114 ## WebSocket Protocol Additions 115 ### Client -> Server 116 - `reportCreate` 117 - `{ type, targetType, targetId, postId?, reason }` 118 - `modAction` 119 - `{ type, actionType, targetType, targetId, reason, metadata? }` 120 - `modListReports` 121 - `{ type, status?, limit?, cursor? }` 122 - `modListLog` 123 - `{ type, filters?, limit?, cursor? }` 124 - `modListUsers` 125 - `{ type, query?, limit?, cursor? }` 126 127 ### Server -> Client 128 - `reportCreated` 129 - `{ type, report }` 130 - `reportUpdated` 131 - `{ type, report }` 132 - `modActionApplied` 133 - `{ type, action, effects }` 134 - `modLogAppended` 135 - `{ type, entry }` 136 - `modSnapshot` 137 - `{ type, reports, users, log, cursor }` 138 - `permissionDenied` 139 - `{ type, message }` 140 141 ## Server Enforcement Points 142 Add a centralized guard: 143 - `requireRole(ws, minRole)` helper. 144 145 Add status guards on write actions: 146 - block `chatMessage` if muted/suspended/banned. 147 - block `newPost`, `boostPost`, `react` if suspended/banned. 148 - block `login` if banned. 149 150 Moderation bypass: 151 - in protected post checks, allow if role is `moderator` or `owner`. 152 153 Audit-first rule: 154 - do not execute moderation action unless log write succeeds. 155 156 ## Mod Panel UX (MVP) 157 Add a moderator panel visible only to `moderator`/`owner` with tabs: 158 159 1. `Reports` 160 - List open reports first. 161 - Quick actions: resolve + apply moderation action, dismiss. 162 163 2. `Users` 164 - Search users. 165 - Actions: mute/suspend/ban/unban, role set (owner only). 166 - Show current status badges. 167 168 3. `Hives` 169 - Quick post and chat moderation actions. 170 171 4. `Log` 172 - Chronological immutable list. 173 - Filters: action type, actor, target, date window. 174 - Clicking entry shows structured metadata. 175 176 ## Validation and Limits 177 - `reason` min 8 chars, max 280 chars. 178 - `report reason` min 8 chars, max 500 chars. 179 - Rate limits: 180 - report creation per user 181 - moderation actions per moderator per minute 182 - Reject duplicate open reports from same user on same target in short window. 183 184 ## Security Considerations 185 - Never trust client role claims; role loaded server-side from user store. 186 - Include actor + timestamp from server only. 187 - Log entries are append-only. 188 - Hide sensitive fields from non-moderators. 189 190 ## Rollout Plan 191 1. Backend schemas + guards + log write path. 192 2. Report creation UI. 193 3. Moderator panel (`Reports`, `Users`, `Hives`). 194 4. Log tab and filtering. 195 5. End-to-end testing with at least 3 roles. 196 197 ## Acceptance Criteria 198 - Members can report posts/messages. 199 - Moderators can action reports and moderate users/content. 200 - Every moderation action appears in log with actor/reason/time. 201 - Banned users cannot log in. 202 - Muted users cannot chat. 203 - Suspended users cannot post/chat/react/boost. 204 - Mod panel updates in real time for concurrent moderators.