Skip to content

Declare the six extensionless tool configs as text - #954

Merged
loganfinney27 merged 2 commits into
mainfrom
claude/gitattributes-declare-qzt7le
Aug 12, 2026
Merged

Declare the six extensionless tool configs as text#954
loganfinney27 merged 2 commits into
mainfrom
claude/gitattributes-declare-qzt7le

Conversation

@loganfinney27

@loganfinney27 loganfinney27 commented Aug 11, 2026

Copy link
Copy Markdown
Member

AGENT PR TEMPLATE

Agent: Claude Code (agent:claude-code)
Date: 2026-08-11
Branch: claude/gitattributes-declare-qzt7lemain


Changes Made

Six root-anchored entries in .gitattributes, plus a comment.

check_character_conformity.py judges only files whose text attribute is set — anything unspecified is skipped and counted as a visible gap (586 tracked files today). The configs #950 adds have no extension, or an extension .gitattributes doesn't cover, so all six would land in that bucket and never be checked for encoding:

/.bandit, /.pylintrc, /.remarkrc, /.shellcheckrc, /.stylelintrc, /ruleset.xml

Correction: the first version of this PR was broader than it claimed

This body originally said "No pattern, so no file outside the named six can be affected." That was wrong. Copilot caught it. A .gitattributes pattern containing no slash is a basename match applied at any depth — the same rule as .gitignore. Measured before the fix:

some/deep/dir/.pylintrc     text: set
.codex/skills/ruleset.xml   text: set
sub/.bandit                 text: set

Each entry now carries a leading slash, which is what actually restricts it to the repo root.

Worth naming the pattern rather than just the bug: this is the identical trap as !*.md in #953, which I documented there and then walked into from the other direction here. A git pattern is path-anchored only when it contains a slash — true for .gitignore and .gitattributes alike.

Why literal entries and not *.xml

*.xml was the obvious shortcut for the last one, and it is wrong for a different reason. RSS.xml is committed with CRLF — a blanket text eol=lf would rewrite its line endings as a side effect of declaring a config file. There are only 6 tracked .xml files outside THE-GEMSTONE, several of them media sidecars (JFAC Panel Full.mp4.xml); none need this and one would be damaged by it.

Verified

Path Before After
root /.bandit/ruleset.xml (all six) set set — unchanged
some/deep/dir/.pylintrc set unspecified
.codex/skills/ruleset.xml set unspecified
sub/.bandit set unspecified
RSS.xml unspecified unspecified — untouched

The benefit only materialises once #950 merges, since these files don't exist on main yet. git check-attr resolves attributes for any path whether or not it's tracked, which is why it's the verification here rather than a before/after count of the 586.

Related Work

Blockers

  • None.

Checklist:

  • Tests pass (or no tests required) — no suite. Verified with git check-attr text on all six root paths, three nested paths, and RSS.xml, before and after anchoring; plus git status --porcelain to confirm nothing else moved.
  • No secrets in diff — six attribute declarations.
  • Documentation updated IF needed — the entries carry their own comment, covering both the anchoring rule and the *.xml trap.
  • Reviewer assigned — Logan.

Risk Level:

  • LOW: Single file fix, non-critical
  • MEDIUM: Multiple files, standard operation
  • HIGH: Core changes, requires human eyes

Six root-anchored path declarations, with the nested-match behaviour now measured in both directions rather than asserted.


Labels to apply:

  • agent:claude-code

https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs

check_character_conformity.py judges only files whose `text` attribute is
set in .gitattributes; anything unspecified is skipped and counted as a
visible gap (586 tracked files today). The configs #950 adds have no
extension, or an extension .gitattributes does not cover, so all six would
join that bucket and never be checked for encoding.

Declared literally rather than by pattern. `*.xml` was the obvious shortcut
and it is wrong here: RSS.xml is committed with CRLF, so a blanket
`text eol=lf` would rewrite its line endings as a side effect of declaring
a config file. Six named entries cost nothing and touch nothing else.

Verified: all six resolve to `text: set, eol: lf` via `git check-attr`;
RSS.xml still resolves to `unspecified` on both; no other file in the tree
changes.

The benefit only materialises once #950 merges, since these files do not
exist on main yet. `git check-attr` works on paths regardless of whether
they are tracked, which is why it is the verification used here rather than
a before/after count.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@loganfinney27, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 42 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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 492b8b27-9ff4-44c4-b8e2-4d7a4e50ffe0

📥 Commits

Reviewing files that changed from the base of the PR and between c2d070e and db8a5f5.

📒 Files selected for processing (1)
  • .gitattributes

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai

sourcery-ai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

This PR updates .gitattributes to explicitly declare six extensionless (or special-case) tool configuration files as text with LF line endings, avoiding broad XML patterns that could inadvertently alter existing XML files like RSS.xml.

File-Level Changes

Change Details Files
Declare six specific config files as text with LF line endings in .gitattributes to ensure they are validated by encoding checks without impacting other XML files.
  • Add explicit attribute entries for .bandit, .pylintrc, .remarkrc, .shellcheckrc, .stylelintrc, and ruleset.xml
  • Set text and eol=lf for these six paths so they are included in check_character_conformity.py validation
  • Avoid using a blanket *.xml pattern to prevent modifying RSS.xml and other XML sidecar files
  • Document the rationale and the *.xml pitfall via an inline comment in .gitattributes
.gitattributes

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@loganfinney27 loganfinney27 added the risk/med Filetype: med (computer code — executes). label Aug 11, 2026
@loganfinney27
loganfinney27 marked this pull request as ready for review August 11, 2026 05:31
Copilot AI balanced review requested due to automatic review settings August 11, 2026 05:31
@tenki-reviewer

Copy link
Copy Markdown

Insufficient balance to process this code review. Please add funds or upgrade your plan in billing.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@qodo-code-review

Copy link
Copy Markdown
Contributor

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@codacy-production

Copy link
Copy Markdown
Contributor

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

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.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Declares six tool configuration files as LF-normalized text for character-conformity checks.

Changes:

  • Adds explicit .gitattributes entries for six configs.
  • Avoids a broad XML rule that would affect RSS.xml.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .gitattributes Outdated
@loganfinney27 loganfinney27 added the review/threads-open Current unresolved review threads still need attention before merge. label Aug 11, 2026
Copilot: the six entries were unanchored basename patterns, so git applied
them at any depth. Measured before the fix:

  some/deep/dir/.pylintrc     text: set
  .codex/skills/ruleset.xml   text: set
  sub/.bandit                 text: set

That directly contradicts this PR's own claim -- "no pattern, so no file
outside the named six can be affected." A .gitattributes pattern with no
slash is a basename match, exactly like .gitignore. Which is the same trap
I documented in #953 one PR earlier, in the other direction.

Each entry now carries a leading slash. Verified after:

  root .bandit/.pylintrc/.remarkrc/.shellcheckrc/.stylelintrc/ruleset.xml
                              text: set          (unchanged)
  some/deep/dir/.pylintrc     text: unspecified  (was: set)
  .codex/skills/ruleset.xml   text: unspecified  (was: set)
  sub/.bandit                 text: unspecified  (was: set)
  RSS.xml                     text: unspecified  (unchanged)

The comment now explains the anchoring alongside the `*.xml` note, since
the two traps have the same root cause: git pattern matching is
path-anchored only when the pattern contains a slash.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EBV6TkrwsZhcwkh1b6NUHs
Copilot AI review requested due to automatic review settings August 11, 2026 05:34
@tenki-reviewer

Copy link
Copy Markdown

Insufficient balance to process this code review. Please add funds or upgrade your plan in billing.

@loganfinney27 loganfinney27 removed the review/threads-open Current unresolved review threads still need attention before merge. label Aug 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@loganfinney27

Copy link
Copy Markdown
Member Author

PING!

@loganfinney27
loganfinney27 added this pull request to the merge queue Aug 12, 2026
Merged via the queue into main with commit bd715c2 Aug 12, 2026
35 of 36 checks passed
@loganfinney27
loganfinney27 deleted the claude/gitattributes-declare-qzt7le branch August 12, 2026 02:48
loganfinney27 pushed a commit that referenced this pull request Aug 15, 2026
The 110-line case-folded LFS + eol ruleset was deleted in ecbe685,
leaving zero attributes resolving: LFS orphaned (1,845 pointers, no
patterns), no eol authority (system core.autocrlf=true unchecked - the
mechanism behind the 2026-08-11 .ollama model-blob corruption).

Base = origin/main:.gitattributes adopted verbatim (incl. #954's
anchored extensionless-config block) so the eventual logan/obsidian ->
main merge stays suffix-only. Vault-local section appends: .ollama
byte-exactness guard (-text -diff -merge -filter), LF-anchored repo
plumbing, and census binary classes (fonts/ico/pyc/etl/dat/sqlite-wal).

Historical raw blobs (440 jpg / 130 png / 52 mp4 / 16 MOV) deliberately
NOT converted - no renormalize churn; they migrate individually on next
modification. Future adds of all media classes go to LFS automatically.
loganfinney27 pushed a commit that referenced this pull request Aug 15, 2026
The 110-line case-folded LFS + eol ruleset was deleted in 7e26d23,
leaving zero attributes resolving: LFS orphaned (1,845 pointers, no
patterns), no eol authority (system core.autocrlf=true unchecked - the
mechanism behind the 2026-08-11 .ollama model-blob corruption).

Base = origin/main:.gitattributes adopted verbatim (incl. #954's
anchored extensionless-config block) so the eventual logan/obsidian ->
main merge stays suffix-only. Vault-local section appends: .ollama
byte-exactness guard (-text -diff -merge -filter), LF-anchored repo
plumbing, and census binary classes (fonts/ico/pyc/etl/dat/sqlite-wal).

Historical raw blobs (440 jpg / 130 png / 52 mp4 / 16 MOV) deliberately
NOT converted - no renormalize churn; they migrate individually on next
modification. Future adds of all media classes go to LFS automatically.
loganfinney27 pushed a commit that referenced this pull request Aug 16, 2026
The 110-line case-folded LFS + eol ruleset was deleted in aff3e54,
leaving zero attributes resolving: LFS orphaned (1,845 pointers, no
patterns), no eol authority (system core.autocrlf=true unchecked - the
mechanism behind the 2026-08-11 .ollama model-blob corruption).

Base = origin/main:.gitattributes adopted verbatim (incl. #954's
anchored extensionless-config block) so the eventual logan/obsidian ->
main merge stays suffix-only. Vault-local section appends: .ollama
byte-exactness guard (-text -diff -merge -filter), LF-anchored repo
plumbing, and census binary classes (fonts/ico/pyc/etl/dat/sqlite-wal).

Historical raw blobs (440 jpg / 130 png / 52 mp4 / 16 MOV) deliberately
NOT converted - no renormalize churn; they migrate individually on next
modification. Future adds of all media classes go to LFS automatically.
loganfinney27 pushed a commit that referenced this pull request Aug 16, 2026
The 110-line case-folded LFS + eol ruleset was deleted in 2658311d6,
leaving zero attributes resolving: LFS orphaned (1,845 pointers, no
patterns), no eol authority (system core.autocrlf=true unchecked - the
mechanism behind the 2026-08-11 .ollama model-blob corruption).

Base = origin/main:.gitattributes adopted verbatim (incl. #954's
anchored extensionless-config block) so the eventual logan/obsidian ->
main merge stays suffix-only. Vault-local section appends: .ollama
byte-exactness guard (-text -diff -merge -filter), LF-anchored repo
plumbing, and census binary classes (fonts/ico/pyc/etl/dat/sqlite-wal).

Historical raw blobs (440 jpg / 130 png / 52 mp4 / 16 MOV) deliberately
NOT converted - no renormalize churn; they migrate individually on next
modification. Future adds of all media classes go to LFS automatically.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk/med Filetype: med (computer code — executes).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants