Skip to content

fix(checks): give every tracked text file LF on checkout - #8657

Open
harjothkhara wants to merge 1 commit into
NVIDIA:mainfrom
harjothkhara:oss-find/nemoclaw-2026-08-09
Open

fix(checks): give every tracked text file LF on checkout#8657
harjothkhara wants to merge 1 commit into
NVIDIA:mainfrom
harjothkhara:oss-find/nemoclaw-2026-08-09

Conversation

@harjothkhara

@harjothkhara harjothkhara commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

A Windows checkout with core.autocrlf=true rewrites tracked text files to CRLF, so repository checks fail before a contributor changes anything. .gitattributes sets no line-ending rule, so Git converts every text file in the repository.

This sets * text=auto eol=lf, which gives every tracked text file LF on every checkout.

Related Issue

Refs: #8648

Changes

  • .gitattributes: * text=auto eol=lf.
  • test/checkout-line-endings.test.ts: three assertions, all derived from git ls-files --eol, so a file added later is covered without editing the test.
    1. git check-attr resolves eol: lf for every file the index stores with LF.
    2. Every one of those files is checked out with LF. Git converts a file when it copies that file out of the index, not when .gitattributes changes, so a checkout made before this rule keeps its CRLF bytes and keeps failing. This assertion names those files instead of leaving a digest mismatch to diagnose.
    3. The index stores no file with CRLF or mixed line endings.
  • CONTRIBUTING.md: how to re-check-out an existing Windows clone, next to the existing core.hooksPath note.

No source file changes, and no tracked content changes.

Why a repository-wide rule and not per-file rules

The issue proposes a rule for the starter-prompt source. That file is one of many. These checks all compare a tracked file byte-for-byte against a pinned digest, or reject a carriage return:

  • scripts/generate-starter-prompt.mts:19 rejects any carriage return.
  • scripts/checks/local-credential-helper-pin.mts:66 compares the SHA-256 of the working-tree bytes.
  • test/starter-prompt-docs.test.ts:731 byte-compares each prompt asset with its pinned Git blob.
  • test/hermes-final-image-layout.test.ts:502 compares 16 SHA-256 digests with the values agents/hermes/Dockerfile declares.
  • test/mcp-tool-discovery-image-contract.test.ts:306 pins four reviewed runtime bundle digests.

There are more. scripts/audit-reviewed-npm-graph.mts:265 digests reviewed npm lockfiles, tools/e2e/workflow-boundary-policy.mts:4 pins workflow action and script content, and test/e2e-fixture-dependency-review.test.ts and test/langchain-deepagents-code-image.test.ts pin image fixtures. The Verification section shows those failing on a CRLF checkout too.

An enumerated list was written first and reviewed; the review found 18 files the list had missed. A list that must name every pinned file is wrong the moment someone pins a new one, and a test built on that list cannot detect the omission. One rule covers all of them and every future one.

Why this is safe

  • text=auto keeps Git's own binary detection. git ls-files --eol reports the same 110 binary files before and after the rule, so no binary file is touched.
  • No tracked file holds CRLF or mixed line endings today: git ls-files --eol reports 0 i/crlf and 0 i/mixed. The rule therefore normalizes no content and produces no renormalization commit.
  • The existing linguist-generated, diff=markdown, and -diff rules still resolve. git check-attr confirms this for the bundle and skills paths.

One behavior change worth naming: scripts/bootstrap-windows.ps1 and tools/wsl/ci-helper.ps1 will check out with LF on Windows instead of CRLF. Both are already LF in the index and on every Linux and macOS checkout today. PowerShell runs LF scripts.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes — CONTRIBUTING.md gains the existing-Windows-clone remediation. No docs/ page changes: no public API, CLI, configuration, default, error, or product behavior changes, and no tracked content changes.
  • Docs not applicable — justification:
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: the rule covers credential-capture and Hermes image-integrity sources. It changes no file content; it makes those existing integrity checks hold on a Windows checkout instead of failing.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Documentation Writer Review

  • Documentation writer subagent reviewed the completed changes
  • Result: docs-updated
  • Evidence: CONTRIBUTING.md. The reviewer confirmed no docs/ page needs a change: docs/get-started/windows-preparation.mdx:54 fetches the bootstrap script from raw.githubusercontent.com, which serves the index blob, so the documented Windows user path is byte-identical. It found the existing-clone gap and the two overclaiming test titles, both fixed here.
  • Agent: Claude Code

Verification

Two real clones with core.autocrlf=true, one at base 8096cdd7b and one at this commit.

Tracked files that check out with CRLF:

before @ 8096cdd7b: 5052
after  @ HEAD:         0

Repository checks:

                            before  after
docs:sync-starter-prompt    exit 1  exit 0   ("use LF line endings")
checks:repository           exit 1  exit 0

Pinned-digest suites in the same two trees, --no-file-parallelism:

npx vitest run --project integration --no-file-parallelism \
  test/hermes-final-image-layout.test.ts test/mcp-tool-discovery-image-contract.test.ts \
  test/starter-prompt-docs.test.ts test/e2e-fixture-dependency-review.test.ts

before: 27 failed
after:   0 failed

Every one of the 27 failures is fixed, and none fails in both trees. They include keeps security entrypoint hashes synchronized with the copied files, pins the reviewed image runtime artifacts exactly, keeps local prompt assets byte-aligned with their pinned revision blobs (#6990), and rejects a cache seed that does not match the lockfile integrity.

New test, red and green on this checkout:

attribute assertion without the rule: expected [ …(5055) ] to deeply equal []
worktree assertion, one file forced to CRLF:
  + "docs/resources/starter-prompt.md: w/crlf"
all three with the rule:              Tests  3 passed (3)

Affected suites on this checkout: Test Files 5 passed (5) Tests 49 passed (49).

npm run checks:repository, npm run typecheck:cli, npx @biomejs/biome check, and npm run docs all pass.

Limits, stated plainly:

  • The Windows behavior is proven by a core.autocrlf=true checkout on macOS, not on a Windows host. core.autocrlf is the setting that performs the conversion and it behaves the same on every platform.

  • An existing Windows working tree that already holds CRLF is not rewritten by pulling this commit. The second test names those files and CONTRIBUTING.md gives the fix, but the commit cannot repair a working tree by itself.

  • .github/workflows/wsl-e2e.yaml:33 and .github/workflows/platform-vitest-main.yaml:174 already set core.autocrlf false. Those lines are now redundant. They are left in place because they are harmless and removing them is a separate decision.

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub

  • Normal pre-commit, commit-msg, and pre-push hooks passed

  • Targeted behavior tests pass for the current change set — command/result above

  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result:

  • Quality Gates section completed with required justifications or waivers

  • No secrets, API keys, or credentials committed

  • npm run docs builds without warnings

  • Doc pages follow the style guide (doc changes only)

  • New doc pages include SPDX header and frontmatter (new pages only)


Signed-off-by: Harjoth Khara harjoth.khara@gmail.com

Summary by CodeRabbit

  • Documentation

    • Added Windows-specific guidance for restoring consistent LF line endings after cloning the repository.
  • Chores

    • Standardized tracked text files to use LF line endings while preserving binary-file handling.
  • Tests

    • Added automated checks to verify consistent LF endings and prevent CRLF or mixed line endings.

A Windows checkout with core.autocrlf=true rewrites tracked text files to
CRLF. Repository checks then fail before a contributor changes a file.
The starter-prompt generator rejects a carriage return, and these compare
a tracked file byte-for-byte against a pinned digest:

- the credential-helper pin
- the pinned prompt assets
- the Hermes image layout
- the reviewed MCP runtime bundle
- the reviewed npm lockfiles
- the pinned workflow actions and scripts
- the Deep Agents Code and E2E image fixtures

Set text=auto eol=lf for every path instead of naming files, so a file
added later is covered too. text=auto keeps Git's binary detection, so
Git does not convert the 110 binary files. No tracked file holds CRLF or
mixed line endings today, so this normalizes no content.

Add a test that derives its file list from git ls-files --eol. Git
converts a file when it copies that file out of the index, not when
.gitattributes changes, so the test also asserts the worktree form and
CONTRIBUTING.md gives an existing Windows checkout the fix.

Fixes NVIDIA#8648

Signed-off-by: harjoth <harjoth.khara@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 9, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The repository now enforces LF line endings for tracked text files, documents Windows checkout recovery, and adds Git-backed tests for index and worktree line endings.

Changes

LF line-ending enforcement

Layer / File(s) Summary
Line-ending policy and remediation
.gitattributes, CONTRIBUTING.md
.gitattributes applies text=auto eol=lf while preserving binary detection. CONTRIBUTING.md documents Windows recovery steps.
Git line-ending validation
test/checkout-line-endings.test.ts
Vitest tests inspect Git metadata and verify LF attributes, LF worktrees, and the absence of CRLF or mixed line endings.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Suggested reviewers: brandonpelfrey

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: enforcing LF line endings for tracked text files on checkout.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — No blocking findings reported

Advisor assessment: No blocking advisor findings reported
Next action: Review the warnings below.
Findings: 0 blockers · 1 warning · 0 suggestions

Model lanes

  • GPT-5.6 Terra (primary): Completed · high confidence · 0 blockers · 1 warning · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Completed · high confidence · 0 blockers · 0 warnings · 0 suggestions
  • Model comparison: normalized findings differ; normalized terminology decisions differ; normalized E2E selections match; Nemotron reported the same number of blockers, 1 fewer warning, the same number of suggestions.
3 terminology differences from the second opinion

Advisory only. These are normalized differences from the primary terminology receipt.

  • starter-prompt generator at .gitattributes:5: selected only by the second-opinion lane as define.
  • text=auto at .gitattributes:8: selected only by the second-opinion lane as established.
  • eol=lf at .gitattributes:9: selected only by the second-opinion lane as established.

Second-opinion terminology and E2E selections are advisory. Live E2E does not run automatically for pull requests.

3 semantic terminology decisions

Terminology decisions are advisory. They affect the assessment only when a separate finding identifies concrete semantic impact.

  • established — pinned digest at .gitattributes:5: Keep `pinned digest`; the changed comment uses the established repository term.
  • established — working tree at CONTRIBUTING.md:367: Keep `working tree`; the contributor guidance distinguishes checked-out bytes from index content.
  • established — tracked file at .gitattributes:4: Keep `tracked file`; the comments and test titles use the established Git concept consistently.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite against this exact revision.

Recommended E2E: None

1 warning · 0 suggestions

Warnings

Warnings do not block.

PRA-1 Warning — Preserve local changes before the re-checkout procedure

  • Location: CONTRIBUTING.md:367
  • Category: correctness
  • Problem: The contributor procedure runs `git rm --cached -r .` and `git reset --hard` without requiring the contributor to commit or stash local changes first.
  • Impact: The documented remediation can cause irreversible loss of contributor work while repairing line endings.
  • Recommendation: Add a condition that contributors must commit or stash local changes before this procedure, or replace the procedure with a non-destructive re-checkout method.
  • Verification: In a disposable clone, modify and stage a tracked file, then inspect the result of the documented Git sequence.
  • Test coverage: Add a documentation contract test that requires a commit-or-stash prerequisite beside this destructive recovery procedure.
  • Evidence: CONTRIBUTING.md:367 documents `git rm --cached -r .` followed by `git reset --hard` with no local-change preservation condition. `git reset --hard` replaces tracked working-tree content and removes staged changes.

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

@harjothkhara
harjothkhara marked this pull request as ready for review August 9, 2026 22:16

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CONTRIBUTING.md`:
- Line 367: Update the Windows line-ending remediation instructions in
CONTRIBUTING.md to require contributors to commit or stash local changes, or
verify that the working tree is clean, before running git reset --hard; preserve
the existing cache removal and reset steps.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 17df4ffd-4a4c-4acf-95a5-e3ee8722b311

📥 Commits

Reviewing files that changed from the base of the PR and between 1a8e6bd and d71be2e.

📒 Files selected for processing (3)
  • .gitattributes
  • CONTRIBUTING.md
  • test/checkout-line-endings.test.ts

Comment thread CONTRIBUTING.md

If you still have `core.hooksPath` set from an old Husky setup, Git will ignore `.git/hooks`. Run `git config --unset core.hooksPath` in this repo, then `npm install` so `prek install` (via `prepare`) can register the hooks.

If you cloned this repo on Windows before `.gitattributes` set `* text=auto eol=lf`, your working tree still holds CRLF and the repository checks still fail. Run `git rm --cached -r .` and then `git reset --hard` in this repo to check the files out again with LF.

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Protect local changes before the hard reset.

git reset --hard discards staged and unstaged changes. Require contributors to commit or stash local work before this command, or state that the working tree must be clean.

Proposed fix
-If you cloned this repo on Windows before `.gitattributes` set `* text=auto eol=lf`, your working tree still holds CRLF and the repository checks still fail. Run `git rm --cached -r .` and then `git reset --hard` in this repo to check the files out again with LF.
+If you cloned this repo on Windows before `.gitattributes` set `* text=auto eol=lf`, your working tree still holds CRLF and the repository checks still fail. First commit or stash all local changes. Then run `git rm --cached -r .` and `git reset --hard` in this repo to check the files out again with LF.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
If you cloned this repo on Windows before `.gitattributes` set `* text=auto eol=lf`, your working tree still holds CRLF and the repository checks still fail. Run `git rm --cached -r .` and then `git reset --hard` in this repo to check the files out again with LF.
If you cloned this repo on Windows before `.gitattributes` set `* text=auto eol=lf`, your working tree still holds CRLF and the repository checks still fail. First commit or stash all local changes. Then run `git rm --cached -r .` and `git reset --hard` in this repo to check the files out again with LF.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CONTRIBUTING.md` at line 367, Update the Windows line-ending remediation
instructions in CONTRIBUTING.md to require contributors to commit or stash local
changes, or verify that the working tree is clean, before running git reset
--hard; preserve the existing cache removal and reset steps.

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