Scope clarification
The original filing incorrectly described the linked NemoClaw GitHub Actions job as using “Docker process/network sidecars.” NemoClaw uses OpenShell’s standard Docker driver with one openshell-sandbox process in the default combined network,process mode. The process-only sidecar watcher described below is not exercised by that topology, so the NemoClaw run is not reproduction evidence for this issue and is being investigated separately.
This issue is scoped to the independently reproduced Kubernetes split-sidecar defect documented in the k3d reproduction.
User Story
As a sandbox operator using the Kubernetes split-sidecar topology, I want a fresh process execution to receive the latest valid provider environment after policy or provider changes, so credential binding converges without recreating the sandbox.
Problem Statement
The process-side control watcher can ignore a distinct provider-environment snapshot. provider_env_revision is derived from a SHA-256 digest and represented as a u64, but the watcher treats the value as a monotonically increasing counter and skips any update whose numeric value is less than or equal to the installed value.
A valid new snapshot whose digest-derived value is numerically lower is therefore never installed for child processes. The network-side desired state advances while fresh executions on the process side retain stale environment state.
Impact / Why This Matters
In Kubernetes split-sidecar mode, attaching or removing an endpoint-bound static provider credential may not converge for fresh sandbox executions. Whether the stale state appears on binding or unbinding depends on the opaque fingerprints’ numeric ordering.
A sandbox restart or recreation can mask the defect, but that is not a safe convergence contract. Repeating no-op provider updates is not a deterministic workaround.
Acceptance Criteria
- The process-side control watcher installs every genuinely newer provider-environment snapshot even when its opaque fingerprint is numerically lower than the currently installed fingerprint.
- An exact duplicate snapshot remains a no-op.
- Ordering or replay safety is explicit: a delayed stale snapshot cannot replace newer desired state.
- A regression test starts with a numerically high current fingerprint, delivers a distinct valid snapshot with a lower fingerprint, and verifies that subsequent child execution receives the new environment.
- A replay test verifies that an older desired-state generation is not reinstalled after a newer one.
- The Kubernetes split-sidecar path is covered.
- An integration or E2E test covers an initially endpointless provider through unbound → bound → unbound transitions and verifies that fresh execs receive the expected environment state without sandbox recreation.
Validated Reproduction
John Myers reproduced the defect through the public CLI on Docker-backed k3d using the Kubernetes sidecar overlay:
- OpenShell checkout:
b2ea81822
- Reported version:
0.0.111-dev.6+gb2ea81822
- Docker Desktop:
29.6.2, ARM64
- Cluster: local k3d
- Supervisor topology: Kubernetes
sidecar via ci/values-sidecar.yaml
- Sidecar overlay:
processBinaryAwareNetworkPolicy: false
Observed transition:
| State |
Network-side desired environment |
Fresh process result |
| Initial unbound |
0 entries |
ABSENT |
| Bound |
revision 17142220022187618806, 1 entry |
PRESENT |
| Unbound again |
revision 7844884057133558206, 0 entries |
PRESENT — stale |
The newer unbound fingerprint is numerically lower than the prior bound fingerprint. The network supervisor installed it, but the process-side state did not converge.
Full commands, redacted observations, and cleanup steps are in the reproduction comment.
Source Diagnosis
In v0.0.106, the server computes provider_env_revision from SHA-256 content (domain openshell-provider-env-revision-v3), so its numeric value has no ordering semantics:
https://github.com/NVIDIA/OpenShell/blob/c4b500a7de64d0b66e3ee8098f58d14299092162/crates/openshell-server/src/grpc/policy.rs
The process-only sidecar watcher nevertheless rejects revision <= provider_credentials.snapshot().revision:
https://github.com/NVIDIA/OpenShell/blob/c4b500a7de64d0b66e3ee8098f58d14299092162/crates/openshell-sandbox/src/lib.rs
The correct design keeps the revision as an opaque content fingerprint and uses a separate monotonic delivery generation, or an equivalently tested transport-order contract, for replay safety.
Related issues checked for duplication: #2777, #1731, and #2518. They cover credential refresh lifecycle, pushed desired state, and policy hashing, but not this digest-order suppression in the process sidecar.
Scope clarification
The original filing incorrectly described the linked NemoClaw GitHub Actions job as using “Docker process/network sidecars.” NemoClaw uses OpenShell’s standard Docker driver with one
openshell-sandboxprocess in the default combinednetwork,processmode. The process-only sidecar watcher described below is not exercised by that topology, so the NemoClaw run is not reproduction evidence for this issue and is being investigated separately.This issue is scoped to the independently reproduced Kubernetes split-sidecar defect documented in the k3d reproduction.
User Story
As a sandbox operator using the Kubernetes split-sidecar topology, I want a fresh process execution to receive the latest valid provider environment after policy or provider changes, so credential binding converges without recreating the sandbox.
Problem Statement
The process-side control watcher can ignore a distinct provider-environment snapshot.
provider_env_revisionis derived from a SHA-256 digest and represented as au64, but the watcher treats the value as a monotonically increasing counter and skips any update whose numeric value is less than or equal to the installed value.A valid new snapshot whose digest-derived value is numerically lower is therefore never installed for child processes. The network-side desired state advances while fresh executions on the process side retain stale environment state.
Impact / Why This Matters
In Kubernetes split-sidecar mode, attaching or removing an endpoint-bound static provider credential may not converge for fresh sandbox executions. Whether the stale state appears on binding or unbinding depends on the opaque fingerprints’ numeric ordering.
A sandbox restart or recreation can mask the defect, but that is not a safe convergence contract. Repeating no-op provider updates is not a deterministic workaround.
Acceptance Criteria
Validated Reproduction
John Myers reproduced the defect through the public CLI on Docker-backed k3d using the Kubernetes sidecar overlay:
b2ea818220.0.111-dev.6+gb2ea8182229.6.2, ARM64sidecarviaci/values-sidecar.yamlprocessBinaryAwareNetworkPolicy: falseObserved transition:
ABSENT17142220022187618806, 1 entryPRESENT7844884057133558206, 0 entriesPRESENT— staleThe newer unbound fingerprint is numerically lower than the prior bound fingerprint. The network supervisor installed it, but the process-side state did not converge.
Full commands, redacted observations, and cleanup steps are in the reproduction comment.
Source Diagnosis
In v0.0.106, the server computes
provider_env_revisionfrom SHA-256 content (domainopenshell-provider-env-revision-v3), so its numeric value has no ordering semantics:https://github.com/NVIDIA/OpenShell/blob/c4b500a7de64d0b66e3ee8098f58d14299092162/crates/openshell-server/src/grpc/policy.rs
The process-only sidecar watcher nevertheless rejects
revision <= provider_credentials.snapshot().revision:https://github.com/NVIDIA/OpenShell/blob/c4b500a7de64d0b66e3ee8098f58d14299092162/crates/openshell-sandbox/src/lib.rs
The correct design keeps the revision as an opaque content fingerprint and uses a separate monotonic delivery generation, or an equivalently tested transport-order contract, for replay safety.
Related issues checked for duplication: #2777, #1731, and #2518. They cover credential refresh lifecycle, pushed desired state, and policy hashing, but not this digest-order suppression in the process sidecar.