fix(prompt): OCP_LOCAL_TOOLS wrapper no longer hard-codes a tool list (closes #185) (#191)

The positive local-tools wrapper (server.mjs) claimed the model has "full access
to the local filesystem, working directory, and shell through your available
tools (Bash, Read, Write, Edit, Glob, Grep, etc.)". That over-promises when an
operator narrows CLAUDE_ALLOWED_TOOLS (e.g. to Read,Grep): the model is told it
has Bash/Write/shell it doesn't hold, then attempts a non-granted tool and gets
denied. The default set matches the text, so the primary/OpenClaw path was fine —
but the enumeration was a prompt-honesty mismatch (flagged in the #182 fact-check).

Reworded to flip the POSTURE only ("you may use your available local tools … do
not assume access beyond the tool set provided to you in this session") without
enumerating specific tools or asserting shell/write capability. The model learns
its real tools from the tool definitions claude is given (--allowedTools), so the
enumeration was redundant as well as fragile — now honest under any allowed set.

No const reordering / no CONFIG_EPOCH change (still a constant; the epoch-fold
test confirms toggling still invalidates the cache with the new text). Test
markers updated (selectPromptWrapper unit + the boot-server integration assertion
that the positive wrapper reaches the -p spawn). Suite 449/0.

Rule 2: OCP-owned prompt composition, no wire change, no cli.js citation.

Closes #185

Co-authored-by: dtzp555 <dtzp555@gmail.com>
Co-authored-by: Claude <claude-opus-4-8> <noreply@anthropic.com>
This commit is contained in:
dtzp555-max
2026-07-23 17:38:41 +10:00
committed by GitHub
co-authored by taodeng Claude <claude-opus-4-8> <noreply@anthropic.com>
parent 8aac87aa61
commit a32bc9af17
2 changed files with 3 additions and 3 deletions
+2 -2
View File
@@ -910,7 +910,7 @@ test("appendOperatorPrompt: operator value is trimmed before appending", () => {
console.log("\nOCP_LOCAL_TOOLS wrapper + safety gate:");
const NEG = "You do NOT have access to any local filesystem";
const POS = "You have full access to the local filesystem";
const POS = "you may use your available local tools";
test("selectPromptWrapper: default (disabled) returns the negative wrapper BYTE-IDENTICAL", () => {
// Mutation-proof: flip the ternary and the default path leaks the positive wrapper.
@@ -967,7 +967,7 @@ import { fileURLToPath as _ltF2P } from "node:url";
const LT_SERVER = _ltF2P(new URL("./server.mjs", import.meta.url));
const LT_POSIX = process.platform !== "win32"; // fake is a /bin/sh script; CI is POSIX
const LT_NEG_MARK = "You do NOT have access to any local filesystem";
const LT_POS_MARK = "You have full access to the local filesystem";
const LT_POS_MARK = "you may use your available local tools";
// Fake claude: record the --system-prompt it was spawned with, bump an optional spawn counter,
// then emit a minimal valid stream-json response so the request completes (and caches).
const LT_FAKE = `#!/bin/sh