@helyx/bot 1.3.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/CHANGELOG.md +100 -28
  2. package/README.md +65 -11
  3. package/dist/channel-audit-configuration.d.ts +7 -0
  4. package/dist/channel-audit-configuration.js +40 -0
  5. package/dist/channel-audit-control.d.ts +14 -0
  6. package/dist/channel-audit-control.js +61 -0
  7. package/dist/channel-audit-permissions.d.ts +56 -0
  8. package/dist/channel-audit-permissions.js +417 -0
  9. package/dist/channel-audit-routes.d.ts +4 -0
  10. package/dist/channel-audit-routes.js +42 -0
  11. package/dist/cloud-connector.d.ts +11 -4
  12. package/dist/cloud-connector.js +54 -15
  13. package/dist/cloud-control-dispatcher.d.ts +8 -3
  14. package/dist/cloud-control-dispatcher.js +84 -4
  15. package/dist/control-errors.d.ts +12 -0
  16. package/dist/control-errors.js +32 -0
  17. package/dist/control-server-schemas.d.ts +84 -0
  18. package/dist/control-server-schemas.js +101 -0
  19. package/dist/control-server.d.ts +25 -8
  20. package/dist/control-server.js +101 -152
  21. package/dist/core-retention.d.ts +26 -0
  22. package/dist/core-retention.js +49 -0
  23. package/dist/creator-guild-join-service.d.ts +25 -0
  24. package/dist/creator-guild-join-service.js +218 -0
  25. package/dist/creator-invite-service.d.ts +37 -0
  26. package/dist/creator-invite-service.js +686 -0
  27. package/dist/creator-onboarding-control.d.ts +12 -0
  28. package/dist/creator-onboarding-control.js +65 -0
  29. package/dist/creator-onboarding-platform.d.ts +20 -0
  30. package/dist/creator-onboarding-platform.js +58 -0
  31. package/dist/dashboard-action-control.d.ts +2 -2
  32. package/dist/dashboard-action-control.js +2 -3
  33. package/dist/database-bootstrap.d.ts +36 -0
  34. package/dist/database-bootstrap.js +101 -0
  35. package/dist/developer-operations-module.d.ts +1 -0
  36. package/dist/developer-operations-module.js +34 -16
  37. package/dist/discord-channel-audit.d.ts +9 -0
  38. package/dist/discord-channel-audit.js +195 -0
  39. package/dist/discord-guild-health.d.ts +2 -2
  40. package/dist/discord-owned-message-service.d.ts +1 -0
  41. package/dist/discord-owned-message-service.js +3 -0
  42. package/dist/discord-role-safety.d.ts +4 -0
  43. package/dist/discord-role-safety.js +30 -0
  44. package/dist/events.d.ts +2 -0
  45. package/dist/events.js +5 -20
  46. package/dist/guild-command-read-service.d.ts +8 -3
  47. package/dist/guild-command-read-service.js +14 -7
  48. package/dist/guild-command-release.d.ts +15 -8
  49. package/dist/guild-command-release.js +10 -3
  50. package/dist/guild-command-worker.d.ts +17 -4
  51. package/dist/guild-command-worker.js +17 -6
  52. package/dist/guilds.d.ts +24 -3
  53. package/dist/guilds.js +185 -64
  54. package/dist/hosted-server-moderation.js +10 -4
  55. package/dist/index.d.ts +1 -0
  56. package/dist/index.js +200 -82
  57. package/dist/interactions.js +16 -3
  58. package/dist/module-configuration.d.ts +1 -1
  59. package/dist/module-configuration.js +5 -2
  60. package/dist/module-logging.d.ts +8 -3
  61. package/dist/module-logging.js +13 -7
  62. package/dist/modules.d.ts +1 -0
  63. package/dist/modules.js +8 -1
  64. package/dist/mysql-runtime-persistence.d.ts +46 -0
  65. package/dist/mysql-runtime-persistence.js +91 -0
  66. package/dist/oauth-module.js +2 -2
  67. package/dist/oauth-service.d.ts +7 -0
  68. package/dist/oauth-service.js +3 -0
  69. package/dist/scheduled-task-runner.d.ts +9 -85
  70. package/dist/scheduled-task-runner.js +1 -1
  71. package/dist/shard-contracts.d.ts +222 -0
  72. package/dist/shard-contracts.js +52 -1
  73. package/dist/shard-router.d.ts +4 -1
  74. package/dist/shard-router.js +19 -0
  75. package/dist/shard-supervisor.js +43 -9
  76. package/dist/shard-worker.d.ts +5 -2
  77. package/dist/shard-worker.js +41 -5
  78. package/dist/supervisor-cloud-directory.d.ts +9 -3
  79. package/dist/supervisor-cloud-directory.js +8 -12
  80. package/dist/trivia-data-provider.d.ts +11 -0
  81. package/dist/trivia-data-provider.js +46 -26
  82. package/dist/verification-service.d.ts +2 -2
  83. package/dist/verification-service.js +6 -3
  84. package/documentation/README.md +5 -3
  85. package/documentation/examples/.env.example +15 -11
  86. package/documentation/guides/getting-started.md +29 -12
  87. package/documentation/guides/privacy-and-support.md +6 -5
  88. package/documentation/guides/self-hosting.md +16 -11
  89. package/documentation/modules/auto-moderation.md +7 -5
  90. package/documentation/modules/building-a-module.md +48 -2
  91. package/documentation/modules/moderation.md +5 -5
  92. package/documentation/modules/publishing-a-module.md +6 -4
  93. package/documentation/modules/testing-a-module.md +39 -4
  94. package/documentation/reference/environment.md +43 -9
  95. package/documentation/runbooks/backup-and-recovery.md +26 -7
  96. package/documentation/runbooks/installation-and-upgrades.md +97 -27
  97. package/package.json +20 -16
@@ -10,7 +10,8 @@ DISCORD_CLIENT_ID=12345678901234567
10
10
  # requires message content and it is enabled in the Discord developer portal.
11
11
  HELYX_MESSAGE_CONTENT_ENABLED=false
12
12
  # Enhanced Auto Moderation stays inside this bot process. One worker is the
13
- # recommended default; increase only after measuring local CPU and memory.
13
+ # recommended default (range 1-4); increase only after measuring CPU and memory.
14
+ # Hosted scanning uses the separate Helyx Ecko service, not these settings.
14
15
  HELYX_AUTOMOD_EMBEDDED_WORKERS=1
15
16
  # Optional conservative queue overrides (hard ceilings: 5000 items, 64 MiB,
16
17
  # 100 items per server). Defaults are used when these remain commented.
@@ -18,13 +19,19 @@ HELYX_AUTOMOD_EMBEDDED_WORKERS=1
18
19
  # HELYX_AUTOMOD_EMBEDDED_QUEUE_BYTES=67108864
19
20
  # HELYX_AUTOMOD_EMBEDDED_QUEUE_ITEMS_PER_GUILD=100
20
21
  # HELYX_AUTOMOD_EMBEDDED_REFRESH_SECONDS=300
21
- # Enable only when member inspection modules are loaded and the Discord Server
22
- # Members Intent is enabled in the Discord developer portal.
22
+ # Enable for loaded member workflows such as Welcome, Access Control or Levels,
23
+ # with Server Members Intent also enabled in the Discord developer portal.
23
24
  HELYX_GUILD_MEMBERS_ENABLED=false
24
25
  # Database
25
26
  # Docker: keep the URL. Direct Node.js/managed hosting: use your provider URL.
27
+ DATABASE_ENGINE=postgresql
26
28
  DATABASE_URL=postgresql://database:5432/helyx
27
29
  DATABASE_SSL=disable
30
+ # Self-host startup applies pending migrations automatically (the default).
31
+ # Hosted-only inspect mode is not a self-host setting; leave this commented.
32
+ # HELYX_DATABASE_STARTUP_MODE=apply
33
+ # Match your provider: disable=no TLS; require=TLS without certificate
34
+ # verification; verify-full=TLS with certificate verification.
28
35
 
29
36
  # Included Docker database — both password values must match.
30
37
  PGUSER=helyx
@@ -51,8 +58,8 @@ LOG_LEVEL=info
51
58
  # SHARDING: OFF BY DEFAULT
52
59
 
53
60
  # `off` is the compatible self-host default. Keep shard-only values commented
54
- # in this mode; an empty value is still rejected as configured. Advanced local
55
- # self-hosting may use `auto` to obtain Discord's recommendation under one
61
+ # in this mode; an empty value is still rejected as configured. MySQL must stay
62
+ # off. Advanced PostgreSQL self-hosting may use `auto` under one
56
63
  # supervisor, or `fixed` with a deliberate total count. Local mode never needs
57
64
  # Redis. Coordinated multi-host self-hosting is outside the first release.
58
65
  HELYX_SHARD_MODE=off
@@ -80,18 +87,15 @@ HELYX_SHARD_MODE=off
80
87
  HELYX_HOSTED_MODERATION_ENABLED=false
81
88
 
82
89
  # Guild command writes remain off until explicitly enabled for known guild IDs.
90
+ # For enabled-module server commands, set writes=true, retain allowlist scope,
91
+ # add comma-separated Discord server IDs below, and use global mode platform-only.
92
+ # See README.md before changing these defaults. Legacy mode still allows globals.
83
93
  HELYX_GUILD_COMMAND_WRITES_ENABLED=false
84
94
  HELYX_GUILD_COMMAND_WRITE_SCOPE=allowlist
85
95
  # HELYX_GUILD_COMMAND_RELEASE_ID=
86
96
  HELYX_GLOBAL_COMMAND_MODE=legacy
87
97
  # HELYX_GUILD_COMMAND_WRITE_GUILD_IDS=
88
98
 
89
- # Privacy tooling ships with self-hosted Helyx but stays disabled until the
90
- # dedicated least-privilege executor connection has been configured.
91
- HELYX_PRIVACY_ENABLED=false
92
- # HELYX_PRIVACY_EXECUTOR_DATABASE_URL=<dedicated-privacy-executor-postgresql-url>
93
- # HELYX_PRIVACY_EXECUTOR_DATABASE_SSL=disable
94
-
95
99
  # Alternative Cloud Connect enrolment — the Discord command is preferred
96
100
  # HELYX_CLOUD_ENROLMENT_TOKEN=replace-with-a-short-lived-enrolment-code
97
101
  # HELYX_CLOUD_ENROLMENT_FILE=./helyx.cloud-enrolment.json
@@ -10,9 +10,9 @@ configuration and prove one module works in a private Discord server.
10
10
 
11
11
  ## Requirements
12
12
 
13
- - Node.js 24 or 26 and npm 11 or later.
13
+ - Node.js `>=24 <27` and npm 11 or later for generation and direct operation.
14
14
  - A Discord application and bot token.
15
- - PostgreSQL with a database you can back up and restore.
15
+ - A supported PostgreSQL or MySQL-compatible database you can back up and restore.
16
16
  - Permission to install the bot in the Discord servers you manage.
17
17
 
18
18
  Keep the bot token, database credentials, encryption keys, and control secrets
@@ -21,8 +21,8 @@ outside source control.
21
21
  ## Create the project
22
22
 
23
23
  The simplest path is to sign in at
24
- [app.helyx.gg/self-host](https://app.helyx.gg/self-host), choose the Live
25
- modules you need and download a complete starter ZIP. Extract it into a new
24
+ [app.helyx.gg/self-host](https://app.helyx.gg/self-host), choose the database
25
+ engine and Live modules you need, then download a complete starter ZIP. Extract it into a new
26
26
  private directory and read its generated `README.md`.
27
27
 
28
28
  For scripted generation, download a build manifest from the same builder and
@@ -34,9 +34,20 @@ cd helyx
34
34
  npm run setup
35
35
  ```
36
36
 
37
- `helyx setup` creates `.env` from `.env.example` only when `.env` does not
38
- already exist. Edit the required Discord and database values before continuing.
39
- See the [environment reference](../reference/environment.md).
37
+ `helyx setup` creates `.env` from `.env.example` when needed and fills a missing,
38
+ blank or example data-encryption key. It preserves other existing configuration
39
+ and a non-placeholder key. Edit the required Discord and database values before
40
+ continuing. Direct Node.js users must replace the Docker-only `database`
41
+ hostname with their reachable database address. See the
42
+ [environment reference](../reference/environment.md).
43
+
44
+ Choose the generated README's Node.js, Docker Compose or managed-hosting path
45
+ before validation. Managed hosts can supply variables without `.env`; generate
46
+ and securely retain the required key once. Docker users build the image and run
47
+ doctor inside Compose, as described in the
48
+ [installation runbook](../runbooks/installation-and-upgrades.md#run-doctor-in-the-right-environment).
49
+ The generated project uses compiled packages, so direct operation needs no
50
+ source build command.
40
51
 
41
52
  ## Validate before Discord sign-in
42
53
 
@@ -44,9 +55,12 @@ See the [environment reference](../reference/environment.md).
44
55
  npm run doctor
45
56
  ```
46
57
 
47
- The doctor checks configuration, PostgreSQL connectivity, migration history,
48
- and installed module metadata without logging in to Discord or changing the
49
- database. Correct every reported error before starting.
58
+ For direct Node.js, doctor checks configuration, selected-database connectivity,
59
+ core migration history and installed module metadata without logging in to
60
+ Discord or changing the database. It inspects module migrations once core
61
+ migrations have no pending entries. Pending migrations on a new database are
62
+ expected; startup applies them and probes server capabilities. Correct every
63
+ reported error before starting.
50
64
 
51
65
  ## Start Helyx
52
66
 
@@ -54,6 +68,9 @@ database. Correct every reported error before starting.
54
68
  npm start
55
69
  ```
56
70
 
71
+ Use this command for direct Node.js. Docker users follow the generated
72
+ Compose start command; managed hosts use their configured `npm start` process.
73
+
57
74
  For a long-running host, use the service or container supervision provided by
58
75
  your operating system or hosting platform. Configure automatic restarts with a
59
76
  bounded delay, retain logs without secrets, and arrange database backups before
@@ -77,9 +94,9 @@ separate actions. Installed customer modules start disabled.
77
94
 
78
95
  ## Troubleshooting
79
96
 
80
- ### Doctor cannot reach PostgreSQL
97
+ ### Doctor cannot reach the database
81
98
 
82
- Check the connection URL, credentials, network allowlist and `DATABASE_SSL`
99
+ Check `DATABASE_ENGINE`, the connection URL, credentials, network allowlist and `DATABASE_SSL`
83
100
  against the provider's instructions. Do not paste the URL into a support
84
101
  request.
85
102
 
@@ -6,7 +6,7 @@ route a request to the correct owner and ask for help without exposing secrets.
6
6
  ## Identify who controls the record
7
7
 
8
8
  - **Local Helyx Self-Hosted data:** the deployment owner controls the local
9
- PostgreSQL database, module records, logs and backups.
9
+ PostgreSQL or MySQL-compatible database, module records, logs and backups.
10
10
  - **Cloud Connect and Helyx account data:** Helyx controls the bounded hosted
11
11
  installation, session, support and connector records it receives.
12
12
  - **Discord data:** Discord controls platform messages, roles, channels and
@@ -31,9 +31,10 @@ automatically reach local-only records.
31
31
  6. Record the outcome without copying unnecessary personal data into support
32
32
  logs.
33
33
 
34
- Self-host privacy tooling ships disabled until its dedicated least-privilege
35
- executor connection is configured. Do not grant the normal bot or a support
36
- account unrestricted database access as a shortcut.
34
+ The Helyx-hosted **Request my data** export does not read the self-hosted
35
+ database. Self-host operators must handle local-only requests through their
36
+ own access and retention process. Do not grant a support account unrestricted
37
+ database access as a shortcut.
37
38
 
38
39
  ## Use the Helyx Privacy Centre
39
40
 
@@ -70,7 +71,7 @@ administration remain outside the normal generated-project support boundary.
70
71
  ### The central export does not contain a local record
71
72
 
72
73
  This is expected when the record exists only in the deployment owner's
73
- PostgreSQL database. Contact that owner and follow the local request process.
74
+ selected database. Contact that owner and follow the local request process.
74
75
 
75
76
  ### A support reply asks for more evidence
76
77
 
@@ -1,13 +1,14 @@
1
1
  # Self-hosting responsibilities
2
2
 
3
3
  Self-hosting gives you control of the Helyx runtime and its data. It also makes
4
- you responsible for the host, PostgreSQL, Discord credentials, environment
4
+ you responsible for the host, selected database, Discord credentials, environment
5
5
  configuration, updates, monitoring, backups, and recovery testing.
6
6
 
7
7
  ## Supported shape
8
8
 
9
- A normal installation contains one generated Helyx project, one PostgreSQL
10
- database, the reviewed core packages, and independently selected modules. Keep
9
+ A normal installation contains one generated Helyx project, one PostgreSQL or
10
+ supported MySQL-compatible database, the reviewed core packages, and
11
+ independently selected modules. Keep
11
12
  module boundaries intact: a module must be installable, configurable, testable,
12
13
  and removable without relying on unrelated module behaviour.
13
14
 
@@ -26,7 +27,7 @@ installation.
26
27
  ### Enhanced Auto Moderation resources
27
28
 
28
29
  Enhanced Auto Moderation remains inside the existing bot process and uses the
29
- installation's existing PostgreSQL database. It does not require Helyx Ecko,
30
+ installation's selected database. It does not require Helyx Ecko,
30
31
  Redis, another bot, another database, a public endpoint or a Premium heartbeat.
31
32
  Standard mode starts no scanning worker.
32
33
 
@@ -39,7 +40,7 @@ coverage; it does not make unsafe actions on delayed content. Use `npm run docto
39
40
  after environment changes and the dashboard module-health view for diagnosis.
40
41
 
41
42
  Every implemented catalogue entry carries a manifest-backed deployment label
42
- and credential-risk label. A planned entry without a canonical v0.4 manifest
43
+ and credential-risk label. A planned entry without a classified supported manifest
43
44
  is explicitly `unclassified`; that label makes no promise about its future
44
45
  deployment support and it cannot be selected. The builder accepts only Live
45
46
  modules whose
@@ -56,7 +57,7 @@ downloaded manifest.
56
57
  deployment.
57
58
  - Rotate a Discord token or control secret if it may have been exposed.
58
59
  - Do not paste secret values into logs, issues, screenshots, or support chats.
59
- - Limit network access to PostgreSQL and private control endpoints.
60
+ - Limit network access to the database and private control endpoints.
60
61
 
61
62
  ## Operating baseline
62
63
 
@@ -64,11 +65,13 @@ downloaded manifest.
64
65
  - Watch process health, database capacity, command deployment errors, and module
65
66
  health. When Enhanced Auto Moderation is active, also watch CPU, memory,
66
67
  scanner queue pressure and Standard-fallback guidance.
67
- - Back up both PostgreSQL and the environment or key material needed to decrypt
68
+ - Back up both the selected database and the environment or key material needed to decrypt
68
69
  its records.
69
70
  - Test recovery in a disposable environment.
70
71
  - Apply compatible releases as one reviewed set; do not upgrade internal Helyx
71
- packages independently.
72
+ packages independently. Check the
73
+ [fresh-install release boundary](../runbooks/installation-and-upgrades.md#check-the-release-boundary-first)
74
+ before using the updater on an existing database.
72
75
 
73
76
  Cloud Connect is optional. Enabling it does not transfer responsibility for the
74
77
  self-hosted process, database, secrets, or backups to Helyx.
@@ -97,7 +100,7 @@ must remain entirely local.
97
100
  1. Prove `npm run doctor` from the production environment.
98
101
  2. Test one stateful module in a private server.
99
102
  3. Restart the process and confirm settings remain available.
100
- 4. Create and test a PostgreSQL restore in a disposable environment.
103
+ 4. Create and test a restore of the selected database in a disposable environment.
101
104
  5. Record package versions, log access, monitoring and the responsible owner.
102
105
  6. Document how local data access, correction, restriction and deletion will be
103
106
  handled.
@@ -113,8 +116,10 @@ fresh one-use code.
113
116
  ### A hosting provider cannot run the starter
114
117
 
115
118
  The provider must support the release's Node.js and npm versions, run
116
- `npm start`, preserve protected environment values and reach PostgreSQL. A
117
- provider that cannot meet those requirements is not a supported runtime path.
119
+ `npm start`, preserve protected environment values and reach the selected
120
+ database. MySQL-compatible deployments must also support unsharded operation
121
+ with `HELYX_SHARD_MODE=off`. A provider that cannot meet those requirements is
122
+ not a supported runtime path.
118
123
 
119
124
  ## Related guides
120
125
 
@@ -1,10 +1,10 @@
1
1
  # Auto Moderation module
2
2
 
3
- Auto Moderation is an unpublished Testing module that manages Helyx-owned Discord Auto Moderation rules and optional Enhanced matching. It supports Hosted and Self-Hosted Helyx, but version `1.0.0` must be explicitly included in a reviewed test composition and is not available from the public npm catalogue.
3
+ Auto Moderation is a published module that manages Helyx-owned Discord Auto Moderation rules and optional Enhanced matching. It supports Hosted and Self-Hosted Helyx; include it in the selected self-host module composition before enabling its features.
4
4
 
5
5
  ## Supported Self-Hosted shape
6
6
 
7
- Use the same Helyx bot process and PostgreSQL database as the rest of the installation. Standard mode starts no content-scanning worker. Enhanced starts a bounded worker pool inside the bot process. Self-hosters do not deploy Helyx Ecko, Redis, a second bot connection or any Helyx-hosted scanner.
7
+ Use the same Helyx bot process and configured PostgreSQL or MySQL-compatible database as the rest of the installation. Standard mode starts no content-scanning worker. Enhanced starts a bounded worker pool inside the bot process. Self-hosters do not deploy Helyx Ecko, Redis, a second bot connection or any Helyx-hosted scanner.
8
8
 
9
9
  The matching engine is the deliberate `@helyx/module-automod/engine` package export. Hosted Ecko and the embedded worker use the same versioned engine and result contract; module code remains free of Discord.js, database, network and environment access.
10
10
 
@@ -28,7 +28,7 @@ Size the bot for actual Enhanced traffic and begin with Balanced confidence. Wat
28
28
 
29
29
  ## Data and privacy
30
30
 
31
- PostgreSQL stores logical rules, Discord mapping/fingerprint, structural action receipts, durable enforcement claims and anonymous daily counts. It never stores matched content, matched terms, bodies, attachments, embeds or transient evidence. Native receipts expire after 90 days; settled claim/count history is bounded to 365 days.
31
+ The selected database stores logical rules, Discord mapping/fingerprint, structural action receipts, durable enforcement claims and anonymous daily counts. It never stores matched content, matched terms, bodies, attachments, embeds or transient evidence. Native receipts expire after 90 days; settled claim/count history is bounded to 365 days.
32
32
 
33
33
  Discord native alerts and optional Moderation violation-thread evidence are Discord-owned content. Restrict those channels separately. Logging, Audit, metrics and traces must remain content-free.
34
34
 
@@ -40,8 +40,10 @@ The module is unhealthy when required records, configuration, installation, Disc
40
40
 
41
41
  ## Verify a test installation
42
42
 
43
- 1. Confirm the private Testing module is present in the test catalogue.
44
- 2. Apply migrations with the migration role and start the bot with Standard.
43
+ 1. Confirm the Live Auto Moderation module is selected in the installation's catalogue.
44
+ 2. Start the bot with Standard and verify its engine-matched module migrations
45
+ and health. Normal startup applies pending supported migrations; do not run
46
+ SQL manually or rewrite receipts to bypass a failure.
45
47
  3. Publish one fictional native rule and verify block/alert plus a content-free receipt.
46
48
  4. Enable Message Content, switch to Enhanced and test one obfuscated phrase plus one safe near-match.
47
49
  5. Restart the bot and confirm snapshots rebuild without retained message content.
@@ -4,6 +4,12 @@ Start from the published `@helyx/module-example` package. It contains a
4
4
  self-contained TypeScript project, manifest, source, tests, and packaging
5
5
  allowlist that can be copied into a new repository or workspace.
6
6
 
7
+ The current Example demonstrates the supported v0.4 compatibility contract.
8
+ New modules must adopt the complete v0.5 contract described below; changing only
9
+ `manifestVersion` is insufficient. Install dependencies in the copied project
10
+ before building: use `npm install` if it has no lockfile, then retain the generated
11
+ lockfile and use `npm ci` for repeatable installations.
12
+
7
13
  ## Before you begin
8
14
 
9
15
  - Use Node.js `>=24 <27` and npm `>=11`.
@@ -20,7 +26,8 @@ Every module needs:
20
26
  - a Helyx module manifest parsed by `@helyx/module-manifest`;
21
27
  - a default JavaScript export created with `defineModule` from `@helyx/sdk`;
22
28
  - explicit `start` and `stop` lifecycle functions;
23
- - a privacy declaration and provider, including when no personal data is held;
29
+ - an explicit privacy declaration and matching executable provider, including
30
+ a zero-record provider when no personal data is retained;
24
31
  - compiled JavaScript and declarations matching the package exports;
25
32
  - tests for manifest parity, loading, lifecycle behaviour, and each declared
26
33
  contribution.
@@ -32,12 +39,20 @@ them.
32
39
 
33
40
  ## Deployment and credential policy
34
41
 
35
- Use manifest version `0.4` and make deployment eligibility explicit:
42
+ Use manifest version `0.5` and make deployment eligibility explicit:
36
43
 
37
44
  - `deploymentSupport` is `hosted`, `self-hosted` or `both`;
38
45
  - `credentialRisk` is `none`, `low`, `medium`, `high` or `very-high`; and
39
46
  - `deploymentReason` is a short internal explanation with no secret values.
40
47
 
48
+ Declare the module classification, `features` and `permissionOperations` too.
49
+ A module without reviewed features uses an empty `features` array. A v0.5
50
+ dashboard needs a declared `settingsMutationPermissionId`; settings need explicit
51
+ `supportVisibility`, and actions need declared permission IDs. Keep executable
52
+ permission defaults and handlers aligned with those declarations. Refer to the
53
+ installed `@helyx/module-manifest` README and exported schema rather than copying
54
+ an older manifest and changing its version string.
55
+
41
56
  The classification is a release decision, not a runtime guess. A hosted-only
42
57
  manifest is rejected from self-host selection and generated projects. A
43
58
  self-host-only manifest is rejected from hosted composition. The separate
@@ -49,6 +64,25 @@ must not require a provider credential or separate integration service. If a
49
64
  future design changes that boundary, review the deployment and credential risk
50
65
  before implementation; do not weaken the manifest to make composition pass.
51
66
 
67
+ ## Database support
68
+
69
+ Declare the supported `databaseEngines` in the manifest, using `postgresql` and
70
+ `mysql`. Do not advertise an engine before its migrations and runtime behaviour
71
+ are supported. Deployment eligibility and database support are separate: adding
72
+ MySQL support does not make a hosted-only module eligible for self-hosting.
73
+
74
+ Use SDK database/record capabilities for portable runtime work, not private
75
+ application repositories or a direct driver embedded in each module. Keep
76
+ module-owned PostgreSQL migrations in `migrations/` and the MySQL equivalents
77
+ in `migrations-mysql/`. Preserve the same field meanings, nullability and
78
+ returned JavaScript types; equivalent SQL does not require identical SQL syntax.
79
+ Keep engine-specific implementation details behind the adapter contract.
80
+
81
+ Do not rewrite an already-applied migration. A fresh unpublished baseline can
82
+ be consolidated only through the agreed release process, with clean/repeat
83
+ installation evidence. See the database-backed section of
84
+ [testing a module](testing-a-module.md) for ownership and selective test gates.
85
+
52
86
  ## Commands and dashboard policy
53
87
 
54
88
  Normal customer-module commands use
@@ -78,6 +112,18 @@ repository-relative configuration. Depend only on published packages with
78
112
  compatible version ranges. Module behaviour must fail clearly when an optional
79
113
  external service is unavailable.
80
114
 
115
+ Keep `start` and `stop` even when they simply return resolved promises. The
116
+ `health` hook is optional; implement it when there is meaningful owned runtime
117
+ state or a dependency to report. A zero-personal-data module declares
118
+ `containsPersonalData: false`, a provider version and an empty collection list;
119
+ the bot loader still requires a matching executable provider. The Example leaves
120
+ that contribution unregistered, so compose its supplied privacy helper into
121
+ `defineModule` before a copied module is installed in the bot. Use
122
+ `getModulePrivacyDeclaration` and `createPrivacyProvider` from the SDK to keep the
123
+ provider identity, version and declaration in parity. The SDK supplies the
124
+ zero-data `not_applicable` outcomes. A personal-data module must implement access
125
+ and erasure for its retained records, including while disabled.
126
+
81
127
  See [testing a module](testing-a-module.md) before adding product behaviour.
82
128
 
83
129
  ## Related guides
@@ -1,10 +1,10 @@
1
1
  # Moderation module
2
2
 
3
- Moderation is an unpublished Testing module for accountable Discord staff actions. It supports Hosted and Self-Hosted Helyx, but version `1.0.0` must be explicitly included in a reviewed test composition and is not available from the public npm catalogue.
3
+ Moderation is a published module for accountable Discord staff actions. It supports Hosted and Self-Hosted Helyx; include it in the selected self-host module composition before enabling its features.
4
4
 
5
5
  ## Supported Self-Hosted shape
6
6
 
7
- Run the normal Helyx bot process and PostgreSQL only. Moderation needs no Redis, scanner service, Cloud Connect or Helyx-hosted dependency. Install its migrations through the normal reviewed module lifecycle; never run migration credentials in the bot process.
7
+ Run the normal Helyx bot process with the configured PostgreSQL or MySQL-compatible database adapter. Moderation needs no Redis, scanner service, Cloud Connect or Helyx-hosted dependency. Normal startup applies its engine-matched migrations through the reviewed module lifecycle. Supply only the database privileges needed by the supported installation procedure; do not give the bot an unrelated provider administrator account.
8
8
 
9
9
  ## Discord setup
10
10
 
@@ -22,7 +22,7 @@ Kick, ban, demotion, unban and timeouts longer than 24 hours require an actor-bo
22
22
 
23
23
  The module creates a pending numbered case and immutable attempt before changing Discord. An ambiguous outcome enters Review and must be reconciled from current Discord state; do not blindly repeat the action. Warning DMs and violation-thread delivery are secondary and cannot roll back a successful case.
24
24
 
25
- PostgreSQL stores case, action, identity, safe outcome and Discord-reference metadata. It does not store offending message bodies. Transient evidence can be copied directly to a Discord-owned private thread with mentions disabled and is never persisted or queued.
25
+ The selected database stores case, action, identity, safe outcome and Discord-reference metadata. It does not store offending message bodies. Transient evidence can be copied directly to a Discord-owned private thread with mentions disabled and is never persisted or queued.
26
26
 
27
27
  Settled retention is configurable from 30 to 730 days. Dashboard disassociation clears the subject and future repeat-count association while preserving an anonymous tombstone. It is not hard deletion or Privacy Service erasure.
28
28
 
@@ -32,8 +32,8 @@ Health is unhealthy while the module is stopped or a required platform boundary
32
32
 
33
33
  ## Verify a test installation
34
34
 
35
- 1. Confirm the module is private, Testing and explicitly selected in the test catalogue.
36
- 2. Apply the current database baseline and module migrations with the migration role.
35
+ 1. Confirm the Live Moderation module is selected in the installation's catalogue.
36
+ 2. Run doctor to check configuration, database access and migration history.
37
37
  3. Start the bot and verify module health.
38
38
  4. Test a warning, a confirmed high-impact action, a hierarchy rejection and a case history read with fictional accounts.
39
39
  5. Exercise channel inspection, one private violation thread, staff-control denial for the affected user and safe Close visibility.
@@ -3,8 +3,9 @@
3
3
  This checklist prepares a package for review. It does not authorize publishing
4
4
  to npm or adding a module to the official Helyx catalogue.
5
5
 
6
- 1. Choose a unique package name and keep the package version equal to the
7
- manifest version.
6
+ 1. Choose a unique package name and keep `package.json`'s `version` equal to
7
+ `manifest.json`'s package `version`. That value is separate from the manifest
8
+ schema's `manifestVersion`, which is `0.5` for new modules.
8
9
  2. Use compatible ranges for `@helyx/module-manifest` and `@helyx/sdk`.
9
10
  3. Compile to `dist/` and expose both a JavaScript default entry and a `.d.ts`
10
11
  declaration entry.
@@ -13,8 +14,9 @@ to npm or adding a module to the official Helyx catalogue.
13
14
  5. Include `manifest.json`, `README.md`, `CHANGELOG.md`, and the licence that
14
15
  applies to your code.
15
16
  6. Run the complete test suite and `npm pack --dry-run` from a clean checkout.
16
- 7. Extract the generated tarball into a temporary project and import its default
17
- export under a supported Node.js version.
17
+ 7. Run `npm pack` to create a local `.tgz` file; `--dry-run` does not create one.
18
+ Install that file in a temporary project and import its default export under
19
+ a supported Node.js version. This does not publish to npm.
18
20
  8. Search the packed file list for `.env`, credentials, private URLs, logs,
19
21
  dumps, tests with fixtures containing real data, and repository-only notes.
20
22
 
@@ -10,9 +10,11 @@ drifting away from executable contributions.
10
10
 
11
11
  ## Lifecycle
12
12
 
13
- Call `start`, `health`, and `stop` with a minimal SDK runtime context. Verify
14
- observable behaviour and make both lifecycle functions safe for the runtime to
15
- call. Do not start network listeners or timers at import time.
13
+ Call the required `start` and `stop` functions with a minimal SDK runtime context.
14
+ Test `health` only when the module supplies that optional hook. Verify observable
15
+ behaviour and make lifecycle functions safe for the runtime to call. No-op
16
+ lifecycle functions are valid when the module owns no runtime resources. Do not
17
+ start network listeners or timers at import time.
16
18
 
17
19
  ## Dashboard
18
20
 
@@ -41,12 +43,45 @@ stale command may still be visible during Discord reconciliation.
41
43
 
42
44
  ## Privacy and multi-worker behaviour
43
45
 
44
- Test the privacy declaration and executable provider together. A provider must
46
+ For a zero-personal-data module, verify the explicit declaration and empty
47
+ collection list together with its matching zero-record executable provider. The
48
+ bot loader requires that contribution for manifest v0.2 and later, even though
49
+ the Example source does not register it. Test provider identity, version and
50
+ declaration parity before bot installation. For a module that retains personal
51
+ data, test its declaration and executable provider together. A provider must
45
52
  find matching retained records even when its module is disabled, and a missing
46
53
  or failed provider must not be interpreted as an empty result. Stateful
47
54
  modules also test duplicate delivery, concurrent claims, retry, restart and
48
55
  stale-worker behaviour where those failures are possible.
49
56
 
57
+ ## Database-backed behaviour
58
+
59
+ Keep tests with the module that owns the behaviour. For a module supporting both
60
+ engines, use a shared, non-discovered `tests/database.contract.ts` and separate
61
+ `tests/database.postgresql.integration.test.ts` and
62
+ `tests/database.mysql.integration.test.ts` entry files. Adapter-specific tests
63
+ belong to that adapter, not to another module or a batch-named test file.
64
+
65
+ The shared contract should exercise important observable guarantees, such as a
66
+ successful write/read, a revision conflict, duplicate delivery or a fenced
67
+ refund. Do not copy every PostgreSQL SQL-text assertion into MySQL or repeat a
68
+ module's entire contract in the core adapter suite. Keep engine-specific checks
69
+ where the implementation genuinely differs, including MySQL interrupted-DDL
70
+ receipts and PostgreSQL transaction or legacy-migration behaviour.
71
+
72
+ Use a disposable test database on an explicitly authorised server. Integration
73
+ fixtures can drop their tables; never point them at an active bot installation.
74
+ Check clean and repeat migration application and the actual returned types:
75
+ numbers, booleans, arrays, dates and nullable values must satisfy the same SDK
76
+ contract on both engines. A MySQL-compatible server is accepted by the required
77
+ capabilities, not by its vendor name. Oracle MySQL and MariaDB are reference
78
+ gates, not an exhaustive compatibility promise.
79
+
80
+ In the Helyx workspace, PostgreSQL and MySQL integration files run in separate
81
+ `test:database:postgresql` and `test:database:mysql` suites. Run the narrow relevant suite first;
82
+ reserve whole-workspace validation for cross-cutting or release gates. Add a
83
+ test for a material unprotected guarantee, not merely because a file changed.
84
+
50
85
  ## Before packaging
51
86
 
52
87
  Run the module's build and test scripts, then inspect exactly what npm would
@@ -9,10 +9,18 @@ the comments in `.env.example` remain the version-matched field reference.
9
9
  ## Required values
10
10
 
11
11
  `DISCORD_TOKEN` is the bot token from the Discord developer portal.
12
- `DISCORD_CLIENT_ID` is the application's numeric ID. `DATABASE_URL` points to
13
- PostgreSQL; `DATABASE_SSL` must match the database provider. Docker users must
14
- also replace the example PostgreSQL password consistently in `PGPASSWORD` and
15
- `POSTGRES_PASSWORD`.
12
+ `DISCORD_CLIENT_ID` is the application's numeric ID. `DATABASE_ENGINE` accepts
13
+ `postgresql` or `mysql` and defaults to PostgreSQL when omitted. `DATABASE_URL`
14
+ must match the selected engine, and `DATABASE_SSL` must match the database
15
+ provider. PostgreSQL Docker users must also replace the example password
16
+ consistently in `PGPASSWORD` and `POSTGRES_PASSWORD`. The MySQL Compose starter
17
+ runs only the bot and connects to the external database in `DATABASE_URL`.
18
+
19
+ Percent-encode special characters in URL credentials. `DATABASE_SSL=disable`
20
+ uses no TLS; `require` encrypts without verifying the server certificate;
21
+ `verify-full` also verifies the certificate. Prefer `verify-full` for remote
22
+ connections when the provider's certificate is trusted. The MySQL template's
23
+ initial `require` value is not proof of that provider's requirements.
16
24
 
17
25
  ## Safe defaults
18
26
 
@@ -27,6 +35,23 @@ requirements are deliberately configured. An empty variable still counts as a
27
35
  configured value in many environments, so leave unused optional lines
28
36
  commented.
29
37
 
38
+ Enable privileged intents in the Discord Developer Portal as well as the bot
39
+ environment when required: Counting needs Message Content, Welcome and Access
40
+ Control need Guild Members, and Levels needs both. Access Control's Password
41
+ Entry also needs Message Content. The corresponding variables are
42
+ `HELYX_MESSAGE_CONTENT_ENABLED` and `HELYX_GUILD_MEMBERS_ENABLED`.
43
+
44
+ For enabled-module command builds in approved servers, set
45
+ `HELYX_GUILD_COMMAND_WRITES_ENABLED=true`, keep
46
+ `HELYX_GUILD_COMMAND_WRITE_SCOPE=allowlist`, and set
47
+ `HELYX_GUILD_COMMAND_WRITE_GUILD_IDS` to a non-empty comma-separated list of
48
+ Discord server IDs. Use `HELYX_GLOBAL_COMMAND_MODE=platform-only` to retain global
49
+ core/deployment commands while feature commands use per-server builds. Restart
50
+ after changing these values and check the dashboard command-build status. The
51
+ template's default `legacy` mode can still register compatible globals while
52
+ guild writes are disabled; it does not mean that every command is disabled.
53
+ Do not use the advanced `all` scope merely to bypass an allowlist error.
54
+
30
55
  `HELYX_AUTOMOD_EMBEDDED_WORKERS` controls only the in-process Self-Hosted
31
56
  Enhanced Auto Moderation pool. Keep the default of one unless local measurement
32
57
  justifies a value from two through four. Its queue settings may be lowered but
@@ -46,12 +71,19 @@ not a password reset.
46
71
 
47
72
  ## Verification
48
73
 
49
- After every environment change, run:
74
+ After every environment change, run doctor in the same environment that will
75
+ start the bot. For direct Node.js or a managed host console:
50
76
 
51
77
  ```sh
52
78
  npm run doctor
53
79
  ```
54
80
 
81
+ For Compose, build the bot image and run
82
+ `docker compose run --rm bot node node_modules/@helyx/cli/dist/cli.js doctor`
83
+ with its database reachable. Container-only hostnames such as `database` are not
84
+ host-shell addresses. See the
85
+ [runtime-specific steps](../runbooks/installation-and-upgrades.md#run-doctor-in-the-right-environment).
86
+
55
87
  Never include the real `.env` file in an npm package, container image layer,
56
88
  source archive, or support bundle.
57
89
 
@@ -63,11 +95,13 @@ An empty environment variable counts as configured in many hosts. Remove
63
95
  unused optional values instead of setting them to an empty string. Replace all
64
96
  required placeholders with real protected values.
65
97
 
66
- ### PostgreSQL works locally but not on the host
98
+ ### The database works locally but not on the host
67
99
 
68
- Check network access and `DATABASE_SSL` using the database provider's required
69
- mode. The Docker default is for the included private container network and must
70
- not be copied blindly to an Internet database.
100
+ Check that `DATABASE_ENGINE` matches `DATABASE_URL`, then check network access
101
+ and `DATABASE_SSL` using the database provider's required mode. The PostgreSQL
102
+ Docker default is for the included private container network and must not be
103
+ copied blindly to an Internet database. MySQL-compatible self-hosting requires
104
+ `HELYX_SHARD_MODE=off`.
71
105
 
72
106
  ### Encrypted records fail after deployment
73
107