Repository navigation
fix: use American spelling in prose, identifiers and generated output - #21
datapointchris wants to merge 6 commits into
Conversation
Two tmux surfaces keep the British spelling, because both are tmux's own vocabulary rather than this repo's: display-panes-colour, display-panes-active-colour, clock-mode-colour — tmux's canonical option names. tmux accepts a `color` alias and stores it back as `colour`, which is what the manpage documents and what `show-options` prints. align=centre — tmux rejects `align=center` with "invalid style", the same error a bogus value gets. Every theme's pane-border-format needs it to parse. `centre` is declared in .codespellrc beside `noice`, which sits there for the same reason: a third party's spelling of its own thing. retrobox's extended key `grey` becomes `gray`, matching every other theme. Nothing reads it — no generator consumes EXTENDED_GREY and no highlight file references palette.grey.
codespell runs `--builtin clear,rare,en-GB_to_en-US`, so a British spelling is a finding at the moment it is typed. Its exclude gains `.csv` and `.tsv`, where a British place or company name is the record rather than a misspelling.
The block's comment states the constraint without spelling out a British example, so the generated config carries none of the words its own hook exists to catch.
datapointchris
left a comment
There was a problem hiding this comment.
PR review
Read: pull-requests.md, ci.md, documentation.md, shell.md end to end; testing.md and git-workflow.md by rule listing with the rules the diff reaches opened.
Not routed: go.md, rust.md, frontend.md, cli-design.md, release.md, data.md, api-design.md, infrastructure.md — the diff touches nothing they cover. python.md is not selected for this repo and the one .py hunk is a local parameter rename; nothing in its naming rules reaches it.
Read at 361e332. The branch moved twice during the review; every measurement below is at that head.
Findings: 1 correctness · 6 break a rule · 1 should be a rule · 1 design
Two of the body's claims I ran and they hold. Regeneration is byte-identical: git archive HEAD into two scratch trees, lib/generate-all.sh in one, diff -rq between them returns 0 differing files, at 7.4s wall and 625% CPU. And tmux does accept the American option aliases — set-option -g display-panes-color red exits 0 and show-options -g reads back display-panes-colour red, so the decision to leave those three names alone is right.
Correctness
.codespellrc:4— thecentreentry disables thecentre ==> centercorrection across the whole repo, so the gate this PR installs passes a Britishcentrein any prose written here from now on. Measured against the branch's own config:printf 'The centre column.\n' > probe.mdthencodespell --builtin 'clear,rare,en-GB_to_en-US' probe.mdexits 0. The narrower declared form was measured too. Withignore-words-list = noiceandignore-regex = align=centre,git ls-files | tr '\n' '\0' | xargs -0 -r codespell --builtin 'clear,rare,en-GB_to_en-US'still exits 0 over the whole tracked tree, and the same probe goes back toprobe.md:1: centre ==> center, exit 65. So the tree stays green and the word stops being free.ci.md§ "A lint rule is never switched off globally to satisfy one call site" is the rule, and thenoiceprecedent the body leans on does not reach this case — that rule's carve-out is for a proper noun with no source fix available, andcentreis an ordinary English word the new dictionary exists to catch. Fix: replace the word entry withignore-regex = align=centre, keepingignore-words-list = noice.
Breaks a written rule
-
lib/generators/tmux.sh:43,176,183—documentation.md§ "A repo is a product for a stranger; the fleet is one deployment of it" —themeis public (gh api repos/datapointchris/theme --jq .privatereturnsfalse), and three generator comments name a private sibling repo. Line 43 sends the reader todocs/architecture/tmux-sessions.md in dotfiles, which no stranger can open. Lines 176 and 183 are copied verbatim into every generated artifact:git grep -n -i dotfiles -- 'themes/*/tmux.conf'returns 50 lines across 25 files. The rule names generated config as where this vocabulary concentrates. This PR rewrote comments in that generator and regenerated all 25tmux.conf, which is the one moment the other repo-wide comment sweep was free to run. Fix: state the mechanism without naming the repo — "a status-line installer run before this file is sourced" carries it — thenlib/generate-all.sh --generators tmux. -
.codespellrc—ci.md§ "Tool-specific config goes in the tool's own file, not a hook arg" — the dictionary selection exists only in the hook'sargs:, so running the tool by hand in this repo does not reproduce the gate. Measured with the branch's.codespellrcin place, onThe colour of the behaviour we organise.:codespell probe.mdexits 0, andcodespell --builtin 'clear,rare,en-GB_to_en-US' probe.mdreturns three findings. Addingbuiltin = clear,rare,en-GB_to_en-USto.codespellrcreturns the same three with no hook arg at all. The rule names.codespellrcby name and cites this repo'snoiceentry as the worked shape. Fix: declarebuiltinin.codespellrc. The hook arg is forge's block and is not this repo's to change; the point is that the repo's own file should answer the same question. -
lib/generators/tmux.sh:108,109,136—documentation.md§ "Document a constraint at the edit site" —display-panes-active-colour,display-panes-colourandclock-mode-colourare deliberate and carry no note at the lines that hold them. The gate cannot supply one either:codespell --builtin 'clear,rare,en-GB_to_en-US'over a file containingdisplay-panes-colourexits 0, because its word regex keeps a hyphenated token whole. So the only record that these three are tmux's own names is the merge commit, and a reader editing that generator meets neither..codespellrcdocumentscentreat its edit site and these get nothing. Fix: one line above the block saying tmux owns the names and the spell gate cannot see them. -
PR body, How it was verified —
pull-requests.md§ "A receipt names the tool's blind spot" — the survivor scan reports "78 hits, every one a tmux option name", and that is not the population. Over the same file list,git ls-files -z | xargs -0 rg -uu -oi '(colour|centre|grey|behaviour|artefact|licence|organis|recognis|judgement)'returns 78colour, 55centreand 3grey. Thecentrehits split 50 inthemes/*/tmux.conf, 2 inlib/generators/tmux.shand 3 in.codespellrc. The threegreyarethemes/everforest-dark-hard/theme.yml:14,:15and:61, annotating base16 slots asgrey1andgrey2. That word is in the dictionary — a file holding baregreygivesgrey ==> gray, exit 65 — whilegrey1 grey2exits 0, which is exactly the compound-token blind spot the body documents two paragraphs above. It is also the word this PR renamed inretrobox, and none of the three instruments carries the stem. Fix: convert them, or name them in Decisions beside the tmux options as everforest's own slot names. -
PR body:71 —
git-workflow.md§ "A message describes the repo, never the route the change took", whichpull-requests.md§ "The body is the merge commit, so it is written as permanent history" extends to a body — "once from this branch, once from agit archiveof the parent commit".this branchis in that rule's banned list verbatim, and the sentence stops parsing the moment the history is linear. Fix: "once at this head, once from agit archiveof the parent commit". -
PR body, Decisions —
pull-requests.md§ "A claim reasoned to rather than run does not go in a body" — "tmux rejectsalign=centerwithinvalid style, the same erroralign=bogusvaluegets. Every theme'spane-border-formatdepends on it." The first sentence is true of a style option and the second names a format, where it is false. On tmux 3.7c,set-option -g status-style 'align=center'exits 1 withinvalid style: align=center;set-option -g pane-border-format '#[align=center]X'exits 0, and so doesalign=bogusvalue, because a format's#[...]is resolved at draw time rather than validated at set time. Both of this repo'salign=sites are formats —status-format[0]andpane-border-format— andgit grep -n 'style .*align=' themes/*/tmux.conf lib/generators/tmux.shreturns nothing. The decision is right and gets stronger from the correction: on the surface this repo actually uses, a wrong value is not refused, it just draws left. Fix: say the style parser accepts onlycentre, and that inside a format a wrong value fails silently.
Should be a rule
- PR body, How it was verified —
proposed: a-second-extraction-differs-in-vocabulary-not-only-in-tool—pull-requests.md§ "A receipt names the tool's blind spot" asks for "a second extraction by different means", and this body did that three times: codespell, anrgsurvivor scan, and an-ise/-yse/doubled-lscan. All three share one word list, so all three missgreytogether, and finding 4 above is the result. Different tool with the same vocabulary is one extraction run three times, and it reads as triangulation because the tools differ. The rule would say a second extraction differs in what it looks for, not only in what does the looking — and that a sweep's vocabulary must not be derived from what the first instrument already reported, which is how this one was built.testing.md§ "Two extractors in one comparison share one identifier grammar" is the near rule and asks for the opposite property in a different situation, so it does not reach this. It belongs inpull-requests.mdbeside the blind-spot rule, with this branch as the worked example.
Design and architecture
scripts/— the instruments that found the survivors exist only as three command blocks in a merge commit, and the next person doing this reconstructs them from prose. That reconstruction is what missed threegreythis time, so the cost is already paid once. The repo has the pattern for it:scripts/check-plugin-drift.shis a maintenance check, deliberately not athemesubcommand, run once or twice a year and after adding a plugin theme. A spelling sweep has the same shape and the same cadence. It is also smaller than what the body ran —git ls-files | tr '\n' '\0' | xargs -0 -r codespell -H --builtin 'clear,rare,en-GB_to_en-US' --regex "[a-zA-Z']+"replaces all three scans, because the regex splits hyphens and digits and the-Hreaches the dot-files; it reports all 136 British tokens, with hex fragments (EDE,CAF,DAA) andNoiceas the known false positives to filter. Without it, the sentence "78 hits, every one a tmux option name" is a fact about one afternoon, and the check that would keep it true is not in the repo.
This review does not gate merge.
datapointchris
left a comment
There was a problem hiding this comment.
PR review
Read at 361e332, the current head.
Read: pull-requests.md, ci.md, documentation.md end to end; git-workflow.md headings plus its message and merge-commit rules; testing.md, python.md and shell.md at rule-list level, opening the gate-proving and generated-artifact rules.
Not routed: api-design.md, cli-design.md, configuration.md, data.md, go.md, rust.md, frontend.md, infrastructure.md, repo-structure.md, tool-tiers.md — the diff adds no surface, no schema and no code in those stacks.
Findings: 2 correctness · 4 break a rule · 1 should be a rule · 1 design
The design pass first, since it decides whether the rest matters. The change should exist: American spelling is the stated house preference, and the repo carried the British forms in comments, docstrings, bats names, one parameter and one warning string. The two tmux exemptions are real and I ran both. tmux set-option -g status-style 'align=center' returns invalid style: align=center at exit 1, the same output align=bogusvalue produces. tmux set-option -g display-panes-color red is accepted and show-options -g reads it back as display-panes-colour red. The smallest-change rejection also holds: codespell alone returns 0 over the head tree while 133 British tokens remain. Regeneration is byte-identical — git archive 361e332 into a scratch tree, bash lib/generate-all.sh, diff -r against a pre-run copy is empty. bats tests/ in that tree is 243 tests at exit 0.
Correctness
-
.codespellrc:6—ignore-words-list = noice,centreswitches the new gate off forcentreacross the whole repo, so a Britishcentretyped into any prose here is never a finding. That is the outcome the branch exists to prevent, and a narrower declared exception in the same file avoids it. Measured on the head tree. Withignore-regex = align=centreandignore-words-list = noice,codespell -H --builtin 'clear,rare,en-GB_to_en-US'over every file returns 0 — the config's own comment survives, because everycentrein it sits insidealign=centre. A probe file holdingThe centre of the screen.then returnscentre ==> centerat exit 65. Under the committed config that same probe returns 0.ci.md§ "A lint rule is never switched off globally to satisfy one call site" is the rule the body cites; itsnoicecarve-out reasons from a proper noun with no source fix available, andcentreis neither. Fix:ignore-regex = align=centre, withignore-words-list = noice. -
themes/everforest-dark-hard/theme.yml:14,15,61— three British spellings survive and the survivor scan reports none. The body states the scan returns "78 hits, every one a tmux option name". Two extractions overgit ls-filesat361e332disagree. An explicit stem list returns 78colour, 55centreand 3grey. codespell's owndictionary_en-GB_to_en-US.txt, 526 entries, matched as substrings withrg -fover the same file list, returns the same threegreylines once the tmux surfaces and.codespellrcare set aside. They are palette comments:# grey1 - comments, line numbers,# grey2 - dark foreground,# grey1 - NOT white!. codespell cannot see them becausegrey1is one token, which is the blind spot the body itself names.grey->grayis in the dictionary, so a baregreyis caught. Commit6ef3c90converted the same word inthemes/retrobox/theme.yml, at# Comments (grey)and# ANSI 8 - grey. Two further things about that count.align=centreoccurs 52 times across 25tmux.conffiles andlib/generators/tmux.sh, is kept deliberately, and is absent from the 78. And a scan "matching British stems anywhere inside a token" cannot return 78, sincecentreis such a stem. I am certain the three lines are there and that the count is not the count; I do not know whether they were missed or kept. If they were kept, Decisions owes a third bullet — a reader who finds two documented exemptions and a third undocumented one reads the third as an oversight.
Breaks a written rule
-
Body, opening sentence —
documentation.md§ "A repo is a product for a stranger; the fleet is one deployment of it" — "The fleet prefers American spelling in prose and identifiers alike" names a private arrangement.datapointchris/themeis public, andmerge_commit_message=PR_BODYputs this sentence into publicgit logverbatim.pull-requests.md§ "A receipt is remeasured at the head, and a contract stated once" records exactly this gap: that rule's sweep readsgit ls-files, so it cannot see a body, which makes the body the one artifact certain to land onmainand structurally invisible to the check. Fix: state it as this repo's own convention. -
Body, Decisions, third bullet —
pull-requests.md§ "A body cites only what the repo carries" —ci.md§ "A lint rule is never switched off globally to satisfy one call site" points at a corpus no reader of this repo can open. Fix: carry what the rule said instead. A repo-wide exception declares its reason in the tool's own config file. -
Body, How it was verified —
git-workflow.md§ "A message describes the repo, never the route the change took" — "once from this branch, once from agit archiveof the parent commit".this branchis in that rule's banned list verbatim, and the rule's own tell applies: after the merge there is no this branch. Fix: name the two commits. -
Body, What to look at, item 2 —
pull-requests.md§ "The body addresses everyone who ever reads it, never one person" — "Check this is the right register for the exception, and that a per-line# codespell:ignorewould not have been better" hands the reader a decision. Directing attention is allowed and asking for a decision is not. Item 3's "Check nothing resolves it by name" is the sanctioned shape, because it names a fact. Fix: drop the second clause. Decisions already records the choice.
Should be a rule
.codespellrc—proposed: narrowest-declared-lint-exception—ci.md§ "A lint rule is never switched off globally to satisfy one call site" names two tiers. A repo-wide declared exception carrying its reason, and a per-line suppression needing approval. It names no tier for a scoped pattern, and its worked example,ignore-words-list = noice, is the widest of the three. So the body reasons straight from "not per-line" to "declared word list" and never weighsignore-regex, which is neither. Most linters ship the middle tier — codespell'signore-regex, ruff'sper-file-ignores, a shellcheck directive scoped to one function. The existing rule is written too narrowly to catch a case where the narrow form exists and is free.
Design and architecture
themes/*/theme.yml— the only instrument that can see a British spelling inside a compound token is a command typed once into a PR body. codespell tokenizes, sogrey1, and every upstream palette slot spelled the British way, is invisible to the gate this branch installs. Finding 2 above is that gap firing on the current tree. The consequence is for whoever transcribes the next plugin palette: they write# grey0,# grey1from upstream's own names, the hook passes, CI passes, and nothing reports it.CLAUDE.md§ "Mapping a Palette into theme.yml" is the section read at the moment that decision is made and it says nothing about spelling, so the convention6ef3c90establishes for retrobox is recorded nowhere.tests/generators.batsalready holds the repo-wide invariants that used to live inCLAUDE.mdas shell one-liners, which is the shape this scan fits.
This review does not gate merge.
datapointchris
left a comment
There was a problem hiding this comment.
PR review
Read end to end: pull-requests.md, ci.md, shell.md, python.md, configuration.md, README.md
Read in part: documentation.md (the comment, canonical-source, pointer, citation and repo-is-a-product-for-a-stranger rules), testing.md and code-quality.md (heading list, then the sections the diff reaches)
Not routed: go.md, rust.md, frontend.md, data.md, api-design.md, cli-design.md, tool-tiers.md, release.md, infrastructure.md, repo-structure.md, dependencies.md, help.md, common-errors.md, claude-output-style.md — the diff touches nothing they cover
Findings: 3 correctness · 5 break a rule · 1 should be a rule · 1 design
The regeneration claim holds and I re-ran it. lib/generate-all.sh over every theme and every generator, into a copy of the tree at f3277cc, then diff -rq against the committed artifacts: no differences, 9.8s wall. Both tmux decisions hold too, measured on tmux 3.7c — set-option -g display-panes-color '#665c54' exits 0 and show-options -g reads back display-panes-colour #665c54, and set-option -g status-style 'align=center' exits 1 with invalid style: align=center, the same error align=bogusvalue gets. The grey rename is unreferenced: no generator reads EXTENDED_GREY or EXTENDED_GRAY, no highlight file references palette.grey or palette.gray, retrobox carries no colliding key, and the five other themes with such a slot all spell it gray.
Correctness
-
.pre-commit-config.yaml:1— the committed generated config is not what the generator emits, and the stamp says the repo is current in both states.abc9d69andf3277ccboth carry# forge-toolchain: 20, and their codespell blocks differ. The block moved again after this commit, so the die now emits a third text: the paragraph at:109and the one above theexclude:are both superseded, and the later revision exists specifically because the example words in the first one trip the hook the block installs. The next apply rewrites this file with no commit accounting for the diff. Nothing can report that: the stamp declaration's ownbump_whenreads "any change to what a generator emits — a new block, a dropped block, or different content out of an existing one", and the stamp has not moved since 2026-09-01, so a stamp-only currency check answers "current" before this change, after it, and after the correction.ci.md§ "forge is the source of truth" and § "Generated configs carry a# <tool>-toolchain: Nstamp". Fix: bump the declared stamp, re-run the apply, and commit the result on this branch so the file matches the die and the stamp separates the two states. -
The body's Smallest change that would work is measured on the tree the change produced, and the measurement taken on the tree that decides the question says the opposite. The body: "running codespell alone and stopping. Rejected by measurement: it returns 0 while 78 British tokens remain." A 0 at the head is guaranteed — the conversion is what produces it. Run it against the parent instead. Take the 111 lines the spelling commit removed and hand them to the same dictionary:
git diff $(git merge-base origin/main f3277cc)..f3277cc -U0 \ -- . ':!.pre-commit-config.yaml' ':!.codespellrc' \ | rg '^-[^-]' | sed 's/^-//' > removed.txt → 111 lines codespell --builtin 'clear,rare,en-GB_to_en-US' removed.txt \ | cut -d: -f2 | sort -u | wc -l → 110Two extractions agree on the input:
rg -c -i 'colour|behaviour|artefact|licence|organis|recognis|judgement|labelled|favour|honour|grey|analyse'over the same file returns 111. So codespell alone finds 110 of the 111 lines this change edits. The single line it misses is# bell style: inverted rather than merely recoloured.What it genuinely cannot see is the 78 tmux compound names and everforest'sgrey1/grey2— and the change converts neither of those, so the second instrument's unique contribution to the diff is one word. Undermerge_commit_message=PR_BODYthis sentence is permanent history asserting the opposite of what the code shows. Fix: state the measurement overmain, and say what the survivor scan actually added. -
The survivor scan's pattern omits the two words the change is about, and three real survivors fall outside the count. The body reports "82 hits: 78 tmux option names, 4 inside forge's generated hook comment." The same scan over the same tree with
centreandgreyin the pattern returns 141 occurrences: 79colour, 55centre, 3grey, and one each oflicence,Centre,behaviourandartefact. The threegreyarethemes/everforest-dark-hard/theme.yml:14,:15and:61—grey1andgrey2inside comments, compound tokens codespell cannot match, which is exactly the blind spot this instrument exists to cover. They are everforest's own palette slot names (everforest-nvim/lua/everforest/types.lua:66-68declaresgrey0,grey1,grey2), so keeping them is very likely right; nothing in the change says so, and the receipt reads as an exhaustive account of what survived. The hook-comment figure is short too: atf3277ccthat file carries nine British spellings, and codespell flags eight of them the moment the filename does not start with a dot. Fix: rerun the scan withcentreandgreyin the pattern, correct the number, and record what happens togrey1/grey2.
Breaks a written rule
-
.codespellrc:6—ci.md§ "A lint rule is never switched off globally to satisfy one call site" —ignore-words-list = noice,centreturns the word off across the whole repo to satisfyalign=centrein 25 generated files.ignore-regexis the scoped form, and it works:ignore-regex = align=centre codespell --builtin 'clear,rare,en-GB_to_en-US' themes/gruvbox/tmux.conf → exit 0 printf 'the centre of the screen\n' > p.txt ; codespell … p.txt → exit 65 ignore-words-list = noice,centre (as committed) codespell … p.txt → exit 0The committed form is the one that lets a prose
centrethrough the gate this change exists to install; the narrower one does not, and silences the generated files just as completely. The Decisions entry cites that same section in support, and the section's remedy is a declared exception scoped to the case —toolchain.shellcheck_disableis the shape it names. The sanctioned codespell precedent beside it isnoice, which the same paragraph distinguishes explicitly: teaching a checker a proper noun is not disabling a check, and there is no source fix when the word is correct.centrehas a source fix everywhere except tmux's style value, andignore-regexis what says so. Fix:ignore-words-list = noiceplusignore-regex = align=centre, keeping the comment where it is. -
.pre-commit-config.yaml:114—ci.md§ "Tool-specific config goes in the tool's own file, not a hook arg" —args: ['--builtin', 'clear,rare,en-GB_to_en-US']puts half of codespell's configuration in the hook while the other half sits in.codespellrc, and the two halves disagree for anyone not going through pre-commit. Measured at the repo root:codespell themes/gruvbox/tmux.conf lib/generators/tmux.sh CLAUDE.mdexits 0, so a developer checking their own work locally gets a pass on the files the hook is gating..codespellrctakes the setting — withbuiltin = clear,rare,en-GB_to_en-USin that file,codespellonthe colour is greyreturns two findings andthemes/gruvbox/tmux.confstays clean. That rule's own worked example is codespell and it names.codespellrcas the destination. The edit belongs in the die, since generation rewrites this file wholesale. -
body:106 —
pull-requests.md§ "A body cites only what the repo carries" — the Decisions entry carriesci.md § "A lint rule is never switched off globally to satisfy one call site"into the merge commit.gh api repos/datapointchris/theme --jq .visibilityreturnspublic, and no reader of this repo can open that file.documentation.md§ "A repo is a product for a stranger; the fleet is one deployment of it" ships the sweep; its citation half hits this line and nothing else in the body or the tree. Fix: write what the rule said — a check is not switched off repo-wide to satisfy one call site — and drop the pointer. -
body:1 — the same two rules, term half — "The fleet prefers American spelling in prose and identifiers alike". Fix: "This repo prefers American spelling in prose and identifiers alike". Run over the tracked tree at
f3277cc, both halves of that sweep are otherwise clean: the only hits are# forge-managedheader lines andmacminiin test fixtures, which are values a program reads rather than prose. -
body:71 —
git-workflow.md§ "A message describes the repo, never the route the change took", reached throughpull-requests.md§ "Sweep the ban list rather than reading for it" — "once from this branch, once from agit archiveof the parent commit".this branchis in that ban list verbatim. Fix: name the two commits.
Should be a rule
- body —
proposed: rejected-alternative-measured-before-the-change— a receipt ruling out a smaller alternative is taken on the tree before the change, never on the tree the change produced. The post-change tree can only return the answer the change was built to produce, so the number is guaranteed, says nothing, and reads exactly like evidence. No rule reaches it.pull-requests.md§ "A rejected alternative carries the same receipt a finding does" requires a receipt and is silent on which tree it is taken from, and § "A receipt is remeasured at the head, and a contract stated once" points the other way for behaviour receipts — correctly, for what it governs, which is what makes this the easy mistake. It belongs inpull-requests.mdbeside the rejected-alternative rule. Finding 2 above is the worked example.
Design and architecture
lib/generators/tmux.sh:108,:109,:136,:188andthemes/everforest-dark-hard/theme.yml:14— the change deliberately keeps a British spelling in five places and the repo records the reason at none of the sites..codespellrc:3-5explainscentre, in a file nobody opens while editing a generator. The three*-colouroption names and everforest'sgrey1/grey2have nothing anywhere in the tree; their reasons live in a commit message and in this PR. Both failure directions are silent. Renaming the option names is absorbed —set-option -g display-panes-colorexits 0 and tmux stores it back undercolour, so the edit reads as working while the generated configs stop matching whatshow-optionsprints. Andalign=centeris rejected by tmux's style parser (invalid style: align=center) whileset-option -g pane-border-format '#[align=center]X'exits 0, so the one spelling with a hard failure is the one nothing catches at edit time. The repo'sCLAUDE.mdKey Insights is where every trap of this shape already lives, including the quotedGENERATOR_OUTPUTsubscripts, whose whole content is that a formatter rewrote something and the only symptom was silence. Fix: one bullet there naming the three option names,align=centreand everforest'sgrey1/grey2, with the tmux error as the reason.
This review does not gate merge.
PR review — mergedThree reviewers ran, blind to each other and to the session that launched them. This All three read at Findings 5 and 16 as first posted called the sibling repo private. It is public, Findings: 4 correctness · 8 break a rule · 3 should be rules · 4 design The three agree on what the change gets right, each having run it independently. Correctness
Breaks a written rule
Should be a rule
Design and architecture
This review does not gate merge. |
`ignore-words-list = centre` turned the correction off repo-wide, so the gate this branch installs passed the British spelling in any prose written here. `ignore-regex = align=centre` exempts the tmux literal and leaves the word a finding, measured both ways against the same file under codespell's default token regex and the widened one. `.codespellrc` also names the dictionaries the hook passes on the command line. Without them a bare `codespell` at the repo root reports nothing on the files the hook gates, so a developer checking their own work gets a pass the commit refuses. `scripts/check-spelling.sh` covers what neither the hook nor a `\b`-anchored search reaches. codespell keeps a hyphenated or digit-suffixed token whole and refuses a dot-prefixed file without `-H`, and there is no word boundary between a letter and a digit, so `display-panes-colour` and `grey1` are invisible to both instruments at once. The script widens the token regex to letters only, passes `-H`, and declares the five sites where the British spelling is correct. everforest's `grey1` and `grey2` are among them. Every comment in that palette names the upstream slot its value came from, so `gray1` would point at a slot the plugin does not have.
Three generator comments named a sibling repo and a tool it ships, and two sat inside the heredoc, so every generated tmux.conf carried them — 50 lines across 25 themes. A repo is read by someone who has never heard of the machines it happens to be deployed on, and a comment copied into generated config is where that vocabulary travels furthest. The mechanism is what a reader needs and it survives without the name: a status installer relocates tmux's stock window row, and a remote shell sets pane_title over OSC 2. The three `*-colour` option names now say at the edit site that the spelling is tmux's own. Nothing else can say it. codespell keeps a hyphenated token whole, so a file holding that name exits 0, and tmux accepts the `-color` alias while storing it back, so a rename reads as working while the generated config stops matching what `show-options` prints. That comment carries no backticks. The heredoc is unquoted, so a backtick in it is command substitution: the quoted name runs as a command and the generated file gets an empty gap where the name should be, with nothing failing. `scripts/check-spelling.sh` settles the `-colour` suffix those comments name, and iterates its patterns in sorted order so the per-pattern counts are the same on every run.
codespell runs with `-H`, so a file whose basename starts with a dot is read rather than skipped at exit 0. `.pre-commit-config.yaml`, `.codespellrc`, `.gitignore` and `.editorconfig` sat outside the check this file installs. A dot-named directory was always read, so `.github/**` never needed it. The stamp moves to 21, which is what lets a currency check tell this block apart from the one before it. Two commits carrying stamp 20 held different codespell blocks, and nothing could report the difference.
|
Closing without merging. The sweep this belongs to is cancelled. Converting existing British spellings across the portfolio was never the goal — stopping Claude Code from writing them is. Those are different problems, and this PR is what the first one costs. This repo is the case that should have ended the sweep rather than been worked around. tmux's own option names are Meeting that with a The existing comments about tmux's option names were already accurate and needed nothing. Branch |
This repo prefers American spelling in prose and identifiers alike, and it carried
the British forms in comments, docstrings, test names, one Python parameter and
one warning string. This converts those, puts the
en-GB_to_en-USdictionary onthe codespell hook, and adds the check that finds what the hook structurally
cannot. Five sites keep the British spelling because another program owns the
name; each is declared with its reason.
What to look at
lib/generators/tmux.sh— three*-colouroption names and twoalign=centreare untouched, and the comment above the first block says why.The same file's comments no longer name a sibling repo, and 50 lines of that
left the 25 generated
tmux.conffiles with them.scripts/check-spelling.sh— new. ItsSETTLEDtable is the only recordof which British spellings are deliberate. Read whether each pattern is narrow
enough to reject a real one, and whether the reasons are checkable.
.codespellrc—ignore-regex = align=centre|\["[^"]*"\]rather than aword list, plus
builtinso a barecodespellmatches the hook.themes/everforest-dark-hard/theme.yml—grey1andgrey2stay in thecomments that name upstream's slots. Every other comment in that column names
an everforest slot too.
themes/retrobox/theme.ymland its generatedpalette.lua— the extendedkey
greybecomesgray, the only key rename in the diff.lib/lib.sh:395— the only user-visible string that changed.Every other file in the diff is a comment, a docstring or a bats test name.
How it was verified
What the second instrument was actually worth, measured before the change
rather than after it. Taken at the head, a codespell run returns 0 because the
conversion is what produces the 0. Against the parent of the spelling commit:
So codespell alone would have found 110 of the 111 lines this change edits. The
one it misses is
# bell style: inverted rather than merely recoloured.Thesecond instrument's contribution to the diff is one word. Its contribution to the
census is different and is where it failed: it was supposed to tell a deliberate
keep from a miss, and it missed
grey1andgrey2entirely.The three blind spots that produce that, each measured. codespell keeps a
hyphenated or digit-suffixed token whole, so
display-panes-colourandgrey1both exit 0. There is no word boundary between a letter and a digit, so an
rgpattern anchored on
\bmisses the same two — one shared failure, not twoindependent ones. And codespell refuses a dot-prefixed file without
-H, evenwhen the file is named explicitly: identical bytes gave 0 findings as
.pre-commit-config.yamland 9 asplain.yaml. A file inside a dot-prefixeddirectory is read normally;
.github/PROBE.ymlwas flagged either way.scripts/check-spelling.shis the instrument that survives this PR. Onecodespell call with
-H --regex "[a-zA-Z']+"splits on-,_and digits andopens the dot-files, which reaches all three classes at once. At the head:
Its assertion was proved able to fire. A planted
# a colour and a centre and a grey thingproduces three findings, including the two words no earlierinstrument here could catch.
Regeneration is byte-identical across two consecutive runs, and the committed
artifacts match what the generators emit.
The effect was diffed rather than reasoned about.
theme apply gruvboxrantwice into a sandbox with
HOMEand all four XDG paths repointed and everyreload command stubbed, once from each of the two trees. Both installed the same
31 files, and the whole content difference was one comment line. The resulting
gruvbox.confthen sourced into an isolatedtmux -Lserver at exit 0, withshow-options -greading backdisplay-panes-colour #665c54.bats tests/— 243 passing, exit 0.What changes
One user-visible string. The warning shown when a plugin theme's colorscheme is
absent and the theme ships no fallback now ends "the editor keeps its previous
colors".
codespellrun bare at the repo root now applies the same dictionaries as thehook. It previously exited 0 on files the hook rejects.
The commit gate now reads dot-named files.
.codespellrc,.gitignore,.editorconfigand.pre-commit-config.yamlwere skipped at exit 0 before, sothe config installing the check sat outside it. Proved by planting
# a colour of a thingin.gitignore: the old invocation is silent, the new one reports it.The generated
tmux.conffiles lost two comment lines each that named a siblingrepo. Nothing reads them.
Nothing else observable changes. The rest of the generated output differs only in
comments, and
retrobox's renamed palette key is read by nothing.Decisions, and what they rejected
*-colouroptions keep their spelling — they are tmux'scanonical names. tmux accepts
display-panes-colorand stores it back underdisplay-panes-colour, which is whatshow-optionsprints and what themanpage documents. The alias makes a rename survivable rather than correct, and
the generated config would stop matching what tmux reports.
align=centrekeeps its spelling, and the reason is the opposite of loud.A style refuses the other spelling:
set-option -g status-style 'align=center'exits 1 withinvalid style. A format validates nothing, andevery
align=site in this repo is insidepane-border-format:#[align=center]and#[align=bogusvalue]both set at exit 0 and simply drawleft. So the wrong spelling here fails silently at draw time, which is why the
literal is exempted rather than the word.
grey1andgrey2stay — every comment in that palette namesthe upstream slot its value came from, and
gray1would name a slot the plugindoes not have. That is the same failure as renaming a third-party option key:
it reads as working and points at nothing.
ignore-words-list = centreswitches the correction off repo-wide, so the gate this change installswould pass the British spelling in any prose written here afterwards. Measured
both ways against the same file: with the regex form, the tmux literal passes
and prose is still a finding.
greybecomesgrayin retrobox — no generator consumesEXTENDED_GREY,no highlight file references
palette.grey, and every other theme spells thatslot
gray.It converts 110 of the 111 edited lines, so it is most of the change rather
than none of it. What rules it out is the five sites that had to be recognized
and kept: it cannot see four of them, and a clean run reads identically whether
they were considered or overlooked.
Risk and rollback
Nothing deploys. A revert restores the British spellings, the wider codespell
exception and the sibling-repo comments, and costs nothing else — no state is
written and no schema moves.
A revert cannot undo a theme applied to a machine in the meantime. That machine
keeps a
tmux.confwhose comments differ, which nothing reads.What this does not do
It does not change any color value, palette, or generated configuration that an
application parses. It does not sweep the sibling-repo references
outside the tmux generator:
bin/themesources a path under another repo asworking code, and the test fixtures use machine names, and both need decisions
this change does not make.
The review
#21 (comment) — 4
correctness, 8 break a rule, 3 should be rules, 4 design.
ignore-regex = align=centrescopes it to the literal.grey1/grey2were a real miss and stay aseverforest's slot names, now recorded in the theme.yml itself. Both figures in
this body were wrong and are replaced; the survivor scan is retired in favor
of
scripts/check-spelling.sh, which finds them.the claim about what the second instrument added is corrected.
so the bump happened there and the regenerated config lands in that commit.
Stamp 21 separates this block from the two that both carried 20 while
holding different codespell args.
and 50 lines left the generated artifacts.
.codespellrcnames the dictionaries the hook passes.carries no backticks, because the heredoc is unquoted and a backtick in it is
command substitution — the first version of it silently generated an empty gap
where each option name should have been.
the decision rather than weakening it.
repo-wide word list and a per-line suppression, and most linters ship one.
not only in what does the looking. All three instruments here shared one word
list and missed
greytogether.the tree before the change, never on the tree the change produced.
clean. The rest is named under What this does not do rather than left as
an absence.
against the parent tree, and the ones that cannot be are labeled as counts
rather than as evidence.
everforest's palette,
scripts/check-spelling.sh'sSETTLEDtable, and theCLAUDE.md section read while transcribing a palette.
scripts/check-spelling.sh, in the shape of the existing maintenancecheck rather than a
themesubcommand.