Skip to content

test(e2e): update Discord proxy expectation - #5391

Merged
cv merged 1 commit into
mainfrom
fix/messaging-e2e-discord-proxy-expectation
Jun 13, 2026
Merged

cv merged 1 commit into
mainfrom
fix/messaging-e2e-discord-proxy-expectation

Conversation

@sandl99

@sandl99 sandl99 commented Jun 13, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Updates the messaging providers E2E M9b assertion so Discord now expects channels.discord.accounts.default.proxy to match the sandbox proxy while the top-level managed proxy remains configured. This aligns the test with the Discord proxy behavior restored by PR #5248 for issue #5075.

Changes

  • Updated test/e2e/test-messaging-providers.sh M9b comments and pass/fail messages to describe per-account Discord proxy routing.
  • Changed the M9b assertion to require both account.proxy and proxy.proxyUrl to equal the expected sandbox proxy URL.
  • Reviewed docs/ and found no user-facing docs update needed because this is a stale E2E expectation change with no product behavior change.

Type of Change

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

Verification

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

Additional verification:

  • bash -n test/e2e/test-messaging-providers.sh passed.
  • shellcheck test/e2e/test-messaging-providers.sh passed.
  • npx prek run --files test/e2e/test-messaging-providers.sh passed.
  • npx vitest run --project cli test/discord-template-resolver-proxy.test.ts test/generate-openclaw-config.test.ts passed.
  • Docs review completed: no docs changes needed.
  • Full npx prek run --all-files and npm test were attempted and fail in unrelated existing suites outside this change.

Signed-off-by: San Dang sdang@nvidia.com

Summary by CodeRabbit

  • Tests
    • Updated Discord proxy configuration validation in end-to-end tests to reflect current proxy-wiring expectations during configuration patching.

Signed-off-by: San Dang <sdang@nvidia.com>
@sandl99 sandl99 self-assigned this Jun 13, 2026
@coderabbitai

coderabbitai Bot commented Jun 13, 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: e85bcc55-8582-4e02-b55c-ae939906ef41

📥 Commits

Reviewing files that changed from the base of the PR and between 158f575 and 503c3b1.

📒 Files selected for processing (1)
  • test/e2e/test-messaging-providers.sh

📝 Walkthrough

Walkthrough

This PR updates the Discord proxy-wiring test assertion in an end-to-end test script. The test now validates that both the per-account proxy configuration and the top-level managed proxy URL are set to the expected managed proxy value, instead of allowing the per-account proxy to remain empty.

Changes

Discord Proxy-Wiring Assertion

Layer / File(s) Summary
M9b Discord proxy-wiring assertion and validation
test/e2e/test-messaging-providers.sh
Updated the comment and validation logic for Discord gateway routing to expect both account.proxy and proxy.proxyUrl to be set to the computed expected_managed_proxy.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#5248: Both PRs adjust Discord proxy wiring to ensure the generated Discord per-account account.proxy is set to the expected managed/sandbox proxy URL (not left empty/undefined), aligning resolver output and test assertions.

Suggested labels

integration: discord, area: messaging, nightly-e2e, bug-fix

Poem

🐰 A proxy now sets both its places,
Account and platform, matching faces,
The Discord thread now holds them tight,
Per-account and managed, both in sight.
Where routing once stayed incomplete,
Now proxy wiring is all neat! 🔗

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title concisely describes the main change: updating Discord proxy expectations in an E2E test, which directly matches the file modified and the core objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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/messaging-e2e-discord-proxy-expectation

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

@github-code-quality

github-code-quality Bot commented Jun 13, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in the fix/messaging-e2e-di... 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/messaging-e2e-di... 503c3b1 +/-
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/messaging-e2e-di... branch is 44%. Coverage data for the main branch is not yet available.

Show a code coverage summary of the most covered files.
File main fix/messaging-e2e-di... 503c3b1 +/-
src/lib/state/o...oard-session.ts — 90% —
src/lib/inference/local.ts — 77% —
src/lib/sandbox/config.ts — 72% —
src/lib/inference/nim.ts — 72% —
src/lib/onboard/preflight.ts — 64% —
src/lib/state/sandbox.ts — 55% —
src/lib/onboard...er-gpu-patch.ts — 50% —
src/lib/actions...licy-channel.ts — 49% —
src/lib/policy/index.ts — 48% —
src/lib/onboard.ts — 17% —

Updated June 13, 2026 17:19 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: None
Optional E2E: messaging-providers-e2e

Dispatch hint: messaging-providers-e2e

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • None.

Optional E2E

  • messaging-providers-e2e (75 minute timeout): Optional validation for the exact changed shell E2E script. This job exercises the Telegram/Discord/Slack messaging provider credential placeholder and proxy chain, including the edited Discord M9b proxy assertion, but should not be merge-blocking because the PR is tests-only.

New E2E recommendations

  • None.

Dispatch hint

  • Workflow: .github/workflows/nightly-e2e.yaml
  • jobs input: messaging-providers-e2e

@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Recommendation

Required Vitest E2E scenarios: None
Optional Vitest E2E scenarios: None

Workflow run

Full Vitest E2E advisor summary

Vitest E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required Vitest E2E scenarios

  • None. The only changed file is outside the Vitest scenario system (test/e2e-scenario/) and does not modify .github/workflows/e2e-vitest-scenarios.yaml or other directly scenario-relevant Vitest E2E machinery, so no Vitest scenario dispatch is recommended.

Optional Vitest E2E scenarios

  • None.

Relevant changed files

  • None.

@github-actions

Copy link
Copy Markdown
Contributor

PR Review Advisor

Findings: 0 needs attention, 0 worth checking, 1 nice ideas
Top item: Align stale M13 Discord proxy wording

Review findings

🛠️ Needs attention

  • None.

🔎 Worth checking

  • None.

🌱 Nice ideas

  • Align stale M13 Discord proxy wording with the per-account proxy expectation (test/e2e/test-messaging-providers.sh:2406): The updated M9b block now says Discord Gateway routing depends on the per-account proxy, which matches the current Discord manifest and template resolver. A nearby M13d-config comment still says Discord should rely on the top-level proxy config instead of a per-account proxy, which can confuse future debugging about what the E2E proof is validating.
    • Recommendation: Consider updating the M13b-M13g comment/pass/fail wording to say it exercises the same sandbox proxy URL through OpenShell, without implying Discord is top-level-proxy-only.
    • Evidence: M9b now requires `channels.discord.accounts.default.proxy` and `proxy.proxyUrl` to equal `expected_managed_proxy`; nearby lines 2406-2409 still describe the proof as using the generated managed proxy URL and top-level proxy config.

Workflow run details

This is an automated advisory review. A human maintainer must make the final merge decision.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ❌ Some jobs failed

Run: 27473654902
Target ref: fix/messaging-e2e-discord-proxy-expectation
Requested jobs: messaging-providers-e2e
Summary: 0 passed, 1 failed, 0 cancelled, 0 skipped

Job Result
messaging-providers-e2e ❌ failure

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

@sandl99
sandl99 requested a review from cv June 13, 2026 17:26
@sandl99

sandl99 commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator Author

@cv fix messaging-provider-e2e stale after #5248 got checked in, but it still failed due to inference change

@cv
cv merged commit 1457ef3 into main Jun 13, 2026
117 of 121 checks passed
@cv
cv deleted the fix/messaging-e2e-discord-proxy-expectation branch June 13, 2026 17:31
@cv cv added the v0.0.65 label Jun 15, 2026
cv added a commit that referenced this pull request Jun 23, 2026
…5571)

## Summary
The Discord channel config emits a per-account proxy
(`channels.discord.accounts.default.proxy = http://10.200.0.1:3128`)
that OpenClaw's Discord plugin rejects by design.
`extensions/discord/src/proxy-fetch.ts` `validateDiscordProxyUrl` throws
`Proxy URL must target a loopback host` for any non-loopback host, and
that validator runs on both the REST and gateway transports. The
rejected proxy is dropped, so the Discord gateway WebSocket cannot
egress the deny-by-default network namespace and never reaches READY.
This restores reliance on the top-level managed proxy for Discord, the
mechanism that originally addressed #5075 / #3894.

## Related Issue
Fixes #5544

## Changes
- Resolve `discordProxyUrl` back to `undefined` so the per-account proxy
field is omitted from the rendered `openclaw.json`. Discord gateway and
REST egress is carried by the top-level managed proxy
(`proxy.loopbackMode: "gateway-only"`), which OpenClaw documents as the
path for routing channel traffic through the operator proxy.
- Telegram keeps its per-account proxy: its Bot API transport honors a
non-loopback proxy and has no loopback validator. Discord uniquely
validates loopback, so mirroring Telegram was the wrong shape for
Discord.
- Flip the `generate-openclaw-config` and discord template-resolver
expectations back to asserting no per-account Discord proxy, and revert
the messaging-providers `M9b` check to expect the managed proxy with no
Discord `account.proxy`.
- Effectively reverts #5248 (and its #5391 test follow-up).

## 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
- [ ] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [x] Targeted tests pass for changed behavior
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed

Ran: `npx vitest run test/discord-template-resolver-proxy.test.ts
test/generate-openclaw-config.test.ts` (130 passed), `npm run
build:cli`, and `biome check` on the touched files (clean). The
full-suite `test-cli`/`test-plugin` commit and push hooks were skipped
because they trip on a pre-existing collection error in
`test/ssrf-parity.test.ts` (0 tests collected) that also fails on a
clean `main` checkout and is unrelated to this change. CI runs the full
gate.

---
Signed-off-by: latenighthackathon
<latenighthackathon@users.noreply.github.com>


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

* **Features**
* Updated Discord messaging so `discordProxyUrl` is no longer emitted
per account; Discord Gateway traffic is routed via the application’s
managed proxy configuration for consistent behavior.

* **Tests**
* Revised unit and end-to-end tests to assert Discord account `proxy`
remains empty while the global managed proxy URL is used, including
cases with proxy host/port environment overrides.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
jyaunches added a commit that referenced this pull request Jun 25, 2026
## Summary
Restore issue #5800 parity package `P0-C` for merged bash-suite
messaging/Discord/WhatsApp deltas only.

## Related Issues
Refs #5800
Refs #5098
Refs #5328
Refs #5391
Refs #5581
Refs #5624
Refs #5571
Refs #5704

## Scope gate
- Package: `P0-C — Messaging / Discord / channel parity`
- Included PRs all merged and touched `test/e2e`: yes — #5328, #5391,
#5581, #5624, #5571, #5704
- Out of scope: unmerged/non-bash PRs; shell lane retirement / PR #5756
cleanup

## Parity map
| ID | Source PR | Contract | Inference classification | Vitest
assertion / waiver | Status |
| --- | --- | --- | --- | --- | --- |
| C1 | #5328 | Compact persisted messaging plans omit derived
render/build/runtime/state/health sections while retaining durable
channel/config/credential/policy shape. | `none` |
`src/lib/messaging/plan-validation.test.ts`;
`test/e2e-scenario/live/channels-add-remove.test.ts` | covered |
| C2 | #5328 | Existing compact plans hydrate before merge so channel
add preserves prior hooks/render semantics. | `none` | existing
`src/lib/messaging/applier/host-state-applier.test.ts` | covered |
| C3 | #5391, #5571 | Discord config must not emit a non-loopback
per-account proxy; OpenClaw managed proxy remains configured. | `none` |
`test/discord-template-resolver-proxy.test.ts`;
`test/generate-openclaw-config.test.ts`;
`test/e2e-scenario/live/messaging-providers.test.ts`;
`test/e2e-scenario/live/openclaw-discord-pairing.test.ts` | covered |
| C4 | #5581 | OpenClaw Discord pairing Vitest preserves fake Gateway
token rewrite, connect-shell approval, and workflow dispatch boundary. |
`hermetic-default` | existing
`test/e2e-scenario/live/openclaw-discord-pairing.test.ts`; support
boundary/helper tests | covered |
| C5 | #5624 | Fake Discord Gateway capture proof accepts only redacted
identify rows, rejects placeholder/raw-token leakage, and proves token
rewrite. | `hermetic-default` |
`test/e2e-scenario/live/messaging-providers.test.ts`; existing
Hermes/OpenClaw Discord capture assertions and support tests | covered |
| C6 | #5704 | WhatsApp policy checks require expected endpoints before
rebuild and endpoints plus Node binary scope after rebuild. | `none` |
`test/e2e-scenario/live/messaging-providers.test.ts`;
`test/policies.test.ts` | covered |

## Inference mode support
- Default mode for touched live targets: `none` for config/unit
assertions; `hermetic-default` for fake Discord Gateway/live sandbox
token-rewrite assertions.
- Real inference support preserved: not applicable to this package’s
messaging/provider contracts; live sandbox targets still use existing
`NVIDIA_INFERENCE_API_KEY` path where their broader scenario requires
install/onboard.
- Modes validated in this PR: unit/support hermetic commands below;
selective live E2E run `28194650942` passed
`messaging-providers-vitest`, `channels-add-remove-vitest`, and
`openclaw-discord-pairing-vitest` at `531acd9f8`. Follow-up head
`46e004e3` only tightens local workflow-boundary assertions for
`COMPATIBLE_API_KEY`.
- If not validated with real inference: package contracts are
messaging/config/proxy/capture policy boundaries;
`channels-add-remove-vitest` also passed the hosted-compatible workflow
path after staging `NVIDIA_INFERENCE_API_KEY` as `COMPATIBLE_API_KEY`.

## Validation
- [x] `npx vitest run --project cli --maxWorkers 1 --no-fileParallelism
src/lib/messaging/plan-validation.test.ts
src/lib/messaging/applier/host-state-applier.test.ts
test/discord-template-resolver-proxy.test.ts`
- [x] `npx vitest run --project e2e-vitest-support --maxWorkers 1
--no-fileParallelism
test/e2e-scenario/support-tests/openclaw-discord-legacy-capture.test.ts
test/e2e-scenario/support-tests/openclaw-discord-pairing-helpers.test.ts
test/e2e-scenario/support-tests/openclaw-discord-workflow-boundary.test.ts`
- [x] `npx vitest run --project cli --maxWorkers 1 --no-fileParallelism
--testTimeout 30000 test/generate-openclaw-config.test.ts -t
"Discord|proxy|non-Slack"`
- [x] `npx vitest run --project cli --maxWorkers 1 --no-fileParallelism
test/policies.test.ts -t "whatsapp"`
- [x] `npx vitest run --project e2e-vitest-support --maxWorkers 1
--no-fileParallelism
test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
test/e2e-scenario/support-tests/openclaw-discord-workflow-boundary.test.ts`
- [x] Selective live E2E workflow `28194650942`:
`messaging-providers-vitest`, `channels-add-remove-vitest`,
`openclaw-discord-pairing-vitest` all passed.

## Follow-ups / waivers
- None.


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

* **Bug Fixes**
* Improved messaging plan persistence validation to ensure only required
fields are stored; derived workflow sections and per-channel hook data
are no longer persisted.
* Strengthened live channel add/remove assertions to enforce
`agentRender` and per-channel `hooks` absence.
* Updated live messaging provider and Discord pairing validations
(WhatsApp preset hosts and stricter gateway capture checks; account
proxy now required to be exactly empty when unset).
* **Tests / CI**
* Enhanced Vitest/e2e scenario test tooling and environment setup for
hosted-compatible inference, including compatible API key staging and
more robust Discord gateway capture/proxy handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
jyaunches added a commit that referenced this pull request Jun 25, 2026
## Summary
Restore issue #5800 parity package `P0-C` for merged
messaging/Discord/channel bash-suite deltas only.

## Related Issues
Refs #5800
Refs #5098
Refs #5328
Refs #5391
Refs #5581
Refs #5624
Refs #5571
Refs #5704

## Scope gate
- Package: `P0-C — Messaging / Discord / channel parity`
- Included PRs all merged and touched `test/e2e`: yes — #5328, #5391,
#5581, #5624, #5571, #5704
- Out of scope: unmerged/non-bash PRs; shell lane retirement / PR #5756
cleanup

## Parity map
| ID | Source PR | Contract | Inference classification | Vitest
assertion / waiver | Status |
| --- | --- | --- | --- | --- | --- |
| C1 | #5328 | Persisted messaging plans stay compact: `agentRender` and
per-channel `hooks` are derived runtime data, not durable
registry/session state. | `none` |
`src/lib/messaging/plan-validation.test.ts`;
`test/e2e-scenario/live/channels-add-remove.test.ts`; existing
`channels-stop-start-helpers.ts` | covered |
| C2 | #5391, #5571 | Discord config uses OpenClaw managed proxy and
must not emit a non-loopback per-account `account.proxy`. | `none` |
Existing `test/e2e-scenario/live/messaging-providers.test.ts`;
`test/e2e-scenario/live/openclaw-discord-pairing.test.ts` tightened to
require empty `accountProxy` | covered |
| C3 | #5581, #5624 | Fake Discord Gateway proof captures
placeholder-to-token rewrite booleans without persisting raw Discord
token or unresolved placeholder text. | `none` | Existing support tests
plus tightened `test/e2e-scenario/live/messaging-providers.test.ts`
capture assertion | covered |
| C4 | #5581 | OpenClaw Discord pairing workflow/live test preserves
fake token, connect-shell pairing approval, and workflow boundary. |
`none` | Existing
`test/e2e-scenario/live/openclaw-discord-pairing.test.ts`;
`test/e2e-scenario/support-tests/openclaw-discord-*` | covered |
| C5 | #5704 | WhatsApp policy assertions check endpoints as text and
verify post-rebuild Node binary scope. | `none` |
`test/e2e-scenario/live/messaging-providers.test.ts` now checks pre/post
policy text and Node binary scope | covered |

## Inference mode support
- Default mode for touched live targets: `none` for new/tightened
assertions; live scenario install still uses existing
`NVIDIA_INFERENCE_API_KEY` boundary where the pre-existing scenario
requires it.
- Real inference support preserved: not applicable to these
messaging/provider assertion changes.
- Modes validated in this PR: support/unit tests locally; live scenario
files imported with `NEMOCLAW_RUN_E2E_SCENARIOS=1` but not executed
without real sandbox/secrets.
- If not validated with real inference: not required by P0-C contracts;
selective live workflow should validate sandbox boundary on PR.

## Validation
- [x] `git diff --check`
- [x] `npm ci --ignore-scripts`
- [x] `npm run build:cli`
- [x] `npm run typecheck:cli`
- [x] `npx vitest run --project e2e-vitest-support
test/e2e-scenario/support-tests/openclaw-discord-pairing-helpers.test.ts
test/e2e-scenario/support-tests/openclaw-discord-legacy-capture.test.ts
test/e2e-scenario/support-tests/openclaw-discord-workflow-boundary.test.ts`
- [x] `npx vitest run src/lib/messaging/plan-validation.test.ts
src/lib/state/onboard-session.test.ts test/registry.test.ts`
- [x] `NEMOCLAW_RUN_E2E_SCENARIOS=1 npx vitest run --project
e2e-scenarios-live test/e2e-scenario/live/channels-add-remove.test.ts
test/e2e-scenario/live/messaging-providers.test.ts
test/e2e-scenario/live/openclaw-discord-pairing.test.ts
test/e2e-scenario/live/channels-stop-start.test.ts` (files imported;
tests skipped without live secrets/sandbox)
- [x] selective live E2E workflow evidence:
- `messaging-providers-vitest`: passed on PR head `f6a00eb` —
https://github.com/NVIDIA/NemoClaw/actions/runs/28194778783
- `openclaw-discord-pairing-vitest`: passed on PR head `8fdb454` before
the messaging-only fix —
https://github.com/NVIDIA/NemoClaw/actions/runs/28190315340/job/83502969520
- `channels-add-remove-vitest`: attempted in
https://github.com/NVIDIA/NemoClaw/actions/runs/28187168691 and failed
before P0-C assertions on runner/secret setup (`Invalid NVIDIA API
key`); P0-C compact-plan/channel persistence coverage is validated
locally/import-gated in this PR.

Note: initial plain `git commit` ran the full pre-commit test hook and
failed in unrelated CLI timeout/fake-runtime tests; this PR was
committed with focused validation above after `typecheck:cli` was fixed.

## Follow-ups / waivers
- `channels-add-remove-vitest` hosted-key lane needs runner/secret
follow-up; current failure is `Invalid NVIDIA API key` before P0-C
assertions, not a messaging/channel parity assertion failure.


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

* **Bug Fixes**
* Ensured persisted messaging plans only retain core channel/network
settings; derived workflow data (including agent render and per-channel
hooks) is no longer carried into saved plans.

* **Tests**
* Added coverage verifying compacted persisted plans remove derived
workflow sections while preserving network policy and channel structure.
* Updated live Telegram channel checks to stop expecting agent render
and per-channel hooks to be persisted.
* Strengthened WhatsApp policy rebuild assertions, Discord gateway
capture/token safety checks, Discord pairing proxy expectation, and
filesystem probe output.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
…5544) (NVIDIA#5571)

## Summary
The Discord channel config emits a per-account proxy
(`channels.discord.accounts.default.proxy = http://10.200.0.1:3128`)
that OpenClaw's Discord plugin rejects by design.
`extensions/discord/src/proxy-fetch.ts` `validateDiscordProxyUrl` throws
`Proxy URL must target a loopback host` for any non-loopback host, and
that validator runs on both the REST and gateway transports. The
rejected proxy is dropped, so the Discord gateway WebSocket cannot
egress the deny-by-default network namespace and never reaches READY.
This restores reliance on the top-level managed proxy for Discord, the
mechanism that originally addressed NVIDIA#5075 / NVIDIA#3894.

## Related Issue
Fixes NVIDIA#5544

## Changes
- Resolve `discordProxyUrl` back to `undefined` so the per-account proxy
field is omitted from the rendered `openclaw.json`. Discord gateway and
REST egress is carried by the top-level managed proxy
(`proxy.loopbackMode: "gateway-only"`), which OpenClaw documents as the
path for routing channel traffic through the operator proxy.
- Telegram keeps its per-account proxy: its Bot API transport honors a
non-loopback proxy and has no loopback validator. Discord uniquely
validates loopback, so mirroring Telegram was the wrong shape for
Discord.
- Flip the `generate-openclaw-config` and discord template-resolver
expectations back to asserting no per-account Discord proxy, and revert
the messaging-providers `M9b` check to expect the managed proxy with no
Discord `account.proxy`.
- Effectively reverts NVIDIA#5248 (and its NVIDIA#5391 test follow-up).

## 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
- [ ] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [x] Targeted tests pass for changed behavior
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed

Ran: `npx vitest run test/discord-template-resolver-proxy.test.ts
test/generate-openclaw-config.test.ts` (130 passed), `npm run
build:cli`, and `biome check` on the touched files (clean). The
full-suite `test-cli`/`test-plugin` commit and push hooks were skipped
because they trip on a pre-existing collection error in
`test/ssrf-parity.test.ts` (0 tests collected) that also fails on a
clean `main` checkout and is unrelated to this change. CI runs the full
gate.

---
Signed-off-by: latenighthackathon
<latenighthackathon@users.noreply.github.com>

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

* **Features**
* Updated Discord messaging so `discordProxyUrl` is no longer emitted
per account; Discord Gateway traffic is routed via the application’s
managed proxy configuration for consistent behavior.

* **Tests**
* Revised unit and end-to-end tests to assert Discord account `proxy`
remains empty while the global managed proxy URL is used, including
cases with proxy host/port environment overrides.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Hadar Cohen <hacohen@redhat.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
…5544) (NVIDIA#5571)

## Summary
The Discord channel config emits a per-account proxy
(`channels.discord.accounts.default.proxy = http://10.200.0.1:3128`)
that OpenClaw's Discord plugin rejects by design.
`extensions/discord/src/proxy-fetch.ts` `validateDiscordProxyUrl` throws
`Proxy URL must target a loopback host` for any non-loopback host, and
that validator runs on both the REST and gateway transports. The
rejected proxy is dropped, so the Discord gateway WebSocket cannot
egress the deny-by-default network namespace and never reaches READY.
This restores reliance on the top-level managed proxy for Discord, the
mechanism that originally addressed NVIDIA#5075 / NVIDIA#3894.

## Related Issue
Fixes NVIDIA#5544

## Changes
- Resolve `discordProxyUrl` back to `undefined` so the per-account proxy
field is omitted from the rendered `openclaw.json`. Discord gateway and
REST egress is carried by the top-level managed proxy
(`proxy.loopbackMode: "gateway-only"`), which OpenClaw documents as the
path for routing channel traffic through the operator proxy.
- Telegram keeps its per-account proxy: its Bot API transport honors a
non-loopback proxy and has no loopback validator. Discord uniquely
validates loopback, so mirroring Telegram was the wrong shape for
Discord.
- Flip the `generate-openclaw-config` and discord template-resolver
expectations back to asserting no per-account Discord proxy, and revert
the messaging-providers `M9b` check to expect the managed proxy with no
Discord `account.proxy`.
- Effectively reverts NVIDIA#5248 (and its NVIDIA#5391 test follow-up).

## 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
- [ ] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [x] Targeted tests pass for changed behavior
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed

Ran: `npx vitest run test/discord-template-resolver-proxy.test.ts
test/generate-openclaw-config.test.ts` (130 passed), `npm run
build:cli`, and `biome check` on the touched files (clean). The
full-suite `test-cli`/`test-plugin` commit and push hooks were skipped
because they trip on a pre-existing collection error in
`test/ssrf-parity.test.ts` (0 tests collected) that also fails on a
clean `main` checkout and is unrelated to this change. CI runs the full
gate.

---
Signed-off-by: latenighthackathon
<latenighthackathon@users.noreply.github.com>

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

* **Features**
* Updated Discord messaging so `discordProxyUrl` is no longer emitted
per account; Discord Gateway traffic is routed via the application’s
managed proxy configuration for consistent behavior.

* **Tests**
* Revised unit and end-to-end tests to assert Discord account `proxy`
remains empty while the global managed proxy URL is used, including
cases with proxy host/port environment overrides.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Signed-off-by: Hadar Cohen <hacohen@redhat.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
…5544) (NVIDIA#5571)

## Summary
The Discord channel config emits a per-account proxy
(`channels.discord.accounts.default.proxy = http://10.200.0.1:3128`)
that OpenClaw's Discord plugin rejects by design.
`extensions/discord/src/proxy-fetch.ts` `validateDiscordProxyUrl` throws
`Proxy URL must target a loopback host` for any non-loopback host, and
that validator runs on both the REST and gateway transports. The
rejected proxy is dropped, so the Discord gateway WebSocket cannot
egress the deny-by-default network namespace and never reaches READY.
This restores reliance on the top-level managed proxy for Discord, the
mechanism that originally addressed NVIDIA#5075 / NVIDIA#3894.

## Related Issue
Fixes NVIDIA#5544

## Changes
- Resolve `discordProxyUrl` back to `undefined` so the per-account proxy
field is omitted from the rendered `openclaw.json`. Discord gateway and
REST egress is carried by the top-level managed proxy
(`proxy.loopbackMode: "gateway-only"`), which OpenClaw documents as the
path for routing channel traffic through the operator proxy.
- Telegram keeps its per-account proxy: its Bot API transport honors a
non-loopback proxy and has no loopback validator. Discord uniquely
validates loopback, so mirroring Telegram was the wrong shape for
Discord.
- Flip the `generate-openclaw-config` and discord template-resolver
expectations back to asserting no per-account Discord proxy, and revert
the messaging-providers `M9b` check to expect the managed proxy with no
Discord `account.proxy`.
- Effectively reverts NVIDIA#5248 (and its NVIDIA#5391 test follow-up).

## 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
- [ ] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [x] Targeted tests pass for changed behavior
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed

Ran: `npx vitest run test/discord-template-resolver-proxy.test.ts
test/generate-openclaw-config.test.ts` (130 passed), `npm run
build:cli`, and `biome check` on the touched files (clean). The
full-suite `test-cli`/`test-plugin` commit and push hooks were skipped
because they trip on a pre-existing collection error in
`test/ssrf-parity.test.ts` (0 tests collected) that also fails on a
clean `main` checkout and is unrelated to this change. CI runs the full
gate.

---
Signed-off-by: latenighthackathon
<latenighthackathon@users.noreply.github.com>


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

* **Features**
* Updated Discord messaging so `discordProxyUrl` is no longer emitted
per account; Discord Gateway traffic is routed via the application’s
managed proxy configuration for consistent behavior.

* **Tests**
* Revised unit and end-to-end tests to assert Discord account `proxy`
remains empty while the global managed proxy URL is used, including
cases with proxy host/port environment overrides.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
## Summary
Restore issue NVIDIA#5800 parity package `P0-C` for merged bash-suite
messaging/Discord/WhatsApp deltas only.

## Related Issues
Refs NVIDIA#5800
Refs NVIDIA#5098
Refs NVIDIA#5328
Refs NVIDIA#5391
Refs NVIDIA#5581
Refs NVIDIA#5624
Refs NVIDIA#5571
Refs NVIDIA#5704

## Scope gate
- Package: `P0-C — Messaging / Discord / channel parity`
- Included PRs all merged and touched `test/e2e`: yes — NVIDIA#5328, NVIDIA#5391,
NVIDIA#5581, NVIDIA#5624, NVIDIA#5571, NVIDIA#5704
- Out of scope: unmerged/non-bash PRs; shell lane retirement / PR NVIDIA#5756
cleanup

## Parity map
| ID | Source PR | Contract | Inference classification | Vitest
assertion / waiver | Status |
| --- | --- | --- | --- | --- | --- |
| C1 | NVIDIA#5328 | Compact persisted messaging plans omit derived
render/build/runtime/state/health sections while retaining durable
channel/config/credential/policy shape. | `none` |
`src/lib/messaging/plan-validation.test.ts`;
`test/e2e-scenario/live/channels-add-remove.test.ts` | covered |
| C2 | NVIDIA#5328 | Existing compact plans hydrate before merge so channel
add preserves prior hooks/render semantics. | `none` | existing
`src/lib/messaging/applier/host-state-applier.test.ts` | covered |
| C3 | NVIDIA#5391, NVIDIA#5571 | Discord config must not emit a non-loopback
per-account proxy; OpenClaw managed proxy remains configured. | `none` |
`test/discord-template-resolver-proxy.test.ts`;
`test/generate-openclaw-config.test.ts`;
`test/e2e-scenario/live/messaging-providers.test.ts`;
`test/e2e-scenario/live/openclaw-discord-pairing.test.ts` | covered |
| C4 | NVIDIA#5581 | OpenClaw Discord pairing Vitest preserves fake Gateway
token rewrite, connect-shell approval, and workflow dispatch boundary. |
`hermetic-default` | existing
`test/e2e-scenario/live/openclaw-discord-pairing.test.ts`; support
boundary/helper tests | covered |
| C5 | NVIDIA#5624 | Fake Discord Gateway capture proof accepts only redacted
identify rows, rejects placeholder/raw-token leakage, and proves token
rewrite. | `hermetic-default` |
`test/e2e-scenario/live/messaging-providers.test.ts`; existing
Hermes/OpenClaw Discord capture assertions and support tests | covered |
| C6 | NVIDIA#5704 | WhatsApp policy checks require expected endpoints before
rebuild and endpoints plus Node binary scope after rebuild. | `none` |
`test/e2e-scenario/live/messaging-providers.test.ts`;
`test/policies.test.ts` | covered |

## Inference mode support
- Default mode for touched live targets: `none` for config/unit
assertions; `hermetic-default` for fake Discord Gateway/live sandbox
token-rewrite assertions.
- Real inference support preserved: not applicable to this package’s
messaging/provider contracts; live sandbox targets still use existing
`NVIDIA_INFERENCE_API_KEY` path where their broader scenario requires
install/onboard.
- Modes validated in this PR: unit/support hermetic commands below;
selective live E2E run `28194650942` passed
`messaging-providers-vitest`, `channels-add-remove-vitest`, and
`openclaw-discord-pairing-vitest` at `531acd9f8`. Follow-up head
`46e004e3` only tightens local workflow-boundary assertions for
`COMPATIBLE_API_KEY`.
- If not validated with real inference: package contracts are
messaging/config/proxy/capture policy boundaries;
`channels-add-remove-vitest` also passed the hosted-compatible workflow
path after staging `NVIDIA_INFERENCE_API_KEY` as `COMPATIBLE_API_KEY`.

## Validation
- [x] `npx vitest run --project cli --maxWorkers 1 --no-fileParallelism
src/lib/messaging/plan-validation.test.ts
src/lib/messaging/applier/host-state-applier.test.ts
test/discord-template-resolver-proxy.test.ts`
- [x] `npx vitest run --project e2e-vitest-support --maxWorkers 1
--no-fileParallelism
test/e2e-scenario/support-tests/openclaw-discord-legacy-capture.test.ts
test/e2e-scenario/support-tests/openclaw-discord-pairing-helpers.test.ts
test/e2e-scenario/support-tests/openclaw-discord-workflow-boundary.test.ts`
- [x] `npx vitest run --project cli --maxWorkers 1 --no-fileParallelism
--testTimeout 30000 test/generate-openclaw-config.test.ts -t
"Discord|proxy|non-Slack"`
- [x] `npx vitest run --project cli --maxWorkers 1 --no-fileParallelism
test/policies.test.ts -t "whatsapp"`
- [x] `npx vitest run --project e2e-vitest-support --maxWorkers 1
--no-fileParallelism
test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
test/e2e-scenario/support-tests/openclaw-discord-workflow-boundary.test.ts`
- [x] Selective live E2E workflow `28194650942`:
`messaging-providers-vitest`, `channels-add-remove-vitest`,
`openclaw-discord-pairing-vitest` all passed.

## Follow-ups / waivers
- None.


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

* **Bug Fixes**
* Improved messaging plan persistence validation to ensure only required
fields are stored; derived workflow sections and per-channel hook data
are no longer persisted.
* Strengthened live channel add/remove assertions to enforce
`agentRender` and per-channel `hooks` absence.
* Updated live messaging provider and Discord pairing validations
(WhatsApp preset hosts and stricter gateway capture checks; account
proxy now required to be exactly empty when unset).
* **Tests / CI**
* Enhanced Vitest/e2e scenario test tooling and environment setup for
hosted-compatible inference, including compatible API key staging and
more robust Discord gateway capture/proxy handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
## Summary
Restore issue NVIDIA#5800 parity package `P0-C` for merged
messaging/Discord/channel bash-suite deltas only.

## Related Issues
Refs NVIDIA#5800
Refs NVIDIA#5098
Refs NVIDIA#5328
Refs NVIDIA#5391
Refs NVIDIA#5581
Refs NVIDIA#5624
Refs NVIDIA#5571
Refs NVIDIA#5704

## Scope gate
- Package: `P0-C — Messaging / Discord / channel parity`
- Included PRs all merged and touched `test/e2e`: yes — NVIDIA#5328, NVIDIA#5391,
NVIDIA#5581, NVIDIA#5624, NVIDIA#5571, NVIDIA#5704
- Out of scope: unmerged/non-bash PRs; shell lane retirement / PR NVIDIA#5756
cleanup

## Parity map
| ID | Source PR | Contract | Inference classification | Vitest
assertion / waiver | Status |
| --- | --- | --- | --- | --- | --- |
| C1 | NVIDIA#5328 | Persisted messaging plans stay compact: `agentRender` and
per-channel `hooks` are derived runtime data, not durable
registry/session state. | `none` |
`src/lib/messaging/plan-validation.test.ts`;
`test/e2e-scenario/live/channels-add-remove.test.ts`; existing
`channels-stop-start-helpers.ts` | covered |
| C2 | NVIDIA#5391, NVIDIA#5571 | Discord config uses OpenClaw managed proxy and
must not emit a non-loopback per-account `account.proxy`. | `none` |
Existing `test/e2e-scenario/live/messaging-providers.test.ts`;
`test/e2e-scenario/live/openclaw-discord-pairing.test.ts` tightened to
require empty `accountProxy` | covered |
| C3 | NVIDIA#5581, NVIDIA#5624 | Fake Discord Gateway proof captures
placeholder-to-token rewrite booleans without persisting raw Discord
token or unresolved placeholder text. | `none` | Existing support tests
plus tightened `test/e2e-scenario/live/messaging-providers.test.ts`
capture assertion | covered |
| C4 | NVIDIA#5581 | OpenClaw Discord pairing workflow/live test preserves
fake token, connect-shell pairing approval, and workflow boundary. |
`none` | Existing
`test/e2e-scenario/live/openclaw-discord-pairing.test.ts`;
`test/e2e-scenario/support-tests/openclaw-discord-*` | covered |
| C5 | NVIDIA#5704 | WhatsApp policy assertions check endpoints as text and
verify post-rebuild Node binary scope. | `none` |
`test/e2e-scenario/live/messaging-providers.test.ts` now checks pre/post
policy text and Node binary scope | covered |

## Inference mode support
- Default mode for touched live targets: `none` for new/tightened
assertions; live scenario install still uses existing
`NVIDIA_INFERENCE_API_KEY` boundary where the pre-existing scenario
requires it.
- Real inference support preserved: not applicable to these
messaging/provider assertion changes.
- Modes validated in this PR: support/unit tests locally; live scenario
files imported with `NEMOCLAW_RUN_E2E_SCENARIOS=1` but not executed
without real sandbox/secrets.
- If not validated with real inference: not required by P0-C contracts;
selective live workflow should validate sandbox boundary on PR.

## Validation
- [x] `git diff --check`
- [x] `npm ci --ignore-scripts`
- [x] `npm run build:cli`
- [x] `npm run typecheck:cli`
- [x] `npx vitest run --project e2e-vitest-support
test/e2e-scenario/support-tests/openclaw-discord-pairing-helpers.test.ts
test/e2e-scenario/support-tests/openclaw-discord-legacy-capture.test.ts
test/e2e-scenario/support-tests/openclaw-discord-workflow-boundary.test.ts`
- [x] `npx vitest run src/lib/messaging/plan-validation.test.ts
src/lib/state/onboard-session.test.ts test/registry.test.ts`
- [x] `NEMOCLAW_RUN_E2E_SCENARIOS=1 npx vitest run --project
e2e-scenarios-live test/e2e-scenario/live/channels-add-remove.test.ts
test/e2e-scenario/live/messaging-providers.test.ts
test/e2e-scenario/live/openclaw-discord-pairing.test.ts
test/e2e-scenario/live/channels-stop-start.test.ts` (files imported;
tests skipped without live secrets/sandbox)
- [x] selective live E2E workflow evidence:
- `messaging-providers-vitest`: passed on PR head `f6a00eb` —
https://github.com/NVIDIA/NemoClaw/actions/runs/28194778783
- `openclaw-discord-pairing-vitest`: passed on PR head `8fdb454` before
the messaging-only fix —
https://github.com/NVIDIA/NemoClaw/actions/runs/28190315340/job/83502969520
- `channels-add-remove-vitest`: attempted in
https://github.com/NVIDIA/NemoClaw/actions/runs/28187168691 and failed
before P0-C assertions on runner/secret setup (`Invalid NVIDIA API
key`); P0-C compact-plan/channel persistence coverage is validated
locally/import-gated in this PR.

Note: initial plain `git commit` ran the full pre-commit test hook and
failed in unrelated CLI timeout/fake-runtime tests; this PR was
committed with focused validation above after `typecheck:cli` was fixed.

## Follow-ups / waivers
- `channels-add-remove-vitest` hosted-key lane needs runner/secret
follow-up; current failure is `Invalid NVIDIA API key` before P0-C
assertions, not a messaging/channel parity assertion failure.


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

* **Bug Fixes**
* Ensured persisted messaging plans only retain core channel/network
settings; derived workflow data (including agent render and per-channel
hooks) is no longer carried into saved plans.

* **Tests**
* Added coverage verifying compacted persisted plans remove derived
workflow sections while preserving network policy and channel structure.
* Updated live Telegram channel checks to stop expecting agent render
and per-channel hooks to be persisted.
* Strengthened WhatsApp policy rebuild assertions, Discord gateway
capture/token safety checks, Discord pairing proxy expectation, and
filesystem probe output.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@wscurran wscurran added area: e2e End-to-end tests, nightly failures, or validation infrastructure area: messaging Messaging channels, bridges, manifests, or channel lifecycle chore Build, CI, dependency, or tooling maintenance integration: discord Discord integration or channel behavior labels Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: e2e End-to-end tests, nightly failures, or validation infrastructure area: messaging Messaging channels, bridges, manifests, or channel lifecycle chore Build, CI, dependency, or tooling maintenance integration: discord Discord integration or channel behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants