Hook check-issue.sh blocks cross-repo agent dispatches in /tmp worktrees #305

Open
opened 2026-04-26 00:01:29 +00:00 by forgejo_admin · 0 comments
Contributor

Type

Bug

Lineage

Discovered scope from Track A of westside-admin bootstrap (2026-04-25). Dev agent reported the hook blocking Write operations against absolute paths outside the spawning agent's worktree, and .claude-no-enforce opt-out file in the target repo not bypassing it. Cross-repo dispatch is becoming common (every multi-repo bootstrap arc hits this), so worth fixing before it shapes agent prompts into Bash-heredoc workarounds that defeat the safety the hook is meant to enforce.

Repo

~/.claude/hooks/ (claude-custom repo)

What Broke

The PreToolUse hook on Write rejects writes to absolute paths whose nearest containing repo is NOT the spawning session's branch context. A dev agent dispatched to clone forgejo_admin/westside-admin to /tmp/westside-admin-scaffold-sveltekit and write files there had its Write calls blocked. Adding a .claude-no-enforce file inside the target repo did NOT bypass the hook.

The agent worked around it by switching every file creation to Bash heredoc (cat <<EOF > /tmp/.../file), which bypasses the hook entirely — defeating the safety the hook was designed to enforce.

Repro Steps

  1. From a session whose cwd is on a feature branch in repo A (e.g. ~/pal-e-platform on branch 290-payment-pipeline-observability)
  2. Spawn a dev agent and direct it to:
    • git clone <other-repo> /tmp/test-clone
    • cd /tmp/test-clone && git checkout -b some-branch
    • Call Write on /tmp/test-clone/foo.txt
  3. Observe the Write is blocked even though /tmp/test-clone/foo.txt lives in a completely different repo from the spawning session's cwd
  4. Add /tmp/test-clone/.claude-no-enforce and retry — observe still blocked

Expected Behavior

  • The hook should resolve the target file's containing repo (walk up from absolute path to nearest .git) and apply enforcement based on THAT repo's branch and opt-out files.
  • .claude-no-enforce placed in a target repo should bypass the hook for Writes into that repo.
  • Existing in-repo enforcement should still work — same-repo Writes against the spawning branch should remain governed.

Environment

  • Claude Code, Linux 6.18.9-arch1-2
  • Hook location: ~/.claude/hooks/check-issue.sh (suspected — verify with grep -r check-issue ~/.claude/hooks/)
  • Possibly related: ~/.claude/hooks/check-issue-template.sh (the cousin hook that just blocked Ava's own issue creation in this same session — different surface, possibly same enforcement-scoping bug)
  • Reproduces consistently for any cross-repo dispatch using /tmp/{repo}-{branch} clone pattern (3 of 5 tracks in the current westside-admin bootstrap wave hit it)

User Story

story:agent-dispatch-ergonomics — As a main-session orchestrator, I need to dispatch dev agents to clone target repos to /tmp/{repo}-{branch} and Write files there without the PreToolUse hook on the spawning session's cwd blocking those Writes, so that cross-repo bootstrap arcs (typical for any new service onboarding) don't force agents into Bash-heredoc workarounds that bypass safety entirely.

Context

Cross-repo dispatch pattern is now standard. Today's westside-admin bootstrap dispatch wave: Track A (clone westside-admin to /tmp), Track B (clone pal-e-deployments to /tmp), Track E (clone pal-e-services to /tmp) — 3 of 5 tracks use it. Same pattern will recur on every new-service bootstrap arc.

File Targets

  • ~/.claude/hooks/check-issue.sh
  • Possibly: ~/.claude/hooks/check-issue-template.sh

Acceptance Criteria

  • Hook resolves target file's containing repo from the absolute path, not from the spawning session's cwd
  • .claude-no-enforce in a target repo bypasses the hook for Writes into that repo
  • Cross-repo dispatch with /tmp/{repo}-{branch} cwd: agent can Write freely without falling back to Bash heredocs
  • Same-repo enforcement unchanged (no regression)

Test Expectations

  • Manual repro: clone any repo to /tmp/test-clone, dispatch a child agent with cwd /tmp/test-clone, have it call Write /tmp/test-clone/foo.txt — should succeed
  • Counter-test: same agent calling Write ~/pal-e-platform/foo.txt (a path outside its assigned worktree) should still be blocked

Constraints

  • Don't disable the hook outright — its in-repo enforcement is load-bearing for ticket-template discipline
  • Don't require dispatch prompts to set magic env vars or include opt-out boilerplate — the fix should be in the hook itself

Checklist

  • Reviewed via /review-ticket and moved backlog → todo
  • Hook reads target path argument and resolves containing repo
  • Tested with cross-repo dispatch (positive case)
  • Tested with same-repo enforcement (regression case)
  • PR opened in claude-custom with Closes #THIS
  • Triggered by: Track A dev agent report (2026-04-25)
  • Sibling concern: Track A's agent reported it; Tracks B and E used /tmp clones too — likely worked around silently
  • Memory: feedback_smaller_scopes_parallel (cross-repo parallel dispatch is the model — this hook is friction against it)
### Type Bug ### Lineage Discovered scope from Track A of westside-admin bootstrap (2026-04-25). Dev agent reported the hook blocking Write operations against absolute paths outside the spawning agent's worktree, and `.claude-no-enforce` opt-out file in the target repo not bypassing it. Cross-repo dispatch is becoming common (every multi-repo bootstrap arc hits this), so worth fixing before it shapes agent prompts into Bash-heredoc workarounds that defeat the safety the hook is meant to enforce. ### Repo ~/.claude/hooks/ (claude-custom repo) ### What Broke The PreToolUse hook on `Write` rejects writes to absolute paths whose nearest containing repo is NOT the spawning session's branch context. A dev agent dispatched to clone `forgejo_admin/westside-admin` to `/tmp/westside-admin-scaffold-sveltekit` and write files there had its `Write` calls blocked. Adding a `.claude-no-enforce` file inside the target repo did NOT bypass the hook. The agent worked around it by switching every file creation to Bash heredoc (`cat <<EOF > /tmp/.../file`), which bypasses the hook entirely — defeating the safety the hook was designed to enforce. ### Repro Steps 1. From a session whose cwd is on a feature branch in repo A (e.g. `~/pal-e-platform` on branch `290-payment-pipeline-observability`) 2. Spawn a dev agent and direct it to: - `git clone <other-repo> /tmp/test-clone` - `cd /tmp/test-clone && git checkout -b some-branch` - Call `Write` on `/tmp/test-clone/foo.txt` 3. Observe the Write is blocked even though `/tmp/test-clone/foo.txt` lives in a completely different repo from the spawning session's cwd 4. Add `/tmp/test-clone/.claude-no-enforce` and retry — observe still blocked ### Expected Behavior - The hook should resolve the **target file's containing repo** (walk up from absolute path to nearest `.git`) and apply enforcement based on THAT repo's branch and opt-out files. - `.claude-no-enforce` placed in a target repo should bypass the hook for Writes into that repo. - Existing in-repo enforcement should still work — same-repo Writes against the spawning branch should remain governed. ### Environment - Claude Code, Linux 6.18.9-arch1-2 - Hook location: `~/.claude/hooks/check-issue.sh` (suspected — verify with `grep -r check-issue ~/.claude/hooks/`) - Possibly related: `~/.claude/hooks/check-issue-template.sh` (the cousin hook that just blocked Ava's own issue creation in this same session — different surface, possibly same enforcement-scoping bug) - Reproduces consistently for any cross-repo dispatch using `/tmp/{repo}-{branch}` clone pattern (3 of 5 tracks in the current westside-admin bootstrap wave hit it) ### User Story story:agent-dispatch-ergonomics — As a main-session orchestrator, I need to dispatch dev agents to clone target repos to `/tmp/{repo}-{branch}` and Write files there without the PreToolUse hook on the spawning session's cwd blocking those Writes, so that cross-repo bootstrap arcs (typical for any new service onboarding) don't force agents into Bash-heredoc workarounds that bypass safety entirely. ### Context Cross-repo dispatch pattern is now standard. Today's westside-admin bootstrap dispatch wave: Track A (clone westside-admin to /tmp), Track B (clone pal-e-deployments to /tmp), Track E (clone pal-e-services to /tmp) — 3 of 5 tracks use it. Same pattern will recur on every new-service bootstrap arc. ### File Targets - ~/.claude/hooks/check-issue.sh - Possibly: ~/.claude/hooks/check-issue-template.sh ### Acceptance Criteria - [ ] Hook resolves target file's containing repo from the absolute path, not from the spawning session's cwd - [ ] `.claude-no-enforce` in a target repo bypasses the hook for Writes into that repo - [ ] Cross-repo dispatch with `/tmp/{repo}-{branch}` cwd: agent can `Write` freely without falling back to Bash heredocs - [ ] Same-repo enforcement unchanged (no regression) ### Test Expectations - Manual repro: clone any repo to `/tmp/test-clone`, dispatch a child agent with cwd `/tmp/test-clone`, have it call `Write /tmp/test-clone/foo.txt` — should succeed - Counter-test: same agent calling `Write ~/pal-e-platform/foo.txt` (a path outside its assigned worktree) should still be blocked ### Constraints - Don't disable the hook outright — its in-repo enforcement is load-bearing for ticket-template discipline - Don't require dispatch prompts to set magic env vars or include opt-out boilerplate — the fix should be in the hook itself ### Checklist - [ ] Reviewed via /review-ticket and moved backlog → todo - [ ] Hook reads target path argument and resolves containing repo - [ ] Tested with cross-repo dispatch (positive case) - [ ] Tested with same-repo enforcement (regression case) - [ ] PR opened in claude-custom with `Closes #THIS` ### Related - Triggered by: Track A dev agent report (2026-04-25) - Sibling concern: Track A's agent reported it; Tracks B and E used /tmp clones too — likely worked around silently - Memory: `feedback_smaller_scopes_parallel` (cross-repo parallel dispatch is the model — this hook is friction against it)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/pal-e-platform#305
No description provided.