fix(tunnel): detect gateway with rewritten bare 'openclaw' argv (#4951) - #4960
Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR updates gateway stop matching for the bare ChangesGateway stop and PID tracking
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
✨ Thanks for submitting this detailed PR about detecting the gateway with rewritten bare 'openclaw' argv. This proposes a way to fix the regression in the tunnel stop functionality. Related open issues: |
1 similar comment
|
✨ Thanks for submitting this detailed PR about detecting the gateway with rewritten bare 'openclaw' argv. This proposes a way to fix the regression in the tunnel stop functionality. Related open issues: |
prekshivyas
left a comment
There was a problem hiding this comment.
Correct. `process.title = 'openclaw'` after startup made `find_gateway_pids` return empty, so `tunnel stop` silently exited 0. The new awk arm `/(^|[[:space:]/])openclaw[[:space:]]*$/` anchors at EOL, avoiding false matches on `openclaw-gateway` or `openclawish`. The live-process tests with `exec -a 'openclaw' cat` are the right guard for this.
Minor: the 300 ms post-SIGTERM sleep before the liveness check could flake on a heavily loaded CI runner. A short poll loop would be more robust — not a blocker.
97e3f1d to
9f85495
Compare
9f85495 to
6b7015c
Compare
…IA#4951) `nemoclaw tunnel stop` could not stop the in-sandbox gateway: OpenClaw rewrites its own argv via process.title after startup, so the running gateway shows just `openclaw` with no `gateway` suffix. The awk matcher in GATEWAY_STOP_SCRIPT only recognized `openclaw-gateway` and `openclaw gateway`, so find_gateway_pids returned empty, reportStopResult misread exit 1 as "not running", and the command exited 0 while the gateway (and its channel pollers) kept running. Add a third argv form to the matcher: a bare `openclaw` anchored to end-of-string (so it still rejects names like `openclawish`). The example argv tokens are kept out of the awk program text itself, because awk's argv is captured by the concurrent `ps` snapshot and any such literal would make awk match itself and prevent the scan from draining. Export GATEWAY_STOP_SCRIPT and add Linux-gated tests that execute it against real processes reproducing each argv form, asserting the bare gateway is killed (exit 0) and a non-gateway decoy is spared (exit 1). Signed-off-by: Abhimanyu Kumar <abhimanyukumar7290@gmail.com>
6b7015c to
db92038
Compare
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
Vitest E2E Scenario Results — ❌ Some jobs failedRun: 28238128513
|
Selective E2E Results — ✅ All requested jobs passedRun: 28237439156
|
|
@abhi-0906 this is still wanted — the target bug #4951 ( I looked at merging Could you run |
Reconcile with main's gateway-PID identity recording (NVIDIA#4952 line): the branch's interim starttime capture in record_gateway_pid, the Dockerfile HEALTHCHECK starttime hardening, and the stale-starttime provisioning test are all superseded by main's caller-supplied start-identity design and its existing coverage, so those files resolve to main verbatim. The surviving delta is the tunnel stop argv-detection fix in src/lib/tunnel/services.ts and its tests. Signed-off-by: Abhimanyu Kumar <abhimanyukumar7290@gmail.com>
|
@prekshivyas Merged origin/main in (73790af). Resolution notes:
|
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
E2E Target Results — ✅ All requested jobs passedRun: 28936009201
|
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
E2E Target Results — ✅ All requested jobs passedRun: 28936440222
|
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
E2E Target Results — ✅ All requested jobs passedRun: 28936959478
|
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
E2E Target Results — ✅ All requested jobs passedRun: 28937400229
|
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
E2E Target Results — ✅ All requested jobs passedRun: 28937887519
|
prekshivyas
left a comment
There was a problem hiding this comment.
Approved exact head ec09600b070ec83fa8ad1c78917d9e82696d2c41 after focused security and runtime review. The trusted gateway identity path now binds validation/read to opened file descriptors, rejects symlinks, unsafe ownership/mode, malformed or surplus PID records, PID reuse, pathname replacement, and stale/dead PID metadata without aborting safe argv scanning. The executed Linux regression suite and all standard CI shards pass. Both PR Advisors recommend merge_as_is: https://github.com/NVIDIA/NemoClaw/actions/runs/28937881639. E2E Advisor requires only tunnel-lifecycle and passed: https://github.com/NVIDIA/NemoClaw/actions/runs/28937883477. Exact-head tunnel-lifecycle passed: https://github.com/NVIDIA/NemoClaw/actions/runs/28937887519. Full CI passed: https://github.com/NVIDIA/NemoClaw/actions/runs/28937845209.
<!-- markdownlint-disable MD041 --> ## Summary Prepares the user documentation for NemoClaw v0.0.78 by replacing the unreleased section with release highlights and synchronizing the affected inference, lifecycle, messaging, and CLI reference pages with merged behavior. ## Changes - Publish the v0.0.78 release-notes section with links to the most specific user guides for each shipped behavior. - Document authoritative Deep Agents route health, Nemotron Ultra profile behavior, and Hermes compatible-endpoint context metadata. - Document forced rebuild recovery after total backup failure and the ownership-safe tunnel/full-stop behavior. - Keep command examples and shared agent variants aligned with the current OpenClaw, Hermes, and Deep Agents interfaces. Source mapping: - [#3787](#3787) -> `docs/about/release-notes.mdx`: Record reliable workspace template seeding during sandbox startup. - [#4960](#4960) -> `docs/about/release-notes.mdx`: Record safer detection of rewritten OpenClaw gateway processes. - [#5676](#5676) -> `docs/about/release-notes.mdx`: Record warning-tolerant agent-list JSON handling. - [#5857](#5857) -> `docs/about/release-notes.mdx`: Record synchronization of explicit OpenClaw main-agent model state. - [#5929](#5929) -> `docs/about/release-notes.mdx`: Record copyable SSH port-forward guidance for remote dashboards. - [#6068](#6068) -> `docs/about/release-notes.mdx`: Record custom-image plugin provenance reconciliation. - [#6116](#6116) -> `docs/about/release-notes.mdx`: Record live-loopback dashboard-forward recovery. - [#6122](#6122) -> `docs/about/release-notes.mdx`: Announce validated, round-trippable policy YAML output. - [#6211](#6211) -> `docs/manage-sandboxes/lifecycle.mdx`, `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain the explicit no-backup `rebuild --force` recovery boundary. - [#6283](#6283) -> `docs/about/release-notes.mdx`: Record Hermes WebUI port alignment. - [#6293](#6293) -> `docs/inference/switch-inference-providers.mdx`, `docs/about/release-notes.mdx`: Document compatible-endpoint context-length probing for Hermes. - [#6320](#6320) -> `docs/about/release-notes.mdx`: Record bounded gateway-recovery waits. - [#6377](#6377) -> `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain rebuild diagnostics and prepared MCP-destroy recovery. - [#6412](#6412) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document authoritative agent-visible inference route health. - [#6421](#6421) -> `docs/about/release-notes.mdx`: Record the longer quiet-pull window for managed vLLM images. - [#6431](#6431) -> `docs/inference/model-capability-audit.mdx`, `docs/about/release-notes.mdx`: Document the version-pinned Nemotron Ultra profile plugin. - [#6439](#6439) -> `docs/about/release-notes.mdx`: Summarize the authenticated, pinned credential-capture helper boundary. - [#6450](#6450) -> `docs/manage-sandboxes/messaging-channels.mdx`, `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document host-forward cleanup and ownership-safe gateway-port release. - [#6474](#6474) -> `docs/manage-sandboxes/messaging-channels.mdx`, `docs/about/release-notes.mdx`: Record composable OpenClaw messaging runtime loaders. - [#6475](#6475) -> `docs/about/release-notes.mdx`: Record removal of the unavailable Kimi K2.6 production endpoint option. - [#6480](#6480) -> `docs/about/release-notes.mdx`: Record stderr routing for the plugin registration banner. - [#6481](#6481) -> `docs/about/release-notes.mdx`: Record post-pull Ollama model discovery checks. - [#6482](#6482) -> `docs/about/release-notes.mdx`: Record Ollama model warm-up after daemon restart. - [#6486](#6486) -> `docs/about/release-notes.mdx`: Publish the opt-in, thread-scoped Deep Agents auto-approval boundary. - [#6490](#6490) -> `docs/about/release-notes.mdx`: Record diagnostics for custom images missing the managed runtime. - [#6494](#6494) -> `docs/inference/model-capability-audit.mdx`, `docs/about/release-notes.mdx`: Document nonempty tool-call content preservation and placeholder rejection. - [#6497](#6497) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document isolated Deep Agents route-probe output. - [#6506](#6506) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document observability-preserving managed route probes. - [#6508](#6508) -> `docs/about/release-notes.mdx`: Link the new extension taxonomy and SDK-readiness reference from the release summary. Release-source verification: GitHub reports all 29 cited source PRs as merged with base `main`, and every merge commit is an ancestor of `origin/main` at `17bf9a6a9688b3b1d69cf4b37d3f23110acb055e`. No source-mapping mismatches were found. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [x] Doc only (includes code sample changes) ## Quality Gates <!-- Check exactly one tests line and one docs line. Check other lines when applicable. Add every requested justification or approval reference. --> - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: Documentation-only release-prep changes; `npm run docs` validates variants, routes, and Fern content. - [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 <!-- 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. --> - [x] PR description includes the DCO sign-off declaration 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 — command/result or justification: Tests are not applicable to this documentation-only change set. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: - [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) — exited 0 with zero errors; Fern reported the existing unauthenticated redirect-check and light-mode 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) --- <!-- 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: Charan Jagwani <cjagwani@nvidia.com> --------- Signed-off-by: cjagwani <cjagwani@nvidia.com>
…IA#4951) (NVIDIA#4960) ## Summary `nemoclaw tunnel stop` (and its alias `nemoclaw stop`) reported success and exited `0` while the in-sandbox OpenClaw gateway — and its channel pollers — kept running. The stop script's process matcher never found the gateway because OpenClaw rewrites its own argv to a bare `openclaw` after startup. This teaches the matcher that third argv form so the gateway is actually detected and stopped. ## Related Issue Fixes NVIDIA#4951 ## Root cause `stopSandboxChannels` runs an in-sandbox `GATEWAY_STOP_SCRIPT` (`src/lib/tunnel/services.ts`) whose `find_gateway_pids` scans `ps -eo args=` and matches the gateway by argv. It recognized only: - `openclaw-gateway` (the re-execed binary name), and - `openclaw gateway run …` (the launcher command `nemoclaw-start` runs). But OpenClaw sets `process.title = 'openclaw'` after startup, so the live gateway's argv is just `openclaw` with no `gateway` suffix. As a result `find_gateway_pids` returned empty → the script `exit 1` → `reportStopResult` interprets exit 1 as *"gateway was not running"* → the command prints success and exits `0`, leaving the gateway and Slack/Telegram/Discord pollers alive. (Same `process.title` root cause as the sandbox HEALTHCHECK bug, NVB#6282411 / NVB#6282413.) ## Changes - **`src/lib/tunnel/services.ts`** — add a third argv form to the `find_gateway_pids` awk matcher: a bare `openclaw` anchored to end-of-string, so it still rejects unrelated names like `openclawish`. Document the three forms and *why* example argv tokens must stay out of the awk program body (awk's own argv is captured by the concurrent `ps` snapshot, so an in-program literal like `openclaw gateway` makes awk match itself and the kill/verify scan never drains). Export `GATEWAY_STOP_SCRIPT` for end-to-end testing. - **`src/lib/tunnel/services-sandbox.test.ts`** — assert the matcher contains all three argv forms, and add two Linux-gated tests that **execute** the real `GATEWAY_STOP_SCRIPT` against live processes reproducing each argv form: the bare-argv gateway is found and killed (exit 0), and a non-gateway decoy is spared (exit 1). ## 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 - [ ] `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) Ran locally on the affected files: `biome check` (clean), `tsc -p jsconfig.json` (clean), `vitest run src/lib/tunnel/services-sandbox.test.ts` (17 passed, 2 Linux-gated execution tests skipped on the Windows dev box), plus `source-shape` and `test-size` checks. The two Linux-gated execution tests were validated against the compiled script on Ubuntu 24.04 (WSL): bare `openclaw` killed → exit 0; decoy spared → exit 1. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved in-sandbox “tunnel stop” to reliably terminate all relevant gateway process naming variants, including the “bare” gateway form, while sparing unrelated processes. * Strengthened the container gateway health-check to safely validate PID reuse by parsing PID/start-time data and verifying the process matches the expected gateway command name. * **Tests** * Added Linux-only end-to-end coverage for stop-script matching across multiple gateway argv patterns, including ensuring decoy processes are not terminated. * Added a regression test for the health-check fallback when the recorded PID start time is stale. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Signed-off-by: Abhimanyu Kumar <abhimanyukumar7290@gmail.com> Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> --------- Signed-off-by: Abhimanyu Kumar <abhimanyukumar7290@gmail.com> Signed-off-by: Julie Yaunches <jyaunches@nvidia.com> Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com> Co-authored-by: Julie Yaunches <jyaunches@nvidia.com> Co-authored-by: Carlos Villela <cvillela@nvidia.com> Co-authored-by: Prekshi Vyas <prekshiv@nvidia.com>
<!-- markdownlint-disable MD041 --> ## Summary Prepares the user documentation for NemoClaw v0.0.78 by replacing the unreleased section with release highlights and synchronizing the affected inference, lifecycle, messaging, and CLI reference pages with merged behavior. ## Changes - Publish the v0.0.78 release-notes section with links to the most specific user guides for each shipped behavior. - Document authoritative Deep Agents route health, Nemotron Ultra profile behavior, and Hermes compatible-endpoint context metadata. - Document forced rebuild recovery after total backup failure and the ownership-safe tunnel/full-stop behavior. - Keep command examples and shared agent variants aligned with the current OpenClaw, Hermes, and Deep Agents interfaces. Source mapping: - [NVIDIA#3787](NVIDIA#3787) -> `docs/about/release-notes.mdx`: Record reliable workspace template seeding during sandbox startup. - [NVIDIA#4960](NVIDIA#4960) -> `docs/about/release-notes.mdx`: Record safer detection of rewritten OpenClaw gateway processes. - [NVIDIA#5676](NVIDIA#5676) -> `docs/about/release-notes.mdx`: Record warning-tolerant agent-list JSON handling. - [NVIDIA#5857](NVIDIA#5857) -> `docs/about/release-notes.mdx`: Record synchronization of explicit OpenClaw main-agent model state. - [NVIDIA#5929](NVIDIA#5929) -> `docs/about/release-notes.mdx`: Record copyable SSH port-forward guidance for remote dashboards. - [NVIDIA#6068](NVIDIA#6068) -> `docs/about/release-notes.mdx`: Record custom-image plugin provenance reconciliation. - [NVIDIA#6116](NVIDIA#6116) -> `docs/about/release-notes.mdx`: Record live-loopback dashboard-forward recovery. - [NVIDIA#6122](NVIDIA#6122) -> `docs/about/release-notes.mdx`: Announce validated, round-trippable policy YAML output. - [NVIDIA#6211](NVIDIA#6211) -> `docs/manage-sandboxes/lifecycle.mdx`, `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain the explicit no-backup `rebuild --force` recovery boundary. - [NVIDIA#6283](NVIDIA#6283) -> `docs/about/release-notes.mdx`: Record Hermes WebUI port alignment. - [NVIDIA#6293](NVIDIA#6293) -> `docs/inference/switch-inference-providers.mdx`, `docs/about/release-notes.mdx`: Document compatible-endpoint context-length probing for Hermes. - [NVIDIA#6320](NVIDIA#6320) -> `docs/about/release-notes.mdx`: Record bounded gateway-recovery waits. - [NVIDIA#6377](NVIDIA#6377) -> `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Explain rebuild diagnostics and prepared MCP-destroy recovery. - [NVIDIA#6412](NVIDIA#6412) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document authoritative agent-visible inference route health. - [NVIDIA#6421](NVIDIA#6421) -> `docs/about/release-notes.mdx`: Record the longer quiet-pull window for managed vLLM images. - [NVIDIA#6431](NVIDIA#6431) -> `docs/inference/model-capability-audit.mdx`, `docs/about/release-notes.mdx`: Document the version-pinned Nemotron Ultra profile plugin. - [NVIDIA#6439](NVIDIA#6439) -> `docs/about/release-notes.mdx`: Summarize the authenticated, pinned credential-capture helper boundary. - [NVIDIA#6450](NVIDIA#6450) -> `docs/manage-sandboxes/messaging-channels.mdx`, `docs/reference/commands.mdx`, `docs/about/release-notes.mdx`: Document host-forward cleanup and ownership-safe gateway-port release. - [NVIDIA#6474](NVIDIA#6474) -> `docs/manage-sandboxes/messaging-channels.mdx`, `docs/about/release-notes.mdx`: Record composable OpenClaw messaging runtime loaders. - [NVIDIA#6475](NVIDIA#6475) -> `docs/about/release-notes.mdx`: Record removal of the unavailable Kimi K2.6 production endpoint option. - [NVIDIA#6480](NVIDIA#6480) -> `docs/about/release-notes.mdx`: Record stderr routing for the plugin registration banner. - [NVIDIA#6481](NVIDIA#6481) -> `docs/about/release-notes.mdx`: Record post-pull Ollama model discovery checks. - [NVIDIA#6482](NVIDIA#6482) -> `docs/about/release-notes.mdx`: Record Ollama model warm-up after daemon restart. - [NVIDIA#6486](NVIDIA#6486) -> `docs/about/release-notes.mdx`: Publish the opt-in, thread-scoped Deep Agents auto-approval boundary. - [NVIDIA#6490](NVIDIA#6490) -> `docs/about/release-notes.mdx`: Record diagnostics for custom images missing the managed runtime. - [NVIDIA#6494](NVIDIA#6494) -> `docs/inference/model-capability-audit.mdx`, `docs/about/release-notes.mdx`: Document nonempty tool-call content preservation and placeholder rejection. - [NVIDIA#6497](NVIDIA#6497) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document isolated Deep Agents route-probe output. - [NVIDIA#6506](NVIDIA#6506) -> `docs/get-started/quickstart-langchain-deepagents-code.mdx`, `docs/about/release-notes.mdx`: Document observability-preserving managed route probes. - [NVIDIA#6508](NVIDIA#6508) -> `docs/about/release-notes.mdx`: Link the new extension taxonomy and SDK-readiness reference from the release summary. Release-source verification: GitHub reports all 29 cited source PRs as merged with base `main`, and every merge commit is an ancestor of `origin/main` at `17bf9a6a9688b3b1d69cf4b37d3f23110acb055e`. No source-mapping mismatches were found. ## Type of Change - [ ] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [x] Doc only (includes code sample changes) ## Quality Gates <!-- Check exactly one tests line and one docs line. Check other lines when applicable. Add every requested justification or approval reference. --> - [ ] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: Documentation-only release-prep changes; `npm run docs` validates variants, routes, and Fern content. - [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 <!-- 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. --> - [x] PR description includes the DCO sign-off declaration 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 — command/result or justification: Tests are not applicable to this documentation-only change set. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: - [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) — exited 0 with zero errors; Fern reported the existing unauthenticated redirect-check and light-mode 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) --- <!-- 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: Charan Jagwani <cjagwani@nvidia.com> --------- Signed-off-by: cjagwani <cjagwani@nvidia.com>
Summary
nemoclaw tunnel stop(and its aliasnemoclaw stop) reported success and exited0while the in-sandbox OpenClaw gateway — and its channel pollers — kept running. The stop script's process matcher never found the gateway because OpenClaw rewrites its own argv to a bareopenclawafter startup. This teaches the matcher that third argv form so the gateway is actually detected and stopped.Related Issue
Fixes #4951
Root cause
stopSandboxChannelsruns an in-sandboxGATEWAY_STOP_SCRIPT(src/lib/tunnel/services.ts) whosefind_gateway_pidsscansps -eo args=and matches the gateway by argv. It recognized only:openclaw-gateway(the re-execed binary name), andopenclaw gateway run …(the launcher commandnemoclaw-startruns).But OpenClaw sets
process.title = 'openclaw'after startup, so the live gateway's argv is justopenclawwith nogatewaysuffix. As a resultfind_gateway_pidsreturned empty → the scriptexit 1→reportStopResultinterprets exit 1 as "gateway was not running" → the command prints success and exits0, leaving the gateway and Slack/Telegram/Discord pollers alive. (Sameprocess.titleroot cause as the sandbox HEALTHCHECK bug, NVB#6282411 / NVB#6282413.)Changes
src/lib/tunnel/services.ts— add a third argv form to thefind_gateway_pidsawk matcher: a bareopenclawanchored to end-of-string, so it still rejects unrelated names likeopenclawish. Document the three forms and why example argv tokens must stay out of the awk program body (awk's own argv is captured by the concurrentpssnapshot, so an in-program literal likeopenclaw gatewaymakes awk match itself and the kill/verify scan never drains). ExportGATEWAY_STOP_SCRIPTfor end-to-end testing.src/lib/tunnel/services-sandbox.test.ts— assert the matcher contains all three argv forms, and add two Linux-gated tests that execute the realGATEWAY_STOP_SCRIPTagainst live processes reproducing each argv form: the bare-argv gateway is found and killed (exit 0), and a non-gateway decoy is spared (exit 1).Type of Change
Verification
npx prek run --all-filespassesnpm testpassesnpm run docsbuilds without warnings (doc changes only)Ran locally on the affected files:
biome check(clean),tsc -p jsconfig.json(clean),vitest run src/lib/tunnel/services-sandbox.test.ts(17 passed, 2 Linux-gated execution tests skipped on the Windows dev box), plussource-shapeandtest-sizechecks. The two Linux-gated execution tests were validated against the compiled script on Ubuntu 24.04 (WSL): bareopenclawkilled → exit 0; decoy spared → exit 1.Summary by CodeRabbit
Bug Fixes
Tests
Signed-off-by: Abhimanyu Kumar abhimanyukumar7290@gmail.com
Signed-off-by: Julie Yaunches jyaunches@nvidia.com