From e2d05a414b9b20c52a716c50114f5f5a8c0f3acc Mon Sep 17 00:00:00 2001 From: Applekid Date: Tue, 10 Feb 2026 13:19:32 -0800 Subject: [PATCH 1/4] Add Purge feature specification and summary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Comprehensive spec for automated message cleanup feature - Progressive 3-phase rollout: notify โ†’ manual โ†’ auto-delete - Per-channel retention policies (configurable days) - Scheduled checks with mod notifications - Commands: /mod purge view/set/execute/disable - Safety features: confirmation prompts, audit log, rate limiting - Database schema for config and history - Discord API considerations (bulk delete, rate limits) - Testing plan and future enhancements --- docs/PurgeFeatureSpec.md | 323 ++++++++++++++++++++++++++++++++++++ docs/PurgeFeatureSummary.md | 150 +++++++++++++++++ 2 files changed, 473 insertions(+) create mode 100644 docs/PurgeFeatureSpec.md create mode 100644 docs/PurgeFeatureSummary.md diff --git a/docs/PurgeFeatureSpec.md b/docs/PurgeFeatureSpec.md new file mode 100644 index 0000000..e4239bf --- /dev/null +++ b/docs/PurgeFeatureSpec.md @@ -0,0 +1,323 @@ +# Purge Feature Specification + +## Overview + +The Purge feature enables moderators to configure automated message cleanup policies for individual channels. Messages older than a configurable timeframe are identified, and moderators can be notified or have them automatically deleted based on progressive rollout phases. + +## Goals + +1. **Channel-specific retention policies**: Configure different message retention windows for each channel +2. **Automated monitoring**: Scheduled checks identify channels with messages past retention threshold +3. **Progressive rollout**: Start with notifications, progress to manual execution, then auto-deletion +4. **Safety first**: Multiple phases ensure deletion mechanics work as expected before automation + +## Phases + +### Phase 1: Notification Only (Initial Deployment) +- Scheduled checks identify channels with messages exceeding retention window +- Bot posts notifications to mod-comms channel +- No deletion occurs โ€” purely informational + +### Phase 2: Manual Execution +- Moderators can trigger purge via `/mod purge execute` command +- Provides hands-on experience with deletion mechanics +- Allows verification that correct messages are targeted + +### Phase 3: Auto-Delete +- Moderators can enable auto-delete per channel via `autodelete:true` flag +- Bot automatically deletes qualifying messages on schedule +- Posts summary to mod-comms after each purge + +## Commands + +### `/mod purge view` +View current purge configuration for all channels. + +**Output:** +``` +๐Ÿ“‹ Purge Configuration: + +#general - 30 days, auto-delete: disabled +#announcements - 90 days, auto-delete: disabled +#off-topic - 7 days, auto-delete: enabled +``` + +### `/mod purge set channel:<#channel> days: [autodelete:]` +Configure purge settings for a channel. + +**Parameters:** +- `channel` (required): Channel to configure (mention) +- `days` (required): Retention window in days (1-365) +- `autodelete` (optional): Enable/disable auto-deletion (default: false) + +**Examples:** +``` +/mod purge set channel:#general days:30 +/mod purge set channel:#off-topic days:7 autodelete:true +``` + +**Validation:** +- Channel must exist and be accessible by bot +- Days must be between 1 and 365 +- Auto-delete only allowed if Phase 3 is enabled (env var) + +### `/mod purge execute channel:<#channel>` +Manually trigger purge for a specific channel. + +**Parameters:** +- `channel` (required): Channel to purge (mention) + +**Behavior:** +- Only available in Phase 2+ +- Deletes messages older than configured retention window +- Posts summary to mod-comms +- Requires confirmation (button interaction) + +**Example:** +``` +/mod purge execute channel:#general + +โš ๏ธ Purge Confirmation +Channel: #general +Retention: 30 days +Estimated messages: 1,247 +Are you sure? [Confirm] [Cancel] +``` + +### `/mod purge disable channel:<#channel>` +Disable purge for a specific channel. + +**Parameters:** +- `channel` (required): Channel to disable (mention) + +**Example:** +``` +/mod purge disable channel:#important +``` + +## Scheduled Checks + +### Cadence Configuration +Set via environment variable: +``` +PURGE_SCHEDULE_CRON="0 9 * * 0" # Every Sunday at 9 AM UTC +``` + +Default: Every Sunday at 9 AM UTC + +### Check Process +1. Bot iterates through all channels with configured retention windows +2. For each channel: + - Fetch messages older than retention window + - Count qualifying messages + - If count > 0: + - **Phase 1**: Post notification to mod-comms + - **Phase 2**: Same as Phase 1 (manual execution only) + - **Phase 3**: If `autodelete:true`, delete messages and post summary; else notify + +### Notification Format (Phase 1 & 2) +``` +๐Ÿงน Purge Alert + +Channel: #general +Retention: 30 days +Messages past threshold: 1,247 +Oldest message: 2025-11-10 14:32 UTC + +Use `/mod purge execute channel:#general` to purge manually. +``` + +### Auto-Delete Summary (Phase 3) +``` +โœ… Auto-Purge Complete + +Channel: #general +Retention: 30 days +Messages deleted: 1,247 +Oldest remaining: 2025-12-10 09:15 UTC +Next check: 2026-01-19 09:00 UTC +``` + +## Data Storage + +### Channel Configuration +Store per-channel settings in database (SQLite for simplicity): + +**Table: `purge_config`** +```sql +CREATE TABLE purge_config ( + channel_id TEXT PRIMARY KEY, + retention_days INTEGER NOT NULL, + autodelete_enabled BOOLEAN DEFAULT FALSE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` + +### Purge History +Track purge executions for audit trail: + +**Table: `purge_history`** +```sql +CREATE TABLE purge_history ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + channel_id TEXT NOT NULL, + executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + messages_deleted INTEGER NOT NULL, + trigger_type TEXT NOT NULL, -- 'manual', 'auto', 'scheduled_check' + triggered_by TEXT, -- user_id for manual, 'system' for auto + oldest_deleted TIMESTAMP, + newest_deleted TIMESTAMP +); +``` + +## Environment Variables + +```bash +# Purge feature configuration +PURGE_SCHEDULE_CRON="0 9 * * 0" # Cron schedule for checks (default: Sundays 9 AM UTC) +PURGE_PHASE="1" # Deployment phase (1, 2, or 3) +PURGE_MOD_CHANNEL_ID="123456789" # Channel ID for purge notifications +PURGE_BATCH_SIZE="100" # Messages to delete per batch (Discord rate limit: 100/bulk) +PURGE_BATCH_DELAY_MS="1000" # Delay between batches (rate limit safety) +``` + +## Discord API Considerations + +### Rate Limits +- **Bulk delete**: Max 100 messages per call +- **Bulk delete age limit**: Messages must be < 14 days old +- For messages > 14 days: Use individual delete (1 message per call, 5/sec rate limit) + +### Message Fetching +- Fetch in batches of 100 using `before` parameter +- Discord returns messages newest โ†’ oldest +- Stop when reaching retention threshold + +### Permissions Required +- `MANAGE_MESSAGES` - Required for bulk delete +- `READ_MESSAGE_HISTORY` - Required to fetch old messages +- `VIEW_CHANNEL` - Required to access channel + +## Implementation Notes + +### Phase Rollout Strategy +1. **Phase 1**: Deploy with `PURGE_PHASE=1` + - Monitor notifications for 2-4 weeks + - Verify message counts are accurate + - Confirm no false positives + +2. **Phase 2**: Update to `PURGE_PHASE=2` + - Moderators manually test `/mod purge execute` + - Verify deletion only affects correct messages + - Run for 2-4 weeks with spot checks + +3. **Phase 3**: Update to `PURGE_PHASE=3` + - Enable auto-delete for low-risk channels first (e.g., #off-topic) + - Monitor for 1-2 weeks + - Gradually enable for more channels + +### Deletion Logic +``` +For each message: + message_age = now - message.timestamp + if message_age > retention_days: + if message.timestamp < 14_days_ago: + delete_individual(message) # Slow path + else: + add_to_bulk_batch(message) # Fast path + if batch.size >= PURGE_BATCH_SIZE: + bulk_delete(batch) + sleep(PURGE_BATCH_DELAY_MS) +``` + +### Error Handling +- If deletion fails (permissions, rate limit), log error and skip +- Post error summary to mod-comms +- Continue with remaining messages (don't abort entire purge) + +### Safety Guards +- **Dry-run mode**: Optional flag to simulate deletion without executing +- **Max messages per purge**: Configurable limit (default: 10,000) +- **Confirmation prompts**: Required for manual execution +- **Audit log**: All purges logged with trigger type, user, timestamp + +## User Stories + +### Story 1: Configure Channel Retention +**As a moderator**, I want to set a 30-day retention policy for #general so that old messages are automatically cleaned up. + +**Steps:** +1. Moderator: `/mod purge set channel:#general days:30` +2. Bot: "โœ… Purge configured for #general: 30 days retention, auto-delete disabled" + +### Story 2: Receive Purge Notification (Phase 1) +**As a moderator**, I want to be notified when #general has messages older than 30 days so I can review before deletion. + +**Steps:** +1. Scheduled check runs on Sunday 9 AM +2. Bot finds 1,247 messages > 30 days old in #general +3. Bot posts notification to mod-comms with count and oldest message timestamp + +### Story 3: Manual Purge (Phase 2) +**As a moderator**, I want to manually purge #off-topic after reviewing the notification. + +**Steps:** +1. Moderator: `/mod purge execute channel:#off-topic` +2. Bot: Shows confirmation prompt with estimated message count +3. Moderator: Clicks [Confirm] +4. Bot: Deletes messages, posts summary to mod-comms + +### Story 4: Auto-Delete (Phase 3) +**As a moderator**, I want #off-topic to auto-delete messages older than 7 days so I don't have to manually purge. + +**Steps:** +1. Moderator: `/mod purge set channel:#off-topic days:7 autodelete:true` +2. Bot: "โœ… Purge configured for #off-topic: 7 days retention, auto-delete enabled" +3. Next scheduled check: Bot auto-deletes qualifying messages, posts summary + +## Testing Plan + +### Unit Tests +- Retention window calculation +- Message age filtering +- Batch deletion logic +- Configuration validation + +### Integration Tests +- Database CRUD operations +- Discord API interactions (mocked) +- Scheduled job execution + +### Manual Testing Checklist +- [ ] Configure retention for test channel +- [ ] Verify notification accuracy in Phase 1 +- [ ] Test manual execution in Phase 2 +- [ ] Verify only correct messages deleted +- [ ] Test auto-delete in Phase 3 +- [ ] Verify error handling (missing permissions, rate limits) +- [ ] Test bulk delete vs individual delete paths +- [ ] Verify audit log completeness + +## Future Enhancements + +1. **Whitelist users**: Exclude messages from specific users (e.g., bot announcements) +2. **Pinned message exemption**: Never delete pinned messages +3. **Reaction-based protection**: Messages with specific reactions are preserved +4. **Per-role visibility**: Different retention windows based on who can see the channel +5. **Export before delete**: Archive messages to S3/disk before deletion +6. **Dashboard**: Web UI to view/configure purge settings + +## Open Questions + +1. Should pinned messages be exempt by default? +2. Should we require a minimum retention window (e.g., 7 days)? +3. Should purge history be retained indefinitely or expire? +4. Should we support regex patterns for message content filtering? +5. Should we allow per-user exemptions via command or config file? + +## References + +- [Discord Bulk Delete API](https://discord.com/developers/docs/resources/channel#bulk-delete-messages) +- [Discord Rate Limits](https://discord.com/developers/docs/topics/rate-limits) +- [Node-cron scheduling](https://www.npmjs.com/package/node-cron) diff --git a/docs/PurgeFeatureSummary.md b/docs/PurgeFeatureSummary.md new file mode 100644 index 0000000..7f186fb --- /dev/null +++ b/docs/PurgeFeatureSummary.md @@ -0,0 +1,150 @@ +# Purge Feature Summary + +**TL;DR**: Automated message cleanup for Discord channels with configurable retention policies and progressive rollout (notify โ†’ manual โ†’ auto-delete). + +## What It Does + +- Configure per-channel message retention windows (e.g., "delete messages older than 30 days") +- Scheduled checks identify channels with messages past threshold +- Phase 1: Notify mods +- Phase 2: Allow manual purge +- Phase 3: Auto-delete with mod notifications + +## Key Commands + +``` +/mod purge view # View all channel configs +/mod purge set channel:#general days:30 # Set 30-day retention +/mod purge set channel:#off-topic days:7 autodelete:true # Enable auto-delete +/mod purge execute channel:#general # Manual purge (Phase 2+) +/mod purge disable channel:#important # Disable purge +``` + +## Rollout Phases + +### Phase 1: Notification Only โœ… (Start here) +- Bot checks channels on schedule (e.g., every Sunday) +- Posts notifications to mod-comms about messages past threshold +- **No deletion occurs** +- Run for 2-4 weeks to verify accuracy + +### Phase 2: Manual Execution +- Enable `/mod purge execute` command +- Mods can manually trigger purge after reviewing notifications +- Verify deletion mechanics work as expected +- Run for 2-4 weeks with spot checks + +### Phase 3: Auto-Delete +- Enable `autodelete:true` flag per channel +- Bot automatically deletes qualifying messages on schedule +- Posts summary to mod-comms after each purge +- Start with low-risk channels (#off-topic), expand gradually + +## Configuration Example + +```bash +# Environment variables +PURGE_SCHEDULE_CRON="0 9 * * 0" # Every Sunday 9 AM UTC +PURGE_PHASE="1" # Start with Phase 1 +PURGE_MOD_CHANNEL_ID="123456789" # Where to post notifications +``` + +## Safety Features + +- **Progressive rollout**: Three phases ensure safe deployment +- **Confirmation prompts**: Required for manual execution +- **Audit log**: All purges tracked with timestamp, user, count +- **Rate limit handling**: Respects Discord API limits +- **Error recovery**: Continues on failure, posts error summary + +## Database Schema + +```sql +-- Channel retention policies +CREATE TABLE purge_config ( + channel_id TEXT PRIMARY KEY, + retention_days INTEGER NOT NULL, + autodelete_enabled BOOLEAN DEFAULT FALSE +); + +-- Audit trail +CREATE TABLE purge_history ( + id INTEGER PRIMARY KEY, + channel_id TEXT, + executed_at TIMESTAMP, + messages_deleted INTEGER, + trigger_type TEXT, -- 'manual', 'auto', 'scheduled_check' + triggered_by TEXT +); +``` + +## Discord Permissions Required + +- `MANAGE_MESSAGES` - Delete messages +- `READ_MESSAGE_HISTORY` - Fetch old messages +- `VIEW_CHANNEL` - Access channels + +## Discord API Limits + +- **Bulk delete**: Max 100 messages, must be < 14 days old +- **Individual delete**: 5 messages/second for messages > 14 days old +- Purge uses bulk delete when possible, falls back to individual delete for older messages + +## Example Notification (Phase 1) + +``` +๐Ÿงน Purge Alert + +Channel: #general +Retention: 30 days +Messages past threshold: 1,247 +Oldest message: 2025-11-10 14:32 UTC + +Use `/mod purge execute channel:#general` to purge manually. +``` + +## Example Summary (Phase 3) + +``` +โœ… Auto-Purge Complete + +Channel: #general +Retention: 30 days +Messages deleted: 1,247 +Oldest remaining: 2025-12-10 09:15 UTC +Next check: 2026-01-19 09:00 UTC +``` + +## Quick Start (Phase 1 Deployment) + +1. Set environment variables: + ```bash + PURGE_SCHEDULE_CRON="0 9 * * 0" + PURGE_PHASE="1" + PURGE_MOD_CHANNEL_ID="your-mod-channel-id" + ``` + +2. Configure a test channel: + ``` + /mod purge set channel:#test-channel days:30 + ``` + +3. Wait for next scheduled check (or trigger manually for testing) + +4. Verify notification appears in mod-comms with accurate message count + +5. Monitor for 2-4 weeks, then proceed to Phase 2 + +## Future Enhancements + +- Whitelist specific users (preserve bot announcements) +- Exempt pinned messages +- Reaction-based protection (keep messages with specific reactions) +- Export messages before deletion (archive to S3/disk) +- Web dashboard for configuration + +## References + +- Full spec: [PurgeFeatureSpec.md](./PurgeFeatureSpec.md) +- Discord Bulk Delete API: https://discord.com/developers/docs/resources/channel#bulk-delete-messages +- Discord Rate Limits: https://discord.com/developers/docs/topics/rate-limits From bde12055dc5a2350c3ed46758aae808c7c02422b Mon Sep 17 00:00:00 2001 From: Applekid Date: Tue, 10 Feb 2026 13:27:51 -0800 Subject: [PATCH 2/4] Remove PURGE_PHASE env var, clarify phases as build order - Removed PURGE_PHASE environment variable - Phases are now a recommended build order, not deployment gates - Updated implementation notes to focus on incremental development - Clarified Phase 2/3 features available when implementation complete - Updated Quick Start and configuration examples --- docs/PurgeFeatureSpec.md | 28 ++++++++++++++++++---------- docs/PurgeFeatureSummary.md | 26 ++++++++++++++------------ 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/docs/PurgeFeatureSpec.md b/docs/PurgeFeatureSpec.md index e4239bf..fc3ba88 100644 --- a/docs/PurgeFeatureSpec.md +++ b/docs/PurgeFeatureSpec.md @@ -59,7 +59,7 @@ Configure purge settings for a channel. **Validation:** - Channel must exist and be accessible by bot - Days must be between 1 and 365 -- Auto-delete only allowed if Phase 3 is enabled (env var) +- Auto-delete only allowed if Phase 3 implementation is complete ### `/mod purge execute channel:<#channel>` Manually trigger purge for a specific channel. @@ -68,10 +68,10 @@ Manually trigger purge for a specific channel. - `channel` (required): Channel to purge (mention) **Behavior:** -- Only available in Phase 2+ - Deletes messages older than configured retention window - Posts summary to mod-comms - Requires confirmation (button interaction) +- Not available until Phase 2 implementation is complete **Example:** ``` @@ -176,7 +176,6 @@ CREATE TABLE purge_history ( ```bash # Purge feature configuration PURGE_SCHEDULE_CRON="0 9 * * 0" # Cron schedule for checks (default: Sundays 9 AM UTC) -PURGE_PHASE="1" # Deployment phase (1, 2, or 3) PURGE_MOD_CHANNEL_ID="123456789" # Channel ID for purge notifications PURGE_BATCH_SIZE="100" # Messages to delete per batch (Discord rate limit: 100/bulk) PURGE_BATCH_DELAY_MS="1000" # Delay between batches (rate limit safety) @@ -201,19 +200,28 @@ PURGE_BATCH_DELAY_MS="1000" # Delay between batches (rate limit safety) ## Implementation Notes -### Phase Rollout Strategy -1. **Phase 1**: Deploy with `PURGE_PHASE=1` - - Monitor notifications for 2-4 weeks +### Build Order (Recommended) +The phases represent a recommended implementation order, not distinct deployments: + +1. **Phase 1: Notification Only** (Build first) + - Implement scheduled checks + - Implement notification posting to mod-comms + - Deploy and monitor for 2-4 weeks - Verify message counts are accurate - Confirm no false positives -2. **Phase 2**: Update to `PURGE_PHASE=2` - - Moderators manually test `/mod purge execute` +2. **Phase 2: Manual Execution** (Build second) + - Implement `/mod purge execute` command + - Implement deletion logic (bulk + individual) + - Implement confirmation prompts + - Moderators manually test purge - Verify deletion only affects correct messages - Run for 2-4 weeks with spot checks -3. **Phase 3**: Update to `PURGE_PHASE=3` - - Enable auto-delete for low-risk channels first (e.g., #off-topic) +3. **Phase 3: Auto-Delete** (Build last) + - Add `autodelete` flag to `/mod purge set` command + - Implement auto-delete logic in scheduled checks + - Enable for low-risk channels first (e.g., #off-topic) - Monitor for 1-2 weeks - Gradually enable for more channels diff --git a/docs/PurgeFeatureSummary.md b/docs/PurgeFeatureSummary.md index 7f186fb..afcd049 100644 --- a/docs/PurgeFeatureSummary.md +++ b/docs/PurgeFeatureSummary.md @@ -20,22 +20,24 @@ /mod purge disable channel:#important # Disable purge ``` -## Rollout Phases +## Build Order (Recommended) -### Phase 1: Notification Only โœ… (Start here) -- Bot checks channels on schedule (e.g., every Sunday) -- Posts notifications to mod-comms about messages past threshold +The phases represent recommended implementation order, not separate deployments: + +### Phase 1: Notification Only โœ… (Build first) +- Implement scheduled checks +- Post notifications to mod-comms about messages past threshold - **No deletion occurs** -- Run for 2-4 weeks to verify accuracy +- Deploy and monitor for 2-4 weeks to verify accuracy -### Phase 2: Manual Execution -- Enable `/mod purge execute` command +### Phase 2: Manual Execution (Build second) +- Implement `/mod purge execute` command - Mods can manually trigger purge after reviewing notifications - Verify deletion mechanics work as expected - Run for 2-4 weeks with spot checks -### Phase 3: Auto-Delete -- Enable `autodelete:true` flag per channel +### Phase 3: Auto-Delete (Build last) +- Implement `autodelete:true` flag per channel - Bot automatically deletes qualifying messages on schedule - Posts summary to mod-comms after each purge - Start with low-risk channels (#off-topic), expand gradually @@ -45,8 +47,9 @@ ```bash # Environment variables PURGE_SCHEDULE_CRON="0 9 * * 0" # Every Sunday 9 AM UTC -PURGE_PHASE="1" # Start with Phase 1 PURGE_MOD_CHANNEL_ID="123456789" # Where to post notifications +PURGE_BATCH_SIZE="100" # Messages per batch +PURGE_BATCH_DELAY_MS="1000" # Delay between batches ``` ## Safety Features @@ -115,12 +118,11 @@ Oldest remaining: 2025-12-10 09:15 UTC Next check: 2026-01-19 09:00 UTC ``` -## Quick Start (Phase 1 Deployment) +## Quick Start (Phase 1 Implementation) 1. Set environment variables: ```bash PURGE_SCHEDULE_CRON="0 9 * * 0" - PURGE_PHASE="1" PURGE_MOD_CHANNEL_ID="your-mod-channel-id" ``` From b68cd255714915734d8b2bddd0b6868fb6383a83 Mon Sep 17 00:00:00 2001 From: Applekid Date: Tue, 10 Feb 2026 13:29:51 -0800 Subject: [PATCH 3/4] Add privacy constraints: bot only accesses message metadata, not content - Added Privacy & Security section to spec - Clarified READ_MESSAGE_HISTORY grants access to content, but implementation must not use it - Bot only accesses message ID and timestamp (metadata) - Message content, author, attachments never read or stored - Updated deletion logic and message fetching with privacy notes - Added implementation pattern examples (correct vs incorrect) - Audit log only stores counts and timestamp ranges, never message data - Updated summary with privacy section for quick reference --- docs/PurgeFeatureSpec.md | 67 +++++++++++++++++++++++++++++++++++-- docs/PurgeFeatureSummary.md | 14 +++++++- 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/docs/PurgeFeatureSpec.md b/docs/PurgeFeatureSpec.md index fc3ba88..53b2cef 100644 --- a/docs/PurgeFeatureSpec.md +++ b/docs/PurgeFeatureSpec.md @@ -181,6 +181,45 @@ PURGE_BATCH_SIZE="100" # Messages to delete per batch (Discord rat PURGE_BATCH_DELAY_MS="1000" # Delay between batches (rate limit safety) ``` +## Privacy & Security + +### Message Content Access +**The purge feature MUST NOT access message content.** + +While Discord's `READ_MESSAGE_HISTORY` permission grants access to full message objects (including content), the purge implementation should: + +**โœ… DO:** +- Access message `id` (required for deletion) +- Access message `timestamp` / `createdTimestamp` (required to determine age) +- Count messages for reporting + +**โŒ DO NOT:** +- Read or process message `content` +- Access message `author`, `mentions`, `embeds`, `attachments` +- Log message data (even in errors) +- Store any message information beyond counts and timestamps ranges + +### Implementation Pattern +```javascript +// โœ… CORRECT: Extract only metadata +const messages = await channel.messages.fetch({ limit: 100 }); +const toDelete = messages + .filter(msg => Date.now() - msg.createdTimestamp > retentionMs) + .map(msg => msg.id); // Only extract ID + +// โŒ WRONG: Accessing content +const messages = await channel.messages.fetch({ limit: 100 }); +messages.forEach(msg => { + console.log(msg.content); // NEVER do this + if (msg.content.includes('sensitive')) { /* ... */ } // NEVER do this +}); +``` + +### Audit & Logging +- Audit log stores: channel ID, timestamp range, message count, executor +- Audit log NEVER stores: message content, author IDs, message snippets +- Error logs reference messages by ID only, never log content + ## Discord API Considerations ### Rate Limits @@ -192,12 +231,26 @@ PURGE_BATCH_DELAY_MS="1000" # Delay between batches (rate limit safety) - Fetch in batches of 100 using `before` parameter - Discord returns messages newest โ†’ oldest - Stop when reaching retention threshold +- **Extract only `id` and `timestamp` from each message** +- Immediately discard all other message data (content, author, etc.) + +**Example (pseudocode)**: +```javascript +const messages = await channel.messages.fetch({ limit: 100, before: lastId }); +const messageMetadata = messages.map(msg => ({ + id: msg.id, + timestamp: msg.createdTimestamp +})); +// messages object is now discarded, content never accessed +``` ### Permissions Required - `MANAGE_MESSAGES` - Required for bulk delete -- `READ_MESSAGE_HISTORY` - Required to fetch old messages +- `READ_MESSAGE_HISTORY` - Required to fetch message metadata (timestamp, ID) - `VIEW_CHANNEL` - Required to access channel +**Privacy Note**: While `READ_MESSAGE_HISTORY` technically allows access to message content, the purge feature **MUST NOT** read, store, or process message content. The bot should only access message metadata (ID, timestamp) to determine which messages to delete. Message content is never logged, stored, or inspected. + ## Implementation Notes ### Build Order (Recommended) @@ -228,17 +281,25 @@ The phases represent a recommended implementation order, not distinct deployment ### Deletion Logic ``` For each message: + // ONLY access: message.id, message.timestamp + // DO NOT access: message.content, message.author, message.attachments, etc. message_age = now - message.timestamp if message_age > retention_days: if message.timestamp < 14_days_ago: - delete_individual(message) # Slow path + delete_individual(message.id) # Slow path - only ID needed else: - add_to_bulk_batch(message) # Fast path + add_to_bulk_batch(message.id) # Fast path - only ID needed if batch.size >= PURGE_BATCH_SIZE: bulk_delete(batch) sleep(PURGE_BATCH_DELAY_MS) ``` +**Privacy Implementation**: +- When fetching messages via Discord API, immediately extract only `id` and `timestamp` +- Discard all other message properties (content, author, embeds, attachments, etc.) +- Never log message content, even in error cases +- Database only stores message counts, not message data + ### Error Handling - If deletion fails (permissions, rate limit), log error and skip - Post error summary to mod-comms diff --git a/docs/PurgeFeatureSummary.md b/docs/PurgeFeatureSummary.md index afcd049..586acbf 100644 --- a/docs/PurgeFeatureSummary.md +++ b/docs/PurgeFeatureSummary.md @@ -60,6 +60,16 @@ PURGE_BATCH_DELAY_MS="1000" # Delay between batches - **Rate limit handling**: Respects Discord API limits - **Error recovery**: Continues on failure, posts error summary +## Privacy & Security + +**Message content is never accessed.** + +- Bot only reads message ID and timestamp (metadata) +- Message content, author, attachments are never accessed +- No message data stored in database (only counts and timestamp ranges) +- Audit log contains no message content or user data +- Implementation extracts metadata immediately and discards full message objects + ## Database Schema ```sql @@ -84,9 +94,11 @@ CREATE TABLE purge_history ( ## Discord Permissions Required - `MANAGE_MESSAGES` - Delete messages -- `READ_MESSAGE_HISTORY` - Fetch old messages +- `READ_MESSAGE_HISTORY` - Fetch message metadata (timestamp, ID) - `VIEW_CHANNEL` - Access channels +**Privacy Note**: While `READ_MESSAGE_HISTORY` allows access to message content, the purge feature **only uses message metadata** (ID and timestamp). Message content is never read, stored, or processed. + ## Discord API Limits - **Bulk delete**: Max 100 messages, must be < 14 days old From 721bcaf4d1adc9b19c022c3fe33e3f01c44fc3a6 Mon Sep 17 00:00:00 2001 From: Applekid Date: Tue, 10 Feb 2026 13:31:22 -0800 Subject: [PATCH 4/4] Condense spec by ~50%: remove verbosity, keep technical details - Reduced PurgeFeatureSpec.md from ~10KB to ~6KB - Reduced PurgeFeatureSummary.md from ~4.4KB to ~2.9KB - Removed redundant examples and verbose explanations - Kept all essential info: commands, schema, privacy, implementation - Merged related sections for clarity - More direct, concise writing style --- docs/PurgeFeatureSpec.md | 402 +++++++++--------------------------- docs/PurgeFeatureSummary.md | 157 +++++--------- 2 files changed, 156 insertions(+), 403 deletions(-) diff --git a/docs/PurgeFeatureSpec.md b/docs/PurgeFeatureSpec.md index 53b2cef..2346ff2 100644 --- a/docs/PurgeFeatureSpec.md +++ b/docs/PurgeFeatureSpec.md @@ -2,149 +2,108 @@ ## Overview -The Purge feature enables moderators to configure automated message cleanup policies for individual channels. Messages older than a configurable timeframe are identified, and moderators can be notified or have them automatically deleted based on progressive rollout phases. - -## Goals - -1. **Channel-specific retention policies**: Configure different message retention windows for each channel -2. **Automated monitoring**: Scheduled checks identify channels with messages past retention threshold -3. **Progressive rollout**: Start with notifications, progress to manual execution, then auto-deletion -4. **Safety first**: Multiple phases ensure deletion mechanics work as expected before automation - -## Phases - -### Phase 1: Notification Only (Initial Deployment) -- Scheduled checks identify channels with messages exceeding retention window -- Bot posts notifications to mod-comms channel -- No deletion occurs โ€” purely informational - -### Phase 2: Manual Execution -- Moderators can trigger purge via `/mod purge execute` command -- Provides hands-on experience with deletion mechanics -- Allows verification that correct messages are targeted - -### Phase 3: Auto-Delete -- Moderators can enable auto-delete per channel via `autodelete:true` flag -- Bot automatically deletes qualifying messages on schedule -- Posts summary to mod-comms after each purge +Automated message cleanup for Discord channels with configurable retention policies. Progressive build order: notifications โ†’ manual execution โ†’ auto-delete. ## Commands ### `/mod purge view` View current purge configuration for all channels. -**Output:** -``` -๐Ÿ“‹ Purge Configuration: - -#general - 30 days, auto-delete: disabled -#announcements - 90 days, auto-delete: disabled -#off-topic - 7 days, auto-delete: enabled -``` - ### `/mod purge set channel:<#channel> days: [autodelete:]` Configure purge settings for a channel. -**Parameters:** -- `channel` (required): Channel to configure (mention) -- `days` (required): Retention window in days (1-365) -- `autodelete` (optional): Enable/disable auto-deletion (default: false) - -**Examples:** -``` -/mod purge set channel:#general days:30 -/mod purge set channel:#off-topic days:7 autodelete:true -``` +- `channel` (required): Channel to configure +- `days` (required): Retention window (1-365) +- `autodelete` (optional, default: false): Enable auto-deletion **Validation:** -- Channel must exist and be accessible by bot -- Days must be between 1 and 365 -- Auto-delete only allowed if Phase 3 implementation is complete +- Channel must exist and be accessible +- Days: 1-365 +- Auto-delete only available when Phase 3 is implemented ### `/mod purge execute channel:<#channel>` -Manually trigger purge for a specific channel. +Manually trigger purge for a channel. Requires confirmation prompt. Only available when Phase 2 is implemented. -**Parameters:** -- `channel` (required): Channel to purge (mention) +### `/mod purge disable channel:<#channel>` +Disable purge for a channel. -**Behavior:** -- Deletes messages older than configured retention window -- Posts summary to mod-comms -- Requires confirmation (button interaction) -- Not available until Phase 2 implementation is complete +## Build Order -**Example:** -``` -/mod purge execute channel:#general +### Phase 1: Notification Only (Build first) +- Scheduled checks identify channels with messages past retention threshold +- Post notifications to mod-comms channel +- No deletion occurs +- Deploy and monitor 2-4 weeks to verify accuracy -โš ๏ธ Purge Confirmation -Channel: #general -Retention: 30 days -Estimated messages: 1,247 -Are you sure? [Confirm] [Cancel] -``` +### Phase 2: Manual Execution (Build second) +- Implement `/mod purge execute` command +- Moderators can manually trigger purge after reviewing notifications +- Verify deletion mechanics work as expected +- Run 2-4 weeks with spot checks -### `/mod purge disable channel:<#channel>` -Disable purge for a specific channel. - -**Parameters:** -- `channel` (required): Channel to disable (mention) - -**Example:** -``` -/mod purge disable channel:#important -``` +### Phase 3: Auto-Delete (Build last) +- Implement `autodelete` flag in `/mod purge set` +- Bot automatically deletes qualifying messages on schedule +- Posts summary to mod-comms after each purge +- Enable gradually, starting with low-risk channels ## Scheduled Checks -### Cadence Configuration -Set via environment variable: -``` -PURGE_SCHEDULE_CRON="0 9 * * 0" # Every Sunday at 9 AM UTC -``` +**Cadence**: Configured via `PURGE_SCHEDULE_CRON` (default: every Sunday 9 AM UTC) -Default: Every Sunday at 9 AM UTC +**Process**: +1. Iterate channels with configured retention windows +2. Fetch messages older than retention threshold +3. Count qualifying messages +4. If count > 0: + - **Phase 1/2**: Post notification to mod-comms + - **Phase 3**: If autodelete enabled, delete messages and post summary; else notify -### Check Process -1. Bot iterates through all channels with configured retention windows -2. For each channel: - - Fetch messages older than retention window - - Count qualifying messages - - If count > 0: - - **Phase 1**: Post notification to mod-comms - - **Phase 2**: Same as Phase 1 (manual execution only) - - **Phase 3**: If `autodelete:true`, delete messages and post summary; else notify - -### Notification Format (Phase 1 & 2) +**Notification format**: ``` ๐Ÿงน Purge Alert - Channel: #general Retention: 30 days Messages past threshold: 1,247 -Oldest message: 2025-11-10 14:32 UTC - -Use `/mod purge execute channel:#general` to purge manually. +Oldest: 2025-11-10 14:32 UTC ``` -### Auto-Delete Summary (Phase 3) +**Auto-delete summary**: ``` โœ… Auto-Purge Complete - Channel: #general -Retention: 30 days Messages deleted: 1,247 Oldest remaining: 2025-12-10 09:15 UTC -Next check: 2026-01-19 09:00 UTC ``` -## Data Storage +## Privacy & Security + +**The bot MUST NOT access message content.** + +While `READ_MESSAGE_HISTORY` grants access to full message objects, implementation should: + +**โœ… DO:** +- Access message `id` and `timestamp` only +- Count messages for reporting + +**โŒ DO NOT:** +- Read message `content`, `author`, `embeds`, `attachments` +- Log message data (even in errors) +- Store message information beyond counts -### Channel Configuration -Store per-channel settings in database (SQLite for simplicity): +**Implementation pattern**: +```javascript +// Extract only metadata immediately +const messages = await channel.messages.fetch({ limit: 100 }); +const toDelete = messages + .filter(msg => Date.now() - msg.createdTimestamp > retentionMs) + .map(msg => msg.id); // Only ID +``` + +## Database Schema -**Table: `purge_config`** ```sql +-- Channel retention policies CREATE TABLE purge_config ( channel_id TEXT PRIMARY KEY, retention_days INTEGER NOT NULL, @@ -152,241 +111,86 @@ CREATE TABLE purge_config ( created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -``` -### Purge History -Track purge executions for audit trail: - -**Table: `purge_history`** -```sql +-- Audit trail CREATE TABLE purge_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, channel_id TEXT NOT NULL, executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, messages_deleted INTEGER NOT NULL, trigger_type TEXT NOT NULL, -- 'manual', 'auto', 'scheduled_check' - triggered_by TEXT, -- user_id for manual, 'system' for auto + triggered_by TEXT, -- user_id or 'system' oldest_deleted TIMESTAMP, newest_deleted TIMESTAMP ); ``` -## Environment Variables - -```bash -# Purge feature configuration -PURGE_SCHEDULE_CRON="0 9 * * 0" # Cron schedule for checks (default: Sundays 9 AM UTC) -PURGE_MOD_CHANNEL_ID="123456789" # Channel ID for purge notifications -PURGE_BATCH_SIZE="100" # Messages to delete per batch (Discord rate limit: 100/bulk) -PURGE_BATCH_DELAY_MS="1000" # Delay between batches (rate limit safety) -``` - -## Privacy & Security - -### Message Content Access -**The purge feature MUST NOT access message content.** - -While Discord's `READ_MESSAGE_HISTORY` permission grants access to full message objects (including content), the purge implementation should: - -**โœ… DO:** -- Access message `id` (required for deletion) -- Access message `timestamp` / `createdTimestamp` (required to determine age) -- Count messages for reporting - -**โŒ DO NOT:** -- Read or process message `content` -- Access message `author`, `mentions`, `embeds`, `attachments` -- Log message data (even in errors) -- Store any message information beyond counts and timestamps ranges - -### Implementation Pattern -```javascript -// โœ… CORRECT: Extract only metadata -const messages = await channel.messages.fetch({ limit: 100 }); -const toDelete = messages - .filter(msg => Date.now() - msg.createdTimestamp > retentionMs) - .map(msg => msg.id); // Only extract ID - -// โŒ WRONG: Accessing content -const messages = await channel.messages.fetch({ limit: 100 }); -messages.forEach(msg => { - console.log(msg.content); // NEVER do this - if (msg.content.includes('sensitive')) { /* ... */ } // NEVER do this -}); -``` - -### Audit & Logging -- Audit log stores: channel ID, timestamp range, message count, executor -- Audit log NEVER stores: message content, author IDs, message snippets -- Error logs reference messages by ID only, never log content - -## Discord API Considerations +## Discord API ### Rate Limits -- **Bulk delete**: Max 100 messages per call -- **Bulk delete age limit**: Messages must be < 14 days old -- For messages > 14 days: Use individual delete (1 message per call, 5/sec rate limit) - -### Message Fetching -- Fetch in batches of 100 using `before` parameter -- Discord returns messages newest โ†’ oldest -- Stop when reaching retention threshold -- **Extract only `id` and `timestamp` from each message** -- Immediately discard all other message data (content, author, etc.) - -**Example (pseudocode)**: -```javascript -const messages = await channel.messages.fetch({ limit: 100, before: lastId }); -const messageMetadata = messages.map(msg => ({ - id: msg.id, - timestamp: msg.createdTimestamp -})); -// messages object is now discarded, content never accessed -``` - -### Permissions Required -- `MANAGE_MESSAGES` - Required for bulk delete -- `READ_MESSAGE_HISTORY` - Required to fetch message metadata (timestamp, ID) -- `VIEW_CHANNEL` - Required to access channel - -**Privacy Note**: While `READ_MESSAGE_HISTORY` technically allows access to message content, the purge feature **MUST NOT** read, store, or process message content. The bot should only access message metadata (ID, timestamp) to determine which messages to delete. Message content is never logged, stored, or inspected. - -## Implementation Notes - -### Build Order (Recommended) -The phases represent a recommended implementation order, not distinct deployments: - -1. **Phase 1: Notification Only** (Build first) - - Implement scheduled checks - - Implement notification posting to mod-comms - - Deploy and monitor for 2-4 weeks - - Verify message counts are accurate - - Confirm no false positives - -2. **Phase 2: Manual Execution** (Build second) - - Implement `/mod purge execute` command - - Implement deletion logic (bulk + individual) - - Implement confirmation prompts - - Moderators manually test purge - - Verify deletion only affects correct messages - - Run for 2-4 weeks with spot checks - -3. **Phase 3: Auto-Delete** (Build last) - - Add `autodelete` flag to `/mod purge set` command - - Implement auto-delete logic in scheduled checks - - Enable for low-risk channels first (e.g., #off-topic) - - Monitor for 1-2 weeks - - Gradually enable for more channels +- **Bulk delete**: Max 100 messages, must be < 14 days old +- **Individual delete**: 5 messages/sec for messages > 14 days old +- Use bulk delete when possible, fall back to individual delete for older messages ### Deletion Logic -``` +```javascript For each message: // ONLY access: message.id, message.timestamp - // DO NOT access: message.content, message.author, message.attachments, etc. message_age = now - message.timestamp if message_age > retention_days: if message.timestamp < 14_days_ago: - delete_individual(message.id) # Slow path - only ID needed + delete_individual(message.id) else: - add_to_bulk_batch(message.id) # Fast path - only ID needed + add_to_bulk_batch(message.id) if batch.size >= PURGE_BATCH_SIZE: bulk_delete(batch) sleep(PURGE_BATCH_DELAY_MS) ``` -**Privacy Implementation**: -- When fetching messages via Discord API, immediately extract only `id` and `timestamp` -- Discard all other message properties (content, author, embeds, attachments, etc.) -- Never log message content, even in error cases -- Database only stores message counts, not message data - -### Error Handling -- If deletion fails (permissions, rate limit), log error and skip -- Post error summary to mod-comms -- Continue with remaining messages (don't abort entire purge) - -### Safety Guards -- **Dry-run mode**: Optional flag to simulate deletion without executing -- **Max messages per purge**: Configurable limit (default: 10,000) -- **Confirmation prompts**: Required for manual execution -- **Audit log**: All purges logged with trigger type, user, timestamp - -## User Stories - -### Story 1: Configure Channel Retention -**As a moderator**, I want to set a 30-day retention policy for #general so that old messages are automatically cleaned up. - -**Steps:** -1. Moderator: `/mod purge set channel:#general days:30` -2. Bot: "โœ… Purge configured for #general: 30 days retention, auto-delete disabled" - -### Story 2: Receive Purge Notification (Phase 1) -**As a moderator**, I want to be notified when #general has messages older than 30 days so I can review before deletion. - -**Steps:** -1. Scheduled check runs on Sunday 9 AM -2. Bot finds 1,247 messages > 30 days old in #general -3. Bot posts notification to mod-comms with count and oldest message timestamp +### Permissions Required +- `MANAGE_MESSAGES` - Delete messages +- `READ_MESSAGE_HISTORY` - Fetch message metadata (ID, timestamp) +- `VIEW_CHANNEL` - Access channels -### Story 3: Manual Purge (Phase 2) -**As a moderator**, I want to manually purge #off-topic after reviewing the notification. +## Environment Variables -**Steps:** -1. Moderator: `/mod purge execute channel:#off-topic` -2. Bot: Shows confirmation prompt with estimated message count -3. Moderator: Clicks [Confirm] -4. Bot: Deletes messages, posts summary to mod-comms +```bash +PURGE_SCHEDULE_CRON="0 9 * * 0" # Cron schedule (default: Sundays 9 AM UTC) +PURGE_MOD_CHANNEL_ID="123456789" # Notification channel ID +PURGE_BATCH_SIZE="100" # Messages per batch (max 100) +PURGE_BATCH_DELAY_MS="1000" # Delay between batches +``` -### Story 4: Auto-Delete (Phase 3) -**As a moderator**, I want #off-topic to auto-delete messages older than 7 days so I don't have to manually purge. +## Error Handling -**Steps:** -1. Moderator: `/mod purge set channel:#off-topic days:7 autodelete:true` -2. Bot: "โœ… Purge configured for #off-topic: 7 days retention, auto-delete enabled" -3. Next scheduled check: Bot auto-deletes qualifying messages, posts summary +- If deletion fails (permissions, rate limit), log error and skip +- Post error summary to mod-comms +- Continue with remaining messages (don't abort) -## Testing Plan +## Safety Features -### Unit Tests -- Retention window calculation -- Message age filtering -- Batch deletion logic -- Configuration validation +- **Progressive rollout**: Three phases ensure safe deployment +- **Confirmation prompts**: Required for manual execution +- **Audit log**: All purges tracked (channel, count, timestamp, executor) +- **Rate limit handling**: Respects Discord API limits +- **Max messages limit**: Configurable per-purge (default: 10,000) -### Integration Tests -- Database CRUD operations -- Discord API interactions (mocked) -- Scheduled job execution +## Testing Checklist -### Manual Testing Checklist - [ ] Configure retention for test channel -- [ ] Verify notification accuracy in Phase 1 -- [ ] Test manual execution in Phase 2 +- [ ] Verify notification accuracy (Phase 1) +- [ ] Test manual execution (Phase 2) - [ ] Verify only correct messages deleted -- [ ] Test auto-delete in Phase 3 -- [ ] Verify error handling (missing permissions, rate limits) +- [ ] Test auto-delete (Phase 3) - [ ] Test bulk delete vs individual delete paths +- [ ] Verify error handling (missing permissions, rate limits) - [ ] Verify audit log completeness +- [ ] Confirm message content never accessed ## Future Enhancements -1. **Whitelist users**: Exclude messages from specific users (e.g., bot announcements) -2. **Pinned message exemption**: Never delete pinned messages -3. **Reaction-based protection**: Messages with specific reactions are preserved -4. **Per-role visibility**: Different retention windows based on who can see the channel -5. **Export before delete**: Archive messages to S3/disk before deletion -6. **Dashboard**: Web UI to view/configure purge settings - -## Open Questions - -1. Should pinned messages be exempt by default? -2. Should we require a minimum retention window (e.g., 7 days)? -3. Should purge history be retained indefinitely or expire? -4. Should we support regex patterns for message content filtering? -5. Should we allow per-user exemptions via command or config file? - -## References - -- [Discord Bulk Delete API](https://discord.com/developers/docs/resources/channel#bulk-delete-messages) -- [Discord Rate Limits](https://discord.com/developers/docs/topics/rate-limits) -- [Node-cron scheduling](https://www.npmjs.com/package/node-cron) +- Whitelist users (exclude specific users' messages) +- Exempt pinned messages +- Reaction-based protection (preserve messages with specific reactions) +- Export messages before deletion (archive to S3) +- Web dashboard for configuration diff --git a/docs/PurgeFeatureSummary.md b/docs/PurgeFeatureSummary.md index 586acbf..b89661e 100644 --- a/docs/PurgeFeatureSummary.md +++ b/docs/PurgeFeatureSummary.md @@ -1,79 +1,49 @@ # Purge Feature Summary -**TL;DR**: Automated message cleanup for Discord channels with configurable retention policies and progressive rollout (notify โ†’ manual โ†’ auto-delete). +**TL;DR**: Automated message cleanup for Discord channels with configurable retention policies. Progressive build: notify โ†’ manual โ†’ auto-delete. -## What It Does - -- Configure per-channel message retention windows (e.g., "delete messages older than 30 days") -- Scheduled checks identify channels with messages past threshold -- Phase 1: Notify mods -- Phase 2: Allow manual purge -- Phase 3: Auto-delete with mod notifications - -## Key Commands +## Commands ``` -/mod purge view # View all channel configs -/mod purge set channel:#general days:30 # Set 30-day retention -/mod purge set channel:#off-topic days:7 autodelete:true # Enable auto-delete -/mod purge execute channel:#general # Manual purge (Phase 2+) -/mod purge disable channel:#important # Disable purge +/mod purge view # View all configs +/mod purge set channel:#general days:30 # Set retention +/mod purge set channel:#off-topic days:7 autodelete:true # Enable auto-delete +/mod purge execute channel:#general # Manual purge +/mod purge disable channel:#important # Disable ``` -## Build Order (Recommended) +## Build Order -The phases represent recommended implementation order, not separate deployments: +**Phase 1: Notification Only** (Build first) +- Scheduled checks find old messages +- Notify mods via mod-comms +- No deletion +- Monitor 2-4 weeks -### Phase 1: Notification Only โœ… (Build first) -- Implement scheduled checks -- Post notifications to mod-comms about messages past threshold -- **No deletion occurs** -- Deploy and monitor for 2-4 weeks to verify accuracy +**Phase 2: Manual Execution** (Build second) +- Add `/mod purge execute` command +- Mods trigger purge manually +- Verify deletion works +- Run 2-4 weeks -### Phase 2: Manual Execution (Build second) -- Implement `/mod purge execute` command -- Mods can manually trigger purge after reviewing notifications -- Verify deletion mechanics work as expected -- Run for 2-4 weeks with spot checks +**Phase 3: Auto-Delete** (Build last) +- Add `autodelete:true` flag +- Auto-delete on schedule +- Start with low-risk channels -### Phase 3: Auto-Delete (Build last) -- Implement `autodelete:true` flag per channel -- Bot automatically deletes qualifying messages on schedule -- Posts summary to mod-comms after each purge -- Start with low-risk channels (#off-topic), expand gradually - -## Configuration Example +## Configuration ```bash -# Environment variables -PURGE_SCHEDULE_CRON="0 9 * * 0" # Every Sunday 9 AM UTC -PURGE_MOD_CHANNEL_ID="123456789" # Where to post notifications -PURGE_BATCH_SIZE="100" # Messages per batch -PURGE_BATCH_DELAY_MS="1000" # Delay between batches +PURGE_SCHEDULE_CRON="0 9 * * 0" # Every Sunday 9 AM UTC +PURGE_MOD_CHANNEL_ID="123456789" # Notification channel +PURGE_BATCH_SIZE="100" # Messages per batch +PURGE_BATCH_DELAY_MS="1000" # Delay between batches ``` -## Safety Features - -- **Progressive rollout**: Three phases ensure safe deployment -- **Confirmation prompts**: Required for manual execution -- **Audit log**: All purges tracked with timestamp, user, count -- **Rate limit handling**: Respects Discord API limits -- **Error recovery**: Continues on failure, posts error summary - -## Privacy & Security - -**Message content is never accessed.** - -- Bot only reads message ID and timestamp (metadata) -- Message content, author, attachments are never accessed -- No message data stored in database (only counts and timestamp ranges) -- Audit log contains no message content or user data -- Implementation extracts metadata immediately and discards full message objects - ## Database Schema ```sql --- Channel retention policies +-- Channel configs CREATE TABLE purge_config ( channel_id TEXT PRIMARY KEY, retention_days INTEGER NOT NULL, @@ -91,74 +61,53 @@ CREATE TABLE purge_history ( ); ``` -## Discord Permissions Required +## Privacy + +**Message content is never accessed.** +- Bot only reads message ID and timestamp +- No message content, author, or attachments accessed +- Audit log contains only counts and timestamp ranges + +## Discord Permissions - `MANAGE_MESSAGES` - Delete messages -- `READ_MESSAGE_HISTORY` - Fetch message metadata (timestamp, ID) +- `READ_MESSAGE_HISTORY` - Fetch metadata (ID, timestamp only) - `VIEW_CHANNEL` - Access channels -**Privacy Note**: While `READ_MESSAGE_HISTORY` allows access to message content, the purge feature **only uses message metadata** (ID and timestamp). Message content is never read, stored, or processed. - ## Discord API Limits - **Bulk delete**: Max 100 messages, must be < 14 days old -- **Individual delete**: 5 messages/second for messages > 14 days old -- Purge uses bulk delete when possible, falls back to individual delete for older messages - -## Example Notification (Phase 1) - -``` -๐Ÿงน Purge Alert - -Channel: #general -Retention: 30 days -Messages past threshold: 1,247 -Oldest message: 2025-11-10 14:32 UTC - -Use `/mod purge execute channel:#general` to purge manually. -``` +- **Individual delete**: 5 messages/sec for older messages +- Bot uses bulk when possible, falls back to individual -## Example Summary (Phase 3) - -``` -โœ… Auto-Purge Complete +## Safety Features -Channel: #general -Retention: 30 days -Messages deleted: 1,247 -Oldest remaining: 2025-12-10 09:15 UTC -Next check: 2026-01-19 09:00 UTC -``` +- Progressive 3-phase rollout +- Confirmation prompts for manual execution +- Audit log for all purges +- Rate limit handling +- Error recovery (continues on failure) -## Quick Start (Phase 1 Implementation) +## Quick Start -1. Set environment variables: +1. Set env vars: ```bash PURGE_SCHEDULE_CRON="0 9 * * 0" PURGE_MOD_CHANNEL_ID="your-mod-channel-id" ``` -2. Configure a test channel: +2. Configure test channel: ``` - /mod purge set channel:#test-channel days:30 + /mod purge set channel:#test days:30 ``` -3. Wait for next scheduled check (or trigger manually for testing) - -4. Verify notification appears in mod-comms with accurate message count - -5. Monitor for 2-4 weeks, then proceed to Phase 2 +3. Wait for scheduled check or test manually -## Future Enhancements +4. Verify notification accuracy -- Whitelist specific users (preserve bot announcements) -- Exempt pinned messages -- Reaction-based protection (keep messages with specific reactions) -- Export messages before deletion (archive to S3/disk) -- Web dashboard for configuration +5. Monitor 2-4 weeks, then build Phase 2 ## References - Full spec: [PurgeFeatureSpec.md](./PurgeFeatureSpec.md) -- Discord Bulk Delete API: https://discord.com/developers/docs/resources/channel#bulk-delete-messages -- Discord Rate Limits: https://discord.com/developers/docs/topics/rate-limits +- Discord Bulk Delete: https://discord.com/developers/docs/resources/channel#bulk-delete-messages