3.8 KiB
Decisions
This document records the main design decisions and their reasons.
ADR-1: Use the real client
Decision. Run the real Vesktop client. Do not use a third-party selfbot protocol library.
Reason. The popular selfbot libraries are archived or deprecated. Stale protocol emulation is a ban risk. The real client sends official traffic.
ADR-2: Validated capability layer
Decision. The core exposes a small, fixed action list. The core validates all input. The core returns structured errors. All logic lives in the external daemon.
Reason. The split gives three properties:
- The daemon cannot run arbitrary code in the client.
- A daemon bug cannot crash the client or send malformed data to Discord.
- Core patches stay small, so an upstream rebase is easy.
Consequence. A new capability needs a small core change. The action list is the contract.
ADR-3: CDP is a fallback, not the primary transport
Decision. The project validated control over Chrome DevTools Protocol. The primary transport is the validated core bridge.
Reason. CDP needs no Vesktop patch. However, CDP evaluates raw code in the page. It bypasses the core-side validation and rate limits. The project keeps the probe as a development tool.
Status. The primary transport is the validated core bridge. The CDP client and the probe stay in
poc/ as development tools.
ADR-4: No bespoke client
Decision. Do not write a new Electron shell for Discord.
Reason. Vesktop maintains the desktop integration for Vencord, for example settings, themes, quick CSS, and the native plugin bridge. A bespoke shell must reimplement that surface. Vesktop already does this work.
Consequence. Keep the patch small and isolated. This approach is cheaper than a new shell.
ADR-5: Two pacing layers
Decision. The daemon paces all commands with a random delay of 500 to 2800 ms. The core adds a hard limit of 500 ms between sends and 30 sends per minute.
Reason. The daemon policy looks human. The core limit is a safety net. A daemon bug cannot cause a send flood.
ADR-6: Pin the profile directory
Decision. DATA_DIR is $VENCORD_USER_DATA_DIR, else $VESKSLOP_DATA_DIR, else
<appData>/veskslop.
Reason. The Discord session lives in the Electron profile. An app rename or a version update must not move the profile. A stable path keeps the login.
ADR-7: Separate token file
Decision. The QR tool writes the account token to a file. The client seeds the token at startup when no session exists.
Reason. The token file survives a profile reset. It also survives a change in the Discord storage format. The recovery path is one QR scan.
ADR-8: Trigger log limits
Decision. Keep the last 100 triggers from trusted users and the last 30 triggers from untrusted users.
Reason. The limits keep memory small. The trusted limit is larger because those messages matter more.
ADR-9: One live test target
Decision. The only permitted live-send target is user zzib (177117296140091393).
Reason. Tests must not send messages to other users. DMs to zzib are safe and permitted.
ADR-10: Poll command
Decision. The poll command accepts | or // as separators, an optional quoted question, and
many reactions per user. A bare command shows help.
Reason. The pipe is hard to type on some keyboards. // is safe in Discord markdown when it has
whitespace on both sides, so URLs stay in one piece. Many selections match how people use polls in
group chats. A bare command gives the user the syntax without a failed poll.
ADR-11: Persistent action log
Decision. Write triggers, continuations, commands, replies, and errors to a rotating JSONL file. Redact token-shaped strings before the write.
Reason. The in-memory trigger log resets at restart. The action log gives a durable audit trail without storing raw credentials.