Skip to content

fix(e2e): repair protected managed-image qualification - #8762

Merged
cv merged 4 commits into
mainfrom
fix/protected-managed-image-harness
Aug 10, 2026
Merged

fix(e2e): repair protected managed-image qualification#8762
cv merged 4 commits into
mainfrom
fix/protected-managed-image-harness

Conversation

@ericksoa

@ericksoa ericksoa commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Repairs the trusted protected managed-image qualification after it failed before candidate launch because required onboarding operations were not exported. Cleanup now uses the existing state-scoped gateway ownership boundary, recognizes exited zombie processes, and retains runtime evidence whenever cleanup cannot be proven complete.

Related Issue

Fixes #8759.
Part of #7744.

Changes

  • Export and validate the OpenShell operations consumed by the protected managed-image harness, with a precise missing-operation error and exact dynamic-import coverage.
  • Replace bare PID cleanup with the existing scoped gateway cleanup owner, including PID file, runtime marker, UID, namespace, command, gateway name, and port checks before signaling.
  • Treat zombie states as exited and process-status errors as unknown so cleanup fails closed without signaling or deleting ownership evidence.
  • Remove harness state only after both scoped process cleanup and gateway removal succeed.
  • Update downstream process-status fixtures and add negative coverage for identity drift, denied signals, unreadable status, invalid status, and evidence retention.

Type of Change

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

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: this changes an internal trusted qualification harness and cleanup implementation; no command, flag, default, configuration, API, policy schema, or supported workflow changes.
  • 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: an independent Codex Desktop security reviewer evaluated exact head 5ee4160e5 across all nine repository security categories and returned PASS; scoped ownership, fail-closed status handling, runtime module validation, and evidence retention were explicitly verified.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: no-docs-needed
  • Evidence: No documentation paths changed; the repair is limited to the internal trusted qualification harness and gateway cleanup.
  • Agent: Codex Desktop

DGX Station Hardware Evidence

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

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 — 106/106 focused tests passed across the protected contract, gateway cleanup, uninstall, and destroy-cleanup suites; npm run typecheck:cli, npm run checks:repository, and npm run test:e2e-phases:check passed.
  • Applicable broad gate passed — not claimed locally. npm run test:changed -- --maxWorkers=1 passed 134/137 files and 1,674/1,689 non-skipped tests; the three failing files reproduced on exact current base f817ad609 because two uninstall fixtures reached this Mac's ambient Homebrew trust check and one command test timed out only under suite load. The command test passed 7/7 alone, and a detached-base comparison reproduced the uninstall failures unchanged.
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Signed-off-by: Aaron Erickson aerickson@nvidia.com

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@ericksoa ericksoa self-assigned this Aug 10, 2026
@github-code-quality

github-code-quality Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in commit 5ee4160 in the fix/protected-manage... branch remains at 96%, unchanged from commit 430406f in the main branch.

TypeScript / code-coverage/cli

The overall coverage in commit 5ee4160 in the fix/protected-manage... branch remains at 82%, unchanged from commit 430406f in the main branch.

Show a code coverage summary of the most impacted files.
File main 430406f fix/protected-manage... 5ee4160 +/-
src/lib/sandbox...rce-identity.ts 86% 86% 0%
src/lib/onboard...eway-process.ts 88% 90% +2%

Updated August 10, 2026 22:05 UTC

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The changes use ps stat= to classify host-gateway processes. Scoped cleanup fails closed for unknown or unverifiable processes. Managed-image cleanup preserves state evidence unless gateway stopping and removal succeed. Required onboarding exports are added.

Changes

Gateway cleanup hardening

Layer / File(s) Summary
Process-state classification and scoped stopping
src/lib/onboard/host-gateway-process.ts, src/lib/onboard/host-gateway-process*.test.ts, src/lib/actions/*/run-plan.test.ts, src/lib/actions/sandbox/destroy-gateway-runtime-evidence.test.ts
Gateway liveness checks use ps stat=. Zombie processes are treated as stopped. Unknown states block scoped cleanup and signaling. Tests cover polling, stale PIDs, command failures, invalid states, and denied signals.
Managed-image state cleanup and onboarding exports
scripts/checks/run-managed-image-openshell-e2e.ts, src/lib/onboard.ts, test/managed-image-protected-runtime-contract.test.ts
Managed-image cleanup uses scoped gateway stopping and removes state only after successful stopping and gateway removal. Failed cleanup preserves evidence. runOpenshell and sleepSeconds are exported. Contract tests cover module validation and cleanup behavior.

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

Sequence Diagram(s)

sequenceDiagram
  participant ManagedImageE2E
  participant stopHostGatewayProcesses
  participant GatewayRemoval
  participant StateDirectory
  ManagedImageE2E->>stopHostGatewayProcesses: stop scoped OpenShell gateway
  stopHostGatewayProcesses-->>ManagedImageE2E: return stop and ownership status
  ManagedImageE2E->>GatewayRemoval: remove gateway
  GatewayRemoval-->>ManagedImageE2E: return status 0 or failure
  ManagedImageE2E->>StateDirectory: remove state only after successful checks
Loading

Possibly related issues

  • NVIDIA/NemoClaw issue 8759 — The PR addresses the missing runOpenshell export, dynamic module validation, and managed-gateway cleanup failures.

Possibly related PRs

  • NVIDIA/NemoClaw#8523 — Both changes modify managed-runtime/OpenShell compatibility and runtime contract behavior.
  • NVIDIA/NemoClaw#8583 — Both changes modify OpenShell onboarding exports and gateway lifecycle handling.
  • NVIDIA/NemoClaw#8763 — This PR extends the related managed-image module validation and gateway cleanup behavior.

Suggested labels: area: sandbox, bug-fix, security

Suggested reviewers: cv, apurvvkumaria, jyaunches

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: repairing protected managed-image qualification in the E2E harness.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/protected-managed-image-harness

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

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
@github-actions

github-actions Bot commented Aug 10, 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 · 0 warnings · 0 suggestions
  • Model comparison: normalized findings match; normalized terminology decisions differ; normalized E2E selections differ; severity counts match.
5 terminology differences from the second opinion

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

  • resolveManagedImageOnboardModule at scripts/checks/run-managed-image-openshell-e2e.ts:154: selected only by the second-opinion lane as define.
  • managed-image onboard module at scripts/checks/run-managed-image-openshell-e2e.ts:170: selected only by the second-opinion lane as define.
  • removeManagedImageGatewayStateIfSafe at scripts/checks/run-managed-image-openshell-e2e.ts:279: selected only by the second-opinion lane as define.
  • HostGatewayProcessStatus at src/lib/onboard/host-gateway-process.ts:183: selected only by the second-opinion lane as define.
  • process status cannot be proven at src/lib/onboard/host-gateway-process.ts:506: selected only by the second-opinion lane as define.
2 additional E2E selections from the second opinion

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

  • gpu-e2e: The completed second-opinion lane identified E2E coverage that the primary lane omitted.
  • full-e2e: 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.

3 semantic terminology decisions

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

  • established — ownership evidence at scripts/checks/run-managed-image-openshell-e2e.ts:1102: Keep `ownership evidence` for records that establish gateway ownership.
  • justified — ownership evidence at src/lib/onboard/host-gateway-process-target.test.ts:240: Use `scoped ownership evidence` when the selected gateway distinction is required.
  • define — process status at src/lib/onboard/host-gateway-process.ts:506: Define `process status` near its first user-facing or test-facing use when this classification is referenced outside the implementation.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite against this exact revision.

Recommended E2E: managed-image-multiarch-startup, managed-image-protected-runtime, onboard-repair, onboard-resume, cloud-onboard

Workflow run details

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

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@scripts/checks/run-managed-image-openshell-e2e.ts`:
- Around line 146-175: Make REQUIRED_ONBOARD_OPERATIONS an exported canonical
tuple from resolveManagedImageOnboardModule’s module, and update
test/managed-image-protected-runtime-contract.test.ts to import it and derive
its validation loop rather than duplicating the five keys. Add a namespace-only
fixture to exercise the resolver’s importRecord/default branch, while retaining
coverage for valid imports and missing operations without introducing false
positives.
🪄 Autofix

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: 58d28cf6-3fcf-4143-9953-9d8060a536a4

📥 Commits

Reviewing files that changed from the base of the PR and between 6072934 and 5ee4160.

📒 Files selected for processing (2)
  • scripts/checks/run-managed-image-openshell-e2e.ts
  • test/managed-image-protected-runtime-contract.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/managed-image-protected-runtime-contract.test.ts

Comment on lines +146 to +175
const REQUIRED_ONBOARD_OPERATIONS = [
"openshellArgv",
"runOpenshell",
"runCaptureOpenshell",
"sleepSeconds",
"startGatewayForRecovery",
] as const satisfies readonly (keyof OnboardModule)[];

export function resolveManagedImageOnboardModule(onboardImport: unknown): OnboardModule {
const importRecord =
typeof onboardImport === "object" && onboardImport !== null
? (onboardImport as Record<string, unknown>)
: null;
const candidate =
importRecord && "default" in importRecord ? importRecord.default : onboardImport;
const candidateRecord =
typeof candidate === "object" && candidate !== null
? (candidate as Record<string, unknown>)
: null;
const missing = REQUIRED_ONBOARD_OPERATIONS.filter(
(operation) => typeof candidateRecord?.[operation] !== "function",
);
if (missing.length > 0) {
throw new Error(
`managed-image onboard module is missing required operation(s): ${missing.join(", ")}`,
);
}
return candidate as OnboardModule;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Make the onboarding contract inventory canonical.

REQUIRED_ONBOARD_OPERATIONS duplicates the OnboardModule keys and the five-operation list in test/managed-image-protected-runtime-contract.test.ts. A change to only one list can make the runtime guard and tests disagree. Export the tuple and derive the test loop from it. Add a namespace-only fixture because the current tests cover the real import and a missing operation under default, but not the namespace branch. (raw.githubusercontent.com)

As per path instructions, “Derive inventories and limits from a canonical source where possible; flag duplicated lists that can silently drift” and “Require focused tests for both detection and false-positive behavior.”

🤖 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 `@scripts/checks/run-managed-image-openshell-e2e.ts` around lines 146 - 175,
Make REQUIRED_ONBOARD_OPERATIONS an exported canonical tuple from
resolveManagedImageOnboardModule’s module, and update
test/managed-image-protected-runtime-contract.test.ts to import it and derive
its validation loop rather than duplicating the five keys. Add a namespace-only
fixture to exercise the resolver’s importRecord/default branch, while retaining
coverage for valid imports and missing operations without introducing false
positives.

Source: Path instructions

@cv
cv merged commit 567a033 into main Aug 10, 2026
93 of 97 checks passed
@cv
cv deleted the fix/protected-managed-image-harness branch August 10, 2026 22:19
jyaunches added a commit that referenced this pull request Aug 11, 2026
<!-- markdownlint-disable MD041 -->
## Summary

This PR updates the August 10, 2026 v0.0.106 release entry with gateway
readiness fixes that merged after PR #8756.
PRs #8765, #8767, and #8768 remain outside this entry because they are
open and do not carry the `v0.0.106` release label.

## Changes

- Document acceptance of OpenShell v0.0.101 `Server:` endpoint output
and target-bound process tags when trusted listener evidence matches the
configured gateway.
- Document preservation of selected-gateway stale state so onboarding
can reconcile a registered gateway when a gateway-scoped OpenShell
status check cannot connect.
- Record evidence-backed exclusions for internal image, startup,
qualification, proxy-environment, CI, and test-harness changes in PRs
#8754, #8609, #8762, #8432, #8766, and #8581.
- Exclude PRs #8765, #8767, and #8768 because their changes are absent
from `main` and the PRs do not carry the `v0.0.106` release label.
The release entry must be updated after any of those PRs merges for
v0.0.106.

## 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 dated changelog SPDX placement,
version headings, forbidden terms, and link form.
- [ ] Tests not applicable — justification:
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Documentation Writer Review

- [x] Documentation writer subagent reviewed the completed changes
- Result: `docs-updated`
- Evidence: `docs/changelog/2026-08-10.mdx`; an independent Codex
Desktop subagent reviewed the writing rules and documentation style,
terminology, structure, voice, code-sample presentation, links, source
and test accuracy, release meaning, product scope, and evidence-backed
exclusions at commit `190bf882c`.
- Agent: Codex Desktop
<!-- docs-review-head-sha: 190bf88 -->
<!-- docs-review-agents-blob-sha: c4923a3 -->

## DGX Station Hardware Evidence

- [ ] Tested on DGX Station
- Tested commit: Not applicable; `scripts/prepare-dgx-station-host.sh`
is unchanged.
- 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 — command/result or justification: `npx
vitest run test/changelog-docs.test.ts` passed 6 tests.
- [ ] 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 a
documentation-only release-entry update.
- [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) —
result: passed with 0 errors and 2 existing 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)
— no page was added.

---
Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>


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

## Summary by CodeRabbit

* **Bug Fixes**
* Improved gateway readiness detection for OpenShell v0.0.101 endpoint
output.
* Process tags are now accepted only when they match trusted listener
information for the configured gateway.
* Preserved stale gateway status during connection failures to support
accurate onboarding reconciliation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Protected managed-image runtime stops after Ollama on missing runOpenshell hook

2 participants