Skip to content

feat(messaging): onboard Microsoft Teams channel#5585

Open
sandl99 wants to merge 16 commits into
mainfrom
feat/ms-teams-messaging-onboard
Open

feat(messaging): onboard Microsoft Teams channel#5585
sandl99 wants to merge 16 commits into
mainfrom
feat/ms-teams-messaging-onboard

Conversation

@sandl99

@sandl99 sandl99 commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds experimental Microsoft Teams channel onboarding through NemoClaw's manifest-first messaging architecture for OpenClaw and Hermes. The change wires Teams credentials, policy presets, package installs, config rendering, host webhook forwarding, recovery handling, and tests so Teams participates in onboard, rebuild, and channel lifecycle flows.

Key features

  1. Adding MS Teams channel
  2. Support Port forwarding for messaging channel generic. (support for callback, bi-directional call, e.g. Chat host calls into OpenClaw/Hermes)

Inputs

MSTEAMS_APP_ID: ClientID - Required
MSTEAMS_APP_PASSWORD: ClientSecret - Required
MSTEAMS_TENANT_ID: TenantId - Required
MSTEAMS_ALLOWED_USERS: Optional - OpenClaw allows to pairing after setup.

Related Issue

Part of #5492

Result

image

Changes

  • Add a built-in Microsoft Teams messaging manifest, template resolver, host-forward conflict/status hooks, and manifest registration.
  • Add manifest-declared host-forward planning, validation, persistence, dashboard preservation, and process-recovery support for webhook ports such as MSTEAMS_PORT.
  • Add Teams network policy presets plus OpenClaw and Hermes package/config integration.
  • Treat the Teams user allowlist as optional, pin Hermes Teams PyPI packages, narrow Graph egress to read-only GET, and fail closed on malformed persisted host-forward plans.
  • Update messaging metadata, inventory/status surfaces, and channel commands for Teams setup and lifecycle behavior.
  • Add focused tests for Teams manifests, hooks, policy presets, build applier behavior, host forwarding, rebuild hydration, process recovery, and channel lifecycle handling.
  • Leave user-facing documentation to a follow-up docs-owner change.

PR Review Advisor justification

PR Review Advisor follow-up: #5585 (comment)

  • PRA-1: TEAMS_ALLOWED_USERS is intentionally optional. Microsoft app, tenant, and Bot Framework auth are the primary boundary; allowed_list can be added later via openclaw.
  • PRA-2: The plan-tampering risk is addressed by exact pins plus the trusted built-in manifest recheck. Hash/lockfile verification is broader supply-chain hardening and can be tracked separately.
  • PRA-3: Addressed in 8ab7b004f: Graph is now read-only in both Teams policy sources, and the remaining Bot Connector wildcard is documented and tested as method-scoped because SDK service URLs vary by tenant/region.
  • PRA-4: Deferred for now. Teams IDs come from Microsoft tooling and are validated downstream; adding strict manifest regexes risks rejecting legitimate forms before we have stronger runtime evidence.

No additional mocked tests added for the justified items; real Teams E2E needs an external Microsoft tenant/app.

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)

Verification run:

  • npm run build:cli
  • npx vitest run src/lib/onboard/messaging-host-forward.test.ts src/lib/messaging/channels/manifests.test.ts src/lib/messaging/channels/metadata.test.ts src/lib/messaging/compiler/manifest-compiler.test.ts src/lib/messaging/compiler/workflow-planner.test.ts test/messaging-build-applier.test.ts test/policies-teams.test.ts test/process-recovery.test.ts
  • npx vitest run test/sandbox-connect-inference/auto-pair-approval.test.ts
  • npm run typecheck:cli
  • npm run test-conditionals:scan -- --top 25
  • Normal commit hooks passed, including the broad CLI hook
  • Pushes after hook-verified commits used git push --no-verify as requested

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

Summary by CodeRabbit

Summary of Changes

New Features

  • Added Microsoft Teams as a supported messaging platform for both OpenClaw and Hermes, including Teams channel setup (credentials, allowed users, webhook port, mention mode).
  • Introduced a Teams network policy preset to enable required Microsoft/Teams endpoints.
  • Implemented Teams webhook host-forwarding with conflict detection and overlap/status reporting.

Improvements

  • Preserves messaging host-forward ports during dashboard refresh and restores them during sandbox recovery.
  • Messaging overlap warnings now include the conflicted port.
  • Rebuild and channel enable/disable flows now correctly recompute Teams host-forwarding.
  • Updated prompt behavior to no longer surface manifest placeholders.

@sandl99 sandl99 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

Adds Microsoft Teams as a fully supported messaging channel across NemoClaw: Teams channel manifest with inputs, credentials, render fragments for OpenClaw and Hermes, and lifecycle hooks; host-forward planning engine integrated into the compiler and workflow planner; network policy preset with Microsoft/Azure endpoint allowlists; Hermes uv-pip package installer for Teams Python dependencies; port-conflict detection hooks with overlap status reporting; onboarding orchestration with port preservation and rollback; process recovery for webhook forwards; and comprehensive test coverage across compiler, manifests, policies, and integration scenarios.

Changes

Microsoft Teams Messaging Channel Rollout

Layer / File(s) Summary
Agent manifests, policies, Dockerfile, and documentation
agents/hermes/Dockerfile, agents/hermes/Dockerfile.base, agents/hermes/manifest.yaml, agents/openclaw/manifest.yaml, agents/hermes/policy-additions.yaml, nemoclaw-blueprint/policies/presets/teams.yaml, nemoclaw-blueprint/policies/tiers.yaml, src/lib/messaging/AGENTS.md, src/lib/tunnel/services.ts
Adds teams to supported messaging platforms in Hermes and OpenClaw manifests. Creates Teams network policy preset with Microsoft/Graph/Bot Framework endpoint allowlists. Wires Teams into the open tier. Reorders Hermes Dockerfile agent-install hook before workdir switch. Updates documentation and comments.
Manifest type contracts and host-forward specification
src/lib/messaging/manifest/types.ts, src/lib/messaging/hooks/common/config-prompt.ts
Extends ChannelManifest with hostForward?: ChannelHostForwardSpec. Adds SandboxMessagingHostForwardPlan for compiled plans. Expands ChannelAgentPackageManager to include "hermes-uv-pip". Removes placeholder from ChannelInputPromptSpec and placeholder-based hinting from config-prompt field resolution.
Teams channel manifest and template resolver
src/lib/messaging/channels/teams/manifest.ts, src/lib/messaging/channels/teams/template-resolver.ts, src/lib/messaging/channels/template-resolver.ts, src/lib/messaging/channels/built-ins.ts, src/lib/messaging/channels/slack/manifest.ts
Adds complete teamsManifest with inputs (app ID, secret, tenant ID, allowed users, webhook port, mention mode), credentials, render fragments for OpenClaw JSON and Hermes env/config, runtime visibility, agent packages (plugin + aiohttp), state persistence, rebuild hydration, and lifecycle hooks. Implements resolveTeamsTemplateReference for port/mention/allowed-ID resolution. Registers both in built-in registries.
Teams host-forward conflict and status hooks
src/lib/messaging/channels/teams/hooks/host-forward-port-conflict.ts, src/lib/messaging/channels/teams/hooks/index.ts, src/lib/messaging/hooks/builtins.ts, src/lib/messaging/channels/teams/hooks/host-forward-port-conflict.test.ts
Introduces Teams pre-enable port-conflict hook detecting and formatting port collisions across active sandboxes, status hook reporting overlaps via messaging-overlaps status output, overlap detection and formatting helpers, registration factories, and comprehensive unit tests covering conflict/overlap detection, serialized inputs, and edge cases.
Host-forward planning engine and manifest compiler integration
src/lib/messaging/compiler/engines/host-forward-engine.ts, src/lib/messaging/compiler/manifest-compiler.ts, src/lib/messaging/compiler/workflow-planner.ts, src/lib/messaging/host-forward.ts, src/lib/messaging/index.ts
Adds planHostForward engine deriving SandboxMessagingHostForwardPlan from manifest and inputs with port validation. Integrates into ManifestCompiler.compileChannel and MessagingWorkflowPlanner.refreshDerivedPlanFields with template-reference resolver support. Exports getActiveMessagingHostForward utility.
Persistence hydration and plan validation
src/lib/messaging/persistence.ts, src/lib/messaging/plan-validation.ts, src/lib/messaging/applier/setup-applier.ts, src/lib/messaging/plan-validation.test.ts
Recomputes hostForward during channel persistence normalization and manifest hydration. Adds isHostForward validation guard to parseSandboxMessagingPlan and isSerializableChannelPlan check to assertSandboxMessagingPlan to validate object shape and port ranges (1–65535).
Hermes uv-pip build applier support
src/lib/messaging/applier/build/messaging-build-applier.mts
Adds hermesUvPackages to BuildCommandResult, introduces collection and validation of Hermes Teams Python package specs, deduplication by spec string, and installation via uv pip install --no-cache against the Hermes venv Python.
Messaging host-forward onboarding and recovery
src/lib/onboard/messaging-host-forward.ts, src/lib/onboard/dashboard.ts, src/lib/onboard/agent-dashboard-forward.ts, src/lib/actions/sandbox/process-recovery.ts, src/lib/actions/sandbox/rebuild.ts, src/lib/actions/sandbox/policy-channel.ts
Adds resolveMessagingHostForward and ensureMessagingHostForwardIfConfigured with rollback-on-failure (port deduplication, forward stop, sandbox deletion, exit). Integrates forwarding port preservation and webhook setup into ensureDashboardForward and ensureAgentDashboardForward via preserveForwardPorts. Adds messaging forward recovery to checkAndRecoverSandboxProcesses. Updates planner constructor calls to pass render template resolver.
Overlap port reporting and channel metadata
src/lib/inventory/index.ts, src/lib/status-command-deps.ts, src/lib/messaging-channel-config.test.ts, src/lib/sandbox/channels.test.ts, src/lib/messaging/channels/metadata.test.ts
Extends MessagingOverlap with optional port?: number, propagates port through overlap formatting. Updates channel metadata for Teams: credential env keys, provider suffixes, policy key aliases, managed channel names, config env keys, and DM allowlist support.
Compiler, manifest, policy, and integration test coverage
src/lib/messaging/compiler/manifest-compiler.test.ts, src/lib/messaging/compiler/workflow-planner.test.ts, src/lib/messaging/channels/manifests.test.ts, src/lib/messaging/diagnostics.test.ts, src/lib/messaging/hooks/hook-runner.test.ts, src/lib/onboard/messaging-host-forward.test.ts, src/lib/onboard/agent-dashboard-forward.test.ts, src/lib/onboard/initial-policy.test.ts, test/policies-teams.test.ts, test/policies.test.ts, test/messaging-build-applier.test.ts, test/channels-add-preset.test.ts, test/sandbox-provider-cleanup.test.ts, test/messaging-plan-test-helper.ts, src/lib/agent/defs.test.ts, src/lib/inventory/index.test.ts, src/lib/onboard/messaging-prep.test.ts, src/lib/actions/sandbox/channel-status.test.ts, src/lib/actions/sandbox/policy-channel-conflict.test.ts
Adds comprehensive Teams coverage: manifest compiler tests (OpenClaw and Hermes plans, env safety, defaults, port validation, host-forward cycles), workflow-planner stop/start/rebuild, built-in registry inclusion, policy preset listing and Hermes sandbox integration, messaging build applier pip install validation, channels-add workflow, sandbox prep defaults, and agent defs.

Sequence Diagram(s)

sequenceDiagram
  participant ManifestCompiler
  participant planHostForward
  participant MessagingWorkflowPlanner
  participant refreshDerivedPlanFields

  ManifestCompiler->>planHostForward: compileChannel(manifest, inputs, active, resolver)
  planHostForward-->>ManifestCompiler: SandboxMessagingHostForwardPlan | undefined
  ManifestCompiler-->>MessagingWorkflowPlanner: SandboxMessagingChannelPlan with hostForward

  MessagingWorkflowPlanner->>refreshDerivedPlanFields: stop/start/rebuild plan update
  refreshDerivedPlanFields->>planHostForward: recompute hostForward per channel
  planHostForward-->>refreshDerivedPlanFields: updated SandboxMessagingHostForwardPlan
  refreshDerivedPlanFields-->>MessagingWorkflowPlanner: updated plan with hostForward and runtimeSetup
Loading
sequenceDiagram
  participant ensureDashboardForward
  participant resolveMessagingHostForwardForSandbox
  participant ensureMessagingHostForwardForSandbox
  participant ensureForward
  participant abortMessagingHostForwardFailure

  ensureDashboardForward->>resolveMessagingHostForwardForSandbox: resolve active hostForward
  resolveMessagingHostForwardForSandbox-->>ensureDashboardForward: port to preserve
  ensureDashboardForward->>ensureDashboardForward: add port to preservedPorts
  ensureDashboardForward->>ensureMessagingHostForwardForSandbox: ensure webhook forward
  ensureMessagingHostForwardForSandbox->>ensureForward: start forward(sandboxName, port, label)
  ensureForward-->>ensureMessagingHostForwardForSandbox: true / false
  alt forward fails with rollback enabled
    ensureMessagingHostForwardForSandbox->>abortMessagingHostForwardFailure: stop ports, delete sandbox
    abortMessagingHostForwardFailure-->>abortMessagingHostForwardFailure: exit(1)
  end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related issues

Poem

🐰 Hop hop, Teams is here at last!
A manifest grown, a webhook cast,
hostForward planned, the port secured,
Rollback on failure? That's assured.
From Hermes venv to OpenClaw's door,
This bunny codes Teams forevermore! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.44% 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
Title check ✅ Passed The title 'feat(messaging): onboard Microsoft Teams channel' clearly and specifically describes the main change in the changeset—adding Microsoft Teams channel support to the messaging system.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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 feat/ms-teams-messaging-onboard

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

@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 branch is 96%. Coverage data for the branch is not yet available.

Show a code coverage summary of the most covered files.
File 8ab7b00 +/-
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 branch is 46%. Coverage data for the branch is not yet available.

Show a code coverage summary of the most covered files.
File 8ab7b00 +/-
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 23, 2026 06:17 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: hermes-root-entrypoint-smoke-vitest, hermes-e2e-vitest, channels-add-remove-vitest, channels-stop-start-vitest, network-policy-vitest, rebuild-hermes-vitest
Optional E2E: messaging-providers-vitest, rebuild-openclaw-vitest, tunnel-lifecycle-vitest

Dispatch hint: hermes-root-entrypoint-smoke-vitest,hermes-e2e-vitest,channels-add-remove-vitest,channels-stop-start-vitest,network-policy-vitest,rebuild-hermes-vitest

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • hermes-root-entrypoint-smoke-vitest (medium): Hermes Dockerfile behavior changed to run messaging agent-install hooks as root before dropping to the sandbox user. This job builds/probes the real Hermes image and root entrypoint boundary.
  • hermes-e2e-vitest (high): Hermes manifest, image build hooks, policy additions, and messaging support changed. This runs the live Hermes install/onboard/runtime/inference path through the real CLI and OpenShell boundary.
  • channels-add-remove-vitest (high): The channel add/remove planner, policy-channel action, manifest registry, presets, credential bindings, and rebuild-after-add flow are touched. This is the closest existing live coverage for adding a manifest-backed messaging channel, applying policy, rebuilding, and removing it.
  • channels-stop-start-vitest (high): The stop/start/remove persistence path now constructs planners with the render-template resolver, and process recovery now re-establishes messaging host forwards. This job exercises channel stop/start, provider state, rebuild, and agent config for OpenClaw and Hermes.
  • network-policy-vitest (medium): A new Teams policy preset, open-tier inclusion, and Hermes Teams egress rules alter enforced network boundaries and credential rewrite surfaces. Live network-policy coverage should block merge.
  • rebuild-hermes-vitest (high): Rebuild planning for messaging manifests changed and the Hermes image now applies messaging install hooks differently. This verifies Hermes rebuild preserves state and messaging placeholder/backup hygiene across the real sandbox lifecycle.

Optional E2E

  • messaging-providers-vitest (high): Useful broader confidence for messaging provider placeholder, policy, runtime, and send contracts, though it does not directly cover the new Teams channel.
  • rebuild-openclaw-vitest (high): OpenClaw manifest support and generic rebuild messaging planning changed. This is useful adjunct coverage for OpenClaw rebuild preservation, but channels-add-remove already exercises an OpenClaw rebuild after channel mutation.
  • tunnel-lifecycle-vitest (medium): Teams introduces webhook host-forward/tunnel-like behavior and process recovery now re-establishes messaging forwards. This is adjacent confidence for host-exposed lifecycle behavior.

New E2E recommendations

  • Microsoft Teams messaging channel (high): No existing live E2E appears to add/start/stop/remove the new Teams channel or validate its Bot Framework webhook host-forward, generated agent config, credential placeholders, and port-conflict behavior. Existing messaging E2Es cover Telegram/Discord/Slack/WeChat/WhatsApp only.
    • Suggested test: Add a Teams-focused live E2E that uses fake Bot Framework/Graph endpoints where possible, runs nemoclaw <sandbox> channels add teams, verifies Teams policy preset application, host-forward port allocation and conflict diagnostics, sandbox config placeholders, rebuild preservation, stop/start, and remove cleanup for both OpenClaw and Hermes.
  • messaging host-forward recovery (medium): Process recovery now re-establishes the active messaging webhook forward, but existing live tests do not appear to kill/drop a messaging host-forward and assert nemoclaw recover restores it.
    • Suggested test: Add a focused recovery E2E that creates a sandbox with a webhook-backed channel, stops or corrupts its OpenShell forward, runs the public recover/status flow, and asserts the messaging forward is re-created without disturbing dashboard/API forwards.

Dispatch hint

  • Workflow: .github/workflows/e2e-vitest-scenarios.yaml
  • jobs input: hermes-root-entrypoint-smoke-vitest,hermes-e2e-vitest,channels-add-remove-vitest,channels-stop-start-vitest,network-policy-vitest,rebuild-hermes-vitest

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Recommendation

Required Vitest E2E scenarios: messaging-providers-vitest, channels-add-remove-vitest, channels-stop-start-vitest, rebuild-hermes-vitest, openclaw-slack-pairing-vitest, openclaw-discord-pairing-vitest, ubuntu-repo-docker-post-reboot-recovery
Optional Vitest E2E scenarios: ubuntu-repo-cloud-openclaw, hermes-slack-vitest, tunnel-lifecycle-vitest

Dispatch required Vitest E2E scenarios:

  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=messaging-providers-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=channels-add-remove-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=channels-stop-start-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=rebuild-hermes-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=openclaw-slack-pairing-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=openclaw-discord-pairing-vitest
  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field scenarios=ubuntu-repo-docker-post-reboot-recovery

Workflow run

Full Vitest E2E advisor summary

Vitest E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: medium

Required Vitest E2E scenarios

  • messaging-providers-vitest: Broad messaging provider, placeholder, policy, redaction, and runtime coverage is required for the new Teams manifest/policy plumbing and shared messaging compiler/applier changes.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=messaging-providers-vitest
  • channels-add-remove-vitest: The PR changes channel planning, render template resolver wiring, policy preset application, and add/remove persistence paths; this job exercises channels add, rebuild, policy-list, and remove through the live CLI/OpenShell boundary.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=channels-add-remove-vitest
  • channels-stop-start-vitest: Stop/start planning now depends on the render template resolver and host-forward metadata; this job exercises live OpenClaw and Hermes channel stop/start, rebuild, registry, policy-list, and in-sandbox config contracts.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=channels-stop-start-vitest
  • rebuild-hermes-vitest: Hermes rebuild staging now passes the render template resolver and the Hermes image build path changed; this job covers real Hermes rebuild, base-image rebuild, registry, messaging-placeholder, and backup hygiene boundaries.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=rebuild-hermes-vitest
  • openclaw-slack-pairing-vitest: test/e2e-scenario/live/openclaw-pairing-helpers.ts is shared by the OpenClaw Slack pairing live test; run the wired free-standing job that imports the changed helper.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=openclaw-slack-pairing-vitest
  • openclaw-discord-pairing-vitest: test/e2e-scenario/live/openclaw-pairing-helpers.ts is shared by the OpenClaw Discord pairing live test; run the wired free-standing job that imports the changed helper.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=openclaw-discord-pairing-vitest
  • ubuntu-repo-docker-post-reboot-recovery: src/lib/actions/sandbox/process-recovery.ts now restores messaging host forwards during recovery; this live-supported typed recovery scenario is the targeted registry scenario for the recovery path.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field scenarios=ubuntu-repo-docker-post-reboot-recovery

Optional Vitest E2E scenarios

  • ubuntu-repo-cloud-openclaw: Optional baseline typed OpenClaw scenario for the changed OpenClaw agent manifest, policy tier, onboarding, and messaging-adjacent code paths.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field scenarios=ubuntu-repo-cloud-openclaw
  • hermes-slack-vitest: Adjacent Hermes messaging coverage for policy placeholders and egress; useful because Teams support is added for Hermes but no dedicated Teams live job exists yet.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=hermes-slack-vitest
  • tunnel-lifecycle-vitest: Optional adjacent coverage for the changed tunnel service path and host-forward behavior, especially if reviewers want live validation beyond messaging-specific forwards.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=tunnel-lifecycle-vitest

Relevant changed files

  • agents/hermes/Dockerfile
  • agents/hermes/Dockerfile.base
  • agents/hermes/manifest.yaml
  • agents/hermes/policy-additions.yaml
  • agents/openclaw/manifest.yaml
  • nemoclaw-blueprint/policies/presets/teams.yaml
  • nemoclaw-blueprint/policies/tiers.yaml
  • src/lib/actions/sandbox/policy-channel.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/rebuild.ts
  • src/lib/inventory/index.ts
  • src/lib/messaging/applier/build/messaging-build-applier.mts
  • src/lib/messaging/applier/setup-applier.ts
  • src/lib/messaging/channels/built-ins.ts
  • src/lib/messaging/channels/slack/manifest.ts
  • src/lib/messaging/channels/teams/hooks/host-forward-port-conflict.ts
  • src/lib/messaging/channels/teams/hooks/index.ts
  • src/lib/messaging/channels/teams/manifest.ts
  • src/lib/messaging/channels/teams/template-resolver.ts
  • src/lib/messaging/channels/template-resolver.ts
  • src/lib/messaging/compiler/engines/host-forward-engine.ts
  • src/lib/messaging/compiler/manifest-compiler.ts
  • src/lib/messaging/compiler/workflow-planner.ts
  • src/lib/messaging/hooks/builtins.ts
  • src/lib/messaging/hooks/common/config-prompt.ts
  • src/lib/messaging/host-forward.ts
  • src/lib/messaging/index.ts
  • src/lib/messaging/manifest/types.ts
  • src/lib/messaging/persistence.ts
  • src/lib/messaging/plan-validation.ts
  • src/lib/onboard/agent-dashboard-forward.ts
  • src/lib/onboard/dashboard.ts
  • src/lib/onboard/messaging-host-forward.ts
  • src/lib/status-command-deps.ts
  • src/lib/tunnel/services.ts
  • test/e2e-scenario/live/openclaw-pairing-helpers.ts

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Changes requested

Merge posture: Do not merge yet
Primary next action: Fix PRA-2: Teams channel add/start persists a webhook port but does not start the host forward; then add or justify PRA-T1.
Open items: 1 required · 6 warnings · 0 suggestions · 8 test follow-ups
Top item: Start Teams host forwards during channel lifecycle flows

Action checklist

  • PRA-2 Fix: Teams channel add/start persists a webhook port but does not start the host forward in src/lib/actions/sandbox/policy-channel.ts:946
  • PRA-1 Resolve or justify: Source-of-truth review needed: Teams pre-enable registry read failure
  • PRA-3 Resolve or justify: Teams pre-enable port-conflict guard fails open when registry reads fail in src/lib/actions/sandbox/policy-channel.ts:460
  • PRA-4 Resolve or justify: Teams user allowlist and Microsoft IDs are not enforced or format-validated in src/lib/messaging/channels/teams/manifest.ts:52
  • PRA-5 Resolve or justify: Teams policy adds broad Bot Connector and SharePoint/OneDrive egress in nemoclaw-blueprint/policies/presets/teams.yaml:43
  • PRA-6 Resolve or justify: New root-time Hermes Python packages need supply-chain review evidence in src/lib/messaging/channels/teams/manifest.ts:192
  • PRA-7 Resolve or justify: User-facing Teams setup and security semantics are undocumented
  • 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: Runtime validation
  • PRA-T5 Add or justify test follow-up: Runtime validation
  • PRA-T6 Add or justify test follow-up: Acceptance clause
  • PRA-T7 Add or justify test follow-up: Acceptance clause
  • PRA-T8 Add or justify test follow-up: Acceptance clause

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify architecture Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-2 Required correctness src/lib/actions/sandbox/policy-channel.ts:946 After a successful rebuild for an active plan with `hostForward`, start or re-establish the messaging host forward in the same lifecycle path. Apply the same contract to `channels start teams` and rebuild of an already-active Teams plan, and make failures visible rather than silently relying on recovery.
PRA-3 Resolve/justify security src/lib/actions/sandbox/policy-channel.ts:460 Fail closed for Teams host-forward pre-enable checks when registry entries cannot be read, unless the operator explicitly supplies `--force`. If some non-port pre-enable checks must remain fail-soft, distinguish those from host-forward conflict checks.
PRA-4 Resolve/justify security src/lib/messaging/channels/teams/manifest.ts:52 Either require an explicit allowlist/open-mode choice for Teams, or add manifest-level format validation for app, tenant, and allowed-user IDs and document the intentional no-allowlist semantics. Keep the no-newline checks, but do not rely on downstream validation as the only local guard for security-sensitive identifiers.
PRA-5 Resolve/justify security nemoclaw-blueprint/policies/presets/teams.yaml:43 Add a code comment or policy validation note documenting why the connector wildcard and SharePoint wildcard are the least-privilege shape available for Teams, and keep regression tests that Graph/media remain GET-only and write methods stay confined to the connector host.
PRA-6 Resolve/justify security src/lib/messaging/channels/teams/manifest.ts:192 Add review evidence for the two new pinned PyPI packages, or strengthen the install path with a lock/hash mechanism if that is the expected supply-chain standard for root-time image dependencies. Keep the trusted-manifest tamper recheck.
PRA-7 Resolve/justify docs Add user-facing Teams channel documentation in the current PR, including required Microsoft app setup, credential names, allowed-user/open-mode semantics, webhook forwarding behavior, policy scope, and recovery/start/stop expectations.

🚨 Required before merge

Address these before merging unless a maintainer explicitly overrides the advisor with rationale.

PRA-2 Required — Teams channel add/start persists a webhook port but does not start the host forward

  • Location: src/lib/actions/sandbox/policy-channel.ts:946
  • Category: correctness
  • Problem: The Teams manifest now compiles an active `hostForward`, and onboarding has a helper that can start it, but the channel lifecycle paths only persist/recompute the plan and rebuild. `addSandboxChannel` calls `promptAndRebuild` after `MessagingHostStateApplier.applyPlanToRegistry`, and `startSandboxChannel` only toggles disabled state before rebuild; the only `ensureMessagingHostForwardForSandbox` call site is in `src/lib/onboard/dashboard.ts`, while `rebuild.ts` has no messaging host-forward ensure call.
  • Impact: A sandbox can report Teams as active after `nemoclaw <sandbox> channels add teams` or `channels start teams`, with OpenClaw/Hermes configured to listen on `MSTEAMS_PORT`, but no OpenShell host forward exists for `/api/messages`. Inbound Teams callbacks remain unreachable until a later connect/recover path happens to repair the forward.
  • Required action: After a successful rebuild for an active plan with `hostForward`, start or re-establish the messaging host forward in the same lifecycle path. Apply the same contract to `channels start teams` and rebuild of an already-active Teams plan, and make failures visible rather than silently relying on recovery.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Read-only check: `grep -R "ensureMessagingHostForwardForSandbox" src/lib` shows only the onboard dashboard call site; then inspect `src/lib/actions/sandbox/policy-channel.ts` around the add/start paths and `src/lib/actions/sandbox/rebuild.ts` for the absence of a post-rebuild host-forward ensure.
  • Missing regression test: Add a behavioral test named `channels add teams starts MSTEAMS_PORT host forward after rebuild-now completes`, plus `channels start teams re-establishes MSTEAMS_PORT forward`, asserting `openshell forward start --background <port> <sandbox>` is invoked for the active Teams hostForward.
  • Done when: The required change is committed and verification passes: Read-only check: `grep -R "ensureMessagingHostForwardForSandbox" src/lib` shows only the onboard dashboard call site; then inspect `src/lib/actions/sandbox/policy-channel.ts` around the add/start paths and `src/lib/actions/sandbox/rebuild.ts` for the absence of a post-rebuild host-forward ensure.
  • Evidence: `policy-channel.ts` persists the add plan before `promptAndRebuild`; `sandboxChannelsSetEnabled` persists disabled=false and prompts rebuild; `src/lib/onboard/dashboard.ts` is the only changed production call site for `ensureMessagingHostForwardForSandbox`.
Review findings by urgency: 1 required fix, 6 items to resolve/justify, 0 in-scope improvements

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Source-of-truth review needed: Teams pre-enable registry read failure

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: No Teams-specific regression was found that proves registry read failures abort unless `--force`.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: `checkMessagingPreEnableHooks` catches registry errors, logs a warning, and returns true before running Teams conflict hooks.

PRA-3 Resolve/justify — Teams pre-enable port-conflict guard fails open when registry reads fail

  • Location: src/lib/actions/sandbox/policy-channel.ts:460
  • Category: security
  • Problem: `checkMessagingPreEnableHooks` catches `registry.listSandboxes()` errors, logs a warning, and returns true. For Teams, the pre-enable hook is the guard that prevents two active sandboxes from sharing the same local webhook forward port before provider/policy/registry mutation.
  • Impact: If the registry is unreadable or malformed, a Teams add can proceed even though NemoClaw cannot verify that the requested `MSTEAMS_PORT` is unique. That weakens the local port ownership invariant and can leave one sandbox stealing or masking another sandbox's Teams webhook.
  • Recommended action: Fail closed for Teams host-forward pre-enable checks when registry entries cannot be read, unless the operator explicitly supplies `--force`. If some non-port pre-enable checks must remain fail-soft, distinguish those from host-forward conflict checks.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read-only check: inspect `src/lib/actions/sandbox/policy-channel.ts` lines 458-464 and `src/lib/messaging/channels/teams/manifest.ts` lines 236-242 to see the registry-dependent Teams pre-enable hook.
  • Missing regression test: Add `teams pre-enable conflict check aborts when registry entries cannot be read unless --force is supplied`, asserting non-interactive add exits before provider, policy, or plan registry mutation.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read-only check: inspect `src/lib/actions/sandbox/policy-channel.ts` lines 458-464 and `src/lib/messaging/channels/teams/manifest.ts` lines 236-242 to see the registry-dependent Teams pre-enable hook.
  • Evidence: The code comment says registry read failures stay fail-soft and the catch block returns true; the Teams pre-enable hook requires `registryEntries` to detect host-forward port conflicts.

PRA-4 Resolve/justify — Teams user allowlist and Microsoft IDs are not enforced or format-validated

  • Location: src/lib/messaging/channels/teams/manifest.ts:52
  • Category: security
  • Problem: `TEAMS_ALLOWED_USERS` is optional and the manifest does not declare `formatPattern` validation for the app ID, tenant ID, or user IDs. The compiler test explicitly proves Teams stays active with no allowlist and renders no `dmPolicy` or `allowFrom` fields.
  • Impact: A Teams bot webhook can be enabled with no explicit user allowlist and with malformed Microsoft identifiers. If the downstream agent treats missing allowlist as open access or accepts malformed IDs leniently, the public Teams webhook may be broader than the operator intended.
  • Recommended action: Either require an explicit allowlist/open-mode choice for Teams, or add manifest-level format validation for app, tenant, and allowed-user IDs and document the intentional no-allowlist semantics. Keep the no-newline checks, but do not rely on downstream validation as the only local guard for security-sensitive identifiers.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read-only check: inspect `src/lib/messaging/channels/teams/manifest.ts` for `allowedUsers.required: false` and missing `formatPattern`, then inspect `src/lib/messaging/compiler/manifest-compiler.test.ts` for `keeps Microsoft Teams active when no explicit user allowlist is provided`.
  • Missing regression test: Add `teams enrollment rejects malformed app tenant and allowed-user identifiers` if validating locally, or `teams enrollment requires explicit open access acknowledgement when TEAMS_ALLOWED_USERS is empty` if no-allowlist remains supported.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read-only check: inspect `src/lib/messaging/channels/teams/manifest.ts` for `allowedUsers.required: false` and missing `formatPattern`, then inspect `src/lib/messaging/compiler/manifest-compiler.test.ts` for `keeps Microsoft Teams active when no explicit user allowlist is provided`.
  • Evidence: The Teams manifest marks `allowedUsers` required false; `resolveTeamsTemplateReference` returns no `dmPolicy` when the list is empty; existing tests assert the channel remains active without an allowlist.

PRA-5 Resolve/justify — Teams policy adds broad Bot Connector and SharePoint/OneDrive egress

  • Location: nemoclaw-blueprint/policies/presets/teams.yaml:43
  • Category: security
  • Problem: The Teams preset allows `GET`, `POST`, `PUT`, and `DELETE` to `smba.trafficmanager.net/**`, and allows GET to wildcard `*.sharepoint.com` plus `1drv.ms`. The Graph and media hosts are read-only, which is good, but the connector host remains path-wildcarded and SharePoint is tenant-wildcarded.
  • Impact: This expands sandbox egress to broad Microsoft surfaces. If a sandboxed agent or dependency is compromised, the policy permits broad connector writes/deletes on the Bot Framework connector host and broad read access to SharePoint/OneDrive URLs reachable with available credentials or public links.
  • Recommended action: Add a code comment or policy validation note documenting why the connector wildcard and SharePoint wildcard are the least-privilege shape available for Teams, and keep regression tests that Graph/media remain GET-only and write methods stay confined to the connector host.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read-only check: inspect `nemoclaw-blueprint/policies/presets/teams.yaml` and `agents/hermes/policy-additions.yaml` for `smba.trafficmanager.net` and `*.sharepoint.com`; inspect `test/policies-teams.test.ts` for method assertions.
  • Missing regression test: Add `teams policy denies non-GET Graph and media methods while permitting connector write methods only on smba.trafficmanager.net`, covering both shared and Hermes policy sources.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read-only check: inspect `nemoclaw-blueprint/policies/presets/teams.yaml` and `agents/hermes/policy-additions.yaml` for `smba.trafficmanager.net` and `*.sharepoint.com`; inspect `test/policies-teams.test.ts` for method assertions.
  • Evidence: `test/policies-teams.test.ts` asserts Graph is GET-only and `smba.trafficmanager.net` allows GET/POST/PUT/DELETE on `/**`; both Teams policy sources include wildcard SharePoint GET.

PRA-6 Resolve/justify — New root-time Hermes Python packages need supply-chain review evidence

  • Location: src/lib/messaging/channels/teams/manifest.ts:192
  • Category: security
  • Problem: The PR adds Hermes `agent-install` package installs for `microsoft-teams-apps==2.0.13.4` and `aiohttp==3.14.1`. The build applier correctly exact-pins specs and rechecks serialized plans against trusted built-in manifests, but the repository diff does not include advisory/CVE evidence or hash/lock verification for these new root-time installs.
  • Impact: Docker builds will install new third-party Python packages into `/opt/hermes/.venv` as root. Exact pins reduce drift, but a vulnerable or compromised package version would become part of the sandbox image.
  • Recommended action: Add review evidence for the two new pinned PyPI packages, or strengthen the install path with a lock/hash mechanism if that is the expected supply-chain standard for root-time image dependencies. Keep the trusted-manifest tamper recheck.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read-only check: inspect `src/lib/messaging/channels/teams/manifest.ts` `agentPackages` and `src/lib/messaging/applier/build/messaging-build-applier.mts` `installHermesMessagingUvPackages` / `trustedHermesUvPackageSpecsForPlan`.
  • Missing regression test: Existing `test/messaging-build-applier.test.ts` covers trusted-manifest tamper rejection. Add `hermes teams package install rejects floating or ranged package specs from trusted manifests` if a local manifest-safety test is desired, and attach advisory-review evidence for the pinned versions.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read-only check: inspect `src/lib/messaging/channels/teams/manifest.ts` `agentPackages` and `src/lib/messaging/applier/build/messaging-build-applier.mts` `installHermesMessagingUvPackages` / `trustedHermesUvPackageSpecsForPlan`.
  • Evidence: `test/messaging-build-applier.test.ts` verifies `uv pip install --python /opt/hermes/.venv/bin/python --no-cache -- microsoft-teams-apps==2.0.13.4 aiohttp==3.14.1` and rejects an unexpected package, but no advisory or hash evidence is present in the diff.

PRA-7 Resolve/justify — User-facing Teams setup and security semantics are undocumented

  • Location: not file-specific
  • Category: docs
  • Problem: This PR adds a new user-facing Teams channel, new environment variables, a public webhook port, optional allowlist behavior, package installs, and broad Microsoft egress. The only documentation change is the developer-facing `src/lib/messaging/AGENTS.md`; the PR body states user-facing documentation is deferred.
  • Impact: Operators may not know how to configure the Azure/Bot Framework app, expose `/api/messages`, choose `MSTEAMS_PORT`, understand optional `TEAMS_ALLOWED_USERS`, or assess the policy scope. That raises misconfiguration risk for an internet-facing webhook channel.
  • Recommended action: Add user-facing Teams channel documentation in the current PR, including required Microsoft app setup, credential names, allowed-user/open-mode semantics, webhook forwarding behavior, policy scope, and recovery/start/stop expectations.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read-only check: inspect changed docs files; only `src/lib/messaging/AGENTS.md` is changed and no user-facing docs under `docs/` are updated.
  • Missing regression test: If docs lint/frontmatter checks are available, include the new Teams docs page in those checks; otherwise the regression is the documented setup procedure itself with examples for add/start/rebuild and allowlist-empty behavior.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read-only check: inspect changed docs files; only `src/lib/messaging/AGENTS.md` is changed and no user-facing docs under `docs/` are updated.
  • Evidence: PR changed messaging developer instructions but no user-facing docs; the PR body checkbox for docs is unchecked and says documentation is left to a follow-up.

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

  • None.
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 — channels add teams starts MSTEAMS_PORT host forward after rebuild-now completes. The PR changes Dockerfiles, network policy, sandbox recovery, and OpenShell host-forward lifecycle code. Unit coverage is broad, but the highest-risk gap is the runtime lifecycle behavior that should actually create the Teams webhook forward after add/start/rebuild.
  • PRA-T2 Runtime validation — channels start teams re-establishes MSTEAMS_PORT forward and channels stop teams does not preserve or restart it. The PR changes Dockerfiles, network policy, sandbox recovery, and OpenShell host-forward lifecycle code. Unit coverage is broad, but the highest-risk gap is the runtime lifecycle behavior that should actually create the Teams webhook forward after add/start/rebuild.
  • PRA-T3 Runtime validation — rebuild with an active Teams messaging plan starts the persisted hostForward port after sandbox recreate. The PR changes Dockerfiles, network policy, sandbox recovery, and OpenShell host-forward lifecycle code. Unit coverage is broad, but the highest-risk gap is the runtime lifecycle behavior that should actually create the Teams webhook forward after add/start/rebuild.
  • PRA-T4 Runtime validation — teams pre-enable conflict check aborts when registry entries cannot be read unless --force is supplied. The PR changes Dockerfiles, network policy, sandbox recovery, and OpenShell host-forward lifecycle code. Unit coverage is broad, but the highest-risk gap is the runtime lifecycle behavior that should actually create the Teams webhook forward after add/start/rebuild.
  • PRA-T5 Runtime validation — teams enrollment rejects malformed app tenant and allowed-user identifiers or requires explicit open-access acknowledgement when TEAMS_ALLOWED_USERS is empty. The PR changes Dockerfiles, network policy, sandbox recovery, and OpenShell host-forward lifecycle code. Unit coverage is broad, but the highest-risk gap is the runtime lifecycle behavior that should actually create the Teams webhook forward after add/start/rebuild.
  • PRA-T6 Acceptance clause — Adds experimental Microsoft Teams channel onboarding through NemoClaw's manifest-first messaging architecture for OpenClaw and Hermes. — add test evidence or identify existing coverage. `teamsManifest.supportedAgents` includes OpenClaw and Hermes, agent manifests add `teams`, and compiler/manifest tests cover both agents; lifecycle webhook forwarding after add/start/rebuild is incomplete.
  • PRA-T7 Acceptance clause — 2. Support Port forwarding for messaging channel generic. (support for callback, bi-directional call, e.g. Chat host calls into OpenClaw/Hermes) — add test evidence or identify existing coverage. Generic host-forward planning, validation, persistence, onboard helper, and recovery are added, but add/start/rebuild paths do not start the Teams host forward.
  • PRA-T8 Acceptance clause — Part of feat(messaging): onboard additional experimental messaging channels #5492 — add test evidence or identify existing coverage. The deterministic validation context did not provide linked issue clauses or comments for feat(messaging): onboard additional experimental messaging channels #5492, so no issue acceptance clauses could be mapped.

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.

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

🧹 Nitpick comments (2)
nemoclaw-blueprint/policies/tiers.yaml (1)

47-47: 🧹 Nitpick | 🔵 Trivial

Run network-policy-e2e for the Open-tier preset expansion.

Adding teams to the default Open tier broadens policy scope; please run the targeted network-policy job to validate deny-by-default, whitelist behavior, hot-reload, and SSRF filtering with the new preset mix.

As per coding guidelines: changes under nemoclaw-blueprint/policies/** should run network-policy-e2e.

🤖 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 `@nemoclaw-blueprint/policies/tiers.yaml` at line 47, You have modified the
network policies in the tiers.yaml file by adding teams with read-write access
to the Open tier. Per coding guidelines, any changes to
nemoclaw-blueprint/policies/** require running the network-policy-e2e test suite
to validate that the policy expansion maintains deny-by-default behavior,
whitelist functionality, hot-reload capabilities, and SSRF filtering. Run the
network-policy-e2e job to verify these behaviors work correctly with the new
teams access added to the Open tier preset.

Source: Coding guidelines

agents/hermes/policy-additions.yaml (1)

258-340: 🧹 Nitpick | 🔵 Trivial

Run the Hermes E2E set for this channel-policy addition.

This change touches Hermes channel onboarding/egress behavior, so run the Hermes-targeted nightly jobs before merge to catch policy + lifecycle regressions (hermes-e2e, hermes-inference-switch-e2e, hermes-discord-e2e, hermes-slack-e2e, hermes-onboard-security-posture-e2e, rebuild-hermes-e2e, rebuild-hermes-stale-base-e2e).

As per coding guidelines: changes under agents/hermes/** should be validated with the listed Hermes E2E jobs.

🤖 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 `@agents/hermes/policy-additions.yaml` around lines 258 - 340, Before merging
this Teams channel policy addition (which modifies the teams endpoint
configuration with various Microsoft hosts including login.microsoftonline.com,
api.botframework.com, graph.microsoft.com, and others with
request_body_credential_rewrite settings), you must run the Hermes E2E test
suite to validate that the policy changes do not introduce regressions. Execute
all of the following Hermes-targeted E2E test jobs: hermes-e2e,
hermes-inference-switch-e2e, hermes-discord-e2e, hermes-slack-e2e,
hermes-onboard-security-posture-e2e, rebuild-hermes-e2e, and
rebuild-hermes-stale-base-e2e to ensure no policy or lifecycle issues are
introduced by these changes under agents/hermes/policy-additions.yaml.

Source: Coding guidelines

🤖 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 `@docs/_components/StarterPromptButton.tsx`:
- Around line 149-153: The shell code block in StarterPromptButton.tsx uses a
generic `shell` fence instead of a language-specific one and hardcodes
`nemoclaw` commands instead of using the alias-agnostic placeholder. Change the
code fence from `shell` to `bash` to make it copyable, and replace all
occurrences of the `nemoclaw` command with `$$nemoclaw` in both the channels add
teams command and the rebuild command to ensure the example works for both
OpenClaw and Hermes environments.

In `@docs/about/overview.mdx`:
- Line 41: The table row for "Messaging channels" in the overview table contains
multiple sentences combined into a single line, which violates the markdown
guideline of one sentence per line. Locate the Messaging channels table cell and
split the content into separate lines, placing each distinct sentence on its own
line while maintaining the table's markdown structure. The cell currently has at
least two sentences about OpenShell-managed processes and NemoClaw configuration
that should each be on their own lines.

In `@src/lib/messaging/applier/build/messaging-build-applier.mts`:
- Around line 892-893: The regex pattern used to validate package specs does not
adequately prevent leading dashes, allowing malicious options like -r or
--index-url to bypass validation and be interpreted as CLI options by uv pip
install. Fix this by modifying the regex pattern to include a negative lookahead
that explicitly rejects any spec starting with a dash, and add the -- delimiter
before the selectedPackages variable when constructing the uv pip install
command to ensure all following arguments are treated as requirement specs
rather than CLI options.

In `@src/lib/onboard/messaging-host-forward.ts`:
- Around line 35-38: The normalizedPlan assignment currently falls back to the
unparsed plan value when parseSandboxMessagingPlan fails, bypassing parser
validation. Remove the ?? plan fallback from the normalizedPlan assignment so
that when parseSandboxMessagingPlan returns null or undefined, normalizedPlan
becomes null instead of reverting to the original unparsed plan, ensuring
invalid data is not passed to hydrateDerivedSandboxMessagingPlanFields.

In `@test/policies-teams.test.ts`:
- Around line 19-24: The requirePresetContent function has an if statement
checking the null condition that is causing the test-conditionals:scan CI check
to fail. Remove the if statement that tests !content and the throw statement
inside it, then use a non-null assertion operator on the return statement
instead to assert that content is truthy. Keep the expect assertion at the
beginning to maintain the test validation.

---

Nitpick comments:
In `@agents/hermes/policy-additions.yaml`:
- Around line 258-340: Before merging this Teams channel policy addition (which
modifies the teams endpoint configuration with various Microsoft hosts including
login.microsoftonline.com, api.botframework.com, graph.microsoft.com, and others
with request_body_credential_rewrite settings), you must run the Hermes E2E test
suite to validate that the policy changes do not introduce regressions. Execute
all of the following Hermes-targeted E2E test jobs: hermes-e2e,
hermes-inference-switch-e2e, hermes-discord-e2e, hermes-slack-e2e,
hermes-onboard-security-posture-e2e, rebuild-hermes-e2e, and
rebuild-hermes-stale-base-e2e to ensure no policy or lifecycle issues are
introduced by these changes under agents/hermes/policy-additions.yaml.

In `@nemoclaw-blueprint/policies/tiers.yaml`:
- Line 47: You have modified the network policies in the tiers.yaml file by
adding teams with read-write access to the Open tier. Per coding guidelines, any
changes to nemoclaw-blueprint/policies/** require running the network-policy-e2e
test suite to validate that the policy expansion maintains deny-by-default
behavior, whitelist functionality, hot-reload capabilities, and SSRF filtering.
Run the network-policy-e2e job to verify these behaviors work correctly with the
new teams access added to the Open tier preset.
🪄 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: af41e3bd-1aaa-4379-930c-8a19bf19304e

📥 Commits

Reviewing files that changed from the base of the PR and between cf403cf and 9ecbfd4.

📒 Files selected for processing (76)
  • agents/hermes/Dockerfile
  • agents/hermes/Dockerfile.base
  • agents/hermes/manifest.yaml
  • agents/hermes/policy-additions.yaml
  • agents/openclaw/manifest.yaml
  • docs/_components/StarterPromptButton.tsx
  • docs/about/overview.mdx
  • docs/deployment/brev-web-ui.mdx
  • docs/deployment/deploy-to-remote-gpu.mdx
  • docs/get-started/quickstart.mdx
  • docs/manage-sandboxes/lifecycle.mdx
  • docs/manage-sandboxes/messaging-channels.mdx
  • docs/manage-sandboxes/runtime-controls.mdx
  • docs/network-policy/customize-network-policy.mdx
  • docs/network-policy/integration-policy-examples.mdx
  • docs/reference/architecture.mdx
  • docs/reference/commands-nemohermes.mdx
  • docs/reference/commands.mdx
  • docs/reference/network-policies.mdx
  • docs/reference/troubleshooting.mdx
  • docs/security/best-practices.mdx
  • nemoclaw-blueprint/policies/presets/teams.yaml
  • nemoclaw-blueprint/policies/tiers.yaml
  • src/lib/actions/sandbox/channel-status.test.ts
  • src/lib/actions/sandbox/policy-channel-conflict.test.ts
  • src/lib/actions/sandbox/policy-channel.ts
  • src/lib/actions/sandbox/process-recovery.ts
  • src/lib/actions/sandbox/rebuild.ts
  • src/lib/agent/defs.test.ts
  • src/lib/inventory/index.test.ts
  • src/lib/inventory/index.ts
  • src/lib/messaging-channel-config.test.ts
  • src/lib/messaging/AGENTS.md
  • src/lib/messaging/applier/build/messaging-build-applier.mts
  • src/lib/messaging/applier/setup-applier.ts
  • src/lib/messaging/channels/built-ins.ts
  • src/lib/messaging/channels/manifests.test.ts
  • src/lib/messaging/channels/metadata.test.ts
  • src/lib/messaging/channels/slack/manifest.ts
  • src/lib/messaging/channels/teams/hooks/host-forward-port-conflict.test.ts
  • src/lib/messaging/channels/teams/hooks/host-forward-port-conflict.ts
  • src/lib/messaging/channels/teams/hooks/index.ts
  • src/lib/messaging/channels/teams/manifest.ts
  • src/lib/messaging/channels/teams/template-resolver.ts
  • src/lib/messaging/channels/template-resolver.ts
  • src/lib/messaging/compiler/engines/host-forward-engine.ts
  • src/lib/messaging/compiler/manifest-compiler.test.ts
  • src/lib/messaging/compiler/manifest-compiler.ts
  • src/lib/messaging/compiler/workflow-planner.test.ts
  • src/lib/messaging/compiler/workflow-planner.ts
  • src/lib/messaging/diagnostics.test.ts
  • src/lib/messaging/hooks/builtins.ts
  • src/lib/messaging/hooks/common/config-prompt.ts
  • src/lib/messaging/hooks/hook-runner.test.ts
  • src/lib/messaging/host-forward.ts
  • src/lib/messaging/index.ts
  • src/lib/messaging/manifest/types.ts
  • src/lib/messaging/persistence.ts
  • src/lib/messaging/plan-validation.test.ts
  • src/lib/messaging/plan-validation.ts
  • src/lib/onboard/agent-dashboard-forward.test.ts
  • src/lib/onboard/agent-dashboard-forward.ts
  • src/lib/onboard/dashboard.ts
  • src/lib/onboard/initial-policy.test.ts
  • src/lib/onboard/messaging-host-forward.test.ts
  • src/lib/onboard/messaging-host-forward.ts
  • src/lib/onboard/messaging-prep.test.ts
  • src/lib/sandbox/channels.test.ts
  • src/lib/status-command-deps.ts
  • src/lib/tunnel/services.ts
  • test/channels-add-preset.test.ts
  • test/messaging-build-applier.test.ts
  • test/messaging-plan-test-helper.ts
  • test/policies-teams.test.ts
  • test/policies.test.ts
  • test/sandbox-provider-cleanup.test.ts
💤 Files with no reviewable changes (2)
  • src/lib/messaging/channels/slack/manifest.ts
  • src/lib/messaging/hooks/common/config-prompt.ts

Comment thread docs/_components/StarterPromptButton.tsx Outdated
Comment thread docs/about/overview.mdx Outdated
Comment thread src/lib/messaging/applier/build/messaging-build-applier.mts Outdated
Comment thread src/lib/onboard/messaging-host-forward.ts Outdated
Comment thread test/policies-teams.test.ts Outdated
@sandl99 sandl99 added area: messaging Messaging channels, bridges, manifests, or channel lifecycle VRDC Issues and PRs submitted by NVIDIA VRDC test team. labels Jun 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 27931132475
Target ref: feat/ms-teams-messaging-onboard
Requested jobs: messaging-providers-e2e,channels-add-remove-e2e,channels-stop-start-hermes-e2e,network-policy-e2e,hermes-root-entrypoint-smoke-e2e,rebuild-hermes-e2e,channels-stop-start-openclaw-e2e,rebuild-openclaw-e2e,sandbox-survival-e2e,tunnel-lifecycle-e2e
Summary: 10 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
channels-add-remove-e2e ✅ success
channels-stop-start-hermes-e2e ✅ success
channels-stop-start-openclaw-e2e ✅ success
hermes-root-entrypoint-smoke-e2e ✅ success
messaging-providers-e2e ✅ success
network-policy-e2e ✅ success
rebuild-hermes-e2e ✅ success
rebuild-openclaw-e2e ✅ success
sandbox-survival-e2e ✅ success
tunnel-lifecycle-e2e ✅ success

@sandl99 sandl99 added the v0.0.66 Release target label Jun 22, 2026
@sandl99 sandl99 requested review from cv and ericksoa June 22, 2026 07:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@src/lib/actions/sandbox/process-recovery.ts`:
- Around line 268-271: The fallback logic in parseSandboxCommandResult that uses
the nullish coalescing operator (??), executeLocalDockerSandboxCommand pattern
does not distinguish between a genuine parse failure and a case where OpenShell
already executed the command but stdout framing/marker parsing failed. This
causes non-idempotent commands to execute twice. Modify the logic to check
whether the command was actually executed in OpenShell (even if parsing failed)
before falling back to executeLocalDockerSandboxCommand. You may need to return
additional information from parseSandboxCommandResult or check the result object
directly to determine if OpenShell executed the command, and only fall back to
Docker if execution did not occur at all.
🪄 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: 04f358a6-508a-4ff0-a07e-e57eeddc9da4

📥 Commits

Reviewing files that changed from the base of the PR and between 23325a9 and 019bf70.

📒 Files selected for processing (2)
  • src/lib/actions/sandbox/process-recovery.ts
  • test/process-recovery.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/process-recovery.test.ts

@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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

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

Inline comments:
In `@src/lib/actions/sandbox/process-recovery.ts`:
- Around line 268-271: The fallback logic in parseSandboxCommandResult that uses
the nullish coalescing operator (??), executeLocalDockerSandboxCommand pattern
does not distinguish between a genuine parse failure and a case where OpenShell
already executed the command but stdout framing/marker parsing failed. This
causes non-idempotent commands to execute twice. Modify the logic to check
whether the command was actually executed in OpenShell (even if parsing failed)
before falling back to executeLocalDockerSandboxCommand. You may need to return
additional information from parseSandboxCommandResult or check the result object
directly to determine if OpenShell executed the command, and only fall back to
Docker if execution did not occur at all.
🪄 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: 04f358a6-508a-4ff0-a07e-e57eeddc9da4

📥 Commits

Reviewing files that changed from the base of the PR and between 23325a9 and 019bf70.

📒 Files selected for processing (2)
  • src/lib/actions/sandbox/process-recovery.ts
  • test/process-recovery.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/process-recovery.test.ts
🛑 Comments failed to post (1)
src/lib/actions/sandbox/process-recovery.ts (1)

268-271: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Prevent duplicate command execution on parse-only failure.

At Line 268, Docker fallback runs whenever parsing returns null. That null also includes cases where OpenShell already executed the command but stdout framing/marker parsing failed, so the same command can be executed twice (OpenShell + Docker fallback). For non-idempotent commands this can duplicate side effects.

⚙️ Proposed fix
-    return (
-      parseSandboxCommandResult(result) ??
-      executeLocalDockerSandboxCommand(sandboxName, markedCommand, effectiveTimeout)
-    );
+    const parsed = parseSandboxCommandResult(result);
+    if (parsed) return parsed;
+    if (result.error || (result.status ?? 1) !== 0) {
+      return executeLocalDockerSandboxCommand(sandboxName, markedCommand, effectiveTimeout);
+    }
+    return null;
📝 Committable suggestion

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

    const parsed = parseSandboxCommandResult(result);
    if (parsed) return parsed;
    if (result.error || (result.status ?? 1) !== 0) {
      return executeLocalDockerSandboxCommand(sandboxName, markedCommand, effectiveTimeout);
    }
    return null;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/actions/sandbox/process-recovery.ts` around lines 268 - 271, The
fallback logic in parseSandboxCommandResult that uses the nullish coalescing
operator (??), executeLocalDockerSandboxCommand pattern does not distinguish
between a genuine parse failure and a case where OpenShell already executed the
command but stdout framing/marker parsing failed. This causes non-idempotent
commands to execute twice. Modify the logic to check whether the command was
actually executed in OpenShell (even if parsing failed) before falling back to
executeLocalDockerSandboxCommand. You may need to return additional information
from parseSandboxCommandResult or check the result object directly to determine
if OpenShell executed the command, and only fall back to Docker if execution did
not occur at all.

@cv cv added v0.0.67 Release target and removed v0.0.66 Release target labels Jun 23, 2026
sandl99 added 3 commits June 23, 2026 10:12
…ng-onboard

# Conflicts:
#	src/lib/actions/sandbox/process-recovery.ts
#	src/lib/onboard/agent-dashboard-forward.ts
@NVIDIA NVIDIA deleted a comment from github-actions Bot Jun 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28003939444
Target ref: feat/ms-teams-messaging-onboard
Requested jobs: messaging-providers-e2e,channels-add-remove-e2e,channels-stop-start-hermes-e2e,network-policy-e2e,hermes-root-entrypoint-smoke-e2e,rebuild-hermes-e2e,channels-stop-start-openclaw-e2e,rebuild-openclaw-e2e,sandbox-survival-e2e,tunnel-lifecycle-e2e
Summary: 10 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
channels-add-remove-e2e ✅ success
channels-stop-start-hermes-e2e ✅ success
channels-stop-start-openclaw-e2e ✅ success
hermes-root-entrypoint-smoke-e2e ✅ success
messaging-providers-e2e ✅ success
network-policy-e2e ✅ success
rebuild-hermes-e2e ✅ success
rebuild-openclaw-e2e ✅ success
sandbox-survival-e2e ✅ success
tunnel-lifecycle-e2e ✅ success

@jyaunches jyaunches added v0.0.68 Release target and removed v0.0.67 Release target labels Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: messaging Messaging channels, bridges, manifests, or channel lifecycle v0.0.68 Release target VRDC Issues and PRs submitted by NVIDIA VRDC test team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants