Commit Graph
114 Commits
Author SHA1 Message Date
MythEclipse 6b3f2cdecd feat(ai-moderation): tighten rules for anatomical vulgarity and BL mentions
- Added explicit zero-tolerance rule for anatomical/sexual vulgarity (e.g. titten, kontol), explicitly forbidding the AI from passing them off as 'casual conversation' or 'jokes'
- Expanded sexual_deviation rule to explicitly cover brief mentions of BL (Boys Love), yaoi, yuri, and LGBT topics, instructing the AI to flag them regardless of casual context
2026-06-05 16:16:21 +07:00
MythEclipse e00b23f9b8 fix(concurrency): eliminate all identified double-queue and race conditions
Implements full audit from double_queue_audit.md.

## Critical

fix(backend): reanalyze-batch — per-scope in-flight guard (messages.routes.ts)
  Two concurrent admin sessions clicking 'Retry All Errors' simultaneously now
  get a 409 REANALYZE_BATCH_IN_PROGRESS for the same guildId:channelId scope.
  Prevents the recovery worker from being triggered twice for the same set of
  error messages.

fix(discord-gateway): messageUpdate embed resolution skip (messageCapture.ts)
  Discord fires messageUpdate when link previews resolve 1-2s after send
  even though the message body is unchanged. Compare newContent vs
  existingContent before resetting ai_status to pending and re-queueing LLM.
  Eliminates a spurious duplicate analysis that could overwrite a valid result.

## High

fix(discord-gateway): scheduleAutoDelete idempotency (aiAnalyzer.ts)
  Add autoDeleteInFlight Set. Both processBatch and processIndividualFallback
  call scheduleAutoDelete; without the guard, a message that races through
  both paths launches two concurrent attemptAutoDeleteFlaggedMessage calls,
  producing a duplicate moderation-action log entry and a Discord 10008 error.
  The Set is cleaned up in a .finally() block after each attempt completes.

## Medium

fix(frontend): revert optimistic pending state on HTTP failure (useMessages.ts)
  Capture the prior MessageRecord inside the setMessages functional updater
  (no extra useCallback deps needed). If reanalyzeMessage() throws, restore
  the snapshot so the UI reflects the real DB state instead of lying.

fix(discord-gateway): exclude individual_analysis_exhausted from recovery queries
  Both getConversationKeysWithIncompleteAnalysis and
  getIncompleteMessagesByConversation now add a NOT LIKE guard for
  individual_analysis_exhausted. Prevents an infinite recovery loop if a bug
  ever writes both flags to the same row.

## Low

fix(discord-gateway): unified timer path in scheduleConversationAnalysis
  Remove the separate cooldown-path that created a secondary timer calling
  scheduleConversationAnalysis recursively. Replace with a single
  clear-and-reset pattern where delayMs = max(cooldownRemainder+500, debounce).
  Eliminates the edge case where both timers were live simultaneously.

## Misc

fix(backend): cast req.params.id to String() to satisfy Express typings
  Pre-existing tsc error (string | string[]) exposed by our edit.
  String() is correct; route params are always scalar strings at runtime.
2026-06-05 16:09:23 +07:00
MythEclipse 5c0a837cf0 fix(ai-moderation): eliminate double-queue on failure and spam-retry
Three root causes patched:

1. aiAnalyzer.ts — processBatch apiFailedMessages path:
   After reverting messages to 'pending', suppress shouldScheduleNext
   (was true by default) to prevent scheduleConversationAnalysis from
   firing immediately and racing with the recovery worker that will pick
   up those same pending messages on its next poll cycle.
   Also release the conversationProcessing lock immediately after the
   revert so the cooldown timer (not the full processing-timeout) gates
   the next attempt.

2. messages.routes.ts — POST /messages/:id/reanalyze:
   Add a per-message reanalyzeInFlight Set.  Concurrent requests for
   the same ID now return HTTP 409 instead of issuing duplicate UPDATEs
   and triggering multiple recovery worker activations.
   Also narrow the SQL predicate to 'WHERE id =  AND ai_status != pending'
   so a click that arrives while the recovery worker already picked the
   message up is a no-op at the DB level.
2026-06-05 15:38:31 +07:00
MythEclipse a0bf7dfdd9 chore(ai-moderation): harden LLM prompt and lexical scanner against evasion techniques and cross-lingual vulgarities 2026-06-05 15:28:04 +07:00
MythEclipse 9a02ac8d17 feat(ai-moderation): flag excessive religious jokes and satire as sara 2026-06-04 19:31:08 +07:00
MythEclipse a965fb1e08 fix(moderation): treat age_restricted skipped messages as clean instead of error 2026-06-04 19:28:59 +07:00
MythEclipse d1d4510ce8 chore(format): auto-format files with biome 2026-06-04 18:52:56 +07:00
MythEclipse 367d8696c8 fix(moderation): revert API failures to pending instead of sticking in error state 2026-06-04 18:52:37 +07:00
MythEclipse 946343ec8c fix(ai-moderation): skip caching error results to prevent false positives from transient failures 2026-06-04 17:42:23 +07:00
MythEclipse 4996acfacf refactor(ai-moderation): unify worker pool entry points with discriminated union routing 2026-06-04 17:39:40 +07:00
MythEclipse 686dc2de4f refactor(ai-moderation): remove unused count variable in stale CB error pruning loop 2026-06-04 17:35:52 +07:00
MythEclipse 121b78198c feat(ai-moderation): add circuit breaker alert system with extensible handlers 2026-06-04 17:35:26 +07:00
MythEclipse 8c67eefede refactor(ai-moderation): offload individual message analysis to worker pool and add auto-delete notifications 2026-06-04 17:34:54 +07:00
MythEclipse ce8a42f5fd feat(ai-moderation): eliminate LLM-based badword detection in favor of pure rule-based matching 2026-06-04 17:33:08 +07:00
MythEclipse b3d42118bd fix(ai-moderation): use cached status instead of hardcoding "clean" for cache hit results 2026-06-04 17:30:37 +07:00
MythEclipse 9474d30cb7 refactor(ai-moderation): migrate sticker cache SQL queries from ? to $N parameter placeholders 2026-06-04 17:29:19 +07:00
MythEclipse 269a13d96a fix(ai-moderation): restrict vision cache pre-download check to stickers and custom emojis only 2026-06-04 17:20:52 +07:00
MythEclipse 5d9713b162 chore(config): update TELE_UPLOAD_URL domain across all services 2026-06-04 17:12:02 +07:00
MythEclipse aaebe168cf fix(ai-moderation): fallback to discord_url when uploaded_url is null for attachment images 2026-06-04 17:06:57 +07:00
MythEclipse fc52fe5c1d feat(ai-moderation): cache per-user moderation results for text-only messages to skip redundant LLM calls 2026-06-04 16:54:06 +07:00
MythEclipse c1e79dca23 feat(ai-moderation): add per-user moderation result cache for spammer deduplication 2026-06-04 16:51:08 +07:00
MythEclipse b0278de51a feat(ai-moderation): add URL analysis rules to moderation prompt to prevent domain-based false positives 2026-06-04 16:35:14 +07:00
MythEclipse 65a65fdf39 feat(ai-moderation): fetch web content from URLs in text-only messages for accurate LLM analysis 2026-06-04 16:32:08 +07:00
MythEclipse 259b0babb5 feat(ai-moderation): parse moderation category from LLM fallback response instead of using static defaults 2026-06-04 13:49:35 +07:00
MythEclipse 3fc26592fc feat(ai-moderation): add simple text-only LLM fallback when normal analysis fails for small models 2026-06-04 13:40:25 +07:00
MythEclipse e55ee342b1 fix(ai-moderation): downgrade operational logs to debug and add missing debug logs to silent early-return paths 2026-06-04 13:13:55 +07:00
MythEclipse d568cab88f fix(ai-moderation): add defensive logging to silent failure paths in media analysis 2026-06-04 13:06:35 +07:00
MythEclipse c304d4ca7c fix(ai-moderation): implement exponential backoff for LLM and vision API retries 2026-06-04 13:02:02 +07:00
MythEclipse 1c46a8a084 feat(ai-moderation): add conflict instigation, offensive username, and discrimination moderation flags and prompt rules 2026-06-04 12:49:24 +07:00
MythEclipse aad62bc66b fix(ai-moderation): strip fallback text from LLM analysis content 2026-06-03 20:59:10 +07:00
MythEclipse dc78faa65d refactor(attachment-upload): switch image resizer to lossless PNG for vision analysis 2026-06-03 19:25:55 +07:00
MythEclipse b7d4e66600 refactor: remove json_schema response format, simplify to json_object only 2026-06-03 00:40:42 +07:00
MythEclipse d81aaf2b4a feat(db): add migration to drop unused AI columns and dynamically resolve initial migration tag 2026-06-02 23:55:12 +07:00
MythEclipse 88acda4703 feat(db): add migration snapshot for corrected_moderations table 2026-06-02 23:44:29 +07:00
MythEclipseandClaude Opus 4.8 8ff547af43 fix(db): add migration for corrected_moderations table
Table was defined in Drizzle schema at schema.ts:425 but no migration
existed. Runtime queries from text-cache-store fail with:
  relation "corrected_moderations" does not exist

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 23:43:40 +07:00
MythEclipse b98aba5748 Tidak ada perubahan staged. Staging area kosong — git diff --cached tidak menghasilkan output. Silakan git add file yang ingin di-commit terlebih dahulu. 2026-06-02 23:09:30 +07:00
MythEclipse 3f3a1184fe Tidak ada perubahan staged untuk dibuatkan commit message. Working tree bersih — git status menunjukkan tidak ada file yang di-stage. Silakan git add file yang ingin di-commit terlebih dahulu, lalu saya bisa bantu tulis commit messagenya. 2026-06-02 23:08:48 +07:00
MythEclipse 75983a390c There are no staged changes to commit — the working tree is clean (nothing to commit, working tree clean). Stage some files first with git add, then I can craft the commit message. 2026-06-02 23:07:21 +07:00
MythEclipse c1de1279a5 There are no staged changes to commit. The staging area is empty — git status shows a clean working tree with nothing staged. 2026-06-02 23:07:11 +07:00
MythEclipse 1f3d1ac3f4 API Error: API returned an empty or malformed response (HTTP 200) — check for a proxy or gateway intercepting the request 2026-06-02 23:06:55 +07:00
MythEclipse 0339ff75f9 There are no staged changes to commit. Stage some files first with git add, then I can help craft the commit message. 2026-06-02 23:06:18 +07:00
MythEclipse f10fa9aa88 feat(discord-gateway): export correctedModerationsTable from database schema 2026-06-02 23:05:37 +07:00
MythEclipse eb16c1f504 ``` 2026-06-02 23:05:33 +07:00
MythEclipse 0cd4f197e9 No staged changes found — the staging area is empty. Stage some files first with git add, then I can help craft the commit message. 2026-06-02 23:05:06 +07:00
MythEclipse 130f45a859 The git add -A command needs your approval to stage the modified file. Once staged, I'll craft the commit message. 2026-06-02 23:04:16 +07:00
MythEclipse a227c883e3 There are no staged changes to commit. The staging area is empty — stage some files first with git add and I can help craft the message. 2026-06-02 23:00:42 +07:00
MythEclipse aac80e569f perf(discord-gateway): parallelize all media downloads into single Promise.all batch 2026-06-02 22:59:33 +07:00
MythEclipse c18954a263 The staging area is empty — there are no staged changes to summarize. Stage some files first with git add and I can help craft the message. 2026-06-02 22:58:41 +07:00
MythEclipse 9f0d0d06ad If you meant to summarize the most recent (already committed) changes on this branch (41 commits ahead of origin/master), let me know and I can help craft a message for a squash or a summary instead. 2026-06-02 22:57:03 +07:00
MythEclipse ce2b789282 ``` 2026-06-02 22:55:32 +07:00