fix(onboard): fall back from managed gateway failures - #8106
Conversation
Signed-off-by: San Dang <sdang@nvidia.com>
|
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. |
📝 WalkthroughWalkthroughManaged gateway startup now reports platform-specific logs and falls back to standalone startup after operational service failures. Trust-validation, unsafe environment, invalid Docker settings, and occupied-port conditions remain blocking conditions. Tests and documentation cover the updated behavior. ChangesGateway fallback
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant Onboarding
participant ManagedGatewayService
participant GatewayCutover
participant StandaloneGateway
Onboarding->>ManagedGatewayService: start and check managed gateway
ManagedGatewayService-->>Onboarding: success or operational failure
Onboarding->>GatewayCutover: run managed fallback
GatewayCutover->>ManagedGatewayService: stop failed service
GatewayCutover->>StandaloneGateway: verify port and reuse or launch
StandaloneGateway-->>Onboarding: reused or launched gateway
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
|
🌿 Preview your docs: https://nvidia-preview-pr-8106.docs.buildwithfern.com/nemoclaw |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage in commit 39304fd in the TypeScript / code-coverage/cliThe overall coverage in commit 39304fd in the Show a code coverage summary of the most impacted files.
Updated |
Signed-off-by: San Dang <sdang@nvidia.com>
Signed-off-by: San Dang <sdang@nvidia.com>
Signed-off-by: San Dang <sdang@nvidia.com>
Security Review: PR #8106Overall Verdict: PASS The final diff at FindingsNo findings. Category Results
Files Reviewed
Reviewer: Codex CLI ( |
Fresh Ubuntu validationManual validation passed on a fresh Ubuntu machine with Docker and OpenShell 0.0.85: nemoclaw onboard --agent openclaw --freshThe managed
No logout/login cycle was required. |
PR Review Advisor — No blocking findings reportedAdvisor assessment: No blocking advisor findings reported Model lanes
3 terminology differences from the second opinionAdvisory only. These are normalized differences from the primary terminology receipt.
2 additional E2E selections from the second opinionAdvisory only. The primary lane did not select these E2E jobs or targets.
Second-opinion terminology and E2E selections are advisory. They do not change the primary assessment or E2E / PR Gate. 3 semantic terminology decisionsTerminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.
E2E guidanceAdvisory only. E2E / PR Gate selects and runs jobs independently. Recommended E2E: 1 optional E2E recommendation
This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge. |
Signed-off-by: San Dang <sdang@nvidia.com>
|
Addressed the current
The focused managed-service suite passes 58/58, caller/cutover tests pass 11/11, CLI typechecking passes, and the normal pre-commit and pre-push hooks pass. |
Signed-off-by: San Dang <sdang@nvidia.com>
Signed-off-by: San Dang <sdang@nvidia.com>
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/lib/onboard/docker-driver-gateway-service.ts (1)
316-329: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winClassify the missing Homebrew formula as an unavailable service, not an error.
Line 319 still throws a generic
Errorwhenbrew listreports that the formula is absent. The PR objective states that a missing Homebrew formula must fall back as an unavailable service. The genericErrorreachesstartPackageManagedDockerDriverGatewaythroughhasService()at Line 825 and is caught at Line 826, so onboarding does fall back. However, the user sees the warning "managed service could not be inspected", which describes an inspection defect rather than an absent formula.Return
falsefor the absent formula soresolveOpenShellGatewayUserServicereports the service as not installed. Keep the trust errors for unverifiable or incorrectly sourced formulas.🐛 Proposed fix
if ( !runBrew(["list", "--formula", OPENSHELL_GATEWAY_HOMEBREW_SERVICE], { env, spawnSyncImpl }).ok ) { - throw new Error("The official OpenShell Homebrew formula is not installed"); + return false; }🤖 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/onboard/docker-driver-gateway-service.ts` around lines 316 - 329, Update the Homebrew formula check in the service-availability helper around runBrew and resolveOpenShellGatewayUserService so a failed brew list indicating the formula is absent returns false instead of throwing a generic Error. Preserve the existing OpenShellGatewayServiceTrustError for failed identity or source verification, allowing unavailable-service handling while retaining trust failures.
🧹 Nitpick comments (5)
docs/reference/troubleshooting.mdx (1)
935-936: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUse one term for the failure set and one actor for the fallback.
Three variants describe the same condition: "inspection, startup, or its health check" (Line 936), "inspection, start, or health failure" (Line 951 and Line 964), and "inspection, start, and health failures" (Line 972).
docs/reference/architecture.mdxLine 90 uses the first form. Pick one form. Line 935 also makes the formula the actor; NemoClaw performs the fallback. Line 964 drops "this log command", which breaks parallelism with Line 951.As per coding guidelines, "Use the same term for the same concept" and "Use a professional, active, conversational voice".
📝 Proposed wording alignment
- During onboarding, a missing `openshell` formula uses the standalone fallback. + During onboarding, NemoClaw uses the standalone fallback when the `openshell` formula is missing. If the installed service fails inspection, startup, or its health check, NemoClaw prints this log command:- After an inspection, start, or health failure, NemoClaw prints this log command: + If the service fails inspection, startup, or its health check, NemoClaw prints this log command:- After an inspection, start, or health failure, NemoClaw prints: + If the service fails inspection, startup, or its health check, NemoClaw prints this log command:- Managed-service inspection, start, and health failures on either platform attempt the standalone fallback. + On either platform, NemoClaw attempts the standalone fallback after managed-service inspection, startup, and health check failures.Also applies to: 951-951, 964-964, 972-972
🤖 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 `@docs/reference/troubleshooting.mdx` around lines 935 - 936, Align the troubleshooting wording at the referenced fallback descriptions to consistently use “inspection, startup, or its health check” for the failure set, make NemoClaw the actor performing the standalone fallback, and retain “this log command” wherever the log command is introduced or referenced, including the parallel entries around lines 951, 964, and 972.Source: Coding guidelines
src/lib/onboard/docker-driver-gateway-service.ts (3)
63-68: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valuePreserve the original error as
cause.
OpenShellGatewayServiceEnvironmentErrorkeeps only the formatted message. The original error object, including its stack anderrnocode, is discarded. Node.js 22 supports thecauseoption, so keeping it costs nothing and improves diagnosis of filesystem failures raised bywriteDockerGatewayDebEnvOverrideFile.♻️ Proposed change
export class OpenShellGatewayServiceEnvironmentError extends Error { constructor(error: unknown) { - super(formatError(error)); + super(formatError(error), { cause: error }); this.name = "OpenShellGatewayServiceEnvironmentError"; } }🤖 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/onboard/docker-driver-gateway-service.ts` around lines 63 - 68, Update the OpenShellGatewayServiceEnvironmentError constructor to preserve the incoming error as the Error cause while retaining the formatted message and existing name. Ensure errors raised by writeDockerGatewayDebEnvOverrideFile keep their original stack and errno details.
820-896: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffExtract the managed-start and fallback handling into helpers.
startPackageManagedDockerDriverGatewaynow spans about 140 lines. It contains the inspection guard, a nestedstopBeforeStandaloneFallbackclosure, a nestedreportLogsclosure, the starttry/catch, the not-started branch, the health poll, and the timeout branch. This exceeds the complexity target for the file type.Extract
stopBeforeStandaloneFallbackand the managed-start-result handling into module-level functions that takestopService,managedServiceLogCommand, andexitOnFailureas parameters. The function then reads as inspect, start, wait, report.As per coding guidelines: "Keep function complexity low and prefix intentionally unused variables with
_."🤖 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/onboard/docker-driver-gateway-service.ts` around lines 820 - 896, Refactor startPackageManagedDockerDriverGateway by extracting the nested stopBeforeStandaloneFallback and managed-start-result handling (including log reporting) into module-level helpers that accept stopService, managedServiceLogCommand, and exitOnFailure. Keep the main function’s flow limited to inspect, start, wait, and report while preserving existing fallback, trust-error, logging, and exit behavior; prefix any intentionally unused helper parameters with _.Source: Coding guidelines
330-351: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueNarrow the
tryblock to the JSON parse.The
tryat Line 330 also wraps the tap check at Line 337. TheOpenShellGatewayServiceTrustErrorthrown at Line 338 enters thecatch, passes theSyntaxErrortest, and is rethrown at Line 348. The result is correct, but the control flow is indirect. Parse inside thetryand validate the tap outside it.♻️ Proposed refactor
- try { - const parsed = JSON.parse(info.stdout ?? "") as { - formulae?: Array<{ name?: string; tap?: string }>; - }; - const formula = parsed.formulae?.find( - (candidate) => candidate.name === OPENSHELL_GATEWAY_HOMEBREW_SERVICE, - ); - if (formula?.tap !== OPENSHELL_GATEWAY_HOMEBREW_TAP) { - throw new OpenShellGatewayServiceTrustError( - `OpenShell Homebrew formula must come from ${OPENSHELL_GATEWAY_HOMEBREW_TAP}`, - ); - } - } catch (error) { - if (error instanceof SyntaxError) { - throw new OpenShellGatewayServiceTrustError( - "OpenShell Homebrew formula identity check returned invalid JSON", - ); - } - throw error; - } + let parsed: { formulae?: Array<{ name?: string; tap?: string }> }; + try { + parsed = JSON.parse(info.stdout ?? "") as typeof parsed; + } catch { + throw new OpenShellGatewayServiceTrustError( + "OpenShell Homebrew formula identity check returned invalid JSON", + ); + } + const formula = parsed.formulae?.find( + (candidate) => candidate.name === OPENSHELL_GATEWAY_HOMEBREW_SERVICE, + ); + if (formula?.tap !== OPENSHELL_GATEWAY_HOMEBREW_TAP) { + throw new OpenShellGatewayServiceTrustError( + `OpenShell Homebrew formula must come from ${OPENSHELL_GATEWAY_HOMEBREW_TAP}`, + ); + }🤖 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/onboard/docker-driver-gateway-service.ts` around lines 330 - 351, In the formula identity check, narrow the try/catch around JSON.parse so it only converts SyntaxError into OpenShellGatewayServiceTrustError. Move the formula lookup and tap validation using parsed and OPENSHELL_GATEWAY_HOMEBREW_TAP outside the try block, preserving the existing validation behavior and error message.src/lib/onboard/docker-driver-gateway-env.ts (1)
354-355: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueThread the injected environment into the log-command helper.
Every other default in this call site receives the resolved
envandeffectiveHome.getOpenShellGatewayManagedServiceLogCommand()receives no options, so it readsprocess.platformand the realfs.existsSync. Tests that inject a temporary home still resolve the unit name from the host filesystem. The helper acceptsplatformandexistsSync, so pass them for consistency and test determinism.🤖 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/onboard/docker-driver-gateway-env.ts` around lines 354 - 355, Update the managedServiceLogCommand default in the surrounding configuration to call getOpenShellGatewayManagedServiceLogCommand with the resolved env and effectiveHome dependencies, including the injected platform and existsSync implementations. Preserve the explicit options.managedServiceLogCommand override while ensuring the default uses the same injected environment as the other defaults.
🤖 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/onboard.ts`:
- Around line 1974-1990: Refresh the listener scan after managed startup
fallback before invoking runDockerDriverGatewayCutover. Replace the stale
servicePortOwnership.portListenerScan used in the cutover arguments with a newly
obtained port probe and listener scan, preserving the existing scan fields and
using the refreshed pids and complete values for reuse and cleanup decisions.
In `@src/lib/onboard/docker-driver-gateway-service.ts`:
- Around line 882-895: Update startPackageManagedDockerDriverGateway so
OpenShellGatewayServiceTrustError from stopBeforeStandaloneFallback, including
health-timeout cleanup, follows the same exitOnFailure behavior as
standaloneFallbackBlocked: exit with status 1 when enabled, otherwise propagate
the error. Add coverage for both cleanup paths.
In `@test/onboard-gateway-prelaunch-cutover.test.ts`:
- Around line 123-136: Add a test that invokes the public
startDockerDriverGateway entry point from the onboard module, configuring
managed startup to succeed and observing the standalone cutover callback or
equivalent invocation. Assert the result reflects managed startup and verify
standalone startup is not called; keep the existing helper-level test unchanged.
---
Outside diff comments:
In `@src/lib/onboard/docker-driver-gateway-service.ts`:
- Around line 316-329: Update the Homebrew formula check in the
service-availability helper around runBrew and
resolveOpenShellGatewayUserService so a failed brew list indicating the formula
is absent returns false instead of throwing a generic Error. Preserve the
existing OpenShellGatewayServiceTrustError for failed identity or source
verification, allowing unavailable-service handling while retaining trust
failures.
---
Nitpick comments:
In `@docs/reference/troubleshooting.mdx`:
- Around line 935-936: Align the troubleshooting wording at the referenced
fallback descriptions to consistently use “inspection, startup, or its health
check” for the failure set, make NemoClaw the actor performing the standalone
fallback, and retain “this log command” wherever the log command is introduced
or referenced, including the parallel entries around lines 951, 964, and 972.
In `@src/lib/onboard/docker-driver-gateway-env.ts`:
- Around line 354-355: Update the managedServiceLogCommand default in the
surrounding configuration to call getOpenShellGatewayManagedServiceLogCommand
with the resolved env and effectiveHome dependencies, including the injected
platform and existsSync implementations. Preserve the explicit
options.managedServiceLogCommand override while ensuring the default uses the
same injected environment as the other defaults.
In `@src/lib/onboard/docker-driver-gateway-service.ts`:
- Around line 63-68: Update the OpenShellGatewayServiceEnvironmentError
constructor to preserve the incoming error as the Error cause while retaining
the formatted message and existing name. Ensure errors raised by
writeDockerGatewayDebEnvOverrideFile keep their original stack and errno
details.
- Around line 820-896: Refactor startPackageManagedDockerDriverGateway by
extracting the nested stopBeforeStandaloneFallback and managed-start-result
handling (including log reporting) into module-level helpers that accept
stopService, managedServiceLogCommand, and exitOnFailure. Keep the main
function’s flow limited to inspect, start, wait, and report while preserving
existing fallback, trust-error, logging, and exit behavior; prefix any
intentionally unused helper parameters with _.
- Around line 330-351: In the formula identity check, narrow the try/catch
around JSON.parse so it only converts SyntaxError into
OpenShellGatewayServiceTrustError. Move the formula lookup and tap validation
using parsed and OPENSHELL_GATEWAY_HOMEBREW_TAP outside the try block,
preserving the existing validation behavior and error message.
🪄 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: 7c97c1eb-af13-4aae-8311-58b2baadf32b
📒 Files selected for processing (10)
docs/reference/architecture.mdxdocs/reference/troubleshooting.mdxsrc/lib/onboard.tssrc/lib/onboard/docker-driver-gateway-cutover.tssrc/lib/onboard/docker-driver-gateway-env-service.test.tssrc/lib/onboard/docker-driver-gateway-env.test.tssrc/lib/onboard/docker-driver-gateway-env.tssrc/lib/onboard/docker-driver-gateway-service.test.tssrc/lib/onboard/docker-driver-gateway-service.tstest/onboard-gateway-prelaunch-cutover.test.ts
cv
left a comment
There was a problem hiding this comment.
Security review for commit e3e1d892cc0211237e1aaa05c688ce28e525ec85 — FAIL
Scope is established by maintainer-authored issue #8104. The fallback must preserve exclusive gateway-port ownership and treat trust failures as hard failures.
- Secrets and credentials — PASS. No secret values are added to source, tests, or diagnostics. Existing environment-file and gateway-identity checks remain fail closed.
- Input validation and data sanitization — PASS. Command execution uses argument arrays, diagnostic commands are static, and invalid
DOCKER_HOSTvalues remain rejected. - Authentication and authorization — PASS. Symlinked environment files, foreign systemd services, and untrusted Homebrew identities remain rejected.
- Dependencies and third-party libraries — PASS. No dependency, package, image, or download changes.
- Error handling and logging — WARNING. Generic service-inspection failures return to fallback without attempting the issue-required best-effort trusted cleanup. Cleanup trust failures also do not follow the established
exitOnFailurebehavior. The latter matches unresolved review thread r3703117804. - Cryptography and data protection — PASS. No cryptographic or persisted-secret behavior changes.
- Configuration and security headers — PASS. No browser security headers or supported policy boundary changes. Existing trusted service configuration checks remain in place.
- Security testing — FAIL. The tests retain a fixed listener snapshot and do not exercise caller wiring when listener ownership changes during the managed attempt. This matches unresolved thread r3703117812.
- System security — FAIL.
src/lib/onboard.tscaptures the gateway listener scan before managed startup or cleanup, then passes that stale snapshot into standalone cutover after the managed attempt may have changed listeners. BecausescanGatewayPortListenersmaterializes a point-in-time result, a managed or auto-restarting listener can be omitted from scoped cleanup or reuse evidence. That violates the exclusive port-ownership requirement and matches unresolved CodeRabbit Major finding r3703117799.
Smallest safe next step: after managed fallback, refresh the port probe and listener scan, pass that refreshed evidence into standalone cutover, and add a caller-level regression in which the listener set changes during the managed attempt. Address the cleanup and failure-boundary findings as part of the same lifecycle fix. Then resolve the review threads and repeat security and documentation writer reviews for the final commit; the current receipts cover 65828bfaa, not this commit.
Signed-off-by: San Dang <sdang@nvidia.com>
cv
left a comment
There was a problem hiding this comment.
Security review for commit 41f139a87f2656fd2e3268afd77106d9d3745475 — FAIL
Scope is established by maintainer-authored issue #8104. The fallback must preserve exclusive gateway-port ownership and attempt best-effort managed-service cleanup after operational failures while treating identity and trust failures as hard failures.
- Secrets and credentials — PASS. No secret values are added to source, tests, or diagnostics.
- Input validation and data sanitization — PASS. Command execution uses argument arrays, and invalid gateway inputs remain rejected.
- Authentication and authorization — PASS. Untrusted service identities and service configuration remain rejected.
- Dependencies and third-party libraries — PASS. No dependency, package, image, or download changes.
- Error handling and logging — WARNING.
startPackageManagedDockerDriverGatewaylogs a non-trusthasService()exception and returnsfalsewithout calling the trustedstopServicecleanup used by the later failure paths. Issue #8104 explicitly requires best-effort managed-service stop before standalone fallback after operational inspection failures. The corresponding test supplies a stop spy but never asserts cleanup. - Cryptography and data protection — PASS. No cryptographic or persisted-secret behavior changes.
- Configuration and security headers — PASS. Existing trusted service configuration checks remain in place; browser security headers are outside this change.
- Security testing — FAIL. The new regression invokes only
runDockerDriverGatewayManagedFallbackwith inline callbacks. It does not exercisestartDockerDriverGatewayor prove that the production caller refreshes listener evidence after the managed attempt. It would still pass if production reverted to the stale snapshot. This matches current unresolved thread r3703117812. - System security — PASS for the prior stale-listener finding. The production fallback now obtains a fresh port probe and listener scan after managed startup returns
false, so current listener evidence reaches standalone cutover.
Required before approval: attempt the same trusted cleanup after a non-trust service-inspection exception and assert it in the unit test; add a caller-level regression through startDockerDriverGateway that proves managed success skips standalone cutover and managed fallback uses listener evidence captured after the managed attempt. Then resolve the remaining review thread and repeat the security and documentation writer reviews for the new commit.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/onboard-gateway-prelaunch-cutover.test.ts`:
- Around line 4-6: Update the subprocess invocation in the onboarding prelaunch
test to run through the repository’s tsx loader instead of relying on bare Node
type stripping. Adjust the spawnSync command setup and retain the existing
script arguments and assertions so src/lib/onboard.ts and its runtime-boundary
dependency load successfully.
🪄 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: 0d568992-61dc-46a6-b439-5d0149f07cb7
📒 Files selected for processing (4)
src/lib/onboard.tssrc/lib/onboard/docker-driver-gateway-service.test.tssrc/lib/onboard/docker-driver-gateway-service.tstest/onboard-gateway-prelaunch-cutover.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/lib/onboard.ts
- src/lib/onboard/docker-driver-gateway-service.ts
cv
left a comment
There was a problem hiding this comment.
Approved for commit SHA 39304fd42e618015e6c27beb5aafcb4e3e633786 and base SHA 4cd4d64fe67143b57707f874afa0b9d269dfeff2.
Product scope passes. Issue #8104 repairs the existing managed-gateway onboarding fallback and does not create a new supported surface.
The current nine-category security review passes. Operational inspection, startup, cleanup, and health failures enter the existing ownership-gated standalone path. Service trust errors, unsafe environment state, foreign or symlinked units, and untrusted executables remain hard failures. Current regression tests cover the cleanup, trust, port-ownership, and public-caller paths.
The documentation writer review is current for this commit. Required GitHub checks for this commit pass. The repository gate checker reports allPass: true; GitHub reports MERGEABLE. The PR body contains the DCO declaration, all nine commits appear as GitHub Verified, and no unresolved major or critical CodeRabbit finding remains.
<!-- markdownlint-disable MD041 --> ## Summary Adds the canonical dated `v0.0.101` changelog entry that was missing when the release tag was cut. This post-release recovery records the shipped behavior on current `main` without changing or replacing the existing tag. ## Changes - Add `docs/changelog/2026-08-03.mdx` with the exact `## v0.0.101` heading, release summary, detailed behavior changes, support boundaries, and links to durable documentation. - [#7317](#7317) -> `docs/changelog/2026-08-03.mdx`: Records experimental OpenClaw Google Chat support and its restricted credential and webhook boundary. - [#7715](#7715) -> `docs/changelog/2026-08-03.mdx`: Records strict onboarding recovery state and authoritative resume identity. - [#7749](#7749) -> `docs/changelog/2026-08-03.mdx`: Records the provider-neutral policy seam and unchanged runtime support boundary. - [#7817](#7817) -> `docs/changelog/2026-08-03.mdx`: Records preserved Hermes home-channel assignments across rebuilds. - [#7820](#7820) -> `docs/changelog/2026-08-03.mdx`: Records the SSH-session status field correction. - [#7847](#7847) -> `docs/changelog/2026-08-03.mdx`: Records fail-closed credential filtering for migration and rebuild backups. - [#7870](#7870) -> `docs/changelog/2026-08-03.mdx`: Records sandbox-qualified in-sandbox host command hints. - [#7875](#7875) -> `docs/changelog/2026-08-03.mdx`: Records Microsoft Teams stop and start E2E coverage. - [#7885](#7885) -> `docs/changelog/2026-08-03.mdx`: Records Hermes managed gateway detection in status. - [#7889](#7889) -> `docs/changelog/2026-08-03.mdx`: Records policy-authenticated HTTPS Pin Runtime route revocation. - [#7891](#7891) -> `docs/changelog/2026-08-03.mdx`: Records default fallback for negative timeout and polling overrides. - [#7993](#7993) -> `docs/changelog/2026-08-03.mdx`: Records correct sibling detection during uninstall. - [#7995](#7995) -> `docs/changelog/2026-08-03.mdx`: Records absent configuration-hash handling before shields lock. - [#8001](#8001) -> `docs/changelog/2026-08-03.mdx`: Records the dormant atomic managed workload replacement foundation. - [#8029](#8029) -> `docs/changelog/2026-08-03.mdx`: Records repository terminology review in PR Review Advisor. - [#8031](#8031) -> `docs/changelog/2026-08-03.mdx`: Records provider-neutral managed snapshot authority. - [#8032](#8032) -> `docs/changelog/2026-08-03.mdx`: Records immutable managed clone handoff contracts. - [#8034](#8034) -> `docs/changelog/2026-08-03.mdx`: Records the dormant provider-owned clone transaction surface. - [#8035](#8035) -> `docs/changelog/2026-08-03.mdx`: Records the dormant Hermes managed clone broker boundary. - [#8036](#8036) -> `docs/changelog/2026-08-03.mdx`: Records the dormant transactional managed bootstrap boundary. - [#8037](#8037) -> `docs/changelog/2026-08-03.mdx`: Records dormant Docker bootstrap primitives and the unchanged provider support boundary. - [#8070](#8070) -> `docs/changelog/2026-08-03.mdx`: Records consolidated sandbox resource-limit E2E coverage. - [#8071](#8071) -> `docs/changelog/2026-08-03.mdx`: Records escaped and bounded CLI validation diagnostics. - [#8081](#8081) -> `docs/changelog/2026-08-03.mdx`: Records bounded linear snapshot Base64 validation. - [#8085](#8085) -> `docs/changelog/2026-08-03.mdx`: Records commit-bound workflow approval for eligible same-repository maintainers. - [#8088](#8088) -> `docs/changelog/2026-08-03.mdx`: Records Hermes managed-policy E2E selection. - [#8090](#8090) -> `docs/changelog/2026-08-03.mdx`: Records pinned CI search-tool provisioning. - [#8106](#8106) -> `docs/changelog/2026-08-03.mdx`: Records fallback from failed managed OpenShell gateway startup. - [#8107](#8107) -> `docs/changelog/2026-08-03.mdx`: Records Hermes adapter lifecycle E2E selection. - [#8128](#8128) -> `docs/changelog/2026-08-03.mdx`: Records the dormant transactional Docker bootstrap adapter and rollback authority. - [#8140](#8140) -> `docs/changelog/2026-08-03.mdx`: Records Slack conflict scope across independent OpenShell gateways. - [#8147](#8147) -> `docs/changelog/2026-08-03.mdx`: Records completion of durable v0.0.100 documentation audit follow-ups. ## 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 - [ ] Existing tests cover changed behavior — justification: - [x] Tests not applicable — justification: This documentation-only recovery does not change executable behavior. - [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: ## Documentation Writer Review - [x] Documentation writer subagent reviewed the completed changes - Result: `docs-updated` - Evidence: Independently reviewed `docs/changelog/2026-08-03.mdx` at commit `0bebe1f568e3dc85cf410aac1dfb8f8830070b85`. Its blob is `82887920f9720eafd75db6b2271c35f7477edb9b`. The entry follows the writing guide, controlled terminology, changelog structure, MDX SPDX format, literal CLI-name rule, and root-absolute route requirements. It accurately records the `v0.0.100...v0.0.101` release range, Announcement #8162, accepted scope boundaries, and shipped security behavior. There are no code samples. Focused changelog tests and the documentation build pass for this commit. - Agent: Codex Desktop independent documentation writer <!-- docs-review-head-sha: 0bebe1f --> <!-- docs-review-agents-blob-sha: 3dd7c24 --> ## Security Review - Result: `PASS` - Reviewed commit: `0bebe1f568e3dc85cf410aac1dfb8f8830070b85` - Base commit: `643a4ab8b5f583d8555192a37927268b26022c51` - Findings: None. - Secrets and credentials: `PASS`. No credential values or secret files are present. - Input validation and data sanitization: `PASS`. No executable input path changes. - Authentication and authorization: `PASS`. No identity or permission logic changes. - Dependencies and third-party libraries: `PASS`. No dependency changes. - Error handling and logging: `PASS`. No runtime path changes; diagnostic-security claims are precise. - Cryptography and data protection: `PASS`. No implementation changes. - Configuration and security controls: `PASS`. No configuration, container, port, or HTTP changes. - Security testing: `PASS`. No coverage is removed; the entry records shipped test and security behavior. - System security: `PASS`. No runtime control changes; dormant and non-activation boundaries are explicit. - Agent: Codex Desktop independent security reviewer ## Verification - [ ] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub — verification is pending after commit `0bebe1f568e3dc85cf410aac1dfb8f8830070b85` is pushed. - [ ] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run validate:pr` passed after refreshing `origin/main` when hooks were skipped or unavailable — commit hooks passed; pre-push is pending. - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — tests are not applicable to this documentation-only recovery. - [x] Applicable broad gate passed — not applicable to this documentation-only recovery. - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, credentials, or private keys are added by this diff. - [ ] `npm run docs` builds without warnings (doc changes only) — GitHub documentation checks are pending. - [x] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) — independent documentation review passed. - [x] 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. GitHub CI is authoritative. Focused changelog tests and `npm run docs` passed after the merge refresh. --- Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added experimental Google Chat support. * Improved runtime and session status visibility. * Added onboarding recovery and persistence safeguards. * Added snapshot validation and dormant managed-workload support. * **Bug Fixes** * Improved backup sanitization, route handling, and gateway reliability. * **Documentation** * Added the v0.0.101 changelog and related updates. * **Tests** * Expanded end-to-end coverage and strengthened trusted CI validation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Apurv Kumaria <akumaria@nvidia.com> Signed-off-by: Carlos Villela <cvillela@nvidia.com> Co-authored-by: Carlos Villela <cvillela@nvidia.com> Co-authored-by: Senthil Ravichandran <senthilr@nvidia.com>
Summary
Managed OpenShell gateway failures previously stopped onboarding after the selected systemd or Homebrew service failed to start or become healthy. Onboarding now prints the platform-specific log command, attempts managed-service cleanup, and continues through the existing ownership-gated standalone gateway path.
Related Issue
Fixes #8104
Changes
DOCKER_HOST, and symlinked service-environment rejection.Type of Change
Quality Gates
39304fd42; review report.Documentation Writer Review
docs-updatedorigin/main...39304fd42for PR fix(onboard): fall back from managed gateway failures #8106 / issue Onboarding stops instead of falling back after managed gateway failure #8104. Keptdocs/reference/architecture.mdxanddocs/reference/troubleshooting.mdxconcise. Focused service tests passed 59/59 and caller/cutover tests passed 12/12; test-title check, CLI typecheck, Biome, and normal pre-commit checks passed;npm run docspassed with 0 errors and Fern's existing 2-warning summary;git diff --checkpassed.DGX Station Hardware Evidence
Verification
Signed-off-by:line and every commit appears asVerifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run validate:prpassed after refreshingorigin/mainwhen hooks were skipped or unavailabletest/onboard-gateway-prelaunch-cutover.test.tspassed 12/12 at39304fd42; the unrelated pinned prompt-asset test passed 18/18 locally after an external GitHub fetch timeout in CI.journalctlcommand, the standalone gateway became healthy, and onboarding continued to step 3/8 without logout/login (evidence).npm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result: Not applicable; this is a focused onboarding behavior change covered by the targeted CLI tests and normal hooks.npm run docsbuilds without warnings (doc changes only) — the command passed, but Fern reported its general 2-warning summary.Signed-off-by: San Dang sdang@nvidia.com
Summary by CodeRabbit
New Features
Bug Fixes