diff --git a/docs/changelog-20260709-repo-lint-crlf-fix.md b/docs/changelog-20260709-repo-lint-crlf-fix.md new file mode 100644 index 0000000..b576c6a --- /dev/null +++ b/docs/changelog-20260709-repo-lint-crlf-fix.md @@ -0,0 +1,31 @@ +# Changelog 2026-07-09 -- repo_lint.py CRLF write_text bug (DOCFIX-143) + +## Item + +### 1. DOCFIX-143 -- `--record-clientdocs-sweep`/`--record-guide-skill-coupling` no longer emit CRLF +FILE: `scripts/repo_lint.py` (2 sites: the receipt writer, the coupling writer) + +WHY: flagged during the 2026-07-09 commit-and-push of the repo-agnostic sweep +(DOCFIX-141) -- `receipt.write_text(...)` on Windows translates `\n` to the +platform newline (`\r\n`) before writing, so `clientdocs/sweep-receipt.txt` +came out CRLF on disk every time `--record-clientdocs-sweep` ran in this +session. `.gitattributes`' `eol=lf` normalizes it away at `git add` time, so +no CRLF ever reached a commit -- but the script was silently depending on git +to clean up after its own sloppy output, the same class of "works here only +because something downstream bails us out" issue as the DOCFIX-140 L1 +path-separator bug. + +FIX: both writers now build the exact string, `.encode("ascii")` it, and +`write_bytes()` it -- no platform-dependent newline translation happens at +all. `.encode("ascii")` (not `"utf-8"`) deliberately: this repo's own L1 rule +is ASCII-only, so a future path/hash that somehow isn't ASCII now raises +loudly here instead of writing content L1 would fail on anyway. + +VERIFIED: re-ran `--record-clientdocs-sweep` after the fix; `sweep-receipt.txt` +byte-inspected directly (0 CR, 41 LF, was 41/41 before). `tests/repo-lint` +harness 34/34 (unchanged -- the fix doesn't change any file's logical +content, only its byte-level newline encoding). Full `repo-lint.sh` still +0 fail / 1 documented legacy warn. + +REVERT: `git checkout HEAD~ -- scripts/repo_lint.py` (re-arms the +CRLF-then-git-cleans-it-up dependency; not recommended). diff --git a/docs/session-ledger.md b/docs/session-ledger.md index 9d2392e..eaa6f08 100644 --- a/docs/session-ledger.md +++ b/docs/session-ledger.md @@ -745,6 +745,19 @@ `tofu providers schema -json` against the initialized provider, and read the real `libvirt_domain`/`libvirt_volume` schema directly before authoring the node-VM module. +- **DONE -- OPNsense gap detail (2026-07-09):** gap register item 4 split into + its 4 separable sub-gaps (network substrate done; VM/image blocked on the + domain module; OPNsense's own routing config not started, no mechanism + chosen; `tc netem` a separate OS-level thing blocked on an unruled D-100 + parameter). Mirrored into `opentofu/README.md` + the visual tracker. + COMMITTED + PUSHED (0bb6cff). +- **DONE -- DOCFIX-143 (changelog `docs/changelog-20260709-repo-lint-crlf-fix.md`):** + fixed the CRLF `write_text` bug flagged during the DOCFIX-141 commit -- + `--record-clientdocs-sweep`/`--record-guide-skill-coupling` now + `write_bytes()` with an explicit ascii-encode instead of relying on + `.gitattributes` eol=lf to clean up CRLF after the fact. Verified 0 CR bytes + on a live re-record; harness 34/34 unchanged; repo-lint 0 fail/1 warn. + Uncommitted -- operator has not yet asked to commit this piece. diff --git a/scripts/repo_lint.py b/scripts/repo_lint.py index 9f1225f..639fd02 100644 --- a/scripts/repo_lint.py +++ b/scripts/repo_lint.py @@ -149,13 +149,19 @@ body.append("%s %s" % (sweep_sha(p), rp)) else: print(" [info] L7 record: dropped missing %s from receipt" % rp) - receipt.write_text(RECEIPT_HEADER + "\n".join(body) + "\n") + # write_bytes + explicit ascii encode, not write_text: write_text's + # newline translation emits CRLF on Windows (this repo is LF-only; + # .gitattributes eol=lf cleans it up at `git add` time regardless, + # but this script should not depend on git to fix its own output). + receipt.write_bytes((RECEIPT_HEADER + "\n".join(body) + "\n").encode("ascii")) print(" [info] L7 recorded clientdocs sweep receipt (%d files)" % len(body)) if coupling_record: if guide.is_file(): - coupling.write_text(COUPLING_HEADER + "%s %s\n" - % (sweep_sha(guide), guide.relative_to(R).as_posix())) + coupling.write_bytes( + (COUPLING_HEADER + "%s %s\n" + % (sweep_sha(guide), guide.relative_to(R).as_posix())).encode("ascii") + ) print(" [info] L8 recorded guide->skill coupling pin") else: print(" [info] L8 record: no jenkins-kubernetes-guide.md -- nothing to record")