feat(harness): extend .env guard to pi harness + redact broad-grep leaks - #59
Merged
Merged
Conversation
Follow-up to ENG-2925 (#57), completing ENG-2926. - pi harness: wrap the built-in Read/Edit/Write/Ls/Find/Grep tools so a call whose input targets a secret file (.env, …) is refused before it runs — parity with the anthropic PreToolUse deny. Reuses toolInputTouchesSecret; pi's path fields (path/glob/dir/directory) are now covered too. - anthropic harness: add a PostToolUse hook that strips .env-sourced lines from Grep output via updatedToolOutput. The PreToolUse deny only fires when a tool *names* a secret path, so a repo-wide grep (path ".") could still surface .env lines; this closes that residual. - secret-paths.ts: add redactSecretGrepLines + the pi path-field keys, with tests.
4 tasks
itelo
added a commit
that referenced
this pull request
Aug 25, 2026
#63) Completes the broad-grep residual left by #59. The pi tool wrapper already blocks a grep that *names* .env, but a repo-wide grep (path ".") still scanned it and returned its lines. The wrapper holds each tool's result, so it can now strip .env-sourced lines from the grep tool's output via redactSecretGrepLines — parity with the anthropic harness's PostToolUse redaction. (Corrects #59's note that pi has "no output-rewrite hook": the wrapper itself is that hook.)
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.
Summary
Completes ENG-2926, the two follow-ups scoped out of ENG-2925 (#57, which hard-blocked
.envreads in the anthropic harness and dropped WebFetch).1. Pi harness guard (was: prompt-only)
src/lib/steps/harness/pi.tsnow wraps pi's built-in Read/Edit/Write/Ls/Find/Grep tools (guardSecretFileTools): a call whose input targets.env/.env.*(except.env.example) is refused before it runs, returning a blockedAgentToolResultso the agent sees it and moves on. This brings the eval-only challenger to parity with the anthropicPreToolUsedeny. Reuses the sharedtoolInputTouchesSecret;PATH_BEARING_KEYSgains pi's field names (path,glob,dir,directory).2. Broad-grep residual (anthropic)
The
PreToolUsedeny only fires when a tool names a secret path, so a repo-wideGrep(path: ".") could still scan.envand return its lines. Added aPostToolUsehook that strips.env-sourced lines from Grep output viaupdatedToolOutput(precise: it filters on each grep line's leadingpath:token, so no heuristic false positives;.env.examplelines are kept).Both reuse
isSecretFilePath— one source of truth for what counts as a secret file.Verified against the real SDK/pi types
PostToolUseHookSpecificOutput.updatedToolOutput("Replaces the tool output before it is sent to the model").ToolDefinition.execute(toolCallId, params, signal, onUpdate, ctx)returningAgentToolResult = { content, details, terminate? }; input field names read from each tool's schema (read→path,grep/find→path+glob,ls→dir/directory).Known residual (documented)
pi's broad-grep output can't be redacted the way anthropic's can — pi exposes no tool-output rewrite hook — but pi is eval-only and the eval workspace carries no real secret, so direct-
.envblocking is sufficient there.Testing
npm run lintcleannpm run typecheckcleannpm test— 158 passed (+3: grep redaction + pi path fields)Security & Compliance
🤖 Generated with Claude Code