Skip to content

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

Merged
cv merged 8 commits into
NVIDIA:mainfrom
harjothkhara:oss-find/nemoclaw-2026-08-09
Aug 13, 2026
Merged

fix(checks): give every tracked text file LF on checkout#8657
cv merged 8 commits 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

Fixes #8648

Changes

  • .gitattributes: * text=auto eol=lf.
  • CONTRIBUTING.md: how to re-check-out an existing Windows clone, next to the existing core.hooksPath note. Git converts a file when it copies that file out of the index, not when .gitattributes changes, so a clone made before this rule keeps its CRLF bytes.

The current-main merge updates test/starter-prompt-docs.test.ts to verify the repository-wide LF attribute contract.

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 check 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: fix(checks): give every tracked text file LF on checkout #8657 (comment)
  • 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 documents the existing-Windows-clone remediation and requires a clean worktree before git reset --hard. .gitattributes preserves Git binary detection while assigning LF to tracked text. test/starter-prompt-docs.test.ts verifies the repository-wide attribute contract. No public docs page changes because this affects contributor checkout behavior.
  • Agent: Codex Desktop documentation writer

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 on branch:       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.

On the rebased tree, every tracked text file resolves the rule:

git ls-files --eol | awk '$1=="i/lf"{sub(/^[^\t]*\t/,""); print}' \
  | git check-attr --stdin eol | grep -vc ': eol: lf$'
0

Index forms are unchanged by the rule: 5140 i/lf, 110 i/-text, 3 i/none, 3 empty.

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. 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 — the normal pre-commit hook passed repository checks after the attribute-contract test update.

  • 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 — the build completed with 0 errors and 2 existing Fern 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 in local checkouts.
    • Included steps to preserve local changes, verify a clean working tree, and safely reset files.
  • Chores

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

@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

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The repository now normalizes tracked text files to LF endings and documents Windows checkout recovery steps.

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 recovery steps for Windows checkouts that retain CRLF endings.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Suggested reviewers: cv

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue #8648 by enforcing LF checkout for tracked text files while preserving existing CRLF validation.
Out of Scope Changes check ✅ Passed The changes remain within scope because the repository-wide rule and Windows guidance support the checkout-line-ending objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: configuring tracked text files to use LF line endings on checkout.
✨ 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: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions

Model lanes

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

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.

  • justified — tracked text file at CONTRIBUTING.md:396: Retain this term for files affected by the repository LF checkout rule.
  • justified — binary detection at .gitattributes:8: Retain this term because it identifies why the wildcard attribute does not convert binary files.
  • established — working tree at CONTRIBUTING.md:395: Use the established Git term consistently in the remediation procedure.

E2E guidance

Advisory only. A maintainer can dispatch the default E2E suite for the commit under review.

Recommended E2E: None

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 Outdated
cv
cv previously requested changes Aug 10, 2026

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please remove the test (too much IO for such a simple config change) and fix the CodeRabbit requests.

@wscurran wscurran added area: ci CI workflows, checks, release automation, or GitHub Actions bug-fix PR fixes a bug or regression labels Aug 10, 2026
@harjothkhara
harjothkhara force-pushed the oss-find/nemoclaw-2026-08-09 branch from d71be2e to e8226b0 Compare August 11, 2026 02:12
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@harjothkhara
harjothkhara force-pushed the oss-find/nemoclaw-2026-08-09 branch from e8226b0 to 1280551 Compare August 11, 2026 02:14
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.

Git converts a file when it copies that file out of the index, not when
.gitattributes changes, so CONTRIBUTING.md gives an existing Windows
checkout the fix.

Fixes NVIDIA#8648

Signed-off-by: harjoth <harjoth.khara@gmail.com>
@harjothkhara
harjothkhara force-pushed the oss-find/nemoclaw-2026-08-09 branch from 1280551 to 8b5b544 Compare August 11, 2026 02:26
@harjothkhara

Copy link
Copy Markdown
Contributor Author

Done both.

Removed test/checkout-line-endings.test.ts.

Took CodeRabbit's suggestion on the CONTRIBUTING.md note, plus four words: git rm --cached -r . is path-relative, so running it from nemoclaw/ discards local changes and only fixes that subtree. It now says to run from the repo root.

The diff is 9 lines across .gitattributes and CONTRIBUTING.md.

@harjothkhara
harjothkhara requested a review from cv August 11, 2026 02:30
@apurvvkumaria apurvvkumaria self-assigned this Aug 11, 2026
Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Security review

Verdict: PASS — no findings.

I reviewed branch revision 9d46fb94f and the complete .gitattributes plus contributor-guidance change.

  1. Secrets and credentials — PASS. No credential value or sensitive file content changes. LF checkout makes existing credential-helper and artifact digest checks deterministic on Windows.
  2. Input validation and sanitization — PASS. Git retains text=auto binary detection; the rule changes line endings only for paths Git classifies as text.
  3. Authentication and authorization — PASS. No identity, permission, ownership, or authentication surface changes.
  4. Dependencies and third-party libraries — PASS. No dependency, image, registry, download, or lockfile changes.
  5. Error handling and logging — PASS. The change prevents false repository-check failures caused by CRLF conversion and adds no new logging or exception path.
  6. Cryptography and data protection — PASS. Existing hashes and byte-for-byte integrity checks remain authoritative. The index contains no tracked CRLF or mixed-line-ending text that would be silently normalized.
  7. Configuration and security headers — PASS. Existing path-specific attributes remain in force. PowerShell scripts already stored as LF continue to run with LF on Windows.
  8. Security testing — PASS. A core.autocrlf=true checkout reduced CRLF text files from 5,052 to 0 and fixed 27 pinned-digest failures. Repository checks and the documentation build pass.
  9. System security — PASS. The recovery guidance now warns that git reset --hard discards tracked changes, covers tracked and untracked stashing, and requires a clean git status --short result before index removal and reset.

The change is small and does not require a large-LOC flag. Both commits are signed off, and GitHub marks them Verified.

@VishnuR23

Copy link
Copy Markdown
Contributor

Apologies — I opened #8779 against the same issue without noticing this PR first. Yours came 31 hours earlier and is broader, so I have said on mine that it should not land as a competing change.

Offering something concrete instead. #8779 carries regression tests for the checkout contract, and I checked that they work against your rule rather than mine. With * text=auto eol=lf in place and none of my targeted rules, every path whose exact bytes test/starter-prompt-docs.test.ts asserts resolves to eol: lf, and 23 of the 24 tests pass.

What transfers:

  • A parameterised test over the five byte-asserted paths (starter-prompt.md, the three prompt-assets/*.md, and local-credential-form.html) asserting each resolves to eol: lf.
  • The lookups spawn git with GIT_ATTR_NOSYSTEM=1 and an absent core.attributesFile. Without that, a contributor's global * text=auto decides the result instead of the repository, which I reproduced.
  • Each lookup asserts the path exists first, because git check-attr answers unspecified with exit 0 for a path that does not exist.
  • A failed git spawn reports status, signal, and stderr rather than expected null to be 0.

What does not transfer: my sixth test asserts that a file without a byte-exact contract stays unpinned. That has no meaning under a repository-wide rule, so it should be dropped rather than adapted.

Take any of it if useful — copy it directly, or tell me and I will open a PR against your branch. No attribution needed.

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>
@cv
cv dismissed their stale review August 11, 2026 08:32

The latest PR commit removes the requested test and retains the requested data-loss warning and worktree checks.

@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Merge-train comparison for #8648

Both PRs remain blocked on a maintainer policy choice:

Neither PR has approval or all required checks. I will not close either PR until a maintainer selects the policy. The unselected PR can then close with this comparison and the selected replacement as evidence.

@prekshivyas prekshivyas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Comparator review for issue #8648: neither competing PR is mergeable yet; #8779 is closer to the accepted issue scope.

#8657's repository-wide * text=auto eol=lf policy does fix the reported source file, but it expands checkout behavior for every tracked text file and carries no checked-in git check-attr regression. Score: 9.0/16.0. #8779 uses file-specific pins, explains the untracked generated output, and provides positive/negative resolved-attribute tests; score: 16.0/16.0.

Both PRs are behind current main, missing the current required checks, and still need branch-protection approval. No supersession declaration or transferred work was found. Please obtain an explicit maintainer scope choice and converge on one PR rather than advancing both.

@senthilr-nv

Copy link
Copy Markdown
Collaborator

PR #8779 implemented the accepted file-specific scope from #8648 and merged in commit 88eecd8. This PR applies line-ending rules repo-wide and does not include the file-specific git check-attr contract test. I recommend closing this PR as superseded by #8779.

Signed-off-by: Apurv Kumaria <akumaria@nvidia.com>

# Conflicts:
#	.gitattributes

@prekshivyas prekshivyas left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Blocking: the new global .gitattributes rule, * text=auto eol=lf, contradicts test/starter-prompt-docs.test.ts, which still asserts that docs/resources/agent-skills.mdx does not resolve to eol: lf. The applicable test path was skipped in required CI, so green status does not validate this behavior. Please update the obsolete assertion and run the full affected test.

@apurvvkumaria

Copy link
Copy Markdown
Collaborator

Supersession evidence is now conclusive:

I am not resolving the conflict or changing this branch. PR #8779 is the implemented replacement. This PR is being left open for a human maintainer to close.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv
cv dismissed prekshivyas’s stale review August 13, 2026 07:08

Dismissed as stale at b1bee67. The obsolete negative eol assertion is now a positive checkout contract test for LF, and the normal pre-commit checks passed.

@cv cv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved at b1bee67. All 39 exact-commit checks pass. The LF checkout contract test replaces the obsolete negative assertion, the advisor reports no blocking findings, and no unresolved review thread remains. Current main is newer but non-overlapping, so the requested branch policy does not permit an unnecessary main merge.

@cv
cv merged commit 24eaba1 into NVIDIA:main Aug 13, 2026
43 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci CI workflows, checks, release automation, or GitHub Actions bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows checkout converts the starter prompt to CRLF and breaks repository checks

7 participants