Repository navigation
Make .gitignore actually implement its own stated policy - #939
Conversation
The header says the vault tracks by default and ignores only secrets and
exhaust. The file did not do that. It carried one pattern — `!**.md`, a
negation with nothing to negate — so it ignored nothing at all:
$ git check-ignore --no-index .env .mcp.json .claude/.credentials.json \
.codex/auth.json .ssh/id_ed25519
(no output)
The policy text is kept verbatim. Only the implementation is added.
Shape notes, because two git rules make the obvious spelling wrong:
- Git does not descend into an excluded DIRECTORY, so a later `!` cannot
rescue a file inside one. `node_modules/` followed by `!**/*.md` loses
the markdown silently. Exhaust is therefore written `dir/**` plus
`!dir/**/`, which keeps git descending and lets the markdown
re-include at the bottom actually work. 49 markdown files are tracked
inside node_modules today.
- A pattern containing a slash is anchored to this directory, so
`node_modules/**` matches only a root copy and `THE-GEMSTONE/node_modules/`
escapes it. Unambiguous tool directories get a `**/` prefix. Names that
are also ordinary vault folders (build, dist, logs, tmp, .cache — 83
tracked files live under such paths) stay anchored at the root with a
leading `/`, because track-by-default means a note folder named `logs`
is content, not exhaust.
Verified with git check-ignore --no-index, not by reading:
secrets 11/11 now ignored (was 0/11)
exhaust ignored at any depth, including nested node_modules
markdown NOT ignored anywhere, including inside exhaust dirs
vault dirs notes/logs/, project/build/, vault/tmp/ still tracked
tracked 38,480 files before and after; nothing untracked
11 tracked files match an ignore rule and are unaffected (tracked files
are never ignored): ten .log files, and .factory/certs/factory-ai-root.pem,
which is a public root certificate rather than a private key.
Context: the 4-line version arrived in 3591a4b (+3 -507), the same push
that discarded the #913 and #918 merges from logan/obsidian.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs
|
Insufficient balance to process this code review. Please add funds or upgrade your plan in billing. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing |
Reviewer's guide (collapsed on small PRs)Reviewer's Guide.gitignore is updated to actually implement the stated "track markdown, ignore secrets and exhaust" policy, with carefully scoped ignore patterns that avoid accidentally dropping markdown or vault content while ignoring common secret and build/exhaust files and directories at appropriate depths. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Warning Review limit reached
Next review available in: 50 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Insufficient balance to process this code review. Please add funds or upgrade your plan in billing. |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Coverage variation | ✅ -0.02% coverage variation (-1.00%) |
| Diff coverage | ✅ ∅ diff coverage |
Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (2de9687) 13529 11333 83.77% Head commit (ab680cb) 13529 (+0) 11330 (-3) 83.75% (-0.02%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>
Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#939) 0 0 ∅ (not applicable) Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
|
If you are watching or subscribed to this PR, please respond to this comment. |
|
Watching. Session State at Waiting on you for one decision, and it's the reason I haven't pushed further: your My argument is that specimens grow and move while patterns don't, so Related: you asked what an "exhaust directory" was. That phrase was mine, not yours — I welded your noun onto a category and never checked your definition against it. The secrets half is unambiguous; the exhaust half rests on my guess at what you meant. Also corrected here: I originally framed the 4-line Generated by Claude Code Generated by Claude Code |
Pull Request Summary by devActivityMetricsAchievements
|
… proposal While this branch's pattern-set proposal waited for review, Logan merged #939 — a fuller .gitignore engineered around git's two sharp edges (tracked files are never ignored; excluded directories swallow later re-includes). That merge is the ruling on the pattern set, so this merge resolves every conflict by taking main wholesale: the proposal yields to the canon file, and the workflows, LLM-Router.md, and pyproject's [tool.coverage.report] all come from main. This PR's diff against main is empty again — its second payload landed through another door, like its first. With auto-merge armed it now terminates by merging as a no-op, which is this vault's lawful ending for a PR. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fipj4vEJ5ADPuunn9ed5Hd
AGENT PR TEMPLATE
Agent: Claude Code (
agent:claude-code)Date: 2026-08-09
Branch:
claude/gitignore-qzt7le→mainThe defect
The file states a policy and does not implement it. Its only pattern is
!**.md— a negation with nothing before it to negate:Nothing is ignored. "Ignore only secrets and exhaust" currently ignores neither. A stray
.envor a copiedauth.jsonis picked up bygit add -Awith nothing to stop it.Your policy text is kept verbatim. Only the implementation is added.
The tension you should rule on
b52b1e585— "Retire the specimen-path gitignore assertions; keep the real questions" — retired 24 hardcoded paths on the grounds that "an enumeration of one day's junk drawer is a ratchet, not a policy." That ruling is one day old and it points at this PR.My argument for why this is not that ratchet: those were specimens (individual salvage paths, one line per file, re-firing whenever a file moved). These are patterns —
*.pem,*.env,**/node_modules/**— which do not grow when a new file appears and do not care where anything moves. A pattern set is what "ignore secrets and exhaust" means mechanically; there is no way to ignore secrets without naming their shapes.But it is 152 lines, and you just ruled in the direction of less. If you want the secrets half only — drop the entire exhaust section, ~60 lines — say so and I'll cut it. Exhaust is untidiness; secrets are the part with consequences.
Two git rules that make the obvious spelling wrong
1. Git does not descend into an excluded directory, so a later
!cannot rescue a file inside one.node_modules/followed by!**/*.mdloses the markdown silently. Exhaust is thereforedir/**plus!dir/**/, which keeps git descending so the markdown re-include applies. 49 markdown files are tracked insidenode_modules.2. A pattern containing a slash is anchored to this directory.
node_modules/**matches only a root copy;THE-GEMSTONE/node_modules/escapes it. My first draft had this bug; the test below caught it. Tool dirs now use**/; names that are also ordinary vault folders (build,dist,logs,tmp,.cache— 83 tracked files live under such paths) stay root-anchored with a leading/.Verification
node_modulesnotes/logs/,project/build/,vault/tmp/still trackedtests/test_dotfolder_gitignore_policy.py.claude/CLAUDE.md,.codex/AGENTS.md,.config/CONFIG.mdall visible--no-indexmatters: without it an already-tracked file always reports as not-ignored, which makes a broken pattern look like it works. That is how the current file's emptiness stayed invisible.The 11 tracked files that match a rule are unaffected — git never ignores a tracked file — but named rather than left as a number: ten
.logfiles, and.factory/certs/factory-ai-root.pem, which is a public root certificate, not a private key. No live secret exposure in the tracked set.Blockers
Checklist:
tests/test_dotfolder_gitignore_policy.pypasses against this file (run locally;mainnow carries pytest inuv.lock, so it runs in CI too).Risk Level:
One file, but a wrong pattern here hides content silently rather than loudly. Nothing is untracked and markdown is verified unignorable; the judgement calls worth your eyes are the root-anchoring of
build/dist/logs/tmp, and whether the exhaust section should exist at all givenb52b1e585.Labels to apply:
agent:claude-codehttps://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs