From 9d4d3294c054ecdd4e92adbfb4547baec188abed Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sun, 21 Jun 2026 23:05:45 +0200 Subject: [PATCH 1/3] Add rudimentary codespell config --- pyproject.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 6359976..c7cb1e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,3 +25,10 @@ markers = [ "smoke: marks as smoke test", "slow: marks as a slow running test", ] + +[tool.codespell] +# Ref: https://github.com/codespell-project/codespell#using-a-config-file +skip = '.git,.gitignore,.gitattributes,*.svg,vendor,*.lock,*.css' +check-hidden = true +# ignore-regex = '' +# ignore-words-list = '' From 6b4b6a4534b183ccb77c27fca0d034c89052e6b9 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sun, 21 Jun 2026 17:18:32 -0400 Subject: [PATCH 2/3] Tune codespell config: migrate pre-commit args, expand whitelist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the inline `-L` / `-S` arguments out of `.pre-commit-config.yaml` and into the central `[tool.codespell]` section of `pyproject.toml` so that every runner (pre-commit, direct `codespell` invocation, CI) reads the same configuration. Previously, the inline `-S Cargo.*,vendor/*` masked vendored-code typos that a direct `codespell` run would have surfaced. Other changes: - Skip `*/thirdparty/*` (vendored native code like rpmalloc has its own typos) and `*/vale/styles/*` (Vale rules use deliberate word-fragment patterns like `lication`). - Add documenting comments explaining why each ignored word is whitelisted (Rust keyword, library name, surname, French loanword, mathematical term, etc.). - Add `pathC`/`subB`-style camelCase regex so test path components don't get flagged. - Add an `exclude:` regex on the pre-commit hook to mirror the central `skip` patterns — pre-commit passes file paths explicitly, which bypasses codespell's own skip handling. - Bump the codespell pre-commit hook from `v2.2.4` to `v2.4.2`. Signed-off-by: Yaroslav Halchenko Co-Authored-By: Claude Code 2.1.138 / Claude Opus 4.7 (1M context) --- .pre-commit-config.yaml | 10 +++++++--- pyproject.toml | 21 ++++++++++++++++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c63b798..dc77444 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -57,11 +57,15 @@ repos: exclude: ".envrc$" - repo: https://github.com/codespell-project/codespell - rev: v2.2.4 + # Configuration lives in pyproject.toml [tool.codespell]. + rev: v2.4.2 hooks: - id: codespell - args: [ "-L", "ue,crate,numer,ser,ratatui,ect,noes,keep-alives", "-S", "Cargo.*,vendor/*" ] - exclude: ^docs/developing/doc-standards/tools/vale/styles/ + additional_dependencies: + - tomli; python_version<'3.11' + # Mirror central `skip` patterns — pre-commit passes file paths + # explicitly, which bypasses codespell's own skip handling. + exclude: '^(docs/developing/doc-standards/tools/vale/styles/|vendor/|Cargo\.)' - repo: https://github.com/rhysd/actionlint rev: v1.7.1 diff --git a/pyproject.toml b/pyproject.toml index c7cb1e5..656aafc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,22 @@ markers = [ [tool.codespell] # Ref: https://github.com/codespell-project/codespell#using-a-config-file -skip = '.git,.gitignore,.gitattributes,*.svg,vendor,*.lock,*.css' +# Keep options here in sync with the pre-commit `exclude:` regex for codespell — +# pre-commit passes file paths explicitly, which bypasses these `skip` patterns. +skip = '.git,.gitignore,.gitattributes,*.svg,vendor,*.lock,*.css,Cargo.*,*/thirdparty/*,*/vale/styles/*' check-hidden = true -# ignore-regex = '' -# ignore-words-list = '' +# Ignore camelCase identifiers (e.g. test path components like `pathC/subB/`) +ignore-regex = '\b[a-z]+[A-Z]\w*\b' +# crate - Rust keyword (e.g. `crate::`) +# ratatui - Rust TUI library name (https://ratatui.rs) +# ser - `serde::ser` module / serializer abbreviation +# noes - intentional "Oh noes" in test error message +# keep-alives - HTTP keep-alive (plural form used in some configs) +# thirdparty - directory name used in path strings (e.g. `native/thirdparty/`) +# requestor - alt spelling used in lore-transport / system-design docs +# numer - numerator abbreviation (preserved from prior inline config) +# ue, ect - preserved from prior inline pre-commit config (legacy false positives) +# collet - surname (Yann Collet, author of Zstandard) cited in system-design.md +# accomplis - French loanword in English ("faits accomplis") +# disjointness - mathematical property of being disjoint (≠ "disjointedness") +ignore-words-list = 'crate,ratatui,ser,noes,keep-alives,thirdparty,requestor,numer,ue,ect,collet,accomplis,disjointness' From 2791789d8a828bcd5d4eaa94b6a7e67163466c94 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sun, 21 Jun 2026 17:19:02 -0400 Subject: [PATCH 3/3] Fix typos detected by codespell Real typos: - lore-server/src/settings.rs: "sits infront of" -> "sits in front of" - lore-revision/src/nametable.rs: "rebuiling" -> "rebuilding" (in a TODO comment about garbage-collecting the nametable) Style normalisation (codespell prefers the closed form, both are valid English): - lore-server/build.rs: "re-declared" -> "redeclared" - docs/.../canon/doc-types.md: "re-use" -> "reuse" - docs/.../operational/review-checklist.md: "re-used" -> "reused" Intentional test-fixture typos in `scripts/test/test_conflict.py` (the test deliberately writes "conflic" to exercise merge-conflict behaviour against a later "conflict" fix) are protected with inline `# codespell:ignore conflic` pragmas rather than whitelisted globally, so future genuine misspellings of "conflict" still get flagged. Signed-off-by: Yaroslav Halchenko Co-Authored-By: Claude Code 2.1.138 / Claude Opus 4.7 (1M context) --- docs/developing/doc-standards/canon/doc-types.md | 2 +- .../doc-standards/operational/review-checklist.md | 2 +- lore-revision/src/nametable.rs | 2 +- lore-server/build.rs | 2 +- lore-server/src/settings.rs | 2 +- scripts/test/test_conflict.py | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/developing/doc-standards/canon/doc-types.md b/docs/developing/doc-standards/canon/doc-types.md index aa632b5..deb4f51 100644 --- a/docs/developing/doc-standards/canon/doc-types.md +++ b/docs/developing/doc-standards/canon/doc-types.md @@ -397,7 +397,7 @@ Optional sections (use when the content warrants): `docs/developing/decisions/NNNNN-.md`, where `NNNNN` is zero-padded and `` is the lowercased, hyphenated form of the decision title (drop articles). -Numbering is monotonic across the project. A new ADR claims the next available number; never re-use a number even for superseded ADRs. The H1 itself doesn't include the number — readers find it via the filename and the directory listing. +Numbering is monotonic across the project. A new ADR claims the next available number; never reuse a number even for superseded ADRs. The H1 itself doesn't include the number — readers find it via the filename and the directory listing. ### Voice and length diff --git a/docs/developing/doc-standards/operational/review-checklist.md b/docs/developing/doc-standards/operational/review-checklist.md index bcd9e20..63a605b 100644 --- a/docs/developing/doc-standards/operational/review-checklist.md +++ b/docs/developing/doc-standards/operational/review-checklist.md @@ -86,7 +86,7 @@ Triggers when the change adds a new ADR or updates the `status` or `date` fields *See [`../canon/doc-types.md`](../canon/doc-types.md) § ADR.* - [ ] New ADR: uses a `status` / `date` header block (not a title/description block). -- [ ] New ADR: filename follows `NNNNN-.md` with the next available sequence number; no number is re-used. +- [ ] New ADR: filename follows `NNNNN-.md` with the next available sequence number; no number is reused. - [ ] Status update on an accepted ADR: only `status` and `date` fields changed — body is untouched. - [ ] Change of decision: a new ADR is written (not an edit to the existing body); the prior ADR's `status` is updated to `superseded by ADR-NNNNN` and its body is left unchanged. - [ ] Change of decision: the new ADR links to the prior (superseded) ADR in its `More Information` section. diff --git a/lore-revision/src/nametable.rs b/lore-revision/src/nametable.rs index f24a5e7..d0c0ce8 100644 --- a/lore-revision/src/nametable.rs +++ b/lore-revision/src/nametable.rs @@ -219,7 +219,7 @@ impl NameTable { /// (entries are never removed or relocated), and all callers immediately /// copy the result to an owned `String` before the borrow expires. pub fn load(&self, hash: u64) -> &str { - // TODO(mjansson): Garbage collect nametable by iterating entire merkle tree and rebuiling + // TODO(mjansson): Garbage collect nametable by iterating entire merkle tree and rebuilding // nametable, cleaning out stale entries let data = self.data.read(); let entry = data.entry_buffer.as_type_slice::(); diff --git a/lore-server/build.rs b/lore-server/build.rs index 2f9c14e..e08a971 100644 --- a/lore-server/build.rs +++ b/lore-server/build.rs @@ -89,7 +89,7 @@ fn protoc_available() -> bool { .is_ok_and(|output| output.status.success()) } -/// Compile the legacy urc.rpc.{Storage,Revision,Repository,Environment}Service protos that now live in this crate. `urc.model` messages stay in `lore-proto`; `extern_path` redirects generated references there so the types are not re-declared. +/// Compile the legacy urc.rpc.{Storage,Revision,Repository,Environment}Service protos that now live in this crate. `urc.model` messages stay in `lore-proto`; `extern_path` redirects generated references there so the types are not redeclared. fn compile_legacy_protos() -> Result<(), Box> { // Declare the codegen inputs unconditionally so Cargo re-runs this script // when PROTOC changes or a watched .proto is edited — even on a build where diff --git a/lore-server/src/settings.rs b/lore-server/src/settings.rs index 6fad5ff..0b0cacc 100644 --- a/lore-server/src/settings.rs +++ b/lore-server/src/settings.rs @@ -306,7 +306,7 @@ pub struct QuicSettings { pub port: i32, pub transport_bits_per_second: Option, pub transport_rtt: Option, - /// Keep below a threshold for whatever Load Balancer sits infront of the server + /// Keep below a threshold for whatever Load Balancer sits in front of the server /// or is expecting responses. If request handlers exceed this reasonable threshold /// then assume something has gone wrong and return a timeout response so we can get metrics /// and clients don't hang forever diff --git a/scripts/test/test_conflict.py b/scripts/test/test_conflict.py index c032a67..88bf632 100644 --- a/scripts/test/test_conflict.py +++ b/scripts/test/test_conflict.py @@ -177,7 +177,7 @@ def test_merge_conflict_reset_shows_file_once(new_lore_repo): # Initial commit with a typo in auto_merged_file with repo.open_file(auto_merged_file, "w+") as output_file: - output_file.writelines(["conflic in main\n"]) + output_file.writelines(["conflic in main\n"]) # codespell:ignore conflic with repo.open_file(conflicting_file, "w+") as output_file: output_file.writelines(["Line A\n", "Line B\n", "Line C\n"]) @@ -201,7 +201,7 @@ def test_merge_conflict_reset_shows_file_once(new_lore_repo): repo.branch_switch("main") repo.branch_create("branch2") with repo.open_file(auto_merged_file, "w+") as output_file: - output_file.writelines(["conflic in main\n"]) + output_file.writelines(["conflic in main\n"]) # codespell:ignore conflic with repo.open_file(conflicting_file, "w+") as output_file: output_file.writelines(["Line A\n", "Modified by branch2\n", "Line C\n"]) @@ -218,7 +218,7 @@ def test_merge_conflict_reset_shows_file_once(new_lore_repo): # Unstage the auto-merged file (now contains "conflict in main") repo.unstage(auto_merged_file) - # Reset the auto-merged file (reverts to "conflic in main" - branch2's HEAD) + # Reset the auto-merged file (reverts to "conflic in main" - branch2's HEAD) # codespell:ignore conflic # BUG: This should show the file once, but it shows twice repo.reset(auto_merged_file)