Skip to content

feat(onboard): add SLACK_ALLOWED_CHANNELS support for channel allowlisting#1757

Merged
ericksoa merged 6 commits into
NVIDIA:mainfrom
filipenf:slack-allowed-channels
May 26, 2026
Merged

feat(onboard): add SLACK_ALLOWED_CHANNELS support for channel allowlisting#1757
ericksoa merged 6 commits into
NVIDIA:mainfrom
filipenf:slack-allowed-channels

Conversation

@filipenf

@filipenf filipenf commented Apr 10, 2026

Copy link
Copy Markdown

Summary

Slack's groupPolicy defaults to allowlist but NemoClaw had no way to bake channel IDs into openclaw.json at image build time, leaving all channels blocked after onboarding with no CLI workaround. This adds SLACK_ALLOWED_CHANNELS support parallel to the existing TELEGRAM_ALLOWED_IDS mechanism.

Related Issue

Changes

  • Dockerfile: add NEMOCLAW_SLACK_ALLOWED_CHANNELS_B64 ARG/ENV and write channels.slack.accounts.default.channels in the Python config generation script when the list is non-empty
  • src/lib/onboard.ts: add userIdEnvKey/allowIdsMode/userIdLabel to the Slack entry in MESSAGING_CHANNELS; collect SLACK_ALLOWED_CHANNELS into slackAllowedChannels; add param and replacement block to patchStagedDockerfile
  • test/onboard.test.ts: add test verifying the build arg is correctly base64-encoded with the expected channel IDs
  • docs/deployment/set-up-slack-bridge.md: new how-to guide for Slack setup including Socket Mode, token collection, and channel allowlisting
  • docs/reference/architecture.md: add SLACK_BOT_TOKEN, SLACK_APP_TOKEN, and SLACK_ALLOWED_CHANNELS to the env var table

Type of Change

  • Code change with doc updates.

Testing

  • npx prek run --all-files passes (or equivalently make check).
  • npm test passes.

Manual verification:

SLACK_BOT_TOKEN=xoxb-... \
SLACK_APP_TOKEN=xapp-... \
SLACK_ALLOWED_CHANNELS="C0ARSP0MLMA" \
nemoclaw onboard --recreate-sandbox

openshell sandbox download <name> /sandbox/.openclaw/openclaw.json /tmp/oc.json
jq '.channels.slack.accounts.default.channels' /tmp/oc.json
# expect: { "C0ARSP0MLMA": { "enabled": true } }

Checklist

General

Code Changes

  • Formatters applied — npx prek run --all-files auto-fixes formatting (or make format for targeted runs).
  • Tests added or updated for new or changed behavior.
  • No secrets, API keys, or credentials committed.
  • Doc pages updated for any user-facing behavior changes.

Doc Changes

  • New page (set-up-slack-bridge.md) includes SPDX header and frontmatter.
  • Cross-references and links verified.

Signed-off-by: Filipe Felisbino filipenf@gmail.com

Summary by CodeRabbit

  • New Features

    • Slack Socket Mode bridge with bot and app-level token support
    • Sandbox build-time Slack channel allowlist baked into images to control which channels can trigger agents
    • Onboarding supports interactive or env-based Slack token provisioning and requires sandbox recreation when tokens/allowlist change; option to apply a Slack network policy
  • Documentation

    • New Slack setup guide and updated reference docs with env/config, scopes, onboarding flow, and verification checklist
  • Tests

    • Added test validating Slack channel allowlist handling

@coderabbitai

coderabbitai Bot commented Apr 10, 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 Slack Socket Mode support: docs and onboarding flows, new Slack sandbox env vars and a Docker build-time allowlist arg, onboarding logic to bake channel allowlists into staged Dockerfiles, and a unit test verifying allowlist injection.

Changes

Cohort / File(s) Summary
Documentation – Slack Setup & Reference
.agents/skills/nemoclaw-user-deploy-remote/SKILL.md, docs/deployment/set-up-slack-bridge.md, docs/reference/architecture.md, .agents/skills/nemoclaw-user-reference/references/architecture.md
Adds Slack onboarding and Socket Mode guidance; documents SLACK_BOT_TOKEN, SLACK_APP_TOKEN, and SLACK_ALLOWED_CHANNELS; explains token provisioning, required scopes/events, channel allowlist behavior, sandbox-recreate requirement, and slack policy. Renumbers Telegram steps.
Docker Configuration
Dockerfile
Adds build ARG NEMOCLAW_SLACK_ALLOWED_CHANNELS_B64 and ENV passthrough; build logic decodes the ARG and, when present, injects Slack appToken and a channels allowmap under slack.accounts.default.
Onboarding Logic
src/lib/onboard.ts
patchStagedDockerfile(...) gains slackAllowedChannels param to write base64-encoded allowlist ARG; createSandbox(...) parses SLACK_ALLOWED_CHANNELS (when SLACK_BOT_TOKEN enabled) and passes allowlist into Dockerfile staging; updates Slack metadata/help text.
Tests
test/onboard.test.ts
Adds Vitest that patches a temporary Dockerfile with NEMOCLAW_SLACK_ALLOWED_CHANNELS_B64, decodes/parses the ARG and asserts it matches the provided allowlist; cleans up fixture.
Skill Docs Update
.agents/skills/nemoclaw-user-deploy-remote/SKILL.md
Refocused messaging bridge docs to include Slack alongside existing Telegram steps; added Slack onboarding flow and updated step numbering for Telegram.

Sequence Diagram

sequenceDiagram
    actor User
    participant Onboard as Onboarding
    participant Provider as OpenShellProvider
    participant Docker as DockerBuild
    participant Sandbox as SandboxImage

    User->>Onboard: run `nemoclaw onboard` (provide SLACK_BOT_TOKEN, optional SLACK_APP_TOKEN, SLACK_ALLOWED_CHANNELS)
    Onboard->>Provider: persist tokens as providers (not injected into sandbox)
    Onboard->>Onboard: parse SLACK_ALLOWED_CHANNELS → JSON → Base64
    Onboard->>Docker: patch staged Dockerfile with ARG NEMOCLAW_SLACK_ALLOWED_CHANNELS_B64
    Docker->>Docker: decode ARG, merge channels into slack.accounts.default.channels
    Docker->>Sandbox: build image with allowlist baked in
    Onboard->>User: advise `nemoclaw onboard --recreate-sandbox` and `nemoclaw <sandbox> policy-add slack`
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I found a Slack token in the hay,

I wrapped channel lists in Base64 play,
Built the sandbox snug and warm,
Socket Mode beats like a drum,
Hop — deploy, and messages swarm! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately summarizes the main change: adding SLACK_ALLOWED_CHANNELS support for channel allowlisting in the onboarding flow.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@filipenf filipenf marked this pull request as draft April 10, 2026 19:00

@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

🧹 Nitpick comments (5)
docs/reference/architecture.md (1)

191-193: Split into one sentence per line.

Line 193 contains two sentences on the same line. Per the documentation style guide, each sentence should be on its own line to make diffs more readable.

📝 Suggested fix
 | `SLACK_BOT_TOKEN` | Slack bot token (`xoxb-...`) you provide before `nemoclaw onboard`. Stored as an OpenShell provider; never passed directly to the sandbox. |
 | `SLACK_APP_TOKEN` | Slack app-level token (`xapp-...`) required for Socket Mode. Stored alongside `SLACK_BOT_TOKEN` during onboarding. |
-| `SLACK_ALLOWED_CHANNELS` | Comma-separated Slack channel IDs to allowlist (e.g. `C012AB3CD,C987ZY6XW`). Baked into the sandbox image at build time. When unset, no channels are allowed by default. |
+| `SLACK_ALLOWED_CHANNELS` | Comma-separated Slack channel IDs to allowlist (e.g. `C012AB3CD,C987ZY6XW`). Baked into the sandbox image at build time. |

Note: For markdown tables, the "one sentence per line" rule is often relaxed since table cells are inherently single-line. If this is intentional for table formatting, this can be ignored.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/reference/architecture.md` around lines 191 - 193, The table row for
`SLACK_ALLOWED_CHANNELS` contains two sentences on the same line; split that
cell into two sentences on separate lines so each sentence is its own line in
the markdown source (update the `SLACK_ALLOWED_CHANNELS` table cell text to
break after "Baked into the sandbox image at build time." and move "When unset,
no channels are allowed by default." to the next line) to satisfy the
one-sentence-per-line rule for diffs.
src/lib/onboard.ts (1)

2508-2517: Type annotation in @ts-nocheck file.

Line 2511 uses a TypeScript type annotation (const slackAllowedChannels: string[] = []), but the file has // @ts-nocheck`` at the top. While syntactically valid, this is inconsistent with the rest of the file which uses plain JavaScript variable declarations. Consider removing the type annotation for consistency:

-  const slackAllowedChannels: string[] = [];
+  const slackAllowedChannels = [];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/onboard.ts` around lines 2508 - 2517, Remove the TypeScript-specific
type annotation from the slackAllowedChannels declaration to match the file's //
`@ts-nocheck` JavaScript style: change the declaration for slackAllowedChannels
(used alongside enabledTokenEnvKeys and process.env.SLACK_ALLOWED_CHANNELS) to a
plain JS declaration (e.g., const slackAllowedChannels = []) and leave the rest
of the logic (splitting, trimming, filtering, and pushing ids) unchanged.
docs/deployment/set-up-slack-bridge.md (3)

107-113: Missing "Next Steps" section.

Per the documentation style guide, pages should include a "Next Steps" section at the bottom linking to related pages. Consider adding links to related content such as other messaging bridges (Telegram, Discord) or policy preset documentation.

 - Gateway logs inside the sandbox: `openshell sandbox connect <sandbox-name>` then `tail -f /tmp/gateway.log`.
+
+## Next Steps
+
+- [Set Up Telegram Bridge](set-up-telegram-bridge.md) — configure Telegram messaging.
+- [Set Up Discord Bridge](set-up-discord-bridge.md) — configure Discord messaging.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/deployment/set-up-slack-bridge.md` around lines 107 - 113, Add a "Next
Steps" section after the "Confirm Delivery" paragraph that links to related
messaging bridge docs (e.g., Telegram and Discord bridge setup) and to the
policy preset documentation; reference the existing terms in this page
(SLACK_ALLOWED_CHANNELS, the 'slack' policy preset, and the openshell sandbox
troubleshooting command like openshell sandbox connect <sandbox-name>
/tmp/gateway.log) so readers can navigate from confirmation to other bridge
guides and to the policy preset reference.

25-25: One sentence per line.

This line contains two sentences. Per the style guide, each sentence should be on its own line to make diffs more readable.

-NemoClaw supports Slack via Socket Mode — a persistent WebSocket connection that does not require a public URL or inbound firewall rules. The bot and app tokens are stored by OpenShell as secure providers; the sandbox receives placeholder values, not the raw secrets.
+NemoClaw supports Slack via Socket Mode — a persistent WebSocket connection that does not require a public URL or inbound firewall rules.
+The bot and app tokens are stored by OpenShell as secure providers; the sandbox receives placeholder values, not the raw secrets.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/deployment/set-up-slack-bridge.md` at line 25, The sentence "NemoClaw
supports Slack via Socket Mode — a persistent WebSocket connection that does not
require a public URL or inbound firewall rules. The bot and app tokens are
stored by OpenShell as secure providers; the sandbox receives placeholder
values, not the raw secrets." contains two sentences on one line; split them
into two lines so each sentence is its own line in the docs file (update the
line containing the text shown above and ensure the first sentence ends after
"inbound firewall rules." and the second sentence "The bot and app tokens..."
starts on the next line).

89-89: One sentence per line.

Split this into separate lines for better diff readability:

-Channel entries in `/sandbox/.openclaw/openclaw.json` are fixed at image build time. Landlock keeps that path read-only at runtime, so you cannot patch messaging config inside a running sandbox.
+Channel entries in `/sandbox/.openclaw/openclaw.json` are fixed at image build time.
+Landlock keeps that path read-only at runtime, so you cannot patch messaging config inside a running sandbox.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/deployment/set-up-slack-bridge.md` at line 89, The paragraph "Channel
entries in `/sandbox/.openclaw/openclaw.json` are fixed at image build time.
Landlock keeps that path read-only at runtime, so you cannot patch messaging
config inside a running sandbox." should be split into separate lines so each
sentence is on its own line; edit the markdown so the first line is "Channel
entries in `/sandbox/.openclaw/openclaw.json` are fixed at image build time."
and the next line is "Landlock keeps that path read-only at runtime, so you
cannot patch messaging config inside a running sandbox."
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.agents/skills/nemoclaw-user-deploy-remote/SKILL.md:
- Around line 173-175: The onboarding flow in src/lib/onboard.ts never prompts
for or stores SLACK_APP_TOKEN (xapp-...) even though SKILL.md requires it for
Socket Mode; update the Slack branch of the onboarding logic (the function that
collects Slack credentials—e.g., the Slack provider prompt handler /
saveProviderCredentials block) to prompt for SLACK_APP_TOKEN when the provider
is Slack, validate the token format (starts with "xapp-"), and persist it in the
same storage/credentials structure used for SLACK_BOT_TOKEN so the token is
available wherever SLACK_BOT_TOKEN is stored/loaded during runtime.
- Around line 140-226: The README-like skill doc under
.agents/skills/nemoclaw-user-deploy-remote/SKILL.md was edited directly and now
diverges from source (renumbered steps); regenerate this file from the canonical
docs using the documentation script. Run the docs-to-skills generator (python3
scripts/docs-to-skills.py docs/ .agents/skills/ --prefix nemoclaw-user) to
rebuild all .agents/skills/nemoclaw-user-*.md files so the SKILL.md content
(including Step X headings and Slack section) matches the source; commit the
regenerated output and remove manual edits to prevent future drift.

---

Nitpick comments:
In `@docs/deployment/set-up-slack-bridge.md`:
- Around line 107-113: Add a "Next Steps" section after the "Confirm Delivery"
paragraph that links to related messaging bridge docs (e.g., Telegram and
Discord bridge setup) and to the policy preset documentation; reference the
existing terms in this page (SLACK_ALLOWED_CHANNELS, the 'slack' policy preset,
and the openshell sandbox troubleshooting command like openshell sandbox connect
<sandbox-name> /tmp/gateway.log) so readers can navigate from confirmation to
other bridge guides and to the policy preset reference.
- Line 25: The sentence "NemoClaw supports Slack via Socket Mode — a persistent
WebSocket connection that does not require a public URL or inbound firewall
rules. The bot and app tokens are stored by OpenShell as secure providers; the
sandbox receives placeholder values, not the raw secrets." contains two
sentences on one line; split them into two lines so each sentence is its own
line in the docs file (update the line containing the text shown above and
ensure the first sentence ends after "inbound firewall rules." and the second
sentence "The bot and app tokens..." starts on the next line).
- Line 89: The paragraph "Channel entries in `/sandbox/.openclaw/openclaw.json`
are fixed at image build time. Landlock keeps that path read-only at runtime, so
you cannot patch messaging config inside a running sandbox." should be split
into separate lines so each sentence is on its own line; edit the markdown so
the first line is "Channel entries in `/sandbox/.openclaw/openclaw.json` are
fixed at image build time." and the next line is "Landlock keeps that path
read-only at runtime, so you cannot patch messaging config inside a running
sandbox."

In `@docs/reference/architecture.md`:
- Around line 191-193: The table row for `SLACK_ALLOWED_CHANNELS` contains two
sentences on the same line; split that cell into two sentences on separate lines
so each sentence is its own line in the markdown source (update the
`SLACK_ALLOWED_CHANNELS` table cell text to break after "Baked into the sandbox
image at build time." and move "When unset, no channels are allowed by default."
to the next line) to satisfy the one-sentence-per-line rule for diffs.

In `@src/lib/onboard.ts`:
- Around line 2508-2517: Remove the TypeScript-specific type annotation from the
slackAllowedChannels declaration to match the file's // `@ts-nocheck` JavaScript
style: change the declaration for slackAllowedChannels (used alongside
enabledTokenEnvKeys and process.env.SLACK_ALLOWED_CHANNELS) to a plain JS
declaration (e.g., const slackAllowedChannels = []) and leave the rest of the
logic (splitting, trimming, filtering, and pushing ids) unchanged.
🪄 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: Pro

Run ID: 9b7a0dad-a9f0-4f37-a188-cb6752e9dacf

📥 Commits

Reviewing files that changed from the base of the PR and between aa52ed8 and 4b119d5.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • .agents/skills/nemoclaw-user-deploy-remote/SKILL.md
  • .agents/skills/nemoclaw-user-reference/references/architecture.md
  • Dockerfile
  • docs/deployment/set-up-slack-bridge.md
  • docs/reference/architecture.md
  • src/lib/onboard.ts
  • test/onboard.test.ts

Comment thread .agents/skills/nemoclaw-user-deploy-remote/SKILL.md Outdated
Comment thread .agents/skills/nemoclaw-user-deploy-remote/SKILL.md Outdated
@filipenf filipenf force-pushed the slack-allowed-channels branch from 4b119d5 to 2a76ce8 Compare April 10, 2026 19:48
@filipenf filipenf marked this pull request as ready for review April 10, 2026 20:09
@filipenf filipenf force-pushed the slack-allowed-channels branch from 2a76ce8 to a3ed780 Compare April 10, 2026 20:13

@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.

🧹 Nitpick comments (2)
src/lib/onboard.ts (2)

2513-2522: Minor style inconsistency: explicit type annotation.

Line 2516 uses TypeScript type annotation const slackAllowedChannels: string[] = []; while the rest of the file (under // @ts-nocheck``) avoids explicit type annotations. This works but is stylistically inconsistent.

♻️ Optional: remove explicit type annotation for consistency
-  const slackAllowedChannels: string[] = [];
+  const slackAllowedChannels = [];

Otherwise, the logic is correct — it properly parses the comma-separated channel IDs, filters empty strings, and only populates when both Slack is enabled and channels are specified.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/onboard.ts` around lines 2513 - 2522, Remove the explicit TypeScript
type annotation on the slackAllowedChannels declaration to match the file's
style (the code under // `@ts-nocheck` avoids explicit types); locate the const
slackAllowedChannels declaration and change it from a typed declaration to an
untyped one (leaving the rest of the logic that checks
enabledTokenEnvKeys.has("SLACK_BOT_TOKEN") and parses
process.env.SLACK_ALLOWED_CHANNELS intact).

762-764: Consider importing encodeDockerJsonArg from web-search.ts instead of duplicating it.

This function is already exported from src/lib/web-search.ts (line 10-12). The local copy creates a maintenance burden — if the encoding logic ever needs to change, both copies must be updated.

♻️ Suggested refactor
 const webSearch = require("./web-search");
+const { encodeDockerJsonArg } = webSearch;
 
-function encodeDockerJsonArg(value) {
-  return Buffer.from(JSON.stringify(value || {}), "utf8").toString("base64");
-}

Alternatively, if you prefer to keep imports at the top unchanged, you can reference it via the existing import:

// Replace calls to encodeDockerJsonArg(...) with:
webSearch.encodeDockerJsonArg(...)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/onboard.ts` around lines 762 - 764, Duplicate encodeDockerJsonArg
implementation in onboard.ts should be removed and the existing exported
function from src/lib/web-search.ts reused; replace local function usage with
the imported encodeDockerJsonArg (or call it via the existing webSearch import
if present) so there’s a single source of truth for encodeDockerJsonArg and
avoid duplicated encoding logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/lib/onboard.ts`:
- Around line 2513-2522: Remove the explicit TypeScript type annotation on the
slackAllowedChannels declaration to match the file's style (the code under //
`@ts-nocheck` avoids explicit types); locate the const slackAllowedChannels
declaration and change it from a typed declaration to an untyped one (leaving
the rest of the logic that checks enabledTokenEnvKeys.has("SLACK_BOT_TOKEN") and
parses process.env.SLACK_ALLOWED_CHANNELS intact).
- Around line 762-764: Duplicate encodeDockerJsonArg implementation in
onboard.ts should be removed and the existing exported function from
src/lib/web-search.ts reused; replace local function usage with the imported
encodeDockerJsonArg (or call it via the existing webSearch import if present) so
there’s a single source of truth for encodeDockerJsonArg and avoid duplicated
encoding logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6daaf20b-b1a8-442f-968a-9f83369ef7be

📥 Commits

Reviewing files that changed from the base of the PR and between 4b119d5 and 2a76ce8.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • .agents/skills/nemoclaw-user-deploy-remote/SKILL.md
  • .agents/skills/nemoclaw-user-reference/references/architecture.md
  • Dockerfile
  • docs/deployment/set-up-slack-bridge.md
  • docs/reference/architecture.md
  • src/lib/onboard.ts
  • test/onboard.test.ts
✅ Files skipped from review due to trivial changes (4)
  • docs/reference/architecture.md
  • .agents/skills/nemoclaw-user-reference/references/architecture.md
  • docs/deployment/set-up-slack-bridge.md
  • test/onboard.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • .agents/skills/nemoclaw-user-deploy-remote/SKILL.md

@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: 4

♻️ Duplicate comments (1)
.agents/skills/nemoclaw-user-deploy-remote/SKILL.md (1)

1-293: ⚠️ Potential issue | 🟠 Major

Regenerate this skill file from docs/ instead of editing it directly.

This file path is under .agents/skills/nemoclaw-user-*/*.md, so direct edits should be replaced by generated output from the docs source to avoid drift.

As per coding guidelines, ".agents/skills/nemoclaw-user-/.md: Never edit .agents/skills/nemoclaw-user-*/*.md directly; regenerate skills from docs/ source".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.agents/skills/nemoclaw-user-deploy-remote/SKILL.md around lines 1 - 293,
This skill markdown was edited directly under
.agents/skills/nemoclaw-user-deploy-remote/SKILL.md but must be regenerated from
the canonical docs source; revert this file and regenerate the skill from docs/
(update the source docs entry that defines the "nemoclaw-user-deploy-remote"
skill or the "NemoClaw User Deploy Remote" document, then run the docs→skills
generation step) so the generated SKILL.md matches the docs source and avoids
direct edits in .agents/skills/nemoclaw-user-*/*.md.
🧹 Nitpick comments (1)
src/lib/onboard.ts (1)

3659-3676: Consider extracting channel-specific follow-up prompts.

This adds another nested special case inside an already stateful prompt loop. Pulling Slack/Discord extras into per-channel handlers would make future channel additions safer and keep this flow closer to the repo's complexity target. As per coding guidelines, "Limit cyclomatic complexity to 20 in JavaScript/TypeScript files, with target of 15".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/onboard.ts` around lines 3659 - 3676, The channel-specific app-token
prompt block increases cyclomatic complexity and nests special cases inside the
main onboarding loop; extract this logic into a dedicated per-channel handler
(e.g., a function like handleChannelAppToken(channel) or a channelHandlers map
keyed by channel name) that encapsulates the behavior around getMessagingToken,
prompt/normalizeCredentialValue, saveCredential, and setting process.env, and
move any Slack/Discord-specific extras into their own handlers; then replace the
inline block in the loop with a single call to that handler (pass ch,
ch.appTokenEnvKey, ch.appTokenHelp, ch.appTokenLabel, ch.name) so the loop stays
simple and future channels can add custom flows without increasing the main
function's complexity.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.agents/skills/nemoclaw-user-deploy-remote/SKILL.md:
- Around line 197-198: The doc line about creating a provider for the bot token
is inaccurate: update the sentence to state that onboarding creates providers
for both SLACK_BOT_TOKEN and SLACK_APP_TOKEN (in addition to baking
NEMOCLAW_SLACK_ALLOWED_CHANNELS_B64 into the image and starting the sandbox), so
replace the phrase "creates an OpenShell provider for the bot token" with
wording that explicitly references both SLACK_BOT_TOKEN and SLACK_APP_TOKEN
providers.

In `@Dockerfile`:
- Line 138: The current line unconditionally injects the placeholder
openshell:resolve:env:SLACK_APP_TOKEN into
_ch_cfg['slack']['accounts']['default'] which breaks the "no Socket Mode" path
when no app token provider/env exists; change the logic in the Dockerfile
snippet so you only call
_ch_cfg['slack']['accounts']['default'].update({'appToken':
'openshell:resolve:env:SLACK_APP_TOKEN'}) if 'slack' in _ch_cfg AND the
SLACK_APP_TOKEN provider/env is actually present and non-empty (e.g., check for
existence/non-empty value before updating), so the appToken key is only added
when a real app token will be resolvable.

In `@src/lib/onboard.ts`:
- Around line 3519-3523: The follow-up logging in setupMessagingChannels() still
uses "user ID"/"manual pairing" copy when allowIdsMode is set to "channel";
update setupMessagingChannels() to special-case allowIdsMode === "channel" (like
it already does for "guild") and change the log strings and user-facing messages
to refer to "Slack channel ID(s)", "channel allowlist", and "channels remain
blocked until configured" instead of user/pairing wording; ensure any references
to manual pairing or user IDs (e.g., in prompts, help text, and processLogger
messages) are replaced with channel-specific phrasing so the behavior matches
userIdHelp/userIdLabel and the "channel" mode semantics.
- Around line 2328-2332: The SLACK_APP_TOKEN entry is being dropped by the
enabledEnvKeys filter because the Slack provider only contributes its primary
envKey (SLACK_BOT_TOKEN); update the provider selection so secondary tokens are
preserved: change the enabledEnvKeys computation or the logic inside
upsertMessagingProviders to include all envKey values from messaging provider
definitions (not just the primary one), so entries created with
getMessagingToken("SLACK_APP_TOKEN") are retained and passed through to Socket
Mode; alternatively, explicitly add "SLACK_APP_TOKEN" to the set contributed by
the Slack provider alongside "SLACK_BOT_TOKEN" to ensure it survives the
filtering that currently prevents the fallback path.

---

Duplicate comments:
In @.agents/skills/nemoclaw-user-deploy-remote/SKILL.md:
- Around line 1-293: This skill markdown was edited directly under
.agents/skills/nemoclaw-user-deploy-remote/SKILL.md but must be regenerated from
the canonical docs source; revert this file and regenerate the skill from docs/
(update the source docs entry that defines the "nemoclaw-user-deploy-remote"
skill or the "NemoClaw User Deploy Remote" document, then run the docs→skills
generation step) so the generated SKILL.md matches the docs source and avoids
direct edits in .agents/skills/nemoclaw-user-*/*.md.

---

Nitpick comments:
In `@src/lib/onboard.ts`:
- Around line 3659-3676: The channel-specific app-token prompt block increases
cyclomatic complexity and nests special cases inside the main onboarding loop;
extract this logic into a dedicated per-channel handler (e.g., a function like
handleChannelAppToken(channel) or a channelHandlers map keyed by channel name)
that encapsulates the behavior around getMessagingToken,
prompt/normalizeCredentialValue, saveCredential, and setting process.env, and
move any Slack/Discord-specific extras into their own handlers; then replace the
inline block in the loop with a single call to that handler (pass ch,
ch.appTokenEnvKey, ch.appTokenHelp, ch.appTokenLabel, ch.name) so the loop stays
simple and future channels can add custom flows without increasing the main
function's complexity.
🪄 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: Pro

Run ID: 78f373b4-3ded-40c3-a341-39b8030b4f70

📥 Commits

Reviewing files that changed from the base of the PR and between 2a76ce8 and a3ed780.

📒 Files selected for processing (7)
  • .agents/skills/nemoclaw-user-deploy-remote/SKILL.md
  • .agents/skills/nemoclaw-user-reference/references/architecture.md
  • Dockerfile
  • docs/deployment/set-up-slack-bridge.md
  • docs/reference/architecture.md
  • src/lib/onboard.ts
  • test/onboard.test.ts
✅ Files skipped from review due to trivial changes (2)
  • docs/reference/architecture.md
  • docs/deployment/set-up-slack-bridge.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .agents/skills/nemoclaw-user-reference/references/architecture.md

Comment thread .agents/skills/nemoclaw-user-deploy-remote/SKILL.md Outdated
Comment thread Dockerfile Outdated
Comment thread src/lib/onboard.ts
Comment thread src/lib/onboard.ts Outdated
@wscurran wscurran added enhancement: feature integration: slack Slack integration or channel behavior labels Apr 13, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for submitting this PR, which proposes a new feature to add support for SLACK_ALLOWED_CHANNELS.

@filipenf filipenf force-pushed the slack-allowed-channels branch from a3ed780 to 7953ad3 Compare April 14, 2026 13:50
…sting

Slack's default groupPolicy is "allowlist" but NemoClaw provided no way
to bake channel IDs into openclaw.json at image build time, leaving all
channels blocked after onboarding with no CLI workaround.

This change adds SLACK_ALLOWED_CHANNELS (comma-separated Slack channel
IDs) parallel to the existing TELEGRAM_ALLOWED_IDS mechanism. The IDs
are base64-encoded into a new NEMOCLAW_SLACK_ALLOWED_CHANNELS_B64
Dockerfile ARG and written into channels.slack.accounts.default.channels
at image build time.

- Dockerfile: add NEMOCLAW_SLACK_ALLOWED_CHANNELS_B64 ARG/ENV and write
  the channels map in the Python config generation script
- src/lib/onboard.ts: add userIdEnvKey/allowIdsMode to the Slack
  MESSAGING_CHANNELS entry; collect and inject slackAllowedChannels
  into patchStagedDockerfile
- test/onboard.test.ts: add test for Slack channel allowlist build arg
- docs/deployment/set-up-slack-bridge.md: new how-to guide for Slack
  setup including Socket Mode, token collection, and channel allowlisting
- docs/reference/architecture.md: document SLACK_BOT_TOKEN,
  SLACK_APP_TOKEN, and SLACK_ALLOWED_CHANNELS env vars
@filipenf filipenf force-pushed the slack-allowed-channels branch from 7953ad3 to 81d426a Compare April 14, 2026 13:54

@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)
Dockerfile (1)

138-138: ⚠️ Potential issue | 🟠 Major

Only write appToken when the app-token provider is actually wired in.

Line 138 still bakes openshell:resolve:env:SLACK_APP_TOKEN into every Slack config, but src/lib/onboard.ts only creates the SLACK_APP_TOKEN provider when that token already exists. Fresh Slack sandboxes can still end up with an unresolvable secret reference.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Dockerfile` at line 138, The Dockerfile currently unconditionally injects the
unresolved secret reference via
_ch_cfg['slack']['accounts']['default'].update({'appToken':
'openshell:resolve:env:SLACK_APP_TOKEN'}), which can produce an unresolvable
secret for fresh sandboxes; change this to only add the appToken entry when the
SLACK_APP_TOKEN provider will actually be created (the logic in
src/lib/onboard.ts). Concretely, guard or conditionalize the update so it only
runs if the SLACK_APP_TOKEN provider/flag (or an env check like presence of
SLACK_APP_TOKEN) is present, leaving the slack.accounts.default config untouched
otherwise. Ensure you reference and use the same signal that onboard.ts uses to
decide wiring the provider so configs remain consistent.
🧹 Nitpick comments (1)
src/lib/onboard.ts (1)

2569-2590: Consider extracting messaging-config assembly out of createSandbox().

This adds another provider-specific branch to an already very large function. Pulling the messagingAllowedIds / discordGuilds / slackAllowedChannels harvesting into a helper would make the flow easier to reason about and keep it closer to the repo's complexity target.

As per coding guidelines, "Limit cyclomatic complexity to 20 in JavaScript/TypeScript files, with target of 15".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/onboard.ts` around lines 2569 - 2590, The createSandbox() function is
getting large and includes provider-specific harvesting of messagingAllowedIds,
discordGuilds, and slackAllowedChannels; extract that logic into a new helper
(e.g., assembleMessagingConfig or buildMessagingChannels) that accepts the
inputs used inside createSandbox (env, enabledTokenEnvKeys, etc.) and returns an
object { messagingAllowedIds, discordGuilds, slackAllowedChannels,
activeMessagingChannels } (or individual values); replace the inlined code in
createSandbox() with a single call to that helper and pass the returned values
into patchStagedDockerfile and other call sites, ensuring all referenced symbols
(messagingAllowedIds, discordGuilds, slackAllowedChannels, createSandbox,
patchStagedDockerfile) still compile and tests cover the refactor.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/onboard.ts`:
- Around line 3571-3574: The onboarding metadata added
appTokenEnvKey/appTokenLabel/appTokenHelp are never used by the interactive
wizard, so update setupMessagingChannels to include and prompt for the new
appTokenEnvKey (in addition to ch.envKey) when the selected channel/provider is
Slack: modify the logic in setupMessagingChannels that builds the prompt list
for a channel (look for references to ch.envKey and Slack-specific branches) to
add a second prompt entry for ch.appTokenEnvKey (or use the metadata field name
appTokenEnvKey) with label appTokenLabel and help appTokenHelp, validate and
save the provided value into the same store where ch.envKey is persisted so
first-time Slack onboarding can populate SLACK_APP_TOKEN.

---

Duplicate comments:
In `@Dockerfile`:
- Line 138: The Dockerfile currently unconditionally injects the unresolved
secret reference via _ch_cfg['slack']['accounts']['default'].update({'appToken':
'openshell:resolve:env:SLACK_APP_TOKEN'}), which can produce an unresolvable
secret for fresh sandboxes; change this to only add the appToken entry when the
SLACK_APP_TOKEN provider will actually be created (the logic in
src/lib/onboard.ts). Concretely, guard or conditionalize the update so it only
runs if the SLACK_APP_TOKEN provider/flag (or an env check like presence of
SLACK_APP_TOKEN) is present, leaving the slack.accounts.default config untouched
otherwise. Ensure you reference and use the same signal that onboard.ts uses to
decide wiring the provider so configs remain consistent.

---

Nitpick comments:
In `@src/lib/onboard.ts`:
- Around line 2569-2590: The createSandbox() function is getting large and
includes provider-specific harvesting of messagingAllowedIds, discordGuilds, and
slackAllowedChannels; extract that logic into a new helper (e.g.,
assembleMessagingConfig or buildMessagingChannels) that accepts the inputs used
inside createSandbox (env, enabledTokenEnvKeys, etc.) and returns an object {
messagingAllowedIds, discordGuilds, slackAllowedChannels,
activeMessagingChannels } (or individual values); replace the inlined code in
createSandbox() with a single call to that helper and pass the returned values
into patchStagedDockerfile and other call sites, ensuring all referenced symbols
(messagingAllowedIds, discordGuilds, slackAllowedChannels, createSandbox,
patchStagedDockerfile) still compile and tests cover the refactor.
🪄 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: Pro Plus

Run ID: fab57749-ae5c-4363-9f76-b591a777f120

📥 Commits

Reviewing files that changed from the base of the PR and between a3ed780 and 7953ad3.

📒 Files selected for processing (7)
  • .agents/skills/nemoclaw-user-deploy-remote/SKILL.md
  • .agents/skills/nemoclaw-user-reference/references/architecture.md
  • Dockerfile
  • docs/deployment/set-up-slack-bridge.md
  • docs/reference/architecture.md
  • src/lib/onboard.ts
  • test/onboard.test.ts
✅ Files skipped from review due to trivial changes (3)
  • test/onboard.test.ts
  • docs/deployment/set-up-slack-bridge.md
  • .agents/skills/nemoclaw-user-reference/references/architecture.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/reference/architecture.md
  • .agents/skills/nemoclaw-user-deploy-remote/SKILL.md

Comment thread src/lib/onboard.ts Outdated

@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.

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

3709-3713: ⚠️ Potential issue | 🟡 Minor

The new "channel" allowlist mode still reuses DM/pairing copy.

setupMessagingChannels() only special-cases "guild", so Slack still prints "allowed IDs already set", "user ID saved", and "manual pairing" messaging for this path. That makes the new channel allowlist flow read like DM pairing instead of channel gating.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/onboard.ts` around lines 3709 - 3713, setupMessagingChannels
currently only treats allowIdsMode "guild" as a special case, so when
allowIdsMode is "channel" the code reuses DM/pairing messages like "allowed IDs
already set", "user ID saved", and "manual pairing"; update
setupMessagingChannels to detect allowIdsMode === "channel" and provide
channel-specific messaging and flow (e.g., replace user/DM/pairing text with
channel-focused text such as "channel IDs already set", "channel ID saved", and
instructions for manual channel gating) ensuring any branches that reference
allowIdsMode or the labels "Slack Channel IDs (optional allowlist)" use the new
channel-specific strings and logic.

3705-3708: ⚠️ Potential issue | 🟠 Major

Slack can still be enabled without SLACK_APP_TOKEN.

These new fields are only metadata right now: setupMessagingChannels() never prompts for ch.appTokenEnvKey, and createSandbox() still enables Slack from SLACK_BOT_TOKEN alone. First-time onboarding can therefore finish with a Slack bridge that cannot connect in Socket Mode.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/onboard.ts` around lines 3705 - 3708, The new Slack app token
metadata (ch.appTokenEnvKey / "SLACK_APP_TOKEN") is only descriptive right now,
so onboarding can finish with Slack enabled but missing the App-Level token
required for Socket Mode: update setupMessagingChannels() to prompt for and save
ch.appTokenEnvKey when the user selects Slack and chooses Socket Mode (or when
Socket Mode is required), and update createSandbox() to validate presence of
both SLACK_BOT_TOKEN and SLACK_APP_TOKEN before enabling Socket Mode (or fall
back to disabling Socket Mode and log/warn clearly); ensure references to
ch.appTokenEnvKey, SLACK_APP_TOKEN and SLACK_BOT_TOKEN are used for the presence
check so the sandbox isn't created in a broken state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/lib/onboard.ts`:
- Around line 3709-3713: setupMessagingChannels currently only treats
allowIdsMode "guild" as a special case, so when allowIdsMode is "channel" the
code reuses DM/pairing messages like "allowed IDs already set", "user ID saved",
and "manual pairing"; update setupMessagingChannels to detect allowIdsMode ===
"channel" and provide channel-specific messaging and flow (e.g., replace
user/DM/pairing text with channel-focused text such as "channel IDs already
set", "channel ID saved", and instructions for manual channel gating) ensuring
any branches that reference allowIdsMode or the labels "Slack Channel IDs
(optional allowlist)" use the new channel-specific strings and logic.
- Around line 3705-3708: The new Slack app token metadata (ch.appTokenEnvKey /
"SLACK_APP_TOKEN") is only descriptive right now, so onboarding can finish with
Slack enabled but missing the App-Level token required for Socket Mode: update
setupMessagingChannels() to prompt for and save ch.appTokenEnvKey when the user
selects Slack and chooses Socket Mode (or when Socket Mode is required), and
update createSandbox() to validate presence of both SLACK_BOT_TOKEN and
SLACK_APP_TOKEN before enabling Socket Mode (or fall back to disabling Socket
Mode and log/warn clearly); ensure references to ch.appTokenEnvKey,
SLACK_APP_TOKEN and SLACK_BOT_TOKEN are used for the presence check so the
sandbox isn't created in a broken state.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a1288a32-ce47-4d02-9086-4d26b5fd16fd

📥 Commits

Reviewing files that changed from the base of the PR and between 7953ad3 and 81d426a.

📒 Files selected for processing (7)
  • .agents/skills/nemoclaw-user-deploy-remote/SKILL.md
  • .agents/skills/nemoclaw-user-reference/references/architecture.md
  • Dockerfile
  • docs/deployment/set-up-slack-bridge.md
  • docs/reference/architecture.md
  • src/lib/onboard.ts
  • test/onboard.test.ts
✅ Files skipped from review due to trivial changes (4)
  • docs/reference/architecture.md
  • .agents/skills/nemoclaw-user-reference/references/architecture.md
  • test/onboard.test.ts
  • docs/deployment/set-up-slack-bridge.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • Dockerfile

@wscurran

Copy link
Copy Markdown
Contributor

Thanks for contributing — SLACK_ALLOWED_CHANNELS allowlisting gives teams a meaningful way to scope which channels NemoClaw can interact with. We're still working through how we want to approach third-party integrations more broadly, so this has been tagged for that evaluation. We'll follow up once we have clearer guidance on the path forward.

@cv cv closed this May 12, 2026
@cv cv reopened this May 12, 2026
@copy-pr-bot

copy-pr-bot Bot commented May 12, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@cv cv added the v0.0.51 Release target label May 24, 2026
ericksoa added 2 commits May 25, 2026 07:24
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

# Conflicts:
#	.agents/skills/nemoclaw-user-deploy-remote/SKILL.md
#	Dockerfile
#	src/lib/onboard.ts
#	test/onboard.test.ts
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 26407205250
Target ref: 75e1e230206e1ac39863412818226754563258c4
Workflow ref: main
Requested jobs: all (no filter)
Summary: 48 passed, 2 failed, 2 skipped

Job Result
bedrock-runtime-compatible-anthropic-e2e ✅ success
brave-search-e2e ✅ success
channels-add-remove-e2e ✅ success
channels-stop-start-e2e ✅ success
cloud-e2e ✅ success
cloud-inference-e2e ✅ success
cloud-onboard-e2e ✅ success
credential-migration-e2e ✅ success
credential-sanitization-e2e ✅ success
device-auth-health-e2e ✅ success
diagnostics-e2e ✅ success
docs-validation-e2e ✅ success
double-onboard-e2e ✅ success
gpu-double-onboard-e2e ⏭️ skipped
gpu-e2e ⏭️ skipped
hermes-discord-e2e ✅ success
hermes-e2e ✅ success
hermes-inference-switch-e2e ✅ success
hermes-onboard-security-posture-e2e ✅ success
hermes-slack-e2e ✅ success
inference-routing-e2e ✅ success
issue-2478-crash-loop-recovery-e2e ✅ success
issue-3600-gpu-proof-optional-e2e ✅ success
kimi-inference-compat-e2e ✅ success
launchable-smoke-e2e ✅ success
messaging-compatible-endpoint-e2e ✅ success
messaging-providers-e2e ✅ success
network-policy-e2e ✅ success
onboard-negative-paths-e2e ✅ success
onboard-repair-e2e ✅ success
onboard-resume-e2e ✅ success
openclaw-discord-pairing-e2e ✅ success
openclaw-inference-switch-e2e ✅ success
openclaw-onboard-security-posture-e2e ✅ success
openclaw-slack-pairing-e2e ✅ success
openclaw-tui-chat-correlation-e2e ❌ failure
openshell-gateway-upgrade-e2e ✅ success
overlayfs-autofix-e2e ✅ success
rebuild-hermes-e2e ✅ success
rebuild-hermes-stale-base-e2e ✅ success
rebuild-openclaw-e2e ✅ success
runtime-overrides-e2e ✅ success
sandbox-operations-e2e ✅ success
sandbox-survival-e2e ✅ success
shields-config-e2e ✅ success
skill-agent-e2e ✅ success
snapshot-commands-e2e ✅ success
state-backup-restore-e2e ✅ success
telegram-injection-e2e ✅ success
token-rotation-e2e ✅ success
tunnel-lifecycle-e2e ❌ failure
upgrade-stale-sandbox-e2e ✅ success

Failed jobs: openclaw-tui-chat-correlation-e2e, tunnel-lifecycle-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 26433368796
Target ref: f27d069bdd628ca0cb7c5a0664f33cb9769625d2
Workflow ref: main
Requested jobs: all (no filter)
Summary: 49 passed, 1 failed, 2 skipped

Job Result
bedrock-runtime-compatible-anthropic-e2e ✅ success
brave-search-e2e ✅ success
channels-add-remove-e2e ✅ success
channels-stop-start-e2e ✅ success
cloud-e2e ✅ success
cloud-inference-e2e ✅ success
cloud-onboard-e2e ✅ success
credential-migration-e2e ✅ success
credential-sanitization-e2e ✅ success
device-auth-health-e2e ✅ success
diagnostics-e2e ✅ success
docs-validation-e2e ✅ success
double-onboard-e2e ✅ success
gpu-double-onboard-e2e ⏭️ skipped
gpu-e2e ⏭️ skipped
hermes-discord-e2e ✅ success
hermes-e2e ✅ success
hermes-inference-switch-e2e ✅ success
hermes-onboard-security-posture-e2e ❌ failure
hermes-slack-e2e ✅ success
inference-routing-e2e ✅ success
issue-2478-crash-loop-recovery-e2e ✅ success
issue-3600-gpu-proof-optional-e2e ✅ success
kimi-inference-compat-e2e ✅ success
launchable-smoke-e2e ✅ success
messaging-compatible-endpoint-e2e ✅ success
messaging-providers-e2e ✅ success
network-policy-e2e ✅ success
onboard-negative-paths-e2e ✅ success
onboard-repair-e2e ✅ success
onboard-resume-e2e ✅ success
openclaw-discord-pairing-e2e ✅ success
openclaw-inference-switch-e2e ✅ success
openclaw-onboard-security-posture-e2e ✅ success
openclaw-slack-pairing-e2e ✅ success
openclaw-tui-chat-correlation-e2e ✅ success
openshell-gateway-upgrade-e2e ✅ success
overlayfs-autofix-e2e ✅ success
rebuild-hermes-e2e ✅ success
rebuild-hermes-stale-base-e2e ✅ success
rebuild-openclaw-e2e ✅ success
runtime-overrides-e2e ✅ success
sandbox-operations-e2e ✅ success
sandbox-survival-e2e ✅ success
shields-config-e2e ✅ success
skill-agent-e2e ✅ success
snapshot-commands-e2e ✅ success
state-backup-restore-e2e ✅ success
telegram-injection-e2e ✅ success
token-rotation-e2e ✅ success
tunnel-lifecycle-e2e ✅ success
upgrade-stale-sandbox-e2e ✅ success

Failed jobs: hermes-onboard-security-posture-e2e. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 26449305113
Target ref: bd97f3eada9b85670b1effeba7f77f108abada1a
Workflow ref: main
Requested jobs: hermes-onboard-security-posture-e2e
Summary: 1 passed, 0 failed, 0 skipped

Job Result
hermes-onboard-security-posture-e2e ✅ success

@ericksoa ericksoa 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.

Looks good. Validated with the full nightly sweep plus a focused rerun of hermes-onboard-security-posture-e2e on the current head.

@ericksoa ericksoa enabled auto-merge (squash) May 26, 2026 15:14
@ericksoa ericksoa merged commit 9d68966 into NVIDIA:main May 26, 2026
20 checks passed
@miyoungc miyoungc mentioned this pull request May 26, 2026
12 tasks
miyoungc added a commit that referenced this pull request May 26, 2026
## Summary
Refresh NemoClaw documentation and generated user skills for the v0.0.50
and v0.0.51 release-prep window.
Remove obsolete legacy docs version metadata now that Fern docs no
longer use `docs/project.json`, `docs/versions1.json`, or the legacy
Sphinx config.

## Source summary
- #1757 -> `docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document
Slack channel allowlisting with `SLACK_ALLOWED_CHANNELS`.
- #4134 -> `docs/manage-sandboxes/messaging-channels.mdx`,
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document
Cloudflare named tunnel support through `CLOUDFLARE_TUNNEL_TOKEN`.
- #4186 and #4135 -> `docs/inference/use-local-inference.mdx`,
`docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document
Ollama upgrade and user-local install behavior.
- #4185 -> `docs/network-policy/integration-policy-examples.mdx`,
`docs/about/release-notes.mdx`: Clarify Jira policy validation probes.
- Release cleanup ->
`.claude/skills/nemoclaw-contributor-update-docs/SKILL.md`,
`docs/CONTRIBUTING.md`, `.github/PULL_REQUEST_TEMPLATE.md`,
`scripts/bump-version.ts`: Stop using legacy docs version JSON files and
align docs verification on `npm run docs`.

## Changes
- Add v0.0.50 and v0.0.51 release notes.
- Regenerate NemoClaw user skills from the current Fern docs.
- Remove obsolete `docs/conf.py`, `docs/project.json`, and
`docs/versions1.json`.
- Update docs workflow guidance and PR templates to use `npm run docs`
instead of `make docs`.
- Remove release-version JSON handling from `scripts/bump-version.ts`.

## 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
- [ ] `npm run 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)

Additional verification:
- `python3 scripts/docs-to-skills.py docs/ .agents/skills/ --prefix
nemoclaw-user --doc-platform fern-mdx`
- `npm run build:cli`
- `npx tsc --noEmit --allowSyntheticDefaultImports --module NodeNext
--moduleResolution NodeNext --target ES2022 --types node
scripts/bump-version.ts`
- `ReadLints` on touched docs, skills, template, and script files
- Searched for stale `versions1.json`, `project.json`, and `make docs`
references

Known gaps:
- `npm run docs` was not rerun after cleanup because the earlier Fern
CLI fetch failed with npm registry `403 Forbidden` in this environment.
- A broad `npm run typecheck -- --noEmit` hit an unrelated existing
`scripts/dev-tier-selector.js` type error.

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

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

* **New Features**
* Added resource profiling with CPU/RAM configuration controls for
sandboxes
* Enhanced local Ollama inference with automatic GPU memory-aware model
fallback
* Added `nemoclaw resources` command to display host hardware inventory
* Enabled Cloudflare named tunnel support via environment configuration

* **Documentation**
* Improved setup guides for local inference, sandbox hardening, and
policy validation
* Enhanced troubleshooting for messaging delivery and host service
routing
  * Added release notes for v0.0.50 and v0.0.51

* **Chores**
* Updated build documentation commands from `make docs` to `npm run
docs`

<!-- 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/4262?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 -->
@filipenf filipenf deleted the slack-allowed-channels branch May 29, 2026 14:37
@wscurran wscurran added area: integrations Third-party service integration behavior feature PR adds or expands user-visible functionality and removed enhancement: feature labels Jun 3, 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 feature PR adds or expands user-visible functionality integration: slack Slack integration or channel behavior v0.0.51 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants