Skip to content

test(e2e): migrate OpenClaw Discord pairing to Vitest - #5581

Merged
jyaunches merged 24 commits into
mainfrom
e2e-phase6-openclaw-discord-pairing-linear
Jun 22, 2026
Merged

test(e2e): migrate OpenClaw Discord pairing to Vitest#5581
jyaunches merged 24 commits into
mainfrom
e2e-phase6-openclaw-discord-pairing-linear

Conversation

@cv

@cv cv commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Migrates the OpenClaw Discord pairing E2E into live Vitest coverage. The replacement keeps the real install/OpenShell sandbox boundary, hermetic fake Discord Gateway token rewrite, runtime pairing request creation, and connect-shell approval flow.

Related Issue

Refs #5098

Changes

  • Add test/e2e-scenario/live/openclaw-discord-pairing.test.ts as Vitest coverage for test/e2e/test-openclaw-discord-pairing.sh.
  • Add test/e2e-scenario/live/openclaw-pairing-helpers.ts as Discord-specific fake Gateway and pairing assertion helpers; Slack coverage remains separate from this Discord migration.
  • Wire openclaw-discord-pairing-vitest into .github/workflows/e2e-vitest-scenarios.yaml.

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

  • 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
  • Targeted tests pass for changed behavior
  • Full npm test passes (broad runtime changes only)
  • 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

Release Notes

  • Tests

    • Added live end-to-end Vitest coverage for Discord pairing, including gateway protocol checks, pairing request/approval flows, and artifact output.
    • Replaced the prior shell-script scenario with assertions covering Discord configuration, OpenClaw state root, and token-rewrite behavior (ensuring sensitive values aren’t captured).
    • Expanded helper/contract testing, including legacy Discord capture validation and stronger “fails closed” sandbox/runtime handling.
  • Chores

    • Added a dedicated free-standing CI job for the Discord pairing scenario and included its status in PR reporting.
    • Introduced workflow boundary validation for the new job to enforce secure, isolated Docker/auth handling.

@cv cv self-assigned this Jun 22, 2026
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Migrates the legacy bash test-openclaw-discord-pairing.sh to a Vitest live test (openclaw-discord-pairing.test.ts), backed by a new openclaw-pairing-helpers.ts library and new sandboxEncodedSh/sandboxNode utilities in phase6-messaging-helpers.ts. Hardens the fake Discord gateway by removing raw token from capture logs and tightens token-rewrite assertions in the shell checker. Adds comprehensive support tests validating helper contracts and legacy capture behavior, and wires a new CI job with full workflow boundary validation.

Changes

OpenClaw Discord Pairing Vitest Migration

Layer / File(s) Summary
Fake Discord gateway and shell script: token-rewrite hardening
test/e2e/lib/fake-discord-gateway.cjs, test/e2e/test-openclaw-discord-pairing.sh
Removes raw token field from IDENTIFY record() in the fake gateway; refactors the embedded Node checker in the shell script to serialize captures first, then adds four dedicated failure modes: tokenMatchesExpected, placeholder leak detection, raw identify.token property presence, and full-capture substring leak.
phase6-messaging-helpers: shared sandbox execution utilities
test/e2e-scenario/live/phase6-messaging-helpers.ts
New module exporting sandboxEncodedSh, which base64-encodes/decodes scripts to a temp file with EXIT trap cleanup, and sandboxNode, which validates environment keys, converts env entries to shell exports, embeds module source in Node ESM heredoc, and delegates to sandboxEncodedSh.
openclaw-pairing-helpers: pairing orchestration library
test/e2e-scenario/live/openclaw-pairing-helpers.ts
New comprehensive module exporting PairingChannel type, env/redaction builders, sandbox cleanup, fake Discord gateway lifecycle (startFakeDiscordGateway), policy installation (applyFakePolicy), OpenClaw state-root assertion, embedded LOAD_CONVERSATION_RUNTIME_SOURCE and DISCORD_PAIRING_SCRIPT strings, result parsing, pairing command builders, full approve/assert orchestration, Discord gateway proof via raw WebSocket handshake, and artifact writer.
openclaw-discord-pairing live Vitest test
test/e2e-scenario/live/openclaw-discord-pairing.test.ts
Full Vitest live test replacing bash scenario: scaffolding with token-capture assertion helper, then test.skipIf(...) scenario covering install, readiness, Python config extraction (Discord token/proxy/DM policy), state-root assertion, gateway protocol proof, token-rewrite validation, pairing request/result parsing, artifact writing, and approve flow.
Support tests: contracts, legacy capture, and workflow validation
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/e2e-scenarios-workflow.test.ts
Legacy-capture checker extraction and execution test; pairing-helpers contract tests for shell quoting, loadConversationRuntime fail-closed behavior, sandboxNode validation, and fake-gateway IDENTIFY capture token omission; workflow selector test updated to testTimeoutOptions(240_000) and new test for openclaw-discord-pairing boundary validation.
Workflow boundary validator: OpenClaw Discord pairing
tools/e2e-scenarios/workflow-boundary.mts
New validateOpenClawDiscordPairingVitestJob validator enforcing runner/timeout, free-standing selector, strict env/secret non-exposure, step constraints (Docker Hub auth, no inline secrets), isolated DOCKER_CONFIG, OpenShell env unsets, Vitest invocation, artifact upload naming/path/options, and always() Docker cleanup; wired into validateE2eVitestScenariosWorkflowBoundary; reformats related error messages in validateTelegramInjectionVitestJob.
CI workflow: new Vitest job and report-to-pr wiring
.github/workflows/e2e-vitest-scenarios.yaml
Adds openclaw-discord-pairing-vitest free-standing job with isolated Docker auth (DOCKER_CONFIG in RUNNER_TEMP), Docker Hub login with anonymous fallback, build/install steps, npx vitest run for Discord pairing test with fixed DISCORD_BOT_TOKEN, artifact upload to e2e-artifacts/vitest/openclaw-discord-pairing/, and Docker auth cleanup; extends report-to-pr.needs to include new job.

Sequence Diagram(s)

sequenceDiagram
  participant CI as GitHub Actions
  participant LiveTest as openclaw-discord-pairing.test.ts
  participant Helpers as openclaw-pairing-helpers.ts
  participant FakeGateway as fake-discord-gateway.cjs
  participant Sandbox as OpenShell Sandbox

  rect rgba(70, 130, 180, 0.5)
    note over CI,Sandbox: Setup & Verification
    CI->>LiveTest: npx vitest run
    LiveTest->>Helpers: pairingEnv() / pairingRedactions()
    LiveTest->>Sandbox: installSandbox() + expectSandboxReady()
    LiveTest->>Sandbox: Python config extraction (Discord token/proxy/DM policy)
    LiveTest->>Helpers: assertOpenClawStateRoot()
  end

  rect rgba(60, 179, 113, 0.5)
    note over LiveTest,FakeGateway: Gateway Protocol Proof & Token-Rewrite Validation
    LiveTest->>Helpers: startFakeDiscordGateway()
    Helpers->>FakeGateway: docker run discord-gateway
    LiveTest->>Helpers: applyFakePolicy(websocket-credential-rewrite)
    Helpers->>Sandbox: update policy endpoints + allowlist
    LiveTest->>Helpers: runDiscordGatewayProof()
    Helpers->>FakeGateway: TCP WebSocket UPGRADE + IDENTIFY frame
    FakeGateway-->>Helpers: HELLO / READY / HEARTBEAT_ACK frames
    LiveTest->>FakeGateway: read capture.jsonl
    FakeGateway-->>LiveTest: IDENTIFY record (no raw token, boolean flags only)
  end

  rect rgba(255, 140, 0, 0.5)
    note over LiveTest,Sandbox: Pairing Request & Approval
    LiveTest->>Helpers: issuePairingRequest()
    Helpers->>Sandbox: sandboxEncodedSh(DISCORD_PAIRING_SCRIPT)
    Sandbox-->>Helpers: marked JSON result line
    Helpers-->>LiveTest: PairingResult { code, senderId, channelId, replyText }
    LiveTest->>Helpers: approveAndAssertPairing()
    Helpers->>Sandbox: openclaw pairing approve / list / allow-from
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related issues

Possibly related PRs

  • NVIDIA/NemoClaw#5243: Both PRs modify .github/workflows/e2e-vitest-scenarios.yaml to add free-standing Vitest jobs gated by inputs.jobs/inputs.scenarios selector and wired into the shared report-to-pr job.
  • NVIDIA/NemoClaw#5576: Both PRs extend test/e2e-scenario/live/phase6-messaging-helpers.ts with new shared sandbox execution helpers and wire new job-specific validators into tools/e2e-scenarios/workflow-boundary.mts.
  • NVIDIA/NemoClaw#5346: Both PRs extend tools/e2e-scenarios/workflow-boundary.mts by adding per-job validator calls into validateE2eVitestScenariosWorkflowBoundary to enforce free-standing Vitest job structure.

Suggested labels

area: e2e, integration: discord, chore

Suggested reviewers

  • jyaunches

Poem

🐇 Hop hop, the bash script's gone away,
Now Vitest runs the pairing fray!
No raw token shall the capture keep,
The placeholder guards our secrets deep—
Approve, allow-from, the flow runs tight,
This bunny ships the Discord pairing right! 🎉

🚥 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 title accurately captures the main change: migrating OpenClaw Discord pairing tests from shell scripts to Vitest. It is concise, specific, and directly reflects the primary objective of the PR.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch e2e-phase6-openclaw-discord-pairing-linear

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

@github-code-quality

github-code-quality Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in the e2e-phase6-openclaw-... 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 e2e-phase6-openclaw-... b9ce55b +/-
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 e2e-phase6-openclaw-... branch is 46%. Coverage data for the main branch is not yet available.

Show a code coverage summary of the most covered files.
File main e2e-phase6-openclaw-... b9ce55b +/-
src/lib/state/o...oard-session.ts 91%
src/lib/inference/local.ts 76%
src/lib/sandbox/config.ts 72%
src/lib/actions...dbox/rebuild.ts 67%
src/lib/onboard/preflight.ts 64%
src/lib/actions...licy-channel.ts 56%
src/lib/state/sandbox.ts 55%
src/lib/onboard...er-gpu-patch.ts 50%
src/lib/policy/index.ts 49%
src/lib/onboard.ts 18%

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

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: openclaw-discord-pairing-vitest
Optional E2E: network-policy-vitest, messaging-providers-vitest

Dispatch hint: openclaw-discord-pairing-vitest

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • openclaw-discord-pairing-vitest (high): Merge-blocking because this PR introduces and wires the live Discord pairing scenario itself. It covers real installer/onboarding, sandbox lifecycle, OpenClaw Discord provider setup, websocket credential rewrite, fake Discord Gateway token redaction, pairing request creation, and connect-shell approval.

Optional E2E

  • network-policy-vitest (high): Useful adjacent confidence for the policy update/enforcement path because the new Discord scenario depends on endpoint allow rules and websocket credential rewrite behavior, but the new scenario directly exercises the relevant boundary.
  • messaging-providers-vitest (high): Useful adjacent confidence because the new helpers reuse fake provider/container patterns and Discord provider credentials; not merge-blocking unless reviewers want broader messaging-provider regression coverage.

New E2E recommendations

  • None.

Dispatch hint

  • Workflow: .github/workflows/e2e-vitest-scenarios.yaml
  • jobs input: openclaw-discord-pairing-vitest

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Recommendation

Required Vitest E2E scenarios: openclaw-discord-pairing-vitest
Optional Vitest E2E scenarios: None

Dispatch required Vitest E2E scenarios:

  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=openclaw-discord-pairing-vitest

Workflow run

Full Vitest E2E advisor summary

Vitest E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required Vitest E2E scenarios

  • openclaw-discord-pairing-vitest: Focused free-standing Vitest job wired for changed live test test/e2e-scenario/live/openclaw-discord-pairing.test.ts.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=openclaw-discord-pairing-vitest

Optional Vitest E2E scenarios

  • None.

Relevant changed files

  • .github/workflows/e2e-vitest-scenarios.yaml
  • test/e2e-scenario/live/openclaw-discord-pairing.test.ts
  • test/e2e-scenario/live/openclaw-pairing-helpers.ts
  • test/e2e-scenario/live/phase6-messaging-helpers.ts
  • 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
  • test/e2e/lib/fake-discord-gateway.cjs
  • test/e2e/test-openclaw-discord-pairing.sh
  • tools/e2e-scenarios/workflow-boundary.mts

Comment thread test/e2e-scenario/live/openclaw-pairing-helpers.ts Fixed
@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings

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

Action checklist

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

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

  • PRA-T1 Runtime validation — Run or identify the live OpenClaw Discord pairing Vitest scenario that installs the sandbox, verifies fake Discord Gateway websocket credential rewrite, creates a Discord pairing request, approves it, verifies allowFrom persistence, and verifies repeat approval fails closed.. Static review and support tests cover helper contracts and workflow-boundary drift, but the changed behavior crosses GitHub Actions, installer, Docker, OpenShell sandbox, network policy, fake Discord Gateway credential rewrite, and connect-shell pairing approval boundaries. Those cannot be fully proven without behavior-specific runtime validation.
  • PRA-T2 Runtime validation — Run or identify the support tests that cover malformed sandboxNode env key rejection, malicious pairing code/user shell quoting, missing conversation runtime fail-closed behavior, fake Discord capture raw-token redaction, legacy capture compatibility, and workflow-boundary drift rejection.. Static review and support tests cover helper contracts and workflow-boundary drift, but the changed behavior crosses GitHub Actions, installer, Docker, OpenShell sandbox, network policy, fake Discord Gateway credential rewrite, and connect-shell pairing approval boundaries. Those cannot be fully proven without behavior-specific runtime validation.
  • PRA-T3 Runtime validation — If issue Epic: Migrate legacy bash E2E into the Vitest E2E system #5098 acceptance clauses or comments are available outside this deterministic context, map each literal clause to the new live scenario or support-test evidence, or add a behavior-specific test for any clause not covered.. Static review and support tests cover helper contracts and workflow-boundary drift, but the changed behavior crosses GitHub Actions, installer, Docker, OpenShell sandbox, network policy, fake Discord Gateway credential rewrite, and connect-shell pairing approval boundaries. Those cannot be fully proven without behavior-specific runtime validation.
  • PRA-T4 Acceptance clause — Linked issue Epic: Migrate legacy bash E2E into the Vitest E2E system #5098 clauses/comments — add test evidence or identify existing coverage. The deterministic validation context reported linkedIssues: []; no literal Epic: Migrate legacy bash E2E into the Vitest E2E system #5098 issue body or comments were available to extract. Visible PR text only says Refs Epic: Migrate legacy bash E2E into the Vitest E2E system #5098, which is untrusted evidence and not a literal linked-issue acceptance clause.

Workflow run details

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

Comment thread test/e2e-scenario/live/openclaw-pairing-helpers.ts Fixed
Comment thread test/e2e-scenario/live/openclaw-pairing-helpers.ts Fixed
@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ❌ Some jobs failed

Run: 27963286406
Workflow ref: e2e-phase6-openclaw-discord-pairing-linear
Requested scenarios: (default — all supported)
Requested jobs: openclaw-discord-pairing-vitest
Summary: 1 passed, 1 failed, 54 skipped

Job Result
agent-turn-latency-vitest ⏭️ skipped
bedrock-runtime-compatible-anthropic-vitest ⏭️ skipped
brave-search-vitest ⏭️ skipped
channels-add-remove-vitest ⏭️ skipped
cloud-inference-vitest ⏭️ skipped
cloud-onboard-vitest ⏭️ skipped
common-egress-agent-vitest ⏭️ skipped
concurrent-gateway-ports-vitest ⏭️ skipped
credential-migration-vitest ⏭️ skipped
credential-sanitization-vitest ⏭️ skipped
cron-preflight-inference-local-vitest ⏭️ skipped
device-auth-health-vitest ⏭️ skipped
diagnostics-vitest ⏭️ skipped
double-onboard-vitest ⏭️ skipped
full-e2e-vitest ⏭️ skipped
gateway-drift-preflight-vitest ⏭️ skipped
gateway-guard-recovery ⏭️ skipped
gateway-health-honest-vitest ⏭️ skipped
generate-matrix ✅ success
gpu-double-onboard-vitest ⏭️ skipped
gpu-e2e-vitest ⏭️ skipped
hermes-e2e-vitest ⏭️ skipped
hermes-inference-switch-vitest ⏭️ skipped
hermes-root-entrypoint-smoke-vitest ⏭️ skipped
inference-routing-vitest ⏭️ skipped
issue-2478-crash-loop-recovery-vitest ⏭️ skipped
issue-4434-tui-unreachable-inference-vitest ⏭️ skipped
issue-4462-scope-upgrade-approval-vitest ⏭️ skipped
kimi-inference-compat-vitest ⏭️ skipped
launchable-smoke-vitest ⏭️ skipped
live-scenarios ⏭️ skipped
messaging-compatible-endpoint-vitest ⏭️ skipped
messaging-providers-vitest ⏭️ skipped
model-router-provider-routed-inference-vitest ⏭️ skipped
network-policy-vitest ⏭️ skipped
ollama-auth-proxy-vitest ⏭️ skipped
onboard-negative-paths-vitest ⏭️ skipped
onboard-repair-vitest ⏭️ skipped
onboard-resume-vitest ⏭️ skipped
openclaw-discord-pairing-vitest ❌ failure
openclaw-inference-switch-vitest ⏭️ skipped
openclaw-skill-cli-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
sessions-agents-cli-vitest ⏭️ skipped
shields-config-vitest ⏭️ skipped
skill-agent-vitest ⏭️ skipped
snapshot-commands-vitest ⏭️ skipped
state-backup-restore-vitest ⏭️ skipped
telegram-injection-vitest ⏭️ skipped
token-rotation-vitest ⏭️ skipped
upgrade-stale-sandbox-vitest ⏭️ skipped

Failed jobs: openclaw-discord-pairing-vitest. Check run artifacts for logs.

Base automatically changed from e2e-phase6-telegram-injection to main June 22, 2026 15:56
…iscord-pairing-linear

# Conflicts:
#	.github/workflows/e2e-vitest-scenarios.yaml
#	test/e2e-scenario/live/phase6-messaging-helpers.ts
#	test/e2e-scenario/live/telegram-injection.test.ts
@cv cv added the v0.0.66 label Jun 22, 2026

@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

🧹 Nitpick comments (1)
.github/workflows/e2e-vitest-scenarios.yaml (1)

4080-4094: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Align Docker Hub auth with the retry strategy already used in this workflow.

These two new jobs use a single login attempt, while channels-add-remove-vitest already implements a 3-attempt retry loop. Reusing that pattern here will reduce transient auth/rate-limit flakiness.

Suggested change
-      - name: Authenticate to Docker Hub
+      - name: Authenticate to Docker Hub
         env:
           DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
           DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
         shell: bash
         run: |
           set -euo pipefail
           if [[ -z "${DOCKERHUB_USERNAME}" || -z "${DOCKERHUB_TOKEN}" ]]; then
             echo "::notice::Docker Hub credentials not configured; continuing with anonymous pulls."
             exit 0
           fi
           mkdir -p "${DOCKER_CONFIG}"
           chmod 700 "${DOCKER_CONFIG}"
-          echo "${DOCKERHUB_TOKEN}" | timeout 30s docker login docker.io --username "${DOCKERHUB_USERNAME}" --password-stdin || echo "::warning::Docker Hub login failed; continuing with anonymous pulls."
+          login_succeeded=0
+          for attempt in 1 2 3; do
+            if echo "${DOCKERHUB_TOKEN}" | timeout 30s docker login docker.io --username "${DOCKERHUB_USERNAME}" --password-stdin; then
+              login_succeeded=1
+              break
+            fi
+            if [[ "$attempt" -lt 3 ]]; then
+              echo "::warning::Docker Hub login attempt ${attempt} failed; retrying."
+              sleep 5
+            fi
+          done
+          if [[ "$login_succeeded" -ne 1 ]]; then
+            echo "::warning::Docker Hub login failed after 3 attempts; continuing with anonymous pulls."
+          fi

Also applies to: 4157-4170

🤖 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 @.github/workflows/e2e-vitest-scenarios.yaml around lines 4080 - 4094, The
Docker Hub authentication in the "Authenticate to Docker Hub" step uses a single
login attempt without retry logic, which makes it susceptible to transient
failures. Refactor the docker login command within the run step to implement a
3-attempt retry loop, matching the same retry pattern already used in the
channels-add-remove-vitest job elsewhere in this workflow. This will reduce
flakiness from transient authentication and rate-limit issues.
🤖 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/telegram-injection.test.ts`:
- Around line 154-165: The process table leak check in the telegram-injection
test is applying redactionValues to both the hostPs and sandboxPs commands
before asserting that the apiKeyPrefix is not present, which means the test can
false-pass because the API key gets masked before the assertion runs. Refactor
this to capture the process table output without applying redactionValues so the
assertions in resultText(hostPs) and resultText(sandboxPs) are checking actual
unredacted output, or alternatively check the raw output for the presence of
redaction mask signatures as evidence of key exposure, ensuring the "no key
exposure in process table" contract is actually verified.

---

Nitpick comments:
In @.github/workflows/e2e-vitest-scenarios.yaml:
- Around line 4080-4094: The Docker Hub authentication in the "Authenticate to
Docker Hub" step uses a single login attempt without retry logic, which makes it
susceptible to transient failures. Refactor the docker login command within the
run step to implement a 3-attempt retry loop, matching the same retry pattern
already used in the channels-add-remove-vitest job elsewhere in this workflow.
This will reduce flakiness from transient authentication and rate-limit issues.
🪄 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: 4914b50c-ad88-4292-ad24-92796b7c6b19

📥 Commits

Reviewing files that changed from the base of the PR and between 60b0a00 and 126ed1f.

📒 Files selected for processing (10)
  • .github/workflows/e2e-vitest-scenarios.yaml
  • test/e2e-scenario/live/openclaw-discord-pairing.test.ts
  • test/e2e-scenario/live/openclaw-pairing-helpers.ts
  • test/e2e-scenario/live/phase6-messaging-helpers.ts
  • test/e2e-scenario/live/telegram-injection.test.ts
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • test/e2e-scenario/support-tests/openclaw-discord-legacy-capture.test.ts
  • test/e2e-scenario/support-tests/openclaw-discord-pairing-helpers.test.ts
  • test/e2e/lib/fake-discord-gateway.cjs
  • test/e2e/test-openclaw-discord-pairing.sh
💤 Files with no reviewable changes (1)
  • test/e2e/lib/fake-discord-gateway.cjs

Comment thread test/e2e-scenario/live/telegram-injection.test.ts Outdated

@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

🧹 Nitpick comments (2)
tools/e2e-scenarios/workflow-boundary.mts (2)

3583-3586: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Assert the artifact upload name too.

This pins the upload action and path/options, but not with.name; a drift to the default artifact name would still pass validation and can break downstream artifact lookup/reporting.

Suggested boundary check
   requireFullShaAction(errors, upload, "openclaw-discord-pairing-vitest upload-artifact");
   const uploadWith = asRecord(upload?.with);
+  const expectedArtifactName = `e2e-vitest-scenarios-${scenarioName}`;
+  if (uploadWith.name !== expectedArtifactName) {
+    errors.push(
+      `openclaw-discord-pairing-vitest artifact upload name must be ${expectedArtifactName}`,
+    );
+  }
   const uploadPath = stringValue(uploadWith.path);
🤖 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 `@tools/e2e-scenarios/workflow-boundary.mts` around lines 3583 - 3586, The
validation currently checks the upload action and path but does not validate the
artifact name in the with.name field, which could drift to an unexpected default
value. After extracting uploadPath using stringValue from uploadWith.path, also
extract the upload name using stringValue from uploadWith.name and add a
corresponding validation check (similar to the requireUploadPathContains
pattern) to assert that the artifact name matches the expected value, ensuring
the artifact upload name is properly pinned alongside the path validation.

3502-3503: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Also pin the prerequisite checkout/setup/build steps.

This job-specific validator starts validating step contents after steps is built, but it never requires pinned checkout/setup-node actions or the CLI build step. Drift there would still pass this boundary check while weakening checkout isolation or breaking the live test before OpenShell install.

Suggested boundary check
   const steps = asSteps(job.steps);
   requireNoDispatchInputInterpolation(errors, steps);
+  const checkout = steps.find((step) => stringValue(step.uses).startsWith("actions/checkout@"));
+  if (!checkout) errors.push(`${jobName} job missing checkout step`);
+  requireFullShaAction(errors, checkout, `${jobName} checkout`);
+  if (asRecord(checkout?.with)["persist-credentials"] !== false) {
+    errors.push(`${jobName} checkout step must set persist-credentials=false`);
+  }
+
+  const setupNode = namedStep(steps, "Set up Node");
+  if (!setupNode) errors.push(`${jobName} job missing step: Set up Node`);
+  requireFullShaAction(errors, setupNode, `${jobName} setup-node`);
+
+  const buildCli = requireJobStep(errors, jobName, steps, "Build CLI");
+  requireRunContains(errors, buildCli, "npm run build:cli");
+
   for (const step of steps) {
🤖 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 `@tools/e2e-scenarios/workflow-boundary.mts` around lines 3502 - 3503, The
validator function requireNoDispatchInputInterpolation currently only checks for
dispatch input interpolation in the job steps but does not validate that
prerequisite steps are pinned to specific versions. After building the steps
variable using asSteps(job.steps), add additional validation checks to ensure
that the checkout action, setup-node action, and CLI build step all use pinned
versions rather than floating versions. This will prevent version drift in these
critical prerequisite steps from passing the boundary check and potentially
weakening checkout isolation or breaking the live test.
🤖 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 `@tools/e2e-scenarios/workflow-boundary.mts`:
- Around line 3507-3510: The validation logic at the "Run OpenClaw Discord
pairing live test" condition is exempting both NVIDIA secret checks, but the
allow-list at lines 3565-3570 only permits NVIDIA_INFERENCE_API_KEY. To ensure
NVIDIA_API_KEY remains blocked for the live test step as intended, modify the
condition to only skip the requireEnvDoesNotExposeSecret check for
NVIDIA_INFERENCE_API_KEY while keeping the NVIDIA_API_KEY check active for all
steps including the live test step.

---

Nitpick comments:
In `@tools/e2e-scenarios/workflow-boundary.mts`:
- Around line 3583-3586: The validation currently checks the upload action and
path but does not validate the artifact name in the with.name field, which could
drift to an unexpected default value. After extracting uploadPath using
stringValue from uploadWith.path, also extract the upload name using stringValue
from uploadWith.name and add a corresponding validation check (similar to the
requireUploadPathContains pattern) to assert that the artifact name matches the
expected value, ensuring the artifact upload name is properly pinned alongside
the path validation.
- Around line 3502-3503: The validator function
requireNoDispatchInputInterpolation currently only checks for dispatch input
interpolation in the job steps but does not validate that prerequisite steps are
pinned to specific versions. After building the steps variable using
asSteps(job.steps), add additional validation checks to ensure that the checkout
action, setup-node action, and CLI build step all use pinned versions rather
than floating versions. This will prevent version drift in these critical
prerequisite steps from passing the boundary check and potentially weakening
checkout isolation or breaking the live test.
🪄 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: 3af6fc7a-f587-45f7-80e3-c39b26738657

📥 Commits

Reviewing files that changed from the base of the PR and between f1c6309 and 47d23f2.

📒 Files selected for processing (5)
  • .github/workflows/e2e-vitest-scenarios.yaml
  • test/e2e-scenario/live/phase6-messaging-helpers.ts
  • test/e2e-scenario/support-tests/e2e-scenarios-workflow.test.ts
  • test/e2e-scenario/support-tests/openclaw-discord-pairing-helpers.test.ts
  • tools/e2e-scenarios/workflow-boundary.mts
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/e2e-scenario/support-tests/openclaw-discord-pairing-helpers.test.ts
  • .github/workflows/e2e-vitest-scenarios.yaml

Comment thread tools/e2e-scenarios/workflow-boundary.mts
@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ❌ Some jobs failed

Run: 27970034658
Workflow ref: e2e-phase6-openclaw-discord-pairing-linear
Requested scenarios: (default — all supported)
Requested jobs: openclaw-discord-pairing-vitest
Summary: 1 passed, 1 failed, 54 skipped

Job Result
agent-turn-latency-vitest ⏭️ skipped
bedrock-runtime-compatible-anthropic-vitest ⏭️ skipped
brave-search-vitest ⏭️ skipped
channels-add-remove-vitest ⏭️ skipped
cloud-inference-vitest ⏭️ skipped
cloud-onboard-vitest ⏭️ skipped
common-egress-agent-vitest ⏭️ skipped
concurrent-gateway-ports-vitest ⏭️ skipped
credential-migration-vitest ⏭️ skipped
credential-sanitization-vitest ⏭️ skipped
cron-preflight-inference-local-vitest ⏭️ skipped
device-auth-health-vitest ⏭️ skipped
diagnostics-vitest ⏭️ skipped
double-onboard-vitest ⏭️ skipped
full-e2e-vitest ⏭️ skipped
gateway-drift-preflight-vitest ⏭️ skipped
gateway-guard-recovery ⏭️ skipped
gateway-health-honest-vitest ⏭️ skipped
generate-matrix ✅ success
gpu-double-onboard-vitest ⏭️ skipped
gpu-e2e-vitest ⏭️ skipped
hermes-e2e-vitest ⏭️ skipped
hermes-inference-switch-vitest ⏭️ skipped
hermes-root-entrypoint-smoke-vitest ⏭️ skipped
inference-routing-vitest ⏭️ skipped
issue-2478-crash-loop-recovery-vitest ⏭️ skipped
issue-4434-tui-unreachable-inference-vitest ⏭️ skipped
issue-4462-scope-upgrade-approval-vitest ⏭️ skipped
kimi-inference-compat-vitest ⏭️ skipped
launchable-smoke-vitest ⏭️ skipped
live-scenarios ⏭️ skipped
messaging-compatible-endpoint-vitest ⏭️ skipped
messaging-providers-vitest ⏭️ skipped
model-router-provider-routed-inference-vitest ⏭️ skipped
network-policy-vitest ⏭️ skipped
ollama-auth-proxy-vitest ⏭️ skipped
onboard-negative-paths-vitest ⏭️ skipped
onboard-repair-vitest ⏭️ skipped
onboard-resume-vitest ⏭️ skipped
openclaw-discord-pairing-vitest ❌ failure
openclaw-inference-switch-vitest ⏭️ skipped
openclaw-skill-cli-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
sessions-agents-cli-vitest ⏭️ skipped
shields-config-vitest ⏭️ skipped
skill-agent-vitest ⏭️ skipped
snapshot-commands-vitest ⏭️ skipped
state-backup-restore-vitest ⏭️ skipped
telegram-injection-vitest ⏭️ skipped
token-rotation-vitest ⏭️ skipped
upgrade-stale-sandbox-vitest ⏭️ skipped

Failed jobs: openclaw-discord-pairing-vitest. Check run artifacts for logs.

@github-actions

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Results — ✅ All requested jobs passed

Run: 27978943542
Workflow ref: e2e-phase6-openclaw-discord-pairing-linear
Requested scenarios: (default — all supported)
Requested jobs: openclaw-discord-pairing-vitest
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
openclaw-discord-pairing-vitest ✅ success

@jyaunches
jyaunches merged commit 3fe6382 into main Jun 22, 2026
101 checks passed
@jyaunches
jyaunches deleted the e2e-phase6-openclaw-discord-pairing-linear branch June 22, 2026 19:57
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
## 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 integration: discord Discord integration or channel behavior integration: openclaw OpenClaw integration 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 integration: discord Discord integration or channel behavior integration: openclaw OpenClaw integration behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants