Skip to content

feat(channels): add WhatsApp messaging channel with QR pairing#3392

Merged
ericksoa merged 38 commits into
mainfrom
fix/whatsapp-policy-preset
May 19, 2026
Merged

feat(channels): add WhatsApp messaging channel with QR pairing#3392
ericksoa merged 38 commits into
mainfrom
fix/whatsapp-policy-preset

Conversation

@laitingsheng

@laitingsheng laitingsheng commented May 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds WhatsApp as a QR-paired messaging channel alongside Telegram/Discord/Slack, and ships the network policy preset that unblocks the consumer WhatsApp Web protocol from inside an OpenShell sandbox. WhatsApp uses Curve25519 QR pairing rather than a static token, so ChannelDef.envKey becomes optional and the wizard skips the token prompt for QR-paired channels.

Related Issue

Fixes #361
Fixes #513

Changes

  • New nemoclaw-blueprint/policies/presets/whatsapp.yaml:
    • L4 CONNECT tunnel (access: full, tls: skip) for web.whatsapp.com and *.web.whatsapp.com so the proxy stops negotiating h2 on the /ws/chat upgrade and stops auto-terminating TLS on the Noise handshake.
    • REST allow-lists for the apex whatsapp.net and the *.whatsapp.net wildcard (covers mmg, static, cdn, pps, v, e1, f, s, etc. — all Meta-controlled; mirrors the *.atlassian.net precedent in the jira preset).
    • Non-Meta endpoint: a GET-only rule pinned to the single path raw.githubusercontent.com/WhiskeySockets/Baileys/master/src/Defaults/index.ts so Baileys' fetchLatestBaileysVersion() succeeds at runtime. Without it Baileys advertises its bundled (stale) WA protocol constant and Meta rejects pairing with <failure reason="405"/>.
  • WhatsApp joins the Open tier in tiers.yaml.
  • ChannelDef gains loginMethod ("token-paste" / "host-qr" / "in-sandbox-qr"); envKey becomes optional. New channelUsesInSandboxQrPairing and channelHasStaticToken helpers in sandbox/channels.ts.
  • onboard.ts: wizard prompt loop short-circuits for in-sandbox-QR channels (prints pairing instructions, skips token prompt). getMessagingToken, conflict-detection, enabledEnvKeys / disabledEnvKeys, and the userId loop now tolerate tokenless channels. setupMessagingChannels filters available channels by the active agent's messagingPlatforms so each agent only sees what it advertises. activeMessagingChannels now includes QR-selected channels so the sandbox image, registry state, and policy bootstrap all preserve them.
  • policy-channel.ts: addSandboxChannel and removeSandboxChannel normalise channelArg before logging, registry writes, and rebuild reasons. The in-sandbox-QR path registers the channel in the registry without upserting a bridge provider. The matching built-in network policy preset is applied to the sandbox before the rebuild so the bridge has egress on first start; failures warn and tell the user to run policy-add manually.
  • agents/openclaw/manifest.yaml: whatsapp moves from the # Future: comment into supported: and into state_dirs: (Baileys session state is durable across rebuilds, not baked into the image). Hermes intentionally does not advertise WhatsApp, and the wizard filter respects that.
  • policy/index.ts: messaging-preset warning text now uses generic "channel setup, pairing, and runtime configuration" wording so it reads correctly for QR-paired channels.
  • In-sandbox guard (scripts/nemoclaw-start.sh): openclaw channels login and channels status are intentionally allowed; mutating ops stay blocked. The error message distinguishes WhatsApp's in-sandbox pairing path from WeChat's host-side QR.
  • Tests: channels.test.ts covers the in-sandbox-QR shape, the three loginMethod values, and mixed-case canonicalisation; policies.test.ts adds regression cases for whatsapp.yaml (L4 + tls: skip on web.whatsapp.com; apex+wildcard whatsapp.net REST methods; the GET-pinned raw.githubusercontent.com rule).
  • Docs: messaging-channels.md describes the QR-pair flow, the durable whatsapp state directory, and the three login modes; commands.md describes token-paste / host-qr / in-sandbox-qr for channels add and the auto-applied preset behaviour; network-policies.md and integration-policy-examples.md fold wechat and whatsapp into the baseline-policy and matching-preset wording; user-reference skill regenerated.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Verification

  • npx prek run --all-files passes
  • npm test passes
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs updated for user-facing behavior changes
  • make docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Tinson Lai tinsonl@nvidia.com

Summary by CodeRabbit

  • New Features

    • WhatsApp channel added with in‑sandbox QR pairing; supported in onboarding for both agents and persisted across rebuilds.
  • Documentation

    • Expanded onboarding, channel setup, CLI reference, troubleshooting, network-policy, and integration docs to cover WhatsApp workflows, pairing, and persistence.
  • Policy

    • New WhatsApp network preset (endpoints, node runtime scope) and added to the Open tier.
  • Chores / CLI

    • In‑sandbox WhatsApp login permitted; config generation and agent manifests updated to handle tokenless WhatsApp sessions.
  • Tests

    • Unit, integration, and E2E tests added/updated for WhatsApp behavior.

Review Change Stack

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented May 12, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds WhatsApp as an in‑sandbox QR‑paired messaging channel and integrates it across agent manifests, onboarding and sandbox flows, a WhatsApp network‑policy preset and tier inclusion, Hermes/OpenClaw config and guards, documentation, tests, and CI.

Changes

WhatsApp Channel Support

Layer / File(s) Summary
Network policy preset & tier
nemoclaw-blueprint/policies/presets/whatsapp.yaml, nemoclaw-blueprint/policies/tiers.yaml, test/policies.test.ts
Adds whatsapp preset with L4/REST rules and node binary allowlist; includes preset in open tier and updates tests to expect the new preset.
Agent manifests & Dockerfiles
agents/openclaw/manifest.yaml, agents/hermes/manifest.yaml, agents/hermes/Dockerfile*
Add WhatsApp state dir/platforms and declare whatsapp in supported messaging_platforms; Dockerfiles create and chmod whatsapp platform dirs.
Channel types and KNOWN_CHANNELS
src/lib/sandbox/channels.ts, src/lib/sandbox/channels.test.ts
Introduce discriminated union for channel defs, add in-sandbox-qr loginMethod, add KNOWN_CHANNELS.whatsapp, and update type guards and tests.
Onboarding: state, token, wizard refactor
src/lib/onboard.ts, src/lib/onboard/messaging-state.ts, src/lib/onboard/messaging-state.test.ts, src/lib/onboard/messaging-token.ts, src/lib/onboard/messaging-token.test.ts
Agent-aware and QR-aware onboarding: new messaging-state helpers, token precedence change (env before credential), seeded wizard behavior per agent, and tests for selection logic.
Sandbox channel actions & preset application
src/lib/actions/sandbox/policy-channel.ts
Make channel add/remove agent-aware; QR-paired channels short‑circuit to register without host tokens, attempt preset application before rebuild, and gate gateway/provider ops to presence of token keys.
Hermes/OpenClaw config & scripts
agents/hermes/config/messaging-config.ts, scripts/generate-openclaw-config.py, scripts/nemoclaw-start.sh
Emit WHATSAPP env lines, generate tokenless WhatsApp account in openclaw config, and allow openclaw channels login --channel whatsapp inside sandbox while guarding other mutations.
Tests, integration & E2E
test/*, test/e2e/*, test/generate-hermes-config.test.ts, test/generate-openclaw-config.test.ts
Add/extend unit, integration, and E2E tests to cover WhatsApp channel lifecycle, config generation, sandbox guards, policy preset application, and isolation checks.
Docs and CI
docs/**, .github/workflows/nightly-e2e.yaml
Document WhatsApp pairing flow, channel requirements, commands, network policy guidance, troubleshooting, and extend nightly E2E job timeout and artifacts for WhatsApp.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

enhancement, NemoClaw CLI, enhancement: policy, VRDC, v0.0.44

Suggested reviewers

  • ericksoa
  • jyaunches
  • cv

"🐰 I hopped into the sandbox bright,
Scanned a QR to pair at night.
No tokens spilled, policies set,
WhatsApp joined the chat vignette.
Hooray — the sandbox chats take flight!"

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/whatsapp-policy-preset

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: messaging-providers-e2e, channels-stop-start-e2e, cloud-onboard-e2e, hermes-e2e, rebuild-hermes-e2e, network-policy-e2e, rebuild-openclaw-e2e
Optional E2E: docs-validation-e2e, token-rotation-e2e, messaging-compatible-endpoint-e2e, cloud-e2e

Dispatch hint: messaging-providers-e2e,channels-stop-start-e2e,cloud-onboard-e2e,hermes-e2e,rebuild-hermes-e2e,network-policy-e2e,rebuild-openclaw-e2e

Auto-dispatched E2E: messaging-providers-e2e, channels-stop-start-e2e, cloud-onboard-e2e, hermes-e2e, rebuild-hermes-e2e, network-policy-e2e, rebuild-openclaw-e2e via nightly-e2e.yaml at 8653582e0c601f0987b06a2bd3575804e0e1bed9nightly run

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • messaging-providers-e2e (high; workflow timeout 75 minutes): Directly covers the modified messaging provider/config path, including token-backed providers, placeholder/L7 proxy credential isolation, and the newly added WhatsApp QR-only no-provider policy/config path.
  • channels-stop-start-e2e (very high; workflow timeout 120 minutes): Directly covers channel add/stop/start/remove lifecycle across OpenClaw and Hermes and now includes WhatsApp. This is the strongest existing regression for channel registry state, cached credentials, provider detach/delete behavior, policy unapply/apply, and rebuild survival.
  • cloud-onboard-e2e (high; workflow timeout 45 minutes): Onboarding, policy preset selection, sandbox creation, installer behavior, inference.local, and secret-leak checks are affected by changes in onboard.ts, policy suggestions, tiers, config generation, and startup scripts.
  • hermes-e2e (high; workflow timeout 45 minutes): Hermes Dockerfiles, manifest, messaging env generation, writable state paths, and startup behavior changed. The base Hermes install/onboard/health/live-inference journey should block merge.
  • rebuild-hermes-e2e (high; workflow timeout 60 minutes): Hermes state directory definitions and filesystem permissions changed, including the new platforms/whatsapp session tree. Existing rebuild coverage is needed to catch state loss or stale image/rebuild regressions.
  • network-policy-e2e (high; workflow timeout 45 minutes): The PR adds a WhatsApp network policy preset and modifies policy tiers and policy indexing. Existing network policy E2E validates deny-by-default behavior, policy-add/hot-reload, dry-run, permissive mode, and security boundary behavior.
  • rebuild-openclaw-e2e (high; workflow timeout 60 minutes): OpenClaw manifest state_dirs and messaging platform support changed. Existing OpenClaw rebuild E2E validates rebuild survival, policy preset replay, version upgrade, and credential leak protections for the default agent path.

Optional E2E

  • docs-validation-e2e (low; workflow timeout 15 minutes): Useful because command/reference docs and messaging/network-policy docs changed; validates CLI/docs parity and markdown links, but it is not the main runtime risk.
  • token-rotation-e2e (medium; workflow timeout 45 minutes): Adjacent confidence for token-backed messaging credentials after changes to channel/token helpers. WhatsApp is tokenless, so this is not the primary merge-blocking coverage.
  • messaging-compatible-endpoint-e2e (medium; workflow timeout 45 minutes): Optional regression for messaging plus compatible inference endpoint routing; useful because onboarding/messaging code changed, but the PR is not primarily changing inference routing.
  • cloud-e2e (high; workflow timeout 45 minutes): Broad default OpenClaw install/onboard/live inference smoke coverage. It overlaps with cloud-onboard and messaging jobs, so it is useful if CI capacity permits.

New E2E recommendations

  • whatsapp-real-qr-pairing (high): Existing E2E appears to validate WhatsApp config/policy/no-provider behavior with fake or tokenless setup, but not an actual QR pairing session or message delivery through WhatsApp Web.
    • Suggested test: Add a gated/manual WhatsApp QR pairing E2E that enables WhatsApp, runs the agent-specific pairing command, verifies paired session files, and confirms a real or controlled message delivery path.
  • whatsapp-session-state-preservation (high): The PR adds OpenClaw whatsapp and Hermes platforms/whatsapp state directories, but existing rebuild tests do not appear to create WhatsApp session marker files in those exact paths and verify preservation across rebuild/remove/stop cycles.
    • Suggested test: Add an E2E phase that writes representative WhatsApp session markers under /sandbox/.openclaw/whatsapp and /sandbox/.hermes/platforms/whatsapp/session, rebuilds, and verifies the markers survive while secrets do not leak into host artifacts.
  • whatsapp-policy-preset-live-egress (medium): Messaging providers E2E checks policy text for WhatsApp endpoints, but a dedicated security assertion for allowed WhatsApp hosts versus denied unrelated hosts would better cover the new preset.
    • Suggested test: Extend network-policy-e2e or add a focused WhatsApp policy E2E that applies the whatsapp preset, verifies allowed egress to required WhatsApp Web/CDN endpoints, and verifies unrelated egress remains blocked.

Dispatch hint

  • Workflow: .github/workflows/nightly-e2e.yaml
  • jobs input: messaging-providers-e2e,channels-stop-start-e2e,cloud-onboard-e2e,hermes-e2e,rebuild-hermes-e2e,network-policy-e2e,rebuild-openclaw-e2e

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Docs preview ready!

https://NVIDIA.github.io/NemoClaw/pr-preview/pr-3392/

Comment thread src/lib/onboard.ts Fixed
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/manage-sandboxes/messaging-channels.md (2)

27-28: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update opening sentence to include WhatsApp.

The opening paragraph lists "Telegram, Discord, and Slack" but omits WhatsApp. Update for consistency with the added WhatsApp support throughout this page.

📝 Suggested update
-Telegram, Discord, and Slack reach your agent through OpenShell-managed processes and gateway constructs.
+Telegram, Discord, Slack, and WhatsApp reach your agent through OpenShell-managed processes and gateway constructs.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/manage-sandboxes/messaging-channels.md` around lines 27 - 28, The
opening sentence "Telegram, Discord, and Slack reach your agent through
OpenShell-managed processes and gateway constructs." omits WhatsApp; update that
sentence to include WhatsApp (e.g., "Telegram, Discord, Slack, and WhatsApp
reach your agent...") so the paragraph and the rest of the page consistently
reflect added WhatsApp support.

6-7: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update description to include WhatsApp.

The frontmatter descriptions mention "Telegram, Discord, or Slack" but omit WhatsApp, which is now a supported channel. Update both description.main and description.agent to include WhatsApp for consistency with the body content.

📝 Suggested update
 description:
-  main: "Connect Telegram, Discord, or Slack to your sandboxed OpenClaw agent using OpenShell-managed channel messaging."
-  agent: "Explains how Telegram, Discord, and Slack reach the sandboxed OpenClaw agent through OpenShell-managed processes and NemoClaw channel commands. Use when setting up messaging channels, chat interfaces, or integrations without relying on nemoclaw tunnel start for bridges."
+  main: "Connect Telegram, Discord, Slack, or WhatsApp to your sandboxed OpenClaw agent using OpenShell-managed channel messaging."
+  agent: "Explains how Telegram, Discord, Slack, and WhatsApp reach the sandboxed OpenClaw agent through OpenShell-managed processes and NemoClaw channel commands. Use when setting up messaging channels, chat interfaces, or integrations without relying on nemoclaw tunnel start for bridges."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/manage-sandboxes/messaging-channels.md` around lines 6 - 7, Update the
frontmatter descriptions to include WhatsApp: modify the values for
description.main and description.agent so they list "Telegram, Discord, Slack,
or WhatsApp" (or "Telegram, Discord, Slack and WhatsApp") and ensure the second
string also mentions WhatsApp alongside Telegram/Discord/Slack to match the body
content and supported channels.
🧹 Nitpick comments (2)
docs/manage-sandboxes/messaging-channels.md (2)

77-78: 💤 Low value

Consider simplifying with a period instead of an em dash.

Line 77 uses an em dash to connect two independent clauses. The style guide recommends flagging em dashes used instead of commas or periods.

📝 Suggested simplification
-WhatsApp uses QR pairing instead of a host-side token, so the wizard does not prompt — it prints pairing instructions and you complete the pairing inside the sandbox after rebuild.
+WhatsApp uses QR pairing instead of a host-side token, so the wizard does not prompt.
+It prints pairing instructions, and you complete the pairing inside the sandbox after rebuild.

As per coding guidelines: "Excessive em dashes. One per paragraph is fine; multiple per paragraph or em dashes used instead of commas/periods should be flagged."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/manage-sandboxes/messaging-channels.md` around lines 77 - 78, The
sentence "WhatsApp uses QR pairing instead of a host-side token, so the wizard
does not prompt — it prints pairing instructions and you complete the pairing
inside the sandbox after rebuild." uses an em dash to join two independent
clauses; replace the em dash with a period and capitalize the following clause
(i.e., split into "...does not prompt. It prints pairing instructions...") to
follow the style guide; also check the nearby sentence fragment "NemoClaw also
selects the matching network policy preset during policy setup so the channel
can reach its provider API." for similar em-dash or comma usage and adjust
accordingly if present.

70-71: 💤 Low value

Split into separate lines for diff readability.

Lines 70-71 contain two sentences separated by a semicolon. The style guide requires one sentence per line in source to make diffs readable.

📝 Suggested reformat
-Because session credentials are generated and stored inside the sandbox image, NemoClaw cannot detect cross-sandbox WhatsApp conflicts the way it does for token-based channels; pair only one sandbox per WhatsApp account at a time.
+Because session credentials are generated and stored inside the sandbox image, NemoClaw cannot detect cross-sandbox WhatsApp conflicts the way it does for token-based channels.
+Pair only one sandbox per WhatsApp account at a time.

As per coding guidelines: "One sentence per line in source (makes diffs readable). Flag paragraphs where multiple sentences appear on the same line."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/manage-sandboxes/messaging-channels.md` around lines 70 - 71, The
paragraph contains two sentences on the same source line; split them into
separate lines so each sentence stands alone for diff readability — replace the
single line "Because session credentials are generated and stored inside the
sandbox image, NemoClaw cannot detect cross-sandbox WhatsApp conflicts the way
it does for token-based channels; pair only one sandbox per WhatsApp account at
a time." with two lines: one containing "Because session credentials are
generated and stored inside the sandbox image, NemoClaw cannot detect
cross-sandbox WhatsApp conflicts the way it does for token-based channels." and
the next containing "Pair only one sandbox per WhatsApp account at a time."
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/actions/sandbox/policy-channel.ts`:
- Around line 420-429: The QR-paired channel is being persisted using the raw
user input (channelArg), which can be mixed-case and lead to non-canonical
registry entries; normalize the channel name to a canonical form (e.g.,
lower-case) before calling applyChannelAddToGatewayAndRegistry and before using
it in promptAndRebuild and log messages. Locate the block using
channelUsesQrPairing(channel) and replace uses of channelArg with a normalized
variable (e.g., normalizedChannel = channelArg.toLowerCase()) when calling
applyChannelAddToGatewayAndRegistry, console logs that reference the channel
name, and promptAndRebuild to ensure registry entries and subsequent
remove/start/stop logic use the canonical name.

In `@src/lib/onboard.ts`:
- Around line 9087-9092: The branch that logs QR-selected channels but continues
when channelHasStaticToken(ch) is false leaves tokenless (QR) channels visually
"enabled" yet not included in the runtime activation set; update the selection
logic so that when channelHasStaticToken(ch) is false you also mark the channel
as active for the sandbox (e.g., push ch into activeMessagingChannels or set the
same enabled flag used by sandbox config generation), ensuring the QR-selected
channel is preserved into the sandbox/Docker args rather than only being logged;
reference the channelHasStaticToken(ch) check, the ch variable, and the
activeMessagingChannels/sandbox activation path when making the change.

---

Outside diff comments:
In `@docs/manage-sandboxes/messaging-channels.md`:
- Around line 27-28: The opening sentence "Telegram, Discord, and Slack reach
your agent through OpenShell-managed processes and gateway constructs." omits
WhatsApp; update that sentence to include WhatsApp (e.g., "Telegram, Discord,
Slack, and WhatsApp reach your agent...") so the paragraph and the rest of the
page consistently reflect added WhatsApp support.
- Around line 6-7: Update the frontmatter descriptions to include WhatsApp:
modify the values for description.main and description.agent so they list
"Telegram, Discord, Slack, or WhatsApp" (or "Telegram, Discord, Slack and
WhatsApp") and ensure the second string also mentions WhatsApp alongside
Telegram/Discord/Slack to match the body content and supported channels.

---

Nitpick comments:
In `@docs/manage-sandboxes/messaging-channels.md`:
- Around line 77-78: The sentence "WhatsApp uses QR pairing instead of a
host-side token, so the wizard does not prompt — it prints pairing instructions
and you complete the pairing inside the sandbox after rebuild." uses an em dash
to join two independent clauses; replace the em dash with a period and
capitalize the following clause (i.e., split into "...does not prompt. It prints
pairing instructions...") to follow the style guide; also check the nearby
sentence fragment "NemoClaw also selects the matching network policy preset
during policy setup so the channel can reach its provider API." for similar
em-dash or comma usage and adjust accordingly if present.
- Around line 70-71: The paragraph contains two sentences on the same source
line; split them into separate lines so each sentence stands alone for diff
readability — replace the single line "Because session credentials are generated
and stored inside the sandbox image, NemoClaw cannot detect cross-sandbox
WhatsApp conflicts the way it does for token-based channels; pair only one
sandbox per WhatsApp account at a time." with two lines: one containing "Because
session credentials are generated and stored inside the sandbox image, NemoClaw
cannot detect cross-sandbox WhatsApp conflicts the way it does for token-based
channels." and the next containing "Pair only one sandbox per WhatsApp account
at a time."
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 01c5ca9b-70e1-4c20-a107-4393db8fdcda

📥 Commits

Reviewing files that changed from the base of the PR and between 4b47ab4 and 9b918a0.

📒 Files selected for processing (14)
  • agents/openclaw/manifest.yaml
  • docs/manage-sandboxes/messaging-channels.md
  • docs/reference/network-policies.md
  • nemoclaw-blueprint/policies/presets/whatsapp.yaml
  • nemoclaw-blueprint/policies/tiers.yaml
  • src/lib/actions/sandbox/policy-channel.ts
  • src/lib/agent/defs.test.ts
  • src/lib/onboard.ts
  • src/lib/policy/index.ts
  • src/lib/sandbox/channels.test.ts
  • src/lib/sandbox/channels.ts
  • test/policies.test.ts
  • test/policy-tiers-onboard.test.ts
  • test/policy-tiers.test.ts

Comment thread src/lib/actions/sandbox/policy-channel.ts Outdated
Comment thread src/lib/onboard.ts Outdated
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
Comment thread test/policies.test.ts Fixed
Comment thread test/policies.test.ts Fixed
Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/onboard.test.ts (1)

4762-4767: ⚡ Quick win

Prefer a behavioral QR-pairing regression test over this mega-regex.

This assertion now hard-codes a long slice of onboard.ts implementation detail, so harmless refactors will churn the test, but it still won't prove the new tokenless resume path works. A small spawned resume/create-sandbox test that records messagingChannels: ["whatsapp"] with no messaging env vars would catch the QR-paired regression this PR is about more reliably.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/onboard.test.ts` around lines 4762 - 4767, Replace the brittle
mega-regex assertion in onboard.test.ts with a focused behavioral regression
test that spawns a resume/create-sandbox flow and verifies QR-pairing/tokenless
resume behavior: instead of matching implementation text around
startRecordedStep, getRecordedMessagingChannelsForResume,
setupMessagingChannels, readMessagingChannelConfigFromEnv,
onboardSession.updateSession, and createSandbox, write a test that records a
session with messagingChannels: ["whatsapp"] while ensuring no messaging env
vars are set, then resume and assert the resumed session uses the recorded
messagingChannels and proceeds to call createSandbox (or equivalent completion)
without requiring a token; this proves the tokenless resume path works and
avoids fragile implementation-dependent regex matching.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/onboard.ts`:
- Around line 6024-6028: The current logic only builds disabledEnvKeys from
getChannelTokenKeys and misses QR-paired channels (e.g., WhatsApp) because
getChannelTokenKeys returns empty; as a result
qrSelectedChannels/activeMessagingChannels can re-enable channels explicitly
stopped. Update the selection logic that computes
activeMessagingChannels/qrSelectedChannels to also exclude any channel whose
name appears in disabledChannels (use registry.getDisabledChannels(sandboxName)
/ disabledChannels) in addition to checking disabledEnvKeys; specifically adjust
the code paths that use MESSAGING_CHANNELS.filter(...) and the
qrSelectedChannels construction so they check disabledChannels.includes(c.name)
before adding the channel.

---

Nitpick comments:
In `@test/onboard.test.ts`:
- Around line 4762-4767: Replace the brittle mega-regex assertion in
onboard.test.ts with a focused behavioral regression test that spawns a
resume/create-sandbox flow and verifies QR-pairing/tokenless resume behavior:
instead of matching implementation text around startRecordedStep,
getRecordedMessagingChannelsForResume, setupMessagingChannels,
readMessagingChannelConfigFromEnv, onboardSession.updateSession, and
createSandbox, write a test that records a session with messagingChannels:
["whatsapp"] while ensuring no messaging env vars are set, then resume and
assert the resumed session uses the recorded messagingChannels and proceeds to
call createSandbox (or equivalent completion) without requiring a token; this
proves the tokenless resume path works and avoids fragile
implementation-dependent regex matching.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4bcdcced-1503-4cd3-8f70-b427f3a04c4f

📥 Commits

Reviewing files that changed from the base of the PR and between 9b918a0 and f538e4d.

📒 Files selected for processing (7)
  • docs/manage-sandboxes/messaging-channels.md
  • src/lib/actions/sandbox/policy-channel.ts
  • src/lib/onboard.ts
  • src/lib/policy/index.ts
  • src/lib/sandbox/channels.test.ts
  • test/onboard.test.ts
  • test/policies.test.ts
✅ Files skipped from review due to trivial changes (1)
  • docs/manage-sandboxes/messaging-channels.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/policy/index.ts
  • src/lib/sandbox/channels.test.ts

Comment thread src/lib/onboard.ts Outdated
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 25747647716
Branch: fix/whatsapp-policy-preset
Requested jobs: messaging-providers-e2e,network-policy-e2e,cloud-onboard-e2e,token-rotation-e2e
Summary: 4 passed, 0 failed, 0 skipped

Job Result
cloud-onboard-e2e ✅ success
messaging-providers-e2e ✅ success
network-policy-e2e ✅ success
token-rotation-e2e ✅ success

@jyaunches

Copy link
Copy Markdown
Contributor

Targeted E2E validation requested by the E2E Advisor has passed.

Run: https://github.com/NVIDIA/NemoClaw/actions/runs/25747647716

Passed targeted jobs: messaging-providers-e2e, network-policy-e2e, cloud-onboard-e2e, token-rotation-e2e

PR review can proceed with that E2E signal in mind.

…preset

Stop re-enabling QR-only channels (WhatsApp) that the operator paused
with `channels stop`, and recognise WhatsApp as a valid explicit policy
preset selection so onboard suggests its egress rules.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/onboard.ts (1)

6637-6649: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

QR-paired channel allowlists are dropped at build time.

This serialization still keys messagingAllowedIds off enabledTokenEnvKeys, so any userIdEnvKey collected for a tokenless QR channel never makes it into the sandbox config. After a rebuild, the channel comes back without the requested sender restrictions.

Suggested fix
-  const enabledTokenEnvKeys = new Set(messagingTokenDefs.map(({ envKey }) => envKey));
+  const enabledTokenEnvKeys = new Set(messagingTokenDefs.map(({ envKey }) => envKey));
+  const enabledChannelNames = new Set(activeMessagingChannels);
   for (const ch of MESSAGING_CHANNELS) {
     if (
-      ch.envKey &&
-      enabledTokenEnvKeys.has(ch.envKey) &&
+      enabledChannelNames.has(ch.name) &&
       ch.userIdEnvKey &&
       process.env[ch.userIdEnvKey]
     ) {
       const ids = String(process.env[ch.userIdEnvKey])
         .split(",")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/onboard.ts` around lines 6637 - 6649, The current loop only writes
messagingAllowedIds when a channel's envKey is present in messagingTokenDefs
(enabledTokenEnvKeys), which drops QR/tokenless channels that only have a
userIdEnvKey; change the condition so channels with a configured userIdEnvKey
are included regardless of whether ch.envKey is enabled: check first that
ch.userIdEnvKey && process.env[ch.userIdEnvKey], then inside allow the channel
if either ch.envKey is falsy (tokenless) OR enabledTokenEnvKeys.has(ch.envKey);
populate messagingAllowedIds[ch.name] from that env var as before. Reference:
messagingAllowedIds, messagingTokenDefs, MESSAGING_CHANNELS, ch.envKey,
ch.userIdEnvKey, enabledTokenEnvKeys.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/onboard.ts`:
- Around line 9044-9059: The messaging-channel picker currently seeds enabled
state only from host tokens so QR-paired channels drop on rebuilds; update
setupMessagingChannels to accept an optional existingChannels (or
messagingChannels) parameter and use it when computing each channel's initial
enabled state: if getMessagingToken(envKey) is falsy but existingChannels
includes the channel name, treat it as enabled. Ensure availableChannels /
MESSAGING_CHANNELS filtering remains the same and update rebuild call sites to
pass the sandbox/session messagingChannels into setupMessagingChannels so
QR-only channels stay preselected.

---

Outside diff comments:
In `@src/lib/onboard.ts`:
- Around line 6637-6649: The current loop only writes messagingAllowedIds when a
channel's envKey is present in messagingTokenDefs (enabledTokenEnvKeys), which
drops QR/tokenless channels that only have a userIdEnvKey; change the condition
so channels with a configured userIdEnvKey are included regardless of whether
ch.envKey is enabled: check first that ch.userIdEnvKey &&
process.env[ch.userIdEnvKey], then inside allow the channel if either ch.envKey
is falsy (tokenless) OR enabledTokenEnvKeys.has(ch.envKey); populate
messagingAllowedIds[ch.name] from that env var as before. Reference:
messagingAllowedIds, messagingTokenDefs, MESSAGING_CHANNELS, ch.envKey,
ch.userIdEnvKey, enabledTokenEnvKeys.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 1cdeda13-4596-45d2-a993-30cf04e4aa73

📥 Commits

Reviewing files that changed from the base of the PR and between 9b918a0 and 6a78b55.

📒 Files selected for processing (8)
  • docs/manage-sandboxes/messaging-channels.md
  • src/lib/actions/sandbox/policy-channel.ts
  • src/lib/onboard.ts
  • src/lib/policy/index.ts
  • src/lib/sandbox/channels.test.ts
  • test/onboard.test.ts
  • test/policies.test.ts
  • test/policy-tiers-onboard.test.ts
✅ Files skipped from review due to trivial changes (2)
  • test/policy-tiers-onboard.test.ts
  • docs/manage-sandboxes/messaging-channels.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/policy/index.ts
  • src/lib/sandbox/channels.test.ts

Comment thread src/lib/onboard.ts Outdated
Move getSuggestedPolicyPresets and the messaging-state helpers under
src/lib/onboard/ to keep onboard.ts net-neutral.

Seed setupMessagingChannels from the sandbox's recorded messaging
channels so QR-only channels (WhatsApp) survive a non-interactive
rebuild that has no host token to detect them with.

Key messagingAllowedIds off activeMessagingChannels so any future QR
channel with a userIdEnvKey can still serialise its allow-list, and
skip the gateway requirement in channels add/remove when the channel
has no bridge provider to touch.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/onboard.test.ts (1)

6234-6238: ⚡ Quick win

Harden these WhatsApp tests against inherited messaging env leakage.

Both helper scripts clear only a few token vars. To keep these tests fully hermetic, clear full messaging prefixes (DISCORD_*, TELEGRAM_*, SLACK_*) before createSandbox().

♻️ Suggested tweak (apply in both helper scripts)
-  delete process.env.DISCORD_BOT_TOKEN;
-  delete process.env.SLACK_BOT_TOKEN;
-  delete process.env.SLACK_APP_TOKEN;
-  delete process.env.TELEGRAM_BOT_TOKEN;
+  for (const key of Object.keys(process.env)) {
+    if (
+      key.startsWith("DISCORD_") ||
+      key.startsWith("TELEGRAM_") ||
+      key.startsWith("SLACK_")
+    ) {
+      delete process.env[key];
+    }
+  }

Based on learnings: “delete/remove unrelated messaging env vars such as DISCORD_* and TELEGRAM_* … to prevent inherited environment from activating additional channels.”

Also applies to: 6403-6406

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/onboard.test.ts` around lines 6234 - 6238, The WhatsApp tests are not
fully hermetic because helper scripts only delete a few specific tokens; update
the setup that runs before createSandbox() to remove all environment variables
with messaging prefixes so no inherited messaging tokens activate additional
channels — e.g., iterate/remove any process.env keys starting with "DISCORD_",
"TELEGRAM_", and "SLACK_" (in the same helper where
process.env.OPENSHELL_GATEWAY = "nemoclaw" is set) so createSandbox() runs with
those prefixes cleared.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/actions/sandbox/policy-channel.ts`:
- Around line 507-508: The success message always says "Removed {canonical}
bridge" but QR-paired channels (e.g., WhatsApp) don't create bridge providers;
update the code around the console.log in policy-channel.ts so you conditionally
choose the wording based on whether a bridge provider was actually created for
the channel: inspect the channel record or metadata used in the removal flow
(e.g., a provider type or a boolean like bridgeProvider/createdBridge) and if a
bridge exists print the current message, otherwise print a generic "Removed
{canonical} channel" (keep the await promptAndRebuild(sandboxName, `remove
'${canonical}'`) call unchanged).

---

Nitpick comments:
In `@test/onboard.test.ts`:
- Around line 6234-6238: The WhatsApp tests are not fully hermetic because
helper scripts only delete a few specific tokens; update the setup that runs
before createSandbox() to remove all environment variables with messaging
prefixes so no inherited messaging tokens activate additional channels — e.g.,
iterate/remove any process.env keys starting with "DISCORD_", "TELEGRAM_", and
"SLACK_" (in the same helper where process.env.OPENSHELL_GATEWAY = "nemoclaw" is
set) so createSandbox() runs with those prefixes cleared.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4677ca16-a903-4823-92be-454d8aa0005a

📥 Commits

Reviewing files that changed from the base of the PR and between 9b918a0 and 7cffb27.

📒 Files selected for processing (10)
  • docs/manage-sandboxes/messaging-channels.md
  • src/lib/actions/sandbox/policy-channel.ts
  • src/lib/onboard.ts
  • src/lib/onboard/messaging-state.ts
  • src/lib/onboard/policy-presets.ts
  • src/lib/policy/index.ts
  • src/lib/sandbox/channels.test.ts
  • test/onboard.test.ts
  • test/policies.test.ts
  • test/policy-tiers-onboard.test.ts
✅ Files skipped from review due to trivial changes (1)
  • src/lib/onboard/messaging-state.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/policy-tiers-onboard.test.ts
  • src/lib/policy/index.ts
  • src/lib/sandbox/channels.test.ts

Comment thread src/lib/actions/sandbox/policy-channel.ts Outdated
…ntal flag

Address review feedback by (1) hinting at the matching network policy
preset after channels-add, (2) using "channel" instead of "bridge" for
QR-only channels in the remove message, and (3) hiding WhatsApp from
the picker, channels list, channels add, and the policy-preset
suggester unless NEMOCLAW_EXPERIMENTAL=1 is set.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
Keeping the gate half-applied (picker and channels add gated, but the
open tier, agent manifest, and channel metadata not) created an
inconsistent surface that was riskier than the status quo. The post-add
policy-preset hint, removal-message wording, and test hermeticity from
the same commit are kept.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/lib/onboard.ts (1)

10991-10994: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Seed the picker from session state on interactive resume.

If an interactive run is interrupted after current.messagingChannels is saved but before registry.registerSandbox(), existing is still null here. Resuming then reopens the picker with QR-only channels unchecked, and pressing Enter silently drops them from the rebuilt sandbox.

Suggested fix
-        const existing = sandboxName
-          ? registry.getSandbox(sandboxName)?.messagingChannels ?? null
-          : null;
+        const existing = sandboxName
+          ? registry.getSandbox(sandboxName)?.messagingChannels ??
+            session?.messagingChannels ??
+            null
+          : session?.messagingChannels ?? null;
         selectedMessagingChannels = await setupMessagingChannels(agent, existing);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/onboard.ts` around lines 10991 - 10994, When seeding the
messaging-channel picker, fall back to the saved session state on the agent if
registry.getSandbox(sandboxName) is null; replace the current existing
calculation so that if registry.getSandbox(sandboxName)?.messagingChannels is
missing you use agent.current?.messagingChannels (or current.messagingChannels)
before passing to setupMessagingChannels. Update the existing variable used
before calling setupMessagingChannels(agent, existing) so the picker preserves
previously saved channels even when registry.registerSandbox() hasn’t been
called yet.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/onboard.ts`:
- Around line 5317-5318: The getMessagingToken helper currently prefers a saved
credential via getCredential(envKey) before honoring an explicitly exported
environment value, which can let stale saved tokens override exported ones;
update getMessagingToken (and the other similar helper used around the second
occurrence) to check process.env[envKey] /
normalizeCredentialValue(process.env[envKey]) first and only fall back to
getCredential(envKey) if that is missing, returning null otherwise so exported
env credentials always take precedence over stored credentials.

---

Duplicate comments:
In `@src/lib/onboard.ts`:
- Around line 10991-10994: When seeding the messaging-channel picker, fall back
to the saved session state on the agent if registry.getSandbox(sandboxName) is
null; replace the current existing calculation so that if
registry.getSandbox(sandboxName)?.messagingChannels is missing you use
agent.current?.messagingChannels (or current.messagingChannels) before passing
to setupMessagingChannels. Update the existing variable used before calling
setupMessagingChannels(agent, existing) so the picker preserves previously saved
channels even when registry.registerSandbox() hasn’t been called yet.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f66f4ea3-9079-4e64-b32d-379ba341663a

📥 Commits

Reviewing files that changed from the base of the PR and between 9b918a0 and a24798d.

📒 Files selected for processing (11)
  • docs/manage-sandboxes/messaging-channels.md
  • src/lib/actions/sandbox/policy-channel.ts
  • src/lib/onboard.ts
  • src/lib/onboard/messaging-state.ts
  • src/lib/onboard/policy-presets.ts
  • src/lib/policy/index.ts
  • src/lib/sandbox/channels.test.ts
  • src/lib/sandbox/channels.ts
  • test/onboard.test.ts
  • test/policies.test.ts
  • test/policy-tiers-onboard.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/policy-tiers-onboard.test.ts
  • src/lib/policy/index.ts

Comment thread src/lib/onboard.ts Outdated
…t manifest

generate-openclaw-config.py was dropping WhatsApp on the floor: _token_keys
only covers Discord/Telegram/Slack so the loop skipped any QR-paired
channel, leaving the baked image with no config.channels.whatsapp entry
even after the rest of the pipeline registered it. Add a tokenless branch
that emits the same enabled/healthMonitor shape minus the token
placeholders, with a regression test that asserts the block exists and
carries no token, botToken, or appToken.

Channel commands and the onboard create path were also accepting
channels the sandbox's agent does not advertise. Resolve the agent for
the target sandbox in channels add/list and reject channels that are not
in agent.messagingPlatforms, and filter enabledChannels by the same set
inside createSandbox so a stale registry entry (or a recreate with a
session.messagingChannels carrying an unsupported channel) cannot bake
it into the new image.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
Conflict in network-policies.md: keep whatsapp in the Open tier (this
PR adds it) and accept main's "brave when supported" clarification.

Apply CodeRabbit's interactive-resume fix: fall back to session
messagingChannels in setupMessagingChannels when the sandbox isn't
yet in the registry.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26073405190
Target ref: fix/whatsapp-policy-preset
Workflow ref: fix/whatsapp-policy-preset
Requested jobs: messaging-providers-e2e
Summary: 0 passed, 0 failed, 0 skipped

Job Result
messaging-providers-e2e ⚠️ cancelled

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26073403013
Target ref: 0933ecfb5a9f1d46735d9ca3527d2bc4157968ac
Workflow ref: main
Requested jobs: messaging-providers-e2e,channels-stop-start-e2e,network-policy-e2e,cloud-onboard-e2e,hermes-e2e
Summary: 2 passed, 0 failed, 0 skipped

Job Result
channels-stop-start-e2e ⚠️ cancelled
cloud-onboard-e2e ✅ success
hermes-e2e ✅ success
messaging-providers-e2e ⚠️ cancelled
network-policy-e2e ⚠️ cancelled

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 26073779854
Target ref: fix/whatsapp-policy-preset
Workflow ref: fix/whatsapp-policy-preset
Requested jobs: messaging-providers-e2e
Summary: 0 passed, 1 failed, 0 skipped

Job Result
messaging-providers-e2e ❌ failure

Failed jobs: messaging-providers-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 26073818011
Target ref: 66eb4fd7ffdf6bab3b2c1299eef2b08ba5fa4caa
Workflow ref: main
Requested jobs: messaging-providers-e2e,channels-stop-start-e2e,network-policy-e2e,hermes-e2e,docs-validation-e2e
Summary: 3 passed, 1 failed, 0 skipped

Job Result
channels-stop-start-e2e ⚠️ cancelled
docs-validation-e2e ✅ success
hermes-e2e ✅ success
messaging-providers-e2e ❌ failure
network-policy-e2e ✅ success

Failed jobs: messaging-providers-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26074804320
Target ref: a9224759b57f88dcd3ab92a75ae43662ab1f47cd
Workflow ref: main
Requested jobs: messaging-providers-e2e,channels-stop-start-e2e
Summary: 0 passed, 0 failed, 0 skipped

Job Result
channels-stop-start-e2e ⚠️ cancelled
messaging-providers-e2e ⚠️ cancelled

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 26074855642
Target ref: a9224759b57f88dcd3ab92a75ae43662ab1f47cd
Workflow ref: main
Requested jobs: messaging-providers-e2e,channels-stop-start-e2e,network-policy-e2e,cloud-onboard-e2e,hermes-e2e,rebuild-hermes-e2e
Summary: 4 passed, 1 failed, 0 skipped

Job Result
channels-stop-start-e2e ⚠️ cancelled
cloud-onboard-e2e ✅ success
hermes-e2e ✅ success
messaging-providers-e2e ❌ failure
network-policy-e2e ✅ success
rebuild-hermes-e2e ✅ success

Failed jobs: messaging-providers-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26075901899
Target ref: 16b7157e35a042d124feaa2c84878f378ab7d8ef
Workflow ref: main
Requested jobs: messaging-providers-e2e,channels-stop-start-e2e
Summary: 0 passed, 0 failed, 0 skipped

Job Result
channels-stop-start-e2e ⚠️ cancelled
messaging-providers-e2e ⚠️ cancelled

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26075981044
Target ref: 16b7157e35a042d124feaa2c84878f378ab7d8ef
Workflow ref: main
Requested jobs: messaging-providers-e2e,channels-stop-start-e2e,network-policy-e2e
Summary: 3 passed, 0 failed, 0 skipped

Job Result
channels-stop-start-e2e ✅ success
messaging-providers-e2e ✅ success
network-policy-e2e ✅ success

@ericksoa ericksoa merged commit 907e410 into main May 19, 2026
26 checks passed
@ericksoa ericksoa deleted the fix/whatsapp-policy-preset branch May 19, 2026 05:51
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26078664110
Target ref: 8653582e0c601f0987b06a2bd3575804e0e1bed9
Workflow ref: main
Requested jobs: messaging-providers-e2e,channels-stop-start-e2e,cloud-onboard-e2e,hermes-e2e,rebuild-hermes-e2e,network-policy-e2e,rebuild-openclaw-e2e
Summary: 7 passed, 0 failed, 0 skipped

Job Result
channels-stop-start-e2e ✅ success
cloud-onboard-e2e ✅ success
hermes-e2e ✅ success
messaging-providers-e2e ✅ success
network-policy-e2e ✅ success
rebuild-hermes-e2e ✅ success
rebuild-openclaw-e2e ✅ success

@miyoungc miyoungc mentioned this pull request May 20, 2026
12 tasks
miyoungc added a commit that referenced this pull request May 20, 2026
## Summary
Refreshes the NemoClaw docs for v0.0.46 by updating version metadata,
release notes, and generated user skills. The refresh also keeps public
docs aligned with the docs skip list by removing non-public experimental
references from the generated output.

## Related Issue
None.

## Changes
- #3744 and #3824 -> `docs/about/release-notes.mdx`: Added Windows
bootstrap and WSL express install coverage for v0.0.46.
- #3392 -> `docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/commands.mdx`, `docs/reference/network-policies.mdx`,
and policy examples: Refreshed public messaging channel docs around
WhatsApp and matching policy presets.
- #3742, #3767, #3732, #3786, #3777, and #3808 ->
`docs/about/release-notes.mdx`: Added release-note coverage for Hermes
managed tools, Bedrock Runtime endpoint detection, WSL Ollama proxying,
Model Router Python fallback, plugin command registration, and
tool-catalog latency improvements.
- #3124 -> `docs/about/release-notes.mdx`: Added release-note coverage
for hosted uninstall flag guidance.
- Generated `nemoclaw-user-*` skills from the updated MDX docs for the
v0.0.46 release.

## Type of Change
- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [x] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Verification
- [ ] `npx prek run --all-files` passes
- [ ] `npm test` passes
- [ ] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [x] Docs updated for user-facing behavior changes
- [ ] `make docs` builds without warnings (doc changes only)
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

Verification notes:
- Commit hooks passed, including markdownlint, gitleaks, docs-to-skills
verification, env-var docs, and skills YAML checks.
- `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix
nemoclaw-user --doc-platform fern-mdx` passed.
- `bash test/e2e/e2e-cloud-experimental/check-docs.sh --only-links
--local-only --with-skills` passed.
- `git diff --check` passed.
- `make docs` was attempted but blocked before MDX validation because
`npx` received HTTP 403 fetching `fern-api` from npm.

---
Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Released v0.0.46: improved Windows setup, WhatsApp messaging support,
Hermes sandbox/tool routing, Anthropic endpoint compatibility, Ollama
proxy routing, model-router fallback, OpenClaw plugin/backup
compatibility, sandbox build tooling fixes, and updated uninstall flag
behavior.

* **Documentation**
* Removed WeChat from messaging flows and presets across guides and CLI
docs; clarified onboarding and channel setup for WhatsApp. Clarified
runtime mutability and filesystem (Landlock) behavior — some changes
require sandbox rebuilds; prefer host-side commands for durable config.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/NVIDIA/NemoClaw/pull/3911?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@wscurran wscurran added area: integrations Third-party service integration behavior area: messaging Messaging channels, bridges, manifests, or channel lifecycle bug-fix PR fixes a bug or regression feature PR adds or expands user-visible functionality and removed enhancement: feature labels Jun 3, 2026
@wscurran wscurran removed the bug-fix PR fixes a bug or regression label Jun 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: integrations Third-party service integration behavior area: messaging Messaging channels, bridges, manifests, or channel lifecycle feature PR adds or expands user-visible functionality integration: whatsapp WhatsApp integration or channel behavior v0.0.46 Release target

Projects

None yet

6 participants