fix(onboard): refresh stale reused messaging plan from env inputs - #5788
Conversation
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>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds 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. ChangesMessaging channel env detection and sandbox reuse
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage in the Show a code coverage summary of the most covered files.
TypeScript / code-coverage/cliThe overall coverage in the Show a code coverage summary of the most covered files.
Updated |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/onboard/machine/handlers/sandbox.ts (1)
470-495: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffConsider extracting the duplicated env-rebuild logic.
Lines 475-492 (read env plan → filter → clear/keep/write, after
setupMessagingChannels) are nearly identical to the finalelsebranch at Lines 501-518. The only meaningful difference is theexistingseed 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
📒 Files selected for processing (4)
src/lib/onboard/machine/handlers/sandbox.test.tssrc/lib/onboard/machine/handlers/sandbox.tssrc/lib/onboard/messaging-channel-setup.test.tssrc/lib/onboard/messaging-channel-setup.ts
E2E Advisor RecommendationRequired E2E: Dispatch hint: Full advisor summaryE2E Recommendation AdvisorBase: Required E2E
Optional E2E
New E2E recommendations
Dispatch hint
|
Vitest E2E Scenario RecommendationRequired Vitest E2E scenarios: Dispatch required Vitest E2E scenarios:
Full Vitest E2E advisor summaryVitest E2E Scenario AdvisorBase: Required Vitest E2E scenarios
Optional Vitest E2E scenarios
Relevant changed files
|
PR Review Advisor — No blocking findingsMerge posture: No blocking advisor findings Action checklist
Test follow-ups to resolve or justifyIf these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.
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>
cjagwani
left a comment
There was a problem hiding this comment.
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.
…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>
Summary
Non-interactive
nemoclaw onboardreusing an existing sandbox whose stored messaging plan has zero active channels (the reporter's empty/staleMessaging: nonestate) silently refreshed credential hashes and skipped messaging channel setup. Newly supplied messaging env inputs (e.g.TELEGRAM_BOT_TOKEN) were never discovered, so the TelegramgetMereachability probe was bypassed even withNEMOCLAW_SKIP_TELEGRAM_REACHABILITYunset. 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-registryMessagingPlanbranch, when the plan has no active channels but this run supplies complete messaging env inputs, rebuild the plan viasetupMessagingChannels(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: adddetectMessagingChannelsFromEnv, a pure, side-effect-free probe that reports which built-in channels currently have complete required inputs, reusing the same manifest input rules assetupMessagingChannels.NEMOCLAW_POLICY_PRESETSis intentionally ignored — policy presets are not messaging channel selection.detectMessagingChannelsFromEnv(including thatNEMOCLAW_POLICY_PRESETS=telegramalone does not select messaging).Type of Change
Verification
Verifiedin GitHubsandbox.test.ts,messaging-channel-setup.test.ts— 39 tests)npm test(cli project) passes — 8126 passed, 18 skippedEnd-to-end verification (real worktree CLI vs live OpenShell 0.0.44 sandbox)
Built the worktree CLI (
npm run build:cli) and drove realnode ./bin/nemoclaw.js onboardcommands against a live OpenShell 0.0.44 Docker-driver sandbox (CPU host, hosted NVIDIA Endpoints inference). Created the reporter's buggy state — a sandboxcompat-tg-5680whose registry messaging plan is non-null with zero active channels (telegram configured-but-disabled) — then ran the reporter workflow with a fakeTELEGRAM_BOT_TOKENandNEMOCLAW_SKIP_TELEGRAM_REACHABILITYunset.Exact command (same for both builds):
Unpatched build (bug reproduced — probe silently bypassed):
(No
[5/8] Messaging channels, no reachability output — matches the reporter's exact observation.)Patched build (fixed — messaging setup + reachability probe run):
The patched run discovers the env-supplied Telegram input on the reused sandbox and runs the
getMereachability probe, emitting reachability diagnostics instead of silently skipping. (This E2E host's egress toapi.telegram.orgis 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 theTelegram 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
Bug Fixes
Tests
Supersedes #5715 (reopened from NVIDIA/NemoClaw branch so trusted advisor workflows can run).