Skip to content

Wrap fetched content in untrusted output markers#577

Open
VACInc wants to merge 5 commits intoopenclaw:mainfrom
VACInc:untrusted-fetch-wrappers
Open

Wrap fetched content in untrusted output markers#577
VACInc wants to merge 5 commits intoopenclaw:mainfrom
VACInc:untrusted-fetch-wrappers

Conversation

@VACInc
Copy link
Copy Markdown

@VACInc VACInc commented May 10, 2026

Summary

  • Add --wrap-untrusted and GOG_WRAP_UNTRUSTED to opt into external untrusted-content wrappers for JSON/raw output fields that carry fetched Google Workspace/API text.
  • Wrap likely user/content-bearing fields and sheet-like values while preserving IDs, URLs, MIME metadata, pagination tokens, and other tool-chaining fields.
  • Sanitize spoofed wrapper markers and common LLM special tokens inside wrapped text, then annotate wrapped top-level JSON objects with externalContent metadata.
  • Update README, raw API docs, the gog agent skill, and the changelog with the new agent-facing flag.

Problem

Google API fetches can return email bodies, document text, sheet cells, notes, comments, titles, and names that may later be pasted into LLM/agent contexts. gog did not have an output-level untrusted boundary similar to OpenClaw's web fetch/search wrappers.

Root Cause

Fetched Google content and stable metadata were emitted through the same JSON/raw writers. Agents had to remember which fields were external content rather than getting explicit untrusted-content markers at the output boundary.

Exact Change

  • Adds internal/outfmt wrapping helpers that recursively inspect JSON-compatible payloads, wrap content-bearing strings in <<<EXTERNAL_UNTRUSTED_CONTENT ...>>> markers, and sanitize nested marker spoofing.
  • Wires the wrapper into WriteJSON and WriteRaw when the root context enables it.
  • Adds the global --wrap-untrusted flag and GOG_WRAP_UNTRUSTED env default.
  • Leaves default output unchanged unless the flag/env var is enabled.

Scope Boundary

This only changes JSON/raw output when --wrap-untrusted or GOG_WRAP_UNTRUSTED=1 is set. It does not change default output, plain/table output, Google API requests, auth behavior, or mutation semantics.

Real behavior proof

Behavior fixed: opt-in Google fetched text fields are marked as external untrusted content while metadata stays machine-usable.

Environment: local unit tests in this checkout, using the real outfmt.WriteJSON / outfmt.WriteRaw paths and root flag parsing.

Command:

go test ./internal/outfmt ./internal/cmd

Copied output:

ok  	github.com/steipete/gogcli/internal/outfmt	0.002s
ok  	github.com/steipete/gogcli/internal/cmd	20.125s

Observed result: wrapper tests confirm content fields and sheet values contain EXTERNAL_UNTRUSTED_CONTENT, IDs/URLs/document IDs remain unwrapped, spoofed start/end markers are sanitized, metadata-only payloads are not annotated, and both the flag and env default enable the wrapper.

Verification

  • go test ./internal/outfmt ./internal/cmd
  • go test -vet=off ./...
  • make fmt-check

Blocked or unrelated check attempts

  • Initial make fmt-check attempt exited 2 after running the formatter tools because the feature Go diff was still intentionally unstaged; reran after staging the formatted files and it passed.

What was not tested

  • Live Google API fetches were not run. The wrapper is covered at the shared JSON/raw output layer and root flag parser, which is the closest feasible non-live coverage for all fetch commands.

@VACInc VACInc marked this pull request as ready for review May 10, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants