Skip to content

all: correctness, performance, and refactoring pass - #311

Merged
ryanccn merged 4 commits into
mainfrom
61c5c5b6
Sep 6, 2026
Merged

ryanccn merged 4 commits into
mainfrom
61c5c5b6

Conversation

@ryanccn

@ryanccn ryanccn commented Sep 5, 2026

Copy link
Copy Markdown
Owner

Correctness

  • purge charged its budget for messages requested rather than deleted, so a filtered-out message silently cost a slot; now paginates with a before cursor and charges only actual deletions.
  • MessageUpdate wrote message content to Redis before checking the log exclusion list; the check now precedes the write.
  • Message handlers run under join! instead of try_join!, so one failing handler can no longer cancel a code expansion between sending and recording it.
  • Code expansion rejects inverted and out-of-bounds line ranges up front, and caps them at 256 lines.
  • Safe Browsing never matched http:// URLs: scheme stripping fell through to the unstripped string, so every plain-HTTP hash was computed with the scheme still attached.
  • Safe Browsing path expressions now follow the spec — anchored at the root with trailing slashes, capped at four — instead of suffix truncations that matched nothing the database stores.
  • fullHashes:find may return a 4–32 byte hash prefix; matching it required an exact 32-byte hash, silently dropping those results.
  • One unparseable URL no longer fails the scan for the whole message.
  • The Rice decoder sized its buffer from an unbounded wire value, panicked on a zero prefix size, and accepted trailing partial prefixes.
  • Safe Browsing update retries on checksum drift are bounded rather than looping forever.
  • dedent computes a real common prefix, leaving mismatched indentation alone.
  • A single failing guild no longer aborts the daily colour role rotation.

Performance

  • Safe Browsing prefixes are packed into one sorted allocation and looked up by binary search, replacing a Vec<Vec<u8>> alongside a HashSet holding a second copy of every prefix — roughly 10 MB and 200k allocations per list down to 1.2 MB and two.
  • Safe Browsing updates build the new prefix set from borrowed slices instead of deep-cloning the database, and checksum it without materialising a flattened copy.
  • sha256 returns [u8; 32] rather than allocating, and URL checks no longer allocate a key string per hash.
  • Autoreply patterns are compiled once per guild and cached, pruned to whatever the guild currently configures, instead of recompiling every pattern on every message.
  • Message edit and delete logging fetch the guild config and run the exclusion check once instead of twice; bulk deletes fetch once for the batch rather than per message.
  • Starboard deletion checks Redis before fetching the guild and channel, so an ordinary deletion costs no API calls.
  • ThreatType no longer allocates a String per serialisation.
  • Dropped rayon, now that the parallel scan it existed for is gone.
  • Intelligence checks the mention prefix before looking up the member, and skips the lookup entirely when no role allowlist is configured.
  • Starboard fetches the guild once per event instead of twice, and parses starboard_emojis once instead of once per reaction.
  • utils::truncate borrows instead of allocating on every call.
  • StorageKey builds one buffer instead of four allocations per key; wire format unchanged.
  • Analytics events dispatch in the background instead of blocking message handling.
  • Code expansion no longer materialises every fetched line to select a few.
  • Dropped an HTTP call in DM logging that re-derived an already-known fact.

Refactoring

  • ModerationAction replaces ~660 lines of duplicated scaffolding across ban, kick, timeout, purge_user, and warn, preserving the existing DM → log → action → reply ordering.
  • Five near-identical code expansion handlers collapse into expand_file + render_snippet; resolve's eight capture loops become one macro.
  • translate/translate_ephemeral and both code_expand commands share one implementation, differing only in how they defer.
  • Five analytics::send_* wrappers become one send_event.
  • log::is_excluded and is_excluded_message merge into one function taking an optional pre-fetched config.
  • rotate_color_role returns Option<RoleId> rather than a HashSet that never held more than one element.
  • The config interaction handler's ten match arms collapse to their differing assignments.
  • Removed dead commented-out honeypot code, a single-element Vec, shadowed imports, option_env! for an always-present CARGO_PKG_VERSION, and a needless clone of message content.
  • Safe Browsing prefix storage moves into a PrefixSet type, and update decoding into decode_removals and Additions.
  • Tests cover the spec's suffix/prefix expression examples, prefix set lookups, Rice round trips, and the autoreply cache.

ryanccn and others added 4 commits September 5, 2026 12:02
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ryanccn
ryanccn enabled auto-merge (squash) September 6, 2026 05:29
@ryanccn
ryanccn merged commit ec8fc41 into main Sep 6, 2026
13 checks passed
@ryanccn
ryanccn deleted the 61c5c5b6 branch September 13, 2026 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant