You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An OpenClaw launch under the experimental portable/rootless-Podman profile can complete a real reply, return to the post-reply idle state, and process /exit, but the required host-side mutable-config permission cleanup then fails. The receipt-owned Podman target is resolved correctly; the Docker-compatible exec against its qualified socket fails with unable to upgrade to tcp, received 500, so launch correctly fails closed with status 1.
This is a recurrence of #8584 after its fix in #8585. It is also within the broader portable-runtime work tracked by #7744. OpenShell 0.0.101 or other runtime drift may be involved, but current evidence does not establish the cause.
Current environment and exact reproduction
Linux host using the experimental portable profile
rootless Podman with a user-owned local API socket
OpenShell 0.0.101
healthy registered OpenClaw sandbox with current receipt, lifecycle, container, and socket authority
no registry, receipt, or pairing-state mutation during the run
Run the repository launch-readiness probe; confirm status 0.
Launch the registered OpenClaw sandbox in a PTY.
Wait for initial gateway connected | idle.
Send a prompt and observe its exact reply.
Wait for post-reply connected | idle.
Send /exit and observe gateway disconnected: closed | idle.
Observe post-exit permission inspection and the final launch status.
Observed
The reply, post-reply idle state, and /exit all succeed. The first host-side permission inspection reaches the qualified portable route but fails:
docker --host <receipt-owned Podman socket> exec --user root <exact container> ...
unable to upgrade to tcp, received 500
The normal cleanup returns after the first failed pre-repair stat. An independent probe of /usr/bin/id -u sandbox fails through the same API route. NemoClaw reports the OpenClaw permission-cleanup failure and returns launch status 1. No permission mutation is attempted through an unqualified target.
Expected
Post-exit inspection and repair execute against the exact receipt-owned portable workload.
A successful OpenClaw reply and /exit, followed by successful permission verification, return launch status 0.
The mutable OpenClaw directory and file retain the required 2770/660 contract.
Any missing, stale, unsafe, replaced, ambiguous, or failed runtime observation remains fail-closed and actionable.
src/lib/actions/sandbox/exec.ts runs the OpenClaw cleanup after the agent process and makes cleanup failure override a successful command status.
src/lib/sandbox/privileged-exec.ts resolves the portable receipt-owned target, then builds docker --host <socket> exec --user root <container> ....
src/lib/shields/index.ts routes pre-repair inspection and post-repair verification through privileged stat. src/lib/shields/mutable-config-repair.ts uses the same privileged execution route for UID/GID lookup and normalization. Independent probes reproduce the API failure for both stat and /usr/bin/id -u sandbox.
Existing deterministic coverage proves generated argv and identity selection with mocks. It does not execute a real Docker-compatible exec against a rootless Podman socket, so it cannot detect this API upgrade failure.
Acceptance criteria
Resolve and revalidate the current receipt-owned portable target before every privileged operation: exact registry/lifecycle generation, local socket authority, socket identity, exact container ID, expected labels/name, sandbox identity, and running state.
Add deterministic contract tests for provider selection, exact argv construction, lifecycle/socket/container revalidation, lock duration, failure classification, and the no-fallback boundary.
Add protected Linux integration evidence that exercises a real rootless-Podman Docker-compatible exec rather than asserting mocked argv alone. Cover at least the exact stat and /usr/bin/id -u sandbox observations used by mutable-config cleanup.
Before production edits, collect one same-host, same-socket, same-container matrix artifact. Record the exact NemoClaw main SHA; OpenShell, Podman, and Docker-client versions; socket path and authority digest without the raw receipt; a container-ID digest or redacted exact identity; command argv shape; and exit/status/stderr hashes for (a) the current docker --host ... exec route, (b) an explicit native Podman transport against that same qualified socket and container, and (c) a minimal exec without --user root. Use this to distinguish an attach/upgrade-wide failure from a user-option-specific failure, but do not attribute causation from the matrix alone.
Run protected Linux live evidence for a real OpenClaw chat turn on OpenShell 0.0.101: observe the exact reply, post-reply connected | idle, /exit, terminal EOF, permission verification, and final launch status 0.
Verify the mutable OpenClaw directory and configuration file are 2770 and 660 with the expected non-root ownership after exit.
Preserve Docker behavior and unchanged Hermes and other non-OpenClaw launch behavior.
Preserve the existing shields-transition and provider-mutation lock/fence ordering, bounded subprocess timeouts, and cleanup failure taxonomy.
Fail closed with a credential-free, actionable diagnostic for an unavailable API operation, unsafe or non-local socket, socket replacement, stale receipt or lifecycle generation, missing/duplicate/replaced/stopped container, identity mismatch, or command failure.
Add an environment-backed negative integration case for a replaced socket or stale exact container identity; require failure before any command can run against another target.
Do not retry through the default Docker daemon, fall back to name-only discovery, accept ambient runtime selectors, weaken exact socket/container identity, or suppress a cleanup failure after a successful agent exit.
Do not place tokens, credentials, raw receipt contents, or unrestricted runtime state in diagnostics or test artifacts.
It does not change OpenClaw approval, pairing, or readiness-lease behavior.
It does not change the permission contract or weaken fail-closed cleanup.
It does not authorize an OpenShell source change; any confirmed OpenShell defect requires separate scope and ownership.
User impact
The interactive session succeeds, but automation and users receive a failed launch status after a clean /exit, and NemoClaw cannot verify that the OpenClaw mutable-config permission contract was restored.
Smallest design for implementation review
Keep resolvePortableDemoPrivilegedExecTarget as the sole portable authority source. Do not infer Podman from names, environment variables, or socket strings.
Put the portable privileged subprocess behind one provider-bound execution helper that consumes the already qualified socket and exact container ID while holding withPrivilegedSandboxExecutionLease. Keep the existing direct-Docker branch unchanged.
Stop at a first implementation review gate after the same-host/same-socket/same-container matrix identifies the proposed single transport. Do not attribute ownership or causation from the matrix alone. Do not begin production edits while ownership remains ambiguous or the correction would weaken exact identity or fail-closed behavior.
Select one explicit portable transport; do not add a retry or fallback chain. If the failure is only an API-version/dialect mismatch, constrain that dialect narrowly for this call. If native Podman is selected, invoke it with an explicit receipt-owned socket option and a sanitized environment; do not rely on CONTAINER_HOST, named connections, or ambient defaults. Revalidate socket, container, and lifecycle immediately before execution and hold the existing execution lease through subprocess completion.
Route mutable-config inspection, UID/GID lookup, repair, and verification through that helper with the existing sanitized environment, fixed argv, watchdog, host timeout, and lock/fence order.
Add the protected rootless-Podman integration and negative identity-replacement evidence, then retain the live chat + idle + /exit + permissions + status-0 test as the product boundary. Keep ordinary Docker coverage unchanged.
Stop before implementation if the real matrix cannot distinguish a NemoClaw client/API compatibility defect from an OpenShell-owned container/runtime defect, or if the correction would require weakening exact identity or fail-closed behavior.
Summary
An OpenClaw launch under the experimental portable/rootless-Podman profile can complete a real reply, return to the post-reply idle state, and process
/exit, but the required host-side mutable-config permission cleanup then fails. The receipt-owned Podman target is resolved correctly; the Docker-compatible exec against its qualified socket fails withunable to upgrade to tcp, received 500, so launch correctly fails closed with status1.This is a recurrence of #8584 after its fix in #8585. It is also within the broader portable-runtime work tracked by #7744. OpenShell 0.0.101 or other runtime drift may be involved, but current evidence does not establish the cause.
Current environment and exact reproduction
0.gateway connected | idle.connected | idle./exitand observegateway disconnected: closed | idle.Observed
The reply, post-reply idle state, and
/exitall succeed. The first host-side permission inspection reaches the qualified portable route but fails:The normal cleanup returns after the first failed pre-repair
stat. An independent probe of/usr/bin/id -u sandboxfails through the same API route. NemoClaw reports the OpenClaw permission-cleanup failure and returns launch status1. No permission mutation is attempted through an unqualified target.Expected
/exit, followed by successful permission verification, return launch status0.2770/660contract.Ownership and cause evidence
/exit, portable post-command cleanup, permission verification, and final status0.src/lib/actions/sandbox/exec.tsruns the OpenClaw cleanup after the agent process and makes cleanup failure override a successful command status.src/lib/sandbox/privileged-exec.tsresolves the portable receipt-owned target, then buildsdocker --host <socket> exec --user root <container> ....src/lib/shields/index.tsroutes pre-repair inspection and post-repair verification through privilegedstat.src/lib/shields/mutable-config-repair.tsuses the same privileged execution route for UID/GID lookup and normalization. Independent probes reproduce the API failure for bothstatand/usr/bin/id -u sandbox.Acceptance criteria
statand/usr/bin/id -u sandboxobservations used by mutable-config cleanup.mainSHA; OpenShell, Podman, and Docker-client versions; socket path and authority digest without the raw receipt; a container-ID digest or redacted exact identity; command argv shape; and exit/status/stderr hashes for (a) the currentdocker --host ... execroute, (b) an explicit native Podman transport against that same qualified socket and container, and (c) a minimal exec without--user root. Use this to distinguish an attach/upgrade-wide failure from a user-option-specific failure, but do not attribute causation from the matrix alone.connected | idle,/exit, terminal EOF, permission verification, and final launch status0.2770and660with the expected non-root ownership after exit.Scope boundaries
User impact
The interactive session succeeds, but automation and users receive a failed launch status after a clean
/exit, and NemoClaw cannot verify that the OpenClaw mutable-config permission contract was restored.Smallest design for implementation review
resolvePortableDemoPrivilegedExecTargetas the sole portable authority source. Do not infer Podman from names, environment variables, or socket strings.withPrivilegedSandboxExecutionLease. Keep the existing direct-Docker branch unchanged.CONTAINER_HOST, named connections, or ambient defaults. Revalidate socket, container, and lifecycle immediately before execution and hold the existing execution lease through subprocess completion./exit+ permissions + status-0 test as the product boundary. Keep ordinary Docker coverage unchanged.Stop before implementation if the real matrix cannot distinguish a NemoClaw client/API compatibility defect from an OpenShell-owned container/runtime defect, or if the correction would require weakening exact identity or fail-closed behavior.