Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d0f21ef
perf(cli): add secure launch readiness leases
senthilr-nv Aug 13, 2026
7ceac57
merge: resolve conflicts with main
github-actions[bot] Aug 13, 2026
2bba8cc
Merge branch 'main' into codex/8942-launch-readiness-lease
cv Aug 13, 2026
d0c657b
perf(cli): add secure launch readiness leases
senthilr-nv Aug 13, 2026
2a4cad5
fix(cli): harden launch readiness evidence
senthilr-nv Aug 13, 2026
760c10e
fix(cli): disable readiness leases on unsupported hosts
senthilr-nv Aug 13, 2026
51cc49f
merge(cli): preserve protected PR ancestry
senthilr-nv Aug 13, 2026
648e273
merge: resolve conflicts with main
github-actions[bot] Aug 13, 2026
9b49429
merge: resolve conflicts with main
github-actions[bot] Aug 13, 2026
31df5ed
fix(ci): register launch readiness E2E parity
prekshivyas Aug 13, 2026
cd9af73
test(launch): keep readiness cases linear
prekshivyas Aug 13, 2026
bf0bfe7
fix(ci): satisfy launch readiness guardrails
prekshivyas Aug 13, 2026
d1cf319
test(ci): provision launch readiness authority
prekshivyas Aug 13, 2026
34a8956
Merge branch 'main' into codex/8942-launch-readiness-lease
senthilr-nv Aug 13, 2026
bda6b08
merge: refresh PR branch with upstream main
senthilr-nv Aug 13, 2026
4c9994c
fix(cli): complete launch readiness review fixes
senthilr-nv Aug 13, 2026
ed4bdd5
merge(main): refresh pull request base
senthilr-nv Aug 13, 2026
928ea7f
test(cli): keep readiness process cases linear
senthilr-nv Aug 13, 2026
574b655
test(launch): fix Linux readiness CI fixtures
senthilr-nv Aug 13, 2026
f4da8df
test(connect): mock owner-scoped readiness probes
senthilr-nv Aug 13, 2026
a454ac8
test(cli): scope launch readiness fixtures
senthilr-nv Aug 13, 2026
db825a3
perf(cli): reconcile launch readiness with main
senthilr-nv Aug 13, 2026
26f562e
merge(main): preserve reviewed launch readiness ancestry
senthilr-nv Aug 13, 2026
cc40d1d
test(cli): stabilize readiness authority fixtures
senthilr-nv Aug 13, 2026
4a54379
merge(main): reconcile PR 8951 with current main
senthilr-nv Aug 13, 2026
58e1c7b
Merge branch 'main' into codex/8942-launch-readiness-lease
rsliter Aug 13, 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
22 changes: 11 additions & 11 deletions ci/source-architecture-budget.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"defaultMax": 20,
"maxByFile": {
"src/lib/actions/sandbox/mcp-bridge-contracts.ts": 26,
"src/lib/actions/sandbox/process-recovery.ts": 26,
"src/lib/actions/sandbox/process-recovery.ts": 27,
"src/lib/adapters/docker/index.ts": 43,
"src/lib/adapters/openshell/client.ts": 23,
"src/lib/adapters/openshell/resolve.ts": 27,
"src/lib/adapters/openshell/runtime.ts": 52,
"src/lib/adapters/openshell/timeouts.ts": 37,
"src/lib/agent/defs.ts": 32,
"src/lib/adapters/openshell/runtime.ts": 53,
"src/lib/adapters/openshell/timeouts.ts": 38,
"src/lib/agent/defs.ts": 33,
"src/lib/cli/branding.ts": 86,
"src/lib/cli/nemoclaw-oclif-command.ts": 106,
"src/lib/cli/terminal-style.ts": 43,
Expand All @@ -20,15 +20,15 @@
"src/lib/core/url-utils.ts": 27,
"src/lib/core/wait.ts": 35,
"src/lib/credentials/store.ts": 46,
"src/lib/inference/config.ts": 29,
"src/lib/inference/config.ts": 30,
"src/lib/inference/web-search.ts": 21,
"src/lib/messaging/channels/index.ts": 25,
"src/lib/onboard/gateway-binding.ts": 49,
"src/lib/onboard/gateway-binding.ts": 50,
"src/lib/runner.ts": 88,
"src/lib/security/redact.ts": 52,
"src/lib/state/onboard-session.ts": 36,
"src/lib/state/registry.ts": 99,
"src/lib/state/state-root.ts": 20,
"src/lib/state/registry.ts": 100,
"src/lib/state/state-root.ts": 21,
"src/lib/subprocess-env.ts": 24,
"src/lib/validation.ts": 25
}
Expand All @@ -37,7 +37,7 @@
"defaultMax": 20,
"maxByFile": {
"src/lib/actions/inference-set.ts": 32,
"src/lib/actions/sandbox/connect.ts": 38,
"src/lib/actions/sandbox/connect.ts": 39,
"src/lib/actions/sandbox/destroy.ts": 29,
"src/lib/actions/sandbox/doctor.ts": 30,
"src/lib/actions/sandbox/status-snapshot.ts": 20,
Expand All @@ -58,8 +58,8 @@
"maxRootFiles": {
"src/lib/onboard": 308,
"src/lib/actions": 19,
"src/lib/actions/sandbox": 182,
"src/lib/state": 37,
"src/lib/actions/sandbox": 183,
"src/lib/state": 38,
"src/lib/inference": 63,
"scripts": 47
}
Expand Down
5 changes: 4 additions & 1 deletion docs/get-started/quickstart-hermes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ Review the [Prerequisites](prerequisites) before you begin.
nemohermes launch my-hermes
```

`nemohermes launch` runs the same preflight as `connect`, then starts `hermes` in your terminal.
`nemohermes launch` runs the complete preflight or, on Linux, validates an existing fixed 24-hour launch-readiness lease before it starts `hermes` in your terminal.
On macOS, `launch` runs the complete preflight every time and does not publish a launch-readiness lease.
On Linux, if the recorded configuration or live runtime has changed, NemoClaw durably invalidates prior evidence before it runs the complete preflight.
If old evidence might remain acceptable and cannot be invalidated, `launch` stops before preflight or recovery and tells you to repair the secure OS per-user runtime authority or NemoClaw state permissions.
To open a sandbox shell first and start Hermes yourself, run these commands instead.

```bash
Expand Down
5 changes: 4 additions & 1 deletion docs/get-started/quickstart-langchain-deepagents-code.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ Review the [Prerequisites](prerequisites) before you begin.
nemo-deepagents launch my-deepagents
```

`nemo-deepagents launch` runs the same preflight as `connect`, then starts `dcode` in your terminal.
`nemo-deepagents launch` runs the complete preflight or, on Linux, validates an existing fixed 24-hour launch-readiness lease before it starts `dcode` in your terminal.
On macOS, `launch` runs the complete preflight every time and does not publish a launch-readiness lease.
On Linux, if the recorded configuration or live runtime has changed, NemoClaw durably invalidates prior evidence before it runs the complete preflight.
If old evidence might remain acceptable and cannot be invalidated, `launch` stops before preflight or recovery and tells you to repair the secure OS per-user runtime authority or NemoClaw state permissions.
To open a sandbox shell first and start `dcode` yourself, run these commands instead.

```bash
Expand Down
5 changes: 4 additions & 1 deletion docs/get-started/quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ Review the [Prerequisites](prerequisites) before you begin.
nemoclaw launch my-assistant
```

`nemoclaw launch` runs the same preflight as `connect`, then starts `openclaw tui` in your terminal.
`nemoclaw launch` runs the complete preflight or, on Linux, validates an existing fixed 24-hour launch-readiness lease before it starts `openclaw tui` in your terminal.
On macOS, `launch` runs the complete preflight every time and does not publish a launch-readiness lease.
On Linux, if the recorded configuration or live runtime has changed, NemoClaw durably invalidates prior evidence before it runs the complete preflight.
If old evidence might remain acceptable and cannot be invalidated, `launch` stops before preflight or recovery and tells you to repair the secure OS per-user runtime authority or NemoClaw state permissions.
To open a sandbox shell first and start the TUI yourself, run these commands instead.

```bash
Expand Down
41 changes: 41 additions & 0 deletions docs/manage-sandboxes/recover-rebuild-sandboxes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,47 @@ Use `nemo-deepagents <sandbox-name> status`, `logs`, `connect`, and `rebuild` fo
If the terminal runtime reports degraded health, rebuild the sandbox instead of using `recover` or `gateway restart`.
</AgentOnly>

### Understand Launch Readiness Leases

A successful complete preflight for `$$nemoclaw launch <sandbox-name>` can publish a credential-free launch-readiness lease on Linux.
Linux infrastructure can publish the same evidence with `$$nemoclaw <sandbox-name> connect --probe-only`.
The lease has a fixed 24-hour lifetime that repeated launches do not extend.
Leaving the agent with `/exit` does not revoke it, and users do not refresh it manually.

During the lease, `launch` still verifies the owning OpenShell gateway, exact live sandbox identity, registry and agent configuration, effective policy, inference route, required forwards, and semantic runtime health.
Configured inference must return HTTP 2xx from the semantic `inference.local` probe, which is stricter than the HTTP 200–499 reachability diagnostic used by ordinary `connect`.
When those checks pass, it can skip duplicate recovery, readiness polling, and inference-route repair.
The lease is not a health guarantee or repair authority.
Comment thread
senthilr-nv marked this conversation as resolved.

For missing, unsafe, malformed, expired, mismatched, changed, or unhealthy evidence, NemoClaw fences any prior acceptable evidence before it runs the complete preflight.
Ordinary launch continues only when NemoClaw proves that no old authority or evidence can exist, or durably rotates the runtime epoch.
If an old epoch might exist and cannot be durably rotated, `launch` and `connect --probe-only` stop before complete preflight or recovery.
Their redacted guidance asks you to repair the current user's secure OS runtime authority and NemoClaw state permissions, then retry.
If NemoClaw securely proves that both the authority and receipt are absent but cannot create new authority, ordinary `launch` can run the complete preflight without optimization; `connect --probe-only` exits nonzero because it could not publish evidence.
If that preflight succeeds before the lease expires, replacement evidence keeps the original start and expiry time.
After expiry, a successful complete preflight starts a new 24-hour lease only when publication succeeds.

Before the first mutation in the complete preflight, the producer revalidates its sandbox-global runtime epoch under the sandbox lifecycle lock followed by the owning gateway lock.
It holds both locks through all mutations in the complete preflight, final state capture, and publication.
A stale producer makes no changes and re-inspects the newer lease.

If unsafe or malformed authority history makes the prior lease timeline untrustworthy, NemoClaw durably invalidates the old epoch and starts one conservative 24-hour quarantine.
Publication remains disabled until both wall time and monotonic uptime span the full quarantine.
Repeated attempts do not extend it.
After it elapses, the next successful complete preflight can publish a new fixed 24-hour lease.

Lease acceptance and publication are currently Linux-only and require a secure, independently writable OS per-user runtime authority under `/run/user/<numeric-uid>`.
It never uses caller-provided environment variables to select this authority.

On macOS, `launch` runs the complete preflight every time and does not publish a launch-readiness lease.
`connect --probe-only` also runs the complete preflight, including recovery and probes, but exits nonzero because it cannot publish authoritative launch-readiness evidence.
The publication-failure diagnostic is redacted and does not print filesystem paths or environment values.

Infrastructure must run `connect --probe-only` as the same final numeric user that later runs `launch`.
Run it after the final durable home and state volume is mounted and after policy and network provisioning is complete.
NemoClaw rejects evidence after a bound sandbox, configuration, policy, or network identity changes.
Deployment ordering remains responsible for external changes that OpenShell and NemoClaw cannot observe.

<AgentOnly variant="openclaw,hermes">
### Host OpenShell Gateway Versus In-Sandbox Agent Recovery

Expand Down
64 changes: 57 additions & 7 deletions docs/reference/commands.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1013,9 +1013,44 @@ $$nemoclaw use <name> --json
Connect to a sandbox and start its agent in one host-side command.
Use it instead of running `$$nemoclaw <name> connect` and then typing the agent command inside the sandbox.

`launch` runs the same preflight as [`$$nemoclaw <name> connect`](#$$nemoclaw-name-connect), including the readiness wait, in-sandbox agent process recovery, and inference-route reconciliation.
It runs every check in that shared preflight.
After the preflight, `launch` starts the sandbox's agent in your terminal instead of opening a sandbox shell.
`launch` runs the complete preflight from [`$$nemoclaw <name> connect`](#$$nemoclaw-name-connect) when no launch-readiness lease is usable.
That path includes the readiness wait, in-sandbox agent process recovery, and inference-route reconciliation.
A successful complete preflight can publish a credential-free launch-readiness lease with a fixed 24-hour lifetime on Linux.
Lease acceptance and publication are currently Linux-only and require a secure, independently writable OS per-user runtime authority under `/run/user/<numeric-uid>`.
It never uses caller-provided environment variables to select this authority.
On macOS, `launch` runs the complete preflight every time and does not publish a launch-readiness lease.

During that lease, another `launch` still verifies these conditions:

- The owning OpenShell gateway reports the exact sandbox identity in the `Ready` or `Running` state.
- The sandbox registry, agent manifest, interactive command, policy intent, and effective parsed OpenShell network policy match the recorded identity.
- The recorded inference selection matches the live route, and `inference.local` returns HTTP 2xx from its semantic probe when inference is configured. This is stricter than the HTTP 200–499 reachability diagnostic used by ordinary `connect`.
- The agent runtime and its required host-side forwards pass their semantic health checks.

After these checks pass, `launch` can skip duplicate recovery, readiness polling, and inference-route repair.
The lease does not replace a health check or authorize repair.
For missing, expired, malformed, inaccessible, mismatched, or unhealthy evidence, NemoClaw fences any prior acceptable evidence before it runs the complete preflight.
Ordinary launch continues only when NemoClaw proves that no old authority or evidence can exist, or durably rotates the runtime epoch.
If an old epoch might exist and cannot be durably rotated, `launch` stops before complete preflight or recovery.
Its redacted guidance asks you to repair the current user's secure OS runtime authority and NemoClaw state permissions, then retry.
A failed live check never becomes a successful launch because a lease exists.

Immediately before the first mutation in the complete preflight, the producer revalidates its sandbox-global runtime epoch while holding the sandbox lifecycle lock followed by the owning gateway lock.
It holds both locks through all mutations in the complete preflight, final state capture, and publication.
If another producer has replaced the epoch, the stale producer makes no changes and re-inspects the newer lease.

The 24-hour lifetime does not extend when you launch repeatedly.
Exiting the agent with `/exit` does not revoke the lease.
If state changes before expiry, NemoClaw fences the old evidence and runs the complete preflight.
A successful preflight in that interval keeps the original start and expiry time.
After expiry, a successful complete preflight starts a new 24-hour lease only when publication succeeds.

If unsafe or malformed authority history makes the prior lease timeline untrustworthy, NemoClaw durably invalidates the old epoch and starts one conservative 24-hour quarantine.
Both wall time and monotonic uptime must span the full quarantine, and publication remains disabled during it.
Repeated attempts do not extend the quarantine.
After it elapses, the next successful complete preflight can publish a new fixed 24-hour lease.
You do not create or refresh this lease manually, and `launch` has no lease-control flags.
After lease validation or the automatic fallback that runs the complete preflight, `launch` starts the sandbox's agent in your terminal instead of opening a sandbox shell.

The agent command comes from the sandbox's agent manifest.
If the sandbox registry names a non-OpenClaw agent without a readable local agent manifest, `launch` exits before starting an in-sandbox command.
Expand All @@ -1031,6 +1066,8 @@ $$nemoclaw launch <name>
```

The sandbox name is required, and the command takes no flags.
The sandbox must already exist in the local NemoClaw state.
If it is not registered locally, `launch` exits before it runs an OpenShell command or readiness recovery and reports that the sandbox is not registered in the local NemoClaw state.
When the agent exits, you return to the host shell.

<AgentOnly variant="openclaw">
Expand Down Expand Up @@ -1118,11 +1155,24 @@ $$nemoclaw my-assistant connect [--probe-only]
$$nemoclaw connect
```

The `--probe-only` flag waits for the sandbox to become ready, verifies or repairs its in-sandbox agent process and host-side forward, and exits without opening a shell.
On Linux, the `--probe-only` flag is the infrastructure producer for launch-readiness evidence.
It validates a usable lease and exits without duplicate recovery.
Otherwise, it fences prior evidence, waits for the sandbox, verifies or repairs its in-sandbox agent process and host-side forwards, and publishes evidence only after every probe succeeds.
It rechecks the sandbox on its recorded OpenShell gateway after the readiness wait and never restarts the shared host gateway.
Use it for health checks and scripted readiness probes.

Use [`$$nemoclaw launch <name>`](#$$nemoclaw-launch-name) when you want the same preflight followed by the agent instead of a sandbox shell.
If an old runtime epoch might exist and cannot be durably rotated, the command exits nonzero before complete preflight or recovery and gives redacted repair guidance.
A securely absent runtime authority and receipt let ordinary `launch` run the complete preflight without optimization if new authority creation fails, but `connect --probe-only` still exits nonzero because it could not publish launch-readiness evidence.
A runtime failure and a failure to publish evidence for an otherwise healthy runtime also exit nonzero with different diagnostics.

Infrastructure must run the command as the same final numeric user that later runs `launch`.
Run it only after the final durable home and state volume is mounted and after policy and network provisioning is complete.
On Linux, that user also needs a secure, independently writable OS per-user runtime authority under `/run/user/<numeric-uid>`.
Do not redirect this authority with caller environment variables.
Do not use a graphical or login-session identifier as the deployment ordering boundary.
On macOS, `connect --probe-only` runs the complete preflight, including recovery and probes, but exits nonzero because it cannot publish authoritative launch-readiness evidence.
The publication-failure diagnostic is redacted and does not print filesystem paths or environment values.
Run it for health checks and scripted readiness probes; users continue to run only `$$nemoclaw launch <name>`.

Use [`$$nemoclaw launch <name>`](#$$nemoclaw-launch-name) when you want launch-readiness validation, an automatic fallback that runs the complete preflight, and then the agent instead of a sandbox shell.

### `$$nemoclaw <name> exec`

Expand Down
25 changes: 25 additions & 0 deletions scripts/test-launch-readiness-lease.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

set -euo pipefail

if [[ "$(uname -s)" != "Linux" ]]; then
echo "Launch-readiness lease acceptance requires Linux and the util-linux PTY driver." >&2
exit 2
fi

if [[ $# -ne 1 || -z "$1" ]]; then
echo "Usage: scripts/test-launch-readiness-lease.sh <openclaw-sandbox>" >&2
exit 2
fi

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
cd "$repo_root"

npm run clean:cli
npm run build:cli
NEMOCLAW_RUN_LIVE_E2E=1 \
NEMOCLAW_ACCEPTANCE_SANDBOX="$1" \
npx vitest run --project e2e-live \
test/e2e/live/launch-readiness-lease-acceptance.test.ts
2 changes: 1 addition & 1 deletion src/commands/launch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default class LaunchCommand extends NemoClawCommand {
static strict = true;
static summary = "Connect to a sandbox and start its agent";
static description =
"Run the same preflight as connect, then start the sandbox's agent in one step so an interactive session does not need a second command typed inside the sandbox.";
"Validate a current launch-readiness lease or run the complete connect preflight, then start the sandbox's agent in one step so an interactive session does not need a second command typed inside the sandbox.";
static usage = ["launch <name>"];
static examples = ["<%= config.bin %> launch alpha"];
static args = {
Expand Down
Loading
Loading