Skip to content

test(e2e): prove Discord proxy binary whitelist#3663

Merged
cv merged 4 commits into
mainfrom
test/discord-proxy-binary-regression-3477
May 17, 2026
Merged

test(e2e): prove Discord proxy binary whitelist#3663
cv merged 4 commits into
mainfrom
test/discord-proxy-binary-regression-3477

Conversation

@cv

@cv cv commented May 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds Discord messaging E2E coverage for the #3477 proxy/binary-whitelist distinction. The test now proves that curl is denied by the Discord preset while Node can use the same OpenShell proxy path, and adds a hermetic fake HTTPS REST proof so the behavior is reproducible without depending only on live Discord.

Related Issue

Fixes #3477

Changes

  • Extended test/e2e/test-messaging-providers.sh to verify live Discord policy entries, OpenShell proxy env, curl denial, and Node API/CDN reachability.
  • Added test/e2e/lib/discord-rest-policy-proof.sh plus a fake HTTPS Discord-shaped REST server fixture to prove Node-only CONNECT authorization hermetically.
  • Refreshed E2E parity tracking files for the new legacy assertions.

Type of Change

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

Verification

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

Signed-off-by: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

  • Tests
    • Expanded end-to-end messaging provider tests (Telegram, Discord, WeChat) with broader connectivity, proxy/policy, credential leakage/sanitization checks, improved cleanup, and hermetic REST flows that distinguish Node vs curl behavior.
    • Added an E2E advisor auto-dispatch integration test validating plan composition with simultaneous jobs.
  • Chores
    • Auto-dispatch logic: removed max-job truncation so computed jobs are dispatched without enforced capping.

Review Change Stack

@cv cv self-assigned this May 17, 2026
@coderabbitai

coderabbitai Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor

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: 8c1da3e2-6b54-42c0-acc8-ca15baf6ebe6

📥 Commits

Reviewing files that changed from the base of the PR and between 2fb97f4 and 25e99d2.

📒 Files selected for processing (2)
  • test/e2e-advisor-dispatch.test.ts
  • tools/e2e-advisor/dispatch.mts
💤 Files with no reviewable changes (1)
  • tools/e2e-advisor/dispatch.mts

📝 Walkthrough

Walkthrough

Adds a hermetic fake Discord REST HTTPS server, bash test helpers to manage it and apply Node-only policies, refactors E2E messaging tests to perform policy/proxy inspection and Node-vs-curl hermetic checks, and updates generated parity docs and assertion totals (now 2040).

Changes

Discord REST Hermetic Testing

Layer / File(s) Summary
Fake Discord REST HTTPS server
test/e2e/lib/fake-discord-rest-api.cjs
Node.js HTTPS server emulating Discord REST, reads TLS/host/port from env, records JSONL capture events, serves /api/v10/gateway and CDN responses, writes optional port file, and handles SIGTERM/SIGINT shutdown.
Discord REST policy proof test helpers
test/e2e/lib/discord-rest-policy-proof.sh
Bash helpers: start/stop fake REST server with self-signed cert, poll readiness, apply a Node-only nemoclaw preset (tls: skip), run sandboxed Node and curl requests against the fake endpoint, and summarize JSONL capture counts.
Messaging provider test refactoring
test/e2e/test-messaging-providers.sh
Phase 4 refactor: source new REST helper; inspect OpenShell policy for Discord endpoints and Node binary whitelist; verify sandbox proxy env points to 10.200.0.1:3128; diagnostic curl probe; Node reachability probes to Discord API/CDN; hermetic fake REST phase ensuring Node can reach /api/v10/gateway, curl is denied before reaching the fake server, and capture counts show node=1 and curl=0.
Test assertion documentation updates
test/e2e/docs/parity-inventory.generated.json, test/e2e/docs/parity-map.yaml
Generated parity inventory and parity-map updated with expanded Discord M13 assertions covering policy presence, proxy wiring, curl tunnel-denial behavior, hermetic fake REST interactions, and capture/count verification. totals.assertions updated to 2040.

E2E Advisor Auto-dispatch

Layer / File(s) Summary
Remove max-job cap in planner
tools/e2e-advisor/dispatch.mts
Removed logic that enforced E2E_ADVISOR_AUTO_DISPATCH_MAX_JOBS as an upper bound so auto-dispatch proceeds to build dispatch inputs without truncation.
Auto-dispatch test addition
test/e2e-advisor-dispatch.test.ts
Adds a Vitest case asserting auto-dispatch includes all recommended dispatchable jobs even when E2E_ADVISOR_AUTO_DISPATCH_MAX_JOBS is set lower.

Sequence Diagram

sequenceDiagram
  participant TestScript as test-messaging-providers.sh
  participant StartHelper as start_fake_discord_rest_api()
  participant PolicyHelper as apply_fake_discord_rest_policy()
  participant NodeRunner as run_fake_discord_rest_node_request()
  participant CurlRunner as run_fake_discord_rest_curl_request()
  participant Capture as JSONL_Capture
  participant PolicyEngine as nemoclaw

  TestScript->>StartHelper: start fake REST server (get port)
  TestScript->>PolicyHelper: write & apply Node-only policy via nemoclaw
  TestScript->>NodeRunner: Node GET /api/v10/gateway (expect 200)
  TestScript->>CurlRunner: curl GET /api/v10/gateway (expect denial patterns)
  TestScript->>Capture: query node vs curl counts (expect node=1, curl=0)
  PolicyHelper->>PolicyEngine: nemoclaw policy-add with CONNECT rules
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

E2E, Integration: Discord, OpenShell, enhancement: messaging

Suggested reviewers

  • ericksoa
  • jyaunches

Poem

🐰 I built a tiny server with a cert and a hop,
Tests tiptoe in while real networks take a stop,
Node is let through, curl hears a gentle "no",
Captures count whispers what the probes need to know,
Logs neat and tidy—now tests can safely hop!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes one out-of-scope change: modifications to tools/e2e-advisor/dispatch.mts removing E2E_ADVISOR_AUTO_DISPATCH_MAX_JOBS enforcement and a corresponding test in test/e2e-advisor-dispatch.test.ts, which are unrelated to Discord proxy binary whitelist validation. Move the E2E_ADVISOR_AUTO_DISPATCH_MAX_JOBS changes to a separate PR focused on advisor dispatch planning, keeping this PR focused solely on Discord proxy binary whitelist E2E test coverage.
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test(e2e): prove Discord proxy binary whitelist' accurately reflects the main objective: adding E2E test coverage to validate Discord preset's proxy vs. binary-whitelist behavior through hermetic fake REST API testing.
Linked Issues check ✅ Passed All coding requirements from issue #3477 are met: the PR adds E2E test coverage validating the Discord preset's binary-whitelist behavior [#3477], implements hermetic fake Discord REST API testing to bypass external proxy limitations [#3477], includes policy verification and curl/Node reachability classification logic [#3477], and updates parity tracking [#3477].

✏️ 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 test/discord-proxy-binary-regression-3477

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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

@github-actions

github-actions Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: messaging-providers-e2e
Optional E2E: docs-validation-e2e

Dispatch hint: messaging-providers-e2e

Auto-dispatched E2E: messaging-providers-e2e via nightly-e2e.yaml at 25e99d24c089374948720b647e8aed1a3178cec0nightly run

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • messaging-providers-e2e (medium): Validates the modified messaging providers E2E script and newly added Discord REST policy proof, including sandbox policy application, OpenShell gateway proxy use, credential/provider path, and Node-vs-curl binary whitelist enforcement.

Optional E2E

  • docs-validation-e2e (low): Optional confidence for documentation/parity-adjacent changes; the touched parity docs are not the primary docs-validation target, so this is useful but not merge-blocking.

New E2E recommendations

  • None.

Dispatch hint

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@test/e2e/lib/discord-rest-policy-proof.sh`:
- Around line 29-67: Register the cleanup trap immediately after creating the
temporary directory so failures in cert generation or docker startup still
cleanup; move the call to append_exit_trap_for_fake_discord_rest_api
cleanup_fake_discord_rest_api to right after FAKE_DISCORD_REST_DIR is created
(immediately after the mkdir/mktemp block where FAKE_DISCORD_REST_DIR,
FAKE_DISCORD_REST_* variables are set and the capture file is initialized) so
any subsequent early returns (from openssl or docker run) will trigger cleanup;
also ensure the script has a proper shebang and is executable to satisfy
shellfmt/ShellCheck guidelines.

In `@test/e2e/test-messaging-providers.sh`:
- Around line 981-998: The test currently treats a live Discord "CONNECT ...
403" response as definitive proof that curl was blocked by the sandbox (the
branch that calls pass), but that same response can come from an upstream proxy;
change the branch that checks for CONNECT 403/HTTP 403 (the condition using
live_dc_curl and grep) to stop calling pass and instead emit a
diagnostic/ambiguous signal (use info() or a diagnostic helper) that includes
the live_dc_curl snippet and states the result is ambiguous and that
M13-rest-d/M13-rest-e provide hermetic whitelist proof; update the message text
formerly passed to pass("M13-curl: ...") to something like info("M13-curl:
ambiguous – live CONNECT 403 may be upstream; see hermetic whitelist tests;
output: ...") so the test no longer claims a whitelist pass when the live probe
is inconclusive.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 07ec8054-7517-4e45-88d5-7cdbd0a53c27

📥 Commits

Reviewing files that changed from the base of the PR and between 259b89f and c8e07dc.

📒 Files selected for processing (5)
  • test/e2e/docs/parity-inventory.generated.json
  • test/e2e/docs/parity-map.yaml
  • test/e2e/lib/discord-rest-policy-proof.sh
  • test/e2e/lib/fake-discord-rest-api.cjs
  • test/e2e/test-messaging-providers.sh

Comment thread test/e2e/lib/discord-rest-policy-proof.sh Outdated
Comment thread test/e2e/test-messaging-providers.sh
@cv

cv commented May 17, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the two CodeRabbit comments in 2fb97f4: moved fake Discord REST cleanup trap before cert/docker startup failure points, and made the live Discord curl CONNECT-403 probe diagnostic-only instead of a passing assertion. Refreshed parity metadata and re-ran npx prek run --files ..., targeted E2E convention/parity tests, and npm test.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@test/e2e/test-messaging-providers.sh`:
- Around line 970-975: The proxy check currently only verifies
HTTPS_PROXY/https_proxy point to 10.200.0.1:3128 but ignores NO_PROXY/no_proxy
exemptions; update the validation around live_proxy_env so it also scans
NO_PROXY and no_proxy and fails if either contains discord.com or
cdn.discordapp.com (or equivalent host patterns), i.e. keep the existing grep
that asserts proxy endpoints but add an additional negative check that rejects
when live_proxy_env matches
NO_PROXY=.*(discord\.com|cdn\.discordapp\.com)|no_proxy=.*(discord\.com|cdn\.discordapp\.com);
ensure the failure message still references M13-proxy (and M13-curl if
duplicated) and include the truncated live_proxy_env for debugging.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7db736c3-6b86-44a5-9960-82fe014b7a80

📥 Commits

Reviewing files that changed from the base of the PR and between c8e07dc and 2fb97f4.

📒 Files selected for processing (4)
  • test/e2e/docs/parity-inventory.generated.json
  • test/e2e/docs/parity-map.yaml
  • test/e2e/lib/discord-rest-policy-proof.sh
  • test/e2e/test-messaging-providers.sh
✅ Files skipped from review due to trivial changes (1)
  • test/e2e/docs/parity-inventory.generated.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/e2e/docs/parity-map.yaml
  • test/e2e/lib/discord-rest-policy-proof.sh

Comment on lines +970 to +975
live_proxy_env=$(sandbox_exec 'printf "HTTPS_PROXY=%s\nhttps_proxy=%s\nNO_PROXY=%s\nno_proxy=%s\n" "$HTTPS_PROXY" "$https_proxy" "$NO_PROXY" "$no_proxy"' 2>/dev/null || true)
info "Sandbox proxy env: ${live_proxy_env//$'\n'/ }"
if echo "$live_proxy_env" | grep -qE "https?_proxy=.*10\.200\.0\.1:3128|HTTPS_PROXY=.*10\.200\.0\.1:3128"; then
pass "M13-proxy: Sandbox uses the OpenShell gateway proxy"
else
fail "M13-proxy: Sandbox proxy env does not point at OpenShell gateway: ${live_proxy_env:0:200}"

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail when NO_PROXY exempts Discord hosts.

This check can pass even when Discord traffic bypasses the OpenShell gateway, because it ignores NO_PROXY/no_proxy. If discord.com or cdn.discordapp.com is exempted there, M13 and M13-curl can report the right outcome for the wrong path.

Suggested check
 live_proxy_env=$(sandbox_exec 'printf "HTTPS_PROXY=%s\nhttps_proxy=%s\nNO_PROXY=%s\nno_proxy=%s\n" "$HTTPS_PROXY" "$https_proxy" "$NO_PROXY" "$no_proxy"' 2>/dev/null || true)
 info "Sandbox proxy env: ${live_proxy_env//$'\n'/ }"
-if echo "$live_proxy_env" | grep -qE "https?_proxy=.*10\.200\.0\.1:3128|HTTPS_PROXY=.*10\.200\.0\.1:3128"; then
+if echo "$live_proxy_env" | grep -qiE '^(NO_PROXY|no_proxy)=.*(discord\.com|cdn\.discordapp\.com)'; then
+  fail "M13-proxy: Discord hosts are exempted via NO_PROXY/no_proxy, so the live proxy checks can bypass OpenShell"
+elif echo "$live_proxy_env" | grep -qE "https?_proxy=.*10\.200\.0\.1:3128|HTTPS_PROXY=.*10\.200\.0\.1:3128"; then
   pass "M13-proxy: Sandbox uses the OpenShell gateway proxy"
 else
   fail "M13-proxy: Sandbox proxy env does not point at OpenShell gateway: ${live_proxy_env:0:200}"
 fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
live_proxy_env=$(sandbox_exec 'printf "HTTPS_PROXY=%s\nhttps_proxy=%s\nNO_PROXY=%s\nno_proxy=%s\n" "$HTTPS_PROXY" "$https_proxy" "$NO_PROXY" "$no_proxy"' 2>/dev/null || true)
info "Sandbox proxy env: ${live_proxy_env//$'\n'/ }"
if echo "$live_proxy_env" | grep -qE "https?_proxy=.*10\.200\.0\.1:3128|HTTPS_PROXY=.*10\.200\.0\.1:3128"; then
pass "M13-proxy: Sandbox uses the OpenShell gateway proxy"
else
fail "M13-proxy: Sandbox proxy env does not point at OpenShell gateway: ${live_proxy_env:0:200}"
live_proxy_env=$(sandbox_exec 'printf "HTTPS_PROXY=%s\nhttps_proxy=%s\nNO_PROXY=%s\nno_proxy=%s\n" "$HTTPS_PROXY" "$https_proxy" "$NO_PROXY" "$no_proxy"' 2>/dev/null || true)
info "Sandbox proxy env: ${live_proxy_env//$'\n'/ }"
if echo "$live_proxy_env" | grep -qiE '^(NO_PROXY|no_proxy)=.*(discord\.com|cdn\.discordapp\.com)'; then
fail "M13-proxy: Discord hosts are exempted via NO_PROXY/no_proxy, so the live proxy checks can bypass OpenShell"
elif echo "$live_proxy_env" | grep -qE "https?_proxy=.*10\.200\.0\.1:3128|HTTPS_PROXY=.*10\.200\.0\.1:3128"; then
pass "M13-proxy: Sandbox uses the OpenShell gateway proxy"
else
fail "M13-proxy: Sandbox proxy env does not point at OpenShell gateway: ${live_proxy_env:0:200}"
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/e2e/test-messaging-providers.sh` around lines 970 - 975, The proxy check
currently only verifies HTTPS_PROXY/https_proxy point to 10.200.0.1:3128 but
ignores NO_PROXY/no_proxy exemptions; update the validation around
live_proxy_env so it also scans NO_PROXY and no_proxy and fails if either
contains discord.com or cdn.discordapp.com (or equivalent host patterns), i.e.
keep the existing grep that asserts proxy endpoints but add an additional
negative check that rejects when live_proxy_env matches
NO_PROXY=.*(discord\.com|cdn\.discordapp\.com)|no_proxy=.*(discord\.com|cdn\.discordapp\.com);
ensure the failure message still references M13-proxy (and M13-curl if
duplicated) and include the truncated live_proxy_env for debugging.

@cv

cv commented May 17, 2026

Copy link
Copy Markdown
Collaborator Author

Removed the E2E advisor auto-dispatch job cap in 25e99d2. The dispatcher now sends all dispatchable required advisor jobs in one nightly-e2e dispatch; E2E_ADVISOR_AUTO_DISPATCH_MAX_JOBS is intentionally ignored/retired. Added a regression test that sets the old env var to 1 and verifies two required jobs are still dispatched. Validation: npm test -- test/e2e-advisor-dispatch.test.ts.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 25983649324
Target ref: 25e99d24c089374948720b647e8aed1a3178cec0
Workflow ref: main
Requested jobs: messaging-providers-e2e
Summary: 1 passed, 0 failed, 0 skipped

Job Result
messaging-providers-e2e ✅ success

@cv cv merged commit 35e8cb4 into main May 17, 2026
26 checks passed
ericksoa added a commit that referenced this pull request May 21, 2026
## Summary
- add Discord-specific policy-add guidance that curl is not a valid
success signal because it is outside the preset binary allowlist
- document Node HTTPS probes for Discord REST/CDN validation behind
proxy and call out DNS-only checks as inconclusive
- cover the direct warning helper plus interactive and named policy-add
discord flows

## Reopen Context
Issue #3477 was closed by #3663, then reopened from a v0.0.44 QA repro
that still used curl and dns.resolve as validation signals. That same
repro showed Node HTTPS to https://discord.com/api/v10/gateway returning
200, which is the signal this PR now documents and surfaces in
policy-add.

## Related Issue
Fixes #3477

## Verification
- [x] npm run build:cli
- [x] npm test -- test/policies.test.ts
- [x] npm test -- test/validate-blueprint.test.ts
- [x] make docs

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

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

## Documentation
- Added troubleshooting guidance for Discord preset validation behind
proxies: explains why curl probes can mislead, clarifies the built-in
preset’s behavior, warns about DNS-only checks, and provides Node HTTPS
one-liners to verify Discord API/CDN egress and next investigative
steps.

## Tests
- Extended coverage to assert Discord preset validation warnings and to
verify interactive and non-interactive policy-add flows print the new
guidance and proceed with apply as expected.

<!-- review_stack_entry_start -->

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

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@cv cv deleted the test/discord-proxy-binary-regression-3477 branch May 27, 2026 21:19
@wscurran wscurran added the chore Build, CI, dependency, or tooling maintenance label Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Build, CI, dependency, or tooling maintenance

Projects

None yet

2 participants