Gate US English spelling where cspell does not reach - #475
Merged
Conversation
The cspell gate reads README.md and HISTORY.md only, deliberately: gating every markdown file would mean endlessly padding cspell.json with technical terms. That leaves a British spelling anywhere else in the tree with nothing checking it, which is how `labelled`, `behaviour` and `judgement` reached main. The new `spelling` rule closes the gap and joins the blocking CI run, since the tree is clean of them as of this commit. The banned words generate from stems rather than list one by one, since an inflected spelling is as wrong as its base and a hand-listed family drifts as soon as one form is added without the others. Two words are deliberately absent: `analyses` is the US plural of `analysis` as much as a British verb form, and `cancelled` is a GitHub Actions job status rather than prose. Outside markdown the rule reads the comments rather than the source lines, reusing the extraction comment-wrap already does. Judging a source line as prose would have this script report its own table of banned words. Also leads YAML['quote_after'] with the dash. Membership is a set test, so the order carries no behavior, but ':-,' reads as a regex range and cost a review round on #474 when it was read as missing the dash. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new spelling rule to scripts/prose_lint.py to enforce the repo’s US English convention in places not covered by the existing cspell gate, and wires it into CI as a blocking check. This also fixes the currently-known British spellings already present in the tree and adds test coverage for the new rule.
Changes:
- Implemented a
spellingrule inscripts/prose_lint.py(stem-generated British→US mapping; scans Markdown prose and non-Markdown comments). - Added a dedicated
TestSpellingsuite and a repo-cleanliness assertion to prevent the gate from passing due to empty discovery. - Updated CI (
validate-task.yml) to gate onspellingalongsidecharsetanddupword, and corrected the known British spellings in the repository.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| spec/validate.py | Fixes “labelled” → “labeled” in a comment to comply with US English. |
| scripts/test_prose_lint.py | Adds comprehensive tests for the new spelling rule, including table-driven coverage and a repo-wide clean assertion. |
| scripts/README.md | Documents the new spelling rule and clarifies its intent/scope relative to cspell. |
| scripts/prose_lint.py | Implements the spelling rule and integrates it into defaults and per-file scanning logic. |
| reports/vscode-server-dotnetcore/audit.md | Fixes “behaviour” → “behavior” in prose. |
| host-setup/agent-safety/gh-write-guard.py | Fixes “judgement” → “judgment” in a comment. |
| .github/workflows/validate-task.yml | Updates the prose gate step to include --check spelling as a blocking CI rule. |
The TestSpelling docstring named README and HISTORY as excluded, which the rule does not do: it runs on whatever file it is handed. The two gates overlap on those files rather than dividing the tree, and what this rule adds is coverage of the prose cspell was never pointed at. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ptr727
added a commit
that referenced
this pull request
Jul 31, 2026
…479) Forward promotion of four commits. `main` carries no content beyond the merge-base (`f7c77d8`, #473), so this is a clean forward merge with no conflicts. ## What promotes - **#475 - Gate US English spelling where cspell does not reach.** The cspell gate reads README and HISTORY only, so a British spelling anywhere else in the tree had nothing checking it. The `spelling` rule generates its banned words from stems rather than listing them one by one, since an inflected spelling is as wrong as its base and a hand-listed family drifts. - **#476 - Sweep the spaced-hyphen prose class out of the carried docs.** All seven carried documents to zero: `GOVERNANCE.md` 219, `CODESTYLE.md` 53, `WORKFLOW.md` 51, `.github/copilot-instructions.md` 40, `AUDIT.md` 29, `repo-config/README.md` 20, `AGENTS.md` 3. The remaining ~538 are hub-only (`reports/`, `docs/`, `spec/*.md`, `STANDUP.md`, `catalog/`), stay warn-only, and are corrected as each file is next edited, which works because nothing vendors them. - **#477 - Report the suppressed findings the thread poll cannot see.** The merge gate counts a review body's collapsed low-confidence block as an outstanding finding, but the digest read `reviewThreads` alone, where that block never appears, so the one command written to answer "is this PR clean" reported clean while findings stood. - **#478 - Sweep the semicolon prose class out of the carried docs.** The exemption is fixed first (list-wide comma, per-table-cell scoping, bullet-label colon), then 44 genuine clause joins recast across five files. All six remaining carried files reach zero, the bar `GOVERNANCE.md` already met. ## Verification on the merged `develop` Both prose classes report zero across all seven carried documents. The full 180-case script suite, `scripts/repo_gate.py`, `spec/validate.py`, and `spec/audit.py --selftest` pass. The blocking prose run (charset, dupword, spelling) is clean tree-wide, markdownlint reports 0 issues over 39 files, and editorconfig-checker is clean. cspell's gated scope (README + HISTORY) is clean; the tree-wide backlog is unchanged. ## Release A human merge never auto-publishes, so this fires no release, as designed. The latest release stays `2.0.108`. ## Re-vendor debt This promotion changes prose in all seven carried documents, so every downstream repo goes further out of date against canonical. That debt is pre-existing and still untracked - no issue covers it and filing one has not been authorized. `spec/audit.py --branch <ref>` checks a repo's convergence before it promotes. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
GOVERNANCE.mdrequires US English repo-wide, but nothing enforced it outsideREADME.mdandHISTORY.md. The cspell gate is scoped to those two files deliberately (gating every markdown file would mean endlessly paddingcspell.jsonwith technical terms, and the editor extension covers the rest live), so a British spelling anywhere else in the tree reachedmainunchallenged. Three had:spec/validate.py:335-labelledreports/vscode-server-dotnetcore/audit.md:88-behaviourhost-setup/agent-safety/gh-write-guard.py:60-judgementAll three are fixed here, so the new rule joins the blocking CI prose run rather than the warn-only one.
What
A
spellingrule inprose_lint.py, on by default and gating in CI alongsidecharsetanddupword.The word list generates from stems rather than listing each form, since an inflected spelling is as wrong as its base and a hand-listed family drifts the moment one form is added without the others. Three families (
-ise/-ize,-our/-or,-re/-er) plus a literal table for the spellings that follow no family.Two words are deliberately absent.
analysesis the US plural ofanalysisas much as it is a British verb form, soanalyseis carried only asanalyse/analysed/analysing.cancelledis a GitHub Actions job status, quoted rather than written.Outside markdown the rule reads the comments, not the source lines, reusing the extraction
comment-wrapalready does. An identifier, a string literal, or a lookup table is code; judging it as prose made the first draft report this script's own table of banned words. Confirmed by a case.Also leads
YAML['quote_after']with the dash ('-:,[{'). Membership is a set test so the order carries no behavior, but':-,'reads as a regex range and cost a review round on #474 when it was read as missing the dash.Verification
scripts/test_prose_lint.py- 126 cases, 8 new. The table-driven case asserts every entry in the liveBRITISHtable is caught and its US form is not, so a word added later arrives already proven. One case asserts the whole repo is clean, so the gate cannot pass by having nothing to read.test_repo_gate.py,test_pr_review.py,spec/audit.py --selftest,spec/validate.py,scripts/repo_gate.py- all green.markdownlint-cli2(39 files, 0 issues) andeditorconfig-checkerclean via the canonical Docker invocations.git diff --numstatshows line-level changes only, so no file had its endings flipped.Left undone, deliberately
host-setup/agent-safety/gh-write-guard.pycarries a 42-findingcomment-wrap/comment-casebacklog and 250-character lines, a whole-file convention mismatch this one-word spelling fix neither introduced nor worsened. Reflowing that file belongs in its own change, not buried in a spelling gate.🤖 Generated with Claude Code