Skip to content

feat(messaging): add workflow planner#4076

Merged
sandl99 merged 2 commits into
u/sdang/messaging-manifest-compiler-3994from
u/sdang/messaging-workflow-planner-3995
May 25, 2026
Merged

feat(messaging): add workflow planner#4076
sandl99 merged 2 commits into
u/sdang/messaging-manifest-compiler-3994from
u/sdang/messaging-workflow-planner-3995

Conversation

@sandl99
Copy link
Copy Markdown
Contributor

@sandl99 sandl99 commented May 22, 2026

Summary

Adds the phase-1 messaging workflow planner for onboard, channel add/remove/start/stop, and rebuild flows. The planner computes configured, active, and disabled channel state before delegating to the manifest compiler, keeping #3995 architecture-only and out of production CLI paths.

Related Issue

Fixes #3995

Changes

  • Add MessagingWorkflowPlanner with pure planOnboard, planAddChannel, planRemoveChannel, planStartChannel, planStopChannel, and planRebuild methods.
  • Preserve stopped-but-configured channels, remove channels from configured and disabled state on remove, and carry registry/session snapshots through rebuild planning.
  • Refine MessagingCompilerWorkflow to the planner workflows and restrict enrollment hooks to selected onboard/add-channel plans.
  • Add workflow planner tests for lifecycle state transitions, deterministic unsupported-channel reporting, rebuild preservation, secret-free serialization, and avoiding re-enrollment of existing configured channels.

Type of Change

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

Verification

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

Additional verification performed:

  • npm test -- --project cli src/lib/messaging passes.
  • npm run typecheck:cli passes.
  • npm run lint -- src/lib/messaging passes with the existing unrelated warning in src/lib/onboard/child-exit-tracker.test.ts.
  • npm run source-shape:check passes.
  • git diff --check passes.
  • Commit and push hooks were bypassed because the full hook path is currently blocked by unrelated CLI doctor/debug/snapshot failures on this stack.

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

Signed-off-by: San Dang <sdang@nvidia.com>
@sandl99 sandl99 self-assigned this May 22, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c0c401cc-ced4-4d33-bb66-5ad18385d12e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch u/sdang/messaging-workflow-planner-3995

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

E2E Advisor Recommendation

Required E2E: messaging-providers-e2e, channels-add-remove-e2e, channels-stop-start-e2e
Optional E2E: messaging-compatible-endpoint-e2e, token-rotation-e2e, hermes-slack-e2e, telegram-injection-e2e

Dispatch hint: messaging-providers-e2e,channels-add-remove-e2e,channels-stop-start-e2e

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/u/sdang/messaging-manifest-compiler-3994
Head: HEAD
Confidence: high

Required E2E

  • messaging-providers-e2e (high): Validates the end-to-end messaging provider/placeholder/no-secret-leak chain for Telegram, Discord, Slack, and WhatsApp. This is required because the PR changes credential binding/render planning and adds OpenShell provider application logic.
  • channels-add-remove-e2e (high): Covers channel add/remove lifecycle, provider detach/attach, rebuild survival, and auto-application/unapplication of messaging policy presets. This is required because the PR introduces workflow planning for add/remove and changes policy/render side effects for active channels.
  • channels-stop-start-e2e (high): Exercises OpenClaw and Hermes channel stop/start/remove lifecycle across Telegram, Discord, WeChat, Slack, and WhatsApp. This is required because the PR changes workflow planning, disabled/configured state handling, agent-scoped hooks, and WeChat post-install setup behavior.

Optional E2E

  • messaging-compatible-endpoint-e2e (medium): Provides additional confidence that Telegram messaging configuration still coexists with inference.local and OpenAI-compatible endpoint routing after render-plan/template-reference changes.
  • token-rotation-e2e (high): Useful adjacent coverage for provider update/reuse semantics and no cross-talk when messaging credentials change, but the required provider and channel lifecycle jobs cover the primary runtime risks for this PR.
  • hermes-slack-e2e (medium): Optional focused Hermes messaging render/provider check. The PR touches generic Hermes env/config render planning, but channels-stop-start-e2e already includes Hermes lifecycle coverage.
  • telegram-injection-e2e (medium): Optional security regression for Telegram bridge message handling. The PR changes Telegram manifest hooks and render planning rather than the bridge injection path, so this is useful but not merge-blocking.

New E2E recommendations

  • WeChat OpenClaw post-install applier (high): Existing E2E coverage exercises WeChat lifecycle broadly, but there is no clearly named focused E2E that asserts the new serializable applier writes openclaw-weixin plugin installs/load paths, account files, permissions, and channel account config into a real OpenClaw sandbox.
    • Suggested test: Add a focused WeChat OpenClaw messaging setup E2E that onboards/adds WeChat with fake hook outputs, runs the setup applier, then validates /sandbox/.openclaw/openclaw.json plus openclaw-weixin account files and secret placeholders.
  • Telegram reachability-check hook (medium): Telegram now declares an aborting reachability-check hook. Existing E2E jobs use fake tokens and often skip live reachability; there is no focused E2E proving successful and failed reachability-check behavior is surfaced safely without leaking bot tokens.
    • Suggested test: Add a hermetic Telegram reachability E2E using a fake Telegram API endpoint to validate getMe success, abort-on-failure, skip controls, and token redaction in logs.
  • Serializable messaging plan handoff (medium): The new applier serializes plans through NEMOCLAW_MESSAGING_PLAN_B64 and applies credentials, policy, hooks, and config from that plan. Current E2E jobs validate final behavior but do not explicitly assert the env handoff/dry-run shadow plan contract.
    • Suggested test: Add an E2E or scenario validation that captures the compiled messaging plan, round-trips it through the applier env variable, and verifies credentials/policy/config are applied from the serialized plan without raw secrets.

Dispatch hint

  • Workflow: nightly-e2e.yaml
  • jobs input: messaging-providers-e2e,channels-add-remove-e2e,channels-stop-start-e2e

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

PR Review Advisor

Findings: 1 needs attention, 3 worth checking, 0 nice ideas
Since last review: 2 prior items resolved, 1 still applies, 3 new items found

Review findings

🛠️ Needs attention

  • Constrain applier file targets before sandbox writes (src/lib/messaging/applier/setup-applier.ts:599): The new setup applier resolves hook build-file paths by returning any absolute path unchanged and by concatenating other hook-controlled paths under agent directories without normalizing or rejecting traversal segments. Because these paths come from serializable plans and hook outputs, a tampered plan or buggy hook can write outside the intended messaging config roots inside the sandbox, for example to arbitrary absolute paths or via `../` traversal. That is a high-risk boundary for blueprint/config tampering and least-privilege bypass.
    • Recommendation: Normalize paths with a POSIX path resolver, reject absolute paths unless they are explicitly allowlisted, reject `..` traversal and suspicious modes, and enforce that all render/build-file writes stay under the expected agent-owned roots such as `/sandbox/.openclaw` or `/sandbox/.hermes`. Add negative tests for absolute paths and traversal attempts.
    • Evidence: `resolveHookBuildFileTarget` returns `path` directly when `path.startsWith("/")`; relative paths are interpolated as `/sandbox/.openclaw/${path}` or `/sandbox/.hermes/${path}` without normalization; `writeSandboxFile` then writes the resulting target through `sandbox exec`.

🔎 Worth checking

  • Add negative runtime-boundary tests for malformed applier plans (src/lib/messaging/applier/setup-applier.test.ts:1): The new tests cover happy-path credential upsert, config rendering, hook output writes, redaction, and policy application, but they do not exercise malicious or malformed serializable-boundary inputs such as absolute file targets, `..` path traversal, invalid chmod modes, unexpected provider names, or tampered policy presets.
    • Recommendation: Add focused unit tests around `decodePlan`/applier entry points that prove malformed plan and hook-output fields are rejected before any OpenShell runner call. Keep runtime/integration validation for the sandbox-facing behavior separate from external E2E status reporting.
    • Evidence: Trusted test-depth analysis marked runtime validation recommended for the new applier/runtime paths; current visible tests assert positive file writes and provider operations but no path/provider/policy rejection cases.
  • New applier boundary concentrates several high-risk responsibilities in one module (src/lib/messaging/applier/setup-applier.ts:37): `MessagingSetupApplier` is introduced as a 743-line module that handles plan encoding/decoding, hook request construction, credential provider creation/update, policy application, config parsing/merging, hook build-file outputs, target resolution, and sandbox file writes. This makes the new trusted-code boundary harder to audit and increases the chance that validation gaps are missed.
    • Recommendation: Split the applier into smaller units such as plan validation/codec, credential provider applier, policy applier, render merger, hook-output validator, and sandbox file writer. Put the strict validation layer before any runner invocation.
    • Evidence: Deterministic monolith analysis reports `src/lib/messaging/applier/setup-applier.ts` as a new 743-line file, and the diff shows multiple security-sensitive operations in that single class/module.
  • Stacked messaging work still overlaps active manifest/enrollment PRs: The changed files still overlap active stacked work for the manifest compiler and channel enrollment manifests. The files themselves exist in this checkout, but the stack increases drift risk if the base messaging compiler/enrollment branches change before or during landing.
    • Recommendation: Before relying on this diff as the final integration state, re-check it against the landed base of the manifest compiler/enrollment stack and resolve any duplicated or contradictory changes in the overlapping files.
    • Evidence: Trusted drift evidence reports open overlaps with PR feat(messaging): add manifest compiler #4069 across all 22 changed files and PR feat(messaging): rebuild new manifest-style messaging architecture #4050 across channel manifest/enrollment files; recent history shows these files were introduced or modified by the messaging manifest compiler/enrollment series.

🌱 Nice ideas

  • None.
Since last review details

Current findings:

  • Constrain applier file targets before sandbox writes (src/lib/messaging/applier/setup-applier.ts:599): The new setup applier resolves hook build-file paths by returning any absolute path unchanged and by concatenating other hook-controlled paths under agent directories without normalizing or rejecting traversal segments. Because these paths come from serializable plans and hook outputs, a tampered plan or buggy hook can write outside the intended messaging config roots inside the sandbox, for example to arbitrary absolute paths or via `../` traversal. That is a high-risk boundary for blueprint/config tampering and least-privilege bypass.
    • Recommendation: Normalize paths with a POSIX path resolver, reject absolute paths unless they are explicitly allowlisted, reject `..` traversal and suspicious modes, and enforce that all render/build-file writes stay under the expected agent-owned roots such as `/sandbox/.openclaw` or `/sandbox/.hermes`. Add negative tests for absolute paths and traversal attempts.
    • Evidence: `resolveHookBuildFileTarget` returns `path` directly when `path.startsWith("/")`; relative paths are interpolated as `/sandbox/.openclaw/${path}` or `/sandbox/.hermes/${path}` without normalization; `writeSandboxFile` then writes the resulting target through `sandbox exec`.
  • Add negative runtime-boundary tests for malformed applier plans (src/lib/messaging/applier/setup-applier.test.ts:1): The new tests cover happy-path credential upsert, config rendering, hook output writes, redaction, and policy application, but they do not exercise malicious or malformed serializable-boundary inputs such as absolute file targets, `..` path traversal, invalid chmod modes, unexpected provider names, or tampered policy presets.
    • Recommendation: Add focused unit tests around `decodePlan`/applier entry points that prove malformed plan and hook-output fields are rejected before any OpenShell runner call. Keep runtime/integration validation for the sandbox-facing behavior separate from external E2E status reporting.
    • Evidence: Trusted test-depth analysis marked runtime validation recommended for the new applier/runtime paths; current visible tests assert positive file writes and provider operations but no path/provider/policy rejection cases.
  • New applier boundary concentrates several high-risk responsibilities in one module (src/lib/messaging/applier/setup-applier.ts:37): `MessagingSetupApplier` is introduced as a 743-line module that handles plan encoding/decoding, hook request construction, credential provider creation/update, policy application, config parsing/merging, hook build-file outputs, target resolution, and sandbox file writes. This makes the new trusted-code boundary harder to audit and increases the chance that validation gaps are missed.
    • Recommendation: Split the applier into smaller units such as plan validation/codec, credential provider applier, policy applier, render merger, hook-output validator, and sandbox file writer. Put the strict validation layer before any runner invocation.
    • Evidence: Deterministic monolith analysis reports `src/lib/messaging/applier/setup-applier.ts` as a new 743-line file, and the diff shows multiple security-sensitive operations in that single class/module.
  • Stacked messaging work still overlaps active manifest/enrollment PRs: The changed files still overlap active stacked work for the manifest compiler and channel enrollment manifests. The files themselves exist in this checkout, but the stack increases drift risk if the base messaging compiler/enrollment branches change before or during landing.
    • Recommendation: Before relying on this diff as the final integration state, re-check it against the landed base of the manifest compiler/enrollment stack and resolve any duplicated or contradictory changes in the overlapping files.
    • Evidence: Trusted drift evidence reports open overlaps with PR feat(messaging): add manifest compiler #4069 across all 22 changed files and PR feat(messaging): rebuild new manifest-style messaging architecture #4050 across channel manifest/enrollment files; recent history shows these files were introduced or modified by the messaging manifest compiler/enrollment series.

Workflow run details

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

## Summary
Adds the serializable messaging applier boundary for phase 1 of the
manifest-based messaging redesign. The applier consumes
`SandboxMessagingPlan` directly, applies generic OpenShell
credential/config/policy work, and adds compiler support for
manifest-declared reachability hooks without moving production conflict
detection.

## Related Issue
Fixes #3996
Part of #3896

## Changes
- Add `src/lib/messaging/applier/` with env transport, serialization
checks, OpenShell credential provider application, policy application,
agent config rendering, and hook-returned `build-file` application.
- Add Telegram `reachability-check` hook metadata plus fake reachability
hook implementation for phase-1 tests.
- Run reachability hooks during manifest compilation after enrollment
input availability is known while keeping raw secrets out of returned
plans.
- Make WeChat post-install account seeding visible through hook-returned
build files and apply those outputs to OpenClaw account files and
`openclaw.json`.
- Filter hook/build-step planning by agent so OpenClaw-only WeChat work
does not appear in Hermes plans.
- Add focused tests for applier behavior, reachability hooks,
hook-returned file writes, serialization, and secret hygiene.

## Type of Change
- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Verification
- [ ] `npx prek run --all-files` passes
- [ ] `npm test` passes
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed
- [ ] Docs updated for user-facing behavior changes
- [ ] `make docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

Targeted checks run:
- `npm test -- --project cli src/lib/messaging`
- `npm run typecheck:cli`
- `npm run lint -- src/lib/messaging`
- `npm run source-shape:check`
- `git diff --check`

Full pre-commit CLI tests were not marked as passing because an
unrelated host debug-output assertion failed in `test/cli.test.ts:1434`.

---
Signed-off-by: San Dang <sdang@nvidia.com>
@sandl99 sandl99 merged commit c9c545b into u/sdang/messaging-manifest-compiler-3994 May 25, 2026
17 checks passed
@sandl99 sandl99 deleted the u/sdang/messaging-workflow-planner-3995 branch May 25, 2026 07:04
@github-actions
Copy link
Copy Markdown
Contributor

E2E Scenario Advisor Recommendation

Required scenario E2E: None
Optional scenario E2E: None

Workflow run

Full scenario advisor summary

E2E Scenario Advisor

Base: origin/u/sdang/messaging-manifest-compiler-3994
Head: HEAD
Confidence: high

Required scenario E2E

  • None. No scenario workflow, scenario metadata, scenario runtime, or validation-suite files changed.

Optional scenario E2E

  • None.

Relevant changed files

  • None.

@cv cv added the integration: whatsapp WhatsApp integration or channel behavior label May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

integration: whatsapp WhatsApp integration or channel behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants