Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
5ea601f
feat(openshell): add external gateway status
apurvvkumaria Aug 29, 2026
a37b42d
fix(openshell): repair runner package checks
apurvvkumaria Aug 30, 2026
3621714
merge: resolve conflicts with main
github-actions[bot] Aug 30, 2026
81c82f5
test(openshell): lock runner package fixture
apurvvkumaria Aug 30, 2026
cb3c067
test(openshell): stabilize runner qualification
apurvvkumaria Aug 30, 2026
323b9be
merge(main): refresh #9872 candidate
apurvvkumaria Aug 31, 2026
094b2db
fix(blueprint): close external health review gaps
apurvvkumaria Aug 31, 2026
5a4f641
fix(e2e): fail closed external health qualification
apurvvkumaria Aug 31, 2026
9d04da2
merge(main): refresh #9872 before qualification
apurvvkumaria Aug 31, 2026
f5b57e1
fix(blueprint): align external target boundaries
apurvvkumaria Aug 31, 2026
ba61734
docs(schema): describe external target status
apurvvkumaria Aug 31, 2026
5e3707a
merge(main): refresh external target status
apurvvkumaria Aug 31, 2026
1434ed2
merge(main): refresh external target status
apurvvkumaria Aug 31, 2026
259d474
test(blueprint): replace external status shape checks
apurvvkumaria Aug 31, 2026
b70d242
docs(blueprint): document external gateway status
apurvvkumaria Aug 31, 2026
74edab1
merge(main): refresh external target status
apurvvkumaria Aug 31, 2026
53ab70b
docs(blueprint): clarify external gateway safety
apurvvkumaria Aug 31, 2026
0af779b
test(e2e): cover packaged blueprint runner
apurvvkumaria Aug 31, 2026
b766a2d
merge(main): refresh external target status
apurvvkumaria Aug 31, 2026
fe87d15
merge(main): refresh external target status
apurvvkumaria Aug 31, 2026
fdc218c
merge(main): refresh external target status
apurvvkumaria Aug 31, 2026
051333d
test(blueprint): remove redundant deadline assertion
apurvvkumaria Aug 31, 2026
c3328ba
merge(main): restore compiled CI inputs
apurvvkumaria Aug 31, 2026
ce7bff8
test(blueprint): require missing health credential
apurvvkumaria Aug 31, 2026
43d9a8b
merge(main): refresh trusted review workflow
apurvvkumaria Aug 31, 2026
1796ea6
fix(blueprint): avoid credentials during public health
apurvvkumaria Aug 31, 2026
61a7906
fix(blueprint): align credential-free status contract
apurvvkumaria Aug 31, 2026
24f96d4
test(schema): remove wording-only assertion
apurvvkumaria Sep 1, 2026
2dec43b
docs(openshell): clarify status recovery
apurvvkumaria Sep 1, 2026
b8f63bb
merge(main): refresh review advisor base
apurvvkumaria Sep 1, 2026
16d2db8
merge(main): refresh repaired advisor base
apurvvkumaria Sep 1, 2026
656a043
merge(main): refresh final advisor base
apurvvkumaria Sep 1, 2026
e3bced5
merge(main): refresh repaired e2e base
apurvvkumaria Sep 1, 2026
abed18e
docs(openshell): clarify public health path
apurvvkumaria Sep 1, 2026
5897d16
fix(openshell): address advisor findings
cv Sep 1, 2026
1cdac43
refactor(openshell): narrow gateway health ownership
apurvvkumaria Sep 1, 2026
548ef5f
merge(review): reconcile verified advisor fixes
apurvvkumaria Sep 1, 2026
b1ae72e
docs(openshell): cite external target trust decision
cv Sep 1, 2026
dcd34b9
fix(openshell): complete advisor repairs
cv Sep 1, 2026
0587cd5
chore: apply review repair formatting
cv Sep 1, 2026
ed46fb3
test(openshell): keep package contracts deterministic
cv Sep 1, 2026
482f75e
fix(openshell): complete validation before effects
cv Sep 1, 2026
d623c3d
fix(e2e): clarify artifact presence check
cv Sep 1, 2026
dd138be
fix(e2e): verify external target modules
cv Sep 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/actions/ci-build-typecheck/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ runs:

- name: Verify compiled package contracts
shell: bash
env:
NPM_CONFIG_CACHE: ${{ runner.temp }}/npm
run: npx vitest run --project package-contract

- name: Typecheck CLI + tests
Expand Down
17 changes: 15 additions & 2 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -770,11 +770,18 @@ jobs:
{ echo "::error::checked-out commit does not match the artifact candidate SHA"; exit 1; }
[[ "$RUN_ATTEMPT" =~ ^[1-9][0-9]*$ && "$RUN_ID" =~ ^[1-9][0-9]*$ ]] ||
{ echo "::error::workflow run identity is invalid"; exit 1; }
for required_file in dist/nemoclaw.js dist/build-identity.json; do
for required_file in \
dist/nemoclaw.js \
dist/build-identity.json \
dist/lib/blueprint-runner.js \
dist/nemoclaw/package.json \
dist/nemoclaw/blueprint/runner.js; do
[[ -f "$required_file" && ! -L "$required_file" && -s "$required_file" ]] ||
{ echo "::error::candidate CLI build output is missing or is not a nonempty regular file: $required_file"; exit 1; }
done
for boundary in \
openshell-gateway-health-sdk.js \
openshell-observation-boundary.cjs \
openshell-policy-boundary.cjs \
sandbox-name.cjs \
snapshot-sanitizer-boundary.cjs; do
Expand All @@ -790,6 +797,12 @@ jobs:
.sourceRevision == $candidateSha
' dist/build-identity.json >/dev/null ||
{ echo "::error::candidate CLI build identity does not match the candidate commit SHA"; exit 1; }
jq -e '
type == "object" and
(keys | sort) == ["type"] and
.type == "module"
' dist/nemoclaw/package.json >/dev/null ||
{ echo "::error::candidate Blueprint Runner module boundary is invalid"; exit 1; }

# BEGIN exact managed-image catalog staging
managed_catalog="${RUNNER_TEMP}/pr-managed-image-catalog.json"
Expand Down Expand Up @@ -3400,7 +3413,7 @@ jobs:
E2E_DEFAULT_ENABLED: "0"
E2E_TARGET_ID: "external-gateway-health"
E2E_AGENT_RUNTIME: "none"
E2E_OBSERVABLE_OUTCOME: "The reviewed SDK observes exact public gateway health over explicit HTTPS and CA"
E2E_OBSERVABLE_OUTCOME: "The exact Blueprint Runner observes public gateway health over explicit HTTPS and CA"
E2E_ENVIRONMENT_OR_INFERENCE_ENDPOINT: "Ubuntu host with OpenShell 0.0.106; no inference endpoint"
E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/live/external-gateway-health
NEMOCLAW_RUN_LIVE_E2E: "1"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
__pycache__/
coverage/
dist/
nemoclaw/runner-dist/
artifacts/pr-review-advisor-local/
docs/_build/
node_modules/
Expand Down
2 changes: 1 addition & 1 deletion ci/source-architecture-budget.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"src/lib/messaging/channels/index.ts": 25,
"src/lib/onboard/gateway-binding.ts": 53,
"src/lib/runner.ts": 85,
"src/lib/security/redact.ts": 54,
"src/lib/security/redact.ts": 55,
"src/lib/state/onboard-session.ts": 36,
"src/lib/state/mcp-lifecycle-lock.ts": 21,
"src/lib/state/registry.ts": 100,
Expand Down
5 changes: 5 additions & 0 deletions ci/source-shape-test-budget.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@
"test": "provides the package token only to trusted main dependency installation",
"category": "security"
},
{
"file": "test/automation/pull-requests/pr-workflow-contract.test.ts",
"test": "reuses the trusted dependency cache for offline package contracts",
"category": "security"
},
{
"file": "test/automation/pull-requests/pr-workflow-contract.test.ts",
"test": "passes only the base-packaged SDK archive to pull request dependency jobs",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -->
<!-- SPDX-License-Identifier: Apache-2.0 -->

# OpenShell TypeScript SDK 0.0.106 dependency review

> Internal engineering evidence. This file is not part of the public documentation set.

## Status and scope

Issue #9872 permits `@nvidia/openshell-sdk@0.0.106` for one bounded public gateway-health call.
The slice reads no machine credential and makes no authenticated or mutating call.

This review applies only to the exact source, package, and runtime graph below.
It does not qualify a Runner image or approve machine authentication.

## Source and package identity

| Evidence | Reviewed value |
| --- | --- |
| OpenShell tag | `v0.0.106` |
| Source commit | `c4b500a7de64d0b66e3ee8098f58d14299092162` |
| Package | `@nvidia/openshell-sdk@0.0.106` |
| Registry | GitHub Packages |
| Package version ID | `1134230109` |
| Package SHA-512 integrity | `sha512-dB4mLex23Pnw61caGMR2CMHQihy9bj7IK2elJJd718k3yevm+fOt/vG6dJg8/5us4la2BwcOdRwLvOia3tdwFw==` |
| Observed package SHA-256 | `30ae4c4749a610cc6e9b22067ece61f6137ba858acf5102c23cb81c37c4cc3fb` |
| Producer run | `31809093046`, attempt 2, job `94864069197` |

The registry metadata and the OpenShell tag identify the same source commit.
The package has no registry signature or provenance attestation.
The root package lock binds the exact registry URL and SHA-512 integrity.
A later SDK version requires a new dependency review.

## Selected runtime graph

| Package | Version | Declared license |
| --- | --- | --- |
| `@nvidia/openshell-sdk` | `0.0.106` | Apache-2.0 |
| `@bufbuild/protobuf` | `2.12.1` | Apache-2.0 AND BSD-3-Clause |
| `@connectrpc/connect` | `2.1.2` | Apache-2.0 |
| `@connectrpc/connect-node` | `2.1.2` | Apache-2.0 |

The root manifest records all four packages as exact optional dependencies.
The package lock pins each version and package integrity for source installs.
None of these packages defines an install lifecycle script.

## API and security contract

NemoClaw uses `OpenShellClient.connect({ gateway, caCert })` from the official SDK. It calls the
SDK-documented `client.raw.health()` operation over the shared transport created and owned by that
client. NemoClaw does not import ConnectRPC, create a generated client, or create an HTTP/2 session.

The health adapter:

- Accepts only the validated HTTPS endpoint and CA.
- Gives the endpoint and a copy of the CA bytes to the official SDK without an authentication token,
client certificate, client key, or insecure TLS option.
- Retains the SDK's normal TLS certificate and hostname verification.
- Starts one five-second deadline before local SDK loading and bounds adapter return through SDK
client creation and public health.
- Passes that same deadline signal to the SDK health operation.
- Passes no token, client certificate, client key, CLI state, or insecure TLS option.
- Replaces SDK import and transport details with fixed messages.
- Uses no direct transport or fallback.

The SDK does not expose a DNS lookup hook or transport close handle. It uses the platform resolver
when the explicit endpoint contains a hostname. The configured CA and TLS hostname check still
authenticate the remote endpoint, but NemoClaw cannot pin one DNS answer set through this SDK API.
Under the accepted initial contract, cluster and storage administrators are trusted infrastructure
actors, and this operation sends only unauthenticated public health. A later change that sends a
credential or accepts a broader trust model must revisit DNS rebinding and transport ownership.

The SDK client is lazy.
Public health is the first network request.
Identity, workspace inventory, provider inventory, authentication, and mutation remain outside this slice.

## Installation and redistribution

The root NemoClaw package records the SDK and its three runtime dependencies as exact optional dependencies.
Installations that do not use external gateway status can omit private-registry access.
The root package exposes the Blueprint Runner executable.
The OpenClaw plugin package and lock do not contain the SDK.
The reviewed package workflow from PR #10368 supplies exact SDK bytes to untrusted CI without package credentials.

If the runtime omits the SDK or exposes an incompatible client, external gateway status returns a fixed package-unavailable error before a network request.
The result exposes no import detail and starts no fallback.

The SDK and its three runtime dependency archives omit license and notice files.
Before a Runner image distributes this graph, the image release must include the applicable Apache-2.0 and BSD-3-Clause license texts.
The image software bill of materials and third-party notice must bind to the installed graph.

## Concern records

### DEP-1: Package substitution

- Severity and confidence: high, high confidence.
- Failure mode: another package or transitive version executes in the Runner.
- Control: pin the SDK and each runtime dependency exactly in the published root manifest, and pin each package URL and integrity in the source lock.
- Verification: compiled package installation and Runner package-contract tests.

### DEP-2: Package credential exposure

- Severity and confidence: high, high confidence.
- Failure mode: candidate code or an unreviewed dependency receives the package credential.
- Control: use the reviewed base-controlled package workflow from PR #10368.
- Verification: workflow and integration tests owned by that merged change.

### DEP-3: Optional dependency absence or initialization failure

- Severity and confidence: medium, high confidence.
- Failure mode: package failure looks like a gateway outage, or import detail reaches output.
- Control: validate the official SDK client export and generated service-status enum before network
access, then return a fixed package-unavailable error.
- Verification: focused adapter tests and the compiled package contract.

### DEP-4: DNS rebinding or local-target substitution

- Severity and confidence: high, high confidence.
- Failure mode: a validated hostname resolves or rebinds to a local service when the request starts.
- Control: the official SDK retains TLS certificate and hostname verification against the explicit
CA, and the slice sends only unauthenticated public health. The accepted initial contract treats
platform infrastructure administrators as trusted.
- Residual: SDK 0.0.106 does not expose a pinned lookup. A hostname can resolve differently between
validation and connection, including to a local address. TLS identity verification prevents an
unrelated local service from impersonating the configured gateway, but it does not prevent the
connection attempt.
- Verification: wrong-CA and wrong-hostname package tests; independent security review must keep
this residual visible.

### DEP-5: Transport outlives the bounded observation

- Severity and confidence: high, high confidence.
- Failure mode: request cancellation returns, but the HTTP/2 session keeps the Runner process alive.
- Control: pass the one total deadline signal to the official SDK health operation and retain the
bounded Kubernetes Job deadline as the outer control. A late local SDK import cannot start a
network request because health begins only after the bounded load returns.
- Residual: SDK 0.0.106 exposes no transport close handle.
- Verification: adapter deadline tests and a packaged Runner test against a stalled TLS peer prove
that the Runner returns and the process exits within the package boundary.

### DEP-6: Redistribution evidence

- Severity and confidence: medium, high confidence.
- Failure mode: a Runner image omits license evidence or claims unavailable provenance.
- Control: bind the image software bill of materials and license inventory to the installed graph.
- Verification: future Runner image release evidence.

## Remaining gates

- The feature must pass focused, package, type, build, and repository checks on its final commit.
- The final security review must explicitly assess the SDK's standard DNS resolution and lack of a
transport close handle; this review does not claim address pinning or session ownership.
- The future Runner image must prove the exact SDK runtime identity, software bill of materials, and license inventory.
- A separate accepted decision must define machine authentication before credential reads or authenticated calls start.
Loading
Loading