Skip to content

fix(onboard): pass messaging dependencies during reuse - #9366

Merged
ericksoa merged 2 commits into
NVIDIA:mainfrom
deepujain:fix/9359-recorded-messaging-deps
Aug 17, 2026
Merged

fix(onboard): pass messaging dependencies during reuse#9366
ericksoa merged 2 commits into
NVIDIA:mainfrom
deepujain:fix/9359-recorded-messaging-deps

Conversation

@deepujain

@deepujain deepujain commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Restore the recorded messaging resume path after the lifecycle reconciliation update. Recorded channels now pass the required persistence and notification dependencies into host-channel filtering, and the affected reuse fixtures model that contract.

Related Issue

Fixes #9359

Changes

  • Pass onboarding messaging dependencies through recorded-channel reconciliation.
  • Update the existing reuse fixtures to provide the dependency contract required when channels are filtered and persisted.

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:
  • 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:

DGX Station Hardware Evidence

  • Tested on DGX Station
  • Tested commit: Not applicable
  • Station profile/scenario: Not applicable
  • Result: Not applicable
  • Supporting evidence: Not applicable

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 validate:pr passed after refreshing origin/main when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — npx vitest run --project cli src/lib/onboard/machine/handlers/sandbox-messaging.test.ts (32 passed)
  • 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)

Additional validation: npm run build:cli, npm run typecheck:cli, and npm run lint.


Signed-off-by: Deepak Jain deepujain@gmail.com

Summary by CodeRabbit

  • Bug Fixes
    • Improved reconciliation when resuming recorded sandbox messaging sessions.
    • Missing host configuration is now clearly noted, while outdated saved plans are removed without being rewritten.
    • Improved filtering of unavailable messaging channels and handling of related plan updates and notifications.

Fixes NVIDIA#9359

Signed-off-by: Deepak Jain <deepujain@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 17, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a06c7a81-fc0d-4f4f-aba7-47a8d69ecb33

📥 Commits

Reviewing files that changed from the base of the PR and between c157d83 and 817025d.

📒 Files selected for processing (2)
  • src/lib/onboard/machine/handlers/sandbox-messaging.test.ts
  • src/lib/onboard/machine/handlers/sandbox-messaging.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/onboard/machine/handlers/sandbox-messaging.test.ts
  • src/lib/onboard/machine/handlers/sandbox-messaging.ts

Included review availability: Your plan includes up to 12 reviews per rolling hour; 3 remain after this review.


📝 Walkthrough

Walkthrough

The recorded-channel reconciliation path now passes options.deps to filterUnconfiguredHostChannelsFromSelection. Tests add dependency mocks and verify notification, plan clearing, and the absence of plan rewriting.

Changes

Recorded messaging reconciliation

Layer / File(s) Summary
Dependency wiring and validation
src/lib/onboard/machine/handlers/sandbox-messaging.ts, src/lib/onboard/machine/handlers/sandbox-messaging.test.ts
The recorded-channel path passes options.deps to filterUnconfiguredHostChannelsFromSelection. Test fixtures add note and writePlanToEnv mocks. The recorded-resume test verifies notification, persisted-plan cleanup, and no replacement plan write.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Merge Risk: ⚪ Minimal · up to 81702

This localized change restores messaging dependencies during recorded-channel reuse, with targeted validation reported as passing; no actionable merge-blocking risk remains beyond normal checks and review.

Possibly related PRs

Suggested labels: area: messaging, area: onboarding, bug-fix

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 describes the main change: passing messaging dependencies during sandbox reuse.
Linked Issues check ✅ Passed The changes pass options.deps to the helper and add focused recorded-channel regression assertions required by issue #9359.
Out of Scope Changes check ✅ Passed The changes remain within scope by updating the required call site and its focused regression fixtures and assertions.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Signed-off-by: Deepak Jain <deepujain@gmail.com>
@deepujain

Copy link
Copy Markdown
Contributor Author

Added focused assertions for the recorded-channel side effects and documented the reconciliation helper. The targeted suite, typecheck, lint, and repository checks pass.

@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

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

Advisory only. These are normalized differences from the primary terminology receipt.

  • checkpoint channels at src/lib/onboard/machine/handlers/sandbox-messaging.ts:376: selected only by the second-opinion lane as replace.
4 additional E2E selections from the second opinion

Advisory only. The primary lane did not select these E2E jobs or targets.

  • messaging-providers: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • channels-stop-start: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • hermes-discord: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • whatsapp-qr-compact: The completed second-opinion lane identified E2E coverage that the primary lane omitted.

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

1 semantic terminology decision

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • established — host inputs at src/lib/onboard/machine/handlers/sandbox-messaging.ts:376: Keep `host inputs` for current host-side channel configuration.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite for the commit under review.

Recommended E2E: None

Manual-only E2E: cloud-onboard, onboard-repair, onboard-resume
The manual PR workflow does not run these selectors for the commit under review. Run them from reviewed code on main.

1 optional E2E recommendation
  • channels-add-remove

Workflow run details

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

@wscurran wscurran added area: messaging Messaging channels, bridges, manifests, or channel lifecycle area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow bug-fix PR fixes a bug or regression labels Aug 17, 2026
@ericksoa
ericksoa merged commit 54cb2a4 into NVIDIA:main Aug 17, 2026
59 of 66 checks passed
ericksoa added a commit that referenced this pull request Aug 17, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 plain sentences: what changes and why. Describe
before-and-after behavior when it applies. Follow the NemoClaw Writing
Guide: https://github.com/NVIDIA/NemoClaw/blob/main/WRITING.md. Do not
add unrelated prose cleanup. -->
Managed OpenClaw sandbox registration now stores `agent: "openclaw"`
when a validated managed-image receipt owns the sandbox. Legacy and
custom-image registrations keep `agent: null`. A mismatch between the
receipt and selected agent fails before the registry write.

## Related Issue
<!-- Fixes #NNN or Closes #NNN. Remove this section if none. -->
Fixes #9356

## 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. -->
- `buildCreatedSandboxRegistryEntry()` now checks the selected agent
against the validated managed-image receipt and persists the explicit
agent identity. `readManagedWorkloadAuthority()` consumes this field
during rebuild and restore operations.
- `sandbox-registration.test.ts` covers managed OpenClaw authority, the
legacy custom-image convention, and rejection before the registry writer
runs.

## 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. Check other lines when applicable. Add every
requested justification or approval reference. -->
- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Maintainer Aaron
Erickson explicitly accepted the reviewed sensitive-path change for
admin merge on 2026-08-17 after CodeRabbit and all other feedback were
clear; CodeRabbit reported no actionable comments and the exact-head PR
Review Advisor reported zero findings.
- [x] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue: Maintainer Aaron
Erickson accepted the `CI / Pull Request / checks` non-success on
2026-08-17 because shard 6 is the unchanged Launchable
authorization-step contract on `main` (follow-up #9368/#9369), and
accepted `Images / Managed Images / PR exact all-agent managed runtime
activation` because its exact-head-only build hits the unchanged
two-argument `sandbox-messaging.ts` call already fixed on current `main`
by #9366. Neither failure overlaps this PR’s changed files or behavior.

## DGX Station Hardware Evidence
<!-- Required only when scripts/prepare-dgx-station-host.sh changes.
Maintainers must review the linked evidence before approving or merging.
This is human-reviewed evidence, not authenticated hardware provenance.
Exceptional bypasses use existing repository governance and must be
documented on the PR. -->
- [ ] Tested on DGX Station
- Tested commit:
- Station profile/scenario:
- Result:
- Supporting evidence:

## 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 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 validate:pr` passed after refreshing `origin/main` 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:
`vitest run --project cli src/lib/onboard/sandbox-registration.test.ts
--testTimeout 30000` — 18 tests passed; `vitest run --project
integration test/onboard-managed-image-buildless-e2e.test.ts
--testTimeout 30000` — 1 test passed.
- [ ] 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)
- [ ] 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 `pre-commit` and `commit-msg` hooks passed for both commits. At base
SHA `cb018f0224`, the `pre-push` CLI type check was blocked by unchanged
errors in `sandbox-messaging.ts`, `sandbox-messaging.test.ts`, and
`portable-uninstall-retirement.test.ts`. PR #9366 fixed the shared
`sandbox-messaging.ts` root cause on `main`; current-base CI at
`54cb2a414f` passed `build-typecheck` and `installer-integration`. CLI
shard 6 remains blocked by an unchanged E2E test that references the
removed `Authorize Launchable image publication` workflow step; PRs
#9368 and #9369 update that contract, so this branch does not absorb the
unrelated E2E change.

---
<!-- 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: Aaron Erickson <aerickson@nvidia.com>

---------

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
ericksoa pushed a commit that referenced this pull request Aug 18, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Add the canonical dated changelog entry required before planning the
v0.0.110 release. The entry summarizes user-facing changes merged since
v0.0.109 and links each change to its published documentation route and
source PR.

## Changes

- Add `docs/changelog/2026-08-17.mdx` with the exact `## v0.0.110`
release heading.
- Cover managed local inference, endpoint validation, onboarding and
recovery, explicit experimental Portable OpenClaw, messaging and policy
cleanup, backup and security hardening, and release qualification.
- Preserve the documentation skip list and the current supported-agent
matrix; test-only refactors, dormant activation work, and Pi-only
changes are intentionally excluded.

### Source-to-doc mapping

- #8711 -> `docs/changelog/2026-08-17.mdx`: Add the Muse Glimmer
llama.cpp profile.
- #9099 -> `docs/changelog/2026-08-17.mdx`: Update the Muse Glimmer vLLM
runtime.
- #9319 -> `docs/changelog/2026-08-17.mdx`: Select the provider required
by an explicit serving profile.
- #9311 -> `docs/changelog/2026-08-17.mdx`: Report probe-image pull
failures separately.
- #9345 -> `docs/changelog/2026-08-17.mdx`: Reuse mirrored Windows
Ollama.
- #9284 -> `docs/changelog/2026-08-17.mdx`: Complete the required Ollama
upgrade.
- #9320 -> `docs/changelog/2026-08-17.mdx`: Reject unsafe custom
endpoint URLs before mutation.
- #9119 -> `docs/changelog/2026-08-17.mdx`: Reject unsupported custom
endpoint URL components.
- #9236 -> `docs/changelog/2026-08-17.mdx`: Require native Anthropic
tool-use evidence.
- #9347 -> `docs/changelog/2026-08-17.mdx`: Distinguish Gemini runtime
404 diagnostics.
- #9307 -> `docs/changelog/2026-08-17.mdx`: Preserve the recorded API
family when only the model drifts.
- #9233 -> `docs/changelog/2026-08-17.mdx`: Fail incomplete Hermes route
synchronization.
- #9185 -> `docs/changelog/2026-08-17.mdx`: Serialize Model Router
lifecycle work across gateways.
- #9112 -> `docs/changelog/2026-08-17.mdx`: Stop Model Router after the
last routed sandbox is destroyed.
- #9229 -> `docs/changelog/2026-08-17.mdx`: Verify fresh sandbox
execution readiness.
- #9299 -> `docs/changelog/2026-08-17.mdx`: Verify a separate agent API
host forward before reporting ready.
- #9318 -> `docs/changelog/2026-08-17.mdx`: Honor explicit sandbox
recreation.
- #9325 -> `docs/changelog/2026-08-17.mdx`: Measure readiness reuse
windows from collection completion.
- #9352 -> `docs/changelog/2026-08-17.mdx`: Guide users away from the
deprecated global start command.
- #9370 -> `docs/changelog/2026-08-17.mdx`: Persist managed OpenClaw
agent identity.
- #9366 -> `docs/changelog/2026-08-17.mdx`: Pass messaging dependencies
during reused onboarding.
- #9321 -> `docs/changelog/2026-08-17.mdx`: Detect proxied connect
sessions.
- #9285 -> `docs/changelog/2026-08-17.mdx`: Run probe-only recovery when
absent authority cannot be created.
- #9282 -> `docs/changelog/2026-08-17.mdx`: Complete probe-only recovery
without platform evidence.
- #8920 -> `docs/changelog/2026-08-17.mdx`: Preserve legacy gateway
identity.
- #9198 -> `docs/changelog/2026-08-17.mdx`: Report sandbox config-read
failures.
- #9201 -> `docs/changelog/2026-08-17.mdx`: Remove only the exact Docker
orphan on destroy.
- #9176 -> `docs/changelog/2026-08-17.mdx`: Use rootless Podman for
Portable lifecycle operations.
- #9197 -> `docs/changelog/2026-08-17.mdx`: Preflight Portable CPU
delegation.
- #9289 -> `docs/changelog/2026-08-17.mdx`: Narrow Portable policy
defaults.
- #9270 -> `docs/changelog/2026-08-17.mdx`: Preserve Portable model
intent.
- #9339 -> `docs/changelog/2026-08-17.mdx`: Reconcile timed-out Portable
stop state.
- #9209 -> `docs/changelog/2026-08-17.mdx`: Clean receipt-owned Portable
Podman resources.
- #9186 -> `docs/changelog/2026-08-17.mdx`: Separate Podman activation
readiness.
- #9376 -> `docs/changelog/2026-08-17.mdx`: Settle Portable OpenClaw
pairing before readiness.
- #9296 -> `docs/changelog/2026-08-17.mdx`: Retire messaging channel
presets the host no longer configures.
- #9327 -> `docs/changelog/2026-08-17.mdx`: Drop retired channels from
reused messaging selections.
- #9306 -> `docs/changelog/2026-08-17.mdx`: Remove gateway-enforced
presets without a local record.
- #9248 -> `docs/changelog/2026-08-17.mdx`: Activate Google Chat pairing
approval.
- #9374 -> `docs/changelog/2026-08-17.mdx`: Accept schema-owned
messaging plan fields.
- #9317 -> `docs/changelog/2026-08-17.mdx`: Accept safe hard-linked
package files during backup.
- #9288 -> `docs/changelog/2026-08-17.mdx`: Remove managed CLI shims
with destroyed user data.
- #9239 -> `docs/changelog/2026-08-17.mdx`: Read voice credentials from
fixed descriptors.
- #9269 -> `docs/changelog/2026-08-17.mdx`: Accept bounded native
OpenClaw device modes.
- #9371 -> `docs/changelog/2026-08-17.mdx`: Isolate OpenClaw
startup-guard output.
- #9351 -> `docs/changelog/2026-08-17.mdx`: Restore staging Launchable
validation.
- #9350 -> `docs/changelog/2026-08-17.mdx`: Retry transient
collaborator-permission reads.
- #9353 -> `docs/changelog/2026-08-17.mdx`: Retry transient
exact-artifact downloads.
- #9226 -> `docs/changelog/2026-08-17.mdx`: Add bounded Brev readiness
diagnostics.
- #9237 -> `docs/changelog/2026-08-17.mdx`: Report same-commit E2E
reliability.
- #9232 -> `docs/changelog/2026-08-17.mdx`: Execute native-runtime
qualification.
- #9275 -> `docs/changelog/2026-08-17.mdx`: Define E2E selection and
retry guidance.
- #9234 -> `docs/changelog/2026-08-17.mdx`: Move documentation review
after merge.
- #9365 -> `docs/changelog/2026-08-17.mdx`: Mount documentation reviewer
inputs before startup.

## 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 — justification:
`test/changelog-docs.test.ts` validates the dated release-entry
contract.
- [ ] Tests 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:

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable; documentation-only change.
- Station profile/scenario: Not applicable.
- Result: Not applicable.
- Supporting evidence: Not applicable.

## 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 validate:pr` passed after refreshing `origin/main` 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` (7 passed)
- [x] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: Not applicable to one
prose-only changelog page; `npm run docs` passed the repository's strict
documentation gate.
- [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) — passed
with 0 errors and the 2 existing Fern 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 SPDX header is present; dated changelog pages intentionally do not
use frontmatter.

---
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>


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

## Summary by CodeRabbit

* **Documentation**
  * Added release notes for v0.0.110.
* Documented experimental managed llama.cpp and Portable OpenClaw
profiles.
* Covered inference validation, onboarding and recovery improvements,
rootless lifecycle handling, messaging and policy updates, backups,
credential handling, filesystem protections, and release qualification
updates.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
ericksoa added a commit that referenced this pull request Aug 18, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 plain sentences: what changes and why. Describe
before-and-after behavior when it applies. Follow the NemoClaw Writing
Guide: https://github.com/NVIDIA/NemoClaw/blob/main/WRITING.md. Do not
add unrelated prose cleanup. -->
Managed OpenClaw sandbox registration now stores `agent: "openclaw"`
when a validated managed-image receipt owns the sandbox. Legacy and
custom-image registrations keep `agent: null`. A mismatch between the
receipt and selected agent fails before the registry write.

## Related Issue
<!-- Fixes #NNN or Closes #NNN. Remove this section if none. -->
Fixes #9356

## 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. -->
- `buildCreatedSandboxRegistryEntry()` now checks the selected agent
against the validated managed-image receipt and persists the explicit
agent identity. `readManagedWorkloadAuthority()` consumes this field
during rebuild and restore operations.
- `sandbox-registration.test.ts` covers managed OpenClaw authority, the
legacy custom-image convention, and rejection before the registry writer
runs.

## 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. Check other lines when applicable. Add every
requested justification or approval reference. -->
- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Maintainer Aaron
Erickson explicitly accepted the reviewed sensitive-path change for
admin merge on 2026-08-17 after CodeRabbit and all other feedback were
clear; CodeRabbit reported no actionable comments and the exact-head PR
Review Advisor reported zero findings.
- [x] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue: Maintainer Aaron
Erickson accepted the `CI / Pull Request / checks` non-success on
2026-08-17 because shard 6 is the unchanged Launchable
authorization-step contract on `main` (follow-up #9368/#9369), and
accepted `Images / Managed Images / PR exact all-agent managed runtime
activation` because its exact-head-only build hits the unchanged
two-argument `sandbox-messaging.ts` call already fixed on current `main`
by #9366. Neither failure overlaps this PR’s changed files or behavior.

## DGX Station Hardware Evidence
<!-- Required only when scripts/prepare-dgx-station-host.sh changes.
Maintainers must review the linked evidence before approving or merging.
This is human-reviewed evidence, not authenticated hardware provenance.
Exceptional bypasses use existing repository governance and must be
documented on the PR. -->
- [ ] Tested on DGX Station
- Tested commit:
- Station profile/scenario:
- Result:
- Supporting evidence:

## 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 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 validate:pr` passed after refreshing `origin/main` 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:
`vitest run --project cli src/lib/onboard/sandbox-registration.test.ts
--testTimeout 30000` — 18 tests passed; `vitest run --project
integration test/onboard-managed-image-buildless-e2e.test.ts
--testTimeout 30000` — 1 test passed.
- [ ] 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)
- [ ] 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 `pre-commit` and `commit-msg` hooks passed for both commits. At base
SHA `cb018f0224`, the `pre-push` CLI type check was blocked by unchanged
errors in `sandbox-messaging.ts`, `sandbox-messaging.test.ts`, and
`portable-uninstall-retirement.test.ts`. PR #9366 fixed the shared
`sandbox-messaging.ts` root cause on `main`; current-base CI at
`54cb2a414f` passed `build-typecheck` and `installer-integration`. CLI
shard 6 remains blocked by an unchanged E2E test that references the
removed `Authorize Launchable image publication` workflow step; PRs
#9368 and #9369 update that contract, so this branch does not absorb the
unrelated E2E change.

---
<!-- 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: Aaron Erickson <aerickson@nvidia.com>

---------

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
(cherry picked from commit 9f2a0f5)
ericksoa added a commit that referenced this pull request Aug 18, 2026
<!-- markdownlint-disable MD041 -->
## Summary
<!-- 1-3 plain sentences: what changes and why. Describe
before-and-after behavior when it applies. Follow the NemoClaw Writing
Guide: https://github.com/NVIDIA/NemoClaw/blob/main/WRITING.md. Do not
add unrelated prose cleanup. -->
Managed Docker Hermes sandboxes previously reached runtime validation
without a durable `/sandbox/.hermes` mount. Onboarding now provisions
and reuses one NemoClaw-owned named volume, passes it through the
supported Docker driver config, and removes it only when ownership is
exact.

## Related Issue
<!-- Fixes #NNN or Closes #NNN. Remove this section if none. -->
Fixes #9358

## 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. -->
- Add a managed Hermes state-volume lifecycle for the Docker
runtime-provider path. The provider requires a durable writable
`/sandbox/.hermes` mount; OpenShell consumes a pre-existing named volume
but does not own its creation or deletion, so the lifecycle creates,
verifies, reuses, and failure-cleans the exact labeled volume.
`hermes-state-volume.test.ts` protects creation, incomplete-create
cleanup, rebuild reuse, ownership refusal, and deletion.
- Materialize the owned volume as a writable Docker `volume` mount and
reject overlapping user host mounts. A direct host bind is insufficient
because rebuild and restore must retain NemoClaw-owned state.
`sandbox-create-plan.test.ts` protects the emitted driver config and
conflict refusal.
- Remove the volume after confirmed sandbox deletion and before retiring
the registry record, preserving retry authority when cleanup fails.
`destroy-flow.test.ts` protects deletion ordering and failure retention.

## 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. Check other lines when applicable. Add every
requested justification or approval reference. -->
- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests 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:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## DGX Station Hardware Evidence
<!-- Required only when scripts/prepare-dgx-station-host.sh changes.
Maintainers must review the linked evidence before approving or merging.
This is human-reviewed evidence, not authenticated hardware provenance.
Exceptional bypasses use existing repository governance and must be
documented on the PR. -->
- [ ] Tested on DGX Station
- Tested commit:
- Station profile/scenario:
- Result:
- Supporting evidence:

## 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 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 validate:pr` passed after refreshing `origin/main` 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: 106
assertions passed across the managed volume, caller orchestration,
driver-plan, destroy-flow, shared mount-overlap, Podman replacement, and
buildless managed-image E2E suites.
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result: `npm test` initially
stopped on the base #9359 compile regression; with the exact now-merged
#9366 repair applied only for qualification, compilation passed and the
suite then hit unrelated local-state and timeout failures. PR CI is
required.
- [ ] 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)
- [ ] 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: Aaron Erickson <aerickson@nvidia.com>


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

* **New Features**
* Added managed state-volume support for eligible Docker-based
sandboxes, including creation, validation, mounting, reuse, and cleanup.
* Added safeguards preventing host mounts from overlapping the managed
state directory.
* Improved onboarding failure diagnostics with container state and
redacted log details.

* **Bug Fixes**
* Sandbox deletion now removes its managed state volume while preserving
registry state if cleanup fails.
  * Foreign or unowned volumes remain untouched.
* Improved validation of mount paths and durable managed-state
filesystem boundaries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: messaging Messaging channels, bridges, manifests, or channel lifecycle area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

build: recorded messaging reconciliation omits required dependencies

4 participants