Skip to content

Interceptor debug screenshots (interceptor-screenshot-*.png) aren't gitignored — stray captures accumulate in ~/.claude root and get pushed to the user's backup repo #1530

Description

@xmasyx

Summary

Stray Interceptor debug screenshots (interceptor-screenshot-<epoch>.png) accumulate in the ~/.claude repo root and are not covered by the shipped .gitignore. Because they are untracked-but-not-ignored, a routine git add -A && git commit sweeps them into the user's private backup repo, silently bloating it with unrecoverable binary debug artifacts.

Root cause

Two upstream mechanisms are meant to keep these files out, and there is a gap between them:

  1. LifeOS/install/hooks/ContextReduction.hook.sh (≈L187–192) redirects interceptor screenshot --save into /tmp/pai-screenshots:

    # --- Interceptor screenshot --save — redirect output to /tmp/pai-screenshots ---
    # Prevents stray interceptor-screenshot-*.jpg files from landing in the cwd
    # (typically ~/.claude) when a subagent calls the command without the skill's
    # `cd /tmp/pai-screenshots` prefix. Wraps the call in a subshell that chdirs first.
    elif echo "$MATCH_CMD" | grep -qE '^interceptor[[:space:]]+screenshot([[:space:]]|$)' && echo "$MATCH_CMD" | grep -qE -- '--save'; then
      REWRITTEN="${ENV_PREFIX}mkdir -p /tmp/pai-screenshots && ( cd /tmp/pai-screenshots && $CMD_BODY )"

    This is best-effort only: it fires exclusively when the PreToolUse command string matches ^interceptor screenshot … --save and the call actually passes through this hook. Any invocation that bypasses it — a subagent/tool that shells the binary by a different form, a wrapper, or a path that doesn't traverse the PreToolUse rewrite — writes the default interceptor-screenshot-<epoch>.png straight into the current working directory, which for the main session is ~/.claude.

  2. LifeOS/install/LIFEOS/DOCUMENTATION/SystemUserBoundary.md already classifies these as runtime files that should be git-excluded:

    `~/.claude/interceptor-screenshot-*.{png,jpg}` (root) | RUNTIME (debug captures) | yes

    and the RUNTIME-STATE section states such files are "Already excluded from git via .gitignore in most cases."

The gap: the shipped .gitignore (the one whose LifeOS/MEMORY/ rule LifeOS/install/LIFEOS/TOOLS/LifeosUpgrade.ts:120 detects with /^LifeOS\/MEMORY\//m) contains no rule for interceptor-screenshot-*. So the documentation promises these are git-excluded, but they are not — the redirect hook is the only line of defense, and it is best-effort.

Why it matters (impact)

  • Silent accumulation. Captures that slip past the redirect land in ~/.claude root with no error and no visible signal. They pile up unnoticed — a real install accumulated dozens (~9 MB) before anyone looked.
  • Backup pollution, and it's permanent. These files are untracked but not ignored, so the moment any workflow runs git add -A (or the user does), they are committed and pushed to the private ~/.claude backup remote. Once in history they bloat every clone and every diff, and they are exactly the regenerable-binary noise a backup should never carry.
  • Doc-vs-reality mismatch. SystemUserBoundary.md asserts these are already git-excluded, so a maintainer auditing the boundary would reasonably assume the safety net exists when it does not.

Suggested fix

Add an Interceptor-capture rule to the shipped .gitignore (the same file that carries the LifeOS/MEMORY/ rule referenced by LifeosUpgrade.ts:120):

# Interceptor debug screenshots — stray captures that bypass the ContextReduction
# redirect (subagent / non-matching invocation form) land in the ~/.claude root.
# Keep them out of the user's backup repo. See SystemUserBoundary.md (RUNTIME).
interceptor-screenshot-*.png
interceptor-screenshot-*.jpg
interceptor-screenshot-*.webp
interceptor-capture-*.png

This makes the durable backstop match what SystemUserBoundary.md already promises, so a capture that escapes the best-effort redirect can no longer be committed. The .webp variant is included because interceptor screenshot --save --format webp is a documented invocation (skills/Interceptor/References/CommandReference.md).

Optionally, the comment on ContextReduction.hook.sh L188 could be broadened from *.jpg to reflect that the default capture format is .png (the redirect action already handles all formats; only the comment is format-specific).

Reproduction

  1. From a session whose CWD is ~/.claude, cause an interceptor screenshot --save to run in a way that does not pass through the ContextReduction PreToolUse rewrite (e.g. a subagent invocation).
  2. Observe interceptor-screenshot-<epoch>.png written to ~/.claude.
  3. git status --porcelain | grep interceptor-screenshot shows them as untracked.
  4. git check-ignore interceptor-screenshot-*.png returns nothing → they are not ignored and would be included by git add -A.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions