[Feature] Auto-approve Bash invocations of files authored in the same session
Summary
When Claude writes a script via the Write tool and then immediately tries to execute it via Bash (e.g. tools/foo/test.sh 2>&1 | tail -8), the permission system prompts. This friction has no safety benefit: the file's contents are in the session transcript, the agent just authored it, and the only decision-maker who could authorize execution is the same user who'd approve the prompt anyway.
A hook can work around this, but only by reading the transcript itself — there's no first-class notion of "session-authored file" in the permission model.
Concrete repro
- Ask Claude to write a new shell script:
Write: tools/host-test/test.sh(any content). - Claude runs
tools/host-test/test.shorbash tools/host-test/test.sh. - Result: permission prompt despite the file being authored seconds earlier.
Steady-state behavior in long sessions: every create-then-execute loop costs a prompt per script. Compounds painfully for iterative harness development.
Two things that would solve this cleanly
Option A — Built-in permission decision
Add a built-in permissionDecision: "session-authored" (or similar auto-approve rule) that evaluates true when the first resolvable path token in the command matches a file_path from any Write/Edit/MultiEdit tool_use recorded in the current session.
Option B — Expose session tool-use history to PreToolUse hooks
Less invasive: extend the PreToolUse hook stdin payload with a session_tool_use_history field (or similar) listing tool_use events this session, so hooks can implement provenance policies without re-parsing the transcript file on every invocation.
Why both options beat the alternatives
- Broad path allowlists (
Bash(bash tools/**/*.sh:*)) are over-permissive — they allow scripts the user didn't author, defeating the gate. - Session-scoped
fewer-permission-prompts-style allowlists don't apply: newly-authored scripts have no recurring history to learn from. - Hook-layer workaround (reading
$transcript_pathJSONL on every Bash call, extractingWrite/Editfile paths, matching against command's first token) is what I built locally and it works correctly, but it's brittle: every user has to rebuild it, and the transcript format isn't a documented API.
Security analysis
Session-authored-or-edited provenance is a narrow, well-defined trust signal:
- The file exists because the agent asked to write it, and Write already has its own permission layer (
Edit,Write,Edit(path)rules). - If Write was approved, the contents were seen by the user at that moment.
- Execution of a file whose provenance is "this session's agent wrote/edited it this session" is no more dangerous than the Write was.
The blast radius of the proposed auto-approve is strictly ≤ the blast radius already authorized by the existing Write/Edit permission checks.
Hook workaround (for reference)
Until this lands, a PreToolUse Bash hook can read $transcript_path and do:
jq -e --arg p "$resolved_first_token" '
.message.content[]?
| select(.type=="tool_use" and (.name=="Write" or .name=="Edit"))
| .input.file_path
| select(. == $p)
' "$transcript_path" >/dev/null && emit-permission-decision allow
This works, but requires users to know transcript_path is in hook stdin (undocumented guarantee in the public hooks reference), know the JSONL schema, and rebuild this logic per installation. A built-in or first-class hook field would remove that friction.
Environment
- Claude Code CLI 2.1.x (macOS, Apple Silicon)
- Encountered across many sessions, multiple projects.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗