Skip to content

feat(harness): extend .env guard to pi harness + redact broad-grep leaks - #59

Merged
itelo merged 1 commit into
mainfrom
itelo/eng-2926-wizard-extend-env-guard-pi-and-grep
Aug 24, 2026
Merged

feat(harness): extend .env guard to pi harness + redact broad-grep leaks#59
itelo merged 1 commit into
mainfrom
itelo/eng-2926-wizard-extend-env-guard-pi-and-grep

Conversation

@itelo

@itelo itelo commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Completes ENG-2926, the two follow-ups scoped out of ENG-2925 (#57, which hard-blocked .env reads in the anthropic harness and dropped WebFetch).

1. Pi harness guard (was: prompt-only)

src/lib/steps/harness/pi.ts now 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 blocked AgentToolResult so the agent sees it and moves on. This brings the eval-only challenger to parity with the anthropic PreToolUse deny. Reuses the shared toolInputTouchesSecret; PATH_BEARING_KEYS gains pi's field names (path, glob, dir, directory).

2. Broad-grep residual (anthropic)

The PreToolUse deny only fires when a tool names a secret path, so a repo-wide Grep (path: ".") could still scan .env and return its lines. Added a PostToolUse hook that strips .env-sourced lines from Grep output via updatedToolOutput (precise: it filters on each grep line's leading path: token, so no heuristic false positives; .env.example lines are kept).

Both reuse isSecretFilePath — one source of truth for what counts as a secret file.

Verified against the real SDK/pi types

  • Claude Agent SDK: PostToolUseHookSpecificOutput.updatedToolOutput ("Replaces the tool output before it is sent to the model").
  • pi: ToolDefinition.execute(toolCallId, params, signal, onUpdate, ctx) returning AgentToolResult = { content, details, terminate? }; input field names read from each tool's schema (readpath, grep/findpath+glob, lsdir/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-.env blocking is sufficient there.

Testing

  • npm run lint clean
  • npm run typecheck clean
  • npm test — 158 passed (+3: grep redaction + pi path fields)

Security & Compliance

  • Security hardening (defense-in-depth); no secrets in the diff.

🤖 Generated with Claude Code

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.
@itelo
itelo requested a review from razor-x as a code owner August 24, 2026 19:30
@itelo
itelo merged commit e805991 into main Aug 24, 2026
11 checks passed
@itelo
itelo deleted the itelo/eng-2926-wizard-extend-env-guard-pi-and-grep branch August 24, 2026 19:32
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.)
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.

1 participant