Update README.md#6
Closed
miyoungc wants to merge 2 commits into
Closed
Conversation
jessesanford
pushed a commit
to jessesanford/NemoClaw
that referenced
this pull request
Mar 24, 2026
Add onboard as an alias for setup
Merged
12 tasks
ericksoa
pushed a commit
that referenced
this pull request
May 1, 2026
…ons land cleanly (#2681) (#2851) ## Summary Replaces the EACCES-swallow approach proposed in #2693 with proper Unix group permissions. Control-UI toggles in the OpenClaw dashboard (Enable Dreaming, account toggles, etc.) now **persist in default mode** instead of throwing `GatewayRequestError: EACCES` or becoming silent no-ops. ## Background OpenClaw 2026.4.24 (landed via #2484) introduced `mutateConfigFile` as the new control-UI write path. Patch 4 in the Dockerfile only wraps the legacy `replaceConfigFile` (plugin install path), so every config-toggle click in the sandbox dashboard now EACCES'd. #2693 proposed adding "Patch 4b" — a parallel try/catch that swallows the EACCES. That makes toggles non-functional in the sandbox: the user clicks "Enable Dreaming," gets no error, but nothing actually persists. UX improves over the crash; underlying limitation stays. This PR implements the alternative design Aaron sketched for #2681: rather than wrapping each new write path in EACCES handlers, fix the actual permissions so the writes succeed. ## Closes / Supersedes - Closes #2681 - Supersedes #2693 — thanks @Sanjays2402 for raising the issue and the initial swallow attempt that surfaced the deeper design question ## Implementation (the 6-item spec) | # | Item | File | |---|------|------| | 1 | Keep `gateway` as a separate UID from `sandbox`; add it to the `sandbox` group | `Dockerfile.base` | | 2 | Stale-base fallback so older `sandbox-base:latest` tags get the group membership at derived-image build time | `Dockerfile` | | 3 | `/sandbox/.openclaw` group-writable + setgid on dirs; `.config-hash` file mode 664 | `Dockerfile.base`, `Dockerfile` | | 4 | `normalize_mutable_config_perms()` at startup, gated on Shields state | `scripts/nemoclaw-start.sh` | | 5 | `shields down` restores 660/2770 (group-writable + setgid) for OpenClaw; Hermes left at historical 640/750 (no separate gateway UID, contract doesn't apply) | `src/lib/shields.ts` | | 6 | Tests assert the new invariant: writes succeed in default mode, no new EACCES swallow | `test/repro-2681-group-writable.test.ts` | ## Why setgid `chmod g+s` on directories means new files inherit `group=sandbox` regardless of which UID created them. So `gateway` writes a file → file is `group=sandbox` → the `sandbox` user (also in the group) can still read it. Without setgid, gateway's writes would land with `group=gateway` and the agent might lose read access on rotation. ## Patch 4 retention The existing `Patch 4` (replaceConfigFile EACCES swallow) is **intentionally retained** as a defensive fallback for: - Older base images during the rollout window - Host filesystems that don't honor setgid (rare, but possible on some Windows/WSL2 configurations) - Other write paths in OpenClaw that might surface in future versions No new EACCES swallow patch is added — the `Patch 4b` approach from #2693 is explicitly rejected per spec item #6. ## Verification - [x] `npm run build:cli` compiles the changed `shields.ts` - [x] 11/11 new tests pass in `test/repro-2681-group-writable.test.ts` — assert structural invariants of the group-writable contract - [x] 443/443 plugin tests pass - [x] Pre-existing CLI tests that fail on this branch ALSO fail on pristine main (`@oclif/core` module-not-found from in-flight migration; not caused by this PR) - [ ] **Brev E2E required** — touches Dockerfile + Dockerfile.base + shields lifecycle. Adaptive matrix: M×DANGER → full Brev sweep before merge ## Test plan - [x] Unit: 11 structural assertions in `repro-2681-group-writable.test.ts` - [ ] CI: `build-sandbox-images` (validates the group-membership + setgid Dockerfile changes) - [ ] CI: `test-e2e-sandbox` (validates shields lifecycle + onboard flow) - [ ] CI: `test-e2e-gateway-isolation` (validates the gateway-as-different-UID still runs cleanly) - [ ] Manual repro: onboard, click "Enable Dreaming" in dashboard, verify mutation persists across `nemoclaw status` ## Type of Change - [x] Code change (feature, bug fix, or refactor) ## AI Disclosure - [x] AI-assisted — tool: Claude Code
jyaunches
added a commit
to jyaunches/NemoClaw
that referenced
this pull request
May 11, 2026
…unchable Run NVIDIA#6 failed at refreshAndWaitForSsh with 'SSH not ready after 40 attempts' but produced NO diagnostic output between env-dump and failure. Two fixes: 1. vitest.config.ts: override silent:isCi for the e2e-branch-validation project. The whole suite is one describe block so there's no test chatter to suppress, and diagnostic output from createBrevInstance / waitForSsh / waitForLaunchableReady is essential for Brev timing debugging. Local runs already show this; CI should too. 2. waitForSsh: default attempts by mode. Bare-VM startup-script path keeps 40 attempts (~5 min). Published launchable gets 96 attempts (~12 min) because the pre-baked image boot is fast (~2 min) but Brev platform SSH-proxy registration for launchable-provisioned instances appears to lag several more minutes before brev refresh picks them up. Empirical from run NVIDIA#6: instance created but SSH never came up in the 5-min window.
jyaunches
added a commit
that referenced
this pull request
May 28, 2026
…re pending steps Addresses PR Review Advisor finding #2: 'Required security probes and expected-failure checks still skip without failing live runs'. Same architectural failure mode as findings #5 (E2E_DRY_RUN) and #6 (phase-1-skeleton): the typed framework declared a contract, but a code path silently produced non-failing skips that contradicted this PR's 'one mode, no fake green' invariant. Three suites (security-shields, security-policy, security-injection) were wired as kind: 'probe' steps; the orchestrator marked them status: 'skipped' because the probe registry hasn't landed yet. The expected-failure side-effect validator (runtime.expected-failure.no- side-effects) was wired as kind: 'pending'. run.ts only sets process.exitCode = 1 on status === 'failed', so a live run could omit security shields, network policy, prompt-injection blocking, AND the negative-scenario forbidden-side-effect contract while still appearing non-failing. Fix follows the framework spirit: declare requirement in the typed metadata, enforce it once at the orchestrator boundary. Typed contract extension (types.ts): AssertionStep.required?: boolean When true, a probe/pending step that resolves as 'skipped' is reclassified as 'failed' by the phase orchestrator. Defaults to false (existing behavior preserved for diagnostics, docs-validation, and other non-security probes). Orchestrator (phase.ts): executeStep: probe and pending branches now check step.required and return status: 'failed' with a 'required <kind> not <state>' message when set. Non-required probes/pending steps continue to surface as visible skipped results so unrelated gaps stay diagnostic. Registry (assertions/registry.ts): - probeStep / pendingStep helpers grew an options arg with required?: boolean (matches the secretEnv pattern: options come in via typed objects, not positional args). - security-shields, security-policy, security-injection probes annotated required: true. These are the suites the run is not safe without; failing closed beats fake green. - runtime.expected-failure.no-side-effects pending step annotated required: true. Negative scenarios cannot honestly pass while their core side-effect contract is unimplemented. - diagnostics, docs-validation probes intentionally remain non-required: they are informational, not safety-critical, and will switch to required when the probe registry lands and they have real implementations. run.ts: no change needed. The new failed-status flows through the existing exit-code path (process.exitCode = 1 when any phase status is failed), so the workflow correctly reports red for missing required probes/pending steps. Tests (e2e-phase-orchestrators.test.ts, +5): - test_required_probe_step_that_is_unregistered_fails_the_phase - test_non_required_probe_step_continues_to_skip_visibly - test_required_pending_step_fails_closed - test_security_suite_groups_in_registry_mark_their_steps_as_required - test_expected_failure_no_side_effects_step_in_registry_is_required 318/318 e2e-scenario framework tests pass. Until the probe registry follow-up PR registers actual implementations for shieldsConfigProbe / networkPolicyProbe / injectionBlockedProbe / expectedFailureNoSideEffectsProbe, scenarios that include those suites/expected-failure groups will fail loudly with 'required probe not registered' or 'required pending step not implemented'. That is the correct intermediate state: visible red until real, instead of green-by-default. Signed-off-by: Julie Yaunches <jyaunches@nvidia.com>
12 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.