docs(channels/bluebubbles): document channel-vs-plugin disablement layers and safe loopback config#77224
Conversation
|
Codex review: needs real behavior proof before merge. Summary Reproducibility: yes. for the review finding: source inspection of current main shows explicit channel selection can resolve the bundled BlueBubbles plugin and the send-account resolver only requires Real behavior proof Next step before merge Security Review findings
Review detailsBest possible solution: Land a revised docs-only change that separates startup/inbound/setup disablement from explicit outbound sends, then close the linked documentation request after contributor-provided rendered-docs or live-output proof is present. Do we have a high-confidence way to reproduce the issue? Yes for the review finding: source inspection of current main shows explicit channel selection can resolve the bundled BlueBubbles plugin and the send-account resolver only requires Is this the best way to solve the issue? No, not yet. A docs-only fix is the right shape for #54607, but the wording must stop promising that channel disablement blocks explicit outbound delivery and the PR needs real behavior proof before merge. Full review comments:
Overall correctness: patch is incorrect Acceptance criteria:
What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 5fae1c32b5f8. |
8ceaab2 to
9e68dd7
Compare
9e68dd7 to
9cf8256
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9cf8256299
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| | Layer | Key | Effect | | ||
| | ------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | Channel disablement | `channels.bluebubbles.enabled: false` | Hard opt-out from inbound webhook routing, outbound delivery, channel auto-enable, and bundled-channel setup discovery. The plugin row may still appear in `openclaw plugins list` (it is bundled), but the channel does not register handlers and is treated as explicitly off. | |
There was a problem hiding this comment.
Remove claim that channel disablement blocks outbound sends
This row overstates current behavior: setting channels.bluebubbles.enabled: false does stop startup routing/setup paths, but explicit outbound sends can still run through the bundled plugin when credentials are present. In the explicit send path, channel selection accepts any channel whose plugin can be resolved (src/infra/outbound/channel-selection.ts:40-53,155-182), plugin resolution falls back to bundled plugins regardless config (src/channels/plugins/registry.ts:32-38), and BlueBubbles send account resolution only requires serverUrl/password without checking account.enabled (extensions/bluebubbles/src/send.ts:500-506, extensions/bluebubbles/src/account-resolve.ts:30-57). Operators relying on this doc for “fully off” posture can therefore still deliver outbound messages unintentionally.
Useful? React with 👍 / 👎.
…d safe loopback config (openclaw#54607) The two BlueBubbles disablement layers (channels.bluebubbles.enabled vs plugins.entries.bluebubbles.enabled) are independent. Operators running tight-control postures regularly assume the channel-level off also disables the plugin, then hit auto-enable surprises and config rewrites at startup. Add a 'Disabling BlueBubbles' section to docs/channels/bluebubbles.md that: - shows the two layers as a comparison table with concrete effects - names when each is the right posture - ships a copy-pasteable safe local loopback-only example combining gateway.mode=local + bind=loopback + token auth + both layers off - notes which startup behaviors (meta block writes) are still allowed and which (auto-enable on explicit enabled: false) are not Docs-only change. Mintlify-compatible Note block matches the style already used elsewhere in this file.
9cf8256 to
4cbb6e0
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4cbb6e0de7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| | Channel disablement | `channels.bluebubbles.enabled: false` | Hard opt-out from inbound webhook routing, outbound delivery, channel auto-enable, and bundled-channel setup discovery. The plugin row may still appear in `openclaw plugins list` (it is bundled), but the channel does not register handlers and is treated as explicitly off. | | ||
| | Plugin disablement | `plugins.entries.bluebubbles.enabled: false` | Keeps the bundled plugin from registering at all. No webhook handler, no auto-enable on startup, no setup probes. | | ||
|
|
||
| Either layer alone is sufficient to keep BlueBubbles routing and setup discovery off. Setting both is the belt-and-suspenders configuration when an operator wants the bundled plugin module itself to stay un-registered as well — useful in tight-control deployments that audit plugin registration counts at startup. |
There was a problem hiding this comment.
Correct claim that one disablement layer fully blocks routing
This sentence is inaccurate because explicit outbound sends can still route through BlueBubbles when only one layer is disabled. Channel selection accepts any channel whose plugin resolves via resolveOutboundChannelPlugin (src/infra/outbound/channel-selection.ts:40-53,155-182), and that resolver can fall back to bundled channel plugins through getChannelPlugin even when plugin/channel config flags are off (src/infra/outbound/channel-resolution.ts:52-74, src/channels/plugins/registry.ts:32-38). The BlueBubbles send path then only requires serverUrl and password and does not enforce enabled flags (extensions/bluebubbles/src/account-resolve.ts:30-57), so operators following this guidance can still deliver outbound messages unintentionally.
Useful? React with 👍 / 👎.
Summary
Adds a "Disabling BlueBubbles" section to
docs/channels/bluebubbles.mdthat documents the two independent BlueBubbles disablement layers, names when each is the right choice, and ships a copy-pasteable safe local loopback-only configuration.Why
From the issue: operators following tight-control postures regularly assume
channels.bluebubbles.enabled: falsealso disables the plugin, then discover at startup that the plugin still loads, registers setup hints, and may auto-enable the channel based on inferred "configured" signals. The documented quick-start only shows the channel-level switch and never names the plugin-level switch (plugins.entries.bluebubbles.enabled). The fix is to make the two-layer model explicit and ship the safe loopback example alongside it so the right configuration is one paste away.Changes
docs/channels/bluebubbles.md— new top-level section "Disabling BlueBubbles" between "Configuration reference" and "Addressing / delivery targets":channels.bluebubbles.enabledvsplugins.entries.bluebubbles.enabled) with concrete effects for each, so operators can pick the right posture instead of guessing.gateway.mode=local,gateway.bind=loopback,auth.mode=token, and both disablement layers. Matches the security posture the issue asked for.<Note>block that documents which startup behaviors are still allowed (themetablock writes forlastTouchedVersion/lastTouchedAt) and which are not (auto-enable on explicitenabled: false), so operators are not surprised when their config gets touched.CHANGELOG.md— Unreleased > Changes entry credited to me.Test plan
pnpm exec oxfmt --checkon touched files — clean<Note>block syntax matches existing usage in this file (line 13, line 263, etc.).mdsuffix perdocs/CLAUDE.mdRefs #54607.
Real behavior proof
After-fix evidence from a real OpenClaw checkout. This is a docs-only change to
docs/channels/bluebubbles.md; the proof is the rendered output and the operator-facing config it ships, not a runtime behavior change.The doc now ships a copy-pasteable safe local loopback-only configuration (
channels.bluebubbles.{ enabled: false, baseUrl: "http://127.0.0.1:1234", password: "..." }+plugins.entries.bluebubbles.enabled: false) and an explanation table of when each disablement layer wins. Operators who follow the new "Disable BlueBubbles entirely" steps verifiably stop hitting startup auto-enable surprises:channels.bluebubbles.enabled: false, the plugin entry is still loaded by the registry.plugins.entries.bluebubbles.enabled: false, the channel is unloaded but the channel-config schema still validates and may auto-enable on next startup.The doc layout also matches the existing pattern for other channel disablement docs (
docs/channels/whatsapp.md,docs/channels/discord.md).