diff --git a/nemoclaw/src/runtime-context.test.ts b/nemoclaw/src/runtime-context.test.ts index 7beadebb472..861b5234892 100644 --- a/nemoclaw/src/runtime-context.test.ts +++ b/nemoclaw/src/runtime-context.test.ts @@ -84,10 +84,10 @@ describe("getRuntimeSummary", () => { expect(summary.sandboxName).toBe("openclaw"); expect(summary.sandboxPhase).toBeNull(); expect(summary.networkLines).toContain( - "outbound network is deny-by-default; assume no arbitrary internet access", + "outbound network is deny-by-default, but allowed endpoints work, so verify by attempting a request rather than assuming a host is unreachable", ); expect(summary.filesystemLines).toContain( - "filesystem/process access is sandboxed; do not assume host-level access", + "filesystem and process access are scoped to the sandbox, not the host; do not assume access to host paths outside it", ); }); @@ -137,6 +137,13 @@ describe("registerRuntimeContext", () => { expect(result.prependSystemContext).toContain("Network policy:"); expect(result.prependSystemContext).toContain("Filesystem policy:"); expect(result.prependSystemContext).toContain(""); + // Grounding directive: the agent must attempt before asserting a host is + // blocked rather than refusing preemptively, and report the real failure + // mode instead of assuming a specific status code. + expect(result.prependSystemContext).toContain( + "unless you have actually attempted it this turn", + ); + expect(result.prependSystemContext).toContain("raises an operator approval request"); }); it("uses the persisted sandbox name in the injected context", async () => { diff --git a/nemoclaw/src/runtime-context.ts b/nemoclaw/src/runtime-context.ts index 4dd3571054e..1cbc1290ff8 100644 --- a/nemoclaw/src/runtime-context.ts +++ b/nemoclaw/src/runtime-context.ts @@ -12,12 +12,13 @@ interface RuntimeSummary { } const STATIC_NETWORK_LINES = [ - "outbound network is deny-by-default; assume no arbitrary internet access", - "blocked requests can return proxy 403 and may need operator approval or policy changes", + "outbound network is deny-by-default, but allowed endpoints work, so verify by attempting a request rather than assuming a host is unreachable", + "attempting a restricted endpoint is productive: a proxy or policy denial raises an operator approval request in OpenShell, so make the request rather than refusing preemptively; if it fails, report the actual error and distinguish a policy denial (which the operator can approve) from other network errors such as DNS, timeout, or TLS failures", ]; const STATIC_FILESYSTEM_LINES = [ - "filesystem/process access is sandboxed; do not assume host-level access", + "filesystem and process access are scoped to the sandbox, not the host; do not assume access to host paths outside it", + "within the sandbox you can create, edit, and run files (for example in /tmp or /sandbox) using your file and shell tools; try the operation and report if it fails rather than assuming it is unavailable", ]; /** @@ -63,8 +64,9 @@ function buildRuntimeContextText(summary: RuntimeSummary): string { "Filesystem policy:", ...summary.filesystemLines.map((line) => `- ${line}`), "Behavior:", - "- Do not claim unrestricted host or internet access.", - "- if access is blocked, say it is blocked and ask the operator to adjust policy or approve it in OpenShell", + "- Do not assert that a URL or host is blocked or unreachable unless you have actually attempted it this turn; report the actual result rather than speculating.", + "- Distinguish a proxy/policy denial, which raises an operator approval request in OpenShell, from other failures such as DNS, timeout, or TLS errors; only a policy denial is something the operator can approve.", + "- Do not claim unrestricted host or internet access either. When unsure, attempt the action and rely on the real result instead of speculating about the environment.", "", ].filter((line): line is string => Boolean(line)); return lines.join("\n");