test(e2e): remove schema parity campaign (#3864)

Signed-off-by: Evan Lezar <elezar@nvidia.com>
This commit is contained in:
Evan Lezar
2026-10-01 13:17:20 +00:00
committed by GitHub
parent fde79f1aa6
commit 0e8d9e55f9
36 changed files with 138 additions and 7317 deletions
@@ -215,8 +215,8 @@ compatibility under emulation is not part of these tasks. The aggregate
commands above on an ARM64 host.
The repository-wide `mise run pre-commit` task is also supported on Windows.
Run `rust:lockfiles:check`, `sdk:ts:ci`, `go:ci`, and `test:e2e-parity` through
the Windows-aware tasks when validating those surfaces. Do not count the Go
Run `rust:lockfiles:check`, `sdk:ts:ci`, and `go:ci` through the Windows-aware
tasks when validating those surfaces. Do not count the Go
Windows ARM64 race-detector exclusion or POSIX permission-bit skips as security
coverage. SDK test dependencies must remain at their lockfile versions.
Its Rust check, Clippy, and test dependencies enter the same MSVC environment
+1 -1
View File
@@ -36,7 +36,7 @@ These pipelines connect skills into end-to-end workflows. Individual skill files
|------|-----------|---------|
| `crates/openshell-cli/` | CLI binary | User-facing command-line interface |
| `crates/openshell-conformance/` | CLI conformance library | Reusable driver-agnostic scenarios and command runner |
| `crates/openshell-conformance-cli/` | Conformance CLI | Distributable `list` and `run` entrypoint for gateway conformance |
| `crates/openshell-conformance-cli/` | Conformance CLI | Legacy local `list` and `run` entrypoint pending follow-up cleanup |
| `crates/openshell-server/` | Gateway server | Control-plane API, sandbox lifecycle, auth boundary |
| `crates/openshell-sandbox/` | Sandbox runtime | Capability-free workload launcher, process identity, and seccomp-mediated I/O |
| `crates/openshell-supervisor/` | Supervisor runtime | Gateway session, policy evaluation, credentials, and upstream networking |
+5 -2
View File
@@ -52,8 +52,7 @@ Rust validation checks tracked Cargo lockfiles; run `mise run rust:lockfiles:che
Use `mise run --skip-tools pre-commit` with the existing Rust/MSVC toolchain.
Windows now checks tracked Cargo lockfiles through PowerShell rather than
skipping them. The deterministic gateway parity task uses Git for Windows Bash,
with temporary Python launchers confined to a unique checkout-owned directory.
skipping them.
`mise run --skip-tools sdk:ts:ci` selects the x64 Biome executable on Windows
(including ARM64 hosts running it under emulation), resolves the protobuf
@@ -104,6 +103,10 @@ OPENSHELL_GATEWAY_ENDPOINT=http://127.0.0.1:18080 mise run e2e
Raw endpoint mode is HTTP-only. Use a named gateway config when a gateway
requires mTLS.
`mise run test:gateway-config` validates generated gateway TOML without a live
runtime. It covers the current schema and the Podman in-tree versus external
driver configuration boundary.
### Python E2E (`e2e/python/`)
`mise run e2e:python` builds `openshell/e2e-python:dev` from
-6
View File
@@ -367,12 +367,6 @@ fn podman_config(
if let Ok(path) = std::env::var("OPENSHELL_PODMAN_SOCKET") {
config.socket_path = Some(path.into());
}
if let Ok(ip) = std::env::var("OPENSHELL_PODMAN_HOST_GATEWAY_IP") {
config.host_gateway_ip = ip;
}
if let Ok(mode) = std::env::var("OPENSHELL_PODMAN_USERNS") {
config.userns = Some(mode);
}
Ok(config)
}
@@ -1,400 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Inventory for the schema-v2 live capability-parity campaign. Every entry is a
# test case contract, not a result. `status = "not_run"` deliberately means no
# live assertion has been made. Keep the oracle observable and put the runtime
# prerequisites in `required_environment`; this lets later waves select a lane
# without rediscovering the migration's intended behavior.
manifest_version = 1
baseline_ref = "origin/main"
baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
baseline_schema_version = 1
candidate_ref = "HEAD"
candidate_commit = "8c868e430e9cd3284d7e274628419ab484ebcee0"
candidate_schema_version = 2
# Allowed lane names: deterministic, e2e-docker, e2e-podman, e2e-kubernetes,
# e2e-vm, windows-mxc, extension-driver, auth-oidc, observability, packaging.
# Allowed statuses: not_run, blocked, planned. A live pass is intentionally not
# a status in this first-wave manifest.
[[capabilities]]
id = "configuration-source-precedence"
topics = ["configuration_producers"]
origin_main_access_paths = ["--config", "OPENSHELL_GATEWAY_CONFIG", "CLI > OPENSHELL_* > [openshell.gateway] > defaults"]
schema_v2_access_paths = ["--config", "OPENSHELL_GATEWAY_CONFIG", "CLI > OPENSHELL_* > [openshell.gateway] > defaults"]
behavioral_oracle = "A CLI or environment value wins over the corresponding file value; an unset value uses the file value."
required_environment = "none; parse and startup-config construction only"
test_lane = "deterministic"
status = "not_run"
[[capabilities]]
id = "schema-version-and-strict-layout"
topics = ["configuration_producers"]
origin_main_access_paths = ["[openshell] version = 1", "[openshell.gateway] inherited driver defaults"]
schema_v2_access_paths = ["[openshell] version = 2", "[openshell.gateway] gateway-only fields", "[openshell.drivers.<name>] driver-owned fields"]
behavioral_oracle = "Missing, v1, future, unknown gateway, misplaced selected-driver, unknown selected-driver, and non-table driver values fail before runtime construction; unselected driver tables are validated when selected."
required_environment = "none; TOML parser only"
test_lane = "deterministic"
status = "not_run"
[[capabilities]]
id = "gateway-identity-and-logging"
topics = ["configuration_producers", "observability"]
origin_main_access_paths = ["--name / OPENSHELL_GATEWAY_NAME", "--log-level / OPENSHELL_LOG_LEVEL", "[openshell.gateway].name", "[openshell.gateway].log_level"]
schema_v2_access_paths = ["[openshell.gateway].name", "[openshell.gateway].log_level", "same CLI and environment variables"]
behavioral_oracle = "The configured name and log filter are retained after v2 file merge and identify emitted gateway telemetry."
required_environment = "gateway process with captured logs"
test_lane = "observability"
status = "not_run"
[[capabilities]]
id = "primary-health-and-metrics-listeners"
topics = ["listeners"]
origin_main_access_paths = ["--bind-address / OPENSHELL_BIND_ADDRESS", "--port / OPENSHELL_SERVER_PORT", "--health-port / OPENSHELL_HEALTH_PORT", "--metrics-port / OPENSHELL_METRICS_PORT", "[openshell.gateway].{bind_address,health_bind_address,metrics_bind_address}"]
schema_v2_access_paths = ["[openshell.gateway].bind_address", "[openshell.gateway].health_bind_address", "[openshell.gateway].metrics_bind_address", "same CLI and environment variables"]
behavioral_oracle = "The primary multiplexed endpoint and optional health/metrics endpoints bind their configured addresses; a zero auxiliary port disables only that auxiliary listener."
required_environment = "loopback TCP ports"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "database-url-and-persistence-backends"
topics = ["database"]
origin_main_access_paths = ["--db-url / OPENSHELL_DB_URL", "[openshell.gateway].database_url (rejected)"]
schema_v2_access_paths = ["--db-url / OPENSHELL_DB_URL only", "[openshell.gateway].database_url (rejected)"]
behavioral_oracle = "A SQLite or Postgres URL supplied outside TOML opens the store; a URL embedded in TOML is rejected without exposing credentials."
required_environment = "SQLite temporary directory; Postgres service for backend variant"
test_lane = "deterministic"
status = "not_run"
[[capabilities]]
id = "ssh-rate-limit-and-policy-posture"
topics = ["listeners"]
origin_main_access_paths = ["[openshell.gateway].ssh_session_ttl_secs", "[openshell.gateway].grpc_rate_limit_{requests,window_seconds}", "[openshell.gateway].policy_validation_failure_mode"]
schema_v2_access_paths = ["same [openshell.gateway] fields"]
behavioral_oracle = "SSH TTL, paired rate-limit behavior, and fail_closed versus retain_last_valid policy posture survive migration with their documented validation rules."
required_environment = "gateway with a controllable clock and policy fixture"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "sandbox-service-routing"
topics = ["listeners"]
origin_main_access_paths = ["--server-san / OPENSHELL_SERVER_SAN", "--enable-loopback-service-http / OPENSHELL_ENABLE_LOOPBACK_SERVICE_HTTP", "[openshell.gateway].{server_sans,enable_loopback_service_http}"]
schema_v2_access_paths = ["[openshell.gateway].server_sans", "[openshell.gateway].enable_loopback_service_http", "same CLI and environment variables"]
behavioral_oracle = "Wildcard SAN routing and loopback-only plaintext sandbox-service HTTP remain available while gateway APIs stay unavailable on that plaintext route."
required_environment = "TLS certificate with sandbox wildcard SAN and loopback HTTP client"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "gateway-listener-tls-and-sni"
topics = ["auth_tls_jwt", "listeners"]
origin_main_access_paths = ["--tls-cert / OPENSHELL_TLS_CERT", "--tls-key / OPENSHELL_TLS_KEY", "--tls-client-ca / OPENSHELL_TLS_CLIENT_CA", "[openshell.gateway.tls]"]
schema_v2_access_paths = ["[openshell.gateway.tls].{cert_path,key_path,client_ca_path,external_cert_path,external_key_path,external_server_names}", "same CLI and environment variables for primary bundle"]
behavioral_oracle = "The listener presents the primary or configured SNI certificate, rejects the unsupported require_client_auth file field, and rejects incomplete server TLS bundles. The frozen baseline derives client-certificate requirements from client CA and OIDC presence; the candidate permits bearer-only connections and validates any presented client certificate against the configured CA."
required_environment = "test CA, primary and external certificates, TLS client"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "plaintext-listener-mode"
topics = ["auth_tls_jwt", "listeners"]
origin_main_access_paths = ["--disable-tls / OPENSHELL_DISABLE_TLS", "[openshell.gateway].disable_tls"]
schema_v2_access_paths = ["[openshell.gateway].disable_tls", "same CLI and environment variable"]
behavioral_oracle = "An explicit plaintext listener starts without a listener TLS table and is usable behind a trusted TLS-terminating proxy."
required_environment = "loopback HTTP client"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "guest-callback-tls-ownership"
topics = ["auth_tls_jwt", "docker", "podman", "vm"]
origin_main_access_paths = ["[openshell.gateway].{guest_tls_ca,guest_tls_cert,guest_tls_key} inherited by local drivers", "driver-local guest_tls_* overrides"]
schema_v2_access_paths = ["[openshell.gateway].guest_tls_ca injected only into selected Docker, Podman, or VM driver", "driver tables reject guest_tls_*"]
behavioral_oracle = "A TLS-enabled selected local driver receives the gateway CA and authenticates callbacks with its sandbox bearer credential; legacy client certificate fields, misplaced TLS fields, and plaintext-incompatible CA settings fail closed."
required_environment = "test CA and sandbox bearer credential; client certificate bundle for the frozen baseline"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "oidc-bearer-authentication"
topics = ["auth_tls_jwt"]
origin_main_access_paths = ["--oidc-* / OPENSHELL_OIDC_*", "[openshell.gateway.oidc].{issuer,audience,jwks_ttl_secs,roles_claim,admin_role,user_role,scopes_claim}"]
schema_v2_access_paths = ["same [openshell.gateway.oidc] fields", "same CLI and environment variables"]
behavioral_oracle = "A token from the configured issuer is accepted only with the expected audience, role, and optional scope; invalid JWTs are rejected."
required_environment = "OIDC issuer with JWKS and signed test tokens"
test_lane = "auth-oidc"
status = "not_run"
[[capabilities]]
id = "mtls-user-authentication"
topics = ["auth_tls_jwt"]
origin_main_access_paths = ["--enable-mtls-auth / OPENSHELL_ENABLE_MTLS_AUTH", "[openshell.gateway.mtls_auth].enabled"]
schema_v2_access_paths = ["[openshell.gateway.mtls_auth].enabled", "same CLI and environment variable"]
behavioral_oracle = "A verified client certificate maps to a user principal only when mTLS user auth is enabled and no stronger auth policy replaces it. The candidate defaults mTLS user auth on when a client CA is configured without OIDC, independently of the compute driver."
required_environment = "local driver, test CA, client certificate"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "unsafe-unauthenticated-user-mode"
topics = ["auth_tls_jwt"]
origin_main_access_paths = ["[openshell.gateway.auth].allow_unauthenticated_users"]
schema_v2_access_paths = ["same [openshell.gateway.auth].allow_unauthenticated_users"]
behavioral_oracle = "The explicit trusted-development switch admits user requests without a credential while sandbox callbacks retain sandbox authentication."
required_environment = "isolated gateway with no public exposure"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "gateway-minted-sandbox-jwt"
topics = ["auth_tls_jwt"]
origin_main_access_paths = ["[openshell.gateway.gateway_jwt].{signing_key_path,public_key_path,kid_path,gateway_id,ttl_secs}"]
schema_v2_access_paths = ["same [openshell.gateway.gateway_jwt] fields"]
behavioral_oracle = "The gateway mints sandbox and extension tokens with the configured identity, key ID, audience, and positive or omitted TTL semantics; explicit zero is rejected."
required_environment = "Ed25519 keypair and sandbox callback fixture"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "otlp-observability"
topics = ["observability"]
origin_main_access_paths = ["[openshell.gateway.otlp].{endpoint,service_name}", "OTEL_* SDK tuning environment"]
schema_v2_access_paths = ["same [openshell.gateway.otlp] fields", "same OTEL_* tuning environment"]
behavioral_oracle = "A configured OTLP/gRPC collector receives gateway and in-tree driver traces with gateway name and selected-driver resource attributes; collector failure does not prevent serving."
required_environment = "loopback OTLP/gRPC collector"
test_lane = "observability"
status = "not_run"
[[capabilities]]
id = "gateway-interceptor-registration"
topics = ["interceptors", "auth_tls_jwt"]
origin_main_access_paths = ["[[openshell.gateway.interceptors]] including endpoint, TLS CA, audience, ordering, failure, timeout, limits, binding policy, and bindings"]
schema_v2_access_paths = ["same [[openshell.gateway.interceptors]] table and [[openshell.gateway.interceptors.bindings]]"]
behavioral_oracle = "Startup validates Describe metadata and configured binding policy; an allowed interceptor observes or modifies only its selected non-secret unary RPC phases."
required_environment = "test interceptor gRPC service; optional private CA or Unix socket"
test_lane = "extension-driver"
status = "not_run"
[[capabilities]]
id = "supervisor-middleware-registration"
topics = ["middleware", "auth_tls_jwt"]
origin_main_access_paths = ["[[openshell.supervisor.middleware]] including endpoint, TLS CA, audience, payload limit, timeout, and insecure transport"]
schema_v2_access_paths = ["same [[openshell.supervisor.middleware]] table"]
behavioral_oracle = "Gateway startup validates middleware Describe and policy configuration, applies payload/time limits, and distributes only validated registration data to supervisors."
required_environment = "test supervisor middleware gRPC service and sandbox supervisor"
test_lane = "extension-driver"
status = "not_run"
[[capabilities]]
id = "provider-profile-sources"
topics = ["inference", "interceptors"]
origin_main_access_paths = ["[openshell.gateway].provider_profile_sources"]
schema_v2_access_paths = ["same [openshell.gateway].provider_profile_sources"]
behavioral_oracle = "Configured builtin, user, and interceptor sources form one ordered validated catalog; duplicate normalized profile IDs or invalid interceptor source selections fail closed."
required_environment = "provider records and profile-capable interceptor fixture"
test_lane = "extension-driver"
status = "not_run"
[[capabilities]]
id = "inference-control-plane-configuration"
topics = ["inference"]
origin_main_access_paths = ["OpenShell inference configuration RPCs and persisted gateway settings; not a startup TOML field"]
schema_v2_access_paths = ["unchanged OpenShell inference configuration RPCs and persisted gateway settings; not a startup TOML field"]
behavioral_oracle = "A provider and route configured through the control plane resolves the same effective inference bundle after a schema-v2 gateway starts."
required_environment = "gateway, provider fixture, and sandbox supervisor"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "credential-driver-selection-and-kek"
topics = ["credentials"]
origin_main_access_paths = ["[openshell.gateway].credential_drivers", "[openshell.gateway].default_credential_driver", "[openshell.gateway.credential_storage]"]
schema_v2_access_paths = ["same [openshell.gateway] fields"]
behavioral_oracle = "Omission selects encrypted database storage; an explicit empty or multi-driver selection fails, and KEK path/environment configuration preserves credential confidentiality."
required_environment = "temporary gateway database and KEK fixture"
test_lane = "deterministic"
status = "not_run"
[[capabilities]]
id = "credential-driver-backend-tables"
topics = ["credentials", "external_drivers"]
origin_main_access_paths = ["[openshell.credential_drivers.kubernetes-secrets]", "[openshell.credential_drivers.vault]", "[openshell.credential_drivers.<external>]"]
schema_v2_access_paths = ["same credential-driver tables, including in_tree or uds transport, socket_path, command, args, and startup_timeout_secs"]
behavioral_oracle = "Built-in and remote credential driver tables validate their transport contract and store/retrieve opaque credential material without inline secrets in TOML."
required_environment = "credential-driver mock over UDS; Kubernetes or Vault for backend variants"
test_lane = "extension-driver"
status = "not_run"
[[capabilities]]
id = "docker-image-and-callback-configuration"
topics = ["docker"]
origin_main_access_paths = ["[openshell.gateway].{default_image,supervisor_image,host_gateway_ip} inherited by Docker", "[openshell.drivers.docker].{socket_path,default_image,image_pull_policy,sandbox_namespace,grpc_endpoint,supervisor_bin,supervisor_image,network_name,host_gateway_ip,ssh_socket_path}"]
schema_v2_access_paths = ["[openshell.drivers.docker].{socket_path,default_image,image_pull_policy,sandbox_label,grpc_endpoint,supervisor_bin,supervisor_image,network_name,host_gateway_ip,ssh_socket_path}"]
behavioral_oracle = "Docker starts a sandbox using its driver table, maps the canonical sandbox label, honors image policy, and derives or honors a callback endpoint."
required_environment = "Linux Docker daemon, bridge network, sandbox and supervisor images"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "docker-security-and-provider-configuration"
topics = ["docker", "credentials"]
origin_main_access_paths = ["[openshell.drivers.docker].{sandbox_pids_limit,enable_bind_mounts}", "no origin/main Docker equivalent for proxy, SPIFFE, or AppArmor configuration"]
schema_v2_access_paths = ["[openshell.drivers.docker].{sandbox_pids_limit,enable_bind_mounts,https_proxy,no_proxy,proxy_auth_file,proxy_auth_allow_insecure,proxy_connect_by_hostname,provider_spiffe_workload_api_socket,app_armor_profile}"]
behavioral_oracle = "Docker preserves PID and bind-mount behavior while schema v2 adds fail-closed proxy, SPIFFE, and AppArmor configuration whose material is mounted only into the supervisor."
required_environment = "Linux Docker daemon, proxy fixture, optional SPIFFE Unix socket and AppArmor support"
test_lane = "e2e-docker"
status = "not_run"
[[capabilities]]
id = "podman-image-and-callback-configuration"
topics = ["podman"]
origin_main_access_paths = ["[openshell.gateway].{default_image,supervisor_image,host_gateway_ip} inherited by Podman", "[openshell.drivers.podman].{socket_path,default_image,image_pull_policy,grpc_endpoint,gateway_port,network_name,host_gateway_ip,stop_timeout_secs,supervisor_image}"]
schema_v2_access_paths = ["same [openshell.drivers.podman] fields; gateway_port is runtime-derived"]
behavioral_oracle = "Podman starts a sandbox with its selected socket, image and policy, derives the callback route, and applies stop timeout without v1 gateway inheritance."
required_environment = "Podman service socket, user bridge network, sandbox and supervisor images"
test_lane = "e2e-podman"
status = "not_run"
[[capabilities]]
id = "podman-runtime-security-and-health"
topics = ["podman", "credentials"]
origin_main_access_paths = ["[openshell.drivers.podman].{sandbox_ssh_socket_path,sandbox_pids_limit,enable_bind_mounts,provider_spiffe_workload_api_socket,app_armor_profile,health_check_interval_secs,https_proxy,no_proxy,proxy_auth_file,proxy_auth_allow_insecure,proxy_connect_by_hostname,proxy_ca_bundle,userns,uidmap,gidmap}"]
schema_v2_access_paths = ["[openshell.drivers.podman].{ssh_socket_path,sandbox_pids_limit,enable_bind_mounts,provider_spiffe_workload_api_socket,app_armor_profile,health_check_interval_secs,https_proxy,no_proxy,proxy_auth_file,proxy_auth_allow_insecure,proxy_connect_by_hostname,proxy_ca_bundle,userns,uidmap,gidmap}"]
behavioral_oracle = "Podman uses the renamed SSH path and validates PID, health, user namespace mappings, AppArmor, proxy, CA, and SPIFFE contracts before a sandbox can run."
required_environment = "Podman service socket, optional proxy/CA/SPIFFE fixture, rootless and rootful variants"
test_lane = "e2e-podman"
status = "not_run"
[[capabilities]]
id = "kubernetes-core-placement-and-images"
topics = ["kubernetes"]
origin_main_access_paths = ["[openshell.gateway].{default_image,supervisor_image,client_tls_secret_name,service_account_name,host_gateway_ip,enable_user_namespaces,sa_token_ttl_secs} inherited by Kubernetes", "[openshell.drivers.kubernetes].{namespace,default_image,image_pull_policy,image_pull_secrets,service_account_name,supervisor_image,supervisor_image_pull_policy,grpc_endpoint,ssh_socket_path,client_tls_secret_name,host_gateway_ip,enable_user_namespaces,sa_token_ttl_secs}"]
schema_v2_access_paths = ["same fields exclusively in [openshell.drivers.kubernetes]"]
behavioral_oracle = "The Kubernetes driver applies driver-owned namespace, service account, image, pull policy, callback endpoint, SSH socket, TLS Secret, and token TTL settings. The candidate projects only the gateway CA from the TLS Secret into the separate supervisor Pod and authenticates gateway RPCs with a sandbox bearer credential."
required_environment = "Kubernetes cluster, namespace, service account, image pull secret, and client TLS Secret"
test_lane = "e2e-kubernetes"
status = "not_run"
[[capabilities]]
id = "kubernetes-workspace-isolation"
topics = ["kubernetes"]
origin_main_access_paths = ["[openshell.drivers.kubernetes].{workspace_mode,gateway_id,operator_namespace_label,operator_namespace_file,workspace_default_storage_size,workspace_storage_class,default_runtime_class_name}"]
schema_v2_access_paths = ["same [openshell.drivers.kubernetes] fields"]
behavioral_oracle = "Shared, managed, and operator workspace modes select or create the expected namespace and workspace storage with configured discovery, class, and runtime class."
required_environment = "Kubernetes cluster with namespaces, PVC provisioning, and optional RuntimeClass"
test_lane = "e2e-kubernetes"
status = "not_run"
[[capabilities]]
id = "kubernetes-supervisor-topology"
topics = ["kubernetes", "middleware"]
origin_main_access_paths = ["[openshell.drivers.kubernetes].{supervisor_sideload_method,topology}", "[openshell.drivers.kubernetes.sidecar].{proxy_uid,process_binary_aware_network_policy}", "[openshell.drivers.kubernetes.managed_ssh_ingress].{enabled,gateway_namespace,gateway_pod_selector}"]
schema_v2_access_paths = ["same Kubernetes driver subtables and fields"]
behavioral_oracle = "The rendered sandbox Pod matches the selected combined or sidecar supervisor topology, sideload method, ingress selector, and sidecar security posture."
required_environment = "Kubernetes cluster supporting selected image-volume or init-container method"
test_lane = "e2e-kubernetes"
status = "not_run"
[[capabilities]]
id = "kubernetes-egress-spiffe-and-security"
topics = ["kubernetes", "credentials"]
origin_main_access_paths = ["[openshell.drivers.kubernetes].{https_proxy,no_proxy,proxy_auth_secret_name,proxy_auth_secret_key,proxy_auth_allow_insecure,proxy_connect_by_hostname,app_armor_profile,provider_spiffe_workload_api_socket_path,sandbox_uid,sandbox_gid}"]
schema_v2_access_paths = ["same [openshell.drivers.kubernetes] fields"]
behavioral_oracle = "Kubernetes validates proxy/Secret and sidecar-topology relationships, projects SPIFFE only from an allowed path, and applies valid non-root identity and AppArmor settings."
required_environment = "Kubernetes cluster, proxy credential Secret, optional SPIFFE socket, AppArmor-capable node"
test_lane = "e2e-kubernetes"
status = "not_run"
[[capabilities]]
id = "vm-launch-and-resource-configuration"
topics = ["vm"]
origin_main_access_paths = ["[openshell.gateway].{default_image,guest_tls_ca,guest_tls_cert,guest_tls_key} inherited by VM", "[openshell.drivers.vm].{grpc_endpoint,state_dir,driver_dir,default_image,bootstrap_image,krun_log_level,vcpus,mem_mib,overlay_disk_mib,sandbox_uid,sandbox_gid}", "standalone openshell-driver-vm --openshell-endpoint / OPENSHELL_GRPC_ENDPOINT"]
schema_v2_access_paths = ["[openshell.drivers.vm].{grpc_endpoint,state_dir,driver_dir,default_image,bootstrap_image,krun_log_level,vcpus,mem_mib,overlay_disk_mib,sandbox_uid,sandbox_gid}", "[openshell.gateway].guest_tls_ca", "standalone openshell-driver-vm --grpc-endpoint / OPENSHELL_GRPC_ENDPOINT"]
behavioral_oracle = "The gateway finds and launches the VM driver from driver_dir, forwards the TOML grpc_endpoint through the schema-appropriate standalone-driver flag, and launches a guest with the selected state, images, resources, and identity."
required_environment = "Linux libkrun/KVM host, VM driver binary, and OCI image"
test_lane = "e2e-vm"
status = "not_run"
[[capabilities]]
id = "vm-guest-security-and-spiffe"
topics = ["vm", "credentials"]
origin_main_access_paths = ["[openshell.drivers.vm].{sandbox_uid,sandbox_gid}"]
schema_v2_access_paths = ["[openshell.drivers.vm].{sandbox_uid,sandbox_gid,https_proxy,no_proxy,proxy_auth_file,proxy_auth_allow_insecure,proxy_connect_by_hostname,provider_spiffe_workload_api_tcp_endpoint,provider_spiffe_allow_guest_tcp}", "gateway-owned guest_tls_ca"]
behavioral_oracle = "VM validates non-root guest ownership, callback TLS, proxy safety, and requires an explicit opt-in before exposing a guest-reachable SPIFFE TCP endpoint."
required_environment = "Linux libkrun/KVM host, TLS and optional proxy/SPIFFE TCP fixture"
test_lane = "e2e-vm"
status = "not_run"
[[capabilities]]
id = "mxc-windows-driver-configuration"
topics = ["mxc"]
origin_main_access_paths = ["[openshell.drivers.mxc].{wxc_exec_path,backend,pc_least_privilege,pc_capabilities,default_configuration_id,debug}"]
schema_v2_access_paths = ["same [openshell.drivers.mxc] fields"]
behavioral_oracle = "The Windows gateway selects MXC and passes the configured wxc-exec path, backend, AppContainer capabilities, isolation configuration, and debug flag to MXC."
required_environment = "Windows host with MXC/wxc-exec; mock fixture for deterministic smoke variant"
test_lane = "windows-mxc"
status = "not_run"
[[capabilities]]
id = "external-compute-driver-socket"
topics = ["external_drivers"]
origin_main_access_paths = ["--drivers / --driver / OPENSHELL_DRIVERS plus --compute-driver-socket / OPENSHELL_COMPUTE_DRIVER_SOCKET", "[openshell.drivers.<name>] remote socket table"]
schema_v2_access_paths = ["--compute-driver / OPENSHELL_COMPUTE_DRIVER plus --compute-driver-socket / OPENSHELL_COMPUTE_DRIVER_SOCKET", "[openshell.drivers.<name>].socket_path"]
behavioral_oracle = "A selected non-reserved external driver connects through its configured Unix socket; legacy plural selector flags are rejected, while one OPENSHELL_DRIVERS environment value remains a deprecated upgrade alias when it does not conflict with canonical selection."
required_environment = "external compute-driver gRPC fixture over Unix socket"
test_lane = "extension-driver"
status = "not_run"
[[capabilities]]
id = "helm-configuration-producer"
topics = ["configuration_producers", "kubernetes"]
origin_main_access_paths = ["Helm rendered schema-v1 gateway TOML and environment-backed overrides"]
schema_v2_access_paths = ["deploy/helm/openshell/templates/gateway-config.yaml renders [openshell] version = 2 and Kubernetes driver table", "Secret-backed OPENSHELL_DB_URL and certificate inputs"]
behavioral_oracle = "helm template renders schema-v2 TOML, derives the Kubernetes callback endpoint, and keeps database and secret material outside the ConfigMap."
required_environment = "Helm and chart test plugin; Kubernetes cluster only for live install variant"
test_lane = "deterministic"
status = "not_run"
[[capabilities]]
id = "local-launch-script-producers"
topics = ["configuration_producers", "docker", "podman", "vm", "kubernetes"]
origin_main_access_paths = ["tasks/scripts/gateway{,-docker,-podman,-vm}.sh generated schema-v1 TOML"]
schema_v2_access_paths = ["tasks/scripts/gateway{,-docker,-podman,-vm}.sh generated schema-v2 TOML with per-driver tables"]
behavioral_oracle = "Each local launch script emits parseable v2 TOML with a scalar driver and its canonical driver-owned values before it executes the gateway binary."
required_environment = "shell, uv, and fake gateway executable; no runtime daemon required"
test_lane = "deterministic"
status = "not_run"
[[capabilities]]
id = "e2e-fixture-producers"
topics = ["configuration_producers", "docker", "podman"]
origin_main_access_paths = ["e2e/configs/gateway/docker.toml and podman.toml schema-v1 fixtures"]
schema_v2_access_paths = ["e2e/configs/gateway/docker.toml and podman.toml schema-v2 fixtures"]
behavioral_oracle = "Docker and Podman E2E fixtures parse as v2, select one scalar driver, and contain canonical renamed policy and callback fields."
required_environment = "none; TOML parser only"
test_lane = "deterministic"
status = "not_run"
[[capabilities]]
id = "rpm-schema-upgrade"
topics = ["packaging_upgrades", "configuration_producers"]
origin_main_access_paths = ["deploy/rpm/gateway.toml.default version 1", "systemd user config seeded from package default"]
schema_v2_access_paths = ["deploy/rpm/gateway.toml.default version 2", "deploy/rpm/migrate-gateway-config.sh exact-v1 replacement"]
behavioral_oracle = "RPM first start seeds the v2 default and upgrade replaces only an exact package-generated v1 file, preserving edited files, modes, and symlink safety."
required_environment = "temporary filesystem and shell; RPM install test host for package variant"
test_lane = "packaging"
status = "not_run"
[[capabilities]]
id = "homebrew-debian-and-snap-upgrades"
topics = ["packaging_upgrades"]
origin_main_access_paths = ["Homebrew prefix config and migration helper", "Debian XDG user-service config", "Snap $SNAP_COMMON/gateway.toml"]
schema_v2_access_paths = ["package-managed schema-v2 defaults and documented exact-v1/manual migration paths"]
behavioral_oracle = "Each package resolves its documented config location, starts from v2 defaults, and never overwrites operator-edited legacy configuration during upgrade."
required_environment = "macOS Homebrew, Debian/Ubuntu user-service, and Snap test environments"
test_lane = "packaging"
status = "not_run"
@@ -1,376 +0,0 @@
{
"manifest_version": 2,
"baseline_commit": "74960ebfaeec4673885089ed995fad902459749f",
"candidate_commit": "4a39da510e4d278a24dd60291149519c9a570b46",
"lane": "local-linux-x86_64-rootless-podman-5.8.2",
"retained_evidence_bundles": {
"in_tree": "target/parity/step10-intree-4a39da51",
"external_uds": "target/parity/step10-external-4a39da51"
},
"oracle": {
"status": true,
"create": true,
"ready": true,
"list_visible": true,
"callback_exec_exact_marker": true,
"delete": true,
"list_empty": true
},
"in_tree": {
"baseline": {
"schema_version": 1,
"source_sha": "74960ebfaeec4673885089ed995fad902459749f",
"gateway_profile": "in-tree",
"gateway_cargo_features": "default",
"artifact_origins": {
"gateway": "built_by_harness",
"cli": "built_by_harness",
"conformance": "built_by_harness",
"external_driver": "not_applicable",
"supervisor": "built_by_harness"
},
"artifact_sha256": {
"gateway": "264cf3d809bd1d54633bce9251ec1a5540b567b8150640091df85bdfbe61797a",
"cli": "3ad0ec143bf6850af780bf643c303242956d6ef1066d4a9372bc62fef33ada20",
"conformance": "d669f960333f9bcd777f4fac92e5208fa66d1b51578838e5aba9b1f58bc8dc6e",
"supervisor": "ae2e854936a15a5b952187fd4488a746a8a6e31e9f919967e3ead7a80d4b1077",
"supervisor.Dockerfile": "ec8b25f0a674c0c7ae123c978f6857436af987faea43051e67d3a8d4b52831cd",
"cli-trace-wrapper": "0691d47d9eae7e9fe847a58994e170a480c0e61d1d9013193d6ca9c93476777f",
"supervisor.packages.txt": "6966057ffaf1ef0d4617d413dad53646bcd049a4b08f572796392fb0ffbb01b9"
},
"launch_attestation": {
"schema_version": 1,
"gateway_port": 32893,
"external_compute_driver": false,
"compute_driver_transport": "in_tree",
"external_driver_pull_policy": "missing",
"supervisor_image": "localhost/openshell/supervisor:parity-baseline-74960ebfaeec",
"supervisor_image_id": "b5bcaae227a1d6ea90fd146fc2904d4166725c8eb1b9590bdfd85b14c7b9caef",
"supervisor_image_digest": "sha256:0f11b6ca65ff33c99d03d6ebd8af239ac9edc148f849201a692a06d722853030",
"supervisor_runtime_image": "localhost/openshell/supervisor@sha256:0f11b6ca65ff33c99d03d6ebd8af239ac9edc148f849201a692a06d722853030",
"supervisor_base_image": "alpine:3.22",
"supervisor_base_image_id": "b66e0ce64844f5c6435b0c4bfd965558199ab0f53270846861c979cb1ac29365",
"supervisor_base_image_digest": "sha256:7c8cb692ae09657cbc4a3f3cbd0e8d5a2690ba38386aaaf252dbb060bf5eb2e6",
"supervisor_base_runtime_image": "docker.io/library/alpine@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce",
"supervisor_package_manifest_sha256": "6966057ffaf1ef0d4617d413dad53646bcd049a4b08f572796392fb0ffbb01b9",
"sandbox_image_request": "nvcr.io/nvidia/base/ubuntu@sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_image_id": "65fa5d3d598a07d385ddbea41bf593be15af306337b76255b40705287cebcbbf",
"sandbox_image_digest": "sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_runtime_image": "nvcr.io/nvidia/base/ubuntu@sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_client_image_alias": "nvcr.io/nvidia/base/ubuntu:24.04",
"sandbox_client_image_alias_id": "65fa5d3d598a07d385ddbea41bf593be15af306337b76255b40705287cebcbbf",
"gateway_sha256_before_execution": "264cf3d809bd1d54633bce9251ec1a5540b567b8150640091df85bdfbe61797a",
"cli_sha256_before_execution": "3ad0ec143bf6850af780bf643c303242956d6ef1066d4a9372bc62fef33ada20",
"conformance_sha256_before_execution": "d669f960333f9bcd777f4fac92e5208fa66d1b51578838e5aba9b1f58bc8dc6e",
"external_driver_sha256_before_execution": "",
"supervisor_sha256_before_execution": "ae2e854936a15a5b952187fd4488a746a8a6e31e9f919967e3ead7a80d4b1077",
"supervisor_dockerfile_sha256_before_execution": "ec8b25f0a674c0c7ae123c978f6857436af987faea43051e67d3a8d4b52831cd",
"cli_trace_wrapper_sha256_before_execution": "0691d47d9eae7e9fe847a58994e170a480c0e61d1d9013193d6ca9c93476777f",
"external_driver_grpc_endpoint": null,
"external_driver_host_gateway_ip": null,
"external_driver_userns": null,
"external_driver_spiffe": false,
"external_driver_proxy": false,
"external_driver_app_armor": false,
"external_driver_environment": null
},
"raw_evidence_sha256": {
"baseline.json": "d7e7f18607d1eab7fab65b1643febe46499aeaaa00c100b66f92b11101d798a1",
"baseline.launch.json": "a56fe7df2c454137cebcea17bc022adcb9b00f3a2e7403611f61fede62a9b329",
"baseline.log": "e44a39cf19296908e99c58b661bd1c162f0aedd2fafb9c70a1a875d91e712cbe",
"baseline.gateway.toml": "9d11c7c8455308c21354f2a41b546068f06e4605f9127e0156467c321bac550c",
"baseline.exec.stdout": "f3a45a1114b92419a9c4c91364d584de4161ec171a1a9a73dae5b4daca89f8a9"
},
"artifacts_verified": true,
"raw_output_verified": true,
"success": true
},
"candidate": {
"schema_version": 2,
"source_sha": "4a39da510e4d278a24dd60291149519c9a570b46",
"gateway_profile": "in-tree",
"gateway_cargo_features": "default",
"artifact_origins": {
"gateway": "built_by_harness",
"cli": "built_by_harness",
"conformance": "built_by_harness",
"external_driver": "not_applicable",
"supervisor": "built_by_harness"
},
"artifact_sha256": {
"gateway": "2bd42b145f0438f48a579b010537f501e036035b0e22a4ff70e37db733a6e6ff",
"cli": "82827d9068f3e9c75681a804f8fb48274ecf8acb179a46f179fb9fbfe828f69a",
"conformance": "cf6866bdd9755881bf8e2fe0c60a72b41037c6e31725fe43f3328b5c8435cc6d",
"supervisor": "38e1afd251898593619864557ed948ef76370ec0c4618850474a67d1d0508b40",
"supervisor.Dockerfile": "ec8b25f0a674c0c7ae123c978f6857436af987faea43051e67d3a8d4b52831cd",
"cli-trace-wrapper": "0691d47d9eae7e9fe847a58994e170a480c0e61d1d9013193d6ca9c93476777f",
"supervisor.packages.txt": "6966057ffaf1ef0d4617d413dad53646bcd049a4b08f572796392fb0ffbb01b9"
},
"launch_attestation": {
"schema_version": 2,
"gateway_port": 55987,
"external_compute_driver": false,
"compute_driver_transport": "in_tree",
"external_driver_pull_policy": "if_not_present",
"supervisor_image": "localhost/openshell/supervisor:parity-candidate-4a39da510e4d",
"supervisor_image_id": "489ba15df40c47957b400e54633c250b4322dc37f2798a59717b57c75421330a",
"supervisor_image_digest": "sha256:6de7479f138e88da131741e64c170aa75ae14b4e7b9b49de2d11f51af7d1b6d7",
"supervisor_runtime_image": "localhost/openshell/supervisor@sha256:6de7479f138e88da131741e64c170aa75ae14b4e7b9b49de2d11f51af7d1b6d7",
"supervisor_base_image": "alpine:3.22",
"supervisor_base_image_id": "b66e0ce64844f5c6435b0c4bfd965558199ab0f53270846861c979cb1ac29365",
"supervisor_base_image_digest": "sha256:7c8cb692ae09657cbc4a3f3cbd0e8d5a2690ba38386aaaf252dbb060bf5eb2e6",
"supervisor_base_runtime_image": "docker.io/library/alpine@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce",
"supervisor_package_manifest_sha256": "6966057ffaf1ef0d4617d413dad53646bcd049a4b08f572796392fb0ffbb01b9",
"sandbox_image_request": "nvcr.io/nvidia/base/ubuntu@sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_image_id": "65fa5d3d598a07d385ddbea41bf593be15af306337b76255b40705287cebcbbf",
"sandbox_image_digest": "sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_runtime_image": "nvcr.io/nvidia/base/ubuntu@sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_client_image_alias": "nvcr.io/nvidia/base/ubuntu:24.04",
"sandbox_client_image_alias_id": "65fa5d3d598a07d385ddbea41bf593be15af306337b76255b40705287cebcbbf",
"gateway_sha256_before_execution": "2bd42b145f0438f48a579b010537f501e036035b0e22a4ff70e37db733a6e6ff",
"cli_sha256_before_execution": "82827d9068f3e9c75681a804f8fb48274ecf8acb179a46f179fb9fbfe828f69a",
"conformance_sha256_before_execution": "cf6866bdd9755881bf8e2fe0c60a72b41037c6e31725fe43f3328b5c8435cc6d",
"external_driver_sha256_before_execution": "",
"supervisor_sha256_before_execution": "38e1afd251898593619864557ed948ef76370ec0c4618850474a67d1d0508b40",
"supervisor_dockerfile_sha256_before_execution": "ec8b25f0a674c0c7ae123c978f6857436af987faea43051e67d3a8d4b52831cd",
"cli_trace_wrapper_sha256_before_execution": "0691d47d9eae7e9fe847a58994e170a480c0e61d1d9013193d6ca9c93476777f",
"external_driver_grpc_endpoint": null,
"external_driver_host_gateway_ip": null,
"external_driver_userns": null,
"external_driver_spiffe": false,
"external_driver_proxy": false,
"external_driver_app_armor": false,
"external_driver_environment": null
},
"raw_evidence_sha256": {
"candidate.json": "ed7d6334cccb40488291e35e9b7ad4fb45dd47b55b7e27925384d22907bedefd",
"candidate.launch.json": "384ee89066973cacdb43160a39542096bc3d02da051ac0417fefc0be41c2f619",
"candidate.log": "719aaedc019492ccdc2f1e003af6b12af5bf6d2507fc2573135fca529a9f398f",
"candidate.gateway.toml": "504bbea27b56cc630884ba3eb17eb518f7c55cb7886b10ff353cc777e3d08362",
"candidate.exec.stdout": "d903d8a1f84caca8daa2a5a047c3fe90e2501690fba7c0b62e14d3892b5aadc3"
},
"artifacts_verified": true,
"raw_output_verified": true,
"success": true
},
"comparison_sha256": "e97312770ed8cbba6325b901885d083c7f82ef979b5b89e4e0ed2bd32478d9fb",
"classification": "pass",
"parity": true,
"accepted": true
},
"external_uds": {
"baseline": {
"schema_version": 1,
"source_sha": "74960ebfaeec4673885089ed995fad902459749f",
"gateway_profile": "driver-free",
"gateway_cargo_features": "--no-default-features --features telemetry",
"artifact_origins": {
"gateway": "built_by_harness",
"cli": "built_by_harness",
"conformance": "built_by_harness",
"external_driver": "built_by_harness",
"supervisor": "built_by_harness"
},
"artifact_sha256": {
"gateway": "5cc2f700d93dde5dd09060d9c9190ae44a99440b1399530a2b23941ec4e88f85",
"cli": "3ad0ec143bf6850af780bf643c303242956d6ef1066d4a9372bc62fef33ada20",
"conformance": "d669f960333f9bcd777f4fac92e5208fa66d1b51578838e5aba9b1f58bc8dc6e",
"supervisor": "ae2e854936a15a5b952187fd4488a746a8a6e31e9f919967e3ead7a80d4b1077",
"supervisor.Dockerfile": "ec8b25f0a674c0c7ae123c978f6857436af987faea43051e67d3a8d4b52831cd",
"cli-trace-wrapper": "0691d47d9eae7e9fe847a58994e170a480c0e61d1d9013193d6ca9c93476777f",
"external-driver": "d976be0580ab5a2e006ca9e1bc1556b84fa810481f6e1c2132793f8e38c7194c",
"supervisor.packages.txt": "6966057ffaf1ef0d4617d413dad53646bcd049a4b08f572796392fb0ffbb01b9"
},
"launch_attestation": {
"schema_version": 1,
"gateway_port": 50871,
"external_compute_driver": true,
"compute_driver_transport": "remote_uds",
"external_driver_pull_policy": "missing",
"supervisor_image": "localhost/openshell/supervisor:parity-baseline-74960ebfaeec",
"supervisor_image_id": "b2e8f8dae82296a54e7500beb0b2b55d1f8d4ac4afe6ed8de5fba4b3b65ba748",
"supervisor_image_digest": "sha256:b576159e1c7ca3258b9428411977a4fa7eddf2d46aa1a1b2238de7a0081c7e60",
"supervisor_runtime_image": "localhost/openshell/supervisor@sha256:b576159e1c7ca3258b9428411977a4fa7eddf2d46aa1a1b2238de7a0081c7e60",
"supervisor_base_image": "alpine:3.22",
"supervisor_base_image_id": "b66e0ce64844f5c6435b0c4bfd965558199ab0f53270846861c979cb1ac29365",
"supervisor_base_image_digest": "sha256:7c8cb692ae09657cbc4a3f3cbd0e8d5a2690ba38386aaaf252dbb060bf5eb2e6",
"supervisor_base_runtime_image": "docker.io/library/alpine@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce",
"supervisor_package_manifest_sha256": "6966057ffaf1ef0d4617d413dad53646bcd049a4b08f572796392fb0ffbb01b9",
"sandbox_image_request": "nvcr.io/nvidia/base/ubuntu@sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_image_id": "65fa5d3d598a07d385ddbea41bf593be15af306337b76255b40705287cebcbbf",
"sandbox_image_digest": "sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_runtime_image": "nvcr.io/nvidia/base/ubuntu@sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_client_image_alias": "nvcr.io/nvidia/base/ubuntu:24.04",
"sandbox_client_image_alias_id": "65fa5d3d598a07d385ddbea41bf593be15af306337b76255b40705287cebcbbf",
"gateway_sha256_before_execution": "5cc2f700d93dde5dd09060d9c9190ae44a99440b1399530a2b23941ec4e88f85",
"cli_sha256_before_execution": "3ad0ec143bf6850af780bf643c303242956d6ef1066d4a9372bc62fef33ada20",
"conformance_sha256_before_execution": "d669f960333f9bcd777f4fac92e5208fa66d1b51578838e5aba9b1f58bc8dc6e",
"external_driver_sha256_before_execution": "d976be0580ab5a2e006ca9e1bc1556b84fa810481f6e1c2132793f8e38c7194c",
"supervisor_sha256_before_execution": "ae2e854936a15a5b952187fd4488a746a8a6e31e9f919967e3ead7a80d4b1077",
"supervisor_dockerfile_sha256_before_execution": "ec8b25f0a674c0c7ae123c978f6857436af987faea43051e67d3a8d4b52831cd",
"cli_trace_wrapper_sha256_before_execution": "0691d47d9eae7e9fe847a58994e170a480c0e61d1d9013193d6ca9c93476777f",
"external_driver_grpc_endpoint": "https://host.containers.internal:50871",
"external_driver_host_gateway_ip": "host-gateway",
"external_driver_userns": null,
"external_driver_spiffe": false,
"external_driver_proxy": false,
"external_driver_app_armor": false,
"external_driver_environment": {
"OPENSHELL_COMPUTE_DRIVER_SOCKET": "/tmp/openshell-e2e-podman.H8oMaO/compute-driver.sock",
"OPENSHELL_PODMAN_SOCKET": "/tmp/openshell-e2e-podman.H8oMaO/podman/podman.sock",
"OPENSHELL_SANDBOX_IMAGE": "nvcr.io/nvidia/base/ubuntu@sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"OPENSHELL_SANDBOX_IMAGE_PULL_POLICY": "missing",
"OPENSHELL_HEALTH_CHECK_INTERVAL_SECS": 10,
"OPENSHELL_GRPC_ENDPOINT": "https://host.containers.internal:50871",
"OPENSHELL_GATEWAY_PORT": 50871,
"OPENSHELL_NETWORK_NAME": "e2e-podman-659291-50871",
"OPENSHELL_STOP_TIMEOUT": 15,
"OPENSHELL_SUPERVISOR_IMAGE": "localhost/openshell/supervisor@sha256:b576159e1c7ca3258b9428411977a4fa7eddf2d46aa1a1b2238de7a0081c7e60",
"OPENSHELL_PODMAN_TLS_CA": {
"path": "/tmp/openshell-e2e-podman.H8oMaO/pki/ca.crt",
"sha256": "1a77771ebd83be7ed988263ea4a8e42d6b2af94c46861693911c4d5bff6a3fdd"
},
"OPENSHELL_PODMAN_TLS_CERT": {
"path": "/tmp/openshell-e2e-podman.H8oMaO/pki/client/tls.crt",
"sha256": "0e9ad610227c223ebca348599a113e07f46ab0c6ff6f4ea5598e4c15673e25fd"
},
"OPENSHELL_PODMAN_TLS_KEY": {
"path": "/tmp/openshell-e2e-podman.H8oMaO/pki/client/tls.key",
"sha256": "d5bbf26f73a8fdfe60e16783bb99275bf35c617b1f229b7c48afb0a3edbacbc0"
},
"OPENSHELL_ENABLE_BIND_MOUNTS": true
}
},
"raw_evidence_sha256": {
"baseline.json": "2b48dd376fd02d46c93d6ae0831d3a81d7337893794ca97c6559676e1b8302de",
"baseline.launch.json": "babe872dd643f024da5e4d0697a3a946ba21432d16e7b7abb2e343e82459ec79",
"baseline.log": "1718593d49cd26f76b7ce1d3be5cfca7c70fae7c44976aa1485796b52048ab41",
"baseline.gateway.toml": "8d4f2579c58ba140e95dc1151216cf9962ac211272ce26d2f811b6f3a1a659d0",
"baseline.exec.stdout": "f740ac1e211850739407334863f73311e7ff508bb4e507b7d7fcaf8d8dc2de32",
"baseline.driver.log": "877ab38e85532d3b772ec080adc727ef517203b1b553e75c9b6f29ad06e3374a"
},
"artifacts_verified": true,
"raw_output_verified": true,
"success": true
},
"candidate": {
"schema_version": 2,
"source_sha": "4a39da510e4d278a24dd60291149519c9a570b46",
"gateway_profile": "driver-free",
"gateway_cargo_features": "--no-default-features --features telemetry",
"artifact_origins": {
"gateway": "built_by_harness",
"cli": "built_by_harness",
"conformance": "built_by_harness",
"external_driver": "built_by_harness",
"supervisor": "built_by_harness"
},
"artifact_sha256": {
"gateway": "fdefc047c1b675c311b1796db9f1b1a944456fc34b76547efc0352c6a75a7707",
"cli": "82827d9068f3e9c75681a804f8fb48274ecf8acb179a46f179fb9fbfe828f69a",
"conformance": "cf6866bdd9755881bf8e2fe0c60a72b41037c6e31725fe43f3328b5c8435cc6d",
"supervisor": "38e1afd251898593619864557ed948ef76370ec0c4618850474a67d1d0508b40",
"supervisor.Dockerfile": "ec8b25f0a674c0c7ae123c978f6857436af987faea43051e67d3a8d4b52831cd",
"cli-trace-wrapper": "0691d47d9eae7e9fe847a58994e170a480c0e61d1d9013193d6ca9c93476777f",
"external-driver": "9accb17523a33e8fc4df93b3b3dec619f1f5ad6f5ff3f51abb2a8a5718278f8c",
"supervisor.packages.txt": "6966057ffaf1ef0d4617d413dad53646bcd049a4b08f572796392fb0ffbb01b9"
},
"launch_attestation": {
"schema_version": 2,
"gateway_port": 32901,
"external_compute_driver": true,
"compute_driver_transport": "remote_uds",
"external_driver_pull_policy": "if_not_present",
"supervisor_image": "localhost/openshell/supervisor:parity-candidate-4a39da510e4d",
"supervisor_image_id": "9c7f51faec648947fe1515ec4bcbab52234e4e143a53bd1bf0a358eadd11440e",
"supervisor_image_digest": "sha256:b4cc939fcf3a95ee7cbfa1560acda5ab8c234b041a21d31ac958810e6b748798",
"supervisor_runtime_image": "localhost/openshell/supervisor@sha256:b4cc939fcf3a95ee7cbfa1560acda5ab8c234b041a21d31ac958810e6b748798",
"supervisor_base_image": "alpine:3.22",
"supervisor_base_image_id": "b66e0ce64844f5c6435b0c4bfd965558199ab0f53270846861c979cb1ac29365",
"supervisor_base_image_digest": "sha256:7c8cb692ae09657cbc4a3f3cbd0e8d5a2690ba38386aaaf252dbb060bf5eb2e6",
"supervisor_base_runtime_image": "docker.io/library/alpine@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce",
"supervisor_package_manifest_sha256": "6966057ffaf1ef0d4617d413dad53646bcd049a4b08f572796392fb0ffbb01b9",
"sandbox_image_request": "nvcr.io/nvidia/base/ubuntu@sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_image_id": "65fa5d3d598a07d385ddbea41bf593be15af306337b76255b40705287cebcbbf",
"sandbox_image_digest": "sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_runtime_image": "nvcr.io/nvidia/base/ubuntu@sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"sandbox_client_image_alias": "nvcr.io/nvidia/base/ubuntu:24.04",
"sandbox_client_image_alias_id": "65fa5d3d598a07d385ddbea41bf593be15af306337b76255b40705287cebcbbf",
"gateway_sha256_before_execution": "fdefc047c1b675c311b1796db9f1b1a944456fc34b76547efc0352c6a75a7707",
"cli_sha256_before_execution": "82827d9068f3e9c75681a804f8fb48274ecf8acb179a46f179fb9fbfe828f69a",
"conformance_sha256_before_execution": "cf6866bdd9755881bf8e2fe0c60a72b41037c6e31725fe43f3328b5c8435cc6d",
"external_driver_sha256_before_execution": "9accb17523a33e8fc4df93b3b3dec619f1f5ad6f5ff3f51abb2a8a5718278f8c",
"supervisor_sha256_before_execution": "38e1afd251898593619864557ed948ef76370ec0c4618850474a67d1d0508b40",
"supervisor_dockerfile_sha256_before_execution": "ec8b25f0a674c0c7ae123c978f6857436af987faea43051e67d3a8d4b52831cd",
"cli_trace_wrapper_sha256_before_execution": "0691d47d9eae7e9fe847a58994e170a480c0e61d1d9013193d6ca9c93476777f",
"external_driver_grpc_endpoint": "https://host.containers.internal:32901",
"external_driver_host_gateway_ip": "host-gateway",
"external_driver_userns": null,
"external_driver_spiffe": false,
"external_driver_proxy": false,
"external_driver_app_armor": false,
"external_driver_environment": {
"OPENSHELL_COMPUTE_DRIVER_SOCKET": "/tmp/openshell-e2e-podman.M8xsgQ/compute-driver.sock",
"OPENSHELL_PODMAN_SOCKET": "/tmp/openshell-e2e-podman.M8xsgQ/podman/podman.sock",
"OPENSHELL_SANDBOX_IMAGE": "nvcr.io/nvidia/base/ubuntu@sha256:c280ee89f8bfcbdaba6179ad4347f60c509e841cbe63eb93002f01bf70e0819c",
"OPENSHELL_SANDBOX_IMAGE_PULL_POLICY": "if_not_present",
"OPENSHELL_HEALTH_CHECK_INTERVAL_SECS": 10,
"OPENSHELL_GRPC_ENDPOINT": "https://host.containers.internal:32901",
"OPENSHELL_GATEWAY_PORT": 32901,
"OPENSHELL_NETWORK_NAME": "e2e-podman-660516-32901",
"OPENSHELL_STOP_TIMEOUT": 15,
"OPENSHELL_SUPERVISOR_IMAGE": "localhost/openshell/supervisor@sha256:b4cc939fcf3a95ee7cbfa1560acda5ab8c234b041a21d31ac958810e6b748798",
"OPENSHELL_PODMAN_TLS_CA": {
"path": "/tmp/openshell-e2e-podman.M8xsgQ/pki/ca.crt",
"sha256": "90b268e741240a39838b7074b66ffa30576c053f5c8f5659e1e2e3c0e22809df"
},
"OPENSHELL_PODMAN_TLS_CERT": {
"path": "/tmp/openshell-e2e-podman.M8xsgQ/pki/client/tls.crt",
"sha256": "a89f555a5e53cf155f122bd2c8b58e0856019468cdf1cf80cafb1c832979f40f"
},
"OPENSHELL_PODMAN_TLS_KEY": {
"path": "/tmp/openshell-e2e-podman.M8xsgQ/pki/client/tls.key",
"sha256": "a53d8aaea929dec1b355a5e6ae45eb5001f9c3845d3d2cbbff9ca5a7e468be06"
},
"OPENSHELL_ENABLE_BIND_MOUNTS": true
}
},
"raw_evidence_sha256": {
"candidate.json": "a68a9a3f78a8ba0fbf33c81e9960e705e554e82077fd4e0e8565a3bc8598790b",
"candidate.launch.json": "5be63290c313302ec2fa35cdd55ec641742d2d7009f7c2746842c42072425f1a",
"candidate.log": "d19a44064c8d90b078e4d34d711c599ae424834de433b355805105ae3f272cf2",
"candidate.gateway.toml": "862322125b3bc9438b87b35448e107d87850f4f3cd61c9c36f045560c963385e",
"candidate.exec.stdout": "fc1085830f6824809d3fdec6ecf518d54a7dde92ec4441e134f13abd5a6a6522",
"candidate.driver.log": "0b977d9c2b69a3e9665d457dd88fe231b3da7a55d74d4ace4c1a467e7cf716d1"
},
"artifacts_verified": true,
"raw_output_verified": true,
"success": true
},
"comparison_sha256": "6b30e24a1cf0f9b7d8b5a5de206cfbbfb01c19a7921d6a449900af8448abec4c",
"classification": "pass",
"parity": true,
"accepted": true
},
"callback_listener": {
"in_tree_baseline_exec": true,
"in_tree_candidate_exec": true,
"external_baseline_exec": true,
"external_candidate_exec": true,
"classification": "pass"
},
"classification": "pass",
"accepted": true,
"verification": {
"retained_artifact_hashes_recomputed": true,
"raw_lifecycle_output_inspected": true,
"authenticated_preflight_verified": true,
"exact_callback_exec_stdout_verified": true,
"external_driver_allowlist_verified": true,
"external_driver_logs_retained": true,
"external_uds_isolation_verified": true,
"digest_pinned_supervisor_runtime_verified": true,
"same_immutable_sandbox_verified": true,
"supervisor_dependency_provenance_matched": true
}
}
@@ -1,109 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Step 11 dispositions for the cross-cutting gateway capabilities that are not
# exercised by the compute-driver waves. The paired deterministic preflight is
# regression evidence only: it does not replace a candidate-owned oracle that
# drives both gateway processes and observes the same live behavior.
manifest_version = 1
baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
candidate_commit = "363d8540830b2ea294d43198daa2b7a283a2face"
overall_status = "platform_blocked"
[deterministic_preflight]
status = "pass"
baseline_attestation = "e2e/configs/gateway/schema-v2-step11-baseline-attestation.txt"
baseline_attestation_sha256 = "df3c5e1dcb073eb8db0cb28377516523b331d44fc6f5a5fefab2e92273efaf51"
candidate_attestation = "e2e/configs/gateway/schema-v2-step11-candidate-attestation.txt"
candidate_attestation_sha256 = "2562bff73eba8042199597e814b618b12b93994d15e4ae36e902347347d95fed"
commands = [
"cargo test -q -p openshell-server --lib",
"cargo test -q -p openshell-gateway-interceptors",
"cargo test -q -p openshell-supervisor-middleware",
"cargo test -q -p openshell-otel-test-support",
"cargo test -q -p openshell-server --test multiplex_tls_integration",
"cargo test -q -p openshell-server --test edge_tunnel_auth",
]
evidence = [
"The frozen baseline passed 1,455 openshell-server library tests with 8 ignored; the candidate passed 1,481 with 8 ignored.",
"Both revisions passed 49 gateway-interceptor tests, 85 supervisor-middleware tests, 5 multiplex TLS integration tests, and 5 edge-tunnel authentication tests.",
"The openshell-otel-test-support crate compiled successfully on both revisions but currently defines no tests; OTLP behavior is exercised by openshell-server unit tests and still requires a collector-backed live lane.",
"Both runs used checkout-local target directories with sccache disabled after a prior ENOSPC event corrupted the shared cache.",
]
[[capabilities]]
id = "oidc-bearer-authentication"
status = "platform_blocked"
owner = "OpenShell auth and OIDC CI lane"
lane = "linux-oidc-paired-keycloak-jwks"
blocker = "The host has no isolated paired issuer fixture that presents equivalent signed tokens to both exact-source gateways. Existing Keycloak and OIDC suites are candidate-oriented and cannot establish schema-v1/schema-v2 audience, role, scope, expiry, signature, and key-rotation parity without a shared candidate-owned oracle."
[[capabilities]]
id = "mtls-user-authentication"
status = "platform_blocked"
owner = "OpenShell gateway authentication CI lane"
lane = "linux-mtls-user-principal-paired"
blocker = "The paired TLS integration tests validate handshake policy but do not drive an authenticated user RPC through both gateways or prove certificate-to-principal mapping. A live lane must use isolated client PKI, equivalent schema files, and the same authorization oracle for enabled and disabled mTLS user authentication."
[[capabilities]]
id = "unsafe-unauthenticated-user-mode"
status = "platform_blocked"
owner = "OpenShell gateway authentication CI lane"
lane = "linux-auth-chain-paired-isolated"
blocker = "No paired live fixture currently proves that the trusted-development switch admits user requests while sandbox callbacks continue to require sandbox credentials. Candidate-only extension examples use this switch for setup, but that is not an authentication-boundary parity test."
[[capabilities]]
id = "gateway-minted-sandbox-jwt"
status = "platform_blocked"
owner = "OpenShell gateway JWT CI lane"
lane = "linux-gateway-jwt-claims-paired"
blocker = "Step 10 proved authenticated callback connectivity but did not capture and compare token claims. A controlled callback and extension fixture must verify issuer, gateway identity, key ID, audience, subject, token type, and expiry semantics for both gateways; explicit zero versus omitted TTL remains the ledgered gateway-jwt-zero-sentinel-removed intentional change."
[[capabilities]]
id = "otlp-observability"
status = "platform_blocked"
owner = "OpenShell observability CI lane"
lane = "linux-otlp-grpc-collector-paired"
blocker = "The deterministic exporter tests passed, but no retained paired collector capture proves emitted gateway and in-tree-driver spans, gateway name, service name, selected-driver resource attributes, or continued serving after collector failure. A loopback OTLP/gRPC collector lane must observe those outcomes from both exact-source processes."
[[capabilities]]
id = "gateway-interceptor-registration"
status = "platform_blocked"
owner = "OpenShell gateway interceptor CI lane"
lane = "linux-gateway-interceptor-paired"
blocker = "The interceptor library suite passed on both revisions, while the governance-interceptor smoke test remains candidate-only. A paired service must compare Describe validation, binding selection, unary request and response mutation, failure policy, timeout and size limits, and secret exclusion against both gateway schema variants."
[[capabilities]]
id = "supervisor-middleware-registration"
status = "platform_blocked"
owner = "OpenShell supervisor middleware CI lane"
lane = "linux-supervisor-middleware-paired"
blocker = "The middleware library suite passed on both revisions, while the content-guard smoke test remains candidate-only. A paired gateway, sandbox, and middleware fixture must compare Describe negotiation, policy distribution, guarded and unguarded traffic, failure policy, timeout, and payload limits; the field-name normalization remains the ledgered middleware-payload-name-normalized intentional change."
[[capabilities]]
id = "provider-profile-sources"
status = "platform_blocked"
owner = "OpenShell provider profile CI lane"
lane = "linux-provider-profiles-interceptor-paired"
blocker = "Server tests cover source construction and duplicate rejection, but no shared live interceptor catalog has been queried through both gateways. The assigned lane must compare builtin, user, and interceptor source ordering, normalized profile identities, duplicate rejection, discovery output, and failure handling with isolated persistent state."
[[capabilities]]
id = "inference-control-plane-configuration"
status = "platform_blocked"
owner = "OpenShell inference E2E lane"
lane = "linux-inference-provider-routing-paired"
blocker = "Existing inference routing tests are candidate-oriented and this host has no assigned paired provider and model-service fixture. The lane must configure providers and routes through each gateway control plane, observe the effective supervisor bundle, and compare model discovery and an inference request without reusing database state."
[[capabilities]]
id = "credential-driver-selection-and-kek"
status = "platform_blocked"
owner = "OpenShell credential security CI lane"
lane = "linux-credential-kek-paired"
blocker = "Both server suites passed deterministic selection, KEK, and credential tests, but they are revision-local tests rather than one candidate-owned live oracle. A paired lane must start isolated gateways with independent databases and KEKs, compare default encrypted storage and invalid selections, store and resolve opaque credentials, and verify that logs and configuration do not disclose secrets."
[[capabilities]]
id = "credential-driver-backend-tables"
status = "platform_blocked"
owner = "OpenShell credential driver E2E lane"
lane = "kubernetes-vault-uds-credential-drivers-paired"
blocker = "The host has no assigned disposable Kubernetes Secrets or Vault backend and no retained paired UDS credential-driver execution. Existing backend E2E coverage is candidate-oriented. The assigned lane must compare in-tree and remote transport validation plus opaque store and retrieve behavior using isolated namespaces, Vault state, sockets, databases, and credentials."
@@ -1,170 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Explicit compatibility exceptions for the schema-v2 parity campaign. These
# entries document behavior that is not expected to match schema v1 byte for
# byte. They do not waive the requirement that the replacement behavior work.
ledger_version = 1
issue = 2792
baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
candidate_start_commit = "8c868e430e9cd3284d7e274628419ab484ebcee0"
[[intentional_changes]]
id = "schema-version-cutover"
category = "schema_cutover"
origin_main_contract = "Gateway configuration uses schema version 1; omitted versions were accepted in some paths."
schema_v2_contract = "Every loaded gateway configuration must declare [openshell] version = 2; missing, v1, and future versions fail."
migration = "Set version = 2 and apply every field relocation, rename, and type migration in this ledger before restart."
rationale = "An explicit version boundary prevents a partially migrated security-sensitive configuration from being interpreted with mixed ownership rules."
parity_disposition = "intentional_change"
validation_capability_ids = ["schema-version-and-strict-layout", "rpm-schema-upgrade", "homebrew-debian-and-snap-upgrades"]
[[intentional_changes]]
id = "singular-compute-driver-selector"
category = "cardinality"
origin_main_contract = "Configuration spells the selector compute_drivers as a list even though runtime selection rejects more than one configured driver."
schema_v2_contract = "Configuration uses one optional scalar compute_driver; omission retains built-in auto-detection."
migration = "Replace compute_drivers = [\"name\"] with compute_driver = \"name\"."
rationale = "The schema now represents the existing one-driver runtime invariant instead of implying unsupported multi-driver operation."
parity_disposition = "intentional_change"
validation_capability_ids = ["schema-version-and-strict-layout", "external-compute-driver-socket"]
[[intentional_changes]]
id = "driver-table-exclusive-ownership"
category = "ownership"
origin_main_contract = "Selected driver tables inherit an allowlisted set of values from [openshell.gateway]."
schema_v2_contract = "Driver-specific values are read only from [openshell.drivers.<name>]; gateway scope contains only gateway-owned values."
migration = "Move every driver option to the selected driver table instead of relying on gateway inheritance."
rationale = "Only one compute driver is active, so inheritance adds ambiguity and can map one gateway key to different backend meanings."
parity_disposition = "intentional_change"
validation_capability_ids = ["schema-version-and-strict-layout", "docker-image-and-callback-configuration", "podman-image-and-callback-configuration", "kubernetes-core-placement-and-images", "vm-launch-and-resource-configuration"]
[[intentional_changes]]
id = "kubernetes-fields-relocated"
category = "relocation"
origin_main_contract = "Kubernetes namespace, image, client TLS Secret, ServiceAccount, host gateway, user namespace, and token TTL values may be inherited from gateway scope."
schema_v2_contract = "Those values exist exclusively under [openshell.drivers.kubernetes]."
migration = "Move namespace, default_image, supervisor_image, client_tls_secret_name, service_account_name, host_gateway_ip, enable_user_namespaces, and sa_token_ttl_secs into the Kubernetes driver table."
rationale = "Kubernetes-only deployment controls are not gateway-wide concerns."
parity_disposition = "intentional_change"
validation_capability_ids = ["kubernetes-core-placement-and-images"]
[[intentional_changes]]
id = "docker-sandbox-label-rename"
category = "rename"
origin_main_contract = "Docker identifies OpenShell containers with sandbox_namespace."
schema_v2_contract = "Docker uses sandbox_label."
migration = "Rename [openshell.drivers.docker].sandbox_namespace to sandbox_label."
rationale = "The value is a Docker container label, not a Kubernetes-style namespace."
parity_disposition = "intentional_change"
validation_capability_ids = ["docker-image-and-callback-configuration"]
[[intentional_changes]]
id = "podman-ssh-socket-rename"
category = "rename"
origin_main_contract = "Podman uses sandbox_ssh_socket_path in gateway TOML."
schema_v2_contract = "Podman uses ssh_socket_path in gateway TOML."
migration = "Rename [openshell.drivers.podman].sandbox_ssh_socket_path to ssh_socket_path."
rationale = "The canonical name now matches the Docker and Kubernetes driver tables."
parity_disposition = "intentional_change"
validation_capability_ids = ["podman-runtime-security-and-health"]
[[intentional_changes]]
id = "vm-grpc-endpoint-rename"
category = "rename"
origin_main_contract = "The VM gateway TOML callback override is grpc_endpoint, while the spawned standalone driver uses the internal field openshell_endpoint and flag --openshell-endpoint; OPENSHELL_GRPC_ENDPOINT is the environment override."
schema_v2_contract = "The VM gateway TOML callback override remains grpc_endpoint, and the spawned standalone driver now uses the same internal field name plus --grpc-endpoint; OPENSHELL_GRPC_ENDPOINT is unchanged."
migration = "No gateway TOML key changes. Operators invoking openshell-driver-vm directly must replace --openshell-endpoint with --grpc-endpoint."
rationale = "All compute drivers use the same name for the gateway gRPC callback endpoint."
parity_disposition = "intentional_change"
validation_capability_ids = ["vm-launch-and-resource-configuration", "external-compute-driver-socket"]
[[intentional_changes]]
id = "canonical-image-pull-policy"
category = "type_normalization"
origin_main_contract = "Drivers accept different pull-policy types and spellings, including Podman missing and Kubernetes-style capitalization."
schema_v2_contract = "Gateway TOML uses always, if_not_present, never, and Podman-only newer through the shared typed policy."
migration = "Translate legacy or runtime-native spellings to canonical lowercase values."
rationale = "A shared validated type rejects typos before contacting a container runtime while preserving Podman's additional newer behavior."
parity_disposition = "intentional_change"
validation_capability_ids = ["docker-image-and-callback-configuration", "podman-image-and-callback-configuration", "kubernetes-core-placement-and-images", "local-launch-script-producers"]
[[intentional_changes]]
id = "gateway-jwt-zero-sentinel-removed"
category = "sentinel_removal"
origin_main_contract = "gateway_jwt.ttl_secs = 0 means that sandbox tokens do not expire."
schema_v2_contract = "Omitting gateway_jwt.ttl_secs means non-expiring sandbox tokens; an explicit zero is invalid."
migration = "Remove ttl_secs when non-expiring local tokens are intended, or set a positive duration."
rationale = "Omission distinguishes a deliberate absence of expiry from an invalid duration."
parity_disposition = "intentional_change"
validation_capability_ids = ["gateway-minted-sandbox-jwt"]
[[intentional_changes]]
id = "sandbox-pid-zero-sentinel-removed"
category = "sentinel_removal"
origin_main_contract = "Docker and Podman sandbox_pids_limit use zero as a backend-default sentinel."
schema_v2_contract = "Omitting sandbox_pids_limit uses the OpenShell default of 2048; configured values must be positive."
migration = "Remove a zero sandbox_pids_limit or replace it with a positive explicit limit."
rationale = "A typed optional non-zero limit removes ambiguous zero handling and gives both local container drivers one default."
parity_disposition = "intentional_change"
validation_capability_ids = ["docker-security-and-provider-configuration", "podman-runtime-security-and-health"]
[[intentional_changes]]
id = "podman-pid-limit-restored"
category = "bug_fix"
origin_main_contract = "Podman accepts a positive sandbox_pids_limit, but serializes it with Docker's PidsLimit shape; libpod ignores that field and applies its default limit of 2048."
schema_v2_contract = "Podman serializes a positive sandbox_pids_limit as OCI resource_limits.pids.limit, and the configured value is applied to the container."
migration = "No configuration migration is required; existing positive values begin taking effect after upgrading."
rationale = "Schema-v2 live validation exposed that the frozen baseline accepted this security control without enforcing it at runtime. Preserving that defect would make configuration parity unsafe."
parity_disposition = "intentional_change"
validation_capability_ids = ["podman-runtime-security-and-health"]
[[intentional_changes]]
id = "podman-health-zero-sentinel-removed"
category = "sentinel_removal"
origin_main_contract = "Podman health_check_interval_secs = 0 disables health checks."
schema_v2_contract = "Omitting health_check_interval_secs disables gateway-managed Podman health checks; configured values must be positive."
migration = "Remove a zero health_check_interval_secs or set a positive interval."
rationale = "Optional non-zero duration expresses enabled and disabled states without a sentinel."
parity_disposition = "intentional_change"
validation_capability_ids = ["podman-runtime-security-and-health"]
[[intentional_changes]]
id = "guest-tls-centralized"
category = "ownership"
origin_main_contract = "Local driver tables may override guest_tls_ca, guest_tls_cert, and guest_tls_key inherited from gateway scope."
schema_v2_contract = "The gateway CA is gateway-owned and injected into the selected Docker, Podman, or VM driver for supervisor TLS; legacy client certificate fields and driver-local guest TLS fields are rejected."
migration = "Keep guest_tls_ca under [openshell.gateway] only and remove guest_tls_cert and guest_tls_key. Supervisors authenticate gateway RPCs with sandbox bearer credentials."
rationale = "Gateway TLS trust is separate from sandbox identity. Centralized CA validation supplies supervisor trust without exposing a user client certificate or private key."
parity_disposition = "intentional_change"
validation_capability_ids = ["guest-callback-tls-ownership"]
[[intentional_changes]]
id = "middleware-payload-name-normalized"
category = "rename_with_alias"
origin_main_contract = "Supervisor middleware uses max_body_bytes while gateway interceptors use max_response_bytes."
schema_v2_contract = "Supervisor middleware uses max_payload_bytes and continues accepting max_body_bytes as a compatibility alias."
migration = "Prefer max_payload_bytes in new configuration; existing max_body_bytes remains accepted."
rationale = "Payload describes middleware data more accurately without forcing an immediate compatibility break."
parity_disposition = "intentional_change"
validation_capability_ids = ["supervisor-middleware-registration"]
[[intentional_changes]]
id = "vm-sandbox-identity-selection"
category = "default_behavior"
origin_main_contract = "New VM sandboxes default to UID and GID 10001 when no explicit identity is configured."
schema_v2_contract = "New VM root filesystems use the image sandbox account when present and otherwise UID/GID 1000; persisted overlays retain recorded or recoverable identity and ambiguous state fails closed."
migration = "Set sandbox_uid and sandbox_gid for a fixed identity, or retain the generated owner marker with persistent VM state."
rationale = "Image-derived identity preserves filesystem ownership, while explicit state evidence avoids silently reassigning legacy overlays."
parity_disposition = "intentional_change"
validation_capability_ids = ["vm-launch-and-resource-configuration", "vm-guest-security-and-spiffe"]
[[intentional_changes]]
id = "package-default-only-auto-migration"
category = "migration_policy"
origin_main_contract = "Package-managed and operator-edited schema-v1 configuration may exist at upgrade time."
schema_v2_contract = "RPM and Homebrew automatically replace only recognized byte-identical package defaults; Debian and Snap preserve every legacy file and fail closed through read-only package preflight with explicit manual-migration guidance because their historical generated defaults have no safe provenance marker."
migration = "Automatically migrate recognized defaults, preserve every edited file, and require manual schema-v2 conversion when a package cannot prove that a legacy file is an untouched default."
rationale = "An upgrade must not overwrite operator intent merely because the old schema no longer parses."
parity_disposition = "intentional_change"
validation_capability_ids = ["rpm-schema-upgrade", "homebrew-debian-and-snap-upgrades"]
@@ -1,9 +0,0 @@
{
"accepted": true,
"baseline_commit": "74960ebfaeec4673885089ed995fad902459749f",
"baseline_success": true,
"candidate_commit": "0f08b5822e4da98c9ced3d4b0f2bf4f30dae28fd",
"candidate_success": true,
"classification": "pass",
"parity": true
}
@@ -1,152 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Step 8 records field-level Kubernetes evidence separately from the broader
# capability manifest. A core pass means both frozen schema v1 and schema v2
# successfully produced and executed the same observed Kubernetes resources.
# A platform-blocked field or value still requires its assigned qualifying lane.
manifest_version = 1
baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
validated_candidate_commit = "0f08b5822e4da98c9ced3d4b0f2bf4f30dae28fd"
core_comparison = "e2e/configs/gateway/schema-v2-kubernetes-core-comparison.json"
[[coverage]]
id = "shared-combined-core"
status = "pass"
lane = "kind-v1.36.1-rootless-podman-host-gateway"
fields = [
"namespace",
"default_image",
"image_pull_policy",
"image_pull_secrets",
"service_account_name",
"supervisor_image",
"supervisor_image_pull_policy",
"grpc_endpoint",
"ssh_socket_path",
"client_tls_secret_name",
"host_gateway_ip",
"sa_token_ttl_secs",
"workspace_mode",
"gateway_id",
"workspace_default_storage_size",
"workspace_storage_class",
"default_runtime_class_name",
"supervisor_sideload_method",
"topology",
"app_armor_profile",
"sandbox_uid",
"sandbox_gid",
]
evidence = [
"Both variants reached Ready through ServiceAccount-token exchange and gateway-minted JWT authentication, then completed callback exec.",
"The API oracle matched images, Kubernetes pull-policy spelling, pull Secret, ServiceAccount, callback and SSH environment, client TLS mount, host aliases, 600-second token projection, runc RuntimeClass, Unconfined AppArmor request, UID/GID environment, CPU/memory, managed metadata, Bound 64Mi standard PVC, and deletion.",
"The normalized baseline and candidate results are byte-identical; comparison.json records both successes, parity=true, classification=pass, and accepted=true.",
]
[[coverage]]
id = "operator-namespace-discovery"
status = "platform_blocked"
owner = "OpenShell Kubernetes workspace-mode CI"
lane = "managed-and-operator-workspace-matrix"
fields = ["operator_namespace_label", "operator_namespace_file"]
requirement = "Run paired managed and operator workspace lifecycles with isolated namespace RBAC, label discovery, allowlist hot reload, positive placement, and negative rejection probes."
[[coverage]]
id = "managed-ssh-ingress"
status = "platform_blocked"
owner = "OpenShell Kubernetes network-policy CI"
lane = "managed-workspace-network-policy"
fields = [
"managed_ssh_ingress.enabled",
"managed_ssh_ingress.gateway_namespace",
"managed_ssh_ingress.gateway_pod_selector",
]
requirement = "Run paired managed-workspace creation and inspect the generated NetworkPolicy while proving the configured gateway selector can connect and a nonmatching pod cannot."
[[coverage]]
id = "sidecar-topology"
status = "platform_blocked"
owner = "OpenShell Kubernetes sidecar CI"
lane = "kubernetes-sidecar-network-enforcement"
fields = ["sidecar.proxy_uid", "sidecar.process_binary_aware_network_policy"]
requirement = "Run paired sidecar topology with relaxed and process-aware policy profiles and verify pod security context, proxy UID, network init, and enforcement behavior."
[[coverage]]
id = "authenticated-upstream-proxy"
status = "platform_blocked"
owner = "OpenShell Kubernetes proxy CI"
lane = "kubernetes-authenticated-connect-proxy"
fields = [
"https_proxy",
"no_proxy",
"proxy_auth_secret_name",
"proxy_auth_secret_key",
"proxy_auth_allow_insecure",
"proxy_connect_by_hostname",
]
requirement = "Provide an authenticated HTTP CONNECT proxy and Secret, then run paired allow, deny, no-proxy, credential, insecure-opt-in, and hostname-resolution probes."
[[coverage]]
id = "spiffe-workload-api"
status = "platform_blocked"
owner = "OpenShell SPIRE Kubernetes CI"
lane = "kubernetes-spire-csi"
fields = ["provider_spiffe_workload_api_socket_path"]
requirement = "Provide SPIRE and its CSI driver, then run paired gateway and sandbox JWT-SVID acquisition from the allowed Workload API socket path and reject a disallowed path."
[[coverage]]
id = "user-namespace-isolation"
status = "platform_blocked"
owner = "OpenShell Kubernetes userns CI"
lane = "kubernetes-userns-supported-runtime"
fields = ["enable_user_namespaces"]
requirement = "Run paired hostUsers=false lifecycle and host-ID mapping probes on a node whose kernel, kubelet, and runtime support Kubernetes user namespaces."
[[qualified_value]]
id = "managed-and-operator-workspace-values"
field = "workspace_mode"
status = "platform_blocked"
owner = "OpenShell Kubernetes workspace-mode CI"
lane = "managed-and-operator-workspace-matrix"
requirement = "The local core pass exercised shared mode; managed namespace creation and operator placement/rejection remain assigned live checks."
[[qualified_value]]
id = "image-volume-sideload"
field = "supervisor_sideload_method"
status = "platform_blocked"
owner = "OpenShell Kubernetes version matrix"
lane = "kubernetes-image-volume"
requirement = "The local core pass exercised init-container; run paired image-volume lifecycle on a cluster with the ImageVolume feature enabled."
[[qualified_value]]
id = "sidecar-topology-value"
field = "topology"
status = "platform_blocked"
owner = "OpenShell Kubernetes sidecar CI"
lane = "kubernetes-sidecar-network-enforcement"
requirement = "The local core pass exercised combined topology; sidecar requires its enforcement fixture and positive/negative network probes."
[[qualified_value]]
id = "apparmor-enforcement"
field = "app_armor_profile"
status = "platform_blocked"
owner = "OpenShell Kubernetes AppArmor CI"
lane = "kubernetes-apparmor-runtime-default-localhost"
requirement = "The local core pass proved Unconfined API projection; an AppArmor-enabled node with an installed localhost profile must prove RuntimeDefault and Localhost enforcement."
[[qualified_value]]
id = "runtime-class-isolation"
field = "default_runtime_class_name"
status = "platform_blocked"
owner = "OpenShell Kubernetes confidential-runtime CI"
lane = "kubernetes-kata-runtimeclass"
requirement = "The local core pass proved runc RuntimeClass placement; a configured Kata or equivalent runtime must prove isolation-specific lifecycle behavior."
[[qualified_value]]
id = "gpu-resource-combinations"
field = "create-request.resources.gpu"
status = "platform_blocked"
owner = "OpenShell Kubernetes GPU CI"
lane = "kubernetes-nvidia-device-plugin"
requirement = "Provide NVIDIA GPU nodes and the device plugin, then run paired GPU count/resource-name combinations and verify scheduling, limits, execution, and cleanup."
@@ -1,355 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
manifest_version = 1
baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
candidate_start_commit = "8c868e430e9cd3284d7e274628419ab484ebcee0"
# Step 5 establishes the portable status/create/Ready/list/exec/delete/list-empty
# contract. A platform-blocked result is not parity evidence; each blocked row
# names the lane that must replace it before the final release gate can pass.
[[result]]
id = "portable-lifecycle-podman"
step = 5
capability = "Portable sandbox lifecycle on the in-tree Podman compute driver"
driver = "podman"
status = "pass"
validated_baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
validated_candidate_commit = "a3860084d019ed2ac979e3eaa1ddf085a96b773c"
lane = "local-linux-x86_64-rootless-podman-5.8.2"
evidence = [
"Paired conformance smoke connected with authenticated mTLS on both variants.",
"Both variants passed status, create, Ready inspection, paginated list visibility, exact-output exec, delete, and eventual empty-list checks.",
"Normalized comparison recorded baseline_success=true, candidate_success=true, and parity=true; equal failures are rejected by the harness.",
]
[[result]]
id = "portable-lifecycle-docker"
step = 5
capability = "Portable sandbox lifecycle on the in-tree Docker compute driver"
driver = "docker"
status = "platform_blocked"
owner = "OpenShell Linux Docker CI lane"
lane = "linux-x86_64-docker"
blocker = "The validation host has no Docker CLI or Docker daemon socket. Step 7 and Step 13 must execute and assign this lane."
[[result]]
id = "portable-lifecycle-kubernetes"
step = 5
capability = "Portable sandbox lifecycle on the in-tree Kubernetes compute driver"
driver = "kubernetes"
status = "platform_blocked"
owner = "OpenShell Kubernetes CI lane"
lane = "ephemeral-kind-or-managed-kubernetes"
blocker = "The active kubectl context is an external OpenShift cluster that this validation must not modify. The installed kind cluster belongs to another project; Step 8 and Step 13 must use a dedicated OpenShell cluster."
[[result]]
id = "portable-lifecycle-vm"
step = 5
capability = "Portable sandbox lifecycle on the standalone VM compute driver"
driver = "vm"
status = "platform_blocked"
owner = "OpenShell Linux VM CI lane"
lane = "linux-x86_64-kvm-libkrun"
blocker = "The validation host has no prepared VM runtime bundle or built openshell-driver-vm executable. Step 9 and Step 13 must execute and assign this lane."
[[result]]
id = "portable-lifecycle-mxc"
step = 5
capability = "Portable sandbox lifecycle on the Windows MXC compute driver"
driver = "mxc"
status = "platform_blocked"
owner = "OpenShell Windows MXC CI lane"
lane = "windows-x64-and-windows-arm64-mxc"
blocker = "The validation host is Linux and cannot execute the Windows MXC runtime. Step 13 must assign native Windows validation."
[[result]]
id = "gateway-wide-process-options"
step = 6
capability = "Gateway listeners, configuration precedence, persistence, and legacy singleton selector"
driver = "gateway"
status = "pass"
validated_baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
validated_candidate_commit = "e6aac1aa7c624c5df43535ab4fbe2bc6f9697dea"
lane = "local-linux-x86_64-rootless-podman-5.8.2"
evidence = [
"Fresh binaries from both recorded commits started against isolated schema-v1 and schema-v2 files, SQLite databases, ports, state directories, and a rootless Podman socket.",
"Both variants exposed primary, health, and metrics listeners; the CLI primary port beat conflicting environment and file values, and --health-port 0 disabled the file-configured auxiliary listener.",
"Both variants created and reopened the same isolated SQLite database, rejected database_url in TOML, identified the rejected field, and did not disclose its secret-bearing value.",
"Both variants accepted one legacy OPENSHELL_DRIVERS=podman selector when no canonical selector was present; the candidate emitted its deprecation warning without logging the value.",
"Normalized comparison recorded baseline_success=true, candidate_success=true, and parity=true.",
]
[[result]]
id = "gateway-tls-client-auth-policy"
step = 6
capability = "Gateway TLS client-certificate handshake policy"
driver = "gateway"
status = "intentional_change"
validated_baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
validated_candidate_commit = "e6aac1aa7c624c5df43535ab4fbe2bc6f9697dea"
lane = "local-linux-x86_64-deterministic-tls"
evidence = [
"Security review confirmed that origin/main accepted require_client_auth in TOML but ignored it and instead derived runtime policy from client CA and OIDC presence.",
"Schema v2 now rejects the unsupported file field while preserving the established derived policy: CA without OIDC requires a client certificate, while CA with OIDC permits bearer-only clients and validates certificates that are presented.",
"Focused preparation tests cover both derived branches, and TLS integration tests pass required-certificate, optional-certificate, valid-CA, wrong-CA, and multiplexed HTTP/gRPC handshakes.",
]
[[result]]
id = "docker-driver-option-parity"
step = 7
capability = "Docker image, callback, pull-policy, resource, security, provider, and mount options"
driver = "docker"
status = "platform_blocked"
owner = "OpenShell Linux Docker CI lane"
lane = "linux-x86_64-docker-with-apparmor-sub-lane"
blocker = "The validation host has neither a Docker CLI nor a Docker daemon, and the Docker driver deliberately rejects the available Libpod socket. A dedicated Docker lane must run paired lifecycle and inspect-based resource, label, mount, callback, and pull-policy checks; candidate-only AppArmor, authenticated proxy, and SPIFFE checks must run on qualifying daemons."
[[result]]
id = "podman-driver-option-parity"
step = 7
capability = "Podman image, callback, pull-policy, resource, mount, bootstrap, SSH, and health options"
driver = "podman"
status = "intentional_change"
validated_baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
validated_candidate_commit = "e09070d4ba0b30f0ac278fbb9938c1520ecff696"
lane = "local-linux-x86_64-rootless-podman-5.8.2"
evidence = [
"Fresh binaries from both recorded commits ran the same candidate-owned oracle against isolated schema-v1 and schema-v2 gateway processes, state, PKI, sockets, networks, and container stores.",
"Both variants selected the same immutable sandbox image, mapped their schema-specific pull-policy spelling to Podman missing, applied 750m CPU and 384Mi memory limits, preserved managed labels, mounted read-only bind and tmpfs configuration, injected sandbox-token and guest-TLS bootstrap files, used the renamed SSH socket, became healthy at the configured seven-second interval, and completed callback exec.",
"The normalized results were identical except for pids_limit: the frozen baseline accepted 31 but sent Docker's ignored PidsLimit field and received Podman's 2048 default, while the candidate sent OCI resource_limits.pids.limit and applied 31.",
"comparison.json recorded baseline_success=true, candidate_success=true, parity=false, classification=intentional_change, intentional_change_id=podman-pid-limit-restored, and accepted=true.",
]
[[result]]
id = "podman-qualified-security-option-parity"
step = 7
capability = "Podman AppArmor, authenticated proxy, SPIFFE, and rootful user-namespace options"
driver = "podman"
status = "platform_blocked"
owner = "OpenShell Podman security matrix"
lane = "linux-podman-apparmor-proxy-spiffe-rootful-userns"
blocker = "The available daemon is rootless and reports AppArmor disabled, and this local run has no authenticated proxy or SPIFFE Workload API fixture. A qualifying rootful matrix must validate those environment-dependent options live; deterministic driver tests remain coverage, not parity evidence."
[[result]]
id = "kubernetes-core-option-parity"
step = 8
capability = "Kubernetes shared workspace, images, placement, bootstrap, security projection, resources, and combined supervisor options"
driver = "kubernetes"
status = "pass"
validated_baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
validated_candidate_commit = "0f08b5822e4da98c9ced3d4b0f2bf4f30dae28fd"
lane = "kind-v1.36.1-rootless-podman-host-gateway"
evidence = [
"Fresh candidate gateway and CLI binaries were built from the recorded candidate commit and bound by SHA-256, with the frozen baseline binary, in the retained artifact manifest.",
"Both host gateway variants used isolated schema-v1/schema-v2 files, SQLite stores, JWT keys, ports, namespaces, ServiceAccounts, Secrets, and resource names against a guarded disposable kind cluster.",
"Both variants reached Ready through authenticated callback, completed exact-marker exec, and produced matching Sandbox, Pod, and PVC semantics for images and pull policies, pull Secret, ServiceAccount, TLS and token projections, host aliases, SSH endpoint, runc placement, AppArmor request, UID/GID, CPU/memory, shared storage, managed metadata, and deletion.",
"comparison.json recorded baseline_success=true, candidate_success=true, parity=true, classification=pass, and accepted=true; private keys and all per-run Kubernetes fixtures were removed.",
]
[[result]]
id = "kubernetes-qualified-option-parity"
step = 8
capability = "Kubernetes managed/operator workspaces, sidecar enforcement, proxy, SPIFFE, user namespaces, AppArmor enforcement, confidential runtimes, and GPUs"
driver = "kubernetes"
status = "platform_blocked"
owner = "OpenShell Kubernetes qualified option matrix"
lane = "kubernetes-managed-operator-sidecar-proxy-spire-userns-apparmor-kata-gpu"
blocker = "The disposable core lane executed shared, combined, init-container, runc, and Unconfined values but did not execute the infrastructure-qualified alternatives. Assigned lanes must run paired managed/operator namespace discovery, sidecar network enforcement, authenticated proxy, SPIRE CSI, hostUsers=false, AppArmor RuntimeDefault/Localhost, image-volume, Kata RuntimeClass, and NVIDIA device-plugin GPU probes."
[[result]]
id = "vm-launch-and-resource-configuration"
step = 9
capability = "VM launch, callback, persistent state, images, resources, and guest identity"
driver = "vm"
status = "platform_blocked"
owner = "OpenShell Linux VM CI lane"
lane = "linux-x86_64-kvm-libkrun"
blocker = "This host has no prepared VM runtime bundle and no frozen-baseline or candidate openshell-driver-vm executable linked to a runnable libkrun environment. Both source trees passed their deterministic VM library suites, but only a paired KVM/libkrun lane can prove Ready, exec, restart recovery, overlay persistence, resource sizing, callback equivalence, and deletion."
[[result]]
id = "vm-guest-security-and-spiffe"
step = 9
capability = "VM guest token containment, TLS, owner state, proxy credentials, and SPIFFE opt-in"
driver = "vm"
status = "platform_blocked"
owner = "OpenShell Linux VM security CI lane"
lane = "linux-x86_64-kvm-libkrun-proxy-spiffe"
blocker = "The guest JWT mode and visibility, private owner-marker and sandbox-state persistence, callback recovery, TLS key permissions, proxy credential containment, and guest-reachable SPIFFE TCP behavior require a booted VM. The assigned lane must add authenticated-proxy and Workload API TCP fixtures to the paired libkrun/KVM run."
[[result]]
id = "compute-driver-boundary-parity"
step = 10
capability = "In-tree and external-UDS compute-driver execution with sandbox callback connectivity"
driver = "podman"
status = "pass"
validated_baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
validated_candidate_commit = "4a39da510e4d278a24dd60291149519c9a570b46"
lane = "local-linux-x86_64-rootless-podman-5.8.2"
evidence = [
"Fresh exact-source gateway, CLI, conformance, Podman driver, and supervisor artifacts were staged before execution, hashed, executed from retained staging directories, and verified unchanged after execution.",
"Driver-free baseline and candidate gateways completed the same authenticated status, create, Ready, list, callback-exec, delete, and list-empty oracle through distinct-content external-driver executables over separate UDS endpoints; in-tree gateways completed the same oracle.",
"External drivers ran under env -i with a complete allowlisted environment attestation covering compute and Podman sockets, callback endpoint and TLS-file hashes, pull policy, images, network, timeouts, and bind mounts; successful driver logs were retained and hashed.",
"The verifier bound each transport-only gateway socket_path to the driver process input and required distinct baseline and candidate compute sockets, Podman sockets, networks, and callback TLS paths.",
"All four runs executed one repository-digest-pinned sandbox image and matched its image ID and manifest digest. They also matched the supervisor base-image identity, digest-pinned base reference, source Dockerfile, installed-package manifest, and same-source runtime artifacts across topologies.",
"Each variant built its supervisor image from its own staged supervisor binary in a forced temporary Podman service and isolated store; all supervisor runtime image references were digest-pinned.",
"A staged and hashed transparent CLI wrapper retained exact exec stdout bytes; the verifier tied them to the unique conformance run ID, required authenticated preflight and every lifecycle exit 0, and hashed result, launch, driver, raw-log, exec-stdout, gateway-configuration, package, and staged-artifact evidence.",
]
# Step 11 inventories the remaining cross-cutting capabilities. Paired
# deterministic suites passed, but they are regression preflight rather than
# live parity evidence. Every row therefore remains assigned to a live lane.
[[result]]
id = "oidc-bearer-authentication"
step = 11
capability = "OIDC bearer token validation, role and scope authorization, and JWKS refresh"
driver = "auth"
status = "platform_blocked"
owner = "OpenShell auth and OIDC CI lane"
lane = "linux-oidc-paired-keycloak-jwks"
blocker = "The host has no isolated paired issuer fixture that presents equivalent signed tokens to both exact-source gateways. Existing Keycloak and OIDC suites are candidate-oriented and cannot establish schema-v1/schema-v2 audience, role, scope, expiry, signature, and key-rotation parity without a shared candidate-owned oracle."
[[result]]
id = "mtls-user-authentication"
step = 11
capability = "mTLS client-certificate user identity and authorization"
driver = "auth"
status = "platform_blocked"
owner = "OpenShell gateway authentication CI lane"
lane = "linux-mtls-user-principal-paired"
blocker = "The paired TLS integration tests validate handshake policy but do not drive an authenticated user RPC through both gateways or prove certificate-to-principal mapping. A live lane must use isolated client PKI, equivalent schema files, and the same authorization oracle for enabled and disabled mTLS user authentication."
[[result]]
id = "unsafe-unauthenticated-user-mode"
step = 11
capability = "Explicit trusted-development unauthenticated user mode with authenticated sandbox callbacks"
driver = "auth"
status = "platform_blocked"
owner = "OpenShell gateway authentication CI lane"
lane = "linux-auth-chain-paired-isolated"
blocker = "No paired live fixture currently proves that the trusted-development switch admits user requests while sandbox callbacks continue to require sandbox credentials. Candidate-only extension examples use this switch for setup, but that is not an authentication-boundary parity test."
[[result]]
id = "gateway-minted-sandbox-jwt"
step = 11
capability = "Gateway-minted sandbox and extension JWT claims and lifetime semantics"
driver = "auth"
status = "platform_blocked"
owner = "OpenShell gateway JWT CI lane"
lane = "linux-gateway-jwt-claims-paired"
blocker = "Step 10 proved authenticated callback connectivity but did not capture and compare token claims. A controlled callback and extension fixture must verify issuer, gateway identity, key ID, audience, subject, token type, and expiry semantics for both gateways; explicit zero versus omitted TTL remains the ledgered gateway-jwt-zero-sentinel-removed intentional change."
[[result]]
id = "otlp-observability"
step = 11
capability = "Gateway and in-tree driver OTLP traces and failure isolation"
driver = "observability"
status = "platform_blocked"
owner = "OpenShell observability CI lane"
lane = "linux-otlp-grpc-collector-paired"
blocker = "The deterministic exporter tests passed, but no retained paired collector capture proves emitted gateway and in-tree-driver spans, gateway name, service name, selected-driver resource attributes, or continued serving after collector failure. A loopback OTLP/gRPC collector lane must observe those outcomes from both exact-source processes."
[[result]]
id = "gateway-interceptor-registration"
step = 11
capability = "Gateway interceptor registration, binding, mutation, and failure behavior"
driver = "gateway-interceptor"
status = "platform_blocked"
owner = "OpenShell gateway interceptor CI lane"
lane = "linux-gateway-interceptor-paired"
blocker = "The interceptor library suite passed on both revisions, while the governance-interceptor smoke test remains candidate-only. A paired service must compare Describe validation, binding selection, unary request and response mutation, failure policy, timeout and size limits, and secret exclusion against both gateway schema variants."
[[result]]
id = "supervisor-middleware-registration"
step = 11
capability = "Supervisor middleware registration, policy distribution, and enforcement"
driver = "supervisor-middleware"
status = "platform_blocked"
owner = "OpenShell supervisor middleware CI lane"
lane = "linux-supervisor-middleware-paired"
blocker = "The middleware library suite passed on both revisions, while the content-guard smoke test remains candidate-only. A paired gateway, sandbox, and middleware fixture must compare Describe negotiation, policy distribution, guarded and unguarded traffic, failure policy, timeout, and payload limits; the field-name normalization remains the ledgered middleware-payload-name-normalized intentional change."
[[result]]
id = "provider-profile-sources"
step = 11
capability = "Builtin, user, and interceptor provider-profile source composition"
driver = "provider-profiles"
status = "platform_blocked"
owner = "OpenShell provider profile CI lane"
lane = "linux-provider-profiles-interceptor-paired"
blocker = "Server tests cover source construction and duplicate rejection, but no shared live interceptor catalog has been queried through both gateways. The assigned lane must compare builtin, user, and interceptor source ordering, normalized profile identities, duplicate rejection, discovery output, and failure handling with isolated persistent state."
[[result]]
id = "inference-control-plane-configuration"
step = 11
capability = "Persisted provider and route configuration delivered to sandbox inference"
driver = "inference"
status = "platform_blocked"
owner = "OpenShell inference E2E lane"
lane = "linux-inference-provider-routing-paired"
blocker = "Existing inference routing tests are candidate-oriented and this host has no assigned paired provider and model-service fixture. The lane must configure providers and routes through each gateway control plane, observe the effective supervisor bundle, and compare model discovery and an inference request without reusing database state."
[[result]]
id = "credential-driver-selection-and-kek"
step = 11
capability = "Credential-driver selection, KEK handling, encrypted storage, and secret containment"
driver = "credentials"
status = "platform_blocked"
owner = "OpenShell credential security CI lane"
lane = "linux-credential-kek-paired"
blocker = "Both server suites passed deterministic selection, KEK, and credential tests, but they are revision-local tests rather than one candidate-owned live oracle. A paired lane must start isolated gateways with independent databases and KEKs, compare default encrypted storage and invalid selections, store and resolve opaque credentials, and verify that logs and configuration do not disclose secrets."
[[result]]
id = "credential-driver-backend-tables"
step = 11
capability = "In-tree and remote credential-driver transport and opaque credential lifecycle"
driver = "credential-driver"
status = "platform_blocked"
owner = "OpenShell credential driver E2E lane"
lane = "kubernetes-vault-uds-credential-drivers-paired"
blocker = "The host has no assigned disposable Kubernetes Secrets or Vault backend and no retained paired UDS credential-driver execution. Existing backend E2E coverage is candidate-oriented. The assigned lane must compare in-tree and remote transport validation plus opaque store and retrieve behavior using isolated namespaces, Vault state, sockets, databases, and credentials."
# Step 12 resolves deterministic package-startup blockers without claiming that
# source-tree tests substitute for installation, upgrade, or refresh evidence.
[[result]]
id = "rpm-package-upgrade"
step = 12
capability = "RPM schema-v1 default migration and operator-edited configuration preservation"
driver = "packaging"
status = "platform_blocked"
owner = "OpenShell RPM package upgrade CI lane"
lane = "fedora-rpm-prior-release-upgrade"
blocker = "Deterministic migration tests prove exact-default replacement, edited-file preservation, mode preservation, idempotence, and unsafe-path rejection, but no prior RPM was installed and upgraded on this host. The assigned lane must verify package ownership and permissions, service restart, exact and edited schema-v1 files, and rollback-safe failure behavior."
[[result]]
id = "debian-package-upgrade"
step = 12
capability = "Debian prior-artifact upgrade with schema-v1 configuration preservation"
driver = "packaging"
status = "platform_blocked"
owner = "OpenShell Debian package upgrade CI lane"
lane = "ubuntu-debian-prior-release-upgrade"
blocker = "The source-tree tests prove Debian preflight selection, source-free diagnostics, non-mutation, and ordering before certificate generation, but dpkg-deb and an installed prior Debian artifact are unavailable. The assigned lane must preserve generated and edited schema-v1 files, exercise manual conversion, and prove successful schema-v2 service restart after upgrade."
[[result]]
id = "snap-package-refresh"
step = 12
capability = "Snap prior-release refresh with schema-v1 configuration preservation"
driver = "packaging"
status = "platform_blocked"
owner = "OpenShell Snap refresh CI lane"
lane = "ubuntu-snap-prior-release-refresh"
blocker = "The source-tree tests prove Snap config precedence, preflight failure handling, and non-mutation, but this host cannot install and refresh confined Snap revisions. The assigned lane must refresh a prior Snap with generated and edited schema-v1 files, exercise manual conversion, and prove successful schema-v2 daemon startup."
[[result]]
id = "homebrew-package-upgrade"
step = 12
capability = "Homebrew prior-release upgrade with package-default and operator configuration preservation"
driver = "packaging"
status = "platform_blocked"
owner = "OpenShell macOS Homebrew package upgrade CI lane"
lane = "macos-homebrew-prior-release-upgrade"
blocker = "No Homebrew formula installation or prior-release upgrade ran on this Linux host. The assigned macOS lane must upgrade a prior formula with recognized package defaults and edited schema-v1 configuration, verify only provable defaults migrate automatically, and prove successful schema-v2 service restart."
@@ -1,106 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Reviewed potential blockers for the schema-v2 parity campaign. A disposition
# records whether the branch must change before parity can be claimed; it does
# not record test execution results.
ledger_version = 1
issue = 2792
baseline_commit = "74960ebfaeec4673885089ed995fad902459749f"
candidate_start_commit = "8c868e430e9cd3284d7e274628419ab484ebcee0"
[[gaps]]
id = "legacy-environment-selector-upgrade"
severity = "none"
parity_relation = "regression"
disposition = "resolved"
origin_main_behavior = "OPENSHELL_DRIVERS accepts one driver name and is loaded by RPM, Debian, and Homebrew gateway services through gateway.env."
candidate_behavior = "Schema v2 accepts one non-empty OPENSHELL_DRIVERS value as a deprecated environment-only alias, rejects ambiguity and conflicts, and keeps removed CLI flags rejected."
impact = "The package-upgrade regression is resolved while preserving singular selector semantics and actionable migration guidance."
resolution = "The gateway now accepts one non-empty OPENSHELL_DRIVERS value, preserves canonical selector precedence, rejects multiple values and conflicting canonical and legacy values, and emits one deprecation warning after tracing initialization without logging the selector."
validation = "Paired frozen-baseline and candidate processes reached readiness through OPENSHELL_DRIVERS=podman; focused tests cover empty, plural, malformed, non-UTF-8, equal canonical, conflicting canonical, and remote-socket cases."
owner_step = 6
[[gaps]]
id = "debian-snap-v1-upgrade"
severity = "none"
parity_relation = "upgrade_regression"
disposition = "resolved"
origin_main_behavior = "Debian auto-discovers a persistent schema-v1 XDG gateway.toml and Snap passes a persistent schema-v1 SNAP_COMMON gateway.toml."
candidate_behavior = "Debian and Snap run the gateway's source-free, read-only preflight against the same effectively selected config before certificate generation or daemon startup; rejected legacy files, schema/layout errors, and documented cross-field startup errors remain unchanged with actionable migration guidance. Selected driver-specific fields remain lazily validated at driver construction."
impact = "The package startup regression is resolved without inferring provenance or overwriting operator-owned configuration; release remains gated on real Debian upgrade and Snap refresh execution."
resolution = "Use the shared strict schema-v2 layout parser plus documented read-only effective startup checks, fail closed for explicit, unsafe, or legacy paths, preserve optional absence, and require manual migration because historical Debian and Snap generators have no safe default-provenance marker."
validation = "Deterministic Rust, shell, and Python tests cover selection precedence, stable diagnostics, content non-disclosure, semantic checks, file preservation, and package ordering. Real prior Debian upgrade and Snap refresh lanes remain platform-blocked and must verify preserved v1 files plus successful restart after manual conversion."
owner_step = 12
[[gaps]]
id = "tls-require-client-auth-ignored"
severity = "none"
parity_relation = "preexisting_inaccessible_option"
disposition = "resolved"
origin_main_behavior = "The TOML schema accepts and documents require_client_auth, but runtime derives the value from client CA presence and OIDC instead of using the configured boolean."
candidate_behavior = "Schema v2 rejects require_client_auth and documents the derived client CA and OIDC policy instead of silently accepting an ineffective security option."
impact = "The misleading security-sensitive configuration claim is removed without weakening CA-only gateways or breaking bearer-only OIDC clients."
resolution = "Security review selected removal over runtime wiring: the file-only TLS schema excludes require_client_auth while the internal runtime field continues enforcing the established client CA and OIDC policy."
validation = "File parsing rejects require_client_auth; preparation tests cover CA-only and CA-plus-OIDC derivation; TLS integration tests cover required, optional, valid-CA, wrong-CA, and no-certificate handshakes."
owner_step = 6
[[gaps]]
id = "unselected-driver-validation-claim"
severity = "none"
parity_relation = "documentation_gap"
disposition = "resolved"
origin_main_behavior = "Only the selected driver table receives driver-specific deserialization; unknown fields inside an unselected table are ignored."
candidate_behavior = "Schema v2 validates every driver entry is a table and lazily validates driver-specific fields only when that driver is selected, as the reference now states."
impact = "The documentation now distinguishes table-shape validation from selected-driver deserialization, so it no longer overstates startup guarantees."
resolution = "The gateway configuration reference was narrowed to state that driver-specific fields are validated when their driver is selected."
validation = "Configuration tests establish that every driver entry must be a TOML table and that selected driver tables reject unknown fields; the published reference describes the lazy boundary."
owner_step = 6
[[gaps]]
id = "multi-driver-runtime-loss"
severity = "none"
parity_relation = "non_finding"
disposition = "no_action"
origin_main_behavior = "Schema v1 accepts a list-shaped selector but runtime rejects configurations containing more than one driver."
candidate_behavior = "Schema v2 represents the existing invariant as one optional scalar driver."
impact = "No working multi-driver runtime capability was removed."
resolution = "Keep the singular selector in the intentional-change ledger and validate explicit selection plus auto-detection."
validation = "Confirm origin/main rejects two configured drivers and the candidate supports one scalar or omission."
owner_step = 5
[[gaps]]
id = "generated-e2e-selector-shape"
severity = "none"
parity_relation = "non_finding"
disposition = "no_action"
origin_main_behavior = "Committed E2E fixtures select one driver through the schema-v1 list."
candidate_behavior = "Committed Docker and Podman fixtures and e2e/run.sh consistently use and require the schema-v2 scalar selector."
impact = "No committed fixture mismatch was found."
resolution = "Use the existing fixtures in live Docker and Podman parity lanes."
validation = "Run both driver E2E wrappers and confirm the selected runtime creates a sandbox."
owner_step = 5
[[gaps]]
id = "rpm-exact-default-migration"
severity = "none"
parity_relation = "non_finding"
disposition = "no_action"
origin_main_behavior = "The RPM service seeds its package-owned schema-v1 default."
candidate_behavior = "The RPM pre-start migrator replaces only a byte-identical package v1 default and preserves edited or unsafe paths."
impact = "The implemented exact-default path does not block parity, but environment-file and edited-config behavior remain covered by separate gaps."
resolution = "Retain deterministic migration tests and add a real package upgrade lane."
validation = "Upgrade an installed prior RPM with exact and edited defaults and verify restart, bytes, ownership, and mode."
owner_step = 12
[[gaps]]
id = "gateway-owned-guest-tls"
severity = "none"
parity_relation = "non_finding"
disposition = "no_action"
origin_main_behavior = "Guest callback TLS may be inherited from gateway scope or overridden in the selected local driver table."
candidate_behavior = "One complete gateway-owned bundle is validated and injected into the selected local driver; misplaced driver fields fail explicitly."
impact = "The ownership change fails closed rather than silently disabling callback TLS."
resolution = "Keep the ownership change in the intentional-change ledger and validate callback connectivity on Docker, Podman, and VM."
validation = "Exercise complete, partial, misplaced, and plaintext combinations, then establish a real sandbox callback on each local driver."
owner_step = 10
@@ -1,101 +0,0 @@
schema_v2_step11_deterministic_attestation_version=1
variant=baseline
source_commit=74960ebfaeec4673885089ed995fad902459749f
source_tree_clean=true
cargo_target_scope=checkout-local
rustc_wrapper=disabled
cargo 1.95.0 (f2d3ce0bd 2026-03-21)
rustc 1.95.0 (59807616e 2026-04-14)
=== suite:server-lib ===
command=cargo test -q -p openshell-server --lib
--- output ---
running 1463 tests
....................................................................................... 87/1463
....................................................................................... 174/1463
...............................................................................i....... 261/1463
......................i................................................................ 348/1463
..............................................................................i........ 435/1463
....................................................................................... 522/1463
....................................................................................... 609/1463
....................................................................................... 696/1463
....................................................................................... 783/1463
......................................................................................i 870/1463
....................................................................................... 957/1463
....................................................................................... 1044/1463
....................................................................................... 1131/1463
................................................................................i...... 1218/1463
.........................................ii............................................ 1305/1463
...............................i....................................................... 1392/1463
.......................................................................
test result: ok. 1455 passed; 0 failed; 8 ignored; 0 measured; 0 filtered out; finished in 9.13s
--- exit_status:0 ---
=== suite:gateway-interceptors ===
command=cargo test -q -p openshell-gateway-interceptors
--- output ---
running 49 tests
.................................................
test result: ok. 49 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.32s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
--- exit_status:0 ---
=== suite:supervisor-middleware ===
command=cargo test -q -p openshell-supervisor-middleware
--- output ---
running 85 tests
.....................................................................................
test result: ok. 85 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.52s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
--- exit_status:0 ---
=== suite:otel-test-support ===
command=cargo test -q -p openshell-otel-test-support
--- output ---
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
--- exit_status:0 ---
=== suite:multiplex-tls-integration ===
command=cargo test -q -p openshell-server --test multiplex_tls_integration
--- output ---
running 5 tests
.....
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s
--- exit_status:0 ---
=== suite:edge-tunnel-auth ===
command=cargo test -q -p openshell-server --test edge_tunnel_auth
--- output ---
running 5 tests
.....
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s
--- exit_status:0 ---
attestation_complete=true
@@ -1,102 +0,0 @@
schema_v2_step11_deterministic_attestation_version=1
variant=candidate
source_commit=363d8540830b2ea294d43198daa2b7a283a2face
source_tree_clean=true
cargo_target_scope=checkout-local
rustc_wrapper=disabled
cargo 1.95.0 (f2d3ce0bd 2026-03-21)
rustc 1.95.0 (59807616e 2026-04-14)
=== suite:server-lib ===
command=cargo test -q -p openshell-server --lib
--- output ---
running 1489 tests
....................................................................................... 87/1489
....................................................................................... 174/1489
....................................................................................... 261/1489
...........i.............................i............................................. 348/1489
....................................................................................... 435/1489
................i...................................................................... 522/1489
....................................................................................... 609/1489
....................................................................................... 696/1489
....................................................................................... 783/1489
....................................................................................... 870/1489
........................i.............................................................. 957/1489
....................................................................................... 1044/1489
....................................................................................... 1131/1489
....................................................................................... 1218/1489
..................i...............................................ii................... 1305/1489
........................................................i.............................. 1392/1489
....................................................................................... 1479/1489
..........
test result: ok. 1481 passed; 0 failed; 8 ignored; 0 measured; 0 filtered out; finished in 9.12s
--- exit_status:0 ---
=== suite:gateway-interceptors ===
command=cargo test -q -p openshell-gateway-interceptors
--- output ---
running 49 tests
.................................................
test result: ok. 49 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.27s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
--- exit_status:0 ---
=== suite:supervisor-middleware ===
command=cargo test -q -p openshell-supervisor-middleware
--- output ---
running 85 tests
.....................................................................................
test result: ok. 85 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
--- exit_status:0 ---
=== suite:otel-test-support ===
command=cargo test -q -p openshell-otel-test-support
--- output ---
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
--- exit_status:0 ---
=== suite:multiplex-tls-integration ===
command=cargo test -q -p openshell-server --test multiplex_tls_integration
--- output ---
running 5 tests
.....
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s
--- exit_status:0 ---
=== suite:edge-tunnel-auth ===
command=cargo test -q -p openshell-server --test edge_tunnel_auth
--- output ---
running 5 tests
.....
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.07s
--- exit_status:0 ---
attestation_complete=true
-224
View File
@@ -1,224 +0,0 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Paired process-level checks for gateway-wide options that do not require a
# sandbox. The caller supplies immutable baseline and candidate gateway builds.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
BASELINE_GATEWAY="${OPENSHELL_PARITY_BASELINE_GATEWAY_BIN:-}"
CANDIDATE_GATEWAY="${OPENSHELL_PARITY_CANDIDATE_GATEWAY_BIN:-}"
RESULTS_DIR="${OPENSHELL_PARITY_RESULTS_DIR:-${ROOT}/target/parity/gateway-options}"
BASELINE_SHA="74960ebfaeec4673885089ed995fad902459749f"
CANDIDATE_SHA="$(git -C "${ROOT}" rev-parse HEAD)"
WORKDIR="$(mktemp -d "${TMPDIR:-/tmp}/openshell-gateway-options.XXXXXX")"
PIDS=()
cleanup() {
local status=$? pid
for pid in "${PIDS[@]}"; do
kill -INT "${pid}" >/dev/null 2>&1 || true
wait "${pid}" >/dev/null 2>&1 || true
done
rm -rf "${WORKDIR}"
exit "${status}"
}
trap cleanup EXIT
fail() {
echo "ERROR: $*" >&2
exit 1
}
for binary in "${BASELINE_GATEWAY}" "${CANDIDATE_GATEWAY}"; do
[ -x "${binary}" ] || fail "gateway binary is not executable: ${binary:-<unset>}"
done
command -v curl >/dev/null 2>&1 || fail "curl is required"
command -v podman >/dev/null 2>&1 || fail "podman is required"
podman info >/dev/null 2>&1 || fail "podman service is not reachable"
PODMAN_SOCKET="${OPENSHELL_PODMAN_SOCKET:-${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/podman/podman.sock}"
[ -S "${PODMAN_SOCKET}" ] || fail "Podman API socket is unavailable: ${PODMAN_SOCKET}"
mkdir -p "${RESULTS_DIR}"
pick_port() {
python3 - <<'PY'
import socket
with socket.socket() as sock:
sock.bind(("127.0.0.1", 0))
print(sock.getsockname()[1])
PY
}
write_config() {
local output=$1 schema=$2 variant=$3 file_port=$4 health_port=$5 metrics_port=$6
cat >"${output}" <<EOF
[openshell]
version = ${schema}
[openshell.gateway]
name = "${variant}-file"
bind_address = "127.0.0.1:${file_port}"
health_bind_address = "127.0.0.1:${health_port}"
metrics_bind_address = "127.0.0.1:${metrics_port}"
log_level = "info"
disable_tls = true
EOF
if [ "${schema}" = 1 ]; then
printf 'compute_drivers = ["podman"]\n' >>"${output}"
else
printf 'compute_driver = "podman"\n' >>"${output}"
fi
cat >>"${output}" <<'EOF'
[openshell.gateway.auth]
allow_unauthenticated_users = true
[openshell.drivers.podman]
EOF
}
wait_for_url() {
local pid=$1 url=$2 log=$3 elapsed=0
while [ "${elapsed}" -lt 100 ]; do
if curl --noproxy '*' --max-time 1 -fsS "${url}" >/dev/null 2>&1; then
return 0
fi
if ! kill -0 "${pid}" >/dev/null 2>&1; then
echo "=== gateway log ===" >&2
cat "${log}" >&2 || true
return 1
fi
sleep 0.1
elapsed=$((elapsed + 1))
done
echo "timed out waiting for ${url}" >&2
cat "${log}" >&2 || true
return 1
}
stop_gateway() {
local pid=$1
kill -INT "${pid}" >/dev/null 2>&1 || true
wait "${pid}" >/dev/null 2>&1 || true
PIDS=()
}
run_variant() {
local variant=$1 schema=$2 sha=$3 gateway=$4
local dir="${WORKDIR}/${variant}"
local config="${dir}/gateway.toml" db="${dir}/gateway.db" log="${dir}/gateway.log"
local file_port env_port primary_port health_port metrics_port second_primary
mkdir -p "${dir}/state"
file_port="$(pick_port)"
env_port="$(pick_port)"
primary_port="$(pick_port)"
health_port="$(pick_port)"
metrics_port="$(pick_port)"
second_primary="$(pick_port)"
write_config "${config}" "${schema}" "${variant}" "${file_port}" "${health_port}" "${metrics_port}"
echo "==> ${variant}: precedence, listeners, and initial SQLite open"
XDG_CONFIG_HOME="${dir}/config" \
XDG_STATE_HOME="${dir}/state" \
OPENSHELL_PODMAN_SOCKET="${PODMAN_SOCKET}" \
OPENSHELL_SERVER_PORT="${env_port}" \
"${gateway}" \
--config "${config}" \
--db-url "sqlite:${db}?mode=rwc" \
--name "${variant}-cli" \
--port "${primary_port}" \
--log-level debug >"${log}" 2>&1 &
local pid=$!
PIDS=("${pid}")
wait_for_url "${pid}" "http://127.0.0.1:${health_port}/healthz" "${log}" \
|| fail "${variant} health listener did not start"
curl --noproxy '*' --max-time 2 -fsS "http://127.0.0.1:${metrics_port}/metrics" >/dev/null \
|| fail "${variant} metrics listener is unavailable"
# A plain HTTP request to the gRPC listener returns 404; successful TCP/HTTP
# exchange is sufficient to prove that the selected primary port is bound.
curl --noproxy '*' --max-time 2 -sS "http://127.0.0.1:${primary_port}/" >/dev/null \
|| fail "${variant} primary listener is unavailable"
if curl --noproxy '*' --max-time 1 -sS "http://127.0.0.1:${file_port}/" >/dev/null 2>&1; then
fail "${variant} file port unexpectedly beat the CLI port"
fi
if curl --noproxy '*' --max-time 1 -sS "http://127.0.0.1:${env_port}/" >/dev/null 2>&1; then
fail "${variant} environment port unexpectedly beat the CLI port"
fi
grep -F "127.0.0.1:${primary_port}" "${log}" >/dev/null \
|| fail "${variant} startup log did not identify the effective primary bind"
[ -s "${db}" ] || fail "${variant} SQLite database was not created"
stop_gateway "${pid}"
echo "==> ${variant}: SQLite reopen and health-port zero override"
: >"${log}"
XDG_CONFIG_HOME="${dir}/config" \
XDG_STATE_HOME="${dir}/state" \
OPENSHELL_PODMAN_SOCKET="${PODMAN_SOCKET}" \
"${gateway}" \
--config "${config}" \
--db-url "sqlite:${db}?mode=rwc" \
--port "${second_primary}" \
--health-port 0 >"${log}" 2>&1 &
pid=$!
PIDS=("${pid}")
wait_for_url "${pid}" "http://127.0.0.1:${metrics_port}/metrics" "${log}" \
|| fail "${variant} did not reopen its SQLite database"
if curl --noproxy '*' --max-time 1 -fsS "http://127.0.0.1:${health_port}/healthz" >/dev/null 2>&1; then
fail "${variant} health listener remained active after --health-port 0"
fi
stop_gateway "${pid}"
echo "==> ${variant}: legacy singleton environment selector"
local legacy_config="${dir}/legacy-selector.toml"
grep -v '^compute_driver' "${config}" >"${legacy_config}"
: >"${log}"
env -u OPENSHELL_COMPUTE_DRIVER \
XDG_CONFIG_HOME="${dir}/config" \
XDG_STATE_HOME="${dir}/state" \
OPENSHELL_PODMAN_SOCKET="${PODMAN_SOCKET}" \
OPENSHELL_DRIVERS=podman \
"${gateway}" \
--config "${legacy_config}" \
--db-url "sqlite:${db}?mode=rwc" \
--port "${second_primary}" >"${log}" 2>&1 &
pid=$!
PIDS=("${pid}")
wait_for_url "${pid}" "http://127.0.0.1:${health_port}/healthz" "${log}" \
|| fail "${variant} did not accept the legacy singleton selector"
if [ "${variant}" = candidate ]; then
grep -F 'OPENSHELL_DRIVERS is deprecated' "${log}" >/dev/null \
|| fail "candidate did not emit the legacy selector deprecation warning"
fi
stop_gateway "${pid}"
echo "==> ${variant}: database URL in TOML is rejected without value disclosure"
local invalid="${dir}/invalid.toml" secret="parity-secret-${variant}"
awk -v secret="${secret}" '
/^name =/ { print "database_url = \"postgres://user:" secret "@127.0.0.1/db\"" }
{ print }
' "${config}" >"${invalid}"
if OPENSHELL_PODMAN_SOCKET="${PODMAN_SOCKET}" \
"${gateway}" --config "${invalid}" >"${dir}/invalid.log" 2>&1; then
fail "${variant} accepted database_url in gateway TOML"
fi
grep -F 'database_url' "${dir}/invalid.log" >/dev/null \
|| fail "${variant} database rejection did not identify the field"
if grep -F "${secret}" "${dir}/invalid.log" >/dev/null; then
fail "${variant} database rejection disclosed the configured secret"
fi
cat >"${RESULTS_DIR}/gateway-options-${variant}.json" <<EOF
{"variant":"${variant}","source_sha":"${sha}","schema_version":${schema},"listeners":true,"precedence":true,"sqlite_reopen":true,"legacy_singleton_selector":true,"database_toml_rejected_without_disclosure":true,"success":true}
EOF
}
run_variant baseline 1 "${BASELINE_SHA}" "${BASELINE_GATEWAY}"
run_variant candidate 2 "${CANDIDATE_SHA}" "${CANDIDATE_GATEWAY}"
cat >"${RESULTS_DIR}/gateway-options-comparison.json" <<'EOF'
{"profile":"gateway-options","baseline_success":true,"candidate_success":true,"parity":true}
EOF
echo "Gateway option parity passed."
-54
View File
@@ -1,54 +0,0 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
SCRIPT="${ROOT}/e2e/parity/kubernetes-options.sh"
TMP="$(mktemp -d)"
trap 'rm -rf "${TMP}"' EXIT
OPENSHELL_PARITY_HOST_GATEWAY_IP=169.254.1.2 bash "${SCRIPT}" --print-config baseline >"${TMP}/baseline.toml"
OPENSHELL_PARITY_HOST_GATEWAY_IP=169.254.1.2 bash "${SCRIPT}" --print-config candidate >"${TMP}/candidate.toml"
python3 -I - "${TMP}/baseline.toml" "${TMP}/candidate.toml" <<'PY'
import sys, tomllib
def check(condition, message):
if not condition:
raise RuntimeError(message)
baseline=tomllib.load(open(sys.argv[1],'rb'))['openshell']
candidate=tomllib.load(open(sys.argv[2],'rb'))['openshell']
check(baseline['version']==1 and candidate['version']==2,'schema versions differ')
check(baseline['gateway']['compute_drivers']==['kubernetes'],'baseline selector differs')
check(candidate['gateway']['compute_driver']=='kubernetes','candidate selector differs')
shared={'default_image','supervisor_image','client_tls_secret_name','service_account_name','host_gateway_ip','enable_user_namespaces','sa_token_ttl_secs'}
check(shared <= baseline['gateway'].keys(),'baseline inherited fields missing')
check(shared.isdisjoint(candidate['gateway'].keys()),'candidate leaked driver fields into gateway table')
check(shared <= candidate['drivers']['kubernetes'].keys(),'candidate driver fields missing')
b=dict(baseline['drivers']['kubernetes']); b.update({key:baseline['gateway'][key] for key in shared})
c=dict(candidate['drivers']['kubernetes'])
for projection in (b,c):
projection['gateway_id']='<isolated-gateway-id>'
projection['grpc_endpoint']='http://host.openshell.internal:<isolated-port>'
for field in ('image_pull_policy','supervisor_image_pull_policy'):
projection[field]={'IfNotPresent':'if_not_present'}.get(projection[field],projection[field])
check(b==c,'schema-independent Kubernetes option projections differ')
PY
: >"${TMP}/kubeconfig"
set +e
OPENSHELL_PARITY_BASELINE_ROOT="${TMP}/not-a-worktree" \
OPENSHELL_PARITY_BASELINE_GATEWAY=/bin/true \
OPENSHELL_PARITY_CANDIDATE_GATEWAY=/bin/true \
OPENSHELL_PARITY_CLI=/bin/true \
OPENSHELL_PARITY_KUBECONFIG="${TMP}/kubeconfig" \
OPENSHELL_PARITY_KUBE_CONTEXT=default/external-production-cluster \
OPENSHELL_PARITY_HOST_GATEWAY_IP=169.254.1.2 \
bash "${SCRIPT}" >"${TMP}/unsafe.out" 2>&1
status=$?
set -e
[ "${status}" -ne 0 ]
grep -F 'refusing non-parity context' "${TMP}/unsafe.out" >/dev/null
echo "Kubernetes option parity deterministic tests passed."
-432
View File
@@ -1,432 +0,0 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Compare the frozen schema-v1 and current schema-v2 Kubernetes driver against
# one explicitly supplied, disposable kind cluster. Gateway processes run on
# the host so the same cluster and candidate-owned oracle exercise both schemas.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
BASELINE_SHA="${OPENSHELL_PARITY_BASELINE_SHA:-74960ebfaeec4673885089ed995fad902459749f}"
CANDIDATE_SHA="${OPENSHELL_PARITY_CANDIDATE_SHA:-$(git -C "${ROOT}" rev-parse HEAD)}"
BASELINE_ROOT="${OPENSHELL_PARITY_BASELINE_ROOT:-}"
BASELINE_GATEWAY="${OPENSHELL_PARITY_BASELINE_GATEWAY:-}"
CANDIDATE_GATEWAY="${OPENSHELL_PARITY_CANDIDATE_GATEWAY:-}"
CLI="${OPENSHELL_PARITY_CLI:-}"
ARTIFACT_MANIFEST="${OPENSHELL_PARITY_ARTIFACT_MANIFEST:-}"
KUBECONFIG_PATH="${OPENSHELL_PARITY_KUBECONFIG:-}"
KUBE_CONTEXT="${OPENSHELL_PARITY_KUBE_CONTEXT:-}"
HOST_GATEWAY_IP="${OPENSHELL_PARITY_HOST_GATEWAY_IP:-}"
RUN_ID="${OPENSHELL_PARITY_RUN_ID:-$(date +%s)-$$}"
OUT="${OPENSHELL_PARITY_OUTPUT_DIR:-${ROOT}/target/parity/step8-kubernetes-${CANDIDATE_SHA:0:8}}"
SANDBOX_IMAGE="${OPENSHELL_PARITY_KUBERNETES_SANDBOX_IMAGE:-nvcr.io/nvidia/base/ubuntu:24.04}"
SUPERVISOR_IMAGE="${OPENSHELL_PARITY_KUBERNETES_SUPERVISOR_IMAGE:-ghcr.io/nvidia/openshell/supervisor:latest}"
RUNTIME_CLASS="openshell-parity-runc-${RUN_ID}"
fail() {
echo "ERROR: Kubernetes option parity: $*" >&2
exit 1
}
kctl() {
kubectl --kubeconfig "${KUBECONFIG_PATH}" --context "${KUBE_CONTEXT}" "$@"
}
pick_port() {
python3 -I - <<'PY'
import socket
with socket.socket() as sock:
sock.bind(("0.0.0.0", 0))
print(sock.getsockname()[1])
PY
}
write_config() {
local variant=$1
local path=$2
local namespace=$3
local port=$4
local run_dir=$5
local gateway_id="step8-${variant}-${RUN_ID}"
local pull_policy
if [ "${variant}" = baseline ]; then
pull_policy=IfNotPresent
cat >"${path}" <<EOF
[openshell]
version = 1
[openshell.gateway]
name = "${gateway_id}"
bind_address = "0.0.0.0:${port}"
disable_tls = true
compute_drivers = ["kubernetes"]
default_image = "${SANDBOX_IMAGE}"
supervisor_image = "${SUPERVISOR_IMAGE}"
client_tls_secret_name = "parity-client-tls"
service_account_name = "parity-sandbox"
host_gateway_ip = "${HOST_GATEWAY_IP}"
enable_user_namespaces = false
sa_token_ttl_secs = 600
[openshell.gateway.auth]
allow_unauthenticated_users = true
[openshell.gateway.gateway_jwt]
signing_key_path = "${run_dir}/jwt/signing.pem"
public_key_path = "${run_dir}/jwt/public.pem"
kid_path = "${run_dir}/jwt/kid"
gateway_id = "${gateway_id}"
ttl_secs = 3600
[openshell.drivers.kubernetes]
namespace = "${namespace}"
workspace_mode = "shared"
gateway_id = "${gateway_id}"
image_pull_policy = "${pull_policy}"
image_pull_secrets = ["parity-pull-secret"]
supervisor_image_pull_policy = "${pull_policy}"
supervisor_sideload_method = "init-container"
topology = "combined"
grpc_endpoint = "http://host.openshell.internal:${port}"
ssh_socket_path = "/run/openshell/parity-kubernetes-ssh.sock"
workspace_default_storage_size = "64Mi"
workspace_storage_class = "standard"
default_runtime_class_name = "${RUNTIME_CLASS}"
app_armor_profile = "Unconfined"
sandbox_uid = 1000
sandbox_gid = 1000
EOF
else
pull_policy=if_not_present
cat >"${path}" <<EOF
[openshell]
version = 2
[openshell.gateway]
name = "${gateway_id}"
bind_address = "0.0.0.0:${port}"
disable_tls = true
compute_driver = "kubernetes"
[openshell.gateway.auth]
allow_unauthenticated_users = true
[openshell.gateway.gateway_jwt]
signing_key_path = "${run_dir}/jwt/signing.pem"
public_key_path = "${run_dir}/jwt/public.pem"
kid_path = "${run_dir}/jwt/kid"
gateway_id = "${gateway_id}"
ttl_secs = 3600
[openshell.drivers.kubernetes]
namespace = "${namespace}"
workspace_mode = "shared"
gateway_id = "${gateway_id}"
default_image = "${SANDBOX_IMAGE}"
image_pull_policy = "${pull_policy}"
image_pull_secrets = ["parity-pull-secret"]
service_account_name = "parity-sandbox"
supervisor_image = "${SUPERVISOR_IMAGE}"
supervisor_image_pull_policy = "${pull_policy}"
supervisor_sideload_method = "init-container"
topology = "combined"
grpc_endpoint = "http://host.openshell.internal:${port}"
ssh_socket_path = "/run/openshell/parity-kubernetes-ssh.sock"
client_tls_secret_name = "parity-client-tls"
host_gateway_ip = "${HOST_GATEWAY_IP}"
enable_user_namespaces = false
sa_token_ttl_secs = 600
workspace_default_storage_size = "64Mi"
workspace_storage_class = "standard"
default_runtime_class_name = "${RUNTIME_CLASS}"
app_armor_profile = "Unconfined"
sandbox_uid = 1000
sandbox_gid = 1000
EOF
fi
}
if [ "${1:-}" = --print-config ]; then
variant="${2:-}"
case "${variant}" in baseline|candidate) ;; *) fail "--print-config requires baseline or candidate" ;; esac
HOST_GATEWAY_IP="${HOST_GATEWAY_IP:-169.254.1.2}"
RUNTIME_CLASS=openshell-parity-runc-print
write_config "${variant}" /dev/stdout openshell-parity-print 18080 /tmp/openshell-parity-print
exit 0
fi
[ -n "${BASELINE_ROOT}" ] || fail "OPENSHELL_PARITY_BASELINE_ROOT is required"
[ -x "${BASELINE_GATEWAY}" ] || fail "baseline gateway is not executable: ${BASELINE_GATEWAY}"
[ -x "${CANDIDATE_GATEWAY}" ] || fail "candidate gateway is not executable: ${CANDIDATE_GATEWAY}"
[ -x "${CLI}" ] || fail "candidate CLI is not executable: ${CLI}"
[ -f "${KUBECONFIG_PATH}" ] || fail "private kubeconfig does not exist: ${KUBECONFIG_PATH}"
[ -n "${HOST_GATEWAY_IP}" ] || fail "OPENSHELL_PARITY_HOST_GATEWAY_IP is required; host routing is never guessed"
case "${KUBE_CONTEXT}" in kind-openshell-parity-*) ;; *) fail "refusing non-parity context: ${KUBE_CONTEXT:-<unset>}" ;; esac
[[ "${BASELINE_SHA}" =~ ^[0-9a-f]{40}$ ]] || fail "baseline SHA must be a full lowercase SHA-1"
[[ "${CANDIDATE_SHA}" =~ ^[0-9a-f]{40}$ ]] || fail "candidate SHA must be a full lowercase SHA-1"
[[ "${RUN_ID}" =~ ^[a-z0-9]([a-z0-9-]{0,30}[a-z0-9])?$ ]] || fail "run ID must be a lowercase DNS label of at most 32 characters"
[[ "${SANDBOX_IMAGE}" =~ ^[A-Za-z0-9][A-Za-z0-9._/:@+-]{0,254}$ ]] || fail "sandbox image contains unsafe characters"
[[ "${SUPERVISOR_IMAGE}" =~ ^[A-Za-z0-9][A-Za-z0-9._/:@+-]{0,254}$ ]] || fail "supervisor image contains unsafe characters"
python3 -I - "${HOST_GATEWAY_IP}" <<'PY'
import ipaddress, sys
value=ipaddress.ip_address(sys.argv[1])
if value.version != 4:
raise SystemExit("host gateway IP must be IPv4")
PY
[ "$(git -C "${BASELINE_ROOT}" rev-parse HEAD)" = "${BASELINE_SHA}" ] || fail "baseline worktree is not ${BASELINE_SHA}"
[ "$(git -C "${ROOT}" rev-parse HEAD)" = "${CANDIDATE_SHA}" ] || fail "candidate worktree is not ${CANDIDATE_SHA}"
[ "$(kubectl --kubeconfig "${KUBECONFIG_PATH}" config current-context)" = "${KUBE_CONTEXT}" ] || fail "private kubeconfig current context differs from requested parity context"
[ "$(kctl -n kube-system get configmap openshell-parity-guard -o jsonpath='{.data.context}')" = "${KUBE_CONTEXT}" ] || fail "cluster lacks the matching provisioning-time parity guard"
[ "$(kctl -n kube-system get configmap openshell-parity-guard -o jsonpath='{.data.purpose}')" = schema-v2-capability-parity ] || fail "cluster parity guard has the wrong purpose"
kctl get nodes -o name | grep -q '^node/openshell-parity-' || fail "requested context is not the dedicated OpenShell parity cluster"
[ "$(kctl get crd sandboxes.agents.x-k8s.io -o jsonpath='{.status.conditions[?(@.type=="Established")].status}')" = True ] || fail "Agent Sandbox CRD is not established"
[ -f "${ARTIFACT_MANIFEST}" ] || fail "OPENSHELL_PARITY_ARTIFACT_MANIFEST is required"
python3 -I - "${ARTIFACT_MANIFEST}" "${BASELINE_SHA}" "${CANDIDATE_SHA}" "${BASELINE_GATEWAY}" "${CANDIDATE_GATEWAY}" "${CLI}" <<'PY'
import hashlib, pathlib, sys, tomllib
manifest=tomllib.load(open(sys.argv[1],'rb'))
expected={'baseline_commit':sys.argv[2],'candidate_commit':sys.argv[3]}
for key, value in expected.items():
if manifest.get(key) != value:
raise SystemExit(f'artifact manifest {key} does not match')
for key, path in zip(('baseline_gateway_sha256','candidate_gateway_sha256','candidate_cli_sha256'),sys.argv[4:]):
digest=hashlib.sha256(pathlib.Path(path).read_bytes()).hexdigest()
if manifest.get(key) != digest:
raise SystemExit(f'artifact manifest {key} does not match supplied binary')
PY
PARITY_ROOT="$(realpath -m "${ROOT}/target/parity")"
OUT="$(realpath -m "${OUT}")"
case "${OUT}" in "${PARITY_ROOT}"/step8-kubernetes-*) ;; *) fail "output must be a step8-kubernetes-* directory below ${PARITY_ROOT}" ;; esac
[ ! -L "${OUT}" ] || fail "output directory must not be a symlink"
rm -rf --one-file-system "${OUT}"
umask 077
mkdir -p "${OUT}/raw"
cp "${ARTIFACT_MANIFEST}" "${OUT}/artifact-manifest.toml"
printf '%s\n' "${BASELINE_SHA}" >"${OUT}/baseline.sha"
printf '%s\n' "${CANDIDATE_SHA}" >"${OUT}/candidate.sha"
printf '%s\n' "${KUBE_CONTEXT}" >"${OUT}/context"
runtime_class_created=false
cleanup_cluster_fixture() {
local status=$?
local cleanup_status=0
set +e
if ${runtime_class_created}; then
kctl delete runtimeclass "${RUNTIME_CLASS}" --ignore-not-found --wait=true --timeout=120s >/dev/null 2>&1
cleanup_status=$?
fi
set -e
if [ "${status}" -eq 0 ] && [ "${cleanup_status}" -ne 0 ]; then
echo "ERROR: failed to confirm RuntimeClass cleanup" >&2
exit 1
fi
exit "${status}"
}
trap cleanup_cluster_fixture EXIT
cat <<EOF | kctl create -f - >/dev/null
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: ${RUNTIME_CLASS}
handler: runc
EOF
runtime_class_created=true
run_variant() (
set -euo pipefail
local variant=$1
local gateway=$2
local namespace="openshell-parity-${variant}-${RUN_ID}"
local sandbox="k8s-${variant:0:1}-${RUN_ID: -6}"
local resource="default--${sandbox}"
local run_dir="${OUT}/raw/${variant}"
local config="${run_dir}/gateway.toml"
local port
local gateway_pid=
local registered_endpoint
local namespace_created=false
mkdir -p "${run_dir}/jwt" "${run_dir}/xdg-config/openshell/gateways/parity" "${run_dir}/xdg-state" "${run_dir}/xdg-data"
cleanup_variant() {
local status=$?
local cleanup_status=0
set +e
if [ -n "${gateway_pid}" ]; then
kill "${gateway_pid}" >/dev/null 2>&1 || true
wait "${gateway_pid}" >/dev/null 2>&1 || true
fi
rm -f "${run_dir}/jwt/signing.pem" "${run_dir}/client.key"
if ${namespace_created}; then
kctl delete namespace "${namespace}" --ignore-not-found --wait=true --timeout=120s >"${run_dir}/namespace-delete.log" 2>&1
cleanup_status=$?
fi
set -e
if [ "${status}" -eq 0 ] && [ "${cleanup_status}" -ne 0 ]; then
echo "ERROR: ${variant} namespace cleanup was not confirmed" >&2
exit 1
fi
exit "${status}"
}
trap cleanup_variant EXIT
openssl genpkey -algorithm ED25519 -out "${run_dir}/jwt/signing.pem" >/dev/null 2>&1
openssl pkey -in "${run_dir}/jwt/signing.pem" -pubout -out "${run_dir}/jwt/public.pem" >/dev/null 2>&1
printf 'step8-%s\n' "${variant}" >"${run_dir}/jwt/kid"
openssl req -x509 -newkey rsa:2048 -nodes -subj "/CN=step8-parity-client" \
-keyout "${run_dir}/client.key" -out "${run_dir}/client.crt" -days 1 >/dev/null 2>&1
kctl create namespace "${namespace}" >"${run_dir}/namespace-create.log"
namespace_created=true
kctl -n "${namespace}" create serviceaccount parity-sandbox >"${run_dir}/service-account.log"
kctl -n "${namespace}" create secret generic parity-pull-secret \
--type=kubernetes.io/dockerconfigjson --from-literal=.dockerconfigjson='{"auths":{}}' >"${run_dir}/pull-secret.log"
kctl -n "${namespace}" create secret generic parity-client-tls \
--from-file=ca.crt="${run_dir}/client.crt" \
--from-file=tls.crt="${run_dir}/client.crt" \
--from-file=tls.key="${run_dir}/client.key" >"${run_dir}/client-tls-secret.log"
port="$(pick_port)"
write_config "${variant}" "${config}" "${namespace}" "${port}" "${run_dir}"
KUBECONFIG="${KUBECONFIG_PATH}" \
XDG_CONFIG_HOME="${run_dir}/xdg-config" XDG_STATE_HOME="${run_dir}/xdg-state" XDG_DATA_HOME="${run_dir}/xdg-data" \
OPENSHELL_DB_URL="sqlite:${run_dir}/gateway.db" \
"${gateway}" --config "${config}" >"${run_dir}/gateway.log" 2>&1 &
gateway_pid=$!
listener_ready=false
for _ in $(seq 1 60); do
if ! kill -0 "${gateway_pid}" >/dev/null 2>&1; then
fail "${variant} gateway exited before binding; see ${run_dir}/gateway.log"
fi
if python3 -I - "${port}" <<'PY'
import socket, sys
try:
with socket.create_connection(("127.0.0.1", int(sys.argv[1])), timeout=.2):
pass
except OSError:
raise SystemExit(1)
PY
then
listener_ready=true
break
fi
sleep 0.5
done
${listener_ready} || fail "${variant} gateway did not bind within 30 seconds"
registered_endpoint="http://127.0.0.1:${port}"
cat >"${run_dir}/xdg-config/openshell/gateways/parity/metadata.json" <<EOF
{"name":"parity","gateway_endpoint":"${registered_endpoint}","is_remote":false,"gateway_port":${port},"auth_mode":"plaintext"}
EOF
printf parity >"${run_dir}/xdg-config/openshell/active_gateway"
XDG_CONFIG_HOME="${run_dir}/xdg-config" XDG_STATE_HOME="${run_dir}/xdg-state" XDG_DATA_HOME="${run_dir}/xdg-data" \
timeout 360 "${CLI}" sandbox create --name "${sandbox}" --cpu 250m --memory 128Mi --detach \
>"${run_dir}/create.log" 2>&1
XDG_CONFIG_HOME="${run_dir}/xdg-config" XDG_STATE_HOME="${run_dir}/xdg-state" XDG_DATA_HOME="${run_dir}/xdg-data" \
timeout 60 "${CLI}" sandbox exec --name "${sandbox}" --no-tty -- \
sh -c 'printf step8-kubernetes-exec' >"${run_dir}/exec.log" 2>&1
grep -q 'step8-kubernetes-exec' "${run_dir}/exec.log" || fail "${variant} callback exec marker missing"
kctl -n "${namespace}" get sandbox "${resource}" -o json >"${run_dir}/sandbox.json"
kctl -n "${namespace}" get pod "${resource}" -o json >"${run_dir}/pod.json"
kctl -n "${namespace}" get pvc "workspace-${resource}" -o json >"${run_dir}/pvc.json"
python3 -I - "${run_dir}" "${SANDBOX_IMAGE}" "${SUPERVISOR_IMAGE}" "${HOST_GATEWAY_IP}" "${RUNTIME_CLASS}" <<'PY'
import json, pathlib, sys
def check(condition, message):
if not condition:
raise RuntimeError(message)
run=pathlib.Path(sys.argv[1]); sandbox_image, supervisor_image, host_ip, runtime_class=sys.argv[2:]
pod=json.loads((run/'pod.json').read_text()); pvc=json.loads((run/'pvc.json').read_text()); sb=json.loads((run/'sandbox.json').read_text())
spec=pod['spec']; agent=next(c for c in spec['containers'] if c['name']=='agent'); env={x['name']:x.get('value','') for x in agent.get('env',[])}
inits={c['name']:c for c in spec.get('initContainers',[])}; install=inits['openshell-supervisor-install']
vols={v['name']:v for v in spec.get('volumes',[])}; mounts={m['name']:m for m in agent.get('volumeMounts',[])}
hosts={(h, a['ip']) for a in spec.get('hostAliases',[]) for h in a.get('hostnames',[])}
check(pod['status']['phase']=='Running','Pod is not Running')
conditions={c['type']:c['status'] for c in sb.get('status',{}).get('conditions',[])}
check(conditions.get('Ready')=='True','Sandbox Ready condition is not true')
check(agent['image']==sandbox_image and agent['imagePullPolicy']=='IfNotPresent','sandbox image or pull policy differs')
check(install['image']==supervisor_image and install['imagePullPolicy']=='IfNotPresent','supervisor image or pull policy differs')
check([x['name'] for x in spec.get('imagePullSecrets',[])]==['parity-pull-secret'],'image pull Secret differs')
check(spec['serviceAccountName']=='parity-sandbox','ServiceAccount differs')
check(env['OPENSHELL_ENDPOINT'].startswith('http://host.openshell.internal:'),'callback endpoint differs')
check(env['OPENSHELL_SSH_SOCKET_PATH']=='/run/openshell/parity-kubernetes-ssh.sock','SSH socket differs')
check(env['OPENSHELL_SANDBOX_UID']=='1000' and env['OPENSHELL_SANDBOX_GID']=='1000','sandbox identity differs')
check(('host.openshell.internal',host_ip) in hosts and ('host.docker.internal',host_ip) in hosts,'host aliases differ')
check(spec['runtimeClassName']==runtime_class and spec.get('hostUsers',True) is not False,'RuntimeClass or user namespace posture differs')
check(agent['securityContext']['appArmorProfile']['type']=='Unconfined','AppArmor profile differs')
check(agent['resources']['requests']=={'cpu':'250m','memory':'128Mi'},'resource requests differ')
check(agent['resources']['limits']=={'cpu':'250m','memory':'128Mi'},'resource limits differ')
check(vols['openshell-sa-token']['projected']['sources'][0]['serviceAccountToken']['expirationSeconds']==600,'ServiceAccount token TTL differs')
check(vols['openshell-client-tls']['secret']['secretName']=='parity-client-tls','client TLS Secret differs')
check(mounts['openshell-client-tls']['readOnly'] is True,'client TLS mount is not read-only')
check(pvc['status']['phase']=='Bound' and pvc['spec']['storageClassName']=='standard','PVC phase or StorageClass differs')
check(pvc['spec']['resources']['requests']['storage']=='64Mi','PVC storage request differs')
labels=sb['metadata']['labels']
for key in ('openshell.ai/sandbox-id','openshell.ai/sandbox-name','openshell.ai/sandbox-workspace','openshell.ai/gateway-id','openshell.ai/managed-by'):
check(labels.get(key),f'managed label {key} missing')
observed_sideload='init-container' if 'openshell-supervisor-install' in inits else 'unknown'
observed_topology='combined' if [c['name'] for c in spec['containers']]==['agent'] else 'other'
observed_workspace_mode='shared' if pvc['metadata']['namespace']==pod['metadata']['namespace'] and pvc['metadata']['name'].startswith('workspace-default--') else 'other'
check(observed_sideload=='init-container','supervisor sideload method differs')
check(observed_topology=='combined','supervisor topology differs')
check(observed_workspace_mode=='shared','workspace placement differs')
normalized={
'scenario':'kubernetes-core-options','pod_phase':'Running','sandbox_ready':True,
'sandbox_image':agent['image'],'sandbox_image_pull_policy':agent['imagePullPolicy'],
'image_pull_secrets':['parity-pull-secret'],'service_account':'parity-sandbox',
'supervisor_image':install['image'],'supervisor_image_pull_policy':install['imagePullPolicy'],
'supervisor_sideload_method':observed_sideload,'topology':observed_topology,
'callback_endpoint_host':'host.openshell.internal','callback_exec':True,
'ssh_socket_path':env['OPENSHELL_SSH_SOCKET_PATH'],'client_tls_secret':'parity-client-tls',
'host_gateway_ip':host_ip,'sa_token_ttl_secs':600,'runtime_class_handler':'runc',
'enable_user_namespaces':False,'app_armor_profile':'Unconfined','sandbox_uid':1000,'sandbox_gid':1000,
'workspace_mode':observed_workspace_mode,'workspace_storage':'64Mi','workspace_storage_class':'standard','pvc_phase':'Bound',
'cpu':'250m','memory':'128Mi','managed_labels':True,
}
(run.parent.parent/f'{run.name}.normalized.json').write_text(json.dumps(normalized,sort_keys=True,separators=(',',':'))+'\n')
PY
XDG_CONFIG_HOME="${run_dir}/xdg-config" XDG_STATE_HOME="${run_dir}/xdg-state" XDG_DATA_HOME="${run_dir}/xdg-data" \
timeout 60 "${CLI}" sandbox delete "${sandbox}" >"${run_dir}/delete.log" 2>&1
for _ in $(seq 1 60); do
if ! kctl -n "${namespace}" get sandbox "${resource}" >/dev/null 2>&1 \
&& ! kctl -n "${namespace}" get pod "${resource}" >/dev/null 2>&1 \
&& ! kctl -n "${namespace}" get pvc "workspace-${resource}" >/dev/null 2>&1; then
break
fi
sleep 1
done
! kctl -n "${namespace}" get sandbox "${resource}" >/dev/null 2>&1 || fail "${variant} Sandbox remained after delete"
! kctl -n "${namespace}" get pod "${resource}" >/dev/null 2>&1 || fail "${variant} Pod remained after delete"
! kctl -n "${namespace}" get pvc "workspace-${resource}" >/dev/null 2>&1 || fail "${variant} PVC remained after delete"
)
set +e
run_variant baseline "${BASELINE_GATEWAY}"
baseline_status=$?
run_variant candidate "${CANDIDATE_GATEWAY}"
candidate_status=$?
set -e
baseline_success=false; candidate_success=false
[ "${baseline_status}" -eq 0 ] && baseline_success=true
[ "${candidate_status}" -eq 0 ] && candidate_success=true
parity=false; classification=regression; accepted=false
if ${baseline_success} && ${candidate_success} && [ -f "${OUT}/baseline.normalized.json" ] && [ -f "${OUT}/candidate.normalized.json" ]; then
if cmp -s "${OUT}/baseline.normalized.json" "${OUT}/candidate.normalized.json"; then
parity=true; classification=pass; accepted=true
fi
fi
cat >"${OUT}/comparison.json" <<EOF
{"baseline_commit":"${BASELINE_SHA}","candidate_commit":"${CANDIDATE_SHA}","baseline_success":${baseline_success},"candidate_success":${candidate_success},"parity":${parity},"classification":"${classification}","accepted":${accepted}}
EOF
if ! ${accepted}; then
fail "paired Kubernetes option oracle failed; see ${OUT}/comparison.json and ${OUT}/raw"
fi
cat "${OUT}/comparison.json"
-111
View File
@@ -1,111 +0,0 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
set -euo pipefail
# Shared candidate-owned oracle for both schema variants. It intentionally
# asserts only stable externally observable Podman semantics.
CLI="${OPENSHELL_BIN:?OPENSHELL_BIN is required}"
RESULT="${OPENSHELL_PARITY_ORACLE_RESULT:?OPENSHELL_PARITY_ORACLE_RESULT is required}"
VARIANT="${OPENSHELL_PARITY_VARIANT:?OPENSHELL_PARITY_VARIANT is required}"
IMAGE="${OPENSHELL_E2E_PODMAN_SANDBOX_IMAGE:-${OPENSHELL_SANDBOX_IMAGE:-nvcr.io/nvidia/base/ubuntu:24.04}}"
GATEWAY_LOG="${OPENSHELL_E2E_GATEWAY_LOG:?OPENSHELL_E2E_GATEWAY_LOG is required}"
NAME="po-${VARIANT:0:1}-${RANDOM}"
WORKDIR="${TMPDIR:-/tmp}/openshell-parity-options-${NAME}"
mkdir -p "${WORKDIR}"
CREATED=0
case "${VARIANT}" in
baseline) EXPECTED_PIDS_LIMIT=2048 ;;
candidate) EXPECTED_PIDS_LIMIT=31 ;;
*) echo "ERROR: podman-options oracle: unknown parity variant ${VARIANT}" >&2; exit 2 ;;
esac
fail() { echo "ERROR: podman-options oracle: $*" >&2; exit 1; }
json_escape() { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'; }
podman_cmd() {
if [ "${OPENSHELL_E2E_CONTAINER_ENGINE_UNSET_XDG_CONFIG_HOME:-0}" = 1 ]; then
env -u XDG_CONFIG_HOME podman --url "unix://${OPENSHELL_PODMAN_SOCKET}" "$@"
elif [ -n "${OPENSHELL_E2E_CONTAINER_ENGINE_XDG_CONFIG_HOME:-}" ]; then
XDG_CONFIG_HOME="${OPENSHELL_E2E_CONTAINER_ENGINE_XDG_CONFIG_HOME}" podman --url "unix://${OPENSHELL_PODMAN_SOCKET}" "$@"
else
podman --url "unix://${OPENSHELL_PODMAN_SOCKET}" "$@"
fi
}
cleanup() {
status=$?
if [ "${CREATED}" = 1 ]; then "${CLI}" sandbox delete "${NAME}" >/dev/null 2>&1 || true; fi
rm -rf "${WORKDIR}"
exit "${status}"
}
trap cleanup EXIT
mkdir -p "${WORKDIR}/bind-source"
printf '%s\n' parity-bind-mount >"${WORKDIR}/bind-source/probe"
bind_source="$(json_escape "${WORKDIR}/bind-source")"
DRIVER_CONFIG="{\"podman\":{\"mounts\":[{\"type\":\"bind\",\"source\":\"${bind_source}\",\"target\":\"/tmp/parity-bind\",\"read_only\":true,\"selinux_label\":\"private\"},{\"type\":\"tmpfs\",\"target\":\"/tmp/parity-cache\",\"options\":[\"nosuid\",\"nodev\"],\"size_bytes\":1048576,\"mode\":448}]}}"
"${CLI}" sandbox create --name "${NAME}" --cpu 750m --memory 384Mi \
--driver-config-json "${DRIVER_CONFIG}" --detach
CREATED=1
podman_cmd ps -aq --filter label=openshell.managed=true --filter "label=openshell.ai/sandbox-name=${NAME}" > "${WORKDIR}/ids"
env wc -l "${WORKDIR}/ids" | env grep -E "^[[:space:]]*1[[:space:]]" >/dev/null || fail "expected exactly one managed container"
# Image IDs, names, and inspect attributes are checked but never emitted.
while IFS= read -r id; do
podman_cmd image inspect --format "{{.Id}}" "${IMAGE}" | env sed "s/^sha256://" > "${WORKDIR}/expected-image"
podman_cmd inspect --format "{{.Image}}" "${id}" | env sed "s/^sha256://" > "${WORKDIR}/actual-image"
env cmp -s "${WORKDIR}/expected-image" "${WORKDIR}/actual-image" || fail "selected sandbox image ID differs"
podman_cmd inspect --format "{{index .Config.Labels \"openshell.managed\"}}" "${id}" | env grep -Fx true >/dev/null || fail "managed label missing"
podman_cmd inspect --format "{{index .Config.Labels \"openshell.ai/sandbox-name\"}}" "${id}" | env grep -Fx "${NAME}" >/dev/null || fail "sandbox name label missing"
for label in openshell.ai/sandbox-id openshell.ai/sandbox-workspace; do
podman_cmd inspect --format "{{index .Config.Labels \"${label}\"}}" "${id}" | env grep -Ev "^(|<no value>)$" >/dev/null || fail "${label} missing"
done
actual_pids_limit="$(podman_cmd inspect --format "{{.HostConfig.PidsLimit}}" "${id}")"
[ "${actual_pids_limit}" = "${EXPECTED_PIDS_LIMIT}" ] || fail "pids limit is ${actual_pids_limit}, expected ${EXPECTED_PIDS_LIMIT}"
podman_cmd inspect --format "{{.HostConfig.CpuQuota}}" "${id}" | env grep -Fx 75000 >/dev/null || fail "CPU quota is not 750m"
podman_cmd inspect --format "{{.HostConfig.CpuPeriod}}" "${id}" | env grep -Fx 100000 >/dev/null || fail "CPU period is not 100000"
podman_cmd inspect --format "{{.HostConfig.Memory}}" "${id}" | env grep -Fx 402653184 >/dev/null || fail "memory limit is not 384Mi"
podman_cmd inspect --format '{{range .Mounts}}{{if eq .Destination "/tmp/parity-bind"}}{{.RW}}{{end}}{{end}}' "${id}" \
| env grep -Fx false >/dev/null || fail "bind mount is not read-only"
podman_cmd inspect --format "{{.Config.Entrypoint}}" "${id}" | env grep -F /opt/openshell/bin/openshell-sandbox >/dev/null || fail "supervisor entrypoint missing"
podman_cmd inspect --format "{{index .Config.Cmd 0}} {{index .Config.Cmd 1}}" "${id}" | env grep -Fx -- "--workdir /sandbox" >/dev/null || fail "supervisor workdir differs"
podman_cmd inspect --format "{{range .Config.Env}}{{println .}}{{end}}" "${id}" | env grep -Fx OPENSHELL_SSH_SOCKET_PATH=/run/openshell/parity-ssh.sock >/dev/null || fail "SSH environment differs"
podman_cmd inspect --format "{{range .Config.Env}}{{println .}}{{end}}" "${id}" | env grep -E "^OPENSHELL_ENDPOINT=https://host\.containers\.internal:" >/dev/null || fail "callback endpoint differs"
done < "${WORKDIR}/ids"
# Both schema spellings must map to Podman's pull-if-missing request. Inspect
# the driver emission so regressions to always or never do not pass merely
# because the wrapper preloaded the image.
sed $'s/\033\[[0-9;]*m//g' "${GATEWAY_LOG}" \
| env grep -F 'Ensuring sandbox image' \
| env grep -F 'policy=missing' >/dev/null \
|| fail "image pull policy did not map to Podman missing"
# Podman 5.8 reports Healthcheck.Interval in nanoseconds; wait for the
# eventual state instead of accepting a merely running container.
healthy=0
for attempt in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90; do
while IFS= read -r id; do
podman_cmd inspect --format "{{.Config.Healthcheck.Interval}}" "${id}" | env grep -E "^(7000000000|7s)$" >/dev/null || fail "health interval is not 7 seconds"
if podman_cmd inspect --format "{{.State.Health.Status}}" "${id}" | env grep -Fx healthy >/dev/null; then healthy=1; fi
done < "${WORKDIR}/ids"
[ "${healthy}" = 1 ] && break
sleep 1
done
[ "${healthy}" = 1 ] || fail "container did not become healthy"
container_id="$(cat "${WORKDIR}/ids")"
podman_cmd exec "${container_id}" sh -c 'test "$(cat /tmp/parity-bind/probe)" = parity-bind-mount' \
|| fail "read-only bind mount is unavailable"
podman_cmd exec "${container_id}" test -d /tmp/parity-cache \
|| fail "tmpfs mount is unavailable"
podman_cmd exec "${container_id}" test -s /etc/openshell/auth/sandbox.jwt \
|| fail "sandbox token mount is unavailable"
for tls_file in ca.crt tls.crt tls.key; do
podman_cmd exec "${container_id}" test -s "/etc/openshell/tls/client/${tls_file}" \
|| fail "guest TLS mount ${tls_file} is unavailable"
done
"${CLI}" sandbox exec --name "${NAME}" --no-tty --no-login-shell -- true
# This is the normalized result: no container IDs, timestamps, IPs, or ports.
escaped_image="$(json_escape "${IMAGE}")"
printf "%s\n" "{\"scenario\":\"podman-options\",\"sandbox_image\":\"${escaped_image}\",\"image_pull_policy\":\"if_not_present\",\"managed_labels\":true,\"supervisor_entrypoint\":\"/opt/openshell/bin/openshell-sandbox\",\"supervisor_workdir\":\"/sandbox\",\"callback_endpoint_scheme\":\"https\",\"callback_endpoint_host\":\"host.containers.internal\",\"ssh_socket_path\":\"/run/openshell/parity-ssh.sock\",\"cpu_millis\":750,\"memory_bytes\":402653184,\"pids_limit\":${actual_pids_limit},\"bind_mount\":\"read_only\",\"tmpfs_mount\":true,\"sandbox_token_mount\":true,\"guest_tls_mounts\":true,\"health_check_interval_secs\":7,\"health\":\"healthy\",\"callback_exec\":true}" > "${RESULT}"
-658
View File
@@ -1,658 +0,0 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Compare the frozen schema-v1 gateway contract with the checkout's schema-v2
# contract. This intentionally begins with one small semantic scenario; later
# parity waves add scenarios without changing the isolated variant runner.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
MANIFEST="${OPENSHELL_PARITY_CAPABILITY_MANIFEST:-${ROOT}/e2e/configs/gateway/schema-v2-capability-parity.toml}"
DRIVER=""
SCENARIO="smoke"
COMMAND_CLASS="conformance_smoke"
BASELINE_WORKTREE="${OPENSHELL_PARITY_BASELINE_WORKTREE:-}"
CANDIDATE_WORKTREE="${OPENSHELL_PARITY_CANDIDATE_WORKTREE:-${ROOT}}"
RESULTS_DIR="${OPENSHELL_PARITY_RESULTS_DIR:-}"
WRAPPER="${OPENSHELL_PARITY_PODMAN_WRAPPER:-${ROOT}/e2e/with-podman-gateway.sh}"
PODMAN_OPTIONS_ORACLE="${OPENSHELL_PARITY_PODMAN_OPTIONS_ORACLE:-${ROOT}/e2e/parity/podman-options.sh}"
CONFORMANCE_TRACE_WRAPPER="${ROOT}/e2e/parity/trace-conformance.sh"
RESULTS_VERIFIER="${ROOT}/e2e/parity/verify-results.py"
PODMAN_BIN="${OPENSHELL_PARITY_PODMAN_BIN:-podman}"
DEFAULT_SANDBOX_IMAGE="nvcr.io/nvidia/base/ubuntu:24.04"
SANDBOX_IMAGE_REQUEST="${OPENSHELL_E2E_PODMAN_SANDBOX_IMAGE:-${DEFAULT_SANDBOX_IMAGE}}"
PARITY_SANDBOX_RUNTIME_IMAGE=""
PARITY_SUPERVISOR_BASE_IMAGE=""
PARITY_SUPERVISOR_BASE_RUNTIME_IMAGE=""
TEMP_WORKTREE=""
RUN_DIR=""
usage() {
cat >&2 <<EOF
Usage: e2e/parity/run.sh --driver podman [--scenario smoke|external-driver|podman-options] [--baseline-worktree PATH] [--results-dir PATH]
The default baseline is the immutable baseline_commit in ${MANIFEST}.
Overrides:
OPENSHELL_PARITY_BASELINE_{GATEWAY,CLI,CONFORMANCE}_BIN
OPENSHELL_PARITY_CANDIDATE_{GATEWAY,CLI,CONFORMANCE}_BIN
OPENSHELL_PARITY_{BASELINE,CANDIDATE}_EXTERNAL_DRIVER_BIN
OPENSHELL_PARITY_{BASELINE,CANDIDATE}_SUPERVISOR_BIN
OPENSHELL_PARITY_{BASELINE,CANDIDATE}_CARGO_TARGET_DIR
OPENSHELL_PARITY_CANDIDATE_WORKTREE (clean checkout at the current HEAD)
EOF
}
while [ "$#" -gt 0 ]; do
case "$1" in
--driver)
[ "$#" -ge 2 ] || { echo "ERROR: --driver requires a value." >&2; exit 2; }
DRIVER=$2
shift 2
;;
--scenario)
[ "$#" -ge 2 ] || { echo "ERROR: --scenario requires a value." >&2; exit 2; }
SCENARIO=$2
shift 2
;;
--baseline-worktree)
[ "$#" -ge 2 ] || { echo "ERROR: --baseline-worktree requires a path." >&2; exit 2; }
BASELINE_WORKTREE=$2
shift 2
;;
--results-dir)
[ "$#" -ge 2 ] || { echo "ERROR: --results-dir requires a path." >&2; exit 2; }
RESULTS_DIR=$2
shift 2
;;
-h|--help) usage; exit 0 ;;
*) echo "ERROR: unknown option: $1" >&2; usage; exit 2 ;;
esac
done
case "${SCENARIO}" in
smoke) COMMAND_CLASS="conformance_smoke" ;;
external-driver) COMMAND_CLASS="external_driver_conformance_smoke" ;;
podman-options) COMMAND_CLASS="podman_options" ;;
*) echo "ERROR: unsupported parity scenario: ${SCENARIO}." >&2; exit 2 ;;
esac
if [ "${DRIVER}" != "podman" ]; then
echo "ERROR: only --driver podman is supported by the schema parity harness (got ${DRIVER:-<none>})." >&2
echo " Docker, Kubernetes, and VM backends are reserved for later parity waves." >&2
exit 2
fi
if [ ! -f "${MANIFEST}" ]; then
echo "ERROR: parity capability manifest not found: ${MANIFEST}" >&2
exit 2
fi
BASELINE_SHA="$(awk -F '"' '/^[[:space:]]*baseline_commit[[:space:]]*=/ { print $2; exit }' "${MANIFEST}")"
if ! [[ "${BASELINE_SHA}" =~ ^[0-9a-fA-F]{40}$ ]]; then
echo "ERROR: manifest baseline_commit must be a full 40-character SHA: ${MANIFEST}" >&2
exit 2
fi
BASELINE_SHA="$(echo "$BASELINE_SHA" | tr '[:upper:]' '[:lower:]')"
EXPECTED_CANDIDATE_SHA="$(git -C "${ROOT}" rev-parse HEAD)"
if [ ! -d "${CANDIDATE_WORKTREE}" ]; then
echo "ERROR: candidate worktree does not exist: ${CANDIDATE_WORKTREE}" >&2
exit 2
fi
CANDIDATE_SHA="$(git -C "${CANDIDATE_WORKTREE}" rev-parse HEAD 2>/dev/null || true)"
if [ "${CANDIDATE_SHA}" != "${EXPECTED_CANDIDATE_SHA}" ]; then
echo "ERROR: candidate worktree must be at current commit ${EXPECTED_CANDIDATE_SHA}: ${CANDIDATE_WORKTREE}" >&2
exit 2
fi
cleanup() {
local status=$?
if [ -n "${TEMP_WORKTREE}" ]; then
git -C "${ROOT}" worktree remove --force "${TEMP_WORKTREE}" >/dev/null 2>&1 || true
fi
if [ -n "${RUN_DIR}" ]; then
# Rootless Podman overlay files can be owned by subordinate UIDs. Remove an
# isolated container store from Podman's user namespace before falling back
# to ordinary cleanup for runs that never reached the container runtime.
if { [ -d "${RUN_DIR}/baseline/data/containers/storage" ] \
|| [ -d "${RUN_DIR}/candidate/data/containers/storage" ] \
|| [ -d "${RUN_DIR}/sandbox-resolver/data/containers/storage" ]; } \
&& command -v "${PODMAN_BIN}" >/dev/null 2>&1; then
"${PODMAN_BIN}" unshare rm -rf -- "${RUN_DIR}" >/dev/null 2>&1 || true
fi
rm -rf "${RUN_DIR}" >/dev/null 2>&1 || true
fi
exit "${status}"
}
trap cleanup EXIT
if [ -n "${BASELINE_WORKTREE}" ]; then
if [ ! -d "${BASELINE_WORKTREE}" ]; then
echo "ERROR: baseline worktree does not exist: ${BASELINE_WORKTREE}" >&2
exit 2
fi
resolved_baseline_sha="$(git -C "${BASELINE_WORKTREE}" rev-parse HEAD 2>/dev/null || true)"
if [ "${resolved_baseline_sha}" != "${BASELINE_SHA}" ]; then
echo "ERROR: baseline worktree is not frozen manifest commit ${BASELINE_SHA}: ${BASELINE_WORKTREE}" >&2
exit 2
fi
else
if ! git -C "${ROOT}" cat-file -e "${BASELINE_SHA}^{commit}" 2>/dev/null; then
echo "ERROR: frozen baseline ${BASELINE_SHA} is unavailable locally; fetch it before running parity." >&2
exit 2
fi
TEMP_WORKTREE="$(mktemp -d "${TMPDIR:-/tmp}/openshell-parity-baseline.XXXXXX")"
# Remove mktemp's directory so git worktree can create and register it.
rmdir "${TEMP_WORKTREE}"
git -C "${ROOT}" worktree add --detach "${TEMP_WORKTREE}" "${BASELINE_SHA}" >/dev/null
BASELINE_WORKTREE="${TEMP_WORKTREE}"
fi
require_clean_source() {
local variant=$1 source_root=$2 dirty
dirty="$(git -C "${source_root}" status --porcelain=v1 --untracked-files=all)"
if [ -n "${dirty}" ]; then
echo "ERROR: ${variant} source worktree must be clean before building parity artifacts: ${source_root}" >&2
printf '%s\n' "${dirty}" >&2
exit 2
fi
}
RUN_DIR="$(mktemp -d "${TMPDIR:-/tmp}/openshell-parity-run.XXXXXX")"
if [ -n "${RESULTS_DIR}" ]; then
if [ -e "${RESULTS_DIR}" ] || [ -L "${RESULTS_DIR}" ]; then
echo "ERROR: parity results directory already exists; choose a fresh path: ${RESULTS_DIR}" >&2
exit 2
fi
mkdir -p "$(dirname "${RESULTS_DIR}")"
mkdir -m 0700 "${RESULTS_DIR}"
else
mkdir -p "${ROOT}/target/parity"
RESULTS_DIR="$(mktemp -d "${ROOT}/target/parity/run.${SCENARIO}.XXXXXX")"
fi
RESULTS_DIR="$(cd "${RESULTS_DIR}" && pwd)"
echo "Retaining parity evidence in ${RESULTS_DIR}"
require_executable() {
local label=$1
local binary=$2
if [ ! -x "${binary}" ]; then
echo "ERROR: ${label} binary is not executable: ${binary}" >&2
exit 2
fi
}
build_variant() {
local variant=$1 source_root=$2 target_dir=$3 gateway_override=$4 cli_override=$5 conformance_override=$6
local gateway_var=$7 cli_var=$8 conformance_var=$9
local gateway cli conformance jobs=() gateway_features=()
if [ -n "${CARGO_BUILD_JOBS:-}" ]; then jobs=(-j "${CARGO_BUILD_JOBS}"); fi
if [ "${SCENARIO}" = external-driver ]; then
gateway_features=(--no-default-features --features telemetry)
fi
target_dir="${target_dir:-${ROOT}/target/parity/${variant}}"
case "${target_dir}" in /*) ;; *) target_dir="${ROOT}/${target_dir}" ;; esac
gateway="${gateway_override:-${target_dir}/debug/openshell-gateway}"
cli="${cli_override:-${target_dir}/debug/openshell}"
conformance="${conformance_override:-${target_dir}/debug/openshell-conformance}"
if [ -z "${gateway_override}" ]; then
require_clean_source "${variant}" "${source_root}"
echo "Building ${variant} gateway in ${target_dir}..."
(cd "${source_root}" && CARGO_TARGET_DIR="${target_dir}" cargo build "${jobs[@]}" -p openshell-gateway --bin openshell-gateway "${gateway_features[@]}")
fi
if [ -z "${cli_override}" ]; then
require_clean_source "${variant}" "${source_root}"
echo "Building ${variant} CLI in ${target_dir}..."
(cd "${source_root}" && CARGO_TARGET_DIR="${target_dir}" cargo build "${jobs[@]}" -p openshell-cli)
fi
if [ -z "${conformance_override}" ]; then
require_clean_source "${variant}" "${source_root}"
echo "Building ${variant} conformance CLI in ${target_dir}..."
(cd "${source_root}" && CARGO_TARGET_DIR="${target_dir}" cargo build "${jobs[@]}" -p openshell-conformance-cli)
fi
require_executable "${variant} gateway" "${gateway}"
require_executable "${variant} CLI" "${cli}"
require_executable "${variant} conformance" "${conformance}"
printf -v "${gateway_var}" '%s' "${gateway}"
printf -v "${cli_var}" '%s' "${cli}"
printf -v "${conformance_var}" '%s' "${conformance}"
}
BASELINE_GATEWAY="" BASELINE_CLI="" BASELINE_CONFORMANCE=""
CANDIDATE_GATEWAY="" CANDIDATE_CLI="" CANDIDATE_CONFORMANCE=""
build_variant baseline "${BASELINE_WORKTREE}" "${OPENSHELL_PARITY_BASELINE_CARGO_TARGET_DIR:-}" "${OPENSHELL_PARITY_BASELINE_GATEWAY_BIN:-}" "${OPENSHELL_PARITY_BASELINE_CLI_BIN:-}" "${OPENSHELL_PARITY_BASELINE_CONFORMANCE_BIN:-}" BASELINE_GATEWAY BASELINE_CLI BASELINE_CONFORMANCE
build_variant candidate "${CANDIDATE_WORKTREE}" "${OPENSHELL_PARITY_CANDIDATE_CARGO_TARGET_DIR:-}" "${OPENSHELL_PARITY_CANDIDATE_GATEWAY_BIN:-}" "${OPENSHELL_PARITY_CANDIDATE_CLI_BIN:-}" "${OPENSHELL_PARITY_CANDIDATE_CONFORMANCE_BIN:-}" CANDIDATE_GATEWAY CANDIDATE_CLI CANDIDATE_CONFORMANCE
BASELINE_GATEWAY_ORIGIN=built_by_harness
BASELINE_CLI_ORIGIN=built_by_harness
BASELINE_CONFORMANCE_ORIGIN=built_by_harness
CANDIDATE_GATEWAY_ORIGIN=built_by_harness
CANDIDATE_CLI_ORIGIN=built_by_harness
CANDIDATE_CONFORMANCE_ORIGIN=built_by_harness
[ -z "${OPENSHELL_PARITY_BASELINE_GATEWAY_BIN:-}" ] || BASELINE_GATEWAY_ORIGIN=supplied_override
[ -z "${OPENSHELL_PARITY_BASELINE_CLI_BIN:-}" ] || BASELINE_CLI_ORIGIN=supplied_override
[ -z "${OPENSHELL_PARITY_BASELINE_CONFORMANCE_BIN:-}" ] || BASELINE_CONFORMANCE_ORIGIN=supplied_override
[ -z "${OPENSHELL_PARITY_CANDIDATE_GATEWAY_BIN:-}" ] || CANDIDATE_GATEWAY_ORIGIN=supplied_override
[ -z "${OPENSHELL_PARITY_CANDIDATE_CLI_BIN:-}" ] || CANDIDATE_CLI_ORIGIN=supplied_override
[ -z "${OPENSHELL_PARITY_CANDIDATE_CONFORMANCE_BIN:-}" ] || CANDIDATE_CONFORMANCE_ORIGIN=supplied_override
build_external_driver() {
local variant=$1 source_root=$2 target_dir=$3 override=$4 output_var=$5
local binary
if [ "${SCENARIO}" != external-driver ]; then
printf -v "${output_var}" '%s' ""
return
fi
target_dir="${target_dir:-${ROOT}/target/parity/${variant}}"
case "${target_dir}" in /*) ;; *) target_dir="${ROOT}/${target_dir}" ;; esac
binary="${override:-${target_dir}/debug/openshell-driver-podman}"
if [ -z "${override}" ]; then
require_clean_source "${variant}" "${source_root}"
echo "Building ${variant} external Podman driver in ${target_dir}..."
(cd "${source_root}" && CARGO_TARGET_DIR="${target_dir}" cargo build -p openshell-driver-podman --bin openshell-driver-podman)
fi
require_executable "${variant} external Podman driver" "${binary}"
printf -v "${output_var}" '%s' "${binary}"
}
BASELINE_EXTERNAL_DRIVER="" CANDIDATE_EXTERNAL_DRIVER=""
BASELINE_EXTERNAL_DRIVER_ORIGIN=not_applicable
CANDIDATE_EXTERNAL_DRIVER_ORIGIN=not_applicable
if [ "${SCENARIO}" = external-driver ]; then
BASELINE_EXTERNAL_DRIVER_ORIGIN=built_by_harness
CANDIDATE_EXTERNAL_DRIVER_ORIGIN=built_by_harness
[ -z "${OPENSHELL_PARITY_BASELINE_EXTERNAL_DRIVER_BIN:-}" ] || BASELINE_EXTERNAL_DRIVER_ORIGIN=supplied_override
[ -z "${OPENSHELL_PARITY_CANDIDATE_EXTERNAL_DRIVER_BIN:-}" ] || CANDIDATE_EXTERNAL_DRIVER_ORIGIN=supplied_override
fi
build_external_driver baseline "${BASELINE_WORKTREE}" "${OPENSHELL_PARITY_BASELINE_CARGO_TARGET_DIR:-}" "${OPENSHELL_PARITY_BASELINE_EXTERNAL_DRIVER_BIN:-}" BASELINE_EXTERNAL_DRIVER
build_external_driver candidate "${CANDIDATE_WORKTREE}" "${OPENSHELL_PARITY_CANDIDATE_CARGO_TARGET_DIR:-}" "${OPENSHELL_PARITY_CANDIDATE_EXTERNAL_DRIVER_BIN:-}" CANDIDATE_EXTERNAL_DRIVER
if [ "${SCENARIO}" = external-driver ]; then
baseline_external_realpath="$(realpath "${BASELINE_EXTERNAL_DRIVER}")"
candidate_external_realpath="$(realpath "${CANDIDATE_EXTERNAL_DRIVER}")"
if [ "${baseline_external_realpath}" = "${candidate_external_realpath}" ] \
|| [ "${BASELINE_EXTERNAL_DRIVER}" -ef "${CANDIDATE_EXTERNAL_DRIVER}" ]; then
echo "ERROR: external-driver parity requires distinct baseline and candidate driver artifacts." >&2
exit 2
fi
fi
supervisor_target_triple() {
case "$(uname -sm)" in
"Linux x86_64") printf '%s\n' x86_64-unknown-linux-musl ;;
"Linux aarch64"|"Linux arm64") printf '%s\n' aarch64-unknown-linux-musl ;;
*) echo "ERROR: Podman parity supervisor builds require Linux x86_64 or arm64." >&2; return 2 ;;
esac
}
build_supervisor() {
local variant=$1 source_root=$2 target_dir=$3 override=$4 output_var=$5
local binary target jobs=()
target_dir="${target_dir:-${ROOT}/target/parity/${variant}}"
case "${target_dir}" in /*) ;; *) target_dir="${ROOT}/${target_dir}" ;; esac
if [ -n "${override}" ]; then
binary="${override}"
else
target="$(supervisor_target_triple)"
binary="${target_dir}/${target}/release/openshell-sandbox"
require_clean_source "${variant}" "${source_root}"
if [ -n "${CARGO_BUILD_JOBS:-}" ]; then jobs=(-j "${CARGO_BUILD_JOBS}"); fi
echo "Building ${variant} supervisor in ${target_dir}..."
(cd "${source_root}" && CARGO_TARGET_DIR="${target_dir}" cargo build "${jobs[@]}" --release --target "${target}" -p openshell-sandbox --bin openshell-sandbox)
"${source_root}/tasks/scripts/verify-static-binary.sh" "${binary}"
fi
require_executable "${variant} supervisor" "${binary}"
printf -v "${output_var}" '%s' "${binary}"
}
BASELINE_SUPERVISOR="" CANDIDATE_SUPERVISOR=""
BASELINE_SUPERVISOR_ORIGIN=built_by_harness
CANDIDATE_SUPERVISOR_ORIGIN=built_by_harness
[ -z "${OPENSHELL_PARITY_BASELINE_SUPERVISOR_BIN:-}" ] || BASELINE_SUPERVISOR_ORIGIN=supplied_override
[ -z "${OPENSHELL_PARITY_CANDIDATE_SUPERVISOR_BIN:-}" ] || CANDIDATE_SUPERVISOR_ORIGIN=supplied_override
build_supervisor baseline "${BASELINE_WORKTREE}" "${OPENSHELL_PARITY_BASELINE_CARGO_TARGET_DIR:-}" "${OPENSHELL_PARITY_BASELINE_SUPERVISOR_BIN:-}" BASELINE_SUPERVISOR
build_supervisor candidate "${CANDIDATE_WORKTREE}" "${OPENSHELL_PARITY_CANDIDATE_CARGO_TARGET_DIR:-}" "${OPENSHELL_PARITY_CANDIDATE_SUPERVISOR_BIN:-}" CANDIDATE_SUPERVISOR
stage_artifact() {
local variant=$1 role=$2 source=$3 mode=$4 path_var=$5 digest_var=$6
local destination="${RESULTS_DIR}/artifacts/${variant}/${role}"
mkdir -p "$(dirname "${destination}")"
install -m "${mode}" "${source}" "${destination}"
printf -v "${path_var}" '%s' "${destination}"
printf -v "${digest_var}" '%s' "$(sha256sum "${destination}" | cut -d' ' -f1)"
}
stage_executable() {
stage_artifact "$1" "$2" "$3" 0555 "$4" "$5"
}
BASELINE_GATEWAY_DIGEST="" BASELINE_CLI_DIGEST="" BASELINE_CONFORMANCE_DIGEST="" BASELINE_EXTERNAL_DRIVER_DIGEST="" BASELINE_SUPERVISOR_DIGEST="" BASELINE_SUPERVISOR_DOCKERFILE="" BASELINE_SUPERVISOR_DOCKERFILE_DIGEST="" BASELINE_CLI_TRACE_WRAPPER="" BASELINE_CLI_TRACE_WRAPPER_DIGEST=""
CANDIDATE_GATEWAY_DIGEST="" CANDIDATE_CLI_DIGEST="" CANDIDATE_CONFORMANCE_DIGEST="" CANDIDATE_EXTERNAL_DRIVER_DIGEST="" CANDIDATE_SUPERVISOR_DIGEST="" CANDIDATE_SUPERVISOR_DOCKERFILE="" CANDIDATE_SUPERVISOR_DOCKERFILE_DIGEST="" CANDIDATE_CLI_TRACE_WRAPPER="" CANDIDATE_CLI_TRACE_WRAPPER_DIGEST=""
stage_executable baseline gateway "${BASELINE_GATEWAY}" BASELINE_GATEWAY BASELINE_GATEWAY_DIGEST
stage_executable baseline cli "${BASELINE_CLI}" BASELINE_CLI BASELINE_CLI_DIGEST
stage_executable baseline conformance "${BASELINE_CONFORMANCE}" BASELINE_CONFORMANCE BASELINE_CONFORMANCE_DIGEST
stage_executable baseline supervisor "${BASELINE_SUPERVISOR}" BASELINE_SUPERVISOR BASELINE_SUPERVISOR_DIGEST
stage_artifact baseline supervisor.Dockerfile "${BASELINE_WORKTREE}/deploy/docker/Dockerfile.supervisor" 0444 BASELINE_SUPERVISOR_DOCKERFILE BASELINE_SUPERVISOR_DOCKERFILE_DIGEST
stage_artifact baseline cli-trace-wrapper "${ROOT}/e2e/parity/trace-cli.sh" 0555 BASELINE_CLI_TRACE_WRAPPER BASELINE_CLI_TRACE_WRAPPER_DIGEST
stage_executable candidate gateway "${CANDIDATE_GATEWAY}" CANDIDATE_GATEWAY CANDIDATE_GATEWAY_DIGEST
stage_executable candidate cli "${CANDIDATE_CLI}" CANDIDATE_CLI CANDIDATE_CLI_DIGEST
stage_executable candidate conformance "${CANDIDATE_CONFORMANCE}" CANDIDATE_CONFORMANCE CANDIDATE_CONFORMANCE_DIGEST
stage_executable candidate supervisor "${CANDIDATE_SUPERVISOR}" CANDIDATE_SUPERVISOR CANDIDATE_SUPERVISOR_DIGEST
stage_artifact candidate supervisor.Dockerfile "${CANDIDATE_WORKTREE}/deploy/docker/Dockerfile.supervisor" 0444 CANDIDATE_SUPERVISOR_DOCKERFILE CANDIDATE_SUPERVISOR_DOCKERFILE_DIGEST
stage_artifact candidate cli-trace-wrapper "${ROOT}/e2e/parity/trace-cli.sh" 0555 CANDIDATE_CLI_TRACE_WRAPPER CANDIDATE_CLI_TRACE_WRAPPER_DIGEST
if [ "${SCENARIO}" = external-driver ]; then
stage_executable baseline external-driver "${BASELINE_EXTERNAL_DRIVER}" BASELINE_EXTERNAL_DRIVER BASELINE_EXTERNAL_DRIVER_DIGEST
stage_executable candidate external-driver "${CANDIDATE_EXTERNAL_DRIVER}" CANDIDATE_EXTERNAL_DRIVER CANDIDATE_EXTERNAL_DRIVER_DIGEST
if [ "${BASELINE_EXTERNAL_DRIVER_DIGEST}" = "${CANDIDATE_EXTERNAL_DRIVER_DIGEST}" ]; then
echo "ERROR: external-driver parity requires different baseline and candidate driver content." >&2
exit 2
fi
fi
require_executable "Podman parity wrapper" "${WRAPPER}"
if [ "${SCENARIO}" = "podman-options" ] && [ ! -f "${PODMAN_OPTIONS_ORACLE}" ]; then
echo "ERROR: Podman options oracle does not exist: ${PODMAN_OPTIONS_ORACLE}" >&2
exit 2
fi
if [ "${SCENARIO}" != "podman-options" ] && [ ! -f "${CONFORMANCE_TRACE_WRAPPER}" ]; then
echo "ERROR: conformance trace wrapper does not exist: ${CONFORMANCE_TRACE_WRAPPER}" >&2
exit 2
fi
podman_in_resolver_store() {
local resolver_home="${RUN_DIR}/sandbox-resolver"
mkdir -p "${resolver_home}/config" "${resolver_home}/state" \
"${resolver_home}/cache" "${resolver_home}/data"
env -u CONTAINER_HOST -u CONTAINER_CONNECTION -u CONTAINERS_STORAGE_CONF \
-u CONTAINERS_CONF -u CONTAINERS_REGISTRIES_CONF -u CONTAINERS_REGISTRIES_CONF_DIR \
-u CONTAINERS_POLICY -u PODMAN_CONNECTIONS_CONF -u DOCKER_HOST \
XDG_CONFIG_HOME="${resolver_home}/config" \
XDG_STATE_HOME="${resolver_home}/state" \
XDG_CACHE_HOME="${resolver_home}/cache" \
XDG_DATA_HOME="${resolver_home}/data" \
"${PODMAN_BIN}" "$@"
}
resolve_parity_sandbox_image() {
local image_id image_digest repository
if [ -n "${OPENSHELL_E2E_PODMAN_SANDBOX_IMAGE:-}" ] \
&& ! [[ "${OPENSHELL_E2E_PODMAN_SANDBOX_IMAGE}" =~ ^[^@]+@sha256:[0-9a-f]{64}$ ]]; then
echo "ERROR: OPENSHELL_E2E_PODMAN_SANDBOX_IMAGE must be digest-pinned for parity runs." >&2
exit 2
fi
case "${SANDBOX_IMAGE_REQUEST}" in
*/*) ;;
*)
echo "ERROR: parity sandbox image must use a fully qualified repository: ${SANDBOX_IMAGE_REQUEST}" >&2
exit 2
;;
esac
echo "Resolving parity sandbox image once: ${SANDBOX_IMAGE_REQUEST}"
podman_in_resolver_store pull "${SANDBOX_IMAGE_REQUEST}" >/dev/null
image_id="$(podman_in_resolver_store image inspect --format '{{.Id}}' "${SANDBOX_IMAGE_REQUEST}")"
image_id="${image_id#sha256:}"
image_digest="$(podman_in_resolver_store image inspect --format '{{.Digest}}' "${SANDBOX_IMAGE_REQUEST}")"
repository="${SANDBOX_IMAGE_REQUEST%%@*}"
case "${repository##*/}" in
*:*) repository="${repository%:*}" ;;
esac
PARITY_SANDBOX_RUNTIME_IMAGE="${repository}@${image_digest}"
if ! [[ "${image_id}" =~ ^[0-9a-f]{64}$ ]] \
|| ! [[ "${PARITY_SANDBOX_RUNTIME_IMAGE}" =~ ^[^@]+@sha256:[0-9a-f]{64}$ ]]; then
echo "ERROR: could not resolve one immutable parity sandbox image from ${SANDBOX_IMAGE_REQUEST}." >&2
exit 2
fi
echo "Using one immutable parity sandbox image for both variants: ${PARITY_SANDBOX_RUNTIME_IMAGE} (ID ${image_id})"
}
resolve_parity_supervisor_base_image() {
local baseline_base candidate_base
baseline_base="$(awk '$1 == "FROM" { print $2; exit }' "${BASELINE_SUPERVISOR_DOCKERFILE}")"
candidate_base="$(awk '$1 == "FROM" { print $2; exit }' "${CANDIDATE_SUPERVISOR_DOCKERFILE}")"
if [ -z "${baseline_base}" ] || [ "${baseline_base}" != "${candidate_base}" ]; then
echo "ERROR: parity supervisor Dockerfiles must select the same base image." >&2
exit 2
fi
PARITY_SUPERVISOR_BASE_IMAGE="${baseline_base}"
echo "Resolving parity supervisor base image once: ${PARITY_SUPERVISOR_BASE_IMAGE}"
podman_in_resolver_store pull "${PARITY_SUPERVISOR_BASE_IMAGE}" >/dev/null
PARITY_SUPERVISOR_BASE_RUNTIME_IMAGE="$(podman_in_resolver_store image inspect --format '{{index .RepoDigests 0}}' "${PARITY_SUPERVISOR_BASE_IMAGE}")"
if ! [[ "${PARITY_SUPERVISOR_BASE_RUNTIME_IMAGE}" =~ ^[^@]+@sha256:[0-9a-f]{64}$ ]]; then
echo "ERROR: could not resolve one immutable supervisor base image from ${PARITY_SUPERVISOR_BASE_IMAGE}." >&2
exit 2
fi
echo "Using one immutable supervisor base image for both variants: ${PARITY_SUPERVISOR_BASE_RUNTIME_IMAGE}"
}
resolve_parity_sandbox_image
resolve_parity_supervisor_base_image
write_result() {
local variant=$1 source_sha=$2 schema=$3 status=$4
local gateway_digest=$5 cli_digest=$6 conformance_digest=$7 external_driver_digest_value=$8 supervisor_digest=$9 supervisor_dockerfile_digest=${10} cli_trace_wrapper_digest=${11}
local normalized_result="" external_driver_digest="" gateway_profile="in-tree"
local gateway_features=default
local gateway_origin cli_origin conformance_origin external_driver_origin supervisor_origin
if [ "${variant}" = baseline ]; then
gateway_origin=${BASELINE_GATEWAY_ORIGIN}
cli_origin=${BASELINE_CLI_ORIGIN}
conformance_origin=${BASELINE_CONFORMANCE_ORIGIN}
external_driver_origin=${BASELINE_EXTERNAL_DRIVER_ORIGIN}
supervisor_origin=${BASELINE_SUPERVISOR_ORIGIN}
else
gateway_origin=${CANDIDATE_GATEWAY_ORIGIN}
cli_origin=${CANDIDATE_CLI_ORIGIN}
conformance_origin=${CANDIDATE_CONFORMANCE_ORIGIN}
external_driver_origin=${CANDIDATE_EXTERNAL_DRIVER_ORIGIN}
supervisor_origin=${CANDIDATE_SUPERVISOR_ORIGIN}
fi
if [ -n "${external_driver_digest_value}" ]; then
external_driver_digest=",\"external_driver_sha256\":\"${external_driver_digest_value}\""
gateway_profile="driver-free"
gateway_features="--no-default-features --features telemetry"
fi
if [ "${SCENARIO}" = "podman-options" ]; then normalized_result=",\"normalized_result\":\"${variant}.normalized.json\""; fi
cat >"${RESULTS_DIR}/${variant}.json" <<EOF
{"variant":"${variant}","source_sha":"${source_sha}","schema_version":${schema},"driver":"${DRIVER}","scenario":"${SCENARIO}","command_class":"${COMMAND_CLASS}","gateway_profile":"${gateway_profile}","gateway_cargo_features":"${gateway_features}","gateway_origin":"${gateway_origin}","cli_origin":"${cli_origin}","conformance_origin":"${conformance_origin}","external_driver_origin":"${external_driver_origin}","supervisor_origin":"${supervisor_origin}","gateway_sha256":"${gateway_digest}","cli_sha256":"${cli_digest}","conformance_sha256":"${conformance_digest}","supervisor_sha256":"${supervisor_digest}","supervisor_dockerfile_sha256":"${supervisor_dockerfile_digest}","cli_trace_wrapper_sha256":"${cli_trace_wrapper_digest}"${normalized_result}${external_driver_digest},"success":${status}}
EOF
}
COMPARISON_ACCEPTED=false
COMPARISON_CLASSIFICATION="regression"
write_comparison() {
local baseline_status=$1 candidate_status=$2 semantic_verified=$3
local parity=false intentional_change_id=null
COMPARISON_ACCEPTED=false
COMPARISON_CLASSIFICATION="regression"
if [ "${baseline_status}" = true ] && [ "${candidate_status}" = true ]; then
if [ "${SCENARIO}" != "podman-options" ] && [ "${semantic_verified}" = true ]; then
parity=true
COMPARISON_ACCEPTED=true
COMPARISON_CLASSIFICATION="pass"
elif [ "${SCENARIO}" = "podman-options" ] \
&& { [ ! -s "${RESULTS_DIR}/baseline.normalized.json" ] \
|| [ ! -s "${RESULTS_DIR}/candidate.normalized.json" ]; }; then
COMPARISON_CLASSIFICATION="regression"
elif [ "${SCENARIO}" = "podman-options" ] \
&& cmp -s "${RESULTS_DIR}/baseline.normalized.json" "${RESULTS_DIR}/candidate.normalized.json"; then
parity=true
COMPARISON_ACCEPTED=true
COMPARISON_CLASSIFICATION="pass"
elif [ "${SCENARIO}" = "podman-options" ]; then
sed -E 's/"pids_limit":[0-9]+/"pids_limit":IGNORED/' "${RESULTS_DIR}/baseline.normalized.json" >"${RUN_DIR}/baseline.semantic"
sed -E 's/"pids_limit":[0-9]+/"pids_limit":IGNORED/' "${RESULTS_DIR}/candidate.normalized.json" >"${RUN_DIR}/candidate.semantic"
if grep -F '"pids_limit":2048' "${RESULTS_DIR}/baseline.normalized.json" >/dev/null \
&& grep -F '"pids_limit":31' "${RESULTS_DIR}/candidate.normalized.json" >/dev/null \
&& cmp -s "${RUN_DIR}/baseline.semantic" "${RUN_DIR}/candidate.semantic"; then
COMPARISON_ACCEPTED=true
COMPARISON_CLASSIFICATION="intentional_change"
intentional_change_id='"podman-pid-limit-restored"'
fi
fi
fi
cat >"${RESULTS_DIR}/comparison.json" <<EOF
{"driver":"${DRIVER}","scenario":"${SCENARIO}","command_class":"${COMMAND_CLASS}","baseline_success":${baseline_status},"candidate_success":${candidate_status},"parity":${parity},"classification":"${COMPARISON_CLASSIFICATION}","intentional_change_id":${intentional_change_id},"accepted":${COMPARISON_ACCEPTED}}
EOF
}
verify_artifact_digest() {
local label=$1 path=$2 expected=$3 actual
actual="$(sha256sum "${path}" | cut -d' ' -f1)"
if [ "${actual}" != "${expected}" ]; then
echo "ERROR: ${label} changed after it was staged for execution." >&2
return 1
fi
}
run_variant() {
local variant=$1 source_sha=$2 schema=$3 gateway=$4 cli=$5 conformance=$6 external_driver=$7 supervisor=$8 supervisor_dockerfile=$9
local gateway_digest=${10} cli_digest=${11} conformance_digest=${12} external_driver_digest=${13} supervisor_digest=${14} supervisor_dockerfile_digest=${15} cli_trace_wrapper=${16} cli_trace_wrapper_digest=${17}
local result_status variant_home="${RUN_DIR}/${variant}"
local supervisor_image="localhost/openshell/supervisor:parity-${variant}-${source_sha:0:12}"
mkdir -p "${variant_home}/config" "${variant_home}/state" "${variant_home}/cache" "${variant_home}/data"
echo "==> schema parity ${variant} (schema v${schema}, ${DRIVER}, ${SCENARIO})"
local option_profile=""
local -a command
if [ "${SCENARIO}" = "podman-options" ]; then
option_profile="podman-options"
command=(bash "${PODMAN_OPTIONS_ORACLE}")
else
command=(bash "${CONFORMANCE_TRACE_WRAPPER}" run --openshell-bin "${cli_trace_wrapper}" --output json)
fi
verify_artifact_digest "${variant} gateway before execution" "${gateway}" "${gateway_digest}" || return 1
verify_artifact_digest "${variant} CLI before execution" "${cli}" "${cli_digest}" || return 1
verify_artifact_digest "${variant} conformance CLI before execution" "${conformance}" "${conformance_digest}" || return 1
verify_artifact_digest "${variant} supervisor before execution" "${supervisor}" "${supervisor_digest}" || return 1
verify_artifact_digest "${variant} supervisor Dockerfile before execution" "${supervisor_dockerfile}" "${supervisor_dockerfile_digest}" || return 1
verify_artifact_digest "${variant} CLI trace wrapper before execution" "${cli_trace_wrapper}" "${cli_trace_wrapper_digest}" || return 1
if [ -n "${external_driver}" ]; then
verify_artifact_digest "${variant} external driver before execution" "${external_driver}" "${external_driver_digest}" || return 1
fi
if env -u OPENSHELL_GATEWAY_ENDPOINT -u OPENSHELL_GATEWAY_CONFIG \
-u OPENSHELL_COMPUTE_DRIVER -u OPENSHELL_COMPUTE_DRIVER_SOCKET -u OPENSHELL_DRIVERS \
-u OPENSHELL_PODMAN_SOCKET \
-u CONTAINER_HOST -u CONTAINER_CONNECTION -u CONTAINERS_STORAGE_CONF \
-u CONTAINERS_CONF -u CONTAINERS_REGISTRIES_CONF -u CONTAINERS_REGISTRIES_CONF_DIR \
-u CONTAINERS_POLICY -u PODMAN_CONNECTIONS_CONF -u DOCKER_HOST \
-u OPENSHELL_SANDBOX_IMAGE -u OPENSHELL_SANDBOX_RUNTIME_IMAGE \
-u OPENSHELL_E2E_PODMAN_SANDBOX_IMAGE \
-u OPENSHELL_GRPC_ENDPOINT -u OPENSHELL_PODMAN_HOST_GATEWAY_IP \
-u OPENSHELL_PODMAN_USERNS -u OPENSHELL_PROVIDER_SPIFFE_WORKLOAD_API_SOCKET \
-u OPENSHELL_E2E_PROVIDER_SPIFFE_SOCKET -u OPENSHELL_APP_ARMOR_PROFILE \
-u OPENSHELL_SANDBOX_HTTPS_PROXY -u OPENSHELL_SANDBOX_NO_PROXY \
-u OPENSHELL_SANDBOX_PROXY_AUTH_FILE -u OPENSHELL_SANDBOX_PROXY_AUTH_ALLOW_INSECURE \
-u OPENSHELL_SANDBOX_PROXY_CONNECT_BY_HOSTNAME -u OPENSHELL_SANDBOX_PROXY_CA_BUNDLE \
-u OPENSHELL_OTLP_ENDPOINT -u OPENSHELL_GATEWAY_NAME -u OPENSHELL_COMPUTE_DRIVER_BIND \
OPENSHELL_PARITY_VARIANT="${variant}" \
OPENSHELL_E2E_CONFIG_SCHEMA_VERSION="${schema}" \
OPENSHELL_E2E_EXTERNAL_COMPUTE_DRIVER="$([ "${SCENARIO}" = external-driver ] && printf 1 || printf 0)" \
OPENSHELL_EXTERNAL_DRIVER_BIN="${external_driver}" \
OPENSHELL_E2E_SUPERVISOR_BIN="${supervisor}" \
OPENSHELL_E2E_SUPERVISOR_DOCKERFILE="${supervisor_dockerfile}" \
OPENSHELL_E2E_FORCE_TEMP_PODMAN_SERVICE=1 \
OPENSHELL_E2E_REQUIRE_DIGEST_PINNED_SANDBOX_IMAGE=1 \
OPENSHELL_E2E_PODMAN_SANDBOX_IMAGE="${PARITY_SANDBOX_RUNTIME_IMAGE}" \
OPENSHELL_E2E_SUPERVISOR_BASE_IMAGE="${PARITY_SUPERVISOR_BASE_IMAGE}" \
OPENSHELL_E2E_SUPERVISOR_BASE_RUNTIME_IMAGE="${PARITY_SUPERVISOR_BASE_RUNTIME_IMAGE}" \
OPENSHELL_E2E_EXPECTED_GATEWAY_SHA256="${gateway_digest}" \
OPENSHELL_E2E_EXPECTED_CLI_SHA256="${cli_digest}" \
OPENSHELL_E2E_EXPECTED_CONFORMANCE_SHA256="${conformance_digest}" \
OPENSHELL_E2E_EXPECTED_EXTERNAL_DRIVER_SHA256="${external_driver_digest}" \
OPENSHELL_E2E_EXPECTED_SUPERVISOR_SHA256="${supervisor_digest}" \
OPENSHELL_E2E_EXPECTED_SUPERVISOR_DOCKERFILE_SHA256="${supervisor_dockerfile_digest}" \
OPENSHELL_E2E_EXPECTED_CLI_TRACE_WRAPPER_SHA256="${cli_trace_wrapper_digest}" \
OPENSHELL_PARITY_REAL_CLI="${cli}" \
OPENSHELL_PARITY_REAL_CONFORMANCE="${conformance}" \
OPENSHELL_PARITY_CONFORMANCE_REPORT_CAPTURE="${RESULTS_DIR}/${variant}.conformance.json" \
OPENSHELL_PARITY_EXEC_STDOUT_CAPTURE="${RESULTS_DIR}/${variant}.exec.stdout" \
OPENSHELL_PARITY_EXTERNAL_DRIVER_LOG_CAPTURE="${RESULTS_DIR}/${variant}.driver.log" \
OPENSHELL_SUPERVISOR_IMAGE="${supervisor_image}" \
OPENSHELL_E2E_PODMAN_OPTION_PROFILE="${option_profile}" \
OPENSHELL_PARITY_ORACLE_RESULT="${RESULTS_DIR}/${variant}.normalized.json" \
OPENSHELL_PARITY_GATEWAY_CONFIG_CAPTURE="${RESULTS_DIR}/${variant}.gateway.toml" \
OPENSHELL_PARITY_LAUNCH_MANIFEST_CAPTURE="${RESULTS_DIR}/${variant}.launch.json" \
OPENSHELL_PARITY_SUPERVISOR_PACKAGE_CAPTURE="${RESULTS_DIR}/artifacts/${variant}/supervisor.packages.txt" \
OPENSHELL_GATEWAY_BIN="${gateway}" \
OPENSHELL_BIN="${cli}" \
OPENSHELL_CONFORMANCE_BIN="${conformance}" \
MISE_TRUSTED_CONFIG_PATHS="${MISE_TRUSTED_CONFIG_PATHS:-${ROOT}}" \
XDG_CONFIG_HOME="${variant_home}/config" \
XDG_STATE_HOME="${variant_home}/state" \
XDG_CACHE_HOME="${variant_home}/cache" \
XDG_DATA_HOME="${variant_home}/data" \
"${WRAPPER}" "${command[@]}" \
2>&1 | tee "${RESULTS_DIR}/${variant}.log"; then
result_status=true
else
result_status=false
fi
if [ ! -s "${RESULTS_DIR}/${variant}.launch.json" ]; then
echo "ERROR: ${variant} launcher did not emit a launch manifest." >&2
result_status=false
fi
verify_artifact_digest "${variant} gateway" "${gateway}" "${gateway_digest}" || result_status=false
verify_artifact_digest "${variant} CLI" "${cli}" "${cli_digest}" || result_status=false
verify_artifact_digest "${variant} conformance CLI" "${conformance}" "${conformance_digest}" || result_status=false
verify_artifact_digest "${variant} supervisor" "${supervisor}" "${supervisor_digest}" || result_status=false
verify_artifact_digest "${variant} supervisor Dockerfile" "${supervisor_dockerfile}" "${supervisor_dockerfile_digest}" || result_status=false
verify_artifact_digest "${variant} CLI trace wrapper" "${cli_trace_wrapper}" "${cli_trace_wrapper_digest}" || result_status=false
if [ -n "${external_driver}" ]; then
verify_artifact_digest "${variant} external driver" "${external_driver}" "${external_driver_digest}" || result_status=false
fi
if [ "${SCENARIO}" != podman-options ] \
&& [ ! -s "${RESULTS_DIR}/${variant}.exec.stdout" ]; then
echo "ERROR: ${variant} CLI trace wrapper did not retain exec stdout." >&2
result_status=false
fi
if [ "${SCENARIO}" != podman-options ] \
&& [ ! -s "${RESULTS_DIR}/${variant}.conformance.json" ]; then
echo "ERROR: ${variant} conformance trace wrapper did not retain a report." >&2
result_status=false
fi
if [ "${SCENARIO}" = external-driver ] && [ ! -s "${RESULTS_DIR}/${variant}.driver.log" ]; then
echo "ERROR: ${variant} external driver log was not retained." >&2
result_status=false
fi
write_result "${variant}" "${source_sha}" "${schema}" "${result_status}" "${gateway_digest}" "${cli_digest}" "${conformance_digest}" "${external_driver_digest}" "${supervisor_digest}" "${supervisor_dockerfile_digest}" "${cli_trace_wrapper_digest}"
[ "${result_status}" = true ]
}
baseline_exit=0
candidate_exit=0
run_variant baseline "${BASELINE_SHA}" 1 "${BASELINE_GATEWAY}" "${BASELINE_CLI}" "${BASELINE_CONFORMANCE}" "${BASELINE_EXTERNAL_DRIVER}" "${BASELINE_SUPERVISOR}" "${BASELINE_SUPERVISOR_DOCKERFILE}" "${BASELINE_GATEWAY_DIGEST}" "${BASELINE_CLI_DIGEST}" "${BASELINE_CONFORMANCE_DIGEST}" "${BASELINE_EXTERNAL_DRIVER_DIGEST}" "${BASELINE_SUPERVISOR_DIGEST}" "${BASELINE_SUPERVISOR_DOCKERFILE_DIGEST}" "${BASELINE_CLI_TRACE_WRAPPER}" "${BASELINE_CLI_TRACE_WRAPPER_DIGEST}" || baseline_exit=$?
# Do not short-circuit: a candidate result is useful even when the frozen
# baseline failed, and two equal failures must never constitute parity.
run_variant candidate "${CANDIDATE_SHA}" 2 "${CANDIDATE_GATEWAY}" "${CANDIDATE_CLI}" "${CANDIDATE_CONFORMANCE}" "${CANDIDATE_EXTERNAL_DRIVER}" "${CANDIDATE_SUPERVISOR}" "${CANDIDATE_SUPERVISOR_DOCKERFILE}" "${CANDIDATE_GATEWAY_DIGEST}" "${CANDIDATE_CLI_DIGEST}" "${CANDIDATE_CONFORMANCE_DIGEST}" "${CANDIDATE_EXTERNAL_DRIVER_DIGEST}" "${CANDIDATE_SUPERVISOR_DIGEST}" "${CANDIDATE_SUPERVISOR_DOCKERFILE_DIGEST}" "${CANDIDATE_CLI_TRACE_WRAPPER}" "${CANDIDATE_CLI_TRACE_WRAPPER_DIGEST}" || candidate_exit=$?
baseline_success=$([ "${baseline_exit}" -eq 0 ] && printf true || printf false)
candidate_success=$([ "${candidate_exit}" -eq 0 ] && printf true || printf false)
semantic_verified=false
if [ "${baseline_success}" = true ] && [ "${candidate_success}" = true ] \
&& [ "${SCENARIO}" != podman-options ]; then
if [ ! -f "${RESULTS_VERIFIER}" ]; then
echo "ERROR: parity semantic verifier not found: ${RESULTS_VERIFIER}" >&2
elif python3 "${RESULTS_VERIFIER}" \
--baseline-sha "${BASELINE_SHA}" \
--candidate-sha "${CANDIDATE_SHA}" \
--scenario "${SCENARIO}" \
--results-dir "${RESULTS_DIR}" \
--output "${RESULTS_DIR}/semantic-verification.json" \
&& [ -s "${RESULTS_DIR}/semantic-verification.json" ]; then
semantic_verified=true
else
echo "ERROR: semantic verification failed for ${SCENARIO}." >&2
fi
fi
write_comparison "${baseline_success}" "${candidate_success}" "${semantic_verified}"
if [ "${COMPARISON_ACCEPTED}" != true ]; then
echo "ERROR: schema parity comparison classified ${SCENARIO} as a regression." >&2
exit 1
fi
if [ "${COMPARISON_CLASSIFICATION}" = intentional_change ]; then
echo "Schema parity accepted an intentional change: podman-pid-limit-restored (${SCENARIO})."
else
echo "Schema parity passed: baseline schema v1 and candidate schema v2 succeeded (${SCENARIO})."
fi
-593
View File
@@ -1,593 +0,0 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Deterministic contract tests for e2e/parity/run.sh. No container runtime is
# invoked; the Podman wrapper and all three artifacts are tiny local fakes.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
TEST_SUPERVISOR_BASE="$(awk '$1 == "FROM" { print $2; exit }' "${ROOT}/deploy/docker/Dockerfile.supervisor")"
TMP_ROOT="${TMPDIR:-/tmp}"
TMP_ROOT="${TMP_ROOT%/}"
WORKDIR="$(mktemp -d "${TMP_ROOT}/openshell-parity-test.XXXXXX")"
trap 'rm -rf "${WORKDIR}"' EXIT
fail() { echo "FAIL: $*" >&2; exit 1; }
assert_contains() { grep -F -- "$2" "$1" >/dev/null || fail "expected $1 to contain: $2"; }
assert_not_contains() { ! grep -F -- "$2" "$1" >/dev/null || fail "expected $1 not to contain: $2"; }
assert_status() { [ "$1" -eq "$2" ] || fail "expected status $2, got $1"; }
# Package provenance must work for both Debian status and distroless status.d.
uv run --no-project python - "${ROOT}" "${WORKDIR}" <<'PYTEST'
import runpy
import sys
from pathlib import Path
manifest = runpy.run_path(str(Path(sys.argv[1]) / "e2e/support/debian-package-manifest.py"))["package_manifest"]
root = Path(sys.argv[2]) / "dpkg-fixture"
root.mkdir()
(root / "status").write_text("Package: removed\nStatus: deinstall ok config-files\n\n")
(root / "status.d").mkdir()
(root / "status.d/libc6").write_text("Package: libc6\nVersion: 2.41\nArchitecture: arm64\nMulti-Arch: same\n")
(root / "status.d/libc6.md5sums").write_text("ignored checksum file")
assert manifest(root) == ["libc6:arm64=2.41"]
(root / "status").write_text("Package: ca-certificates\nStatus: install ok installed\nVersion: 20250419\nArchitecture: all\n")
assert manifest(root) == ["ca-certificates=20250419", "libc6:arm64=2.41"]
(root / "status.d/libc6").write_text("Package: broken\n")
try:
manifest(root)
except ValueError:
pass
else:
raise AssertionError("incomplete package metadata accepted")
try:
manifest(root / "missing")
except ValueError:
pass
else:
raise AssertionError("missing package metadata accepted")
PYTEST
# Schema generator behavior is separately deterministic and does not need a
# gateway, certificates, or Podman.
# shellcheck source=e2e/support/gateway-common.sh
source "${ROOT}/e2e/support/gateway-common.sh"
# shellcheck source=e2e/support/podman-gateway-config.sh
source "${ROOT}/e2e/support/podman-gateway-config.sh"
mkdir -p "${WORKDIR}/pki/client" "${WORKDIR}/jwt"
e2e_write_podman_gateway_config "${WORKDIR}/v1.toml" 1 "${ROOT}" "${WORKDIR}/pki" "${WORKDIR}/jwt" test-gateway 0 socket network 18181 image:test 15 supervisor:test sandbox:test '' '' 0 ''
e2e_write_podman_gateway_config "${WORKDIR}/v2.toml" 2 "${ROOT}" "${WORKDIR}/pki" "${WORKDIR}/jwt" test-gateway 0 socket network 18181 image:test 15 supervisor:test sandbox:test '' '' 0 ''
e2e_write_podman_gateway_config "${WORKDIR}/v2-external.toml" 2 "${ROOT}" "${WORKDIR}/pki" "${WORKDIR}/jwt" test-gateway 1 socket network 18181 image:test 15 supervisor:test sandbox:test '' '' 0 ''
assert_contains "${WORKDIR}/v1.toml" 'version = 1'
assert_contains "${WORKDIR}/v1.toml" 'compute_drivers = ["podman"]'
assert_contains "${WORKDIR}/v1.toml" 'image_pull_policy = "missing"'
assert_contains "${WORKDIR}/v1.toml" 'health_check_interval_secs = 0'
assert_contains "${WORKDIR}/v1.toml" 'sandbox_runtime_image = "sandbox:test"'
assert_contains "${WORKDIR}/v1.toml" 'guest_tls_ca = '
assert_contains "${WORKDIR}/v2.toml" 'version = 2'
assert_contains "${WORKDIR}/v2.toml" 'compute_driver = "podman"'
assert_contains "${WORKDIR}/v2.toml" 'image_pull_policy = "if_not_present"'
assert_contains "${WORKDIR}/v2.toml" 'allow_driver_config = true'
assert_contains "${WORKDIR}/v2.toml" 'sandbox_runtime_image = "sandbox:test"'
assert_contains "${WORKDIR}/v2.toml" '[openshell.drivers.podman.resource_admission]'
assert_not_contains "${WORKDIR}/v2.toml" 'health_check_interval_secs = 0'
assert_contains "${WORKDIR}/v2-external.toml" 'socket_path = "socket"'
assert_not_contains "${WORKDIR}/v2-external.toml" 'sandbox_runtime_image = "sandbox:test"'
assert_not_contains "${WORKDIR}/v2-external.toml" 'allow_driver_config = true'
assert_not_contains "${WORKDIR}/v2-external.toml" '[openshell.drivers.podman.resource_admission]'
# V2 guest TLS is emitted before its driver table; V1 is driver-local.
OPENSHELL_E2E_PODMAN_OPTION_PROFILE=podman-options e2e_write_podman_gateway_config "${WORKDIR}/v1-options.toml" 1 "${ROOT}" "${WORKDIR}/pki" "${WORKDIR}/jwt" test-gateway 0 socket network 18181 image:test 15 supervisor:test sandbox:test "" "" 0 ""
OPENSHELL_E2E_PODMAN_OPTION_PROFILE=podman-options e2e_write_podman_gateway_config "${WORKDIR}/v2-options.toml" 2 "${ROOT}" "${WORKDIR}/pki" "${WORKDIR}/jwt" test-gateway 0 socket network 18181 image:test 15 supervisor:test sandbox:test "" "" 0 ""
for config in "${WORKDIR}/v1-options.toml" "${WORKDIR}/v2-options.toml"; do
assert_contains "${config}" 'sandbox_pids_limit = 31'
assert_contains "${config}" 'health_check_interval_secs = 7'
assert_not_contains "${config}" 'app_armor_profile = '
done
assert_contains "${WORKDIR}/v1-options.toml" 'sandbox_ssh_socket_path = "/run/openshell/parity-ssh.sock"'
assert_contains "${WORKDIR}/v2-options.toml" 'ssh_socket_path = "/run/openshell/parity-ssh.sock"'
if OPENSHELL_E2E_PODMAN_OPTION_PROFILE=unknown e2e_podman_option_profile >/dev/null 2>&1; then fail 'unknown option profile unexpectedly accepted'; fi
v1_driver_line="$(grep -n '^\[openshell.drivers.podman\]' "${WORKDIR}/v1.toml" | cut -d: -f1)"
v1_tls_line="$(grep -n '^guest_tls_ca' "${WORKDIR}/v1.toml" | cut -d: -f1)"
v2_driver_line="$(grep -n '^\[openshell.drivers.podman\]' "${WORKDIR}/v2.toml" | cut -d: -f1)"
v2_tls_line="$(grep -n '^guest_tls_ca' "${WORKDIR}/v2.toml" | cut -d: -f1)"
[ "${v1_tls_line}" -gt "${v1_driver_line}" ] || fail 'v1 TLS must be driver-local'
[ "${v2_tls_line}" -lt "${v2_driver_line}" ] || fail 'v2 TLS must be gateway-owned'
if OPENSHELL_E2E_CONFIG_SCHEMA_VERSION=3 e2e_podman_config_schema_version >/dev/null 2>&1; then
fail 'invalid schema version unexpectedly accepted'
fi
set +e
env -u OPENSHELL_GATEWAY_ENDPOINT \
OPENSHELL_E2E_CONFIG_SCHEMA_VERSION=3 \
bash "${ROOT}/e2e/with-podman-gateway.sh" true >"${WORKDIR}/wrapper-schema.out" 2>&1
status=$?
set -e
assert_status "${status}" 2
assert_contains "${WORKDIR}/wrapper-schema.out" 'must be 1 or 2'
cat >"${WORKDIR}/trace-cli-fixture" <<'EOF'
#!/usr/bin/env bash
printf 'openshell-conformance-tracefixture\n'
printf 'trace fixture stderr\n' >&2
EOF
chmod +x "${WORKDIR}/trace-cli-fixture"
OPENSHELL_PARITY_REAL_CLI="${WORKDIR}/trace-cli-fixture" \
OPENSHELL_PARITY_EXEC_STDOUT_CAPTURE="${WORKDIR}/trace-cli.stdout" \
bash "${ROOT}/e2e/parity/trace-cli.sh" sandbox exec -- echo marker \
>"${WORKDIR}/trace-cli.forwarded.stdout" \
2>"${WORKDIR}/trace-cli.forwarded.stderr"
cmp -s "${WORKDIR}/trace-cli.stdout" "${WORKDIR}/trace-cli.forwarded.stdout" \
|| fail 'CLI trace wrapper did not preserve exact exec stdout'
assert_contains "${WORKDIR}/trace-cli.forwarded.stderr" 'trace fixture stderr'
HEAD_SHA="$(git -C "${ROOT}" rev-parse HEAD)"
cat >"${WORKDIR}/manifest.toml" <<EOF
manifest_version = 1
baseline_ref = "origin/main"
baseline_commit = "${HEAD_SHA}"
EOF
mkdir -p "${WORKDIR}/bin"
cat >"${WORKDIR}/bin/fake-wrapper" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
for variable in \
OPENSHELL_GATEWAY_ENDPOINT OPENSHELL_GATEWAY_CONFIG OPENSHELL_COMPUTE_DRIVER \
OPENSHELL_COMPUTE_DRIVER_SOCKET OPENSHELL_DRIVERS OPENSHELL_PODMAN_SOCKET \
CONTAINER_HOST CONTAINER_CONNECTION CONTAINERS_STORAGE_CONF CONTAINERS_CONF \
CONTAINERS_REGISTRIES_CONF CONTAINERS_REGISTRIES_CONF_DIR CONTAINERS_POLICY \
PODMAN_CONNECTIONS_CONF DOCKER_HOST OPENSHELL_SANDBOX_IMAGE \
OPENSHELL_SANDBOX_RUNTIME_IMAGE \
OPENSHELL_GRPC_ENDPOINT OPENSHELL_PODMAN_HOST_GATEWAY_IP OPENSHELL_PODMAN_USERNS \
OPENSHELL_PROVIDER_SPIFFE_WORKLOAD_API_SOCKET OPENSHELL_E2E_PROVIDER_SPIFFE_SOCKET \
OPENSHELL_APP_ARMOR_PROFILE OPENSHELL_SANDBOX_HTTPS_PROXY OPENSHELL_SANDBOX_NO_PROXY \
OPENSHELL_SANDBOX_PROXY_AUTH_FILE OPENSHELL_SANDBOX_PROXY_AUTH_ALLOW_INSECURE \
OPENSHELL_SANDBOX_PROXY_CONNECT_BY_HOSTNAME OPENSHELL_SANDBOX_PROXY_CA_BUNDLE \
OPENSHELL_OTLP_ENDPOINT OPENSHELL_GATEWAY_NAME OPENSHELL_COMPUTE_DRIVER_BIND; do
[ -z "${!variable:-}" ] || exit 23
done
expected_sandbox="nvcr.io/nvidia/base/ubuntu@sha256:$(printf '%064d' 0)"
[ "${OPENSHELL_E2E_REQUIRE_DIGEST_PINNED_SANDBOX_IMAGE:-0}" = 1 ] || exit 24
[ "${OPENSHELL_E2E_PODMAN_SANDBOX_IMAGE:-}" = "${expected_sandbox}" ] || exit 25
expected_base="docker.io/library/debian@sha256:$(printf '%064d' 0)"
[ "${OPENSHELL_E2E_SUPERVISOR_BASE_IMAGE:-}" = "${OPENSHELL_PARITY_TEST_SUPERVISOR_BASE}" ] || exit 26
[ "${OPENSHELL_E2E_SUPERVISOR_BASE_RUNTIME_IMAGE:-}" = "${expected_base}" ] || exit 27
printf '%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s\n' "$OPENSHELL_PARITY_VARIANT" "$OPENSHELL_E2E_CONFIG_SCHEMA_VERSION" "$OPENSHELL_GATEWAY_BIN" "$OPENSHELL_BIN" "$OPENSHELL_CONFORMANCE_BIN" "$MISE_TRUSTED_CONFIG_PATHS" "${OPENSHELL_E2E_PODMAN_OPTION_PROFILE:-}" "${OPENSHELL_PARITY_ORACLE_RESULT:-}" "${OPENSHELL_E2E_EXTERNAL_COMPUTE_DRIVER:-}" "${OPENSHELL_EXTERNAL_DRIVER_BIN:-}" "${OPENSHELL_E2E_SUPERVISOR_BIN:-}" >>"$OPENSHELL_PARITY_TEST_CALLS"
mkdir -p "$XDG_DATA_HOME/containers/storage"
printf 'fixture-package-1.0-r0\n' >"${OPENSHELL_PARITY_SUPERVISOR_PACKAGE_CAPTURE}"
package_hash="$(sha256sum "${OPENSHELL_PARITY_SUPERVISOR_PACKAGE_CAPTURE}" | cut -d' ' -f1)"
OPENSHELL_PARITY_FIXTURE_PACKAGE_HASH="${package_hash}" python3 - <<'PY'
import json
import os
from pathlib import Path
variant = os.environ["OPENSHELL_PARITY_VARIANT"]
schema = int(os.environ["OPENSHELL_E2E_CONFIG_SCHEMA_VERSION"])
external = os.environ.get("OPENSHELL_E2E_EXTERNAL_COMPUTE_DRIVER") == "1"
zero = "0" * 64
image_digest = f"sha256:{zero}"
sandbox_runtime = f"nvcr.io/nvidia/base/ubuntu@{image_digest}"
sandbox_boundary = "localhost/openshell/sandbox:dev"
supervisor_runtime = f"localhost/openshell/supervisor@{image_digest}"
base_runtime = f"docker.io/library/debian@{image_digest}"
pull_policy = "missing" if schema == 1 else "if_not_present"
gateway_port = 18181
grpc_endpoint = f"https://127.0.0.1:{gateway_port}"
driver_socket = f"/tmp/{variant}-driver.sock"
podman_socket = f"/tmp/{variant}-podman.sock"
network = f"{variant}-network"
selector = (
'compute_drivers = ["podman"]'
if schema == 1
else 'compute_driver = "podman"'
)
config_lines = [
"[openshell]",
f"version = {schema}",
"[openshell.gateway]",
selector,
"[openshell.drivers.podman]",
f'socket_path = "{driver_socket}"',
]
if not external:
config_lines.extend(
[
f'network_name = "{network}"',
f'default_image = "{sandbox_runtime}"',
f'image_pull_policy = "{pull_policy}"',
f'supervisor_image = "{supervisor_runtime}"',
]
)
Path(os.environ["OPENSHELL_PARITY_GATEWAY_CONFIG_CAPTURE"]).write_text(
"\n".join(config_lines) + "\n", encoding="utf-8"
)
launch = {
"schema_version": schema,
"gateway_port": gateway_port,
"external_compute_driver": external,
"compute_driver_transport": "remote_uds" if external else "in_tree",
"external_driver_pull_policy": pull_policy,
"supervisor_image": os.environ["OPENSHELL_SUPERVISOR_IMAGE"],
"supervisor_image_id": zero,
"supervisor_image_digest": image_digest,
"supervisor_runtime_image": supervisor_runtime,
"supervisor_base_image": os.environ["OPENSHELL_PARITY_TEST_SUPERVISOR_BASE"],
"supervisor_base_image_id": zero,
"supervisor_base_image_digest": image_digest,
"supervisor_base_runtime_image": base_runtime,
"supervisor_package_manifest_sha256": os.environ[
"OPENSHELL_PARITY_FIXTURE_PACKAGE_HASH"
],
"sandbox_image_request": sandbox_runtime,
"sandbox_image_id": zero,
"sandbox_image_digest": image_digest,
"sandbox_runtime_image": sandbox_runtime,
"sandbox_boundary_image": sandbox_boundary,
"sandbox_client_image_alias": "nvcr.io/nvidia/base/ubuntu:24.04",
"sandbox_client_image_alias_id": zero,
"gateway_sha256_before_execution": os.environ[
"OPENSHELL_E2E_EXPECTED_GATEWAY_SHA256"
],
"cli_sha256_before_execution": os.environ["OPENSHELL_E2E_EXPECTED_CLI_SHA256"],
"conformance_sha256_before_execution": os.environ[
"OPENSHELL_E2E_EXPECTED_CONFORMANCE_SHA256"
],
"external_driver_sha256_before_execution": os.environ.get(
"OPENSHELL_E2E_EXPECTED_EXTERNAL_DRIVER_SHA256", ""
),
"supervisor_sha256_before_execution": os.environ[
"OPENSHELL_E2E_EXPECTED_SUPERVISOR_SHA256"
],
"supervisor_dockerfile_sha256_before_execution": os.environ[
"OPENSHELL_E2E_EXPECTED_SUPERVISOR_DOCKERFILE_SHA256"
],
"cli_trace_wrapper_sha256_before_execution": os.environ[
"OPENSHELL_E2E_EXPECTED_CLI_TRACE_WRAPPER_SHA256"
],
}
if external:
launch.update(
{
"external_driver_grpc_endpoint": grpc_endpoint,
"external_driver_host_gateway_ip": "host-gateway",
"external_driver_userns": None,
"external_driver_spiffe": False,
"external_driver_proxy": False,
"external_driver_app_armor": False,
"external_driver_environment": {
"XDG_DATA_HOME": f"/tmp/{variant}-driver-data",
"OPENSHELL_COMPUTE_DRIVER_SOCKET": driver_socket,
"OPENSHELL_PODMAN_SOCKET": podman_socket,
"OPENSHELL_SANDBOX_IMAGE": sandbox_runtime,
"OPENSHELL_SANDBOX_IMAGE_PULL_POLICY": pull_policy,
"OPENSHELL_SANDBOX_RUNTIME_IMAGE": sandbox_boundary,
"OPENSHELL_HEALTH_CHECK_INTERVAL_SECS": 10,
"OPENSHELL_GRPC_ENDPOINT": grpc_endpoint,
"OPENSHELL_GATEWAY_PORT": gateway_port,
"OPENSHELL_NETWORK_NAME": network,
"OPENSHELL_STOP_TIMEOUT": 15,
"OPENSHELL_SUPERVISOR_IMAGE": supervisor_runtime,
"OPENSHELL_PODMAN_TLS_CA": {
"path": f"/tmp/{variant}-pki/ca.crt",
"sha256": "8" * 64,
},
"OPENSHELL_PODMAN_TLS_CERT": {
"path": f"/tmp/{variant}-pki/tls.crt",
"sha256": "9" * 64,
},
"OPENSHELL_PODMAN_TLS_KEY": {
"path": f"/tmp/{variant}-pki/tls.key",
"sha256": "a" * 64,
},
"OPENSHELL_ENABLE_BIND_MOUNTS": True,
},
}
)
if external and schema == 2:
del launch["external_driver_environment"]["OPENSHELL_PODMAN_TLS_CERT"]
del launch["external_driver_environment"]["OPENSHELL_PODMAN_TLS_KEY"]
Path(os.environ["OPENSHELL_PARITY_LAUNCH_MANIFEST_CAPTURE"]).write_text(
json.dumps(launch, separators=(",", ":")) + "\n", encoding="utf-8"
)
PY
run_id="fixture${OPENSHELL_PARITY_VARIANT}"
printf 'openshell-conformance-%s\n' "${run_id}" >"${OPENSHELL_PARITY_EXEC_STDOUT_CAPTURE}"
printf 'CLI conformance run ID: %s\n' "${run_id}" >&2
printf 'gateway preflight connected: gateway=fixture, authentication=authenticated\n' >&2
for marker in status create get-ready list-visible/0 exec delete list-empty/query/0; do
printf '[run %s][smoke/%s] completed in 1ms: exit 0\n' "${run_id}" "${marker}" >&2
done
printf '%s %064d sha256:%064d %s %s %s %s\n' \
"${expected_sandbox}" 0 0 "${expected_base}" \
"localhost/openshell/supervisor@sha256:$(printf '%064d' 0)" \
"nvcr.io/nvidia/base/ubuntu:24.04" \
"${package_hash}" >&2
if [ "${OPENSHELL_E2E_EXTERNAL_COMPUTE_DRIVER:-0}" = 1 ]; then
printf 'fixture external driver log\n' >"${OPENSHELL_PARITY_EXTERNAL_DRIVER_LOG_CAPTURE}"
fi
if [ "${OPENSHELL_PARITY_TEST_MUTATE_ARTIFACT:-}" = "${OPENSHELL_PARITY_VARIANT}" ]; then
replacement="${OPENSHELL_GATEWAY_BIN}.replacement"
printf '#!/usr/bin/env bash\nexit 0\n# mutated\n' >"${replacement}"
chmod 0555 "${replacement}"
mv -f "${replacement}" "${OPENSHELL_GATEWAY_BIN}"
fi
if [ "${OPENSHELL_E2E_PODMAN_OPTION_PROFILE:-}" = podman-options ]; then
case "${OPENSHELL_PARITY_VARIANT}" in baseline) pids=2048 ;; candidate) pids=31 ;; esac
stable=true
if [ "${OPENSHELL_PARITY_TEST_SEMANTIC_DRIFT:-0}" = 1 ] && [ "${OPENSHELL_PARITY_VARIANT}" = candidate ]; then stable=false; fi
if [ "${OPENSHELL_PARITY_TEST_SKIP_RESULT:-}" != "${OPENSHELL_PARITY_VARIANT}" ]; then
printf '%s\n' "{\"scenario\":\"podman-options\",\"stable\":${stable},\"pids_limit\":${pids}}" > "${OPENSHELL_PARITY_ORACLE_RESULT}"
fi
fi
exec "$@"
EOF
cat >"${WORKDIR}/bin/fake-podman" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' "$*" >>"$OPENSHELL_PARITY_TEST_PODMAN_CALLS"
case "$1" in
pull) exit 0 ;;
image)
[ "$2" = inspect ] || exit 19
case "$4" in
'{{.Id}}') printf 'sha256:%064d\n' 0 ;;
'{{.Digest}}') printf 'sha256:%064d\n' 0 ;;
'{{index .RepoDigests 0}}') printf 'docker.io/library/debian@sha256:%064d\n' 0 ;;
*) exit 19 ;;
esac
;;
unshare)
shift
exec "$@"
;;
*) exit 19 ;;
esac
EOF
cat >"${WORKDIR}/bin/fake-conformance" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
if [ "${OPENSHELL_PARITY_FAIL_VARIANT:-}" = "${OPENSHELL_PARITY_VARIANT:-}" ] || [ "${OPENSHELL_PARITY_FAIL_VARIANT:-}" = both ]; then
exit 17
fi
if [ "${OPENSHELL_PARITY_TEST_INVALID_REPORT:-0}" = 1 ]; then
# Prove the verifier parses retained stdout instead of accepting a success
# substring injected into unrelated raw stderr.
printf '%s\n' '"passed": true' >&2
printf '%s\n' '{"scenarios":[{"name":"smoke","passed":false,"diagnostic":"fixture failure"}],"passed":false}'
else
printf '%s\n' '{'
printf '%s\n' ' "scenarios": [{"name":"smoke","passed":true,"diagnostic":null}],'
printf '%s\n' ' "passed": true'
printf '%s\n' '}'
fi
EOF
for artifact in baseline-gateway baseline-cli candidate-gateway candidate-cli baseline-driver candidate-driver baseline-supervisor candidate-supervisor; do
printf '#!/usr/bin/env bash\n# %s\nexit 0\n' "${artifact}" >"${WORKDIR}/bin/${artifact}"
done
chmod +x "${WORKDIR}/bin/"*
# shellcheck source=e2e/support/podman-gateway-config.sh
source "${ROOT}/e2e/support/podman-gateway-config.sh"
[ "$(e2e_podman_external_driver_pull_policy 1)" = missing ] || fail 'schema v1 external pull policy mismatch'
[ "$(e2e_podman_external_driver_pull_policy 2)" = if_not_present ] || fail 'schema v2 external pull policy mismatch'
run_harness() {
if [ "${OPENSHELL_PARITY_TEST_KEEP_RESULTS_DIR:-0}" != 1 ]; then
rm -rf -- "${WORKDIR}/results"
fi
OPENSHELL_PARITY_TEST_SUPERVISOR_BASE="${TEST_SUPERVISOR_BASE}" \
OPENSHELL_PARITY_CAPABILITY_MANIFEST="${WORKDIR}/manifest.toml" \
OPENSHELL_PARITY_BASELINE_WORKTREE="${ROOT}" \
OPENSHELL_PARITY_PODMAN_WRAPPER="${WORKDIR}/bin/fake-wrapper" \
OPENSHELL_PARITY_PODMAN_BIN="${WORKDIR}/bin/fake-podman" \
OPENSHELL_PARITY_PODMAN_OPTIONS_ORACLE="${WORKDIR}/bin/fake-conformance" \
OPENSHELL_PARITY_BASELINE_GATEWAY_BIN="${WORKDIR}/bin/baseline-gateway" \
OPENSHELL_PARITY_BASELINE_CLI_BIN="${WORKDIR}/bin/baseline-cli" \
OPENSHELL_PARITY_BASELINE_CONFORMANCE_BIN="${WORKDIR}/bin/fake-conformance" \
OPENSHELL_PARITY_CANDIDATE_GATEWAY_BIN="${WORKDIR}/bin/candidate-gateway" \
OPENSHELL_PARITY_CANDIDATE_CLI_BIN="${WORKDIR}/bin/candidate-cli" \
OPENSHELL_PARITY_CANDIDATE_CONFORMANCE_BIN="${WORKDIR}/bin/fake-conformance" \
OPENSHELL_PARITY_BASELINE_EXTERNAL_DRIVER_BIN="${WORKDIR}/bin/baseline-driver" \
OPENSHELL_PARITY_CANDIDATE_EXTERNAL_DRIVER_BIN="${OPENSHELL_PARITY_TEST_CANDIDATE_DRIVER_OVERRIDE:-${WORKDIR}/bin/candidate-driver}" \
OPENSHELL_PARITY_BASELINE_SUPERVISOR_BIN="${WORKDIR}/bin/baseline-supervisor" \
OPENSHELL_PARITY_CANDIDATE_SUPERVISOR_BIN="${WORKDIR}/bin/candidate-supervisor" \
OPENSHELL_PARITY_RESULTS_DIR="${WORKDIR}/results" \
OPENSHELL_PARITY_TEST_CALLS="${WORKDIR}/calls" \
OPENSHELL_PARITY_TEST_PODMAN_CALLS="${WORKDIR}/podman-calls" \
MISE_TRUSTED_CONFIG_PATHS= \
bash "${ROOT}/e2e/parity/run.sh" --driver podman "$@"
}
OPENSHELL_GATEWAY_ENDPOINT=http://127.0.0.1:9 \
OPENSHELL_GATEWAY_CONFIG=/tmp/untrusted.toml \
OPENSHELL_COMPUTE_DRIVER=wrong \
OPENSHELL_COMPUTE_DRIVER_SOCKET=/tmp/untrusted.sock \
OPENSHELL_DRIVERS=wrong \
OPENSHELL_PODMAN_SOCKET=/tmp/untrusted-podman.sock \
CONTAINER_HOST=tcp://untrusted.invalid:9999 \
CONTAINER_CONNECTION=untrusted \
CONTAINERS_STORAGE_CONF=/tmp/untrusted-storage.conf \
CONTAINERS_CONF=/tmp/untrusted-containers.conf \
CONTAINERS_REGISTRIES_CONF=/tmp/untrusted-registries.conf \
CONTAINERS_REGISTRIES_CONF_DIR=/tmp/untrusted-registries.d \
CONTAINERS_POLICY=/tmp/untrusted-policy.json \
PODMAN_CONNECTIONS_CONF=/tmp/untrusted-connections.json \
DOCKER_HOST=tcp://untrusted.invalid:2375 \
OPENSHELL_SANDBOX_IMAGE=untrusted.invalid/sandbox:latest \
OPENSHELL_SANDBOX_RUNTIME_IMAGE=untrusted.invalid/runtime:latest \
OPENSHELL_GRPC_ENDPOINT=http://untrusted.invalid:1 \
OPENSHELL_PODMAN_HOST_GATEWAY_IP=192.0.2.1 \
OPENSHELL_PODMAN_USERNS=keep-id \
OPENSHELL_PROVIDER_SPIFFE_WORKLOAD_API_SOCKET=/tmp/untrusted-spiffe.sock \
OPENSHELL_E2E_PROVIDER_SPIFFE_SOCKET=/tmp/untrusted-e2e-spiffe.sock \
OPENSHELL_APP_ARMOR_PROFILE=Unconfined \
OPENSHELL_SANDBOX_HTTPS_PROXY=http://untrusted.invalid:8080 \
OPENSHELL_SANDBOX_NO_PROXY=untrusted.invalid \
OPENSHELL_SANDBOX_PROXY_AUTH_FILE=/tmp/untrusted-proxy-auth \
OPENSHELL_SANDBOX_PROXY_AUTH_ALLOW_INSECURE=true \
OPENSHELL_SANDBOX_PROXY_CONNECT_BY_HOSTNAME=true \
OPENSHELL_SANDBOX_PROXY_CA_BUNDLE=/tmp/untrusted-proxy-ca \
OPENSHELL_OTLP_ENDPOINT=http://untrusted.invalid:4317 \
OPENSHELL_GATEWAY_NAME=untrusted \
OPENSHELL_COMPUTE_DRIVER_BIND=192.0.2.2:50061 \
run_harness
assert_contains "${WORKDIR}/calls" "baseline|1|${WORKDIR}/results/artifacts/baseline/gateway|${WORKDIR}/results/artifacts/baseline/cli|${WORKDIR}/results/artifacts/baseline/conformance"
assert_contains "${WORKDIR}/calls" "candidate|2|${WORKDIR}/results/artifacts/candidate/gateway|${WORKDIR}/results/artifacts/candidate/cli|${WORKDIR}/results/artifacts/candidate/conformance"
assert_contains "${WORKDIR}/calls" "|${ROOT}"
[ "$(sed -n '1s/|.*//p' "${WORKDIR}/calls")" = baseline ] || fail 'baseline was not invoked first'
[ "$(sed -n '2s/|.*//p' "${WORKDIR}/calls")" = candidate ] || fail 'candidate was not invoked second'
assert_contains "${WORKDIR}/results/baseline.json" "\"source_sha\":\"${HEAD_SHA}\""
assert_contains "${WORKDIR}/results/baseline.json" '"schema_version":1'
assert_contains "${WORKDIR}/results/candidate.json" '"schema_version":2'
assert_contains "${WORKDIR}/results/candidate.json" "\"source_sha\":\"${HEAD_SHA}\""
assert_contains "${WORKDIR}/results/candidate.json" '"success":true'
assert_contains "${WORKDIR}/results/comparison.json" '"parity":true'
assert_contains "${WORKDIR}/results/semantic-verification.json" '"accepted": true'
assert_not_contains "${WORKDIR}/results/baseline.json" '"scenarios"'
assert_contains "${WORKDIR}/results/baseline.log" '"scenarios"'
assert_contains "${WORKDIR}/results/baseline.conformance.json" '"passed":true'
assert_contains "${WORKDIR}/podman-calls" 'pull nvcr.io/nvidia/base/ubuntu:24.04'
assert_contains "${WORKDIR}/podman-calls" "pull ${TEST_SUPERVISOR_BASE}"
assert_contains "${WORKDIR}/podman-calls" 'unshare rm -rf -- '
assert_contains "${WORKDIR}/podman-calls" 'openshell-parity-run.'
set +e
OPENSHELL_PARITY_TEST_INVALID_REPORT=1 run_harness >"${WORKDIR}/invalid-report.out" 2>&1
status=$?
set -e
assert_status "${status}" 1
assert_contains "${WORKDIR}/invalid-report.out" 'conformance report did not pass'
assert_contains "${WORKDIR}/invalid-report.out" 'semantic verification failed for smoke'
assert_contains "${WORKDIR}/results/comparison.json" '"classification":"regression"'
assert_contains "${WORKDIR}/results/comparison.json" '"accepted":false'
set +e
OPENSHELL_E2E_PODMAN_SANDBOX_IMAGE=untrusted.invalid/sandbox:latest \
run_harness >"${WORKDIR}/mutable-sandbox.out" 2>&1
status=$?
set -e
assert_status "${status}" 2
assert_contains "${WORKDIR}/mutable-sandbox.out" 'must be digest-pinned for parity runs'
run_harness --scenario external-driver
assert_contains "${WORKDIR}/calls" "|1|${WORKDIR}/results/artifacts/baseline/external-driver|${WORKDIR}/results/artifacts/baseline/supervisor"
assert_contains "${WORKDIR}/calls" "|1|${WORKDIR}/results/artifacts/candidate/external-driver|${WORKDIR}/results/artifacts/candidate/supervisor"
assert_contains "${WORKDIR}/results/baseline.json" '"scenario":"external-driver"'
assert_contains "${WORKDIR}/results/baseline.json" '"command_class":"external_driver_conformance_smoke"'
assert_contains "${WORKDIR}/results/baseline.json" '"gateway_profile":"driver-free"'
assert_contains "${WORKDIR}/results/baseline.json" '"gateway_cargo_features":"--no-default-features --features telemetry"'
assert_contains "${WORKDIR}/results/baseline.json" '"gateway_origin":"supplied_override"'
assert_contains "${WORKDIR}/results/baseline.json" '"external_driver_origin":"supplied_override"'
assert_contains "${WORKDIR}/results/baseline.launch.json" '"compute_driver_transport":"remote_uds"'
assert_contains "${WORKDIR}/results/baseline.launch.json" '"external_driver_pull_policy":"missing"'
assert_contains "${WORKDIR}/results/baseline.launch.json" '"supervisor_image_digest":"sha256:'
assert_contains "${WORKDIR}/results/baseline.launch.json" '"supervisor_runtime_image":"localhost/openshell/supervisor@sha256:'
assert_contains "${WORKDIR}/results/candidate.launch.json" '"external_driver_pull_policy":"if_not_present"'
assert_contains "${WORKDIR}/results/baseline.json" '"gateway_sha256"'
assert_contains "${WORKDIR}/results/baseline.json" '"cli_sha256"'
assert_contains "${WORKDIR}/results/baseline.json" '"conformance_sha256"'
assert_contains "${WORKDIR}/results/baseline.json" '"supervisor_origin":"supplied_override"'
assert_contains "${WORKDIR}/results/baseline.json" '"supervisor_sha256"'
assert_contains "${WORKDIR}/results/baseline.json" '"supervisor_dockerfile_sha256"'
assert_contains "${WORKDIR}/results/baseline.json" '"external_driver_sha256"'
assert_contains "${WORKDIR}/results/comparison.json" '"classification":"pass"'
assert_contains "${WORKDIR}/results/semantic-verification.json" '"scenario": "external-driver"'
set +e
OPENSHELL_PARITY_TEST_CANDIDATE_DRIVER_OVERRIDE="${WORKDIR}/bin/baseline-driver" \
run_harness --scenario external-driver >"${WORKDIR}/same-driver.out" 2>&1
status=$?
set -e
assert_status "${status}" 2
assert_contains "${WORKDIR}/same-driver.out" 'requires distinct baseline and candidate driver artifacts'
cp "${WORKDIR}/bin/baseline-driver" "${WORKDIR}/bin/same-content-driver"
set +e
OPENSHELL_PARITY_TEST_CANDIDATE_DRIVER_OVERRIDE="${WORKDIR}/bin/same-content-driver" \
run_harness --scenario external-driver >"${WORKDIR}/same-driver-content.out" 2>&1
status=$?
set -e
assert_status "${status}" 2
assert_contains "${WORKDIR}/same-driver-content.out" 'requires different baseline and candidate driver content'
run_harness --scenario podman-options
assert_contains "${WORKDIR}/calls" "baseline|1|${WORKDIR}/results/artifacts/baseline/gateway|${WORKDIR}/results/artifacts/baseline/cli|${WORKDIR}/results/artifacts/baseline/conformance|${ROOT}|podman-options"
assert_contains "${WORKDIR}/calls" "candidate|2|${WORKDIR}/results/artifacts/candidate/gateway|${WORKDIR}/results/artifacts/candidate/cli|${WORKDIR}/results/artifacts/candidate/conformance|${ROOT}|podman-options"
assert_contains "${WORKDIR}/results/baseline.json" '"scenario":"podman-options"'
assert_contains "${WORKDIR}/results/baseline.json" '"command_class":"podman_options"'
assert_contains "${WORKDIR}/results/baseline.json" '"normalized_result":"baseline.normalized.json"'
assert_contains "${WORKDIR}/results/baseline.normalized.json" '"stable":true'
assert_contains "${WORKDIR}/results/baseline.normalized.json" '"pids_limit":2048'
assert_contains "${WORKDIR}/results/candidate.normalized.json" '"pids_limit":31'
assert_not_contains "${WORKDIR}/results/baseline.json" '"scenarios"'
assert_contains "${WORKDIR}/results/baseline.log" '"scenarios"'
assert_not_contains "${WORKDIR}/results/baseline.json" 'raw output'
assert_contains "${WORKDIR}/results/comparison.json" '"scenario":"podman-options"'
assert_contains "${WORKDIR}/results/comparison.json" '"parity":false'
assert_contains "${WORKDIR}/results/comparison.json" '"classification":"intentional_change"'
assert_contains "${WORKDIR}/results/comparison.json" '"intentional_change_id":"podman-pid-limit-restored"'
assert_contains "${WORKDIR}/results/comparison.json" '"accepted":true'
set +e
OPENSHELL_PARITY_TEST_SEMANTIC_DRIFT=1 run_harness --scenario podman-options >"${WORKDIR}/drift.out" 2>&1
status=$?
set -e
assert_status "${status}" 1
assert_contains "${WORKDIR}/results/comparison.json" '"classification":"regression"'
assert_contains "${WORKDIR}/results/comparison.json" '"accepted":false'
# Refuse an existing output path instead of consuming stale evidence from it.
[ -s "${WORKDIR}/results/candidate.normalized.json" ] || fail 'stale result fixture is missing'
set +e
OPENSHELL_PARITY_TEST_KEEP_RESULTS_DIR=1 run_harness --scenario podman-options >"${WORKDIR}/stale-results.out" 2>&1
status=$?
set -e
assert_status "${status}" 2
assert_contains "${WORKDIR}/stale-results.out" 'parity results directory already exists'
# A fresh run whose wrapper emits no candidate result must fail.
set +e
OPENSHELL_PARITY_TEST_SKIP_RESULT=candidate run_harness --scenario podman-options >"${WORKDIR}/missing-result.out" 2>&1
status=$?
set -e
assert_status "${status}" 1
assert_contains "${WORKDIR}/results/comparison.json" '"classification":"regression"'
assert_contains "${WORKDIR}/results/comparison.json" '"accepted":false'
set +e
OPENSHELL_PARITY_FAIL_VARIANT=both run_harness >"${WORKDIR}/failure.out" 2>&1
status=$?
set -e
assert_status "${status}" 1
assert_contains "${WORKDIR}/results/baseline.json" '"success":false'
assert_contains "${WORKDIR}/results/candidate.json" '"success":false'
assert_contains "${WORKDIR}/results/comparison.json" '"parity":false'
[ "$(wc -l <"${WORKDIR}/calls")" -eq 14 ] || fail 'candidate did not run after baseline failure'
set +e
OPENSHELL_PARITY_TEST_MUTATE_ARTIFACT=candidate run_harness >"${WORKDIR}/mutation.out" 2>&1
status=$?
set -e
assert_status "${status}" 1
assert_contains "${WORKDIR}/mutation.out" 'candidate gateway changed after it was staged for execution'
assert_contains "${WORKDIR}/results/candidate.json" '"success":false'
assert_contains "${WORKDIR}/results/comparison.json" '"classification":"regression"'
set +e
bash "${ROOT}/e2e/parity/run.sh" --driver docker >"${WORKDIR}/driver.out" 2>&1
status=$?
set -e
assert_status "${status}" 2
assert_contains "${WORKDIR}/driver.out" 'only --driver podman is supported'
set +e
bash "${ROOT}/e2e/parity/run.sh" --driver >"${WORKDIR}/option.out" 2>&1
status=$?
set -e
assert_status "${status}" 2
assert_contains "${WORKDIR}/option.out" '--driver requires a value'
echo 'e2e parity deterministic tests passed.'
-31
View File
@@ -1,31 +0,0 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Transparently invoke the staged OpenShell CLI while retaining the exact
# stdout bytes produced by the conformance exec probe.
set -uo pipefail
: "${OPENSHELL_PARITY_REAL_CLI:?OPENSHELL_PARITY_REAL_CLI is required}"
: "${OPENSHELL_PARITY_EXEC_STDOUT_CAPTURE:?OPENSHELL_PARITY_EXEC_STDOUT_CAPTURE is required}"
tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/openshell-parity-cli.XXXXXX")"
cleanup() {
rm -rf "${tmpdir}"
}
trap cleanup EXIT
set +e
"${OPENSHELL_PARITY_REAL_CLI}" "$@" >"${tmpdir}/stdout" 2>"${tmpdir}/stderr"
status=$?
set -e
cat "${tmpdir}/stdout"
cat "${tmpdir}/stderr" >&2
if [ "${1:-}" = sandbox ] && [ "${2:-}" = exec ]; then
install -m 0444 "${tmpdir}/stdout" "${OPENSHELL_PARITY_EXEC_STDOUT_CAPTURE}"
fi
exit "${status}"
-37
View File
@@ -1,37 +0,0 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Retain the conformance runner's stdout as one parseable JSON document while
# forwarding it unchanged to the parity run log. Stderr remains live so
# lifecycle diagnostics and the run ID continue to appear in the raw evidence.
set -euo pipefail
REAL_CONFORMANCE="${OPENSHELL_PARITY_REAL_CONFORMANCE:?OPENSHELL_PARITY_REAL_CONFORMANCE is required}"
CAPTURE="${OPENSHELL_PARITY_CONFORMANCE_REPORT_CAPTURE:?OPENSHELL_PARITY_CONFORMANCE_REPORT_CAPTURE is required}"
if [ ! -x "${REAL_CONFORMANCE}" ]; then
echo "ERROR: real conformance binary is not executable: ${REAL_CONFORMANCE}" >&2
exit 2
fi
mkdir -p "$(dirname "${CAPTURE}")"
temporary="$(mktemp "${CAPTURE}.tmp.XXXXXX")"
cleanup() {
rm -f -- "${temporary}"
}
trap cleanup EXIT
set +e
"${REAL_CONFORMANCE}" "$@" | tee "${temporary}"
statuses=("${PIPESTATUS[@]}")
set -e
status=${statuses[0]}
if [ "${statuses[1]}" -ne 0 ]; then
echo "ERROR: could not retain conformance stdout: ${CAPTURE}" >&2
status=${statuses[1]}
else
mv -f -- "${temporary}" "${CAPTURE}"
fi
exit "${status}"
-839
View File
@@ -1,839 +0,0 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Verify retained parity evidence and emit its normalized comparison."""
from __future__ import annotations
import argparse
import hashlib
import json
import re
import tomllib
from pathlib import Path
from typing import Any
SHA256_RE = re.compile(r"^[0-9a-f]{64}$")
DIGEST_REFERENCE_RE = re.compile(r"^[^@]+@sha256:([0-9a-f]{64})$")
ARTIFACT_FIELDS = {
"gateway_sha256": "gateway",
"cli_sha256": "cli",
"conformance_sha256": "conformance",
"supervisor_sha256": "supervisor",
"supervisor_dockerfile_sha256": "supervisor.Dockerfile",
"cli_trace_wrapper_sha256": "cli-trace-wrapper",
}
ORACLE_MARKERS = (
"][smoke/status] completed",
"][smoke/create] completed",
"][smoke/get-ready] completed",
"][smoke/list-visible/0] completed",
"][smoke/exec] completed",
"][smoke/delete] completed",
"][smoke/list-empty/query/0] completed",
)
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as source:
for chunk in iter(lambda: source.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def load_json(path: Path) -> dict[str, Any]:
with path.open(encoding="utf-8") as source:
value = json.load(source)
if not isinstance(value, dict):
raise ValueError(f"{path}: expected a JSON object")
return value
def require(condition: bool, message: str) -> None:
if not condition:
raise ValueError(message)
def image_repository(reference: str) -> str:
"""Return an OCI image repository without a tag or digest."""
repository = reference.split("@", 1)[0]
last_slash = repository.rfind("/")
last_colon = repository.rfind(":")
if last_colon > last_slash:
repository = repository[:last_colon]
return repository
def verify_conformance_report(path: Path) -> None:
report = load_json(path)
require(report.get("passed") is True, f"{path}: conformance report did not pass")
scenarios = report.get("scenarios")
require(
isinstance(scenarios, list) and len(scenarios) == 1,
f"{path}: expected exactly one conformance scenario",
)
scenario = scenarios[0]
require(isinstance(scenario, dict), f"{path}: invalid conformance scenario")
require(scenario.get("name") == "smoke", f"{path}: smoke scenario is missing")
require(scenario.get("passed") is True, f"{path}: smoke scenario did not pass")
require(
scenario.get("diagnostic") is None,
f"{path}: successful smoke scenario retained a diagnostic",
)
def verify_variant(
results_dir: Path,
variant: str,
expected_sha: str,
schema_version: int,
scenario: str,
*,
require_built_artifacts: bool = True,
require_conformance_report: bool = False,
) -> dict[str, Any]:
result_path = results_dir / f"{variant}.json"
launch_path = results_dir / f"{variant}.launch.json"
log_path = results_dir / f"{variant}.log"
config_path = results_dir / f"{variant}.gateway.toml"
result = load_json(result_path)
launch = load_json(launch_path)
require(config_path.is_file(), f"{config_path}: retained gateway config is missing")
with config_path.open("rb") as config_file:
config = tomllib.load(config_file)
require(result.get("variant") == variant, f"{result_path}: variant mismatch")
require(
result.get("source_sha") == expected_sha, f"{result_path}: source SHA mismatch"
)
require(
result.get("schema_version") == schema_version,
f"{result_path}: schema mismatch",
)
require(result.get("scenario") == scenario, f"{result_path}: scenario mismatch")
require(result.get("driver") == "podman", f"{result_path}: driver mismatch")
expected_profile = "driver-free" if scenario == "external-driver" else "in-tree"
expected_features = (
"--no-default-features --features telemetry"
if scenario == "external-driver"
else "default"
)
require(
result.get("gateway_profile") == expected_profile,
f"{result_path}: gateway profile mismatch",
)
require(
result.get("gateway_cargo_features") == expected_features,
f"{result_path}: gateway feature profile mismatch",
)
require(result.get("success") is True, f"{result_path}: parity oracle did not pass")
accepted_origins = (
{"built_by_harness"}
if require_built_artifacts
else {"built_by_harness", "supplied_override"}
)
for field, label in (
("gateway_origin", "gateway"),
("cli_origin", "CLI"),
("conformance_origin", "conformance runner"),
("supervisor_origin", "supervisor"),
):
require(
result.get(field) in accepted_origins,
f"{result_path}: invalid {label} artifact origin",
)
external = scenario == "external-driver"
if external:
require(
result.get("external_driver_origin") in accepted_origins,
f"{result_path}: invalid external driver artifact origin",
)
else:
require(
result.get("external_driver_origin") == "not_applicable",
f"{result_path}: external driver origin mismatch",
)
require(
launch.get("schema_version") == schema_version,
f"{launch_path}: schema mismatch",
)
require(
launch.get("external_compute_driver") is external,
f"{launch_path}: topology mismatch",
)
expected_transport = "remote_uds" if external else "in_tree"
require(
launch.get("compute_driver_transport") == expected_transport,
f"{launch_path}: transport mismatch",
)
expected_policy = "missing" if schema_version == 1 else "if_not_present"
require(
launch.get("external_driver_pull_policy") == expected_policy,
f"{launch_path}: pull-policy mismatch",
)
openshell = config.get("openshell", {})
gateway = openshell.get("gateway", {})
podman_config = openshell.get("drivers", {}).get("podman", {})
require(
openshell.get("version") == schema_version, f"{config_path}: schema mismatch"
)
expected_selector = ["podman"] if schema_version == 1 else "podman"
selector_field = "compute_drivers" if schema_version == 1 else "compute_driver"
require(
gateway.get(selector_field) == expected_selector,
f"{config_path}: selected compute driver mismatch",
)
require(isinstance(podman_config, dict), f"{config_path}: Podman table is missing")
if external:
require(
set(podman_config) == {"socket_path"},
f"{config_path}: external gateway Podman table is not transport-only",
)
require(
isinstance(podman_config["socket_path"], str)
and Path(podman_config["socket_path"]).is_absolute(),
f"{config_path}: external driver socket path is not absolute",
)
else:
required_runtime_fields = {
"socket_path",
"network_name",
"default_image",
"image_pull_policy",
"supervisor_image",
}
require(
set(podman_config) >= required_runtime_fields,
f"{config_path}: in-tree Podman runtime fields are incomplete",
)
require(
DIGEST_REFERENCE_RE.fullmatch(podman_config["default_image"]) is not None,
f"{config_path}: sandbox image is not digest-pinned",
)
require(
DIGEST_REFERENCE_RE.fullmatch(podman_config["supervisor_image"])
is not None,
f"{config_path}: supervisor image is not digest-pinned",
)
artifact_fields = dict(ARTIFACT_FIELDS)
if external:
artifact_fields["external_driver_sha256"] = "external-driver"
artifact_hashes: dict[str, str] = {}
for field, filename in artifact_fields.items():
expected_hash = result.get(field)
require(
isinstance(expected_hash, str)
and SHA256_RE.fullmatch(expected_hash) is not None,
f"{result_path}: invalid {field}",
)
artifact_path = results_dir / "artifacts" / variant / filename
require(
artifact_path.is_file(), f"{artifact_path}: retained artifact is missing"
)
actual_hash = sha256(artifact_path)
require(
actual_hash == expected_hash,
f"{artifact_path}: retained artifact hash mismatch",
)
artifact_hashes[filename] = actual_hash
image_id = launch.get("supervisor_image_id")
image_digest = launch.get("supervisor_image_digest")
runtime_image = launch.get("supervisor_runtime_image")
require(
isinstance(image_id, str) and SHA256_RE.fullmatch(image_id) is not None,
f"{launch_path}: invalid supervisor image ID",
)
require(
isinstance(image_digest, str)
and re.fullmatch(r"sha256:[0-9a-f]{64}", image_digest) is not None,
f"{launch_path}: invalid supervisor image digest",
)
match = (
DIGEST_REFERENCE_RE.fullmatch(runtime_image)
if isinstance(runtime_image, str)
else None
)
require(
match is not None,
f"{launch_path}: supervisor runtime image is not digest-pinned",
)
require(
f"sha256:{match.group(1)}" == image_digest,
f"{launch_path}: runtime reference digest mismatch",
)
sandbox_request = launch.get("sandbox_image_request")
sandbox_id = launch.get("sandbox_image_id")
sandbox_digest = launch.get("sandbox_image_digest")
sandbox_runtime = launch.get("sandbox_runtime_image")
sandbox_boundary_image = launch.get("sandbox_boundary_image")
sandbox_match = (
DIGEST_REFERENCE_RE.fullmatch(sandbox_runtime)
if isinstance(sandbox_runtime, str)
else None
)
require(
isinstance(sandbox_id, str) and SHA256_RE.fullmatch(sandbox_id) is not None,
f"{launch_path}: invalid sandbox image ID",
)
require(
isinstance(sandbox_digest, str)
and re.fullmatch(r"sha256:[0-9a-f]{64}", sandbox_digest) is not None,
f"{launch_path}: invalid sandbox image digest",
)
require(
sandbox_match is not None
and f"sha256:{sandbox_match.group(1)}" == sandbox_digest,
f"{launch_path}: sandbox runtime image is not digest-pinned",
)
require(
sandbox_request == sandbox_runtime,
f"{launch_path}: sandbox image request was not the resolved digest reference",
)
require(
isinstance(sandbox_boundary_image, str) and sandbox_boundary_image,
f"{launch_path}: sandbox boundary image is missing",
)
if not external:
require(
podman_config["default_image"] == sandbox_runtime
and podman_config["supervisor_image"] == runtime_image,
f"{config_path}: runtime image references differ from launch evidence",
)
base_runtime = launch.get("supervisor_base_runtime_image")
base_runtime_match = (
DIGEST_REFERENCE_RE.fullmatch(base_runtime)
if isinstance(base_runtime, str)
else None
)
require(
base_runtime_match is not None,
f"{launch_path}: supervisor base runtime image is not digest-pinned",
)
for field in ("supervisor_base_image_id", "supervisor_package_manifest_sha256"):
value = launch.get(field)
require(
isinstance(value, str) and SHA256_RE.fullmatch(value) is not None,
f"{launch_path}: invalid {field}",
)
base_digest = launch.get("supervisor_base_image_digest")
require(
isinstance(base_digest, str)
and re.fullmatch(r"sha256:[0-9a-f]{64}", base_digest) is not None,
f"{launch_path}: invalid supervisor base-image digest",
)
package_path = results_dir / "artifacts" / variant / "supervisor.packages.txt"
require(package_path.is_file(), f"{package_path}: package manifest is missing")
require(
sha256(package_path) == launch["supervisor_package_manifest_sha256"],
f"{package_path}: package manifest hash mismatch",
)
artifact_hashes["supervisor.packages.txt"] = sha256(package_path)
sandbox_alias = launch.get("sandbox_client_image_alias")
require(
isinstance(sandbox_alias, str)
and "@" not in sandbox_alias
and image_repository(sandbox_alias) == image_repository(sandbox_runtime)
and launch.get("sandbox_client_image_alias_id") == sandbox_id,
f"{launch_path}: sandbox client alias is not bound to the pinned image",
)
for launch_field, result_field in (
("gateway_sha256_before_execution", "gateway_sha256"),
("cli_sha256_before_execution", "cli_sha256"),
("conformance_sha256_before_execution", "conformance_sha256"),
("supervisor_sha256_before_execution", "supervisor_sha256"),
(
"supervisor_dockerfile_sha256_before_execution",
"supervisor_dockerfile_sha256",
),
("cli_trace_wrapper_sha256_before_execution", "cli_trace_wrapper_sha256"),
):
require(
launch.get(launch_field) == result.get(result_field),
f"{launch_path}: {launch_field} does not bind the staged artifact",
)
if external:
require(
launch.get("external_driver_sha256_before_execution")
== result.get("external_driver_sha256"),
f"{launch_path}: external driver pre-execution hash mismatch",
)
gateway_port = launch.get("gateway_port")
grpc_endpoint = f"https://127.0.0.1:{gateway_port}"
require(
isinstance(gateway_port, int)
and 0 < gateway_port <= 65535
and launch.get("external_driver_grpc_endpoint") == grpc_endpoint,
f"{launch_path}: external driver gRPC endpoint is not isolated",
)
require(
launch.get("external_driver_host_gateway_ip") == "host-gateway"
and launch.get("external_driver_userns") is None
and launch.get("external_driver_spiffe") is False
and launch.get("external_driver_proxy") is False
and launch.get("external_driver_app_armor") is False,
f"{launch_path}: external driver effective configuration is tainted",
)
driver_environment = launch.get("external_driver_environment")
expected_environment_keys = {
"XDG_DATA_HOME",
"OPENSHELL_COMPUTE_DRIVER_SOCKET",
"OPENSHELL_PODMAN_SOCKET",
"OPENSHELL_SANDBOX_IMAGE",
"OPENSHELL_SANDBOX_IMAGE_PULL_POLICY",
"OPENSHELL_HEALTH_CHECK_INTERVAL_SECS",
"OPENSHELL_GRPC_ENDPOINT",
"OPENSHELL_GATEWAY_PORT",
"OPENSHELL_NETWORK_NAME",
"OPENSHELL_STOP_TIMEOUT",
"OPENSHELL_SANDBOX_RUNTIME_IMAGE",
"OPENSHELL_SUPERVISOR_IMAGE",
"OPENSHELL_PODMAN_TLS_CA",
"OPENSHELL_ENABLE_BIND_MOUNTS",
}
tls_fields = {"OPENSHELL_PODMAN_TLS_CA"}
if schema_version == 1:
tls_fields.update({"OPENSHELL_PODMAN_TLS_CERT", "OPENSHELL_PODMAN_TLS_KEY"})
expected_environment_keys.update(tls_fields)
require(
isinstance(driver_environment, dict)
and set(driver_environment) == expected_environment_keys,
f"{launch_path}: external driver allowlisted environment is incomplete",
)
require(
Path(driver_environment["XDG_DATA_HOME"]).is_absolute(),
f"{launch_path}: external driver data directory is not absolute",
)
require(
driver_environment["OPENSHELL_COMPUTE_DRIVER_SOCKET"]
== podman_config["socket_path"],
f"{launch_path}: external driver socket differs from gateway TOML",
)
podman_socket = driver_environment["OPENSHELL_PODMAN_SOCKET"]
require(
isinstance(podman_socket, str)
and Path(podman_socket).is_absolute()
and podman_socket != podman_config["socket_path"],
f"{launch_path}: external driver Podman socket is not isolated",
)
require(
driver_environment["OPENSHELL_SANDBOX_IMAGE"] == sandbox_request
and driver_environment["OPENSHELL_SANDBOX_IMAGE_PULL_POLICY"]
== expected_policy
and driver_environment["OPENSHELL_HEALTH_CHECK_INTERVAL_SECS"] == 10
and driver_environment["OPENSHELL_GRPC_ENDPOINT"] == grpc_endpoint
and driver_environment["OPENSHELL_GATEWAY_PORT"] == gateway_port
and isinstance(driver_environment["OPENSHELL_NETWORK_NAME"], str)
and driver_environment["OPENSHELL_NETWORK_NAME"]
and isinstance(driver_environment["OPENSHELL_STOP_TIMEOUT"], int)
and driver_environment["OPENSHELL_STOP_TIMEOUT"] >= 0
and driver_environment["OPENSHELL_SANDBOX_RUNTIME_IMAGE"]
== sandbox_boundary_image
and driver_environment["OPENSHELL_SUPERVISOR_IMAGE"] == runtime_image
and driver_environment["OPENSHELL_ENABLE_BIND_MOUNTS"] is True,
f"{launch_path}: external driver allowlisted runtime inputs differ",
)
tls_paths: set[str] = set()
for field in tls_fields:
tls_input = driver_environment[field]
require(
isinstance(tls_input, dict)
and set(tls_input) == {"path", "sha256"}
and isinstance(tls_input["path"], str)
and Path(tls_input["path"]).is_absolute()
and isinstance(tls_input["sha256"], str)
and SHA256_RE.fullmatch(tls_input["sha256"]) is not None,
f"{launch_path}: invalid external driver TLS input {field}",
)
tls_paths.add(tls_input["path"])
require(
len(tls_paths) == len(tls_fields),
f"{launch_path}: external driver TLS paths are not distinct",
)
else:
require(
launch.get("external_driver_sha256_before_execution") == "",
f"{launch_path}: unexpected external driver hash",
)
require(log_path.is_file(), f"{log_path}: retained raw log is missing")
raw_log = log_path.read_text(encoding="utf-8", errors="replace")
for marker in ORACLE_MARKERS:
require(
re.search(re.escape(marker) + r".*exit 0", raw_log) is not None,
f"{log_path}: missing successful lifecycle oracle marker {marker}",
)
require(
'"passed": true' in raw_log,
f"{log_path}: missing successful conformance result",
)
require(
re.search(
r"gateway preflight connected: .*authentication=authenticated(?:\n|$)",
raw_log,
)
is not None,
f"{log_path}: authenticated gateway preflight is missing",
)
run_ids = re.findall(
r"^CLI conformance run ID: ([a-z0-9]+)$", raw_log, re.MULTILINE
)
require(
len(run_ids) == 1,
f"{log_path}: expected exactly one conformance run ID",
)
exec_stdout_path = results_dir / f"{variant}.exec.stdout"
require(
exec_stdout_path.is_file(),
f"{exec_stdout_path}: retained exec stdout is missing",
)
expected_exec_stdout = f"openshell-conformance-{run_ids[0]}\n".encode()
require(
exec_stdout_path.read_bytes() == expected_exec_stdout,
f"{exec_stdout_path}: callback exec stdout is not the exact marker",
)
launch_markers = (
runtime_image,
image_id,
image_digest,
sandbox_runtime,
sandbox_id,
sandbox_digest,
sandbox_alias,
launch["sandbox_client_image_alias_id"],
launch["supervisor_base_image_id"],
base_digest,
base_runtime,
launch["supervisor_package_manifest_sha256"],
)
require(
all(marker in raw_log for marker in launch_markers),
f"{log_path}: launch provenance is absent from raw output",
)
conformance_report_verified = False
conformance_report_path = results_dir / f"{variant}.conformance.json"
if require_conformance_report:
verify_conformance_report(conformance_report_path)
conformance_report_verified = True
raw_evidence_hashes = {
result_path.name: sha256(result_path),
launch_path.name: sha256(launch_path),
log_path.name: sha256(log_path),
config_path.name: sha256(config_path),
exec_stdout_path.name: sha256(exec_stdout_path),
}
if require_conformance_report:
raw_evidence_hashes[conformance_report_path.name] = sha256(
conformance_report_path
)
if external:
driver_log_path = results_dir / f"{variant}.driver.log"
require(
driver_log_path.is_file() and driver_log_path.stat().st_size > 0,
f"{driver_log_path}: retained external driver log is missing or empty",
)
raw_evidence_hashes[driver_log_path.name] = sha256(driver_log_path)
verified = {
"schema_version": schema_version,
"source_sha": expected_sha,
"gateway_profile": result["gateway_profile"],
"gateway_cargo_features": result["gateway_cargo_features"],
"artifact_origins": {
"gateway": result["gateway_origin"],
"cli": result["cli_origin"],
"conformance": result["conformance_origin"],
"external_driver": result["external_driver_origin"],
"supervisor": result["supervisor_origin"],
},
"artifact_sha256": artifact_hashes,
"launch_attestation": launch,
"raw_evidence_sha256": raw_evidence_hashes,
"artifacts_verified": True,
"raw_output_verified": True,
"success": True,
}
if conformance_report_verified:
verified["conformance_report_verified"] = True
return verified
def verify_topology(
results_dir: Path,
baseline_sha: str,
candidate_sha: str,
scenario: str,
*,
verify_comparison: bool = True,
require_built_artifacts: bool = True,
) -> dict[str, Any]:
comparison_path = results_dir / "comparison.json"
if verify_comparison:
comparison = load_json(comparison_path)
require(
comparison.get("scenario") == scenario,
f"{comparison_path}: scenario mismatch",
)
for field in ("baseline_success", "candidate_success", "parity", "accepted"):
require(
comparison.get(field) is True,
f"{comparison_path}: {field} is not true",
)
require(
comparison.get("classification") == "pass",
f"{comparison_path}: classification is not pass",
)
baseline = verify_variant(
results_dir,
"baseline",
baseline_sha,
1,
scenario,
require_built_artifacts=require_built_artifacts,
require_conformance_report=not verify_comparison,
)
candidate = verify_variant(
results_dir,
"candidate",
candidate_sha,
2,
scenario,
require_built_artifacts=require_built_artifacts,
require_conformance_report=not verify_comparison,
)
baseline_launch = baseline["launch_attestation"]
candidate_launch = candidate["launch_attestation"]
for field, label in (
("sandbox_image_id", "sandbox image ID"),
("sandbox_image_digest", "sandbox image digest"),
("sandbox_runtime_image", "sandbox runtime image"),
("supervisor_base_image", "supervisor base image"),
("supervisor_base_image_id", "supervisor base-image ID"),
("supervisor_base_image_digest", "supervisor base-image digest"),
("supervisor_package_manifest_sha256", "supervisor package manifest"),
):
require(
baseline_launch.get(field) == candidate_launch.get(field),
f"baseline and candidate {label} differ",
)
if scenario == "external-driver":
baseline_driver = results_dir / "artifacts/baseline/external-driver"
candidate_driver = results_dir / "artifacts/candidate/external-driver"
require(
baseline_driver.resolve() != candidate_driver.resolve(),
"external-driver artifacts resolve to the same path",
)
require(
not baseline_driver.samefile(candidate_driver),
"external-driver artifacts share an inode",
)
require(
baseline["artifact_sha256"]["external-driver"]
!= candidate["artifact_sha256"]["external-driver"],
"external-driver artifacts have identical content",
)
baseline_env = baseline_launch["external_driver_environment"]
candidate_env = candidate_launch["external_driver_environment"]
for field, label in (
("OPENSHELL_COMPUTE_DRIVER_SOCKET", "compute-driver UDS"),
("OPENSHELL_PODMAN_SOCKET", "Podman API UDS"),
("OPENSHELL_NETWORK_NAME", "Podman network"),
):
require(
baseline_env[field] != candidate_env[field],
f"baseline and candidate reuse the same external {label}",
)
for field in (
"OPENSHELL_PODMAN_TLS_CA",
):
require(
baseline_env[field]["path"] != candidate_env[field]["path"],
"baseline and candidate reuse the same external callback TLS path",
)
return {
"baseline": baseline,
"candidate": candidate,
"comparison_sha256": sha256(comparison_path) if verify_comparison else None,
"classification": "pass",
"parity": True,
"accepted": True,
}
def verify_four_run_provenance(
in_tree: dict[str, Any], external_uds: dict[str, Any]
) -> None:
variants = [
in_tree["baseline"]["launch_attestation"],
in_tree["candidate"]["launch_attestation"],
external_uds["baseline"]["launch_attestation"],
external_uds["candidate"]["launch_attestation"],
]
for fields, label in (
(
(
"sandbox_image_id",
"sandbox_image_digest",
"sandbox_runtime_image",
"sandbox_client_image_alias",
"sandbox_client_image_alias_id",
),
"sandbox artifact",
),
(
(
"supervisor_base_image",
"supervisor_base_image_id",
"supervisor_base_image_digest",
"supervisor_base_runtime_image",
"supervisor_package_manifest_sha256",
),
"supervisor dependency provenance",
),
):
tuples = {tuple(launch.get(field) for field in fields) for launch in variants}
require(len(tuples) == 1, f"the four runs use different {label}")
for variant in ("baseline", "candidate"):
in_tree_artifacts = in_tree[variant]["artifact_sha256"]
external_artifacts = external_uds[variant]["artifact_sha256"]
for artifact in (
"cli",
"conformance",
"supervisor",
"supervisor.Dockerfile",
"cli-trace-wrapper",
):
require(
in_tree_artifacts[artifact] == external_artifacts[artifact],
f"{variant} {artifact} differs across topologies",
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument("--baseline-sha", required=True)
parser.add_argument("--candidate-sha", required=True)
parser.add_argument("--in-tree", type=Path)
parser.add_argument("--external-uds", type=Path)
parser.add_argument("--scenario", choices=("smoke", "external-driver"))
parser.add_argument("--results-dir", type=Path)
parser.add_argument("--output", required=True, type=Path)
return parser.parse_args()
def main() -> None:
args = parse_args()
require(
re.fullmatch(r"[0-9a-f]{40}", args.baseline_sha) is not None,
"invalid baseline SHA",
)
require(
re.fullmatch(r"[0-9a-f]{40}", args.candidate_sha) is not None,
"invalid candidate SHA",
)
scenario_mode = args.scenario is not None or args.results_dir is not None
if scenario_mode:
require(
args.scenario is not None and args.results_dir is not None,
"--scenario and --results-dir must be provided together",
)
require(
args.in_tree is None and args.external_uds is None,
"single-scenario verification cannot use --in-tree or --external-uds",
)
topology = verify_topology(
args.results_dir,
args.baseline_sha,
args.candidate_sha,
args.scenario,
verify_comparison=False,
require_built_artifacts=False,
)
report = {
"manifest_version": 1,
"baseline_commit": args.baseline_sha,
"candidate_commit": args.candidate_sha,
"scenario": args.scenario,
"topology": topology,
"classification": "pass",
"accepted": True,
}
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(json.dumps(report, indent=2) + "\n", encoding="utf-8")
return
require(
args.in_tree is not None and args.external_uds is not None,
"--in-tree and --external-uds are required for four-run verification",
)
in_tree = verify_topology(
args.in_tree, args.baseline_sha, args.candidate_sha, "smoke"
)
external_uds = verify_topology(
args.external_uds, args.baseline_sha, args.candidate_sha, "external-driver"
)
verify_four_run_provenance(in_tree, external_uds)
report = {
"manifest_version": 2,
"baseline_commit": args.baseline_sha,
"candidate_commit": args.candidate_sha,
"lane": "local-linux-x86_64-rootless-podman-5.8.2",
"retained_evidence_bundles": {
"in_tree": args.in_tree.as_posix(),
"external_uds": args.external_uds.as_posix(),
},
"oracle": {
"status": True,
"create": True,
"ready": True,
"list_visible": True,
"callback_exec_exact_marker": True,
"delete": True,
"list_empty": True,
},
"in_tree": in_tree,
"external_uds": external_uds,
"callback_listener": {
"in_tree_baseline_exec": True,
"in_tree_candidate_exec": True,
"external_baseline_exec": True,
"external_candidate_exec": True,
"classification": "pass",
},
"classification": "pass",
"accepted": True,
"verification": {
"retained_artifact_hashes_recomputed": True,
"raw_lifecycle_output_inspected": True,
"authenticated_preflight_verified": True,
"exact_callback_exec_stdout_verified": True,
"external_driver_allowlist_verified": True,
"external_driver_logs_retained": True,
"external_uds_isolation_verified": True,
"digest_pinned_supervisor_runtime_verified": True,
"same_immutable_sandbox_verified": True,
"supervisor_dependency_provenance_matched": True,
},
}
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(json.dumps(report, indent=2) + "\n", encoding="utf-8")
if __name__ == "__main__":
main()
-43
View File
@@ -1,43 +0,0 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Read copied Debian/distroless package metadata without executing image tools."""
import sys
from pathlib import Path
def package_manifest(root: Path) -> list[str]:
status = root / "status"
sources = [status] if status.is_file() else []
sources.extend(
path
for path in sorted((root / "status.d").glob("*"))
if path.is_file() and not path.name.endswith(".md5sums")
)
packages = set()
for source in sources:
for stanza in source.read_text().strip().split("\n\n"):
if not stanza.strip():
continue
fields = dict(
line.split(": ", 1)
for line in stanza.splitlines()
if not line.startswith((" ", "\t")) and ": " in line
)
if "Status" in fields and not fields["Status"].endswith(" ok installed"):
continue
if not {"Package", "Version", "Architecture"} <= fields.keys():
raise ValueError(f"Incomplete package metadata in {source}")
name = fields["Package"]
if fields.get("Multi-Arch") == "same":
name += ":" + fields["Architecture"]
packages.add(f"{name}={fields['Version']}")
if not packages:
raise ValueError(f"No installed Debian packages found in {root}")
return sorted(packages)
if __name__ == "__main__":
print("\n".join(package_manifest(Path(sys.argv[1]))))
+67 -170
View File
@@ -2,30 +2,10 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Schema-aware Podman gateway configuration generation shared by the local e2e
# wrapper and schema parity harness. This file expects gateway-common.sh to
# Podman gateway configuration generation shared by the local e2e wrapper and
# its deterministic configuration test. This file expects gateway-common.sh to
# have been sourced first.
e2e_podman_config_schema_version() {
local version="${OPENSHELL_E2E_CONFIG_SCHEMA_VERSION:-2}"
case "${version}" in
1|2) printf '%s\n' "${version}" ;;
*)
echo "ERROR: OPENSHELL_E2E_CONFIG_SCHEMA_VERSION must be 1 or 2 (got ${version})." >&2
return 2
;;
esac
}
e2e_podman_external_driver_pull_policy() {
case "$1" in
1) printf '%s\n' missing ;;
2) printf '%s\n' if_not_present ;;
*) echo "ERROR: unsupported Podman config schema version: $1" >&2; return 2 ;;
esac
}
e2e_podman_toml_string() {
local value="$1"
value="${value//\\/\\\\}"
@@ -33,158 +13,75 @@ e2e_podman_toml_string() {
printf '"%s"' "${value}"
}
# Return the explicitly selected behavioral profile. Keep the default empty so
# ordinary smoke coverage continues to exercise the minimal configuration.
e2e_podman_option_profile() {
case "${OPENSHELL_E2E_PODMAN_OPTION_PROFILE:-}" in
"") printf '%s\n' "" ;;
podman-options) printf '%s\n' "podman-options" ;;
*)
echo "ERROR: unsupported OPENSHELL_E2E_PODMAN_OPTION_PROFILE: ${OPENSHELL_E2E_PODMAN_OPTION_PROFILE}" >&2
return 2
;;
esac
}
# Frozen baseline 74960ebfaeec4673885089ed995fad902459749f does not accept
# Podman app_armor_profile, so it is deliberately not part of this paired profile.
# Write the minimally configured Podman e2e gateway TOML. The schema-v1
# branch deliberately uses the frozen-main contract: list driver selection,
# driver-local guest TLS, the old "missing" pull-policy spelling, and zero to
# disable Podman health checks. Schema v2 uses gateway-owned guest TLS and the
# current positive health-check setting from the RPM template.
# Write the current Podman e2e gateway TOML. The RPM template opens the Podman
# driver table, so gateway-owned TLS is inserted before that table and the
# remaining driver options are appended to it.
e2e_write_podman_gateway_config() {
local output=$1
local schema_version=$2
local root=$3
local pki_dir=$4
local jwt_dir=$5
local gateway_id=$6
local external_driver=$7
local driver_socket=$8
local network_name=$9
local gateway_port=${10}
local sandbox_image=${11}
local stop_timeout_secs=${12}
local supervisor_image=${13}
local sandbox_runtime_image=${14}
local provider_spiffe_socket=${15}
local podman_socket=${16}
local oidc_mode=${17}
local oidc_issuer=${18}
local configured_with_tls option_profile
local root=$2
local pki_dir=$3
local jwt_dir=$4
local gateway_id=$5
local external_driver=$6
local driver_socket=$7
local network_name=$8
local gateway_port=$9
local sandbox_image=${10}
local stop_timeout_secs=${11}
local supervisor_image=${12}
local sandbox_runtime_image=${13}
local provider_spiffe_socket=${14}
local podman_socket=${15}
local oidc_mode=${16}
local oidc_issuer=${17}
local configured_with_tls
case "${OPENSHELL_E2E_PODMAN_OPTION_PROFILE:-}" in
""|podman-options) option_profile="${OPENSHELL_E2E_PODMAN_OPTION_PROFILE:-}" ;;
*) echo "ERROR: unsupported OPENSHELL_E2E_PODMAN_OPTION_PROFILE: ${OPENSHELL_E2E_PODMAN_OPTION_PROFILE}" >&2; return 2 ;;
esac
cp "${root}/deploy/rpm/gateway.toml.default" "${output}"
if [ "${external_driver}" = "1" ]; then
# A remote UDS driver owns all runtime options. Keep the selected gateway
# table transport-only so in-tree settings cannot be mistaken for external
# driver configuration.
sed '/^health_check_interval_secs = /d' "${output}" >"${output}.updated"
mv "${output}.updated" "${output}"
fi
case "${schema_version}" in
1)
cp "${root}/deploy/rpm/gateway.toml.default.v1" "${output}"
{
e2e_write_gateway_jwt_config "${jwt_dir}" "${gateway_id}"
if [ "${oidc_mode}" != "1" ]; then
e2e_write_gateway_mtls_auth_config
if [ -n "${oidc_issuer}" ]; then
e2e_write_gateway_oidc_config "${oidc_issuer}"
fi
fi
printf '\n[openshell.drivers.podman]\n'
if [ "${external_driver}" = "1" ]; then
printf 'socket_path = %s\n' "$(e2e_podman_toml_string "${driver_socket}")"
else
printf 'network_name = %s\n' "$(e2e_podman_toml_string "${network_name}")"
printf 'gateway_port = %s\n' "${gateway_port}"
printf 'default_image = %s\n' "$(e2e_podman_toml_string "${sandbox_image}")"
printf 'image_pull_policy = "missing"\n'
if [ "${option_profile}" = "podman-options" ]; then
printf 'sandbox_pids_limit = 31\n'
printf 'health_check_interval_secs = 7\n'
configured_with_tls="${output}.tls"
while IFS= read -r line; do
if [ "${line}" = "[openshell.drivers.podman]" ]; then
printf 'guest_tls_ca = %s\n' "$(e2e_podman_toml_string "${pki_dir}/ca.crt")"
fi
printf '%s\n' "${line}"
done <"${output}" >"${configured_with_tls}"
mv "${configured_with_tls}" "${output}"
printf 'sandbox_ssh_socket_path = "/run/openshell/parity-ssh.sock"\n'
else
# In schema v1, zero explicitly disables Podman health checks.
printf 'health_check_interval_secs = 0\n'
fi
printf 'stop_timeout_secs = %s\n' "${stop_timeout_secs}"
printf 'supervisor_image = %s\n' "$(e2e_podman_toml_string "${supervisor_image}")"
printf 'sandbox_runtime_image = %s\n' "$(e2e_podman_toml_string "${sandbox_runtime_image}")"
printf 'guest_tls_ca = %s\n' "$(e2e_podman_toml_string "${pki_dir}/ca.crt")"
printf 'guest_tls_cert = %s\n' "$(e2e_podman_toml_string "${pki_dir}/client/tls.crt")"
printf 'guest_tls_key = %s\n' "$(e2e_podman_toml_string "${pki_dir}/client/tls.key")"
printf 'enable_bind_mounts = true\n'
if [ -n "${provider_spiffe_socket}" ]; then
printf 'provider_spiffe_workload_api_socket = %s\n' "$(e2e_podman_toml_string "${provider_spiffe_socket}")"
fi
if [ -n "${podman_socket}" ]; then
printf 'socket_path = %s\n' "$(e2e_podman_toml_string "${podman_socket}")"
fi
fi
} >>"${output}"
;;
2)
cp "${root}/deploy/rpm/gateway.toml.default" "${output}"
if [ "${external_driver}" = "1" ]; then
# A remote UDS driver owns all runtime options. Keep the selected
# gateway table transport-only so no in-tree setting can be mistaken
# for executed external-driver configuration.
sed '/^health_check_interval_secs = /d' "${output}" >"${output}.updated"
mv "${output}.updated" "${output}"
elif [ "${option_profile}" = "podman-options" ]; then
sed 's/^health_check_interval_secs = .*/health_check_interval_secs = 7/' \
"${output}" >"${output}.updated"
mv "${output}.updated" "${output}"
{
if [ "${external_driver}" = "1" ]; then
printf 'socket_path = %s\n' "$(e2e_podman_toml_string "${driver_socket}")"
else
printf 'allow_driver_config = true\n'
printf 'network_name = %s\n' "$(e2e_podman_toml_string "${network_name}")"
printf 'gateway_port = %s\n' "${gateway_port}"
printf 'default_image = %s\n' "$(e2e_podman_toml_string "${sandbox_image}")"
printf 'image_pull_policy = "if_not_present"\n'
printf 'stop_timeout_secs = %s\n' "${stop_timeout_secs}"
printf 'supervisor_image = %s\n' "$(e2e_podman_toml_string "${supervisor_image}")"
printf 'sandbox_runtime_image = %s\n' "$(e2e_podman_toml_string "${sandbox_runtime_image}")"
printf 'enable_bind_mounts = true\n'
if [ -n "${provider_spiffe_socket}" ]; then
printf 'provider_spiffe_workload_api_socket = %s\n' "$(e2e_podman_toml_string "${provider_spiffe_socket}")"
fi
# The v2 template opens the Podman table. Insert gateway-owned TLS
# before it rather than reopening [openshell.gateway] later.
configured_with_tls="${output}.tls"
while IFS= read -r line; do
if [ "${line}" = "[openshell.drivers.podman]" ]; then
printf 'guest_tls_ca = %s\n' "$(e2e_podman_toml_string "${pki_dir}/ca.crt")"
fi
printf '%s\n' "${line}"
done <"${output}" >"${configured_with_tls}"
mv "${configured_with_tls}" "${output}"
{
if [ "${external_driver}" = "1" ]; then
printf 'socket_path = %s\n' "$(e2e_podman_toml_string "${driver_socket}")"
else
printf 'allow_driver_config = true\n'
printf 'network_name = %s\n' "$(e2e_podman_toml_string "${network_name}")"
printf 'gateway_port = %s\n' "${gateway_port}"
printf 'default_image = %s\n' "$(e2e_podman_toml_string "${sandbox_image}")"
printf 'image_pull_policy = "if_not_present"\n'
if [ "${option_profile}" = "podman-options" ]; then
printf 'sandbox_pids_limit = 31\n'
printf 'ssh_socket_path = "/run/openshell/parity-ssh.sock"\n'
fi
printf 'stop_timeout_secs = %s\n' "${stop_timeout_secs}"
printf 'supervisor_image = %s\n' "$(e2e_podman_toml_string "${supervisor_image}")"
printf 'sandbox_runtime_image = %s\n' "$(e2e_podman_toml_string "${sandbox_runtime_image}")"
printf 'enable_bind_mounts = true\n'
if [ -n "${provider_spiffe_socket}" ]; then
printf 'provider_spiffe_workload_api_socket = %s\n' "$(e2e_podman_toml_string "${provider_spiffe_socket}")"
fi
if [ -n "${podman_socket}" ]; then
printf 'socket_path = %s\n' "$(e2e_podman_toml_string "${podman_socket}")"
fi
printf '\n[openshell.drivers.podman.resource_admission]\n'
printf 'enabled = false\n'
fi
e2e_write_gateway_jwt_config "${jwt_dir}" "${gateway_id}"
if [ "${oidc_mode}" != "1" ]; then
e2e_write_gateway_mtls_auth_config
if [ -n "${oidc_issuer}" ]; then
e2e_write_gateway_oidc_config "${oidc_issuer}"
fi
fi
} >>"${output}"
;;
*)
echo "ERROR: unsupported Podman config schema version: ${schema_version}" >&2
return 2
;;
esac
if [ -n "${podman_socket}" ]; then
printf 'socket_path = %s\n' "$(e2e_podman_toml_string "${podman_socket}")"
fi
printf '\n[openshell.drivers.podman.resource_admission]\n'
printf 'enabled = false\n'
fi
e2e_write_gateway_jwt_config "${jwt_dir}" "${gateway_id}"
if [ "${oidc_mode}" != "1" ]; then
e2e_write_gateway_mtls_auth_config
if [ -n "${oidc_issuer}" ]; then
e2e_write_gateway_oidc_config "${oidc_issuer}"
fi
fi
} >>"${output}"
}
+20 -304
View File
@@ -94,20 +94,6 @@ podman_cmd() {
fi
}
require_expected_sha256() {
local label=$1 path=$2 expected=$3 actual
[ -n "${expected}" ] || return 0
if [ ! -f "${path}" ]; then
echo "ERROR: ${label} is missing before execution: ${path}" >&2
exit 2
fi
actual="$(sha256sum "${path}" | cut -d' ' -f1)"
if [ "${actual}" != "${expected}" ]; then
echo "ERROR: ${label} hash changed before execution." >&2
exit 2
fi
}
WORKDIR_PARENT="${TMPDIR:-/tmp}"
WORKDIR_PARENT="${WORKDIR_PARENT%/}"
WORKDIR="$(mktemp -d "${WORKDIR_PARENT}/openshell-e2e-podman.XXXXXX")"
@@ -132,8 +118,7 @@ GATEWAY_PID_FILE="${WORKDIR}/gateway.pid"
GATEWAY_ARGS_FILE="${WORKDIR}/gateway.args"
DRIVER_BIN=""
DRIVER_PID=""
DRIVER_LOG="${OPENSHELL_PARITY_EXTERNAL_DRIVER_LOG_CAPTURE:-${WORKDIR}/podman-driver.log}"
mkdir -p "$(dirname "${DRIVER_LOG}")"
DRIVER_LOG="${WORKDIR}/podman-driver.log"
DRIVER_SOCKET="${WORKDIR}/compute-driver.sock"
DRIVER_DATA_HOME="${WORKDIR}/driver-data"
mkdir -p "${DRIVER_DATA_HOME}"
@@ -158,10 +143,6 @@ export XDG_CONFIG_HOME="${WORKDIR}/config"
cleanup() {
local exit_code=$?
if [ -n "${SUPERVISOR_METADATA_CONTAINER:-}" ]; then
podman_cmd rm -f "${SUPERVISOR_METADATA_CONTAINER}" >/dev/null 2>&1 || true
fi
e2e_stop_gateway "${GATEWAY_PID}" "${GATEWAY_PID_FILE}"
e2e_stop_process "${DRIVER_PID}" "external Podman compute driver"
@@ -283,23 +264,19 @@ default_podman_socket_path() {
}
ensure_podman_api_socket() {
if [ "${OPENSHELL_E2E_FORCE_TEMP_PODMAN_SERVICE:-0}" != 1 ]; then
if [ -n "${OPENSHELL_PODMAN_SOCKET:-}" ]; then
export CONTAINER_HOST="${CONTAINER_HOST:-unix://${OPENSHELL_PODMAN_SOCKET}}"
return 0
fi
if [ -n "${OPENSHELL_PODMAN_SOCKET:-}" ]; then
export CONTAINER_HOST="${CONTAINER_HOST:-unix://${OPENSHELL_PODMAN_SOCKET}}"
return 0
fi
local default_socket
default_socket="$(default_podman_socket_path || true)"
if [ -n "${default_socket}" ] \
&& [ -S "${default_socket}" ] \
&& with_podman_config podman --url "unix://${default_socket}" info >/dev/null 2>&1; then
export OPENSHELL_PODMAN_SOCKET="${default_socket}"
export CONTAINER_HOST="${CONTAINER_HOST:-unix://${OPENSHELL_PODMAN_SOCKET}}"
return 0
fi
else
unset OPENSHELL_PODMAN_SOCKET CONTAINER_HOST
local default_socket
default_socket="$(default_podman_socket_path || true)"
if [ -n "${default_socket}" ] \
&& [ -S "${default_socket}" ] \
&& with_podman_config podman --url "unix://${default_socket}" info >/dev/null 2>&1; then
export OPENSHELL_PODMAN_SOCKET="${default_socket}"
export CONTAINER_HOST="${CONTAINER_HOST:-unix://${OPENSHELL_PODMAN_SOCKET}}"
return 0
fi
# `podman system service` is a Linux-only subcommand — the macOS client
@@ -404,74 +381,6 @@ resolve_podman_sandbox_runtime_image() {
ensure_podman_supervisor_image() {
local image=$1
if [ -n "${OPENSHELL_E2E_SUPERVISOR_BIN:-}" ]; then
local dockerfile=${OPENSHELL_E2E_SUPERVISOR_DOCKERFILE:-${ROOT}/deploy/docker/Dockerfile.supervisor}
local context="${WORKDIR}/supervisor-image" arch
case "${image}" in
*@*)
echo "ERROR: supplied supervisor binaries cannot be built to a digest-pinned image reference: ${image}" >&2
echo " Use a tagged image reference when building from OPENSHELL_E2E_SUPERVISOR_BIN." >&2
exit 2
;;
*:dev|*:latest)
echo "ERROR: supplied supervisor binaries require a unique versioned image tag, not ${image}." >&2
exit 2
;;
*:*) ;;
*)
echo "ERROR: supplied supervisor binaries require an explicit versioned image tag: ${image}." >&2
exit 2
;;
esac
case "$(uname -m)" in
x86_64|amd64) arch=amd64 ;;
aarch64|arm64) arch=arm64 ;;
*) echo "ERROR: unsupported supervisor image architecture: $(uname -m)" >&2; exit 2 ;;
esac
if [ ! -x "${OPENSHELL_E2E_SUPERVISOR_BIN}" ]; then
echo "ERROR: supplied supervisor binary is not executable: ${OPENSHELL_E2E_SUPERVISOR_BIN}" >&2
exit 2
fi
if [ ! -f "${dockerfile}" ]; then
echo "ERROR: supervisor Dockerfile not found: ${dockerfile}" >&2
exit 2
fi
require_expected_sha256 "supervisor binary" "${OPENSHELL_E2E_SUPERVISOR_BIN}" \
"${OPENSHELL_E2E_EXPECTED_SUPERVISOR_SHA256:-}"
require_expected_sha256 "supervisor Dockerfile" "${dockerfile}" \
"${OPENSHELL_E2E_EXPECTED_SUPERVISOR_DOCKERFILE_SHA256:-}"
mkdir -p "${context}/deploy/docker/.build/prebuilt-binaries/${arch}"
install -m 0555 "${OPENSHELL_E2E_SUPERVISOR_BIN}" \
"${context}/deploy/docker/.build/prebuilt-binaries/${arch}/openshell-sandbox"
cp "${dockerfile}" "${context}/deploy/docker/Dockerfile.supervisor"
local -a pull_option=()
if [ -n "${OPENSHELL_E2E_SUPERVISOR_BASE_RUNTIME_IMAGE:-}" ]; then
local dockerfile_base
dockerfile_base="$(awk '$1 == "FROM" { print $2; exit }' "${dockerfile}")"
if [ "${dockerfile_base}" != "${OPENSHELL_E2E_SUPERVISOR_BASE_IMAGE:-}" ] \
|| ! [[ "${OPENSHELL_E2E_SUPERVISOR_BASE_RUNTIME_IMAGE}" =~ ^[^@]+@sha256:[0-9a-f]{64}$ ]]; then
echo "ERROR: supervisor base-image attestation does not match the Dockerfile." >&2
exit 2
fi
echo "Pulling pinned supervisor base image ${OPENSHELL_E2E_SUPERVISOR_BASE_RUNTIME_IMAGE}..."
podman_cmd pull "${OPENSHELL_E2E_SUPERVISOR_BASE_RUNTIME_IMAGE}"
podman_cmd tag "${OPENSHELL_E2E_SUPERVISOR_BASE_RUNTIME_IMAGE}" "${dockerfile_base}"
pull_option=(--pull=never)
fi
echo "Building Podman supervisor image ${image} from supplied binary..."
(
cd "${context}"
podman_cmd build \
"${pull_option[@]}" \
--build-arg "TARGETARCH=${arch}" \
--file deploy/docker/Dockerfile.supervisor \
--target supervisor \
--tag "${image}" \
.
)
return 0
fi
if [ "${image}" = "openshell/supervisor:dev" ] \
&& [ -z "${OPENSHELL_SUPERVISOR_IMAGE:-}" ] \
&& [ -z "${CI:-}" ]; then
@@ -560,12 +469,7 @@ if [ -n "${OPENSHELL_GATEWAY_ENDPOINT:-}" ]; then
exit $?
fi
# Validate the generated configuration dialect before creating runtime resources.
CONFIG_SCHEMA_VERSION="$(e2e_podman_config_schema_version)"
EXTERNAL_DRIVER_PULL_POLICY="$(e2e_podman_external_driver_pull_policy "${CONFIG_SCHEMA_VERSION}")"
# Validate the opt-in profile before building images or allocating runtime resources.
e2e_podman_option_profile >/dev/null
EXTERNAL_DRIVER_PULL_POLICY="if_not_present"
# Preflight for managed Podman gateway mode.
if ! command -v podman >/dev/null 2>&1; then
@@ -588,56 +492,7 @@ fi
SUPERVISOR_IMAGE="$(resolve_podman_supervisor_image)"
ensure_podman_supervisor_image "${SUPERVISOR_IMAGE}"
SUPERVISOR_IMAGE_ID="$(podman_cmd image inspect --format '{{.Id}}' "${SUPERVISOR_IMAGE}")"
SUPERVISOR_IMAGE_ID="${SUPERVISOR_IMAGE_ID#sha256:}"
SUPERVISOR_IMAGE_DIGEST="$(podman_cmd image inspect --format '{{.Digest}}' "${SUPERVISOR_IMAGE}")"
if ! [[ "${SUPERVISOR_IMAGE_ID}" =~ ^[0-9a-f]{64}$ ]]; then
echo "ERROR: could not resolve immutable supervisor image ID for ${SUPERVISOR_IMAGE}." >&2
exit 2
fi
if ! [[ "${SUPERVISOR_IMAGE_DIGEST}" =~ ^sha256:[0-9a-f]{64}$ ]]; then
echo "ERROR: could not resolve supervisor image digest for ${SUPERVISOR_IMAGE}." >&2
exit 2
fi
# The parity harness forces a temporary Podman API service into the same
# isolated XDG store where this image was built. Address the local image by its
# immutable manifest digest so policy=missing cannot resolve a mutable tag or
# contact a registry for a different artifact.
SUPERVISOR_IMAGE_REPOSITORY="${SUPERVISOR_IMAGE%%@*}"
last_component="${SUPERVISOR_IMAGE_REPOSITORY##*/}"
if [[ "${last_component}" == *:* ]]; then
SUPERVISOR_IMAGE_REPOSITORY="${SUPERVISOR_IMAGE_REPOSITORY%:*}"
fi
SUPERVISOR_RUNTIME_IMAGE="${SUPERVISOR_IMAGE_REPOSITORY}@${SUPERVISOR_IMAGE_DIGEST}"
if ! [[ "${SUPERVISOR_RUNTIME_IMAGE}" =~ ^[^@]+@sha256:[0-9a-f]{64}$ ]]; then
echo "ERROR: supervisor runtime image is not digest-pinned: ${SUPERVISOR_RUNTIME_IMAGE}" >&2
exit 2
fi
SUPERVISOR_BASE_IMAGE="$(awk '$1 == "FROM" { print $2; exit }' "${OPENSHELL_E2E_SUPERVISOR_DOCKERFILE:-${ROOT}/deploy/docker/Dockerfile.supervisor}")"
if ! podman_cmd image exists "${SUPERVISOR_BASE_IMAGE}" 2>/dev/null; then
echo "Pulling Podman supervisor base image ${SUPERVISOR_BASE_IMAGE}..."
podman_cmd pull "${SUPERVISOR_BASE_IMAGE}"
fi
SUPERVISOR_BASE_IMAGE_ID="$(podman_cmd image inspect --format '{{.Id}}' "${SUPERVISOR_BASE_IMAGE}")"
SUPERVISOR_BASE_IMAGE_ID="${SUPERVISOR_BASE_IMAGE_ID#sha256:}"
SUPERVISOR_BASE_IMAGE_DIGEST="$(podman_cmd image inspect --format '{{.Digest}}' "${SUPERVISOR_BASE_IMAGE}")"
if ! [[ "${SUPERVISOR_BASE_IMAGE_ID}" =~ ^[0-9a-f]{64}$ ]] \
|| ! [[ "${SUPERVISOR_BASE_IMAGE_DIGEST}" =~ ^sha256:[0-9a-f]{64}$ ]]; then
echo "ERROR: could not resolve supervisor base-image provenance for ${SUPERVISOR_BASE_IMAGE}." >&2
exit 2
fi
SUPERVISOR_PACKAGE_MANIFEST="${OPENSHELL_PARITY_SUPERVISOR_PACKAGE_CAPTURE:-${WORKDIR}/supervisor.packages.txt}"
mkdir -p "$(dirname "${SUPERVISOR_PACKAGE_MANIFEST}")"
# Distroless retains package metadata but has no dpkg-query executable.
# Copy from a stopped container so inventory does not execute image contents.
SUPERVISOR_METADATA_CONTAINER="$(podman_cmd create --network none "${SUPERVISOR_RUNTIME_IMAGE}")"
podman_cmd cp "${SUPERVISOR_METADATA_CONTAINER}:/var/lib/dpkg" "${WORKDIR}/supervisor-dpkg"
podman_cmd rm "${SUPERVISOR_METADATA_CONTAINER}" >/dev/null
SUPERVISOR_METADATA_CONTAINER=""
uv run --no-project python "${ROOT}/e2e/support/debian-package-manifest.py" \
"${WORKDIR}/supervisor-dpkg" >"${SUPERVISOR_PACKAGE_MANIFEST}"
SUPERVISOR_PACKAGE_MANIFEST_SHA256="$(sha256sum "${SUPERVISOR_PACKAGE_MANIFEST}" | cut -d' ' -f1)"
echo "Using Podman supervisor image: ${SUPERVISOR_RUNTIME_IMAGE} (ID ${SUPERVISOR_IMAGE_ID}, digest ${SUPERVISOR_IMAGE_DIGEST}, base ${SUPERVISOR_BASE_IMAGE} ID ${SUPERVISOR_BASE_IMAGE_ID} digest ${SUPERVISOR_BASE_IMAGE_DIGEST}, packages ${SUPERVISOR_PACKAGE_MANIFEST_SHA256})"
echo "Using Podman supervisor image: ${SUPERVISOR_IMAGE}"
SANDBOX_BOUNDARY_IMAGE="$(resolve_podman_sandbox_runtime_image)"
ensure_podman_sandbox_runtime_image "${SANDBOX_BOUNDARY_IMAGE}"
@@ -645,11 +500,6 @@ echo "Using Podman sandbox runtime image: ${SANDBOX_BOUNDARY_IMAGE}"
DEFAULT_SANDBOX_IMAGE="nvcr.io/nvidia/base/ubuntu:24.04"
SANDBOX_IMAGE_REQUEST="${OPENSHELL_E2E_PODMAN_SANDBOX_IMAGE:-${OPENSHELL_SANDBOX_IMAGE:-${DEFAULT_SANDBOX_IMAGE}}}"
if [ "${OPENSHELL_E2E_REQUIRE_DIGEST_PINNED_SANDBOX_IMAGE:-0}" = "1" ] \
&& ! [[ "${SANDBOX_IMAGE_REQUEST}" =~ ^[^@]+@sha256:[0-9a-f]{64}$ ]]; then
echo "ERROR: this e2e invocation requires a digest-pinned sandbox image: ${SANDBOX_IMAGE_REQUEST}" >&2
exit 2
fi
PODMAN_STOP_TIMEOUT_SECS="${OPENSHELL_E2E_PODMAN_STOP_TIMEOUT_SECS:-15}"
if ! [[ "${PODMAN_STOP_TIMEOUT_SECS}" =~ ^[0-9]+$ ]]; then
echo "ERROR: OPENSHELL_E2E_PODMAN_STOP_TIMEOUT_SECS must be a non-negative integer." >&2
@@ -659,37 +509,7 @@ if ! podman_cmd image exists "${SANDBOX_IMAGE_REQUEST}" 2>/dev/null; then
echo "Pulling ${SANDBOX_IMAGE_REQUEST}..."
podman_cmd pull "${SANDBOX_IMAGE_REQUEST}"
fi
SANDBOX_IMAGE_ID="$(podman_cmd image inspect --format '{{.Id}}' "${SANDBOX_IMAGE_REQUEST}")"
SANDBOX_IMAGE_ID="${SANDBOX_IMAGE_ID#sha256:}"
SANDBOX_IMAGE_DIGEST="$(podman_cmd image inspect --format '{{.Digest}}' "${SANDBOX_IMAGE_REQUEST}")"
SANDBOX_IMAGE_REPOSITORY="${SANDBOX_IMAGE_REQUEST%%@*}"
case "${SANDBOX_IMAGE_REPOSITORY##*/}" in
*:*) SANDBOX_IMAGE_REPOSITORY="${SANDBOX_IMAGE_REPOSITORY%:*}" ;;
esac
SANDBOX_RUNTIME_IMAGE="${SANDBOX_IMAGE_REPOSITORY}@${SANDBOX_IMAGE_DIGEST}"
if ! [[ "${SANDBOX_IMAGE_ID}" =~ ^[0-9a-f]{64}$ ]] \
|| ! [[ "${SANDBOX_RUNTIME_IMAGE}" =~ ^[^@]+@sha256:[0-9a-f]{64}$ ]]; then
echo "ERROR: could not resolve an immutable sandbox image for ${SANDBOX_IMAGE_REQUEST}." >&2
exit 2
fi
if [ "${OPENSHELL_E2E_REQUIRE_DIGEST_PINNED_SANDBOX_IMAGE:-0}" = "1" ] \
&& [ "${SANDBOX_IMAGE_REQUEST}" != "${SANDBOX_RUNTIME_IMAGE}" ]; then
echo "ERROR: sandbox image digest changed while resolving ${SANDBOX_IMAGE_REQUEST}." >&2
exit 2
fi
SANDBOX_CLIENT_IMAGE_ALIAS=""
SANDBOX_CLIENT_IMAGE_ALIAS_ID=""
if [ "${OPENSHELL_E2E_REQUIRE_DIGEST_PINNED_SANDBOX_IMAGE:-0}" = "1" ]; then
SANDBOX_CLIENT_IMAGE_ALIAS="${SANDBOX_IMAGE_REPOSITORY}:latest"
podman_cmd tag "${SANDBOX_RUNTIME_IMAGE}" "${SANDBOX_CLIENT_IMAGE_ALIAS}"
SANDBOX_CLIENT_IMAGE_ALIAS_ID="$(podman_cmd image inspect --format '{{.Id}}' "${SANDBOX_CLIENT_IMAGE_ALIAS}")"
SANDBOX_CLIENT_IMAGE_ALIAS_ID="${SANDBOX_CLIENT_IMAGE_ALIAS_ID#sha256:}"
if [ "${SANDBOX_CLIENT_IMAGE_ALIAS_ID}" != "${SANDBOX_IMAGE_ID}" ]; then
echo "ERROR: sandbox client alias does not resolve to the pinned sandbox image." >&2
exit 2
fi
fi
echo "Using Podman sandbox image: ${SANDBOX_RUNTIME_IMAGE} (ID ${SANDBOX_IMAGE_ID}, digest ${SANDBOX_IMAGE_DIGEST}, client alias ${SANDBOX_CLIENT_IMAGE_ALIAS:-none} ID ${SANDBOX_CLIENT_IMAGE_ALIAS_ID:-none})"
echo "Using Podman sandbox image: ${SANDBOX_IMAGE_REQUEST}"
PKI_DIR="${WORKDIR}/pki"
e2e_generate_pki "${GATEWAY_BIN}" "${PKI_DIR}" "host.containers.internal"
@@ -719,7 +539,6 @@ e2e_generate_gateway_jwt "${JWT_DIR}"
GATEWAY_CONFIG="${STATE_DIR}/gateway.toml"
e2e_write_podman_gateway_config \
"${GATEWAY_CONFIG}" \
"${CONFIG_SCHEMA_VERSION}" \
"${ROOT}" \
"${PKI_DIR}" \
"${JWT_DIR}" \
@@ -728,113 +547,19 @@ e2e_write_podman_gateway_config \
"${DRIVER_SOCKET}" \
"${PODMAN_NETWORK_NAME}" \
"${HOST_PORT}" \
"${SANDBOX_RUNTIME_IMAGE}" \
"${SANDBOX_IMAGE_REQUEST}" \
"${PODMAN_STOP_TIMEOUT_SECS}" \
"${SUPERVISOR_RUNTIME_IMAGE}" \
"${SUPERVISOR_IMAGE}" \
"${SANDBOX_BOUNDARY_IMAGE}" \
"${OPENSHELL_E2E_PROVIDER_SPIFFE_SOCKET:-}" \
"${OPENSHELL_PODMAN_SOCKET:-}" \
"${OIDC_MODE}" \
"${OPENSHELL_OIDC_ISSUER:-}"
if [ -n "${OPENSHELL_PARITY_GATEWAY_CONFIG_CAPTURE:-}" ]; then
cp "${GATEWAY_CONFIG}" "${OPENSHELL_PARITY_GATEWAY_CONFIG_CAPTURE}"
fi
EXTERNAL_DRIVER_GRPC_ENDPOINT="https://127.0.0.1:${HOST_PORT}"
EXTERNAL_DRIVER_HEALTH_CHECK_INTERVAL_SECS=10
EXTERNAL_DRIVER_ENABLE_BIND_MOUNTS=true
EXTERNAL_DRIVER_TLS_CA="${PKI_DIR}/ca.crt"
EXTERNAL_DRIVER_TLS_CERT="${PKI_DIR}/client/tls.crt"
EXTERNAL_DRIVER_TLS_KEY="${PKI_DIR}/client/tls.key"
# The frozen schema-v1 baseline still requires a gateway client identity.
external_driver_legacy_tls_env=()
if [ "${CONFIG_SCHEMA_VERSION}" = "1" ]; then
external_driver_legacy_tls_env=(
"OPENSHELL_PODMAN_TLS_CERT=${EXTERNAL_DRIVER_TLS_CERT}"
"OPENSHELL_PODMAN_TLS_KEY=${EXTERNAL_DRIVER_TLS_KEY}"
)
fi
if [ -n "${OPENSHELL_PARITY_LAUNCH_MANIFEST_CAPTURE:-}" ]; then
driver_transport=in_tree
external_driver_grpc_endpoint=null
external_driver_host_gateway_ip=null
external_driver_userns=null
external_driver_spiffe=false
external_driver_proxy=false
external_driver_app_armor=false
external_driver_environment=null
if [ "${OPENSHELL_E2E_EXTERNAL_COMPUTE_DRIVER:-0}" = "1" ]; then
driver_transport=remote_uds
external_driver_grpc_endpoint="\"${EXTERNAL_DRIVER_GRPC_ENDPOINT}\""
external_driver_host_gateway_ip='"host-gateway"'
driver_tls_ca_sha256="$(sha256sum "${EXTERNAL_DRIVER_TLS_CA}" | cut -d' ' -f1)"
legacy_tls_manifest=""
if [ "${CONFIG_SCHEMA_VERSION}" = "1" ]; then
driver_tls_cert_sha256="$(sha256sum "${EXTERNAL_DRIVER_TLS_CERT}" | cut -d' ' -f1)"
driver_tls_key_sha256="$(sha256sum "${EXTERNAL_DRIVER_TLS_KEY}" | cut -d' ' -f1)"
legacy_tls_manifest="$(printf ',"OPENSHELL_PODMAN_TLS_CERT":{"path":"%s","sha256":"%s"},"OPENSHELL_PODMAN_TLS_KEY":{"path":"%s","sha256":"%s"}' \
"${EXTERNAL_DRIVER_TLS_CERT}" "${driver_tls_cert_sha256}" \
"${EXTERNAL_DRIVER_TLS_KEY}" "${driver_tls_key_sha256}")"
fi
external_driver_environment="$(printf '{\"XDG_DATA_HOME\":\"%s\",\"OPENSHELL_COMPUTE_DRIVER_SOCKET\":\"%s\",\"OPENSHELL_PODMAN_SOCKET\":\"%s\",\"OPENSHELL_SANDBOX_IMAGE\":\"%s\",\"OPENSHELL_SANDBOX_IMAGE_PULL_POLICY\":\"%s\",\"OPENSHELL_HEALTH_CHECK_INTERVAL_SECS\":%s,\"OPENSHELL_GRPC_ENDPOINT\":\"%s\",\"OPENSHELL_GATEWAY_PORT\":%s,\"OPENSHELL_NETWORK_NAME\":\"%s\",\"OPENSHELL_STOP_TIMEOUT\":%s,\"OPENSHELL_SANDBOX_RUNTIME_IMAGE\":\"%s\",\"OPENSHELL_SUPERVISOR_IMAGE\":\"%s\",\"OPENSHELL_PODMAN_TLS_CA\":{\"path\":\"%s\",\"sha256\":\"%s\"}%s,\"OPENSHELL_ENABLE_BIND_MOUNTS\":%s}' \
"${DRIVER_DATA_HOME}" \
"${DRIVER_SOCKET}" \
"${OPENSHELL_PODMAN_SOCKET:-}" \
"${SANDBOX_IMAGE_REQUEST}" \
"${EXTERNAL_DRIVER_PULL_POLICY}" \
"${EXTERNAL_DRIVER_HEALTH_CHECK_INTERVAL_SECS}" \
"${EXTERNAL_DRIVER_GRPC_ENDPOINT}" \
"${HOST_PORT}" \
"${PODMAN_NETWORK_NAME}" \
"${PODMAN_STOP_TIMEOUT_SECS}" \
"${SANDBOX_BOUNDARY_IMAGE}" \
"${SUPERVISOR_RUNTIME_IMAGE}" \
"${EXTERNAL_DRIVER_TLS_CA}" \
"${driver_tls_ca_sha256}" \
"${legacy_tls_manifest}" \
"${EXTERNAL_DRIVER_ENABLE_BIND_MOUNTS}")"
fi
printf '{"schema_version":%s,"gateway_port":%s,"external_compute_driver":%s,"compute_driver_transport":"%s","external_driver_pull_policy":"%s","supervisor_image":"%s","supervisor_image_id":"%s","supervisor_image_digest":"%s","supervisor_runtime_image":"%s","supervisor_base_image":"%s","supervisor_base_image_id":"%s","supervisor_base_image_digest":"%s","supervisor_base_runtime_image":"%s","supervisor_package_manifest_sha256":"%s","sandbox_image_request":"%s","sandbox_image_id":"%s","sandbox_image_digest":"%s","sandbox_runtime_image":"%s","sandbox_boundary_image":"%s","sandbox_client_image_alias":"%s","sandbox_client_image_alias_id":"%s","gateway_sha256_before_execution":"%s","cli_sha256_before_execution":"%s","conformance_sha256_before_execution":"%s","external_driver_sha256_before_execution":"%s","supervisor_sha256_before_execution":"%s","supervisor_dockerfile_sha256_before_execution":"%s","cli_trace_wrapper_sha256_before_execution":"%s","external_driver_grpc_endpoint":%s,"external_driver_host_gateway_ip":%s,"external_driver_userns":%s,"external_driver_spiffe":%s,"external_driver_proxy":%s,"external_driver_app_armor":%s,"external_driver_environment":%s}\n' \
"${CONFIG_SCHEMA_VERSION}" \
"${HOST_PORT}" \
"$([ "${OPENSHELL_E2E_EXTERNAL_COMPUTE_DRIVER:-0}" = "1" ] && printf true || printf false)" \
"${driver_transport}" \
"${EXTERNAL_DRIVER_PULL_POLICY}" \
"${SUPERVISOR_IMAGE}" \
"${SUPERVISOR_IMAGE_ID}" \
"${SUPERVISOR_IMAGE_DIGEST}" \
"${SUPERVISOR_RUNTIME_IMAGE}" \
"${SUPERVISOR_BASE_IMAGE}" \
"${SUPERVISOR_BASE_IMAGE_ID}" \
"${SUPERVISOR_BASE_IMAGE_DIGEST}" \
"${OPENSHELL_E2E_SUPERVISOR_BASE_RUNTIME_IMAGE:-${SUPERVISOR_BASE_IMAGE%@*}@${SUPERVISOR_BASE_IMAGE_DIGEST}}" \
"${SUPERVISOR_PACKAGE_MANIFEST_SHA256}" \
"${SANDBOX_IMAGE_REQUEST}" \
"${SANDBOX_IMAGE_ID}" \
"${SANDBOX_IMAGE_DIGEST}" \
"${SANDBOX_RUNTIME_IMAGE}" \
"${SANDBOX_BOUNDARY_IMAGE}" \
"${SANDBOX_CLIENT_IMAGE_ALIAS}" \
"${SANDBOX_CLIENT_IMAGE_ALIAS_ID}" \
"${OPENSHELL_E2E_EXPECTED_GATEWAY_SHA256:-}" \
"${OPENSHELL_E2E_EXPECTED_CLI_SHA256:-}" \
"${OPENSHELL_E2E_EXPECTED_CONFORMANCE_SHA256:-}" \
"${OPENSHELL_E2E_EXPECTED_EXTERNAL_DRIVER_SHA256:-}" \
"${OPENSHELL_E2E_EXPECTED_SUPERVISOR_SHA256:-}" \
"${OPENSHELL_E2E_EXPECTED_SUPERVISOR_DOCKERFILE_SHA256:-}" \
"${OPENSHELL_E2E_EXPECTED_CLI_TRACE_WRAPPER_SHA256:-}" \
"${external_driver_grpc_endpoint}" \
"${external_driver_host_gateway_ip}" \
"${external_driver_userns}" \
"${external_driver_spiffe}" \
"${external_driver_proxy}" \
"${external_driver_app_armor}" \
"${external_driver_environment}" \
>"${OPENSHELL_PARITY_LAUNCH_MANIFEST_CAPTURE}"
fi
if [ "${OPENSHELL_E2E_EXTERNAL_COMPUTE_DRIVER:-0}" = "1" ]; then
require_expected_sha256 "external compute driver" "${DRIVER_BIN}" \
"${OPENSHELL_E2E_EXPECTED_EXTERNAL_DRIVER_SHA256:-}"
env -i \
XDG_DATA_HOME="${DRIVER_DATA_HOME}" \
OPENSHELL_COMPUTE_DRIVER_SOCKET="${DRIVER_SOCKET}" \
@@ -847,9 +572,8 @@ if [ "${OPENSHELL_E2E_EXTERNAL_COMPUTE_DRIVER:-0}" = "1" ]; then
OPENSHELL_NETWORK_NAME="${PODMAN_NETWORK_NAME}" \
OPENSHELL_STOP_TIMEOUT="${PODMAN_STOP_TIMEOUT_SECS}" \
OPENSHELL_SANDBOX_RUNTIME_IMAGE="${SANDBOX_BOUNDARY_IMAGE}" \
OPENSHELL_SUPERVISOR_IMAGE="${SUPERVISOR_RUNTIME_IMAGE}" \
OPENSHELL_SUPERVISOR_IMAGE="${SUPERVISOR_IMAGE}" \
OPENSHELL_PODMAN_TLS_CA="${EXTERNAL_DRIVER_TLS_CA}" \
"${external_driver_legacy_tls_env[@]}" \
OPENSHELL_ENABLE_BIND_MOUNTS="${EXTERNAL_DRIVER_ENABLE_BIND_MOUNTS}" \
"${DRIVER_BIN}" >"${DRIVER_LOG}" 2>&1 &
DRIVER_PID=$!
@@ -896,10 +620,8 @@ e2e_export_gateway_restart_metadata \
"${GATEWAY_LOG}" \
"${GATEWAY_PID_FILE}"
require_expected_sha256 "gateway binary" "${GATEWAY_BIN}" \
"${OPENSHELL_E2E_EXPECTED_GATEWAY_SHA256:-}"
OPENSHELL_LOCAL_TLS_DIR="${PKI_DIR}" \
OPENSHELL_SUPERVISOR_IMAGE="${SUPERVISOR_RUNTIME_IMAGE}" \
OPENSHELL_SUPERVISOR_IMAGE="${SUPERVISOR_IMAGE}" \
OPENSHELL_NETWORK_NAME="${PODMAN_NETWORK_NAME}" \
"${GATEWAY_BIN}" "${GATEWAY_ARGS[@]}" >"${GATEWAY_LOG}" 2>&1 &
GATEWAY_PID=$!
@@ -949,12 +671,6 @@ if [ "${elapsed}" -ge "${timeout}" ]; then
exit 1
fi
require_expected_sha256 "OpenShell CLI" "${CLI_BIN}" \
"${OPENSHELL_E2E_EXPECTED_CLI_SHA256:-}"
if [ -n "${OPENSHELL_E2E_EXPECTED_CONFORMANCE_SHA256:-}" ]; then
require_expected_sha256 "conformance CLI" "${OPENSHELL_CONFORMANCE_BIN}" \
"${OPENSHELL_E2E_EXPECTED_CONFORMANCE_SHA256}"
fi
# Seed the example profiles the provider tests rely on. The mTLS lanes already
# have a registered gateway identity; the OIDC lanes deliberately skip
# registration and have no token yet, so establish an administrator session
@@ -1,293 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Validate the schema-v2 live capability-parity manifest without a runtime."""
from __future__ import annotations
import re
import tomllib
from copy import deepcopy
from pathlib import Path
from typing import Any
import pytest
REPO_ROOT = Path(__file__).resolve().parents[2]
MANIFEST_PATH = REPO_ROOT / "e2e/configs/gateway/schema-v2-capability-parity.toml"
REQUIRED_MANIFEST_FIELDS = {
"manifest_version",
"baseline_ref",
"baseline_commit",
"baseline_schema_version",
"candidate_ref",
"candidate_commit",
"candidate_schema_version",
"capabilities",
}
REQUIRED_CAPABILITY_FIELDS = {
"id",
"topics",
"origin_main_access_paths",
"schema_v2_access_paths",
"behavioral_oracle",
"required_environment",
"test_lane",
"status",
}
REQUIRED_TOPICS = {
"auth_tls_jwt",
"configuration_producers",
"credentials",
"database",
"docker",
"external_drivers",
"inference",
"interceptors",
"kubernetes",
"listeners",
"middleware",
"mxc",
"observability",
"packaging_upgrades",
"podman",
"vm",
}
REQUIRED_CAPABILITY_IDS = {
"configuration-source-precedence",
"schema-version-and-strict-layout",
"gateway-identity-and-logging",
"primary-health-and-metrics-listeners",
"database-url-and-persistence-backends",
"ssh-rate-limit-and-policy-posture",
"sandbox-service-routing",
"gateway-listener-tls-and-sni",
"plaintext-listener-mode",
"guest-callback-tls-ownership",
"oidc-bearer-authentication",
"mtls-user-authentication",
"unsafe-unauthenticated-user-mode",
"gateway-minted-sandbox-jwt",
"otlp-observability",
"gateway-interceptor-registration",
"supervisor-middleware-registration",
"provider-profile-sources",
"inference-control-plane-configuration",
"credential-driver-selection-and-kek",
"credential-driver-backend-tables",
"docker-image-and-callback-configuration",
"docker-security-and-provider-configuration",
"podman-image-and-callback-configuration",
"podman-runtime-security-and-health",
"kubernetes-core-placement-and-images",
"kubernetes-workspace-isolation",
"kubernetes-supervisor-topology",
"kubernetes-egress-spiffe-and-security",
"vm-launch-and-resource-configuration",
"vm-guest-security-and-spiffe",
"mxc-windows-driver-configuration",
"external-compute-driver-socket",
"helm-configuration-producer",
"local-launch-script-producers",
"e2e-fixture-producers",
"rpm-schema-upgrade",
"homebrew-debian-and-snap-upgrades",
}
ALLOWED_LANES = {
"deterministic",
"e2e-docker",
"e2e-podman",
"e2e-kubernetes",
"e2e-vm",
"windows-mxc",
"extension-driver",
"auth-oidc",
"observability",
"packaging",
}
# This inventory plans execution. Live results belong in the execution record,
# not in this baseline manifest, so a PASS cannot be accidentally implied.
ALLOWED_STATUSES = {"not_run", "blocked", "planned"}
def load_manifest() -> dict[str, Any]:
with MANIFEST_PATH.open("rb") as manifest_file:
return tomllib.load(manifest_file)
def require_nonempty_string(value: Any, field: str, entry_id: str) -> None:
assert isinstance(value, str) and value.strip(), f"{entry_id}: {field} is required"
def require_string_list(value: Any, field: str, entry_id: str) -> None:
assert isinstance(value, list) and value, f"{entry_id}: {field} must be non-empty"
assert all(isinstance(item, str) and item.strip() for item in value), (
f"{entry_id}: {field} must contain only non-empty strings"
)
assert len(value) == len(set(value)), f"{entry_id}: {field} contains duplicates"
def validate_manifest(manifest: dict[str, Any]) -> None:
assert set(manifest) == REQUIRED_MANIFEST_FIELDS, (
"unexpected or missing manifest metadata"
)
assert manifest["manifest_version"] == 1
assert manifest["baseline_ref"] == "origin/main"
assert manifest["baseline_commit"] == "74960ebfaeec4673885089ed995fad902459749f"
assert manifest["baseline_schema_version"] == 1
assert manifest["candidate_ref"] == "HEAD"
assert manifest["candidate_commit"] == "8c868e430e9cd3284d7e274628419ab484ebcee0"
assert manifest["candidate_schema_version"] == 2
capabilities = manifest["capabilities"]
assert isinstance(capabilities, list) and capabilities, (
"capabilities must be non-empty"
)
ids: list[str] = []
topics: set[str] = set()
for capability in capabilities:
assert isinstance(capability, dict), "each capability must be a TOML table"
assert set(capability) == REQUIRED_CAPABILITY_FIELDS, (
"capability has unexpected or missing metadata"
)
entry_id = capability["id"]
require_nonempty_string(entry_id, "id", "capability")
ids.append(entry_id)
require_string_list(capability["topics"], "topics", entry_id)
topics.update(capability["topics"])
require_string_list(
capability["origin_main_access_paths"],
"origin_main_access_paths",
entry_id,
)
require_string_list(
capability["schema_v2_access_paths"],
"schema_v2_access_paths",
entry_id,
)
require_nonempty_string(
capability["behavioral_oracle"], "behavioral_oracle", entry_id
)
require_nonempty_string(
capability["required_environment"], "required_environment", entry_id
)
assert capability["test_lane"] in ALLOWED_LANES, (
f"{entry_id}: unknown test lane {capability['test_lane']!r}"
)
assert capability["status"] in ALLOWED_STATUSES, (
f"{entry_id}: live PASS results are not valid in this planning manifest"
)
assert len(ids) == len(set(ids)), "capability IDs must be unique"
assert set(ids) == REQUIRED_CAPABILITY_IDS, (
"capability inventory is incomplete or stale"
)
assert topics == REQUIRED_TOPICS, (
"topic inventory is incomplete or contains an unknown topic"
)
def capability_by_id(manifest: dict[str, Any], capability_id: str) -> dict[str, Any]:
return next(
capability
for capability in manifest["capabilities"]
if capability["id"] == capability_id
)
def test_schema_v2_capability_parity_manifest_is_well_formed() -> None:
validate_manifest(load_manifest())
def test_frozen_comparison_commits_are_full_git_object_ids() -> None:
manifest = load_manifest()
for field in ("baseline_commit", "candidate_commit"):
commit = manifest[field]
assert len(commit) == 40
assert all(character in "0123456789abcdef" for character in commit)
def test_vm_gateway_inventory_excludes_standalone_driver_only_fields() -> None:
capability = capability_by_id(
load_manifest(), "vm-launch-and-resource-configuration"
)
gateway_paths = " ".join(
capability["origin_main_access_paths"] + capability["schema_v2_access_paths"]
)
gateway_fields = set(re.findall(r"[a-z][a-z0-9_]*", gateway_paths))
for standalone_field in ("launcher_bin", "log_level", "gpu_enabled", "gpu_mem_mib"):
assert standalone_field not in gateway_fields
assert "driver_dir" in gateway_fields
def test_new_docker_capabilities_are_not_attributed_to_origin_main() -> None:
capability = capability_by_id(
load_manifest(), "docker-security-and-provider-configuration"
)
origin_paths = " ".join(capability["origin_main_access_paths"])
candidate_paths = " ".join(capability["schema_v2_access_paths"])
assert "no origin/main Docker equivalent" in origin_paths
for added_field in (
"https_proxy",
"provider_spiffe_workload_api_socket",
"app_armor_profile",
):
assert added_field not in origin_paths
assert added_field in candidate_paths
@pytest.mark.parametrize("field", sorted(REQUIRED_MANIFEST_FIELDS - {"capabilities"}))
def test_manifest_rejects_missing_header_metadata(field: str) -> None:
manifest = deepcopy(load_manifest())
del manifest[field]
with pytest.raises(AssertionError, match="missing manifest metadata"):
validate_manifest(manifest)
@pytest.mark.parametrize("field", sorted(REQUIRED_CAPABILITY_FIELDS - {"id"}))
def test_manifest_rejects_missing_capability_metadata(field: str) -> None:
manifest = deepcopy(load_manifest())
del manifest["capabilities"][0][field]
with pytest.raises(AssertionError, match=r"metadata|required|must be"):
validate_manifest(manifest)
@pytest.mark.parametrize(
("field", "value", "match"),
[
("topics", [], "must be non-empty"),
("behavioral_oracle", "", "is required"),
("required_environment", "", "is required"),
("test_lane", "not-a-lane", "unknown test lane"),
],
)
def test_manifest_rejects_malformed_capability_metadata(
field: str, value: Any, match: str
) -> None:
manifest = deepcopy(load_manifest())
manifest["capabilities"][0][field] = value
with pytest.raises(AssertionError, match=match):
validate_manifest(manifest)
def test_manifest_rejects_duplicate_capability_id() -> None:
manifest = deepcopy(load_manifest())
manifest["capabilities"][1]["id"] = manifest["capabilities"][0]["id"]
with pytest.raises(AssertionError, match=r"unique|incomplete"):
validate_manifest(manifest)
def test_manifest_does_not_claim_live_pass_results() -> None:
manifest = deepcopy(load_manifest())
manifest["capabilities"][0]["status"] = "pass"
with pytest.raises(AssertionError, match="live PASS"):
validate_manifest(manifest)
@@ -1,489 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Exercise the retained-artifact verifier used by schema-v2 Step 10."""
from __future__ import annotations
import importlib.util
import json
from pathlib import Path
from typing import TYPE_CHECKING
import pytest
if TYPE_CHECKING:
from types import ModuleType
REPO_ROOT = Path(__file__).resolve().parents[2]
VERIFIER_PATH = REPO_ROOT / "e2e/parity/verify-results.py"
BASELINE_SHA = "1" * 40
CANDIDATE_SHA = "2" * 40
IMAGE_ID = "3" * 64
IMAGE_DIGEST = f"sha256:{'4' * 64}"
RUNTIME_IMAGE = f"localhost/openshell/supervisor@{IMAGE_DIGEST}"
BOUNDARY_IMAGE = f"localhost/openshell/sandbox@{IMAGE_DIGEST}"
BASE_RUNTIME_IMAGE = f"docker.io/library/alpine@{IMAGE_DIGEST}"
def load_verifier() -> ModuleType:
spec = importlib.util.spec_from_file_location("parity_verifier", VERIFIER_PATH)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def write_json(path: Path, value: object) -> None:
path.write_text(json.dumps(value) + "\n", encoding="utf-8")
def create_variant(
verifier: ModuleType,
results_dir: Path,
variant: str,
source_sha: str,
schema_version: int,
) -> None:
artifact_dir = results_dir / "artifacts" / variant
artifact_dir.mkdir(parents=True)
artifacts = {
"gateway": f"{variant}-gateway",
"cli": f"{variant}-cli",
"conformance": f"{variant}-conformance",
"supervisor": f"{variant}-supervisor",
"supervisor.Dockerfile": f"{variant}-dockerfile",
"cli-trace-wrapper": "shared-cli-trace-wrapper",
"external-driver": f"{variant}-external-driver",
"supervisor.packages.txt": "fixture-package-1.0-r0\n",
}
for filename, content in artifacts.items():
(artifact_dir / filename).write_text(content, encoding="utf-8")
write_json(
results_dir / f"{variant}.json",
{
"variant": variant,
"source_sha": source_sha,
"schema_version": schema_version,
"driver": "podman",
"scenario": "external-driver",
"gateway_profile": "driver-free",
"gateway_cargo_features": "--no-default-features --features telemetry",
"gateway_origin": "built_by_harness",
"cli_origin": "built_by_harness",
"conformance_origin": "built_by_harness",
"external_driver_origin": "built_by_harness",
"supervisor_origin": "built_by_harness",
"gateway_sha256": verifier.sha256(artifact_dir / "gateway"),
"cli_sha256": verifier.sha256(artifact_dir / "cli"),
"conformance_sha256": verifier.sha256(artifact_dir / "conformance"),
"supervisor_sha256": verifier.sha256(artifact_dir / "supervisor"),
"supervisor_dockerfile_sha256": verifier.sha256(
artifact_dir / "supervisor.Dockerfile"
),
"cli_trace_wrapper_sha256": verifier.sha256(
artifact_dir / "cli-trace-wrapper"
),
"external_driver_sha256": verifier.sha256(artifact_dir / "external-driver"),
"success": True,
},
)
selector = (
'compute_drivers = ["podman"]'
if schema_version == 1
else 'compute_driver = "podman"'
)
(results_dir / f"{variant}.gateway.toml").write_text(
f"""[openshell]
version = {schema_version}
[openshell.gateway]
{selector}
[openshell.drivers.podman]
socket_path = "/tmp/{variant}.sock"
""",
encoding="utf-8",
)
policy = "missing" if schema_version == 1 else "if_not_present"
package_hash = verifier.sha256(artifact_dir / "supervisor.packages.txt")
result = json.loads((results_dir / f"{variant}.json").read_text(encoding="utf-8"))
legacy_tls_environment = {}
if schema_version == 1:
legacy_tls_environment = {
"OPENSHELL_PODMAN_TLS_CERT": {
"path": f"/tmp/{variant}-pki/tls.crt",
"sha256": "9" * 64,
},
"OPENSHELL_PODMAN_TLS_KEY": {
"path": f"/tmp/{variant}-pki/tls.key",
"sha256": "a" * 64,
},
}
write_json(
results_dir / f"{variant}.launch.json",
{
"schema_version": schema_version,
"gateway_port": 18181,
"external_compute_driver": True,
"compute_driver_transport": "remote_uds",
"external_driver_pull_policy": policy,
"supervisor_image_id": IMAGE_ID,
"supervisor_image_digest": IMAGE_DIGEST,
"supervisor_runtime_image": RUNTIME_IMAGE,
"supervisor_base_image": "alpine:fixture",
"supervisor_base_image_id": IMAGE_ID,
"supervisor_base_image_digest": IMAGE_DIGEST,
"supervisor_base_runtime_image": BASE_RUNTIME_IMAGE,
"supervisor_package_manifest_sha256": package_hash,
"sandbox_image_request": "example.invalid/sandbox@" + IMAGE_DIGEST,
"sandbox_image_id": IMAGE_ID,
"sandbox_image_digest": IMAGE_DIGEST,
"sandbox_runtime_image": "example.invalid/sandbox@" + IMAGE_DIGEST,
"sandbox_boundary_image": BOUNDARY_IMAGE,
"sandbox_client_image_alias": "example.invalid/sandbox:latest",
"sandbox_client_image_alias_id": IMAGE_ID,
"gateway_sha256_before_execution": result["gateway_sha256"],
"cli_sha256_before_execution": result["cli_sha256"],
"conformance_sha256_before_execution": result["conformance_sha256"],
"external_driver_sha256_before_execution": result["external_driver_sha256"],
"supervisor_sha256_before_execution": result["supervisor_sha256"],
"supervisor_dockerfile_sha256_before_execution": result[
"supervisor_dockerfile_sha256"
],
"cli_trace_wrapper_sha256_before_execution": result[
"cli_trace_wrapper_sha256"
],
"external_driver_grpc_endpoint": "https://127.0.0.1:18181",
"external_driver_host_gateway_ip": "host-gateway",
"external_driver_userns": None,
"external_driver_spiffe": False,
"external_driver_proxy": False,
"external_driver_app_armor": False,
"external_driver_environment": {
"XDG_DATA_HOME": f"/tmp/{variant}-driver-data",
"OPENSHELL_COMPUTE_DRIVER_SOCKET": f"/tmp/{variant}.sock",
"OPENSHELL_PODMAN_SOCKET": f"/tmp/{variant}-podman.sock",
"OPENSHELL_SANDBOX_IMAGE": "example.invalid/sandbox@" + IMAGE_DIGEST,
"OPENSHELL_SANDBOX_IMAGE_PULL_POLICY": policy,
"OPENSHELL_HEALTH_CHECK_INTERVAL_SECS": 10,
"OPENSHELL_GRPC_ENDPOINT": "https://127.0.0.1:18181",
"OPENSHELL_GATEWAY_PORT": 18181,
"OPENSHELL_NETWORK_NAME": f"{variant}-network",
"OPENSHELL_STOP_TIMEOUT": 15,
"OPENSHELL_SANDBOX_RUNTIME_IMAGE": BOUNDARY_IMAGE,
"OPENSHELL_SUPERVISOR_IMAGE": RUNTIME_IMAGE,
"OPENSHELL_PODMAN_TLS_CA": {
"path": f"/tmp/{variant}-pki/ca.crt",
"sha256": "8" * 64,
},
**legacy_tls_environment,
"OPENSHELL_ENABLE_BIND_MOUNTS": True,
},
},
)
lifecycle = "\n".join(
f"[run fixture{marker} in 1ms: exit 0" for marker in verifier.ORACLE_MARKERS
)
(results_dir / f"{variant}.log").write_text(
f"CLI conformance run ID: fixture\n"
f"gateway preflight connected: gateway=fixture, authentication=authenticated\n"
f"{lifecycle}\n{RUNTIME_IMAGE} {BOUNDARY_IMAGE} {BASE_RUNTIME_IMAGE} example.invalid/sandbox@{IMAGE_DIGEST} example.invalid/sandbox:latest "
f'{IMAGE_ID} {IMAGE_DIGEST} {package_hash}\n"passed": true\n',
encoding="utf-8",
)
(results_dir / f"{variant}.exec.stdout").write_bytes(
b"openshell-conformance-fixture\n"
)
write_json(
results_dir / f"{variant}.conformance.json",
{
"scenarios": [{"name": "smoke", "passed": True, "diagnostic": None}],
"passed": True,
},
)
(results_dir / f"{variant}.driver.log").write_text(
"external driver fixture started\n", encoding="utf-8"
)
def create_external_bundle(verifier: ModuleType, results_dir: Path) -> None:
create_variant(verifier, results_dir, "baseline", BASELINE_SHA, 1)
create_variant(verifier, results_dir, "candidate", CANDIDATE_SHA, 2)
write_json(
results_dir / "comparison.json",
{
"scenario": "external-driver",
"baseline_success": True,
"candidate_success": True,
"parity": True,
"accepted": True,
"classification": "pass",
},
)
def test_single_scenario_verifier_accepts_bound_supplied_artifacts(
tmp_path: Path,
) -> None:
verifier = load_verifier()
create_external_bundle(verifier, tmp_path)
(tmp_path / "comparison.json").unlink()
for variant in ("baseline", "candidate"):
result_path = tmp_path / f"{variant}.json"
result = json.loads(result_path.read_text(encoding="utf-8"))
for field in (
"gateway_origin",
"cli_origin",
"conformance_origin",
"external_driver_origin",
"supervisor_origin",
):
result[field] = "supplied_override"
write_json(result_path, result)
report = verifier.verify_topology(
tmp_path,
BASELINE_SHA,
CANDIDATE_SHA,
"external-driver",
verify_comparison=False,
require_built_artifacts=False,
)
assert report["comparison_sha256"] is None
assert report["baseline"]["raw_output_verified"] is True
assert report["candidate"]["artifacts_verified"] is True
assert report["candidate"]["conformance_report_verified"] is True
def test_single_scenario_verifier_rejects_failed_conformance_report(
tmp_path: Path,
) -> None:
verifier = load_verifier()
create_external_bundle(verifier, tmp_path)
report_path = tmp_path / "candidate.conformance.json"
report = json.loads(report_path.read_text(encoding="utf-8"))
report["scenarios"][0]["passed"] = False
report["scenarios"][0]["diagnostic"] = "fixture failure"
report["passed"] = False
write_json(report_path, report)
with pytest.raises(ValueError, match="conformance report did not pass"):
verifier.verify_topology(
tmp_path,
BASELINE_SHA,
CANDIDATE_SHA,
"external-driver",
verify_comparison=False,
require_built_artifacts=False,
)
def test_verifier_recomputes_retained_artifact_hashes(tmp_path: Path) -> None:
verifier = load_verifier()
create_external_bundle(verifier, tmp_path)
report = verifier.verify_topology(
tmp_path, BASELINE_SHA, CANDIDATE_SHA, "external-driver"
)
assert report["baseline"]["artifacts_verified"] is True
assert report["candidate"]["raw_output_verified"] is True
(tmp_path / "artifacts/candidate/gateway").write_text(
"mutated after execution", encoding="utf-8"
)
with pytest.raises(ValueError, match="retained artifact hash mismatch"):
verifier.verify_topology(
tmp_path, BASELINE_SHA, CANDIDATE_SHA, "external-driver"
)
def test_verifier_rejects_mutable_sandbox_request(tmp_path: Path) -> None:
verifier = load_verifier()
create_external_bundle(verifier, tmp_path)
launch_path = tmp_path / "candidate.launch.json"
launch = json.loads(launch_path.read_text(encoding="utf-8"))
launch["sandbox_image_request"] = "example.invalid/sandbox:latest"
write_json(launch_path, launch)
with pytest.raises(
ValueError, match="request was not the resolved digest reference"
):
verifier.verify_topology(
tmp_path, BASELINE_SHA, CANDIDATE_SHA, "external-driver"
)
def test_verifier_rejects_different_sandbox_artifacts(tmp_path: Path) -> None:
verifier = load_verifier()
create_external_bundle(verifier, tmp_path)
launch_path = tmp_path / "candidate.launch.json"
launch = json.loads(launch_path.read_text(encoding="utf-8"))
other_id = "5" * 64
other_digest = f"sha256:{'6' * 64}"
other_runtime = f"example.invalid/sandbox@{other_digest}"
launch.update(
{
"sandbox_image_request": other_runtime,
"sandbox_image_id": other_id,
"sandbox_image_digest": other_digest,
"sandbox_runtime_image": other_runtime,
"sandbox_client_image_alias_id": other_id,
}
)
launch["external_driver_environment"]["OPENSHELL_SANDBOX_IMAGE"] = other_runtime
write_json(launch_path, launch)
with (tmp_path / "candidate.log").open("a", encoding="utf-8") as log:
log.write(f"{other_id} {other_digest} {other_runtime}\n")
with pytest.raises(ValueError, match="sandbox image ID differ"):
verifier.verify_topology(
tmp_path, BASELINE_SHA, CANDIDATE_SHA, "external-driver"
)
def test_verifier_rejects_different_supervisor_packages(tmp_path: Path) -> None:
verifier = load_verifier()
create_external_bundle(verifier, tmp_path)
package_path = tmp_path / "artifacts/candidate/supervisor.packages.txt"
package_path.write_text("fixture-package-2.0-r0\n", encoding="utf-8")
package_hash = verifier.sha256(package_path)
launch_path = tmp_path / "candidate.launch.json"
launch = json.loads(launch_path.read_text(encoding="utf-8"))
launch["supervisor_package_manifest_sha256"] = package_hash
write_json(launch_path, launch)
with (tmp_path / "candidate.log").open("a", encoding="utf-8") as log:
log.write(f"{package_hash}\n")
with pytest.raises(ValueError, match="supervisor package manifest differ"):
verifier.verify_topology(
tmp_path, BASELINE_SHA, CANDIDATE_SHA, "external-driver"
)
def test_verifier_rejects_unattested_external_driver_input(tmp_path: Path) -> None:
verifier = load_verifier()
create_external_bundle(verifier, tmp_path)
launch_path = tmp_path / "candidate.launch.json"
launch = json.loads(launch_path.read_text(encoding="utf-8"))
del launch["external_driver_environment"]["OPENSHELL_STOP_TIMEOUT"]
write_json(launch_path, launch)
with pytest.raises(ValueError, match="allowlisted environment is incomplete"):
verifier.verify_topology(
tmp_path, BASELINE_SHA, CANDIDATE_SHA, "external-driver"
)
def test_verifier_binds_gateway_and_driver_uds(tmp_path: Path) -> None:
verifier = load_verifier()
create_external_bundle(verifier, tmp_path)
launch_path = tmp_path / "candidate.launch.json"
launch = json.loads(launch_path.read_text(encoding="utf-8"))
launch["external_driver_environment"]["OPENSHELL_COMPUTE_DRIVER_SOCKET"] = (
"/tmp/different.sock"
)
write_json(launch_path, launch)
with pytest.raises(ValueError, match="driver socket differs from gateway TOML"):
verifier.verify_topology(
tmp_path, BASELINE_SHA, CANDIDATE_SHA, "external-driver"
)
def test_verifier_rejects_reused_external_uds(tmp_path: Path) -> None:
verifier = load_verifier()
create_external_bundle(verifier, tmp_path)
launch_path = tmp_path / "candidate.launch.json"
launch = json.loads(launch_path.read_text(encoding="utf-8"))
launch["external_driver_environment"]["OPENSHELL_COMPUTE_DRIVER_SOCKET"] = (
"/tmp/baseline.sock"
)
write_json(launch_path, launch)
config_path = tmp_path / "candidate.gateway.toml"
config_path.write_text(
config_path.read_text(encoding="utf-8").replace(
"/tmp/candidate.sock", "/tmp/baseline.sock"
),
encoding="utf-8",
)
with pytest.raises(ValueError, match="reuse the same external compute-driver UDS"):
verifier.verify_topology(
tmp_path, BASELINE_SHA, CANDIDATE_SHA, "external-driver"
)
def test_verifier_requires_exact_exec_stdout(tmp_path: Path) -> None:
verifier = load_verifier()
create_external_bundle(verifier, tmp_path)
(tmp_path / "candidate.exec.stdout").write_text("wrong marker\n", encoding="utf-8")
with pytest.raises(ValueError, match="stdout is not the exact marker"):
verifier.verify_topology(
tmp_path, BASELINE_SHA, CANDIDATE_SHA, "external-driver"
)
def test_verifier_requires_authenticated_preflight(tmp_path: Path) -> None:
verifier = load_verifier()
create_external_bundle(verifier, tmp_path)
log_path = tmp_path / "candidate.log"
log_path.write_text(
log_path.read_text(encoding="utf-8").replace(
"authentication=authenticated", "authentication=unauthenticated"
),
encoding="utf-8",
)
with pytest.raises(ValueError, match="authenticated gateway preflight is missing"):
verifier.verify_topology(
tmp_path, BASELINE_SHA, CANDIDATE_SHA, "external-driver"
)
def test_verifier_rejects_cross_topology_sandbox_drift() -> None:
verifier = load_verifier()
launch = {
"sandbox_image_id": IMAGE_ID,
"sandbox_image_digest": IMAGE_DIGEST,
"sandbox_runtime_image": "example.invalid/sandbox@" + IMAGE_DIGEST,
"sandbox_client_image_alias": "example.invalid/sandbox:latest",
"sandbox_client_image_alias_id": IMAGE_ID,
"supervisor_base_image": "alpine:fixture",
"supervisor_base_image_id": IMAGE_ID,
"supervisor_base_image_digest": IMAGE_DIGEST,
"supervisor_base_runtime_image": BASE_RUNTIME_IMAGE,
"supervisor_package_manifest_sha256": "7" * 64,
}
shared_artifacts = {
"cli": "b" * 64,
"conformance": "c" * 64,
"supervisor": "d" * 64,
"supervisor.Dockerfile": "e" * 64,
"cli-trace-wrapper": "f" * 64,
}
in_tree = {
"baseline": {
"launch_attestation": dict(launch),
"artifact_sha256": dict(shared_artifacts),
},
"candidate": {
"launch_attestation": dict(launch),
"artifact_sha256": dict(shared_artifacts),
},
}
external = {
"baseline": {
"launch_attestation": dict(launch),
"artifact_sha256": dict(shared_artifacts),
},
"candidate": {
"launch_attestation": dict(launch),
"artifact_sha256": dict(shared_artifacts),
},
}
external["candidate"]["launch_attestation"]["sandbox_image_id"] = "8" * 64
with pytest.raises(ValueError, match="four runs use different sandbox artifact"):
verifier.verify_four_run_provenance(in_tree, external)
@@ -1,173 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Validate schema-v2 Step 11 cross-cutting capability dispositions."""
from __future__ import annotations
import hashlib
import re
import tomllib
from pathlib import Path
from typing import Any
REPO_ROOT = Path(__file__).resolve().parents[2]
DISPOSITIONS_PATH = (
REPO_ROOT / "e2e/configs/gateway/schema-v2-cross-cutting-dispositions.toml"
)
CAPABILITY_PATH = REPO_ROOT / "e2e/configs/gateway/schema-v2-capability-parity.toml"
INTENTIONAL_CHANGES_PATH = (
REPO_ROOT / "e2e/configs/gateway/schema-v2-intentional-changes.toml"
)
STEP_11_CAPABILITY_IDS = {
"credential-driver-backend-tables",
"credential-driver-selection-and-kek",
"gateway-interceptor-registration",
"gateway-minted-sandbox-jwt",
"inference-control-plane-configuration",
"mtls-user-authentication",
"oidc-bearer-authentication",
"otlp-observability",
"provider-profile-sources",
"supervisor-middleware-registration",
"unsafe-unauthenticated-user-mode",
}
EXPECTED_SUITES = {
"server-lib": "cargo test -q -p openshell-server --lib",
"gateway-interceptors": "cargo test -q -p openshell-gateway-interceptors",
"supervisor-middleware": "cargo test -q -p openshell-supervisor-middleware",
"otel-test-support": "cargo test -q -p openshell-otel-test-support",
"multiplex-tls-integration": (
"cargo test -q -p openshell-server --test multiplex_tls_integration"
),
"edge-tunnel-auth": "cargo test -q -p openshell-server --test edge_tunnel_auth",
}
EXPECTED_CANDIDATE_COMMIT = "363d8540830b2ea294d43198daa2b7a283a2face"
EXPECTED_INTENTIONAL_CHANGES = {
"gateway-jwt-zero-sentinel-removed": "gateway-minted-sandbox-jwt",
"middleware-payload-name-normalized": "supervisor-middleware-registration",
}
def load_toml(path: Path) -> dict[str, Any]:
with path.open("rb") as toml_file:
return tomllib.load(toml_file)
def assert_full_sha(value: object, field: str) -> str:
assert isinstance(value, str), f"{field} must be a string"
assert re.fullmatch(r"[0-9a-f]{40}", value), f"{field} must be a full SHA"
return value
def test_step_11_dispositions_cover_exact_cross_cutting_capabilities() -> None:
manifest = load_toml(DISPOSITIONS_PATH)
assert set(manifest) == {
"manifest_version",
"baseline_commit",
"candidate_commit",
"overall_status",
"deterministic_preflight",
"capabilities",
}
assert manifest["manifest_version"] == 1
assert manifest["overall_status"] == "platform_blocked"
assert (
assert_full_sha(manifest["baseline_commit"], "baseline_commit")
== load_toml(CAPABILITY_PATH)["baseline_commit"]
)
assert (
assert_full_sha(manifest["candidate_commit"], "candidate_commit")
== EXPECTED_CANDIDATE_COMMIT
)
capabilities = manifest["capabilities"]
assert {entry["id"] for entry in capabilities} == STEP_11_CAPABILITY_IDS
assert len(capabilities) == len(STEP_11_CAPABILITY_IDS)
for entry in capabilities:
assert set(entry) == {"id", "status", "owner", "lane", "blocker"}
assert entry["status"] == "platform_blocked"
assert all(entry[field].strip() for field in ("owner", "lane"))
assert len(entry["blocker"]) >= 160
def test_step_11_capability_ids_exist_in_inventory() -> None:
inventory_ids = {
entry["id"] for entry in load_toml(CAPABILITY_PATH)["capabilities"]
}
assert inventory_ids >= STEP_11_CAPABILITY_IDS
def test_deterministic_preflight_is_not_reported_as_live_parity() -> None:
manifest = load_toml(DISPOSITIONS_PATH)
preflight = manifest["deterministic_preflight"]
assert set(preflight) == {
"status",
"baseline_attestation",
"baseline_attestation_sha256",
"candidate_attestation",
"candidate_attestation_sha256",
"commands",
"evidence",
}
assert preflight["status"] == "pass"
assert set(preflight["commands"]) == set(EXPECTED_SUITES.values())
assert len(preflight["commands"]) == len(EXPECTED_SUITES)
assert len(preflight["evidence"]) >= 4
assert all(item.strip() for item in preflight["evidence"])
assert manifest["overall_status"] == "platform_blocked"
assert all(
entry["status"] == "platform_blocked" for entry in manifest["capabilities"]
)
attestations = {
"baseline": manifest["baseline_commit"],
"candidate": manifest["candidate_commit"],
}
for variant, source_commit in attestations.items():
path_field = f"{variant}_attestation"
digest_field = f"{variant}_attestation_sha256"
path = REPO_ROOT / preflight[path_field]
assert path.is_file(), f"missing tracked Step 11 attestation: {path}"
assert re.fullmatch(r"[0-9a-f]{64}", preflight[digest_field])
assert hashlib.sha256(path.read_bytes()).hexdigest() == preflight[digest_field]
attestation = path.read_text(encoding="utf-8")
assert "schema_v2_step11_deterministic_attestation_version=1\n" in attestation
assert f"variant={variant}\n" in attestation
assert f"source_commit={source_commit}\n" in attestation
assert "source_tree_clean=true\n" in attestation
assert "cargo_target_scope=checkout-local\n" in attestation
assert "rustc_wrapper=disabled\n" in attestation
assert attestation.endswith("\nattestation_complete=true\n")
suite_sections = {}
for section in attestation.split("\n=== suite:")[1:]:
suite, separator, body = section.partition(" ===\n")
assert separator
assert suite not in suite_sections
suite_sections[suite] = body
assert set(suite_sections) == set(EXPECTED_SUITES)
for suite, command in EXPECTED_SUITES.items():
section = suite_sections[suite]
assert section.startswith(f"command={command} \n--- output ---\n")
assert section.count("--- exit_status:0 ---") == 1
assert "--- exit_status:" not in section.replace(
"--- exit_status:0 ---", ""
)
def test_step_11_representation_changes_remain_in_intentional_change_ledger() -> None:
changes = {
entry["id"]: entry
for entry in load_toml(INTENTIONAL_CHANGES_PATH)["intentional_changes"]
}
for change_id, capability_id in EXPECTED_INTENTIONAL_CHANGES.items():
assert change_id in changes
change = changes[change_id]
assert change["parity_disposition"] == "intentional_change"
assert capability_id in change["validation_capability_ids"]
@@ -1,158 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Validate the explicit schema-v2 intentional-change ledger."""
from __future__ import annotations
import tomllib
from pathlib import Path
from typing import Any
REPO_ROOT = Path(__file__).resolve().parents[2]
LEDGER_PATH = REPO_ROOT / "e2e/configs/gateway/schema-v2-intentional-changes.toml"
CAPABILITY_PATH = REPO_ROOT / "e2e/configs/gateway/schema-v2-capability-parity.toml"
REQUIRED_HEADER_FIELDS = {
"ledger_version",
"issue",
"baseline_commit",
"candidate_start_commit",
"intentional_changes",
}
REQUIRED_CHANGE_FIELDS = {
"id",
"category",
"origin_main_contract",
"schema_v2_contract",
"migration",
"rationale",
"parity_disposition",
"validation_capability_ids",
}
REQUIRED_CHANGE_IDS = {
"canonical-image-pull-policy",
"docker-sandbox-label-rename",
"driver-table-exclusive-ownership",
"gateway-jwt-zero-sentinel-removed",
"guest-tls-centralized",
"kubernetes-fields-relocated",
"middleware-payload-name-normalized",
"package-default-only-auto-migration",
"podman-health-zero-sentinel-removed",
"podman-pid-limit-restored",
"podman-ssh-socket-rename",
"sandbox-pid-zero-sentinel-removed",
"schema-version-cutover",
"singular-compute-driver-selector",
"vm-grpc-endpoint-rename",
"vm-sandbox-identity-selection",
}
ALLOWED_CATEGORIES = {
"bug_fix",
"cardinality",
"default_behavior",
"migration_policy",
"ownership",
"relocation",
"rename",
"rename_with_alias",
"schema_cutover",
"sentinel_removal",
"type_normalization",
}
def load_toml(path: Path) -> dict[str, Any]:
with path.open("rb") as toml_file:
return tomllib.load(toml_file)
def require_nonempty_string(value: Any, field: str, change_id: str) -> None:
assert isinstance(value, str) and value.strip(), f"{change_id}: {field} is required"
def test_intentional_change_ledger_is_complete_and_well_formed() -> None:
ledger = load_toml(LEDGER_PATH)
assert set(ledger) == REQUIRED_HEADER_FIELDS
assert ledger["ledger_version"] == 1
assert ledger["issue"] == 2792
assert ledger["baseline_commit"] == "74960ebfaeec4673885089ed995fad902459749f"
assert ledger["candidate_start_commit"] == (
"8c868e430e9cd3284d7e274628419ab484ebcee0"
)
changes = ledger["intentional_changes"]
assert isinstance(changes, list) and changes
ids: list[str] = []
for change in changes:
assert set(change) == REQUIRED_CHANGE_FIELDS
change_id = change["id"]
require_nonempty_string(change_id, "id", "intentional change")
ids.append(change_id)
assert change["category"] in ALLOWED_CATEGORIES
assert change["parity_disposition"] == "intentional_change"
for field in (
"origin_main_contract",
"schema_v2_contract",
"migration",
"rationale",
):
require_nonempty_string(change[field], field, change_id)
capability_ids = change["validation_capability_ids"]
assert isinstance(capability_ids, list) and capability_ids
assert len(capability_ids) == len(set(capability_ids))
assert len(ids) == len(set(ids))
assert set(ids) == REQUIRED_CHANGE_IDS
def test_every_intentional_change_links_to_known_capabilities() -> None:
ledger = load_toml(LEDGER_PATH)
capabilities = load_toml(CAPABILITY_PATH)["capabilities"]
known_capability_ids = {capability["id"] for capability in capabilities}
for change in ledger["intentional_changes"]:
assert set(change["validation_capability_ids"]) <= known_capability_ids, (
f"{change['id']}: unknown validation capability"
)
def test_ledger_does_not_hide_known_unresolved_parity_gaps() -> None:
ledger = load_toml(LEDGER_PATH)
change_ids = {change["id"] for change in ledger["intentional_changes"]}
assert "legacy-environment-selector-upgrade" not in change_ids
assert "tls-require-client-auth-ignored" not in change_ids
assert "debian-snap-v1-upgrade" not in change_ids
def test_singular_selector_ledger_preserves_auto_detection() -> None:
ledger = load_toml(LEDGER_PATH)
selector = next(
change
for change in ledger["intentional_changes"]
if change["id"] == "singular-compute-driver-selector"
)
assert "omission retains built-in auto-detection" in selector["schema_v2_contract"]
assert "unsupported multi-driver operation" in selector["rationale"]
def test_operator_edited_package_configuration_is_never_auto_rewritten() -> None:
ledger = load_toml(LEDGER_PATH)
package_policy = next(
change
for change in ledger["intentional_changes"]
if change["id"] == "package-default-only-auto-migration"
)
contract = package_policy["schema_v2_contract"]
assert "byte-identical package defaults" in contract
assert "Debian and Snap preserve every legacy file" in contract
assert "fail closed through read-only package preflight" in contract
assert "manual-migration guidance" in contract
assert "no safe provenance marker" in contract
assert "preserve every edited file" in package_policy["migration"]
assert "manual schema-v2 conversion" in package_policy["migration"]
@@ -1,139 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Validate field-level Step 8 Kubernetes parity dispositions."""
import json
import re
import tomllib
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
LEDGER = (
ROOT
/ "e2e"
/ "configs"
/ "gateway"
/ "schema-v2-kubernetes-option-dispositions.toml"
)
CAPABILITIES = ROOT / "e2e" / "configs" / "gateway" / "schema-v2-capability-parity.toml"
LIVE_RESULTS = ROOT / "e2e" / "configs" / "gateway" / "schema-v2-live-results.toml"
KUBERNETES_CAPABILITY_IDS = {
"kubernetes-core-placement-and-images",
"kubernetes-workspace-isolation",
"kubernetes-supervisor-topology",
"kubernetes-egress-spiffe-and-security",
}
FIELD_GROUP = re.compile(
r"\[openshell\.(?P<table>gateway|drivers\.kubernetes(?:\.(?P<subtable>[a-z_]+))?)\]"
r"\.\{(?P<fields>[^}]+)\}"
)
def load_ledger() -> dict:
with LEDGER.open("rb") as handle:
return tomllib.load(handle)
def manifest_kubernetes_fields() -> set[str]:
with CAPABILITIES.open("rb") as handle:
capabilities = tomllib.load(handle)["capabilities"]
fields: set[str] = set()
for capability in capabilities:
if capability["id"] not in KUBERNETES_CAPABILITY_IDS:
continue
for access_path in [
*capability["origin_main_access_paths"],
*capability["schema_v2_access_paths"],
]:
for match in FIELD_GROUP.finditer(access_path):
table = match.group("table")
if table == "gateway" and "inherited by Kubernetes" not in access_path:
continue
prefix = (
f"{match.group('subtable')}." if match.group("subtable") else ""
)
fields.update(
f"{prefix}{field.strip()}"
for field in match.group("fields").split(",")
)
return fields
def test_kubernetes_ledger_covers_every_manifest_driver_field_once() -> None:
ledger = load_ledger()
coverage = ledger["coverage"]
observed = [field for entry in coverage for field in entry["fields"]]
assert set(observed) == manifest_kubernetes_fields()
assert len(observed) == len(set(observed))
def test_kubernetes_core_pass_is_paired_and_qualified_checks_stay_blocked() -> None:
ledger = load_ledger()
core = next(entry for entry in ledger["coverage"] if entry["status"] == "pass")
assert core["id"] == "shared-combined-core"
assert len(core["evidence"]) >= 3
assert ledger["baseline_commit"] == "74960ebfaeec4673885089ed995fad902459749f"
assert len(ledger["validated_candidate_commit"]) == 40
comparison_path = ROOT / ledger["core_comparison"]
comparison = json.loads(comparison_path.read_text())
assert comparison == {
"accepted": True,
"baseline_commit": ledger["baseline_commit"],
"baseline_success": True,
"candidate_commit": ledger["validated_candidate_commit"],
"candidate_success": True,
"classification": "pass",
"parity": True,
}
with LIVE_RESULTS.open("rb") as handle:
live_results = tomllib.load(handle)["result"]
live_core = next(
result
for result in live_results
if result["id"] == "kubernetes-core-option-parity"
)
assert live_core["status"] == comparison["classification"]
assert live_core["validated_baseline_commit"] == comparison["baseline_commit"]
assert live_core["validated_candidate_commit"] == comparison["candidate_commit"]
blocked = [
entry
for entry in [*ledger["coverage"], *ledger["qualified_value"]]
if entry["status"] == "platform_blocked"
]
assert blocked
for entry in blocked:
assert entry["owner"]
assert entry["lane"]
assert entry["requirement"]
def test_environment_qualified_security_checks_are_not_claimed_by_core() -> None:
ledger = load_ledger()
blocked_fields = {
field
for entry in ledger["coverage"]
if entry["status"] == "platform_blocked"
for field in entry["fields"]
}
qualified = {entry["id"] for entry in ledger["qualified_value"]}
assert {
"enable_user_namespaces",
"https_proxy",
"proxy_auth_secret_name",
"provider_spiffe_workload_api_socket_path",
"sidecar.proxy_uid",
} <= blocked_fields
assert {
"apparmor-enforcement",
"gpu-resource-combinations",
"image-volume-sideload",
"managed-and-operator-workspace-values",
"runtime-class-isolation",
"sidecar-topology-value",
} <= qualified
@@ -1,449 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Validate machine-readable schema-v2 live parity results."""
from __future__ import annotations
import hashlib
import json
import re
import subprocess
import tomllib
from pathlib import Path
from typing import Any
REPO_ROOT = Path(__file__).resolve().parents[2]
RESULTS_PATH = REPO_ROOT / "e2e/configs/gateway/schema-v2-live-results.toml"
CAPABILITY_PATH = REPO_ROOT / "e2e/configs/gateway/schema-v2-capability-parity.toml"
COMPUTE_BOUNDARY_PATH = (
REPO_ROOT / "e2e/configs/gateway/schema-v2-compute-boundary-comparison.json"
)
CROSS_CUTTING_DISPOSITIONS_PATH = (
REPO_ROOT / "e2e/configs/gateway/schema-v2-cross-cutting-dispositions.toml"
)
REQUIRED_HEADER_FIELDS = {
"manifest_version",
"baseline_commit",
"candidate_start_commit",
"result",
}
REQUIRED_STEP_5_IDS = {
"portable-lifecycle-docker",
"portable-lifecycle-kubernetes",
"portable-lifecycle-mxc",
"portable-lifecycle-podman",
"portable-lifecycle-vm",
}
REQUIRED_STEP_6_IDS = {
"gateway-tls-client-auth-policy",
"gateway-wide-process-options",
}
REQUIRED_STEP_7_IDS = {
"docker-driver-option-parity",
"podman-driver-option-parity",
"podman-qualified-security-option-parity",
}
REQUIRED_STEP_8_IDS = {
"kubernetes-core-option-parity",
"kubernetes-qualified-option-parity",
}
REQUIRED_STEP_9_IDS = {
"vm-guest-security-and-spiffe",
"vm-launch-and-resource-configuration",
}
REQUIRED_STEP_10_IDS = {"compute-driver-boundary-parity"}
REQUIRED_STEP_11_IDS = {
"credential-driver-backend-tables",
"credential-driver-selection-and-kek",
"gateway-interceptor-registration",
"gateway-minted-sandbox-jwt",
"inference-control-plane-configuration",
"mtls-user-authentication",
"oidc-bearer-authentication",
"otlp-observability",
"provider-profile-sources",
"supervisor-middleware-registration",
"unsafe-unauthenticated-user-mode",
}
REQUIRED_STEP_12_IDS = {
"debian-package-upgrade",
"homebrew-package-upgrade",
"rpm-package-upgrade",
"snap-package-refresh",
}
EXPECTED_EXECUTED_CANDIDATE_COMMITS = {
"portable-lifecycle-podman": "a3860084d019ed2ac979e3eaa1ddf085a96b773c",
"gateway-wide-process-options": "e6aac1aa7c624c5df43535ab4fbe2bc6f9697dea",
"gateway-tls-client-auth-policy": "e6aac1aa7c624c5df43535ab4fbe2bc6f9697dea",
"podman-driver-option-parity": "e09070d4ba0b30f0ac278fbb9938c1520ecff696",
"kubernetes-core-option-parity": "0f08b5822e4da98c9ced3d4b0f2bf4f30dae28fd",
"compute-driver-boundary-parity": "4a39da510e4d278a24dd60291149519c9a570b46",
}
STEP_10_CANDIDATE_COMMIT = EXPECTED_EXECUTED_CANDIDATE_COMMITS[
"compute-driver-boundary-parity"
]
STEP_10_REPORT_SHA256 = (
"3c1297eef6c0a3b22530b980b571bda2d967a39a79a3e3286bcc09e30df84bf3"
)
STEP_10_EVIDENCE_BUNDLES = {
"in_tree": "target/parity/step10-intree-4a39da51",
"external_uds": "target/parity/step10-external-4a39da51",
}
ALLOWED_STATUSES = {
"pass",
"intentional_change",
"regression",
"platform_blocked",
}
BASE_FIELDS = {"id", "step", "capability", "driver", "status", "lane"}
PASS_FIELDS = {
"validated_baseline_commit",
"validated_candidate_commit",
"evidence",
}
BLOCKED_FIELDS = {"owner", "blocker"}
def load_toml(path: Path) -> dict[str, Any]:
with path.open("rb") as toml_file:
return tomllib.load(toml_file)
def assert_full_sha(value: object, field: str) -> str:
assert isinstance(value, str), f"{field} must be a string"
assert len(value) == 40 and all(char in "0123456789abcdef" for char in value), (
f"{field} must be a full lowercase SHA"
)
return value
def test_live_results_manifest_is_well_formed() -> None:
manifest = load_toml(RESULTS_PATH)
assert set(manifest) == REQUIRED_HEADER_FIELDS
assert manifest["manifest_version"] == 1
baseline = assert_full_sha(manifest["baseline_commit"], "baseline_commit")
assert_full_sha(manifest["candidate_start_commit"], "candidate_start_commit")
assert baseline == load_toml(CAPABILITY_PATH)["baseline_commit"]
results = manifest["result"]
assert isinstance(results, list) and results
ids: list[str] = []
for result in results:
assert set(result) >= BASE_FIELDS
result_id = result["id"]
assert isinstance(result_id, str) and result_id.strip()
ids.append(result_id)
assert result["status"] in ALLOWED_STATUSES
assert isinstance(result["step"], int) and 1 <= result["step"] <= 15
for field in ("capability", "driver", "lane"):
assert isinstance(result[field], str) and result[field].strip(), (
f"{result_id}: {field} is required"
)
assert len(ids) == len(set(ids))
def test_step_5_covers_every_in_tree_compute_driver() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 5
]
assert {result["id"] for result in results} == REQUIRED_STEP_5_IDS
assert {result["driver"] for result in results} == {
"docker",
"kubernetes",
"mxc",
"podman",
"vm",
}
def test_executed_results_pin_commits_and_evidence() -> None:
manifest = load_toml(RESULTS_PATH)
executed = {
result["id"]: result
for result in manifest["result"]
if result["status"] in {"pass", "intentional_change"}
}
assert set(executed) == set(EXPECTED_EXECUTED_CANDIDATE_COMMITS)
for result_id, result in executed.items():
assert set(result) >= PASS_FIELDS, result_id
assert result["validated_baseline_commit"] == manifest["baseline_commit"]
candidate = assert_full_sha(
result["validated_candidate_commit"],
f"{result_id}.validated_candidate_commit",
)
assert candidate == EXPECTED_EXECUTED_CANDIDATE_COMMITS[result_id]
assert isinstance(result["evidence"], list) and result["evidence"]
assert all(
isinstance(item, str) and item.strip() for item in result["evidence"]
)
# These immutable SHAs bind the original live-validation artifacts.
# A later history-preserving source rebase can intentionally make those
# exact execution commits non-ancestors without changing the evidence.
def test_step_6_records_gateway_option_and_tls_dispositions() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 6
]
assert {result["id"] for result in results} == REQUIRED_STEP_6_IDS
statuses = {result["id"]: result["status"] for result in results}
assert statuses["gateway-wide-process-options"] == "pass"
assert statuses["gateway-tls-client-auth-policy"] == "intentional_change"
def test_step_7_records_driver_option_dispositions() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 7
]
assert {result["id"] for result in results} == REQUIRED_STEP_7_IDS
statuses = {result["id"]: result["status"] for result in results}
assert statuses["podman-driver-option-parity"] == "intentional_change"
assert statuses["docker-driver-option-parity"] == "platform_blocked"
assert statuses["podman-qualified-security-option-parity"] == "platform_blocked"
def test_step_8_records_kubernetes_option_dispositions() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 8
]
assert {result["id"] for result in results} == REQUIRED_STEP_8_IDS
statuses = {result["id"]: result["status"] for result in results}
assert statuses["kubernetes-core-option-parity"] == "pass"
assert statuses["kubernetes-qualified-option-parity"] == "platform_blocked"
def test_step_9_records_vm_runtime_dispositions() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 9
]
assert {result["id"] for result in results} == REQUIRED_STEP_9_IDS
assert all(result["status"] == "platform_blocked" for result in results)
assert all(result["driver"] == "vm" for result in results)
def test_step_10_records_verified_compute_boundary_parity(tmp_path: Path) -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 10
]
assert {result["id"] for result in results} == REQUIRED_STEP_10_IDS
assert results[0]["status"] == "pass"
with COMPUTE_BOUNDARY_PATH.open(encoding="utf-8") as report_file:
report = json.load(report_file)
assert report["manifest_version"] == 2
assert report["baseline_commit"] == load_toml(RESULTS_PATH)["baseline_commit"]
assert report["candidate_commit"] == results[0]["validated_candidate_commit"]
assert report["candidate_commit"] == STEP_10_CANDIDATE_COMMIT
assert report["retained_evidence_bundles"] == STEP_10_EVIDENCE_BUNDLES
assert (
hashlib.sha256(COMPUTE_BOUNDARY_PATH.read_bytes()).hexdigest()
== STEP_10_REPORT_SHA256
)
assert report["classification"] == "pass"
assert report["accepted"] is True
assert all(report["oracle"].values())
assert all(report["verification"].values())
launch_attestations = []
for topology_name in ("in_tree", "external_uds"):
topology = report[topology_name]
assert topology["classification"] == "pass"
assert topology["parity"] is True
assert topology["accepted"] is True
assert re.fullmatch(r"[0-9a-f]{64}", topology["comparison_sha256"])
baseline_launch = topology["baseline"]["launch_attestation"]
candidate_launch = topology["candidate"]["launch_attestation"]
for field in (
"sandbox_image_id",
"sandbox_image_digest",
"sandbox_runtime_image",
"supervisor_base_image",
"supervisor_base_image_id",
"supervisor_base_image_digest",
"supervisor_package_manifest_sha256",
):
assert baseline_launch[field] == candidate_launch[field]
launch_attestations.extend((baseline_launch, candidate_launch))
for variant_name, schema_version in (("baseline", 1), ("candidate", 2)):
variant = topology[variant_name]
assert variant["schema_version"] == schema_version
assert variant["success"] is True
assert variant["artifacts_verified"] is True
assert variant["raw_output_verified"] is True
assert all(
re.fullmatch(r"[0-9a-f]{64}", digest)
for digest in variant["artifact_sha256"].values()
)
assert all(
re.fullmatch(r"[0-9a-f]{64}", digest)
for digest in variant["raw_evidence_sha256"].values()
)
launch = variant["launch_attestation"]
supervisor_digest = launch["supervisor_image_digest"]
assert re.fullmatch(r"sha256:[0-9a-f]{64}", supervisor_digest)
assert launch["supervisor_runtime_image"].endswith(f"@{supervisor_digest}")
sandbox_digest = launch["sandbox_image_digest"]
assert re.fullmatch(r"sha256:[0-9a-f]{64}", sandbox_digest)
assert launch["sandbox_image_request"] == launch["sandbox_runtime_image"]
assert launch["sandbox_runtime_image"].endswith(f"@{sandbox_digest}")
for field in (
"sandbox_image_id",
"sandbox_image_digest",
"sandbox_runtime_image",
"supervisor_base_image",
"supervisor_base_image_id",
"supervisor_base_image_digest",
"supervisor_base_runtime_image",
"supervisor_package_manifest_sha256",
"supervisor_dockerfile_sha256_before_execution",
):
assert len({launch[field] for launch in launch_attestations}) == 1, field
external_sockets = []
for variant_name in ("baseline", "candidate"):
external_variant = report["external_uds"][variant_name]
external_launch = external_variant["launch_attestation"]
assert external_launch["compute_driver_transport"] == "remote_uds"
assert external_launch["external_compute_driver"] is True
assert external_launch["external_driver_grpc_endpoint"].startswith("https://")
assert external_launch["external_driver_host_gateway_ip"] == "host-gateway"
assert external_launch["external_driver_userns"] is None
assert external_launch["external_driver_spiffe"] is False
assert external_launch["external_driver_proxy"] is False
assert external_launch["external_driver_app_armor"] is False
driver_environment = external_launch["external_driver_environment"]
assert driver_environment["OPENSHELL_COMPUTE_DRIVER_SOCKET"]
assert driver_environment["OPENSHELL_PODMAN_SOCKET"]
assert driver_environment["OPENSHELL_GRPC_ENDPOINT"].startswith("https://")
assert driver_environment["OPENSHELL_ENABLE_BIND_MOUNTS"] is True
for tls_field in (
"OPENSHELL_PODMAN_TLS_CA",
"OPENSHELL_PODMAN_TLS_CERT",
"OPENSHELL_PODMAN_TLS_KEY",
):
assert re.fullmatch(
r"[0-9a-f]{64}", driver_environment[tls_field]["sha256"]
)
external_sockets.append(driver_environment["OPENSHELL_COMPUTE_DRIVER_SOCKET"])
assert f"{variant_name}.driver.log" in external_variant["raw_evidence_sha256"]
assert f"{variant_name}.exec.stdout" in external_variant["raw_evidence_sha256"]
assert len(set(external_sockets)) == 2
evidence_paths = {
name: REPO_ROOT / relative_path
for name, relative_path in STEP_10_EVIDENCE_BUNDLES.items()
}
present = {name: path.is_dir() for name, path in evidence_paths.items()}
assert len(set(present.values())) == 1, "Step 10 retained evidence is incomplete"
if all(present.values()):
reproduced = tmp_path / "schema-v2-compute-boundary-comparison.json"
subprocess.run(
[
"python3",
str(REPO_ROOT / "e2e/parity/verify-results.py"),
"--baseline-sha",
report["baseline_commit"],
"--candidate-sha",
STEP_10_CANDIDATE_COMMIT,
"--in-tree",
STEP_10_EVIDENCE_BUNDLES["in_tree"],
"--external-uds",
STEP_10_EVIDENCE_BUNDLES["external_uds"],
"--output",
str(reproduced),
],
cwd=REPO_ROOT,
check=True,
)
assert reproduced.read_bytes() == COMPUTE_BOUNDARY_PATH.read_bytes()
def test_step_11_records_cross_cutting_live_lane_dispositions() -> None:
results = {
result["id"]: result
for result in load_toml(RESULTS_PATH)["result"]
if result["step"] == 11
}
dispositions = {
entry["id"]: entry
for entry in load_toml(CROSS_CUTTING_DISPOSITIONS_PATH)["capabilities"]
}
assert set(results) == REQUIRED_STEP_11_IDS
assert set(dispositions) == REQUIRED_STEP_11_IDS
for result_id, result in results.items():
disposition = dispositions[result_id]
assert result["status"] == "platform_blocked"
for field in ("status", "owner", "lane", "blocker"):
assert result[field] == disposition[field]
def test_step_12_keeps_real_package_upgrade_lanes_blocked() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 12
]
assert {result["id"] for result in results} == REQUIRED_STEP_12_IDS
assert all(result["status"] == "platform_blocked" for result in results)
by_id = {result["id"]: result for result in results}
rpm = by_id["rpm-package-upgrade"]
assert rpm["owner"] == "OpenShell RPM package upgrade CI lane"
assert rpm["lane"] == "fedora-rpm-prior-release-upgrade"
assert "prior RPM" in rpm["blocker"]
assert "installed and upgraded" in rpm["blocker"]
debian = by_id["debian-package-upgrade"]
assert debian["owner"] == "OpenShell Debian package upgrade CI lane"
assert debian["lane"] == "ubuntu-debian-prior-release-upgrade"
assert "installed prior Debian artifact" in debian["blocker"]
assert "source-tree tests" in debian["blocker"]
snap = by_id["snap-package-refresh"]
assert snap["owner"] == "OpenShell Snap refresh CI lane"
assert snap["lane"] == "ubuntu-snap-prior-release-refresh"
assert "refresh confined Snap revisions" in snap["blocker"]
assert "source-tree tests" in snap["blocker"]
homebrew = by_id["homebrew-package-upgrade"]
assert homebrew["owner"] == "OpenShell macOS Homebrew package upgrade CI lane"
assert homebrew["lane"] == "macos-homebrew-prior-release-upgrade"
assert "prior-release upgrade" in homebrew["blocker"]
assert "Linux host" in homebrew["blocker"]
def test_platform_blocked_results_name_owner_lane_and_blocker() -> None:
for result in load_toml(RESULTS_PATH)["result"]:
if result["status"] != "platform_blocked":
continue
assert set(result) >= BLOCKED_FIELDS, result["id"]
assert isinstance(result["owner"], str) and result["owner"].strip()
assert isinstance(result["blocker"], str) and len(result["blocker"]) >= 80
def test_step_5_records_only_executed_podman_as_pass() -> None:
statuses = {
result["driver"]: result["status"]
for result in load_toml(RESULTS_PATH)["result"]
if result["step"] == 5
}
assert statuses["podman"] == "pass"
assert all(
status == "platform_blocked"
for driver, status in statuses.items()
if driver != "podman"
)
@@ -1,195 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Validate schema-v2 parity-gap dispositions and release blockers."""
from __future__ import annotations
import tomllib
from pathlib import Path
from typing import Any
REPO_ROOT = Path(__file__).resolve().parents[2]
GAP_LEDGER_PATH = (
REPO_ROOT / "e2e/configs/gateway/schema-v2-parity-gap-dispositions.toml"
)
LIVE_RESULTS_PATH = REPO_ROOT / "e2e/configs/gateway/schema-v2-live-results.toml"
REQUIRED_HEADER_FIELDS = {
"ledger_version",
"issue",
"baseline_commit",
"candidate_start_commit",
"gaps",
}
REQUIRED_GAP_FIELDS = {
"id",
"severity",
"parity_relation",
"disposition",
"origin_main_behavior",
"candidate_behavior",
"impact",
"resolution",
"validation",
"owner_step",
}
REQUIRED_GAP_IDS = {
"debian-snap-v1-upgrade",
"gateway-owned-guest-tls",
"generated-e2e-selector-shape",
"legacy-environment-selector-upgrade",
"multi-driver-runtime-loss",
"rpm-exact-default-migration",
"tls-require-client-auth-ignored",
"unselected-driver-validation-claim",
}
ALLOWED_SEVERITIES = {"blocker", "major", "minor", "none"}
ALLOWED_RELATIONS = {
"documentation_gap",
"non_finding",
"preexisting_inaccessible_option",
"regression",
"upgrade_regression",
}
ALLOWED_DISPOSITIONS = {
"documentation_fix_required",
"must_fix_before_parity",
"must_fix_before_release_gate",
"must_fix_or_remove_claim",
"no_action",
"resolved",
}
def load_ledger() -> dict[str, Any]:
with GAP_LEDGER_PATH.open("rb") as ledger_file:
return tomllib.load(ledger_file)
def test_gap_disposition_ledger_is_complete_and_well_formed() -> None:
ledger = load_ledger()
assert set(ledger) == REQUIRED_HEADER_FIELDS
assert ledger["ledger_version"] == 1
assert ledger["issue"] == 2792
assert ledger["baseline_commit"] == "74960ebfaeec4673885089ed995fad902459749f"
assert ledger["candidate_start_commit"] == (
"8c868e430e9cd3284d7e274628419ab484ebcee0"
)
gaps = ledger["gaps"]
assert isinstance(gaps, list) and gaps
ids: list[str] = []
for gap in gaps:
assert set(gap) == REQUIRED_GAP_FIELDS
gap_id = gap["id"]
assert isinstance(gap_id, str) and gap_id.strip()
ids.append(gap_id)
assert gap["severity"] in ALLOWED_SEVERITIES
assert gap["parity_relation"] in ALLOWED_RELATIONS
assert gap["disposition"] in ALLOWED_DISPOSITIONS
assert isinstance(gap["owner_step"], int) and 1 <= gap["owner_step"] <= 15
for field in (
"origin_main_behavior",
"candidate_behavior",
"impact",
"resolution",
"validation",
):
assert isinstance(gap[field], str) and gap[field].strip(), (
f"{gap_id}: {field} is required"
)
assert len(ids) == len(set(ids))
assert set(ids) == REQUIRED_GAP_IDS
def test_every_blocker_has_a_required_fix_and_validation() -> None:
for gap in load_ledger()["gaps"]:
if gap["severity"] != "blocker":
continue
assert gap["disposition"].startswith("must_fix")
assert gap["owner_step"] in {6, 12}
assert len(gap["resolution"]) >= 80
assert len(gap["validation"]) >= 80
def test_non_findings_do_not_require_product_changes() -> None:
for gap in load_ledger()["gaps"]:
if gap["parity_relation"] == "non_finding":
assert gap["severity"] == "none"
assert gap["disposition"] == "no_action"
def test_security_sensitive_tls_gap_records_reviewed_resolution() -> None:
tls_gap = next(
gap
for gap in load_ledger()["gaps"]
if gap["id"] == "tls-require-client-auth-ignored"
)
assert tls_gap["parity_relation"] == "preexisting_inaccessible_option"
assert tls_gap["disposition"] == "resolved"
assert "Security review" in tls_gap["resolution"]
assert "rejects require_client_auth" in tls_gap["candidate_behavior"]
def test_step_6_gap_dispositions_are_resolved() -> None:
step_6_gaps = [gap for gap in load_ledger()["gaps"] if gap["owner_step"] == 6]
assert {gap["id"] for gap in step_6_gaps} == {
"legacy-environment-selector-upgrade",
"tls-require-client-auth-ignored",
"unselected-driver-validation-claim",
}
assert all(gap["severity"] == "none" for gap in step_6_gaps)
assert all(gap["disposition"] == "resolved" for gap in step_6_gaps)
def test_step_12_product_gaps_are_resolved_without_claiming_live_package_parity() -> (
None
):
step_12_gaps = [gap for gap in load_ledger()["gaps"] if gap["owner_step"] == 12]
assert {gap["id"] for gap in step_12_gaps} == {
"debian-snap-v1-upgrade",
"rpm-exact-default-migration",
}
debian_snap = next(
gap for gap in step_12_gaps if gap["id"] == "debian-snap-v1-upgrade"
)
assert debian_snap["severity"] == "none"
assert debian_snap["disposition"] == "resolved"
assert "source-free, read-only preflight" in debian_snap["candidate_behavior"]
assert "fail closed" in debian_snap["resolution"]
assert "manual migration" in debian_snap["resolution"]
assert "no safe default-provenance marker" in debian_snap["resolution"]
assert "platform-blocked" in debian_snap["validation"]
with LIVE_RESULTS_PATH.open("rb") as results_file:
package_results = {
result["id"]: result
for result in tomllib.load(results_file)["result"]
if result["step"] == 12
}
for result_id in (
"debian-package-upgrade",
"homebrew-package-upgrade",
"rpm-package-upgrade",
"snap-package-refresh",
):
assert package_results[result_id]["status"] == "platform_blocked"
def test_legacy_environment_resolution_preserves_singular_semantics() -> None:
legacy_gap = next(
gap
for gap in load_ledger()["gaps"]
if gap["id"] == "legacy-environment-selector-upgrade"
)
assert "one non-empty OPENSHELL_DRIVERS value" in legacy_gap["resolution"]
assert "rejects multiple values" in legacy_gap["resolution"]
assert "conflicting canonical and legacy values" in legacy_gap["resolution"]
-33
View File
@@ -1,33 +0,0 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
["test:e2e-parity"]
description = "Run deterministic schema-v1/schema-v2 parity harness tests"
run = "bash e2e/parity/test.sh"
run_windows = "powershell -NoProfile -ExecutionPolicy Bypass -File tasks/scripts/run-git-bash.ps1 e2e/parity/test.sh"
hide = true
["e2e:parity:podman"]
description = "Compare frozen schema-v1 and current schema-v2 conformance against Podman and retain a fresh evidence directory (opt-in live test)"
run = "bash e2e/parity/run.sh --driver podman"
["e2e:parity:podman-options"]
description = "Compare paired Podman sandbox option semantics and retain a fresh evidence directory (opt-in live test)"
run = "bash e2e/parity/run.sh --driver podman --scenario podman-options"
["e2e:parity:podman-external-driver"]
description = "Compare paired external Podman lifecycle semantics and retain a fresh evidence directory (opt-in live test)"
run = "bash e2e/parity/run.sh --driver podman --scenario external-driver"
["e2e:parity:gateway-options"]
description = "Compare process-level gateway option behavior across schema v1 and v2 (opt-in live test)"
run = "bash e2e/parity/gateway-options.sh"
["test:e2e-parity:kubernetes-options"]
description = "Run deterministic Kubernetes schema parity harness tests"
run = "bash e2e/parity/kubernetes-options-test.sh"
hide = true
["e2e:parity:kubernetes-options"]
description = "Compare Kubernetes driver options on an explicitly supplied disposable kind cluster"
run = "bash e2e/parity/kubernetes-options.sh"
+43
View File
@@ -31,4 +31,47 @@ CAPTURED_CONFIG="${WORK}/generated.toml" PATH="${WORK}/bin:${PATH}" KUBERNETES_S
printf '%s\n' 'import sys, tomllib' 'from pathlib import Path' 'config = tomllib.loads(Path(sys.argv[1]).read_text())' 'gateway = config["openshell"]["gateway"]' 'driver = config["openshell"]["drivers"]["kubernetes"]' 'assert config["openshell"]["version"] == 2' 'assert gateway["compute_driver"] == "kubernetes"' 'assert "compute_drivers" not in gateway' 'assert driver["image_pull_policy"] == "if_not_present"' 'assert driver["grpc_endpoint"] == "https://callback.example.test:9443"' > "${WORK}/check_generated.py"
"${UV}" run --no-project python "${WORK}/check_generated.py" "${CAPTURED_CONFIG}"
# Keep the Podman E2E generator on the current gateway schema and preserve the
# in-tree versus external-driver ownership boundary without starting Podman.
# shellcheck source=e2e/support/gateway-common.sh
source "${ROOT}/e2e/support/gateway-common.sh"
# shellcheck source=e2e/support/podman-gateway-config.sh
source "${ROOT}/e2e/support/podman-gateway-config.sh"
mkdir -p "${WORK}/pki/client" "${WORK}/jwt"
e2e_write_podman_gateway_config \
"${WORK}/podman.toml" "${ROOT}" "${WORK}/pki" "${WORK}/jwt" \
test-gateway 0 "${WORK}/driver.sock" test-network 18181 \
workload:test 15 supervisor:test sandbox:test "${WORK}/spiffe.sock" \
"${WORK}/podman.sock" 0 ""
e2e_write_podman_gateway_config \
"${WORK}/podman-external.toml" "${ROOT}" "${WORK}/pki" "${WORK}/jwt" \
test-gateway 1 "${WORK}/driver.sock" test-network 18181 \
workload:test 15 supervisor:test sandbox:test "${WORK}/spiffe.sock" \
"${WORK}/podman.sock" 0 ""
printf '%s\n' \
'import sys, tomllib' \
'from pathlib import Path' \
'internal = tomllib.loads(Path(sys.argv[1]).read_text())' \
'external = tomllib.loads(Path(sys.argv[2]).read_text())' \
'assert internal["openshell"]["version"] == 2' \
'gateway = internal["openshell"]["gateway"]' \
'driver = internal["openshell"]["drivers"]["podman"]' \
'assert gateway["compute_driver"] == "podman"' \
'assert gateway["guest_tls_ca"].endswith("/pki/ca.crt")' \
'assert driver["default_image"] == "workload:test"' \
'assert driver["image_pull_policy"] == "if_not_present"' \
'assert driver["supervisor_image"] == "supervisor:test"' \
'assert driver["sandbox_runtime_image"] == "sandbox:test"' \
'assert driver["provider_spiffe_workload_api_socket"].endswith("/spiffe.sock")' \
'assert driver["socket_path"].endswith("/podman.sock")' \
'assert driver["resource_admission"] == {"enabled": False}' \
'external_driver = external["openshell"]["drivers"]["podman"]' \
'assert external["openshell"]["gateway"]["guest_tls_ca"].endswith("/pki/ca.crt")' \
'assert external_driver == {"socket_path": sys.argv[3]}' \
>"${WORK}/check_podman_generated.py"
"${UV}" run --no-project python "${WORK}/check_podman_generated.py" \
"${WORK}/podman.toml" "${WORK}/podman-external.toml" "${WORK}/driver.sock"
echo "gateway generated-TOML tests passed"
-1
View File
@@ -15,7 +15,6 @@ depends = [
"test:gateway-pull-policy",
"test:e2e-image-overrides",
"test:gateway-config",
"test:e2e-parity",
"test:packaging-assets",
"test:qualification-summary",
"test:codex-security-release-range",