Skip to content

drive-root litter detector misses the /tmp class (single-letter names only) #3493

Description

@kyle-sexton

Problem

scripts/check-drive-root-litter.sh is the post-hoc detector for the Windows path-emission defect that docs/conventions/windows-path-emit/README.md owns: a POSIX path handed to a Windows-native consumer resolves against the current drive and creates a phantom directory at a volume root.

It only matches a drive-root directory whose name is a single letter that is itself a mounted drive. That shape catches the /d/dirD:\d class, but it is blind to the /tmp class.

Observed miss

A disk audit of C:\ on 2026-08-30 found an empty C:\tmp\tmp.rSFIkHm5DO, created at 14:15:56.

Root cause of the artifact: plugins/source-control/skills/worktree/context/create.md:88 runs a bare mktemp -d and prints the result. TMPDIR is unset on that machine and GNU mktemp reads TMPDIR only, so the printed string is the POSIX literal /tmp/tmp.rSFIkHm5DO while the real directory lives under %TEMP%. That string round-trips through the model into a native Write tool call, and node.exe resolves the leading / against the current drive.

The detector scored it zero, because tmp is not a single letter. Nothing on the host reported it.

Why the sibling nets did not catch it either

  • plugins/guardrails/hooks/block-windows-drive-tmp.sh reads .tool_input.command and is registered for Bash and PowerShell, so a Write tool call carrying file_path never reaches it.
  • scripts/check-shell-portability.sh is correctly out of charter; its axis is GNU-vs-BSD userland divergence, and an MSYS path literal is valid GNU shell everywhere.

Proposed fix

Give the detector a known-temp-sink-name class at a drive root, reusing block-windows-drive-tmp.sh's existing sink vocabulary rather than inventing a second list, so the two grow together.

Constraints that must hold: the single-letter class stays byte-equivalent, the cwd-containment false-positive guard extends to the new class, the non-Windows no-op stays first and reported, exit codes stay 0/1/2, and the detector stays advisory per docs/adr/0003-verification-guards-earn-default-on-by-measured-precision.md (it has no measured precision yet).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions