Skip to content

feat(messaging): telegram channels-status health probe - #6887

Merged
cv merged 24 commits into
mainfrom
feat/telegram-channels-status-health
Jul 15, 2026
Merged

feat(messaging): telegram channels-status health probe#6887
cv merged 24 commits into
mainfrom
feat/telegram-channels-status-health

Conversation

@hunglp6d

@hunglp6d hunglp6d commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a live health probe for the Telegram messaging channel to nemoclaw <sandbox> channels status --channel telegram, mirroring the existing WhatsApp probe: it classifies the channel into a verdict (healthy / idle / unreachable / token_rejected / not_started) by reading the OpenClaw gateway's own log breadcrumbs, so a Telegram bridge that cannot reach Telegram or has a rejected token no longer renders as all-[ok]. The default channels status summary now prints an honest Runtime health: not checked pointer for probe-capable channels instead of a silent all-green, and --channel telegram merges the existing non-secret config comparison with the health signals.

Related Issue

Closes #6888
Addresses the "Telegram configuration state and health diagnostics are misleading" item of the DGX Spark/Station VDR checklist #6743 (Parts of #6743).

Changes

  • New pure evaluator src/lib/sandbox/telegram-diagnostics.ts (verdict + hints, fixture-testable, no I/O) and host-side probe src/lib/actions/sandbox/telegram-probe.ts (tails /tmp/gateway.log + pgrep); the probe never issues its own getMe, so the resolved bot token stays inside the gateway.
  • Generalize the diagnostics deepProbe marker from "in-sandbox-qr" to "in-sandbox-qr" | "log-tail", derived from a new declarative manifest field ChannelManifest.diagnosticsProbe. Current consumer: Telegram only (declares diagnosticsProbe: "log-tail"); a hardcoded channel check is insufficient because Slack/Discord/WeChat also ship bridge-health hooks and must not be mis-routed to the Telegram evaluator. Dispatch uses a LOG_TAIL_EVALUATORS channel→evaluator map, gated to OpenClaw (the only agent with the breadcrumb producer). Protected by messaging/diagnostics.test.ts and the channel-status dispatch/Hermes-fallback tests.
  • Extract shared DiagnosticSeverity/DiagnosticSignal into src/lib/sandbox/diagnostic-signal.ts so the WhatsApp and Telegram report union uses one type (WhatsApp re-exports for existing importers).
  • --channel telegram merges the existing config-value comparison (group policy / mention mode / allowed IDs) with the health signals and exits non-zero when the channel is unhealthy (was previously always exit 0).
  • Recency-aware breadcrumb parsing: the tailed lines are chronological, so the latest evidence wins (a bridge that recovered after a blocked start reports healthy; one blocked again reports unreachable). Recognizes OpenClaw's own Inbound message telegram: / isolated polling ingress started and Network request … failed / UND_ERR_SOCKET lines, since the preload does not reliably emit its positive breadcrumbs.
  • Hermes Telegram sandboxes fall back to the basic config report (no OpenClaw breadcrumb producer exists for Hermes).
  • Docs: docs/reference/commands.mdx channels status section documents the Telegram probe, verdicts, exit code, and summary pointer.

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)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification:
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification:
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — command/result or justification:
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result:
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Hung Le hple@nvidia.com

Summary by CodeRabbit

  • New Features

    • Added a Telegram “log-tail” runtime health probe driven by gateway-log breadcrumbs, with verdicts such as healthy, idle, unreachable, and token/credential-related states.
    • Expanded channel status output beyond WhatsApp to include Telegram runtime diagnostics combined with configuration/policy signals.
  • Bug Fixes

    • Compact summary view no longer runs live Telegram/WhatsApp runtime probes unless a specific channel is selected.
    • Detailed probe mode now exits non-zero when the verdict is not healthy/unknown, while sandbox probing remains restricted to log classifications.
  • Documentation

    • Updated channels status docs to reflect new probing behavior, verdicts, and exit/probe limitations.

@copy-pr-bot

copy-pr-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown

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

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jul 14, 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

Telegram channel status now supports OpenClaw log-tail health probes, structured verdicts, runtime signal reporting, paused-channel handling, and Hermes config-only fallback behavior. Shared status-hook infrastructure, tests, and documentation were updated.

Changes

Telegram health diagnostics

Layer / File(s) Summary
Diagnostic and probe contracts
src/lib/messaging/channels/channel-health.ts, src/lib/messaging/manifest/types.ts, src/lib/messaging/diagnostics.ts
Adds shared channel-health report types and manifest metadata for log-tail probing.
Telegram breadcrumb evaluation
src/lib/messaging/channels/telegram/hooks/status-health-eval.ts, src/lib/messaging/channels/telegram/hooks/status-health-eval.test.ts
Parses Telegram gateway breadcrumbs and derives verdicts, signals, hints, and precedence behavior.
Sandbox probe and status integration
src/lib/messaging/channels/telegram/hooks/*, src/lib/messaging/hooks/*, src/lib/actions/sandbox/channel-status.ts, src/lib/status-command-deps.ts, src/lib/messaging/channels/telegram/manifest.ts
Registers and runs the Telegram status hook, evaluates bounded gateway-log/process output, merges health with configuration signals, and preserves config-only fallbacks.
Status behavior validation
src/lib/actions/sandbox/*test.ts, src/lib/messaging/*test.ts, docs/reference/commands.mdx
Updates tests and documentation for detailed probes, summary behavior, paused channels, verdict propagation, hook registration, and probe output constraints.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant ChannelStatus
  participant StatusRunner
  participant TelegramHook
  participant Sandbox
  participant Evaluator
  CLI->>ChannelStatus: request detailed Telegram status
  ChannelStatus->>StatusRunner: run status hooks
  StatusRunner->>TelegramHook: pass probe inputs
  TelegramHook->>Sandbox: inspect gateway log and processes
  Sandbox-->>TelegramHook: bounded probe markers and breadcrumbs
  TelegramHook->>Evaluator: evaluate Telegram evidence
  Evaluator-->>ChannelStatus: health report and configuration signals
  ChannelStatus-->>CLI: render verdict
Loading

Suggested labels: area: sandbox

Suggested reviewers: sandl99, cv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.24% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a Telegram channels-status health probe.
Linked Issues check ✅ Passed The changes add a Telegram live health probe, log-breadcrumb verdicts, summary-view fallback, and exit handling, matching #6888's requirements.
Out of Scope Changes check ✅ Passed The added refactors, helpers, and tests all support the Telegram status-health probe and related status-command behavior.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/telegram-channels-status-health

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

@hunglp6d hunglp6d changed the title Feat/telegram channels status health feat(messaging): telegram channels-status health probe Jul 14, 2026
@github-code-quality

github-code-quality Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage remains at 96%, unchanged from the main branch.

TypeScript / code-coverage/cli

The overall coverage in the feat/telegram-channe... branch is 80%. The coverage in the main branch is 79%.

Show a code coverage summary of the most impacted files.
File main 55fdc3f feat/telegram-channe... 5d9b048 +/-
src/lib/core/pr...mpt-activity.ts 92% 67% -25%
src/lib/status-command-deps.ts 57% 47% -10%
src/lib/securit...ntial-filter.ts 98% 99% +1%
src/lib/state/m...-acquisition.ts 89% 90% +1%
src/lib/messagi...reachability.ts 86% 88% +2%
src/lib/actions...test-helpers.ts 62% 65% +3%
src/lib/messagi...-health-eval.ts 0% 92% +92%
src/lib/messagi...tatus-runner.ts 0% 97% +97%
src/lib/messagi...tatus-health.ts 0% 100% +100%
src/lib/messagi...annel-health.ts 0% 100% +100%

Updated July 15, 2026 10:06 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 Jul 14, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Informational

Advisor assessment: Informational / high confidence
Next action: Review the warnings below.
Findings: 0 blockers · 1 warning · 0 suggestions
Status: Canonical ledger: 0 blocker(s), 1 warning(s), 0 suggestion(s).

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 1 warning · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings differ; normalized E2E selections differ; Nemotron reported the same number of blockers, 1 fewer warning, the same number of suggestions.

Nemotron output stays in workflow artifacts and does not change the assessment above.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: channels-add-remove, channels-stop-start, onboard-repair, onboard-resume

2 optional E2E recommendations
  • diagnostics
  • network-policy
1 warning · 0 suggestions

Warnings

Warnings do not block.

PRA-1 Warning — Cover JSON exit status for unhealthy Telegram detail reports

  • Location: src/commands/sandbox/channels/status.ts:39
  • Category: tests
  • Problem: The new Telegram health probe is documented to make JSON detail status nonzero when its verdict is unhealthy, but the added end-to-end exit assertion exercises only text-mode `showSandboxChannelStatus`. The Oclif wrapper takes a separate JSON path and is solely responsible for setting `process.exitCode` from the returned report.
  • Impact: A regression in the wrapper's JSON verdict handling could leave automation treating an `unreachable`, `token_rejected`, or `not_started` Telegram channel as successful even though the report is unhealthy.
  • Recommendation: Add a command-layer regression test that makes the status action return a Telegram `report` with verdict `unreachable` for `--channel telegram --json`, then asserts the command sets `process.exitCode` to 1.
  • Verification: Inspect `src/commands/sandbox/channels/status.ts:32-44`: JSON mode returns the action report and independently assigns `process.exitCode`; compare with the existing text-mode exit test in `channel-status-telegram-policy.test.ts`.
  • Test coverage: A `SandboxChannelsStatusCommand` test for `--channel telegram --json` with `{ report: { verdict: "unreachable" } }` that asserts `process.exitCode === 1` (and, optionally, `healthy`/`unknown` remain zero).
  • Evidence: `src/lib/actions/sandbox/channel-status-telegram-policy.test.ts` asserts text-mode `process.exit(1)` for an unreachable Telegram probe. `src/commands/sandbox/channels/status.ts:39-44` contains a distinct JSON-only exit-code branch. `docs/reference/commands.mdx` states detailed Telegram JSON status exits nonzero unless verdict is healthy or unknown.

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

@hunglp6d hunglp6d self-assigned this Jul 14, 2026
@hunglp6d hunglp6d added VRDC Issues and PRs submitted by NVIDIA VRDC test team. area: cli Command line interface, flags, terminal UX, or output area: messaging Messaging channels, bridges, manifests, or channel lifecycle labels Jul 14, 2026
@wscurran wscurran added feature PR adds or expands user-visible functionality integration: telegram Telegram integration or channel behavior labels Jul 14, 2026
@hunglp6d
hunglp6d marked this pull request as ready for review July 14, 2026 21:21

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/lib/actions/sandbox/telegram-probe.test.ts (1)

33-33: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use a behavior-oriented suite title.

buildTelegramProbeInput is an implementation name rather than test behavior.

Suggested change
-describe("buildTelegramProbeInput", () => {
+describe("when collecting Telegram runtime probe evidence", () => {

As per coding guidelines, “Use behavior-oriented test titles.”

🤖 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/telegram-probe.test.ts` at line 33, Rename the test
suite described by the describe block around buildTelegramProbeInput to a
behavior-oriented title that states what the Telegram probe input-building
behavior does, rather than naming the implementation function.

Source: Coding guidelines

src/lib/sandbox/telegram-diagnostics.ts (1)

260-267: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

pickVerdict re-derives config/policy state via signal-label string matching instead of reading input directly.

input.channelEnabledInRegistry and input.presetInRegistry/presetOnGateway are already booleans on TelegramProbeInput; matching against signals by label === "Channel registration" couples pickVerdict to the exact label strings used in configCoverageSignal/policyCoverageSignal, so a future label rename silently breaks verdict classification with no type error.

♻️ Suggested simplification
 function pickVerdict(signals: DiagnosticSignal[], input: TelegramProbeInput): TelegramVerdict {
   if (!input.probeReachable) return "probe_failed";
-  if (signals.some((s) => s.label === "Channel registration" && s.severity === "fail")) {
-    return "config_gap";
-  }
-  if (signals.some((s) => s.label === "Policy coverage" && s.severity === "fail")) {
-    return "policy_gap";
-  }
+  if (!input.channelEnabledInRegistry) return "config_gap";
+  if (!input.presetInRegistry) return "policy_gap";
   ...
🤖 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/sandbox/telegram-diagnostics.ts` around lines 260 - 267, Update
pickVerdict to classify config_gap and policy_gap from TelegramProbeInput’s
boolean fields directly: use channelEnabledInRegistry for configuration status
and the presetInRegistry/presetOnGateway values for policy coverage. Remove the
signal label/severity matching from verdict selection while preserving the
existing probe_failed precedence and remaining verdict behavior.
src/lib/actions/sandbox/telegram-probe.ts (1)

94-100: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the redundant try/catch around deps.getGatewayPresets()

getGatewayPresets() already returns null for gateway failures, so this wrapper only adds another path to reason about. Handle the null case directly unless an injected dependency is expected to throw.

🤖 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/telegram-probe.ts` around lines 94 - 100, Remove the
try/catch surrounding deps.getGatewayPresets in the gateway preset lookup, and
assign presetOnGateway directly from its null-aware result. Preserve null when
getGatewayPresets returns null and check for "telegram" only for non-null preset
lists.

Source: Learnings

🤖 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/channel-status.ts`:
- Around line 542-551: Thread a paused-channel indicator through
buildBasicChannelReport and its paused-channel call site so the Runtime health
signal reflects the actual request context. For paused single-channel detail
requests, avoid saying “not checked in summary view” and do not suggest
rerunning the same --channel command; preserve the existing summary-view message
and hint for non-paused summary reports.

In `@src/lib/sandbox/telegram-diagnostics.ts`:
- Around line 206-213: Update the parser’s startupHttpError handling alongside
providerReady and tokenRejected so it participates in the same latest-evidence
winner block rather than being assigned unconditionally. Ensure later
provider-ready/inbound evidence clears or supersedes an earlier HTTP error,
allowing reachabilitySignal to report the current healthy state; add a
regression test covering stale HTTP 502/503 evidence followed by provider-ready
evidence.

---

Nitpick comments:
In `@src/lib/actions/sandbox/telegram-probe.test.ts`:
- Line 33: Rename the test suite described by the describe block around
buildTelegramProbeInput to a behavior-oriented title that states what the
Telegram probe input-building behavior does, rather than naming the
implementation function.

In `@src/lib/actions/sandbox/telegram-probe.ts`:
- Around line 94-100: Remove the try/catch surrounding deps.getGatewayPresets in
the gateway preset lookup, and assign presetOnGateway directly from its
null-aware result. Preserve null when getGatewayPresets returns null and check
for "telegram" only for non-null preset lists.

In `@src/lib/sandbox/telegram-diagnostics.ts`:
- Around line 260-267: Update pickVerdict to classify config_gap and policy_gap
from TelegramProbeInput’s boolean fields directly: use channelEnabledInRegistry
for configuration status and the presetInRegistry/presetOnGateway values for
policy coverage. Remove the signal label/severity matching from verdict
selection while preserving the existing probe_failed precedence and remaining
verdict behavior.
🪄 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: c1d86ef7-c4b4-4513-91de-a964bdf15a60

📥 Commits

Reviewing files that changed from the base of the PR and between 45b1cb5 and e56b931.

📒 Files selected for processing (16)
  • docs/reference/commands.mdx
  • src/lib/actions/sandbox/channel-status-config-core.test.ts
  • src/lib/actions/sandbox/channel-status-summary.test.ts
  • src/lib/actions/sandbox/channel-status-telegram-policy.test.ts
  • src/lib/actions/sandbox/channel-status.test-helpers.ts
  • src/lib/actions/sandbox/channel-status.ts
  • src/lib/actions/sandbox/telegram-probe.test.ts
  • src/lib/actions/sandbox/telegram-probe.ts
  • src/lib/messaging/channels/telegram/manifest.ts
  • src/lib/messaging/diagnostics.test.ts
  • src/lib/messaging/diagnostics.ts
  • src/lib/messaging/manifest/types.ts
  • src/lib/sandbox/diagnostic-signal.ts
  • src/lib/sandbox/telegram-diagnostics.test.ts
  • src/lib/sandbox/telegram-diagnostics.ts
  • src/lib/sandbox/whatsapp-diagnostics.ts

Comment thread src/lib/actions/sandbox/channel-status.ts
Comment thread src/lib/messaging/channels/telegram/hooks/status-health-eval.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

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/sandbox/telegram-diagnostics.ts (1)

403-424: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Honor a later HTTP failure over earlier failure breadcrumbs.

lastHttpError is included in lastEvidence, but the token/network branches never compare their timestamps to it. A 401 at index 0 followed by an HTTP 502 at index 1 still sets tokenRejected, hiding the latest non-auth reachability failure.

Proposed fix
   if (lastReached !== -1 && lastReached >= lastEvidence) {
     bc.providerReady = true;
+  } else if (lastHttpError === lastEvidence) {
+    bc.startupHttpError = lastHttpErrorCode;
   } else if (
     Math.max(lastTokenRejected, lastCredentialUnresolved) !== -1 &&
     Math.max(lastTokenRejected, lastCredentialUnresolved) >= lastNetworkFail
@@
   } else if (lastBridgeNotStarted !== -1) {
     bc.bridgeNotStarted = true;
-  } else if (lastHttpError !== -1) {
-    bc.startupHttpError = lastHttpErrorCode;
   }

Add a regression case for rejected-token evidence followed by HTTP 502.

🤖 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/sandbox/telegram-diagnostics.ts` around lines 403 - 424, Update the
verdict selection around lastEvidence so a later non-auth HTTP failure takes
precedence over earlier token, credential, or network failure breadcrumbs.
Ensure the token/network branches only set their flags when their evidence is at
least as recent as lastHttpError, while preserving reached and bridge
precedence; add a regression case covering rejected-token evidence followed by
HTTP 502.
🤖 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.

Outside diff comments:
In `@src/lib/sandbox/telegram-diagnostics.ts`:
- Around line 403-424: Update the verdict selection around lastEvidence so a
later non-auth HTTP failure takes precedence over earlier token, credential, or
network failure breadcrumbs. Ensure the token/network branches only set their
flags when their evidence is at least as recent as lastHttpError, while
preserving reached and bridge precedence; add a regression case covering
rejected-token evidence followed by HTTP 502.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4a9f685e-f681-468d-a959-404146f4aa3f

📥 Commits

Reviewing files that changed from the base of the PR and between e56b931 and 3784010.

📒 Files selected for processing (4)
  • src/lib/actions/sandbox/channel-status.test.ts
  • src/lib/actions/sandbox/channel-status.ts
  • src/lib/sandbox/telegram-diagnostics.test.ts
  • src/lib/sandbox/telegram-diagnostics.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/sandbox/telegram-diagnostics.test.ts
  • src/lib/actions/sandbox/channel-status.ts

@sandl99

sandl99 commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

add new hooks type -> channel status health check -> call getMeReachability.
Then Channel status code will run the hooks of telegram health check status

@sandl99 sandl99 removed the v0.0.84 label Jul 15, 2026
@sandl99
sandl99 self-requested a review July 15, 2026 03:35

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/messaging/channels/telegram/hooks/status-health-eval.ts (1)

388-416: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Include HTTP errors in the final evidence winner.

lastHttpError participates in lastEvidence, but the following else if chain never compares it when a prior token, network, or bridge marker exists. For example, a token rejection followed by HTTP 502 still returns tokenRejected, and a bridge timeout followed by HTTP 502 still returns bridgeNotStarted, despite the HTTP error being newer.

Update each failure branch to require its index to be at least lastHttpError, and add regression coverage for a latest 5xx after each prior failure type.

🐛 Suggested precedence fix
+  const lastAuthFailure = Math.max(lastTokenRejected, lastCredentialUnresolved);
   const lastEvidence = Math.max(lastReached, lastCause, lastBridgeNotStarted, lastHttpError);
   if (lastReached !== -1 && lastReached >= lastEvidence) {
     bc.providerReady = true;
   } else if (
-    Math.max(lastTokenRejected, lastCredentialUnresolved) !== -1 &&
-    Math.max(lastTokenRejected, lastCredentialUnresolved) >= lastNetworkFail
+    lastAuthFailure !== -1 &&
+    lastAuthFailure >= Math.max(lastNetworkFail, lastHttpError)
   ) {
     ...
-  } else if (lastNetworkFail !== -1) {
+  } else if (
+    lastNetworkFail !== -1 &&
+    lastNetworkFail >= Math.max(lastBridgeNotStarted, lastHttpError)
+  ) {
     bc.startupFailedNetwork = true;
-  } else if (lastBridgeNotStarted !== -1) {
+  } else if (lastBridgeNotStarted !== -1 && lastBridgeNotStarted >= lastHttpError) {
     bc.bridgeNotStarted = true;
   } else if (lastHttpError !== -1) {
🤖 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/messaging/channels/telegram/hooks/status-health-eval.ts` around lines
388 - 416, Update the failure precedence logic in the status-health evaluation
chain around lastCause and lastEvidence so token/credential, network, and
bridge-not-started branches only apply when their evidence index is at least
lastHttpError; retain the existing reached precedence and ensure the HTTP-error
branch wins when its 5xx evidence is newer. Add regression coverage for a latest
5xx following each prior failure type.
🧹 Nitpick comments (1)
src/lib/messaging/hooks/builtins.ts (1)

26-28: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Doc comment overstates scope of statusHealth wiring.

The comment says this is
"threaded into every channel's phase:"status" health hook"
, but only the Telegram registration (Line 44-47) actually receives withStatusHealthOptions. Discord/Slack/Teams/Wechat registrations don't. Harmless today (Telegram is the only log-tail probe channel) but misleading for the next channel that adds a status-health hook and assumes this is already generic.

✏️ Suggested comment fix
-  // Host capability threaded into every channel's `phase:"status"` health hook,
-  // so a status caller enables live probing without naming a specific channel.
+  // Host capability threaded into channels whose registration opts in via
+  // `withStatusHealthOptions` (currently Telegram's `phase:"status"` health
+  // hook), so a status caller enables live probing without naming a channel.
   readonly statusHealth?: ChannelStatusHealthHookOptions;

Also applies to: 43-48

🤖 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/messaging/hooks/builtins.ts` around lines 26 - 28, Revise the doc
comment above statusHealth to describe its current, non-generic wiring rather
than claiming it reaches every channel’s phase:"status" health hook. Keep the
explanation accurate for the Telegram registration using withStatusHealthOptions
and avoid implying Discord, Slack, Teams, or Wechat receive these options.
🤖 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/messaging/channels/telegram/hooks/status-health.ts`:
- Around line 56-74: Treat the probe as reachable only when both the sandbox
command succeeds and the output contains TG_SHELL_OK: update the reachable
calculation in the status-health probe flow to require exec.status === 0,
preventing partial failed output from producing healthy breadcrumbs. Add a
regression test covering a non-zero exec status with otherwise healthy-looking
stdout and verify it is not reported healthy.

In `@src/lib/messaging/hooks/status-runner.ts`:
- Around line 105-116: Update readChannelHealthOutputs to validate the nested
report’s required ChannelHealthReport fields and value types before casting and
returning it. Reject malformed reports by returning an empty result, while
preserving the existing output kind and messaging-channel-health type checks.

---

Outside diff comments:
In `@src/lib/messaging/channels/telegram/hooks/status-health-eval.ts`:
- Around line 388-416: Update the failure precedence logic in the status-health
evaluation chain around lastCause and lastEvidence so token/credential, network,
and bridge-not-started branches only apply when their evidence index is at least
lastHttpError; retain the existing reached precedence and ensure the HTTP-error
branch wins when its 5xx evidence is newer. Add regression coverage for a latest
5xx following each prior failure type.

---

Nitpick comments:
In `@src/lib/messaging/hooks/builtins.ts`:
- Around line 26-28: Revise the doc comment above statusHealth to describe its
current, non-generic wiring rather than claiming it reaches every channel’s
phase:"status" health hook. Keep the explanation accurate for the Telegram
registration using withStatusHealthOptions and avoid implying Discord, Slack,
Teams, or Wechat receive these options.
🪄 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: c2ada8ba-bd16-4ea2-a5be-faffa7e3536d

📥 Commits

Reviewing files that changed from the base of the PR and between 3784010 and 5defae4.

📒 Files selected for processing (17)
  • docs/reference/commands.mdx
  • src/lib/actions/sandbox/channel-status-telegram-policy.test.ts
  • src/lib/actions/sandbox/channel-status.test-helpers.ts
  • src/lib/actions/sandbox/channel-status.ts
  • src/lib/messaging/channels/channel-health.ts
  • src/lib/messaging/channels/telegram/hooks/get-me-reachability.ts
  • src/lib/messaging/channels/telegram/hooks/index.ts
  • src/lib/messaging/channels/telegram/hooks/status-health-eval.test.ts
  • src/lib/messaging/channels/telegram/hooks/status-health-eval.ts
  • src/lib/messaging/channels/telegram/hooks/status-health.test.ts
  • src/lib/messaging/channels/telegram/hooks/status-health.ts
  • src/lib/messaging/channels/telegram/manifest.ts
  • src/lib/messaging/compiler/manifest-compiler.test.ts
  • src/lib/messaging/hooks/builtins.ts
  • src/lib/messaging/hooks/hook-runner.test.ts
  • src/lib/messaging/hooks/status-runner.ts
  • src/lib/status-command-deps.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/lib/messaging/channels/telegram/manifest.ts
  • docs/reference/commands.mdx
  • src/lib/actions/sandbox/channel-status.test-helpers.ts

Comment thread src/lib/messaging/channels/telegram/hooks/status-health.ts
Comment thread src/lib/messaging/hooks/status-runner.ts
@sandl99 sandl99 added the VDR Linked to VDR finding label Jul 15, 2026
…-health output

Signed-off-by: Hung Le <hple@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/lib/messaging/hooks/status-runner.test.ts (1)

7-14: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Keep the test fixture type-safe.

as unknown as MessagingStatusHookRunResult bypasses compile-time validation of the runner output contract. Type outputs as MessagingStatusHookRunResult["outputs"] and return the object without the double assertion.

As per path instructions, tests should preserve behavioral confidence without broad contract-bypassing mocks.

Proposed fix
 function runResult(
-  outputs: Record<string, { kind: string; value: unknown }>,
+  outputs: MessagingStatusHookRunResult["outputs"],
 ): MessagingStatusHookRunResult {
   return {
     channelId: "telegram",
     hookId: "telegram-status-health",
     outputs,
-  } as unknown as MessagingStatusHookRunResult;
+  };
 }
🤖 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/messaging/hooks/status-runner.test.ts` around lines 7 - 14, Update
the runResult test fixture to type outputs as
MessagingStatusHookRunResult["outputs"], then return the object directly as a
MessagingStatusHookRunResult without the as unknown as assertion. Preserve the
existing fixture values and behavior while allowing TypeScript to validate the
runner output contract.

Source: Path instructions

🤖 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/messaging/hooks/status-runner.test.ts`:
- Around line 27-66: Update the enclosing describe title for
readChannelHealthOutputs to append the linked issue suffix "(`#6888`)" in the
required final format, leaving the child test titles and behavior unchanged.

---

Nitpick comments:
In `@src/lib/messaging/hooks/status-runner.test.ts`:
- Around line 7-14: Update the runResult test fixture to type outputs as
MessagingStatusHookRunResult["outputs"], then return the object directly as a
MessagingStatusHookRunResult without the as unknown as assertion. Preserve the
existing fixture values and behavior while allowing TypeScript to validate the
runner output contract.
🪄 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: 9e77f8d1-61a3-42b1-8d5f-512ea939b158

📥 Commits

Reviewing files that changed from the base of the PR and between 5defae4 and 9ffa3a4.

📒 Files selected for processing (4)
  • src/lib/messaging/channels/telegram/hooks/status-health.test.ts
  • src/lib/messaging/channels/telegram/hooks/status-health.ts
  • src/lib/messaging/hooks/status-runner.test.ts
  • src/lib/messaging/hooks/status-runner.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/lib/messaging/channels/telegram/hooks/status-health.test.ts
  • src/lib/messaging/hooks/status-runner.ts
  • src/lib/messaging/channels/telegram/hooks/status-health.ts

Comment thread src/lib/messaging/hooks/status-runner.test.ts Outdated
@cv cv mentioned this pull request Jul 15, 2026
21 tasks
hunglp6d added 3 commits July 15, 2026 14:00
…itle

Signed-off-by: Hung Le <hple@nvidia.com>
…'t healthy after an outage

Signed-off-by: Hung Le <hple@nvidia.com>
…up causes

Signed-off-by: Hung Le <hple@nvidia.com>
cv added a commit that referenced this pull request Jul 15, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Replace the synthetic required-check identity with a native `E2E / PR
Gate` job in the base-trusted `pull_request_target` workflow. The Checks
API result becomes `E2E / PR Gate Coordination`, so suite-association
ambiguity like the behavior observed on #6887 cannot leave the required
native job unreported while exact-head/base validation and credentialed
E2E authorization remain unchanged.

## Changes

- Add a read-only native `E2E / PR Gate` job that executes from
`github.workflow_sha`, waits for the trusted exact-diff coordination
result, publishes the terminal verdict as its native job result, logs
the validated trusted run link, and keeps the job summary static.
- Rename the controller-created custom check to `E2E / PR Gate
Coordination`; authenticate it by exact external identity and GitHub
Actions app, retain the old name only as a rollout bridge, and keep
maintainer-authorization states pending.
- Classify the observer as trusted E2E controller code and add behavior,
workflow-boundary, watch-trigger, risk-plan, lifecycle, and contributor
documentation coverage.

## Type of Change

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

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Required before merge;
the new job is base-trusted, checks out `github.workflow_sha`, executes
no PR code, and has only `checks: read`, `contents: read`, and
`pull-requests: read`.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — `npx vitest run
test/pr-e2e-required.test.ts test/pr-e2e-gate-workflow.test.ts` (27
passed); `npm run typecheck:cli`; `npm run test:projects:check`
- [x] Applicable broad gate passed — `npm test` (1,510 files passed, 3
skipped; 17,207 tests passed, 40 skipped)
- [ ] Quality Gates section completed with required justifications or
waivers — pending sensitive-path review above
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) — build
passed with two pre-existing hidden Fern warnings
- [ ] 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)

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


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

* **New Features**
* Added a native required **E2E / PR Gate** workflow job that mirrors a
trusted exact-diff E2E coordination verdict.
* Introduced required-gate polling that passes only for the current
base/head and fails closed if revisions change.
* Updated the coordination check display name to **“E2E / PR Gate
Coordination”**.

* **Documentation**
* Refined E2E/PR gate architecture docs, including evidence,
authorization, cancellation, and rollout/migration behavior.

* **Tests**
* Added required-gate end-to-end coverage and expanded workflow/config
and gate lifecycle assertions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

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

Copy link
Copy Markdown
Contributor

E2E Target Results — ✅ All requested tests passed

Run: 29409269763
Workflow ref: feat/telegram-channels-status-health
Requested targets: (default — all supported)
Requested test IDs: channels-add-remove,channels-stop-start,onboard-repair,onboard-resume,diagnostics,messaging-providers
Summary: 6 passed, 0 failed, 0 cancelled, 0 skipped, 0 unknown

Test Result Total wall clock time
channels-add-remove ✅ success 8m 32s
channels-stop-start ✅ success 17m 18s
diagnostics ✅ success 5m 6s
messaging-providers ✅ success 11m 57s
onboard-repair ✅ success 4m 22s
onboard-resume ✅ success 5m 3s

@cv
cv merged commit f79b09a into main Jul 15, 2026
129 checks passed
@cv
cv deleted the feat/telegram-channels-status-health branch July 15, 2026 15:47
cv pushed a commit that referenced this pull request Jul 16, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Adds the canonical `docs/changelog/2026-07-15.mdx` entry with the exact
`## v0.0.84` heading for the release candidate range from `v0.0.83`
through `710d2b36b9eebcb6bca3c2b2f796a1bdb69c3a31`.
Fills two owner-page gaps for model-aware local inference health and
pre-write OpenClaw candidate validation.

## Changes

- Add the complete shared Fern changelog entry for `v0.0.84`, with
literal CLI names and root-absolute OpenClaw and Hermes routes.
- Document that sandbox status and doctor compare the configured Ollama
or vLLM model with provider inventory without issuing a completion.
- Document that host-side OpenClaw `config set` validates the complete
candidate before replacing live config or reaching gateway restart.
- Reconcile the `v0.0.84` release label with the commit range. PR #6773
is already contained in `v0.0.83` and remains documented there; CI,
test-harness, docs-infrastructure, and `.js` to `.mts` migration-only
changes require no additional user guidance.

### Source summary

- [#6882](#6882) ->
`docs/manage-sandboxes/backup-restore.mdx`,
`docs/changelog/2026-07-15.mdx`: Explain that OpenClaw runtime identity
and pairing state are excluded from snapshots and ignored during
restore.
- [#6873](#6873) ->
`docs/inference/set-up-ollama.mdx`, `docs/changelog/2026-07-15.mdx`:
Record the Ollama requested-model environment fallback and interactive
default.
- [#6835](#6835) ->
`docs/changelog/2026-07-15.mdx`: Include the sandbox name in the
documented rebuild resume-recovery behavior.
- [#6886](#6886) ->
`docs/inference/custom-endpoint-security.mdx`,
`docs/inference/set-up-openai-compatible-endpoint.mdx`,
`docs/changelog/2026-07-15.mdx`: Explain the exact-host trusted-private
endpoint opt-in and retained SSRF boundaries.
- [#6887](#6887) ->
`docs/reference/commands.mdx`, `docs/changelog/2026-07-15.mdx`: Document
Telegram channel health verdicts, summary behavior, and exit status.
- [#6863](#6863) ->
`docs/manage-sandboxes/lifecycle.mdx`, `docs/changelog/2026-07-15.mdx`:
Add the missing model-inventory behavior for local status and doctor
checks.
- [#6902](#6902) ->
`docs/manage-sandboxes/runtime-controls.mdx`,
`docs/changelog/2026-07-15.mdx`: Add the missing pre-write OpenClaw
candidate-validation contract.
- [#6916](#6916) ->
`docs/changelog/2026-07-15.mdx`: Preserve the failed-session
fresh-install recovery correction in the release entry.
- [#6934](#6934) ->
`docs/reference/commands.mdx`, `docs/reference/troubleshooting.mdx`,
`docs/security/credential-storage.mdx`, `docs/changelog/2026-07-15.mdx`:
Summarize completed-prompt checkpointing and validated credential reuse
during OpenClaw resume.
- [#6898](#6898) ->
`docs/inference/switch-models.mdx`,
`docs/inference/switch-providers.mdx`,
`docs/reference/troubleshooting.mdx`, `docs/changelog/2026-07-15.mdx`:
Explain Hermes dashboard convergence after in-place inference changes.
- [#6711](#6711) ->
`docs/manage-sandboxes/run-sandboxes.mdx`,
`docs/manage-sandboxes/uninstall-nemoclaw.mdx`,
`docs/reference/architecture.mdx`, `docs/reference/commands.mdx`,
`docs/changelog/2026-07-15.mdx`: Summarize port-scoped host state and
uninstall preservation.
- [#6767](#6767) ->
`docs/inference/configure-model-limits.mdx`,
`docs/inference/set-up-ollama.mdx`,
`docs/reference/troubleshooting.mdx`, `docs/changelog/2026-07-15.mdx`:
Record the Hermes `64000`-token Ollama floor and unchanged OpenClaw
floor.
- [#6862](#6862) ->
`docs/get-started/quickstart.mdx`,
`docs/inference/verify-inference-route.mdx`,
`docs/changelog/2026-07-15.mdx`: Explain retryable not-ready
finalization for unhealthy inference routes.
- [#6766](#6766) ->
`docs/security/tcb-boundary.mdx`, `docs/changelog/2026-07-15.mdx`:
Document definitive stale transition-lock recovery and fail-closed
ambiguous cases.
- [#6948](#6948) ->
`docs/manage-sandboxes/manage-mcp-servers.mdx`,
`docs/changelog/2026-07-15.mdx`: Include Hermes MCP apply-state race
recovery in the release entry without changing the established user
workflow.
- [#6964](#6964) ->
`docs/reference/troubleshooting.mdx`, `docs/changelog/2026-07-15.mdx`:
Record complete agent-specific fresh-install and resume recovery
commands.
- [#6883](#6883) ->
`docs/get-started/quickstart.mdx`, `docs/inference/set-up-vllm.mdx`,
`docs/reference/platform-support.mdx`, `docs/changelog/2026-07-15.mdx`:
Summarize the DGX Station Nemotron Ultra express path and pinned
managed-vLLM recipe.
- [#6985](#6985) ->
`docs/inference/set-up-vllm.mdx`, `docs/reference/commands.mdx`,
`docs/changelog/2026-07-15.mdx`: Capture the final automated and
interactive storage-warning behavior.

## Type of Change

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

## Quality Gates

- [ ] Tests added or updated for changed behavior
- [x] Existing tests cover changed behavior —
`test/changelog-docs.test.ts` validates the dated-entry structure, exact
version heading, and preserved history.
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — `npx vitest run
test/changelog-docs.test.ts` (6 passed)
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — not run for this doc-only change.
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only) —
completed with 0 errors; Fern reported the unchanged unauthenticated
redirect-check and light-theme contrast warnings.
- [x] 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)
— the native changelog entry uses the required parser-safe MDX SPDX
comment and intentionally has no frontmatter.

---
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>


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

## Summary by CodeRabbit

* **Documentation**
* Added the v0.0.84 changelog entry covering setup, endpoint onboarding,
model handling, sandbox readiness, recovery, channel status, and
configuration safeguards.
* Clarified that sandbox health checks validate configured models
against local Ollama and vLLM provider inventories without generating
completions or consuming tokens.
* Documented that invalid runtime configuration changes are rejected
while preserving the existing working configuration.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
cv added a commit that referenced this pull request Jul 20, 2026
…#7015)

<!-- markdownlint-disable MD041 -->
## Summary
`nemoclaw <sandbox> channels status --channel whatsapp` reported a
working, paired WhatsApp bot as `unpaired` with a dead bridge: the probe
checked the pre-2026.6.10 session path and pgrep'd for a separate bridge
process that no longer exists (the bridge now runs in-process inside the
gateway). This teaches the probe the current OpenClaw session location
and derives in-process liveness from the canonical gateway log, and
moves the whole probe into a manifest-first `phase:"status"` hook so
`channel-status.ts` carries zero WhatsApp-specific code (mirroring the
Telegram hook from #6887).

## Related Issue
Fixes #7016 

## Changes
<!-- List concrete changes. If this adds an abstraction, configuration,
fallback, migration, or compatibility path, name its current requirement
and consumer, explain why a direct change is insufficient, and identify
the test that protects it. -->
- Probe the current OpenClaw session path
`credentials/whatsapp/<account>` in addition to the legacy `whatsapp/`
dir (OpenClaw 2026.6.10+ stores the paired Baileys session there), so a
paired sandbox is no longer misread as `unpaired`.
- Derive in-process-bridge liveness from the canonical in-sandbox
gateway log `/tmp/gateway.log` (where NemoClaw redirects gateway stdout,
per `agent/gateway-script-shared.ts`; the same log the Telegram hook
reads), scoped to `[whatsapp]` lines and emitting **only** markers + a
redacted ISO timestamp — never a raw log line that could carry a phone
number.
- Require a clean probe exit (`exec.status === 0`) before trusting the
result, so a timed-out probe classifies as `probe_failed` instead of
reading a verdict off partial stdout (matches the Telegram hook).
- Refactor (not a new abstraction — adopts the existing manifest-first
status-hook architecture #6887 introduced for Telegram, its §8-deferred
follow-up): move the probe + evaluator to
`messaging/channels/whatsapp/hooks/{status-health,status-health-eval}.ts`,
register a `phase:"status"` hook in the whatsapp manifest, and run it
through the generic status-hook runner. `channel-status.ts` loses ~312
lines of WhatsApp-specific code; its dispatch now routes both
`in-sandbox-qr` and `log-tail` deep-probe channels through the same
generic `runChannelHealthHook`. Deletes
`sandbox/whatsapp-diagnostics.ts`.
- Protected by `messaging/channels/whatsapp/hooks/status-health.test.ts`
+ `status-health-eval.test.ts`: credentials-path evidence, gateway-log
heartbeat synthesis, `/tmp/gateway.log` path assertion (guards the path
regression), non-zero-exit → `probe_failed`, and a `sh -n` syntax check
of the generated probe script.

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

## Quality Gates
<!-- Check one tests line and one docs line. Check other lines when
applicable. Add every requested justification or approval reference. -->
- [x] Tests added or updated for changed behavior
- [x] Docs not applicable — justification: no user-facing command, flag,
or output contract changed; this corrects the accuracy of an existing
diagnostic.
- [ ] Tests not applicable — justification:
- [ ] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [x] Sensitive paths changed (messaging + sandbox)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification
<!-- Check each applicable item only when supported by the requested
evidence. Run targeted tests once per relevant change set and rerun
after later edits or hook autofixes that can affect the tested behavior.
Do not rerun hook-covered checks. -->
- [ ] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [ ] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [ ] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — command/result or justification:
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [ ] Quality Gates section completed with required justifications or
waivers
- [ ] No secrets, API keys, or credentials committed
- [ ] `npm run 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)

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Hung Le <hple@nvidia.com>


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

- **New Features**
- Added a manifest-driven WhatsApp channel health hook
(`whatsapp.statusHealth`) that reports bridge liveness and heartbeat
when available (OpenClaw-based; Hermes bypasses the probe).

- **Bug Fixes**
- Updated sandbox channel status to prefer the declared channel-health
hook and fall back to config-only output when missing or paused.
- Improved health/verdict handling, including correct “stopped bridge”
classification and safer handling of malformed/unreliable probe output.

- **Tests**
- Expanded hook registration, verdict mapping, redaction, and robustness
tests, plus updated sandbox integration expectations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Hung Le <hple@nvidia.com>
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: Apurv Kumaria <akumaria@nvidia.com>
Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Co-authored-by: cjagwani <cjagwani@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli Command line interface, flags, terminal UX, or output area: messaging Messaging channels, bridges, manifests, or channel lifecycle feature PR adds or expands user-visible functionality integration: telegram Telegram integration or channel behavior VDR Linked to VDR finding VRDC Issues and PRs submitted by NVIDIA VRDC test team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[All Platforms][CLI&UX] channels status shows Telegram as all-[ok] while the bridge is unreachable — no runtime health probe for Telegram

6 participants