From 709627319dc7c0ebf31b2e70e0d8f7c054a3eedc Mon Sep 17 00:00:00 2001 From: taihartman Date: Wed, 5 Aug 2026 21:18:54 -0400 Subject: [PATCH] fix(cross-model): send grok peers the prompt verbatim on read-only routes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `grok --prompt-file` does not send the file as given by default. Past roughly 50KB the CLI writes a large-prompt offload file, inlines a bounded preview in its place, and expects the agent to read the remainder back with a file tool. `--verbatim` ("Send the prompt exactly as given", grok 0.2.118) is what turns that off. The three peer scripts missing the flag are the read-only reviewers, and they are exactly the ones that cannot survive the offload: - ce-doc-review passes `--deny Read`, so the offloaded prompt is unrecoverable. Observed symptom: the peer narrates that the read was blocked and returns findings quoting text that does not exist in the reviewed document. - ce-code-review and ce-pov do allow Read, but the offload file lives outside the `--cwd` they pin, and any recovery attempt burns turns against a tight `--max-turns` budget on a `--json-schema` route that returns nothing at all if it runs out. skills/ce-work/scripts/cross-model-work.sh is the in-tree precedent — it already passes `--verbatim`, and it is safe twice over because it also grants `--tools Read,Write,Edit` and could therefore recover an offloaded prompt without the flag. That inversion is why this was missed: the flag landed first on the one route whose permissions made it least necessary, and was never carried to the stricter reviewers, where it is the only thing standing between a peer and a fabricated review. The tighter the sandbox, the more essential `--verbatim` is. The fix is the flag, not weaker isolation — `--deny Read` stays as it is. Each route-safety test now pins `--verbatim` on its grok-cli adapter; all three fail against the pre-fix scripts. --- .../ce-code-review/scripts/cross-model-adversarial-review.sh | 4 +++- skills/ce-doc-review/scripts/cross-model-doc-review.sh | 4 +++- skills/ce-pov/scripts/cross-model-pov.sh | 4 +++- tests/skills/ce-code-review-cross-model-routes.test.ts | 3 +++ tests/skills/ce-doc-review-cross-model-routes.test.ts | 3 +++ tests/skills/ce-pov-cross-model-routes.test.ts | 3 +++ 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/skills/ce-code-review/scripts/cross-model-adversarial-review.sh b/skills/ce-code-review/scripts/cross-model-adversarial-review.sh index f9f3907e5..84e9d6684 100755 --- a/skills/ce-code-review/scripts/cross-model-adversarial-review.sh +++ b/skills/ce-code-review/scripts/cross-model-adversarial-review.sh @@ -224,7 +224,9 @@ adapter_argv() { grok-cli) # Read allowed (in-tree context); deny writes / shell / subagents / web / MCP. # Schema forces non-streaming json on grok — keep hard-only (no PEERLOG idle). - printf '%s\0' grok --prompt-file "$PROMPT_FILE" --model "$(route_model grok-cli)" --effort high \ + # --verbatim: without it grok offloads a large prompt to a session file and + # sends only a preview, spending scarce turns to re-read what it was given. + printf '%s\0' grok --prompt-file "$PROMPT_FILE" --verbatim --model "$(route_model grok-cli)" --effort high \ --cwd "$PEER_WORKDIR" --permission-mode dontAsk [ -z "${LARGE_DIFF_CONTEXT_DIR:-}" ] || printf '%s\0' --allow "Read($LARGE_DIFF_CONTEXT_DIR/**)" printf '%s\0' --deny Edit --deny Write --deny Bash --deny Task --deny 'mcp__*' \ diff --git a/skills/ce-doc-review/scripts/cross-model-doc-review.sh b/skills/ce-doc-review/scripts/cross-model-doc-review.sh index 970477ff6..b4f925045 100755 --- a/skills/ce-doc-review/scripts/cross-model-doc-review.sh +++ b/skills/ce-doc-review/scripts/cross-model-doc-review.sh @@ -221,7 +221,9 @@ adapter_argv() { ;; grok-cli) # Schema forces buffered json — hard-only, no PEERLOG idle (#1270). - printf '%s\0' grok --prompt-file "$PROMPT_FILE" --model "$(route_model grok-cli)" --effort high \ + # --verbatim: without it grok offloads a large prompt to a session file and + # sends only a preview — unrecoverable here, because Read is denied below. + printf '%s\0' grok --prompt-file "$PROMPT_FILE" --verbatim --model "$(route_model grok-cli)" --effort high \ --cwd "$PEER_WORKDIR" --permission-mode dontAsk \ --deny Read --deny Edit --deny Write --deny Bash --deny Task --deny 'mcp__*' \ --disable-web-search --no-subagents --max-turns 15 \ diff --git a/skills/ce-pov/scripts/cross-model-pov.sh b/skills/ce-pov/scripts/cross-model-pov.sh index 858796eda..4a64fcd14 100755 --- a/skills/ce-pov/scripts/cross-model-pov.sh +++ b/skills/ce-pov/scripts/cross-model-pov.sh @@ -216,7 +216,9 @@ adapter_argv() { ;; grok-cli) # Schema forces buffered json — hard-only, no PEERLOG idle (#1270). - printf '%s\0' grok --prompt-file "$PROMPT_FILE" --model "$(route_model grok-cli)" --effort high \ + # --verbatim: without it grok offloads a large prompt to a session file and + # sends only a preview, spending scarce turns to re-read what it was given. + printf '%s\0' grok --prompt-file "$PROMPT_FILE" --verbatim --model "$(route_model grok-cli)" --effort high \ --cwd "$READ_ROOT" --permission-mode dontAsk \ --deny Edit --deny Write --deny Bash --deny Task --deny 'mcp__*' \ --no-subagents --max-turns 15 \ diff --git a/tests/skills/ce-code-review-cross-model-routes.test.ts b/tests/skills/ce-code-review-cross-model-routes.test.ts index 6551bad7a..233ced4f4 100644 --- a/tests/skills/ce-code-review-cross-model-routes.test.ts +++ b/tests/skills/ce-code-review-cross-model-routes.test.ts @@ -346,6 +346,9 @@ printf '%s' '{"structured_output":{"reviewer":"adversarial","findings":[],"resid expect(cmd).toContain("--deny Edit") expect(cmd).toContain("--deny Write") expect(cmd).toContain("--deny Bash") + // Without --verbatim grok offloads a large prompt to a session file and + // sends only a preview, so the peer reviews a diff it never received. + expect(cmd).toContain("--verbatim") expect(cmd).toContain("--disable-web-search") expect(cmd).toContain("--no-subagents") expect(cmd).toContain("--permission-mode dontAsk") diff --git a/tests/skills/ce-doc-review-cross-model-routes.test.ts b/tests/skills/ce-doc-review-cross-model-routes.test.ts index 460336032..27b91774e 100644 --- a/tests/skills/ce-doc-review-cross-model-routes.test.ts +++ b/tests/skills/ce-doc-review-cross-model-routes.test.ts @@ -280,6 +280,9 @@ printf '%s' '{"structured_output":{"reviewer":"adversarial","findings":[],"resid test("grok CLI: deny Read + web/subagents off + dontAsk + effort high", () => { const cmd = emitAdapter("grok-cli") expect(cmd).toContain("--deny Read") + // Load-bearing with --deny Read: without --verbatim grok offloads a large + // prompt to a session file the peer is then forbidden to read back. + expect(cmd).toContain("--verbatim") expect(cmd).toContain("--disable-web-search") expect(cmd).toContain("--no-subagents") expect(cmd).toContain("--permission-mode dontAsk") diff --git a/tests/skills/ce-pov-cross-model-routes.test.ts b/tests/skills/ce-pov-cross-model-routes.test.ts index efbe8ce10..b9d9ccd74 100644 --- a/tests/skills/ce-pov-cross-model-routes.test.ts +++ b/tests/skills/ce-pov-cross-model-routes.test.ts @@ -107,6 +107,9 @@ describe("ce-pov cross-model route safety", () => { expect(emit("grok-cli")).toContain("--deny Edit") expect(emit("grok-cli")).toContain("--deny Write") expect(emit("grok-cli")).toContain("--deny Bash") + // Without --verbatim grok offloads a large prompt to a session file and + // sends only a preview, so the peer answers on context it never received. + expect(emit("grok-cli")).toContain("--verbatim") expect(emit("grok-cli")).toContain("--output-format json") expect(emit("grok-cli")).not.toContain("stream-json") for (const route of ["grok-cursor", "cursor", "composer"]) {