bzl

self-hosted ephemeral community engine
Log | Files | Refs | README | LICENSE

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.