Skip to content

fix(guardrails): block-root-delete-target refuses agent test temp dirs like D:/worktrees/.tmp-* #6542

Closed

Description

@kyle-sexton

Problem

block-root-delete-target refuses rm -rf /d/worktrees/.tmp-<n> from agent sessions. These are throwaway test directories that agents create themselves. In one session on one machine, 15 such directories were refused (.tmp-6481, -6484, -6486, -6487, -6494, -6496, -6498, -6501, -6507, -6523, -6526, -6527, -6540, -fragmode, -pr6481), and each one has to be deleted by hand.

The directories exist because test suites must not write to C: on that machine (a deep-copy leak filled C:). So workers set TMPDIR=/d/worktrees/.tmp-<issue>. That path sits outside the session's git toplevel and is not under a temp root the hook recognizes. The hook reads temp roots from its own environment, not from the command's TMPDIR= assignment. Basis: plugins/guardrails/README.md:1485-1487 and :1498-1500.

Why the existing option does not cover it

block_root_delete_target_allowed_roots cannot express "children of D:/worktrees named .tmp-*". An entry holding a glob character grants nothing (README.md:1506). Listing D:/worktrees instead would let agents recursively delete every worktree, which is far too broad.

Options

  1. Accept a name-prefix entry in block_root_delete_target_allowed_roots, for example D:/worktrees/.tmp-, matched against the target's real path. Only direct children whose name starts with the prefix would pass. Every other refusal would stay in force: the root itself, globs that escape, .., symlinks that leave the root.
  2. Remove the cause on the machine side: point the user-level TEMP/TMPDIR at a D: directory, so the guard already treats it as a temp root and workers no longer need a custom TMPDIR. This needs no guard change, but it is per-machine setup.

Recommendation: option 1, so the guard can express a safe, narrow allowance. Option 2 can be documented as the alternative.

Acceptance

  • rm -rf /d/worktrees/.tmp-6527 passes when D:/worktrees/.tmp- is listed.
  • rm -rf /d/worktrees, rm -rf /d/worktrees/other-worktree, rm -rf /d/worktrees/.tmp- (the bare prefix), and a .tmp-x symlink pointing outside are all still refused.
  • A stay-quiet test fails before the fix (docs/conventions/hook-precision).

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 7, 2026
  2. github-actions commented on Oct 7, 2026

    @github-actions
    Contributor

    Thanks for the report. Automated triage handed this issue to a maintainer.

    Automated triage. A maintainer reviews it.

  3. added
    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.
    on Oct 7, 2026
  4. cc-bb-aa commented on Oct 8, 2026

    @cc-bb-aa

    The guard is doing its job too broadly. Allowlisting per worktree temp prefixes the agent itself created keeps the protection while unblocking legitimate cleanup. Matching on the session owned path rather than the string pattern avoids both false positives and the inevitable bypass attempts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.needs-triageNot yet classified. Floor until a type and one priority tier are set.

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions