From e356a29aa9f0b97964bb3ec17d91a2cd71c4e92a Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 15 Aug 2026 07:11:27 -0500 Subject: [PATCH] chore: adopt the house .claude/ gitignore pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `.claude/worktrees/` holds whole checkouts — node_modules and all — inside the repo, so `git add -A` from the repo root would stage a second copy of the tree. It has shown up as untracked in every mission run against this repo so far. The shape is claude-infra's rather than invented here: `.claude/*` plus the whitelist that its README and `sync-repo.sh` both specify. Two properties a narrower `.claude/worktrees/` entry would not have: - Deny by default. Anything new under `.claude/` is ignored unless it is named, instead of needing a fresh line every time Claude Code grows a directory. - The repo-level install keeps working. Cloud sessions have no `~/.claude` to read agents, hooks or `landed.sh` from, so those have to be committed here. `sync-repo.sh` reports on this file and never edits it, and what it checks for is exactly this pattern. Mind the star. `.claude/` without it excludes the directory itself, and git never descends into an excluded directory, so `!` negations under it fail silently while looking correct. `.claude/*` excludes the children instead, which is what makes the whitelist work at all. One addition to the house list: `!.claude/settings.json`. claude-infra's whitelist omits it while its own setup prompt says to add the PreToolUse blocks to the repo's `.claude/settings.json` and land it as a PR — which the pattern as written makes impossible. Filed as rdtiv/claude-infra#12; this line comes back out if that resolves the other way. `settings.local.json` stays ignored regardless, which is correct. Verified with `git check-ignore` rather than by reading the pattern: worktrees, `settings.local.json` and any unnamed new path are ignored; `agents/`, `hooks/`, `commands/`, `scripts/`, `workflows/`, `settings.json` and `.claude-infra-version` are trackable. Gates: npm run typecheck 0, npm run typecheck:py 0, npm run verify:docs 0. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01NsAeobZPagwRXXXDzqE6bW --- .gitignore | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.gitignore b/.gitignore index f781ee5..a717dae 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,31 @@ usage.csv .venv/ __pycache__/ *.pyc + +# Claude Code. The blanket sweeps everything under .claude/, which is what +# keeps mission worktrees out: they are whole checkouts — node_modules and all — +# living inside the repo, so `git add -A` here would otherwise stage a second +# copy of the tree. +# +# Mind the star. `.claude/` without it excludes the directory itself, and git +# never descends into an excluded directory, so `!` negations under it silently +# do nothing. `.claude/*` excludes the children instead, which is what makes +# the whitelist below work at all. +# +# The whitelist is claude-infra's house pattern (see its README and the report +# in sync-repo.sh, which checks this file and never edits it). It exists for the +# repo-level install: cloud sessions have no `~/.claude` to read agents, hooks +# or landed.sh from, so those have to be committed here to work at all. +# +# `!.claude/settings.json` is the one addition — claude-infra's list omits it +# while its own setup prompt says to commit that file. See +# https://github.com/rdtiv/claude-infra/issues/12; drop this line if that +# resolves the other way. `settings.local.json` stays ignored either way. +.claude/* +!.claude/agents/ +!.claude/hooks/ +!.claude/commands/ +!.claude/scripts/ +!.claude/workflows/ +!.claude/.claude-infra-version +!.claude/settings.json