Skip to content

chore: adopt the house .claude/ gitignore pattern - #8

Open
rdtiv wants to merge 1 commit into
mainfrom
chore/ignore-mission-worktrees
Open

chore: adopt the house .claude/ gitignore pattern#8
rdtiv wants to merge 1 commit into
mainfrom
chore/ignore-mission-worktrees

Conversation

@rdtiv

@rdtiv rdtiv commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Punch-list item from the #5 / #7 review pass. .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 as untracked in every mission run against this repo so far.

The shape is claude-infra's, not invented here

.claude/* plus the whitelist specified in two places upstream — README.md:327-330 and the check loop at sync-repo.sh:538-540. Adopting it rather than a narrower .claude/worktrees/ buys two things:

  • Deny by default. Anything new under .claude/ is ignored unless named, instead of needing a fresh line each 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 must be committed in-repo. sync-repo.sh reports on this file and never edits it, and what it checks for is exactly this pattern — a narrower entry falls to its else branch and gets no help.

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 deviation, tracked

!.claude/settings.json is not in claude-infra's list, while settings/setup-prompt.template.md:58-65 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 without git add -f. Filed upstream as rdtiv/claude-infra#12. The line comes back out if that resolves the other way; the .gitignore comment says so, so the deviation stays traceable.

settings.local.json remains ignored either way, which is correct.

Verified with git check-ignore, not by reading the pattern

Path Intent Result
.claude/worktrees/wt-5-audit-fixes/src/weather.ts ignored ✅ ignored
.claude/settings.local.json ignored ✅ ignored
.claude/anything-new.txt ignored ✅ ignored
.claude/agents/scout.md trackable ✅ trackable
.claude/hooks/g.mjs trackable ✅ trackable
.claude/scripts/landed.sh trackable ✅ trackable
.claude/workflows/w.js trackable ✅ trackable
.claude/settings.json trackable ✅ trackable
.claude/.claude-infra-version trackable ✅ trackable

Gates

Exit codes checked individually, in a clean worktree off origin/main:

  • npm run typecheck → 0
  • npm run typecheck:py → 0
  • npm run verify:docs → 0

No API call. Nothing outside .gitignore is touched.

History

An earlier revision of this PR used a targeted .claude/worktrees/ + .claude/settings.local.json pair, on the reasoning that negation patterns are a footgun. That reasoning was right about .claude/ and wrong about the house pattern, which uses .claude/* precisely to avoid it — and sync-repo.sh:535-537 had already documented the silent-failure case (.claude-infra-version written but never tracked, so --scan "quietly lies about what is deployed") that the targeted version was trying to argue from. Amended to match.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NsAeobZPagwRXXXDzqE6bW

`.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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NsAeobZPagwRXXXDzqE6bW
@rdtiv
rdtiv force-pushed the chore/ignore-mission-worktrees branch from 5427a57 to e356a29 Compare August 15, 2026 12:25
@rdtiv rdtiv changed the title chore: stop mission worktrees from being committable chore: adopt the house .claude/ gitignore pattern Aug 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant