Skip to content

test(e2e): add messaging providers vitest coverage#5364

Merged
cv merged 6 commits into
mainfrom
codex/5098-messaging-providers
Jun 12, 2026
Merged

test(e2e): add messaging providers vitest coverage#5364
cv merged 6 commits into
mainfrom
codex/5098-messaging-providers

Conversation

@cv

@cv cv commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds focused live Vitest coverage for the highest-value messaging-provider paths from the legacy test/e2e/test-messaging-providers.sh scenario and wires that focused scenario into e2e workflow dispatch. This PR does not retire the entire legacy shell contract: Telegram inbound replies, Slack mention/reply feedback, revoked Slack token pre-validation, and no-real-secret plugin-send fallback paths remain in the shell suite until their own scoped migrations.

The new coverage keeps fake-token defaults, _REAL secret overrides, redaction assertions, optional live sends, QR-only WhatsApp behavior, and evidence-rich skips for NVIDIA endpoint validation outages before provider assertions can run.

Related Issue

Refs #5098

Changes

  • Add test/e2e-scenario/live/messaging-providers.test.ts covering provider registration, redaction checks, fake API rewrite probes, optional live sends, and best-effort cleanup.
  • Add test/e2e-scenario/live/messaging-providers-helpers.ts for local helper plumbing so the focused *.test.ts stays under the default test-size guardrail.
  • Add messaging-providers-vitest to .github/workflows/e2e-vitest-scenarios.yaml with the same optional secret contract as the shell scenario.
  • Update free-standing scenario dispatch support and the workflow contract test timeout for the expanded free-standing scenario inventory.

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

Targeted checks run locally:

  • npm ci --ignore-scripts
  • npm run build:cli
  • cd nemoclaw && npm ci --ignore-scripts && npm run build
  • npx @biomejs/biome check test/e2e-scenario/live/messaging-providers.test.ts test/e2e-scenario/live/messaging-providers-helpers.ts test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts .github/workflows/e2e-vitest-scenarios.yaml tools/e2e-scenarios/free-standing-jobs.env ci/test-file-size-budget.json
  • npm run test-size:check
  • npm run source-shape:check
  • npx vitest run --project e2e-vitest-support test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • NEMOCLAW_RUN_E2E_SCENARIOS=1 npx vitest run --project e2e-scenarios-live test/e2e-scenario/live/messaging-providers.test.ts (skips locally without NVIDIA_API_KEY)
  • npm run typecheck:cli -- --pretty false
  • npx vitest run --project cli test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • git diff --check
  • npx prek run --files .github/workflows/e2e-vitest-scenarios.yaml ci/test-file-size-budget.json test/e2e-scenario/live/messaging-providers.test.ts test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts tools/e2e-scenarios/free-standing-jobs.env

GitHub verification:

Local note: the full test-cli hook was attempted during git commit and git push, but hit unrelated 5s local timeouts in CLI help / Brave web-search validation tests. The branch was committed and pushed with only test-cli skipped; pre-push TypeScript and all migration-focused checks passed.

  • 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)

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

Summary by CodeRabbit

  • New Features

    • End-to-end messaging-provider tests for Slack, Discord, Telegram, WhatsApp, and WeChat, including gateway rewrite and mock-provider probes.
  • Tests

    • New CI job to run live messaging-provider E2E scenarios.
    • Extensive helper utilities and a comprehensive live test validating token handling, placeholder/redaction behavior, network/policy probes, and optional real-message sends.
    • Adjusted test timeouts for stability.
  • Chores

    • CI job matrix updated to include messaging-providers scenarios.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv cv self-assigned this Jun 12, 2026
@copy-pr-bot

copy-pr-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jun 12, 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: 545f29f7-eba3-4906-88c4-f755fadbd2cb

📥 Commits

Reviewing files that changed from the base of the PR and between 9189f31 and f3b4503.

📒 Files selected for processing (1)
  • test/e2e-scenario/live/messaging-providers.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/e2e-scenario/live/messaging-providers.test.ts

📝 Walkthrough

Walkthrough

Adds a new live Vitest E2E scenario for messaging providers with comprehensive test helpers (env/token parsing, sandbox/host runners, fake Docker APIs, policy rewrites, Slack REST and Discord gateway clients), integrates the scenario as a free-standing CI job, and wires the job into workflow reporting.

Changes

Messaging Providers E2E

Layer / File(s) Summary
Test helper utilities and infrastructure
test/e2e-scenario/live/messaging-providers-helpers.ts
Exports constants, types, env/token parsing (messagingEnv, MessagingEnv, MessagingTokens), utility predicates and encoders, execution wrappers (runHost, runSandboxShell, runSandboxNode), OpenClaw config readers (readOpenClawConfig), token-surface probes (rawTokenSurfaceProbe), fake Docker API lifecycle (startFakeDockerApi), policy rewrite appliers (applyRestRewritePolicy, applyWebSocketRewritePolicy), and protocol clients for Slack HTTP and Discord Gateway WebSocket.
Test module and scenarios
test/e2e-scenario/live/messaging-providers.test.ts
New Vitest live scenario enforcing placeholder/non-leak expectations, orchestration and cleanup, provider config/rebuild checks, token canonicalization and OpenClaw assertions, network/policy/L7 probes, fake Slack/Discord gateway exercises, and optional real-message sends when live credentials/targets are present.
CI workflow job and free-standing registration
.github/workflows/e2e-vitest-scenarios.yaml, tools/e2e-scenarios/free-standing-jobs.env, test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
Adds messaging-providers-vitest job with Docker Hub login (retry + anonymous fallback), Node setup, messaging secret/allowlist/ID env wiring, test execution, and artifact upload; includes the job in report-to-pr needs; updates free-standing jobs env mapping to enable the scenario and adds a 15s timeout adjustment to the support test.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#5243: Related addition of a free-standing Vitest job and workflow wiring pattern used by this change.
  • NVIDIA/NemoClaw#5236: Also extends the e2e Vitest pipeline with a new *-vitest job and reporter integration.

Suggested labels

area: messaging, area: e2e

Suggested reviewers

  • prekshivyas

Poem

🐰 I hopped through logs and placeholder trails,

Mocked gateways squealed and captured details,
Tokens disguised, no secrets to spill,
Tests danced in CI, quiet and still,
A tiny rabbit nods — the scenarios thrill.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 PR title accurately describes the primary change: migrating the legacy messaging-provider E2E shell contract into a focused Vitest scenario with comprehensive coverage additions.
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 codex/5098-messaging-providers

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

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: messaging-providers-vitest
Optional E2E: credential-sanitization-vitest, network-policy-vitest, token-rotation-vitest

Dispatch hint: messaging-providers-vitest

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • messaging-providers-vitest (high): This PR adds and registers the messaging-providers free-standing E2E job; run the new job to prove the workflow selector, CI environment, install/sandbox lifecycle, provider credential placeholder handling, network policy, and live/fake messaging-provider contracts work end-to-end.

Optional E2E

  • credential-sanitization-vitest (medium): Adjacent confidence for secret redaction and credential boundary behavior that the new messaging-provider test heavily relies on.
  • network-policy-vitest (medium): Adjacent confidence for OpenShell network-policy enforcement and gateway behavior used by the new REST/WebSocket credential rewrite checks.
  • token-rotation-vitest (medium): Optional adjacent check for provider token boundaries and fake messaging-token handling, especially because the new scenario follows similar credential-provider patterns.

New E2E recommendations

  • None.

Dispatch hint

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

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Recommendation

Required Vitest E2E scenarios: 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=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

  • messaging-providers-vitest: Focused free-standing Vitest job wired for changed live test test/e2e-scenario/live/messaging-providers.test.ts.
    • 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

  • .github/workflows/e2e-vitest-scenarios.yaml
  • test/e2e-scenario/live/messaging-providers-helpers.ts
  • test/e2e-scenario/live/messaging-providers.test.ts
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • tools/e2e-scenarios/free-standing-jobs.env

Comment thread test/e2e-scenario/live/messaging-providers.test.ts Fixed
Comment thread test/e2e-scenario/live/messaging-providers.test.ts Fixed
Comment thread test/e2e-scenario/live/messaging-providers.test.ts Fixed
Comment thread test/e2e-scenario/live/messaging-providers.test.ts Fixed
Comment thread test/e2e-scenario/live/messaging-providers.test.ts Fixed
Comment thread test/e2e-scenario/live/messaging-providers.test.ts Fixed
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Comment thread test/e2e-scenario/live/messaging-providers-helpers.ts Fixed
@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor

Findings: 0 needs attention, 6 worth checking, 0 nice ideas
Since last review: 1 prior item resolved, 5 still apply, 0 new items found

Review findings

🛠️ Needs attention

  • None.

🔎 Worth checking

  • Source-of-truth review needed: test/e2e-scenario/live/messaging-providers-helpers.ts::premergeSlackPolicyIfNeeded: The advisor marked localized patch analysis as needs_followup.
    • Recommendation: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
    • Evidence: premergeSlackPolicyIfNeeded() reads BASE_POLICY, appends Slack endpoints when api.slack.com is absent, and restores in cleanup. openclaw-sandbox.yaml says messaging endpoints are intentionally not baseline and should come from presets/{telegram,discord,slack}.yaml.
  • Runtime Slack policy append masks the committed policy source (test/e2e-scenario/live/messaging-providers-helpers.ts:388): The helper appends Slack endpoints directly to the checked-out base sandbox policy when api.slack.com is absent. That lets the live scenario pass against a runtime-mutated policy state instead of the committed user-facing Slack preset/onboard path. This is a policy-sensitive source-of-truth workaround: the base policy explicitly says messaging endpoints are intentionally not in baseline and should come from presets.
    • Recommendation: Do not patch nemoclaw-blueprint/policies/openclaw-sandbox.yaml at runtime. Exercise the committed Slack preset/onboard sequencing, or fail with a clear assertion when the required preset/source policy is missing. If a temporary workaround is unavoidable, document the invalid state, owning source boundary, reason the source fix is deferred, regression guard, and removal condition in code.
    • Evidence: premergeSlackPolicyIfNeeded() reads BASE_POLICY, checks policyTextHasHost(original, "api.slack.com"), then fs.appendFileSync() adds Slack REST/WebSocket policy blocks. The committed base policy says Telegram/Discord/Slack endpoints are intentionally not in baseline and should be in presets/{telegram,discord,slack}.yaml; presets/slack.yaml already contains Slack endpoints with credential rewrite fields.
  • Real Discord token can be written to fake gateway capture output (test/e2e-scenario/live/messaging-providers.test.ts:839): When DISCORD_BOT_TOKEN_REAL is supplied, the test passes the real Discord bot token as FAKE_DISCORD_GATEWAY_EXPECTED_TOKEN. The fake Discord gateway records the raw identify token in JSONL capture output, unnecessarily writing a live secret to runner-local storage and possibly future diagnostics.
    • Recommendation: Change fake-discord-gateway.cjs or this test path to record only non-secret proof such as tokenMatchesExpected, tokenLooksPlaceholder, and optionally a one-way digest. Add an assertion that identify capture omits any raw token field.
    • Evidence: messaging-providers.test.ts passes FAKE_DISCORD_GATEWAY_EXPECTED_TOKEN: state.tokens.discord. test/e2e/lib/fake-discord-gateway.cjs records { event: "identify", token, tokenMatchesExpected, tokenLooksPlaceholder }. The new assertion checks tokenMatchesExpected/tokenLooksPlaceholder but not raw token absence.
  • Secret-bearing fake provider helper pulls an unpinned Docker image (test/e2e-scenario/live/messaging-providers-helpers.ts:565): The fake provider helper runs node:22-bookworm-slim without a digest in a workflow job that can receive NVIDIA and live messaging-provider secrets. The image can drift independently of reviewed code, and expected provider tokens are passed into the container environment.
    • Recommendation: Pin the fake API container image by digest or reuse an existing pinned fixture image. Consider running the fake containers as a non-root user if the fixture supports it.
    • Evidence: startFakeDockerApi() builds docker run args with expectedEnv values and then appends "node:22-bookworm-slim", "node", and the fake API script path.
  • New secret-bearing workflow job lacks job-specific boundary validation (.github/workflows/e2e-vitest-scenarios.yaml:1444): The new messaging-providers-vitest job receives NVIDIA and messaging-provider secrets. The workflow currently uses good baseline controls, but tools/e2e-scenarios/workflow-boundary.mts only provides generic inventory coverage for this new high-risk job. Without a dedicated validator and negative support tests, future drift could move secrets to job-level env or unsafe steps, relax action pinning, change checkout credential persistence, or broaden artifact uploads without a focused guard.
    • Recommendation: Add a validateMessagingProvidersVitestJob check in tools/e2e-scenarios/workflow-boundary.mts with negative support-test coverage for full-SHA action pinning, checkout persist-credentials: false, npm ci --ignore-scripts, secrets only on the intended run step, safe artifact upload settings, expected job/scenario selectors, and Docker auth cleanup/isolation if Docker Hub credentials remain in the job.
    • Evidence: messaging-providers-vitest scopes NVIDIA_API_KEY and provider secrets to the run step and uses pinned actions today, but grep found no validateMessagingProvidersVitestJob in workflow-boundary.mts. The support-test diff only increases the inventory test timeout.
  • Docker Hub auth is not isolated or cleaned before secret-bearing repo-code steps (.github/workflows/e2e-vitest-scenarios.yaml:1461): The new job authenticates to Docker Hub using the default Docker configuration, then runs dependency/build/test steps that execute repository code and receive provider secrets. This follows an existing pattern, but newly extending it to a secrets-heavy messaging-provider lane increases credential-boundary drift risk.
    • Recommendation: Use an isolated DOCKER_CONFIG for the Docker Hub login and remove it before running repo-code steps, or add explicit cleanup after pulls. Include this behavior in the dedicated workflow-boundary validator.
    • Evidence: The messaging-providers-vitest job runs docker login in 'Authenticate to Docker Hub' and does not set an isolated DOCKER_CONFIG or perform docker logout/config cleanup before npm/build/Vitest steps.

🌱 Nice ideas

  • None.
Consider writing more tests for
  • **Runtime validation** — workflow-boundary rejects messaging-providers-vitest when checkout persist-credentials is true. The PR changes live sandbox/network-policy behavior and adds a secret-bearing free-standing workflow job. The new live scenario is useful, but targeted runtime/support tests are still needed for workflow trusted-code boundaries, source-of-truth behavior, and secret-capture behavior.
  • **Runtime validation** — workflow-boundary rejects messaging-providers-vitest when checkout/setup-node/upload-artifact are not full-SHA pinned. The PR changes live sandbox/network-policy behavior and adds a secret-bearing free-standing workflow job. The new live scenario is useful, but targeted runtime/support tests are still needed for workflow trusted-code boundaries, source-of-truth behavior, and secret-capture behavior.
  • **Runtime validation** — workflow-boundary rejects messaging-providers-vitest when NVIDIA or messaging-provider secrets appear in job-level env or non-run steps. The PR changes live sandbox/network-policy behavior and adds a secret-bearing free-standing workflow job. The new live scenario is useful, but targeted runtime/support tests are still needed for workflow trusted-code boundaries, source-of-truth behavior, and secret-capture behavior.
  • **Runtime validation** — workflow-boundary rejects messaging-providers-vitest artifact upload when include-hidden-files is true or the whole artifact directory is uploaded. The PR changes live sandbox/network-policy behavior and adds a secret-bearing free-standing workflow job. The new live scenario is useful, but targeted runtime/support tests are still needed for workflow trusted-code boundaries, source-of-truth behavior, and secret-capture behavior.
  • **Runtime validation** — workflow-boundary rejects messaging-providers-vitest when Docker Hub auth uses the default Docker config without cleanup or isolation. The PR changes live sandbox/network-policy behavior and adds a secret-bearing free-standing workflow job. The new live scenario is useful, but targeted runtime/support tests are still needed for workflow trusted-code boundaries, source-of-truth behavior, and secret-capture behavior.
  • **Acceptance clause:** The new coverage keeps fake-token defaults, `_REAL` secret overrides, redaction assertions, optional live sends, QR-only WhatsApp behavior, and evidence-rich skips for NVIDIA endpoint validation outages before provider assertions can run. — add test evidence or identify existing coverage. messagingEnv() implements fake defaults and _REAL overrides; the scenario probes raw token absence from sandbox env/process/filesystem, includes optional Telegram/Discord/Slack live sends, covers WhatsApp QR-only behavior, and skips on NVIDIA endpoint rate-limit failures before provider assertions. However, the Discord fake gateway path can still write DISCORD_BOT_TOKEN_REAL to capture output.
  • **Acceptance clause:** Refs Epic: Migrate legacy bash E2E into the Vitest E2E system #5098 — add test evidence or identify existing coverage. The deterministic context reported linkedIssues: [] and did not provide issue Epic: Migrate legacy bash E2E into the Vitest E2E system #5098 body or comments, so issue-specific acceptance clauses could not be verified.
  • **Acceptance clause:** Add `messaging-providers-vitest` to `.github/workflows/e2e-vitest-scenarios.yaml` with the same optional secret contract as the shell scenario. — add test evidence or identify existing coverage. The workflow job is added and passes NVIDIA_API_KEY plus optional Telegram/Discord/Slack secrets to the run step. Boundary hardening is incomplete because there is no job-specific workflow validator and Docker auth is not isolated/cleaned.
Since last review details

Current findings:

  • Source-of-truth review needed: test/e2e-scenario/live/messaging-providers-helpers.ts::premergeSlackPolicyIfNeeded: The advisor marked localized patch analysis as needs_followup.
    • Recommendation: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
    • Evidence: premergeSlackPolicyIfNeeded() reads BASE_POLICY, appends Slack endpoints when api.slack.com is absent, and restores in cleanup. openclaw-sandbox.yaml says messaging endpoints are intentionally not baseline and should come from presets/{telegram,discord,slack}.yaml.
  • Runtime Slack policy append masks the committed policy source (test/e2e-scenario/live/messaging-providers-helpers.ts:388): The helper appends Slack endpoints directly to the checked-out base sandbox policy when api.slack.com is absent. That lets the live scenario pass against a runtime-mutated policy state instead of the committed user-facing Slack preset/onboard path. This is a policy-sensitive source-of-truth workaround: the base policy explicitly says messaging endpoints are intentionally not in baseline and should come from presets.
    • Recommendation: Do not patch nemoclaw-blueprint/policies/openclaw-sandbox.yaml at runtime. Exercise the committed Slack preset/onboard sequencing, or fail with a clear assertion when the required preset/source policy is missing. If a temporary workaround is unavoidable, document the invalid state, owning source boundary, reason the source fix is deferred, regression guard, and removal condition in code.
    • Evidence: premergeSlackPolicyIfNeeded() reads BASE_POLICY, checks policyTextHasHost(original, "api.slack.com"), then fs.appendFileSync() adds Slack REST/WebSocket policy blocks. The committed base policy says Telegram/Discord/Slack endpoints are intentionally not in baseline and should be in presets/{telegram,discord,slack}.yaml; presets/slack.yaml already contains Slack endpoints with credential rewrite fields.
  • Real Discord token can be written to fake gateway capture output (test/e2e-scenario/live/messaging-providers.test.ts:839): When DISCORD_BOT_TOKEN_REAL is supplied, the test passes the real Discord bot token as FAKE_DISCORD_GATEWAY_EXPECTED_TOKEN. The fake Discord gateway records the raw identify token in JSONL capture output, unnecessarily writing a live secret to runner-local storage and possibly future diagnostics.
    • Recommendation: Change fake-discord-gateway.cjs or this test path to record only non-secret proof such as tokenMatchesExpected, tokenLooksPlaceholder, and optionally a one-way digest. Add an assertion that identify capture omits any raw token field.
    • Evidence: messaging-providers.test.ts passes FAKE_DISCORD_GATEWAY_EXPECTED_TOKEN: state.tokens.discord. test/e2e/lib/fake-discord-gateway.cjs records { event: "identify", token, tokenMatchesExpected, tokenLooksPlaceholder }. The new assertion checks tokenMatchesExpected/tokenLooksPlaceholder but not raw token absence.
  • Secret-bearing fake provider helper pulls an unpinned Docker image (test/e2e-scenario/live/messaging-providers-helpers.ts:565): The fake provider helper runs node:22-bookworm-slim without a digest in a workflow job that can receive NVIDIA and live messaging-provider secrets. The image can drift independently of reviewed code, and expected provider tokens are passed into the container environment.
    • Recommendation: Pin the fake API container image by digest or reuse an existing pinned fixture image. Consider running the fake containers as a non-root user if the fixture supports it.
    • Evidence: startFakeDockerApi() builds docker run args with expectedEnv values and then appends "node:22-bookworm-slim", "node", and the fake API script path.
  • New secret-bearing workflow job lacks job-specific boundary validation (.github/workflows/e2e-vitest-scenarios.yaml:1444): The new messaging-providers-vitest job receives NVIDIA and messaging-provider secrets. The workflow currently uses good baseline controls, but tools/e2e-scenarios/workflow-boundary.mts only provides generic inventory coverage for this new high-risk job. Without a dedicated validator and negative support tests, future drift could move secrets to job-level env or unsafe steps, relax action pinning, change checkout credential persistence, or broaden artifact uploads without a focused guard.
    • Recommendation: Add a validateMessagingProvidersVitestJob check in tools/e2e-scenarios/workflow-boundary.mts with negative support-test coverage for full-SHA action pinning, checkout persist-credentials: false, npm ci --ignore-scripts, secrets only on the intended run step, safe artifact upload settings, expected job/scenario selectors, and Docker auth cleanup/isolation if Docker Hub credentials remain in the job.
    • Evidence: messaging-providers-vitest scopes NVIDIA_API_KEY and provider secrets to the run step and uses pinned actions today, but grep found no validateMessagingProvidersVitestJob in workflow-boundary.mts. The support-test diff only increases the inventory test timeout.
  • Docker Hub auth is not isolated or cleaned before secret-bearing repo-code steps (.github/workflows/e2e-vitest-scenarios.yaml:1461): The new job authenticates to Docker Hub using the default Docker configuration, then runs dependency/build/test steps that execute repository code and receive provider secrets. This follows an existing pattern, but newly extending it to a secrets-heavy messaging-provider lane increases credential-boundary drift risk.
    • Recommendation: Use an isolated DOCKER_CONFIG for the Docker Hub login and remove it before running repo-code steps, or add explicit cleanup after pulls. Include this behavior in the dedicated workflow-boundary validator.
    • Evidence: The messaging-providers-vitest job runs docker login in 'Authenticate to Docker Hub' and does not set an isolated DOCKER_CONFIG or perform docker logout/config cleanup before npm/build/Vitest steps.

Workflow run details

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

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ✅ All jobs passed

Run: 27438223405
Workflow ref: codex/5098-messaging-providers
Requested scenarios: (default — all supported)
Requested jobs: messaging-providers-vitest
Summary: 1 passed, 0 failed, 22 skipped

Job Result
credential-migration-vitest ⏭️ skipped
credential-sanitization-vitest ⏭️ skipped
double-onboard-vitest ⏭️ skipped
gateway-guard-recovery ⏭️ skipped
generate-matrix ✅ success
hermes-e2e-vitest ⏭️ skipped
hermes-root-entrypoint-smoke-vitest ⏭️ skipped
inference-routing-vitest ⏭️ skipped
issue-4434-tui-unreachable-inference-vitest ⏭️ skipped
launchable-smoke-vitest ⏭️ skipped
live-scenarios ⏭️ skipped
messaging-providers-vitest ⚠️ cancelled
model-router-provider-routed-inference-vitest ⏭️ skipped
network-policy-vitest ⏭️ skipped
onboard-negative-paths-vitest ⏭️ skipped
openclaw-tui-chat-correlation-vitest ⏭️ skipped
openshell-version-pin-vitest ⏭️ skipped
rebuild-openclaw-vitest ⏭️ skipped
runtime-overrides-vitest ⏭️ skipped
sandbox-rebuild-vitest ⏭️ skipped
sandbox-survival-vitest ⏭️ skipped
shields-config-vitest ⏭️ skipped
skill-agent-vitest ⏭️ skipped
token-rotation-vitest ⏭️ skipped

@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ✅ All jobs passed

Run: 27438710530
Workflow ref: codex/5098-messaging-providers
Requested scenarios: (default — all supported)
Requested jobs: messaging-providers-vitest
Summary: 2 passed, 0 failed, 22 skipped

Job Result
credential-migration-vitest ⏭️ skipped
credential-sanitization-vitest ⏭️ skipped
double-onboard-vitest ⏭️ skipped
gateway-guard-recovery ⏭️ skipped
generate-matrix ✅ success
hermes-e2e-vitest ⏭️ skipped
hermes-root-entrypoint-smoke-vitest ⏭️ skipped
inference-routing-vitest ⏭️ skipped
issue-4434-tui-unreachable-inference-vitest ⏭️ skipped
launchable-smoke-vitest ⏭️ skipped
live-scenarios ⏭️ skipped
messaging-providers-vitest ✅ success
model-router-provider-routed-inference-vitest ⏭️ skipped
network-policy-vitest ⏭️ skipped
onboard-negative-paths-vitest ⏭️ skipped
openclaw-tui-chat-correlation-vitest ⏭️ skipped
openshell-version-pin-vitest ⏭️ skipped
rebuild-openclaw-vitest ⏭️ skipped
runtime-overrides-vitest ⏭️ skipped
sandbox-rebuild-vitest ⏭️ skipped
sandbox-survival-vitest ⏭️ skipped
shields-config-vitest ⏭️ skipped
skill-agent-vitest ⏭️ skipped
token-rotation-vitest ⏭️ skipped

@cv

cv commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator Author

Addressing the PR Review Advisor Slack-policy worth-check note: the runtime base-policy premerge is intentional migration parity with test/e2e/test-messaging-providers.sh (the legacy script premerges Slack before install so first boot has Slack egress, see its #2340 comment). Invalid state: openclaw-sandbox.yaml lacks Slack endpoints during initial sandbox creation while the channel preset is applied later. Source boundary: this is test-local checkout mutation only and cleanup restores the file; production policy source is not changed. Removal condition/source fix: delete premergeSlackPolicyIfNeeded once onboarding can apply the committed Slack preset before first sandbox boot or the base policy intentionally includes Slack. Regression signal: required messaging-providers-vitest passed on run 27438710530; Actions exercised the 429 early-skip artifact path and missing-sandbox cleanup tolerance.

@cv cv marked this pull request as ready for review June 12, 2026 21:03

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

🤖 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-scenario/live/messaging-providers-helpers.ts`:
- Around line 767-773: encodeClientText currently always emits the 7-bit
payload-length form which breaks for the IDENTIFY JSON (lines ~836-844) that
exceeds 125 bytes; update encodeClientText to encode extended WebSocket payload
lengths properly: if payload length <=125 use 0x80|len, if <=65535 use 0x80|126
followed by a 2-byte big-endian length, otherwise use 0x80|127 followed by an
8-byte big-endian length, then append the 4-byte mask and masked payload as
before so the IDENTIFY frame is valid for strict gateways.

In `@test/e2e-scenario/live/messaging-providers.test.ts`:
- Around line 603-653: The inline Node probe passed to sandboxOutput should
never terminate with a non-zero exit because sandboxOutput throws on non-zero
exit codes; update the script inside the discordReach call so it always exits 0
(e.g., replace process.exit(failed ? 1 : 0) with process.exit(0) or remove
explicit exiting and let the script naturally end) and keep the existing
logging/failed flag behavior so the subsequent checks (discordReach, check,
skipNote) still run; locate the Node snippet used to build discordReach in the
test and modify the final done() completion path accordingly.
- Around line 174-176: The check currently passes if SANDBOX_NAME appears
anywhere and any sandbox is Ready; change the condition so it searches
sandboxList.stdout for a single line that contains both the SANDBOX_NAME and the
word "Ready" (i.e., match them on the same row). In the check that uses
sandboxList.stdout and SANDBOX_NAME, replace the boolean expression with a
multiline regex that finds a line containing the escaped SANDBOX_NAME and
"Ready" together (ensure you escape any regex metacharacters in SANDBOX_NAME
before building the regex) so the test only succeeds when the target sandbox row
is Ready.
🪄 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: 4dcbd397-c2f0-47d3-85c5-a6c237696236

📥 Commits

Reviewing files that changed from the base of the PR and between 7f583ed and 1119859.

📒 Files selected for processing (5)
  • .github/workflows/e2e-vitest-scenarios.yaml
  • test/e2e-scenario/live/messaging-providers-helpers.ts
  • test/e2e-scenario/live/messaging-providers.test.ts
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • tools/e2e-scenarios/free-standing-jobs.env

Comment thread test/e2e-scenario/live/messaging-providers-helpers.ts
Comment thread test/e2e-scenario/live/messaging-providers.test.ts Outdated
Comment thread test/e2e-scenario/live/messaging-providers.test.ts
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ❌ Some jobs failed

Run: 27444259885
Workflow ref: codex/5098-messaging-providers
Requested scenarios: messaging-providers
Requested jobs: (default — all free-standing when no scenarios are requested)
Summary: 1 passed, 1 failed, 22 skipped

Job Result
credential-migration-vitest ⏭️ skipped
credential-sanitization-vitest ⏭️ skipped
double-onboard-vitest ⏭️ skipped
gateway-guard-recovery ⏭️ skipped
generate-matrix ✅ success
hermes-e2e-vitest ⏭️ skipped
hermes-root-entrypoint-smoke-vitest ⏭️ skipped
inference-routing-vitest ⏭️ skipped
issue-4434-tui-unreachable-inference-vitest ⏭️ skipped
launchable-smoke-vitest ⏭️ skipped
live-scenarios ⏭️ skipped
messaging-providers-vitest ❌ failure
model-router-provider-routed-inference-vitest ⏭️ skipped
network-policy-vitest ⏭️ skipped
onboard-negative-paths-vitest ⏭️ skipped
openclaw-tui-chat-correlation-vitest ⏭️ skipped
openshell-version-pin-vitest ⏭️ skipped
rebuild-openclaw-vitest ⏭️ skipped
runtime-overrides-vitest ⏭️ skipped
sandbox-rebuild-vitest ⏭️ skipped
sandbox-survival-vitest ⏭️ skipped
shields-config-vitest ⏭️ skipped
skill-agent-vitest ⏭️ skipped
token-rotation-vitest ⏭️ skipped

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

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ✅ All jobs passed

Run: 27445134225
Workflow ref: codex/5098-messaging-providers
Requested scenarios: messaging-providers
Requested jobs: (default — all free-standing when no scenarios are requested)
Summary: 2 passed, 0 failed, 22 skipped

Job Result
credential-migration-vitest ⏭️ skipped
credential-sanitization-vitest ⏭️ skipped
double-onboard-vitest ⏭️ skipped
gateway-guard-recovery ⏭️ skipped
generate-matrix ✅ success
hermes-e2e-vitest ⏭️ skipped
hermes-root-entrypoint-smoke-vitest ⏭️ skipped
inference-routing-vitest ⏭️ skipped
issue-4434-tui-unreachable-inference-vitest ⏭️ skipped
launchable-smoke-vitest ⏭️ skipped
live-scenarios ⏭️ skipped
messaging-providers-vitest ✅ success
model-router-provider-routed-inference-vitest ⏭️ skipped
network-policy-vitest ⏭️ skipped
onboard-negative-paths-vitest ⏭️ skipped
openclaw-tui-chat-correlation-vitest ⏭️ skipped
openshell-version-pin-vitest ⏭️ skipped
rebuild-openclaw-vitest ⏭️ skipped
runtime-overrides-vitest ⏭️ skipped
sandbox-rebuild-vitest ⏭️ skipped
sandbox-survival-vitest ⏭️ skipped
shields-config-vitest ⏭️ skipped
skill-agent-vitest ⏭️ skipped
token-rotation-vitest ⏭️ skipped

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv cv changed the title test(e2e): migrate messaging providers scenario test(e2e): add messaging providers vitest coverage Jun 12, 2026
@cv cv merged commit ebd6127 into main Jun 12, 2026
46 checks passed
@cv cv deleted the codex/5098-messaging-providers branch June 12, 2026 22:51
@cv cv added the v0.0.65 Release target label Jun 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v0.0.65 Release target

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants