Skip to content

fix(onboard): refresh stale reused messaging plan from env inputs - #5788

Merged
cv merged 2 commits into
mainfrom
fix/5680-telegram-reachability-reuse
Jun 26, 2026
Merged

fix(onboard): refresh stale reused messaging plan from env inputs#5788
cv merged 2 commits into
mainfrom
fix/5680-telegram-reachability-reuse

Conversation

@yimoj

@yimoj yimoj commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

Non-interactive nemoclaw onboard reusing an existing sandbox whose stored messaging plan has zero active channels (the reporter's empty/stale Messaging: none state) silently refreshed credential hashes and skipped messaging channel setup. Newly supplied messaging env inputs (e.g. TELEGRAM_BOT_TOKEN) were never discovered, so the Telegram getMe reachability probe was bypassed even with NEMOCLAW_SKIP_TELEGRAM_REACHABILITY unset. This fix makes the reused-sandbox path honor fresh messaging env inputs so the reachability probe runs.

Related Issue

Fixes #5680

Changes

  • src/lib/onboard/machine/handlers/sandbox.ts: in the reused-registryMessagingPlan branch, when the plan has no active channels but this run supplies complete messaging env inputs, rebuild the plan via setupMessagingChannels (which runs channel reachability checks) instead of silently refreshing hashes. Plans that already have active channels are preserved as-is, so an existing channel is never dropped when its token is absent from this run. The explicit env-staged plan branch above stays authoritative for rebuild/resume.
  • src/lib/onboard/messaging-channel-setup.ts: add detectMessagingChannelsFromEnv, a pure, side-effect-free probe that reports which built-in channels currently have complete required inputs, reusing the same manifest input rules as setupMessagingChannels. NEMOCLAW_POLICY_PRESETS is intentionally ignored — policy presets are not messaging channel selection.
  • Tests for both the rebuild path and the preserve-active-channel regression guard, plus unit coverage of detectMessagingChannelsFromEnv (including that NEMOCLAW_POLICY_PRESETS=telegram alone does not select messaging).

Type of Change

  • Code change (feature, bug fix, or refactor)

Verification

  • PR description includes the DCO sign-off declaration and every commit appears as Verified in GitHub
  • Git hooks passed during commit and push
  • Targeted tests pass for changed behavior (sandbox.test.ts, messaging-channel-setup.test.ts — 39 tests)
  • Full npm test (cli project) passes — 8126 passed, 18 skipped
  • Tests added or updated for new or changed behavior
  • No secrets, API keys, or credentials committed
  • Docs reviewed — no user-facing doc changes required (internal onboarding state-machine correctness fix; no new flags/env/API)

End-to-end verification (real worktree CLI vs live OpenShell 0.0.44 sandbox)

Built the worktree CLI (npm run build:cli) and drove real node ./bin/nemoclaw.js onboard commands against a live OpenShell 0.0.44 Docker-driver sandbox (CPU host, hosted NVIDIA Endpoints inference). Created the reporter's buggy state — a sandbox compat-tg-5680 whose registry messaging plan is non-null with zero active channels (telegram configured-but-disabled) — then ran the reporter workflow with a fake TELEGRAM_BOT_TOKEN and NEMOCLAW_SKIP_TELEGRAM_REACHABILITY unset.

Exact command (same for both builds):

export NVIDIA_INFERENCE_API_KEY=...                 # hosted inference
export TELEGRAM_BOT_TOKEN="123456789:AAFfake-token-for-5680-e2e-reproduction-xyz"
export TELEGRAM_ALLOWED_IDS="123456789"
export NEMOCLAW_POLICY_PRESETS="telegram"
export NEMOCLAW_NON_INTERACTIVE=1 NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE=1
export NEMOCLAW_SANDBOX_NAME=compat-tg-5680
unset NEMOCLAW_SKIP_TELEGRAM_REACHABILITY
node ./bin/nemoclaw.js onboard --non-interactive --no-gpu --no-sandbox-gpu --yes-i-accept-third-party-software

Unpatched build (bug reproduced — probe silently bypassed):

  Messaging:     none
  [non-interactive] Sandbox 'compat-tg-5680' exists and is ready — reusing it
  [non-interactive] Applying policy presets: telegram

(No [5/8] Messaging channels, no reachability output — matches the reporter's exact observation.)

Patched build (fixed — messaging setup + reachability probe run):

  Messaging:     none
  [non-interactive] Detected messaging channel inputs for telegram; refreshing reused sandbox messaging plan.
  [5/8] Messaging channels
  [non-interactive] Messaging channel inputs detected: telegram
  Telegram integration will be disabled for this enrollment run because api.telegram.org is unreachable.
  [non-interactive] Sandbox 'compat-tg-5680' exists and is ready — reusing it

The patched run discovers the env-supplied Telegram input on the reused sandbox and runs the getMe reachability probe, emitting reachability diagnostics instead of silently skipping. (This E2E host's egress to api.telegram.org is firewall-blocked, so the probe reports "unreachable" rather than a token rejection — both prove the probe executed rather than being bypassed; on a host that can reach Telegram a fake token yields the Telegram bot token was rejected. log.) The test sandbox was destroyed after verification.


Signed-off-by: Yimo Jiang yimoj@nvidia.com

Summary by CodeRabbit

  • New Features

    • Added environment-aware detection of supported messaging channels, improving onboarding and resume behavior when messaging is already configured.
  • Bug Fixes

    • Fixed reused messaging-plan handling when prior channels are no longer active: onboarding now refreshes the plan from current environment configuration.
    • Avoided unnecessary messaging-plan rebuilds when an existing active channel remains valid, even if additional environment inputs are present.
  • Tests

    • Expanded coverage for environment-based messaging channel detection and reused-plan scenarios.

Supersedes #5715 (reopened from NVIDIA/NemoClaw branch so trusted advisor workflows can run).

Non-interactive `nemoclaw onboard` reusing an existing sandbox whose
registry messaging plan has zero active channels (the reporter's empty/
stale "Messaging: none" state) silently refreshed credential hashes and
skipped messaging channel setup. Newly supplied messaging env inputs
(e.g. TELEGRAM_BOT_TOKEN) were never discovered, so the Telegram getMe
reachability probe was bypassed even with NEMOCLAW_SKIP_TELEGRAM_REACHABILITY
unset.

When the reused registry plan has no active channels but this run supplies
complete messaging env inputs, rebuild the plan via setupMessagingChannels
so newly supplied channels are discovered and run their reachability checks.
Plans that already have active channels are preserved as-is so an existing
channel is never dropped when its token is absent from this run. Policy
presets alone (NEMOCLAW_POLICY_PRESETS=telegram) do not select messaging.

Adds detectMessagingChannelsFromEnv, a pure manifest-input probe reusing the
same input rules as setupMessagingChannels, to compare current env inputs
against the reused plan before treating it as authoritative.

Fixes #5680

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 326deece-6896-47f0-a7d4-3e2bab4e6949

📥 Commits

Reviewing files that changed from the base of the PR and between 47a3d2c and 8e838af.

📒 Files selected for processing (1)
  • src/lib/onboard/machine/handlers/sandbox.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/onboard/machine/handlers/sandbox.ts

📝 Walkthrough

Walkthrough

Adds environment-based messaging-channel detection and uses it in sandbox onboarding to refresh reused registry messaging plans when registry channels are inactive but env inputs are present. Adds tests for the helper and for the sandbox refresh/preserve paths.

Changes

Messaging channel env detection and sandbox reuse

Layer / File(s) Summary
Env channel detection
src/lib/onboard/messaging-channel-setup.ts, src/lib/onboard/messaging-channel-setup.test.ts
Adds detectMessagingChannelsFromEnv and tests that it selects built-in channels from env-backed inputs and ignores empty or preset-only env states.
Sandbox reuse refresh
src/lib/onboard/machine/handlers/sandbox.ts
Uses env-detected messaging channels in the non-interactive reused-registry path to refresh messaging state when the reused plan has no active channels, otherwise preserving the existing reuse path.
Sandbox reuse tests
src/lib/onboard/machine/handlers/sandbox.test.ts
Adds regression tests for refreshing an empty reused messaging plan from env inputs and preserving an already active reused plan when env adds another channel.

Sequence Diagram(s)

sequenceDiagram
  participant handleSandboxState
  participant detectMessagingChannelsFromEnv
  participant setupMessagingChannels
  participant getSession

  handleSandboxState->>detectMessagingChannelsFromEnv: detect env messaging channels
  detectMessagingChannelsFromEnv-->>handleSandboxState: channel ids

  alt reused registry plan has no active channels and env channels exist
    handleSandboxState->>setupMessagingChannels: rebuild messaging from registry-seeded existing channels
    setupMessagingChannels-->>handleSandboxState: refreshed plan
    handleSandboxState->>getSession: update messagingPlan
  else reused registry plan has active channels or no env channels
    handleSandboxState->>getSession: reuse registry messagingPlan
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

bug-fix, area: messaging, area: cli

Suggested reviewers

  • cv
  • sandl99

Poem

A bunny peered into the sandbox glow,
Sniffed env-tokens in a neat little row.
Empty plans hopped off, fresh ones came near,
Slack stayed snug while Telegram got a cheer.
Squeak! said the rabbit, with whiskers aglow.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: refreshing stale reused messaging plans from env inputs.
Linked Issues check ✅ Passed The reused-sandbox refresh path should make token-backed messaging setup and Telegram reachability probing run when the stored plan is empty.
Out of Scope Changes check ✅ Passed The added helper and tests are directly tied to the messaging-plan refresh fix and do not introduce unrelated changes.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/5680-telegram-reachability-reuse

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

@github-code-quality

github-code-quality Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in the fix/5680-telegram-re... branch is 96%. Coverage data for the main branch is not yet available.

Show a code coverage summary of the most covered files.
File main fix/5680-telegram-re... 8e838af +/-
nemoclaw/src/se...cret-scanner.ts 100%
nemoclaw/src/commands/slash.ts 100%
nemoclaw/src/li...bprocess-env.ts 100%
nemoclaw/src/bl...eprint/state.ts 98%
nemoclaw/src/onboard/config.ts 98%
nemoclaw/src/bl...int/snapshot.ts 97%
nemoclaw/src/bl...print/runner.ts 95%
nemoclaw/src/co...ration-state.ts 94%
nemoclaw/src/bl...ate-networks.ts 94%
nemoclaw/src/index.ts 94%

TypeScript / code-coverage/cli

The overall coverage in the fix/5680-telegram-re... branch is 47%. Coverage data for the main branch is not yet available.

Show a code coverage summary of the most covered files.
File main fix/5680-telegram-re... 8e838af +/-
src/lib/state/o...oard-session.ts 91%
src/lib/inference/local.ts 76%
src/lib/sandbox/config.ts 72%
src/lib/actions...dbox/rebuild.ts 71%
src/lib/onboard/preflight.ts 64%
src/lib/actions...licy-channel.ts 60%
src/lib/state/sandbox.ts 55%
src/lib/onboard...er-gpu-patch.ts 50%
src/lib/policy/index.ts 49%
src/lib/onboard.ts 19%

Updated June 25, 2026 08:54 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@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 (1)
src/lib/onboard/machine/handlers/sandbox.ts (1)

470-495: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Consider extracting the duplicated env-rebuild logic.

Lines 475-492 (read env plan → filter → clear/keep/write, after setupMessagingChannels) are nearly identical to the final else branch at Lines 501-518. The only meaningful difference is the existing seed source. A small helper taking the seed channels would remove the duplication and keep the two refresh paths from diverging over time.

🤖 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/machine/handlers/sandbox.ts` around lines 470 - 495, The env
plan refresh logic is duplicated between the post-setupMessagingChannels path
and the reuseMessagingPlan branch; extract it into a shared helper so both paths
use the same read/filter/clear/write flow. Keep the helper focused on the env
rebuild steps and pass in the differing seed source (the existing channels vs.
the registry/session-backed source) from sandbox.ts, using the existing symbols
setupMessagingChannels, reuseMessagingPlan, readMessagingPlanFromEnv,
filterMessagingPlanForCurrentAgent, clearPlanEnv, and writePlanToEnv to keep
behavior aligned.
🤖 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.

Nitpick comments:
In `@src/lib/onboard/machine/handlers/sandbox.ts`:
- Around line 470-495: The env plan refresh logic is duplicated between the
post-setupMessagingChannels path and the reuseMessagingPlan branch; extract it
into a shared helper so both paths use the same read/filter/clear/write flow.
Keep the helper focused on the env rebuild steps and pass in the differing seed
source (the existing channels vs. the registry/session-backed source) from
sandbox.ts, using the existing symbols setupMessagingChannels,
reuseMessagingPlan, readMessagingPlanFromEnv,
filterMessagingPlanForCurrentAgent, clearPlanEnv, and writePlanToEnv to keep
behavior aligned.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: aac16051-d87c-428e-b0f6-af0bf7ed3c4e

📥 Commits

Reviewing files that changed from the base of the PR and between e3b8325 and 47a3d2c.

📒 Files selected for processing (4)
  • src/lib/onboard/machine/handlers/sandbox.test.ts
  • src/lib/onboard/machine/handlers/sandbox.ts
  • src/lib/onboard/messaging-channel-setup.test.ts
  • src/lib/onboard/messaging-channel-setup.ts

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: onboard-resume-e2e, onboard-repair-e2e, cloud-onboard-e2e, channels-add-remove-e2e
Optional E2E: messaging-providers-e2e, channels-stop-start-openclaw-e2e

Dispatch hint: onboard-resume-e2e,onboard-repair-e2e,cloud-onboard-e2e,channels-add-remove-e2e

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • onboard-resume-e2e (medium): Required by the onboarding resume compatibility rule: the PR changes the sandbox live slice under src/lib/onboard/machine and changes resume/reuse behavior for recorded registry messaging plans. This must be validated with the real resume E2E, not only unit/runtime-boundary tests.
  • onboard-repair-e2e (medium): Required by the onboarding resume compatibility rule: the sandbox live slice changes can interact with repair paths for recorded sandbox state and registry cleanup/recreation, so the repair E2E must run alongside onboard-resume-e2e.
  • cloud-onboard-e2e (medium): The changed sandbox handler and messaging setup participate in full non-interactive hosted onboarding. Run the hosted onboarding E2E to verify a fresh real onboarding flow still creates the sandbox, records session/registry state, and completes with hosted inference credentials.
  • channels-add-remove-e2e (high): The PR changes non-interactive messaging channel detection/adoption and registry-plan refresh behavior. channels-add-remove-e2e covers real OpenClaw messaging channel add, rebuild, gateway credential reuse, policy-list, and removal cleanup across sandbox lifecycle boundaries.

Optional E2E

  • messaging-providers-e2e (high): Useful additional confidence for messaging provider creation, credential isolation, openclaw.json patching, network reachability, and placeholder/proxy behavior after changing env-based channel detection and setup-plan adoption. Make required if reviewers are especially concerned about provider credential boundaries.
  • channels-stop-start-openclaw-e2e (high): Adjacent coverage for preserving/reusing messaging channel provider state across stop/start and rebuild flows. Optional because the PR mainly changes onboarding-time plan refresh, while channels-add-remove-e2e is the closer lifecycle test.

New E2E recommendations

  • messaging registry-plan refresh during existing-sandbox onboarding (high): Existing E2Es do not appear to directly cover the reporter scenario changed here: a non-interactive onboard targets an existing sandbox whose registry messaging plan has no active channels, while TELEGRAM_BOT_TOKEN is newly supplied; setup should refresh the plan, run Telegram validation/reachability, and preserve non-env/QR-only configured channels from the registry seed.
    • Suggested test: Add a live E2E scenario for re-onboarding an existing sandbox with an empty or disabled registry messaging plan plus newly supplied TELEGRAM_BOT_TOKEN, asserting messaging setup runs and the final registry/session plan reflects the refreshed channel state without silently bypassing validation.

Dispatch hint

  • Workflow: nightly-e2e.yaml
  • jobs input: onboard-resume-e2e,onboard-repair-e2e,cloud-onboard-e2e,channels-add-remove-e2e

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Recommendation

Required Vitest E2E scenarios: onboard-resume-vitest, onboard-repair-vitest, messaging-providers-vitest
Optional Vitest E2E scenarios: None

Dispatch required Vitest E2E scenarios:

  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-resume-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-repair-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=messaging-providers-vitest

Workflow run

Full Vitest E2E advisor summary

Vitest E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required Vitest E2E scenarios

  • onboard-resume-vitest: Changes in src/lib/onboard/machine/handlers/sandbox.ts alter sandbox state-machine orchestration for reused registry messaging plans, env-detected messaging inputs, and persisted onboarding session plan adoption. The onboarding resume compatibility rule requires the live onboard resume Vitest job for these state-machine resume paths.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-resume-vitest
  • onboard-repair-vitest: The sandbox handler change is in the same persisted-session/reused-sandbox path that can flow into repair/backstop behavior for recorded sandboxes. Per the onboarding resume compatibility rule, repair is required, not optional, for these state-machine resume paths.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-repair-vitest
  • messaging-providers-vitest: src/lib/onboard/messaging-channel-setup.ts adds env-based messaging channel detection and changes shared non-interactive messaging setup inputs used by Telegram/Discord/Slack/WhatsApp provider onboarding. The messaging providers live Vitest job is the smallest wired free-standing job that exercises the built-in provider setup and messaging plan/provider contracts.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=messaging-providers-vitest

Optional Vitest E2E scenarios

  • None.

Relevant changed files

  • src/lib/onboard/machine/handlers/sandbox.test.ts
  • src/lib/onboard/machine/handlers/sandbox.ts
  • src/lib/onboard/messaging-channel-setup.test.ts
  • src/lib/onboard/messaging-channel-setup.ts

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings

Merge posture: No blocking advisor findings
Primary next action: Add or justify PRA-T1 and any related test follow-ups.
Open items: 0 required · 0 warnings · 0 suggestions · 8 test follow-ups
Since last review: 1 prior item resolved · 0 still apply · 0 new items found

Action checklist

  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Acceptance clause
  • PRA-T5 Add or justify test follow-up: Acceptance clause
  • PRA-T6 Add or justify test follow-up: Acceptance clause
  • PRA-T7 Add or justify test follow-up: Acceptance clause
  • PRA-T8 Add or justify test follow-up: Acceptance clause
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — Runtime validation: non-interactive reused sandbox with a zero-active Telegram registry plan, fake `TELEGRAM_BOT_TOKEN`, and `NEMOCLAW_SKIP_TELEGRAM_REACHABILITY` unset logs the Telegram reachability rejection or `unreachable` diagnostic instead of silently reusing `Messaging: none`.. Focused unit tests cover the changed decision logic, but the acceptance scenario ultimately depends on live non-interactive CLI onboarding, reused sandbox registry state, Telegram reachability hooks, and host network diagnostics. Read-only review confirms routing to setup, not live curl/getMe output.
  • PRA-T2 Runtime validation — Runtime or integration validation: zero-active registry plan plus env input for a channel unsupported by the selected agent does not stage that channel and passes no unsupported messaging channel to sandbox creation.. Focused unit tests cover the changed decision logic, but the acceptance scenario ultimately depends on live non-interactive CLI onboarding, reused sandbox registry state, Telegram reachability hooks, and host network diagnostics. Read-only review confirms routing to setup, not live curl/getMe output.
  • PRA-T3 Runtime validation — Unit validation: `detectMessagingChannelsFromEnv` behavior with a stored credential but no process env var is asserted explicitly, or the helper is renamed/documented if credential-store fallback is intentional.. Focused unit tests cover the changed decision logic, but the acceptance scenario ultimately depends on live non-interactive CLI onboarding, reused sandbox registry state, Telegram reachability hooks, and host network diagnostics. Read-only review confirms routing to setup, not live curl/getMe output.
  • PRA-T4 Acceptance clause — ## Environment - **NemoClaw version:** v0.0.66 — add test evidence or identify existing coverage. This is reporter environment context rather than a code requirement; the diff changes current onboarding messaging reuse logic in `src/lib/onboard/machine/handlers/sandbox.ts`.
  • PRA-T5 Acceptance clause — - **Host:** DGX Spark — add test evidence or identify existing coverage. This is reporter environment context; read-only review did not run on DGX Spark.
  • PRA-T6 Acceptance clause — ## Preconditions - NemoClaw CLI installed, Docker running. — add test evidence or identify existing coverage. This is runtime environment setup outside the static diff; no installer, Docker, or CLI bootstrap code is changed.
  • PRA-T7 Acceptance clause — 2. Run: ```bash nemoclaw onboard --non-interactive --yes-i-accept-third-party-software \ 2>&1 | tee /tmp/compat-tg-onboard.log ``` — add test evidence or identify existing coverage. Static review confirms the non-interactive reused-sandbox path now routes through `setupMessagingChannels` when a zero-active registry plan and fresh messaging inputs are present. This review did not execute the CLI command.
  • PRA-T8 Acceptance clause — 3. Inspect `/tmp/compat-tg-onboard.log` for `api.telegram.org` or curl errors. — add test evidence or identify existing coverage. The changed `sandbox.test.ts` verifies `setupMessagingChannels` is called instead of being bypassed. The exact runtime log line depends on the Telegram reachability hook and host network conditions, which were not executed in this read-only review.

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

Extract a local setupAndAdoptMessagingPlan helper in handleSandboxState
and call it from both the reused-registry-plan refresh branch (#5680) and
the normal setup branch. Both previously repeated the same post-setup
pattern: run setupMessagingChannels, filter selected channels and the
env-staged plan for the current agent, clear env when unsupported, and
write the filtered plan back when it changed. Behavior is unchanged;
this removes the duplication so future plan-adoption fixes stay in one
place (PR review advisor PRA-1).

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
@yimoj yimoj added the v0.0.69 label Jun 25, 2026
@wscurran wscurran added area: messaging Messaging channels, bridges, manifests, or channel lifecycle area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow bug-fix PR fixes a bug or regression labels Jun 25, 2026
@wscurran

Copy link
Copy Markdown
Contributor

@cjagwani cjagwani self-assigned this Jun 25, 2026

@cjagwani cjagwani left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Walked through the rebuild condition and yeah, the narrow guard (empty active channels + fresh env) is the right shape. Common reuse path is unchanged, and the WhatsApp QR preservation through the registry-plan seed is solid. Tests actually depend on the new branch (would fail if reverted). LGTM.

@wscurran wscurran added the NV QA Bugs found by the NVIDIA QA Team label Jun 26, 2026
@cv
cv merged commit 1aae911 into main Jun 26, 2026
44 checks passed
@cv
cv deleted the fix/5680-telegram-reachability-reuse branch June 26, 2026 16:25
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
…IDIA#5788)

## Summary

Non-interactive `nemoclaw onboard` reusing an existing sandbox whose
stored messaging plan has **zero active channels** (the reporter's
empty/stale `Messaging: none` state) silently refreshed credential
hashes and skipped messaging channel setup. Newly supplied messaging env
inputs (e.g. `TELEGRAM_BOT_TOKEN`) were never discovered, so the
Telegram `getMe` reachability probe was bypassed even with
`NEMOCLAW_SKIP_TELEGRAM_REACHABILITY` unset. This fix makes the
reused-sandbox path honor fresh messaging env inputs so the reachability
probe runs.

## Related Issue

Fixes NVIDIA#5680

## Changes

- `src/lib/onboard/machine/handlers/sandbox.ts`: in the
reused-`registryMessagingPlan` branch, when the plan has **no active
channels** but this run supplies complete messaging env inputs, rebuild
the plan via `setupMessagingChannels` (which runs channel reachability
checks) instead of silently refreshing hashes. Plans that already have
active channels are preserved as-is, so an existing channel is never
dropped when its token is absent from this run. The explicit env-staged
plan branch above stays authoritative for rebuild/resume.
- `src/lib/onboard/messaging-channel-setup.ts`: add
`detectMessagingChannelsFromEnv`, a pure, side-effect-free probe that
reports which built-in channels currently have complete required inputs,
reusing the same manifest input rules as `setupMessagingChannels`.
`NEMOCLAW_POLICY_PRESETS` is intentionally ignored — policy presets are
not messaging channel selection.
- Tests for both the rebuild path and the preserve-active-channel
regression guard, plus unit coverage of `detectMessagingChannelsFromEnv`
(including that `NEMOCLAW_POLICY_PRESETS=telegram` alone does not select
messaging).

## Type of Change

- [x] Code change (feature, bug fix, or refactor)

## Verification

- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Git hooks passed during commit and push
- [x] Targeted tests pass for changed behavior (`sandbox.test.ts`,
`messaging-channel-setup.test.ts` — 39 tests)
- [x] Full `npm test` (cli project) passes — 8126 passed, 18 skipped
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [x] Docs reviewed — no user-facing doc changes required (internal
onboarding state-machine correctness fix; no new flags/env/API)

### End-to-end verification (real worktree CLI vs live OpenShell 0.0.44
sandbox)

Built the worktree CLI (`npm run build:cli`) and drove real `node
./bin/nemoclaw.js onboard` commands against a live OpenShell 0.0.44
Docker-driver sandbox (CPU host, hosted NVIDIA Endpoints inference).
Created the reporter's buggy state — a sandbox `compat-tg-5680` whose
registry messaging plan is non-null with **zero active channels**
(telegram configured-but-disabled) — then ran the reporter workflow with
a fake `TELEGRAM_BOT_TOKEN` and `NEMOCLAW_SKIP_TELEGRAM_REACHABILITY`
unset.

Exact command (same for both builds):

```bash
export NVIDIA_INFERENCE_API_KEY=...                 # hosted inference
export TELEGRAM_BOT_TOKEN="123456789:AAFfake-token-for-5680-e2e-reproduction-xyz"
export TELEGRAM_ALLOWED_IDS="123456789"
export NEMOCLAW_POLICY_PRESETS="telegram"
export NEMOCLAW_NON_INTERACTIVE=1 NEMOCLAW_ACCEPT_THIRD_PARTY_SOFTWARE=1
export NEMOCLAW_SANDBOX_NAME=compat-tg-5680
unset NEMOCLAW_SKIP_TELEGRAM_REACHABILITY
node ./bin/nemoclaw.js onboard --non-interactive --no-gpu --no-sandbox-gpu --yes-i-accept-third-party-software
```

**Unpatched build (bug reproduced — probe silently bypassed):**

```text
  Messaging:     none
  [non-interactive] Sandbox 'compat-tg-5680' exists and is ready — reusing it
  [non-interactive] Applying policy presets: telegram
```

(No `[5/8] Messaging channels`, no reachability output — matches the
reporter's exact observation.)

**Patched build (fixed — messaging setup + reachability probe run):**

```text
  Messaging:     none
  [non-interactive] Detected messaging channel inputs for telegram; refreshing reused sandbox messaging plan.
  [5/8] Messaging channels
  [non-interactive] Messaging channel inputs detected: telegram
  Telegram integration will be disabled for this enrollment run because api.telegram.org is unreachable.
  [non-interactive] Sandbox 'compat-tg-5680' exists and is ready — reusing it
```

The patched run discovers the env-supplied Telegram input on the reused
sandbox and runs the `getMe` reachability probe, emitting reachability
diagnostics instead of silently skipping. (This E2E host's egress to
`api.telegram.org` is firewall-blocked, so the probe reports
"unreachable" rather than a token rejection — both prove the probe
executed rather than being bypassed; on a host that can reach Telegram a
fake token yields the `Telegram bot token was rejected.` log.) The test
sandbox was destroyed after verification.

---

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>


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

* **New Features**
* Added environment-aware detection of supported messaging channels,
improving onboarding and resume behavior when messaging is already
configured.

* **Bug Fixes**
* Fixed reused messaging-plan handling when prior channels are no longer
active: onboarding now refreshes the plan from current environment
configuration.
* Avoided unnecessary messaging-plan rebuilds when an existing active
channel remains valid, even if additional environment inputs are
present.

* **Tests**
* Expanded coverage for environment-based messaging channel detection
and reused-plan scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---
Supersedes NVIDIA#5715 (reopened from NVIDIA/NemoClaw branch so trusted
advisor workflows can run).

---------

Signed-off-by: Yimo Jiang <yimoj@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: messaging Messaging channels, bridges, manifests, or channel lifecycle area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow bug-fix PR fixes a bug or regression NV QA Bugs found by the NVIDIA QA Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Policy&Network][GitHub Issue #5680] Telegram reachability probe does not log or fail for fake tokens when NEMOCLAW_SKIP_TELEGRAM_REACHABILITY is unset

4 participants