Skip to content
Closed
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
7a7daf5
feat(onboard): add hosted inference to portable profile
ericksoa Aug 7, 2026
27e493f
feat(onboard): support activated portable credentials
ericksoa Aug 7, 2026
442e8c7
test(onboard): tighten portable inference isolation
ericksoa Aug 7, 2026
75766ca
fix(onboard): skip portable dashboard forwards
ericksoa Aug 7, 2026
e2a45b8
fix(onboard): require portable hosted inference
ericksoa Aug 7, 2026
ab85412
fix(onboard): secure portable inference bootstrap
ericksoa Aug 7, 2026
3a2c90c
merge: resolve conflicts with main
github-actions[bot] Aug 7, 2026
a2deec5
fix(onboard): apply personal policy for portable profile
ericksoa Aug 7, 2026
b62b3be
fix(onboard): bound portable personal policy
ericksoa Aug 7, 2026
8703856
Revert "fix(onboard): bound portable personal policy"
ericksoa Aug 7, 2026
8fcfb17
fix(policy): recover from policy-set transport resets
ericksoa Aug 7, 2026
bb2f814
chore: keep transport recovery production-only
ericksoa Aug 7, 2026
9d95523
fix(onboard): use basic portable network policy
ericksoa Aug 7, 2026
268d391
fix(onboard): install compact portable policy set
ericksoa Aug 7, 2026
beb7b2b
fix(onboard): use balanced portable policy tier
ericksoa Aug 7, 2026
cc6b7c1
fix(policy): compose personal tier for openshell 0.0.99
ericksoa Aug 7, 2026
4c3fac4
chore(deps): upgrade openshell to 0.0.101
ericksoa Aug 7, 2026
4de5086
fix(onboard): recover portable resume lifecycle
ericksoa Aug 7, 2026
5718a06
fix(build): handle rootless perl icmp tests
ericksoa Aug 7, 2026
7f5d758
fix(build): avoid intentional perl crash popup
ericksoa Aug 7, 2026
9e40284
fix(portable): preserve gateway state on resume
ericksoa Aug 7, 2026
413df3f
fix(installer): restore portable build input
ericksoa Aug 8, 2026
ce4c02d
fix(portable): reopen authoritative gateway state
ericksoa Aug 8, 2026
f4f0937
fix(portable): enroll committed sandbox container
ericksoa Aug 8, 2026
1bfb3c7
fix(portable): discover exact OpenShell container
ericksoa Aug 8, 2026
3fd5d1d
fix(portable): resolve Docker-owned sandbox container
ericksoa Aug 8, 2026
e969c9f
fix(portable): match OpenShell Podman labels
ericksoa Aug 8, 2026
a98754e
Merge branch 'main' into feat/portable-remote-inference-bootstrap
cv Aug 8, 2026
76a8d5d
fix(portable): recover replaced sandbox containers
ericksoa Aug 8, 2026
6f08ad7
fix(portable): always restart GFN sandbox
ericksoa Aug 8, 2026
5d70484
merge: resolve conflicts with main
github-actions[bot] Aug 8, 2026
75e4341
fix(portable): persist Podman container metadata
ericksoa Aug 8, 2026
e014b1e
fix(portable): keep Podman state in durable home
ericksoa Aug 8, 2026
84dde51
fix(portable): isolate Podman image cache
ericksoa Aug 8, 2026
bad3134
fix(portable): persist complete Podman store
ericksoa Aug 8, 2026
64779f0
fix(portable): remove registry on uninstall
ericksoa Aug 8, 2026
434f35b
fix(portable): remove UID-mapped stores
ericksoa Aug 8, 2026
1f94fde
fix(portable): recover stale Podman namespace
ericksoa Aug 8, 2026
793a339
fix(portable): retry Podman 5.4 migration panic
ericksoa Aug 8, 2026
9cf097f
fix(portable): pin OpenShell 0.0.85
ericksoa Aug 8, 2026
4e3f478
fix(portable): restore podman run state on resume
ericksoa Aug 8, 2026
82ccbc9
fix(portable): isolate OpenShell 0.0.85 fallback
ericksoa Aug 8, 2026
1d08909
fix(onboard): restore dashboard registration variable
ericksoa Aug 8, 2026
270df38
fix(portable): restore receipt container run directory
ericksoa Aug 8, 2026
f4a0e76
fix(portable): restore video-era OpenShell 0.0.85 runtime
ericksoa Aug 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,7 @@ jobs:
E2E_ARTIFACT_DIR: ${{ github.workspace }}/e2e-artifacts/live/openshell-gateway-auth-contract
NEMOCLAW_RUN_LIVE_E2E: "1"
NEMOCLAW_NON_INTERACTIVE: "1"
NEMOCLAW_OPENSHELL_PIN_VERSION: "0.0.99"
NEMOCLAW_OPENSHELL_PIN_VERSION: "0.0.101"
DOCKER_GRPC_PROBE_IMAGE: "node:22-trixie-slim@sha256:e6d9a389d34ff9678438af985c9913fbd1eb6ed36e80fea56644f4b4f6dd70ba"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down Expand Up @@ -1087,7 +1087,7 @@ jobs:
NEMOCLAW_OPENSHELL_CHANNEL: stable
NEMOCLAW_OPENSHELL_EXACT_MAIN_PROOF: "1"
NEMOCLAW_RUN_LIVE_E2E: "1"
OPENSHELL_DOCKER_SUPERVISOR_IMAGE: ghcr.io/nvidia/openshell/supervisor@sha256:ea3632b6e9528e2309103af5b6949606fcdc83ca1f69e8db81482a25bea84bb6
OPENSHELL_DOCKER_SUPERVISOR_IMAGE: ghcr.io/nvidia/openshell/supervisor@sha256:b58be5e40c788977ffa0e8305a8cad9c656efdf1a3fe182582a00ca870bb0edb
steps:
- id: trusted_hermes_swap
name: Provision trusted Hermes E2E swap
Expand Down Expand Up @@ -1340,12 +1340,12 @@ jobs:
jq -n '{
schemaVersion: 1,
sourceRepository: "NVIDIA/OpenShell",
releaseTag: "v0.0.99",
sourceSha: "8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032",
releaseTag: "v0.0.101",
sourceSha: "8ddd98c3dff62619a3963f99ba1e055b67650e72",
artifacts: {
cli: {binarySha256: "5c0dabb90152a3cfae9005731771da99f00a22403080c81952c7be8ba4b5728f"},
gateway: {binarySha256: "05bd6c982dd72b73364b91ab694487c026bc56d0cd869f4289b44cc392a5c2ba"},
standaloneSandbox: {binarySha256: "a4b0c38ed90a6dd4b4f312ad3727824a25ec478d88d4e65d22a82377b18e6214"}
cli: {binarySha256: "1ad48efd5e1de8f3f017a81b3a7177872f350343a1a8d8074c7e844bca4801e9"},
gateway: {binarySha256: "a6a5d754605a2144b148637b85a09291d2eeb77e08a4ee34b83685c6920448f5"},
standaloneSandbox: {binarySha256: "a2704babbb468fd0a359bfdd9844de71095b730758541b4ca8cbab77d4018920"}
}
}' > "$E2E_ARTIFACT_DIR/mcp-bridge-deepagents/openshell-exact-main-provenance.json"
fi
Expand Down Expand Up @@ -1409,7 +1409,7 @@ jobs:
NEMOCLAW_OPENSHELL_CHANNEL: stable
NEMOCLAW_OPENSHELL_EXACT_MAIN_PROOF: "1"
NEMOCLAW_RUN_LIVE_E2E: "1"
OPENSHELL_DOCKER_SUPERVISOR_IMAGE: ghcr.io/nvidia/openshell/supervisor@sha256:ea3632b6e9528e2309103af5b6949606fcdc83ca1f69e8db81482a25bea84bb6
OPENSHELL_DOCKER_SUPERVISOR_IMAGE: ghcr.io/nvidia/openshell/supervisor@sha256:b58be5e40c788977ffa0e8305a8cad9c656efdf1a3fe182582a00ca870bb0edb
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand Down Expand Up @@ -1461,12 +1461,12 @@ jobs:
jq -n '{
schemaVersion: 1,
sourceRepository: "NVIDIA/OpenShell",
releaseTag: "v0.0.99",
sourceSha: "8c7dd148a9e6360c9d5b2830e339a0dc4b3f3032",
releaseTag: "v0.0.101",
sourceSha: "8ddd98c3dff62619a3963f99ba1e055b67650e72",
artifacts: {
cli: {binarySha256: "5c0dabb90152a3cfae9005731771da99f00a22403080c81952c7be8ba4b5728f"},
gateway: {binarySha256: "05bd6c982dd72b73364b91ab694487c026bc56d0cd869f4289b44cc392a5c2ba"},
standaloneSandbox: {binarySha256: "a4b0c38ed90a6dd4b4f312ad3727824a25ec478d88d4e65d22a82377b18e6214"}
cli: {binarySha256: "1ad48efd5e1de8f3f017a81b3a7177872f350343a1a8d8074c7e844bca4801e9"},
gateway: {binarySha256: "a6a5d754605a2144b148637b85a09291d2eeb77e08a4ee34b83685c6920448f5"},
standaloneSandbox: {binarySha256: "a2704babbb468fd0a359bfdd9844de71095b730758541b4ca8cbab77d4018920"}
}
}' > "$E2E_ARTIFACT_DIR/openshell-credential-generation-window/openshell-exact-main-provenance.json"

Expand Down
6 changes: 3 additions & 3 deletions agents/hermes/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ COPY agents/hermes/finalize-tirith-marker.py /usr/local/lib/nemoclaw/finalize-ti
COPY agents/hermes/build-mcp-digest.py /usr/local/lib/nemoclaw/build-hermes-mcp-digest.py
COPY agents/hermes/mcp-config-transaction.py /usr/local/lib/nemoclaw/hermes-mcp-config-transaction.py
COPY agents/hermes/cron-restore-control.py /usr/local/lib/nemoclaw/hermes-cron-restore-control.py
COPY src/lib/actions/sandbox/openshell-child-visible-credentials.v0.0.99.json /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.99.json
COPY src/lib/actions/sandbox/openshell-child-visible-credentials.v0.0.101.json /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.101.json
COPY scripts/state-dir-guard.py /usr/local/lib/nemoclaw/state-dir-guard.py
COPY agents/hermes/state-lock-plan.json /usr/local/share/nemoclaw/state-lock-plan.json
COPY nemoclaw-blueprint/scripts/*.js /usr/local/lib/nemoclaw/preloads/
Expand Down Expand Up @@ -363,12 +363,12 @@ RUN chmod -R a+rX /opt/nemoclaw-blueprint/
# minimum supported Hermes sandbox base tag guarantees those artifacts and
# test/sandbox-rlimit-hooks.test.ts covers that base.
RUN chmod 755 /usr/local/bin/nemoclaw-start /usr/local/bin/nemoclaw-managed-startup-hold /usr/local/bin/nemoclaw-managed-bootstrap /usr/local/lib/nemoclaw/sandbox-init.sh /usr/local/lib/nemoclaw/validate-hermes-env-secret-boundary.py /usr/local/lib/nemoclaw/patch-hermes-session-list-preview.py /usr/local/lib/nemoclaw/patch-hermes-sqlite-temp-store.py /usr/local/lib/nemoclaw/patch-hermes-discord-recovery-permissions.py /usr/local/lib/nemoclaw/patch-hermes-profile-policy-defaults.py /usr/local/lib/nemoclaw/seed-hermes-dashboard-config.py /usr/local/lib/nemoclaw/hermes-runtime-config-guard.py /usr/local/lib/nemoclaw/finalize-tirith-marker.py /usr/local/lib/nemoclaw/hermes-mcp-config-transaction.py \
&& chown root:root /usr/local/bin/nemoclaw-gateway-control /usr/local/lib/nemoclaw/gateway-supervisor.sh /usr/local/lib/nemoclaw/state-dir-guard.py /usr/local/share/nemoclaw/state-lock-plan.json /usr/local/lib/nemoclaw/managed-gateway-control.py /usr/local/lib/nemoclaw/build-hermes-mcp-digest.py /usr/local/lib/nemoclaw/hermes-cron-restore-control.py /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.99.json \
&& chown root:root /usr/local/bin/nemoclaw-gateway-control /usr/local/lib/nemoclaw/gateway-supervisor.sh /usr/local/lib/nemoclaw/state-dir-guard.py /usr/local/share/nemoclaw/state-lock-plan.json /usr/local/lib/nemoclaw/managed-gateway-control.py /usr/local/lib/nemoclaw/build-hermes-mcp-digest.py /usr/local/lib/nemoclaw/hermes-cron-restore-control.py /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.101.json \
&& chmod 700 /usr/local/bin/nemoclaw-gateway-control /usr/local/lib/nemoclaw/hermes-cron-restore-control.py \
&& chmod 500 /usr/local/lib/nemoclaw/state-dir-guard.py /usr/local/lib/nemoclaw/managed-gateway-control.py \
&& chmod 444 /usr/local/lib/nemoclaw/entrypoint-env-wrapper.sh /usr/local/share/nemoclaw/state-lock-plan.json /usr/local/lib/nemoclaw/gateway-supervisor.sh /usr/local/lib/nemoclaw/build-hermes-mcp-digest.py /usr/local/lib/nemoclaw/managed_policy.py \
&& chmod 444 /usr/local/lib/nemoclaw/patch-hermes-langfuse-credentials.mts \
&& chmod 444 /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.99.json \
&& chmod 444 /usr/local/lib/nemoclaw/openshell-child-visible-credentials.v0.0.101.json \
&& if [ -d /usr/local/lib/nemoclaw/preloads ]; then \
chown -R 0:0 /usr/local/lib/nemoclaw/preloads \
&& find /usr/local/lib/nemoclaw/preloads -type f -exec chmod 444 {} + \
Expand Down
10 changes: 5 additions & 5 deletions agents/hermes/mcp-config-transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
r"^Bearer openshell:resolve:env:([A-Za-z_][A-Za-z0-9_]{0,127})$"
)
OPENSHELL_REVISIONED_CREDENTIAL_NAME_RE = re.compile(r"^v[0-9]+_[A-Za-z0-9_]+$")
BOUNDARY_MANIFEST_NAME = "openshell-child-visible-credentials.v0.0.99.json"
BOUNDARY_MANIFEST_NAME = "openshell-child-visible-credentials.v0.0.101.json"
ANSI_ESCAPE_RE = re.compile(
r"\x1b(?:\[[0-?]*[ -/]*[@-~]|\][^\x07]*(?:\x07|\x1b\\)|[@-_])"
)
Expand Down Expand Up @@ -107,7 +107,7 @@ def _load_credential_boundary_manifest() -> dict[str, object]:
# corrupt, or wrong-version OpenShell boundary manifest.
# sourceBoundary: NemoClaw owns one reviewed manifest installed beside this
# helper in images; the second path is the deterministic source-checkout layout.
# whyNotSourceFix: OpenShell v0.0.99 has no machine-readable child-env contract.
# whyNotSourceFix: OpenShell v0.0.101 has no machine-readable child-env contract.
# It also deliberately hides the supervisor identity mount from workload
# children and the Hermes image contains no OpenShell CLI. Executing
# ``openshell --version`` here would therefore either fail every real
Expand Down Expand Up @@ -135,7 +135,7 @@ def _load_credential_boundary_manifest() -> dict[str, object]:
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
if (
not isinstance(manifest, dict)
or manifest.get("openshellVersion") != "0.0.99"
or manifest.get("openshellVersion") != "0.0.101"
):
raise RuntimeError("Hermes MCP credential boundary manifest is invalid")
return manifest
Expand Down Expand Up @@ -319,7 +319,7 @@ def _validate_payload(action: str, payload: dict[str, object]) -> None:
}
if action == "add" and hostname in host_aliases:
raise ValueError(
"Authenticated MCP OpenShell host aliases are unavailable with OpenShell v0.0.99"
"Authenticated MCP OpenShell host aliases are unavailable with OpenShell v0.0.101"
)
# Host preflight owns destination trust and binds every accepted endpoint to
# exact OpenShell address pins. This in-sandbox check revalidates canonical
Expand Down Expand Up @@ -1091,7 +1091,7 @@ def _assert_non_root_lifecycle_identity() -> None:
# topology.
# sourceBoundary: OpenShell owns workload topology; NemoClaw owns the
# immutable root-lifecycle marker and validates it before mutation.
# whyNotSourceFix: OpenShell 0.0.99 supports both topologies but exposes no
# whyNotSourceFix: OpenShell 0.0.101 supports both topologies but exposes no
# attested same-UID capability that this packaged helper can query.
# regressionTest: hermes-mcp-config-transaction.test.ts rejects both probe
# and add when the root-lifecycle marker identifies the legacy topology.
Expand Down
4 changes: 2 additions & 2 deletions nemoclaw-blueprint/blueprint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

version: "0.1.0"
# Requires OpenShell MCP/JSON-RPC L7 policy support from NVIDIA/OpenShell#1865.
min_openshell_version: "0.0.99"
max_openshell_version: "0.0.99"
min_openshell_version: "0.0.85"
max_openshell_version: "0.0.85"
min_openclaw_version: "2026.3.11"
# Mirrors the components.sandbox.image manifest digest below. Lets a
# downstream consumer (or release tooling) verify the blueprint declares
Expand Down
2 changes: 1 addition & 1 deletion nemoclaw-blueprint/policies/presets/brew.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ network_policies:
access: full
# Keep GitHub and raw-content routes on automatic TLS handling so this
# preset composes with the agent baselines and narrower inspected
# routes under OpenShell 0.0.99. System git is excluded below; the
# routes under OpenShell 0.0.101. System git is excluded below; the
# remaining curl/Homebrew clients trust the sandbox CA.
- host: ghcr.io
port: 443
Expand Down
2 changes: 1 addition & 1 deletion nemoclaw/src/shared/openshell-policy-boundary.cts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export function parseOpenShellPolicy(raw: string): ParsedOpenShellPolicy {
// regressionTest: the root policy round-trip and plugin runner policy tests.
// removalCondition: OpenShell's supported base-policy contract guarantees that
// provider-composed entries are absent from every mutation read.
// tracking: revalidated for stable OpenShell 0.0.99; revalidate after 0.0.99.
// tracking: revalidated for stable OpenShell 0.0.101; revalidate after 0.0.101.
export function withoutProviderComposedPolicies<T>(policies: Record<string, T>): Record<string, T> {
return Object.fromEntries(
Object.entries(policies).filter(([name]) => !name.startsWith("_provider_")),
Expand Down
4 changes: 2 additions & 2 deletions nemoclaw/src/shared/sandbox-name.cts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
// or provider identifier, or both grammars are enforced by shared upstream
// contracts.

// OpenShell v0.0.99 routes sandbox and workspace identities through labels
// OpenShell v0.0.101 routes sandbox and workspace identities through labels
// capped at 19 characters. Keep NemoClaw's canonical sandbox-name boundary at
// that upstream limit so invalid creates fail before any gateway mutation.
export const NAME_MAX_LENGTH = 19;
export const PROVIDER_NAME_MAX_LENGTH = 128;

// NemoClaw label: starts with a lowercase letter, then lowercase
// letters/digits/single internal hyphens, and ends with a letter or digit.
// OpenShell v0.0.99 reserves `--` as a routed-name segment delimiter.
// OpenShell v0.0.101 reserves `--` as a routed-name segment delimiter.
export const NAME_VALID_PATTERN = /^(?!.*--)[a-z]([a-z0-9-]*[a-z0-9])?$/;
export const PROVIDER_NAME_VALID_PATTERN = /^[A-Za-z][A-Za-z0-9._-]{0,127}$/;

Expand Down
10 changes: 5 additions & 5 deletions scripts/brev-launchable-ci-cpu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ assert_openshell_version() {
if [ -z "$OPENSHELL_VERSION" ]; then
case "${NEMOCLAW_OPENSHELL_CHANNEL:-stable}" in
dev) OPENSHELL_VERSION="dev" ;;
stable | auto) OPENSHELL_VERSION="v0.0.99" ;;
stable | auto) OPENSHELL_VERSION="v0.0.85" ;;
*) fail "NEMOCLAW_OPENSHELL_CHANNEL must be one of: stable, dev, auto" ;;
esac
fi
Expand Down Expand Up @@ -148,11 +148,11 @@ openshell_cli_asset_for_arch() {
openshell_cli_pinned_sha256() {
local release_tag="$1" asset="$2"
case "${release_tag}:${asset}" in
v0.0.99:openshell-x86_64-unknown-linux-musl.tar.gz)
printf '%s\n' "35725a358e42ef7f0f0393035536da317706b0febcc459a2011e0555f6c2b71c"
v0.0.85:openshell-x86_64-unknown-linux-musl.tar.gz)
printf '%s\n' "078fa086f506832c3d47d992e6109f26074bdd55916ce268e47c3971423459eb"
;;
v0.0.99:openshell-aarch64-unknown-linux-musl.tar.gz)
printf '%s\n' "d00cbf0d8779c01ddea6453ead2ad4db3d89a1f14eb6f0785f7919f42813a279"
v0.0.85:openshell-aarch64-unknown-linux-musl.tar.gz)
printf '%s\n' "3cf353e7994d5835a233fe0641f9a860779190b054d0f90a04c897be782734b8"
;;
*)
return 1
Expand Down
3 changes: 3 additions & 0 deletions scripts/check-installer-hash.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ readonly -a OPENSHELL_RELEASE_MANIFEST_ALLOWLIST=(
"0.0.99|openshell-checksums-sha256.txt|ea3e2c1a583e5ea00332c3b65a18068bd1f9b090f7ff0f5e24b29762cfc3b4c7"
"0.0.99|openshell-gateway-checksums-sha256.txt|7f84f728412548720c8ef51993c58414c4f04598451c282b26ead233185e40c5"
"0.0.99|openshell-sandbox-checksums-sha256.txt|9e67af6bab9f975432a1045fcfea5ab182ab585b17886c8c290c1eb77232b87a"
"0.0.101|openshell-checksums-sha256.txt|9c90869d00b109b5ac1062b1a9808a592c2311d3c0c4926bae44d136b979d8a9"
"0.0.101|openshell-gateway-checksums-sha256.txt|dcb3f1917713bf2a8e8e1803ac42c5e39d9dd41e644136b05def32b077082777"
"0.0.101|openshell-sandbox-checksums-sha256.txt|d16f7d369c54d74d36c7df036565267a960e7ce6fb143012fe9d77f257d6e8b3"
)

case "${1:-}" in
Expand Down
2 changes: 1 addition & 1 deletion scripts/checks/managed-image-protected-runtime-contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export type ManagedImageLocalInferenceKind = (typeof MANAGED_IMAGE_LOCAL_INFEREN

export type ManagedImageProtectedRouteKind = ManagedImageLocalInferenceKind | "rollback";

// OpenShell 0.0.99 caps routable sandbox names at 19 characters. Keep the
// OpenShell 0.0.101 caps routable sandbox names at 19 characters. Keep the
// protected-runtime ownership prefix and every agent/route discriminator
// explicit so the qualification matrix remains deterministic and collision
// free without relying on truncation.
Expand Down
Loading
Loading