Clear the snippet prose backlog, exemptions first - #600
Merged
Conversation
`catalog/snippets/` seeds its content into every repo that adopts it, so a non-conformant snippet is handed downstream and the downstream repo is then flagged for prose it never wrote. This clears the snippets to zero findings, taking the tree from 557 across 45 files to 373 across 26. The checker was fixed before the corpus, because the exemptions carry the whole burden of encoding legitimate uses and a stale one hands out a work list that damages correct files. Three findings were exemption misses: - A comment body that is one token closing on a colon is a key or a heading. `# ignore:` heading a commented-out codecov block is disabled configuration, so the capitalization `comment-case` asked for would corrupt the key a repo uncomments. The shape matches exactly two bodies tree-wide; the broader reading of a body with no whitespace covers 99 and sweeps in every reference URI and version marker. - A label opening a definition names the thing being defined, so `# publish - 'true' when ...` documents an output rather than opening a sentence in lowercase. Scoped to a line that opens a definition and never to one continuing a wrapped sentence, because a continuation whose first word takes a spaced dash is a parenthetical, which is what the dash rule exists to catch. Both live instances in the tree are continuations, so the corpus chose the unit: the first design read any comment body and exempted both. - A definition list keyed on a code span (`` - `latest` - text ``) needed no checker change at all. `LABEL_DASH` already exempts `- **`latest`** - text`, the form `GOVERNANCE.md` and `docs/devcontainer.md` use, so the fix is to bold the label. Following the finding's own message and removing the dash would have destroyed the list. Old and new verdicts were diffed in both directions over the whole tree before any prose was touched: exactly those three went silent and nothing was newly reported. Five tests lock the two new arms, including the continuation case that rejected the first design. The detection the label exemption costs is stated in `scripts/README.md` rather than left to be found. `comment-case` still reports a comment opening on a lowercase identifier, which the rule intends restructured, not exempted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request reduces (and in catalog/snippets/**, eliminates) prose_lint findings by (1) tightening/adding two targeted comment-case/comment-wrap exemptions that protect commented-out configuration keys and definition-label comments, (2) adding regression tests documenting the intended boundary behavior, and (3) rewriting snippet comment prose to conform to the gate without changing the underlying workflow semantics.
Changes:
- Extend
scripts/prose_lint.pyto exempt (a) one-tokenKEY:comment bodies and (b) definition-label comment lines fromcomment-case, while preservingcomment-wrapbehavior for wrapped continuations. - Add regression tests for the two new exemption arms plus the key boundary cases (colon-ending prose, continuation-dash wrap, and run-on visibility).
- Rewrite snippet YAML/Markdown/shell comments and snippet docs to satisfy the prose rules, and update
TODO.mdto reflect the post-snippets backlog state.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| TODO.md | Updates the #519 backlog narrative and measured counts now that catalog/snippets/ is clean; adds a missing reference link. |
| scripts/test_prose_lint.py | Adds tests locking the new comment-case exemptions and ensuring they do not hide real prose or continuation wraps. |
| scripts/README.md | Documents the two new exemption rationales and their explicit detection tradeoff. |
| scripts/prose_lint.py | Implements KEY_ONLY and COMMENT_LABEL exemptions in comment_wrap_findings to avoid corrupting commented configuration keys and definition labels. |
| catalog/snippets/workflows/run-periodic-codegen-pull-request.yml | Rewraps concurrency comments into one-sentence-per-line form without changing behavior. |
| catalog/snippets/workflows/README.md | Adjusts prose to avoid dash-rule constructions and clarify guarantee references. |
| catalog/snippets/workflows/publish-plan-task.yml | Restructures comment prose (including the publish/stable definition labels) to comply with comment-case/wrap rules. |
| catalog/snippets/workflows/publish-docker-readme-task.yml | Rewrites long comments into compliant single-sentence lines while preserving meaning. |
| catalog/snippets/workflows/get-version-task.yml | Rewraps explanatory comments for the same prose-lint compliance goal. |
| catalog/snippets/workflows/check-upstream-version-task.yml | Rewraps and clarifies comments; keeps contract details intact. |
| catalog/snippets/workflows/build-release-task.yml | Rewraps and clarifies multi-line explanatory comments; no logic changes. |
| catalog/snippets/workflows/build-pypilibrary-task.yml | Rewraps comments and clarifies smoke/publish behavior without changing steps. |
| catalog/snippets/workflows/build-nugetlibrary-task.yml | Rewraps comments to satisfy prose rules; no workflow logic changes. |
| catalog/snippets/workflows/build-executable-task.yml | Rewraps comments for smoke mode and artifact behavior; no semantic change. |
| catalog/snippets/workflows/build-docker-task.yml | Rewraps comments around smoke/QEMU/login/cache behavior; no semantic change. |
| catalog/snippets/workflows/build-datebadge-task.yml | Rewraps the header comment into compliant prose. |
| catalog/snippets/vscode/README.md | Converts definition-list labels to the bold-label form already exempted by the dash rule. |
| catalog/snippets/husky/README.md | Rewrites prose to avoid dash-rule triggers and sentence-wrap findings. |
| catalog/snippets/husky/pre-commit | Splits multi-sentence comments into compliant per-line sentences. |
| catalog/snippets/devcontainer/python/post-create.sh | Rewraps explanatory comments into one sentence per line while keeping intent unchanged. |
| catalog/snippets/configs/docker-hub-readme.md | Changes definition-list labels to the bold-label form to satisfy the dash rule while preserving code spans. |
| catalog/snippets/configs/dependabot.yml | Rewraps explanatory comments to avoid wrap/case findings. |
| catalog/snippets/configs/codecov.yml | Rewrites comments to avoid dash-rule and wrap/case findings while preserving meaning. |
ptr727
added a commit
that referenced
this pull request
Aug 7, 2026
) Takes the next batch of the `The Prose Content Backlog` cluster from [`TODO.md`](./TODO.md), following [#600](#600) (snippets) and [#604](#604) (comments). Part of [#519](#519). ## The anchor was re-verified first `develop` at `c9c92dd`, where `python3 scripts/prose_lint.py --summary` reports **131 violations across 15 files**. That is the figure the comment batch left, and merging that batch made it the anchor's own rather than a branch's, exactly as the cluster entry predicted. ## Scope, and a correction to it The batch is the **hub-only Markdown files**: `docs/`, `spec/*.md` and `catalog/README.md`. That is **90 findings across 9 files** (79 `dash`, 11 `semicolon`), not the ~104 the batch was scoped at. The carried six hold 41, and 90 + 41 = 131. The 6 carried files are left for a later batch, since they rewrite byte-locked sections and owe a fleet re-vendor while these owe nothing. Every `dash` finding in the tree turned out to be hub-only, so what the carried half now holds is **41 semicolons and no dash at all**. | File | Findings | | --- | ---: | | `docs/devcontainer.md` | 22 | | `docs/ssh-signing.md` | 17 | | `spec/type-model.md` | 17 | | `spec/fidelity-model.md` | 8 | | `docs/repo-config-carry.md` | 7 | | `spec/scope-model.md` | 7 | | `catalog/README.md` | 6 | | `docs/token-cost.md` | 5 | | `spec/readme-structure.md` | 1 | ## The exemption came first, and this time it was right `LABEL_DASH` exempts `- **Label** - text` as a definition separator that is structurally a colon. It reaches neither a code-span label nor a paragraph-leading one, and both shapes flagged here. Widening it was the obvious move, and the corpus rejected it twice. **A code-span definition list** is already spelled with a colon in five files, against four dash-spelled lines in one (`catalog/README.md`): ```text STANDUP.md:91 - `ARCHITECTURE.md`: how a code repo is built spec/section-model.md:68 - `ARCHITECTURE.md`: how a code repo is built scripts/README.md:81 - `sha-pin`: every workflow `uses:` naming repo-config/README.md:6 - `operational/develop.json`: the `develop` CODESTYLE.md:79 - `.NET Build`: Build with diagnostic ``` **A paragraph-leading label** is already spelled `**Label.** Sentence`, against nine dash-spelled lines confined to two troubleshooting sections. So both were a file that had not adopted the tree's own convention rather than a construct the rule fails to describe. **The checker is unchanged by this batch.** That is the same verdict the comment batch reached on a comment opening on a lowercase identifier. A bulleted list terminating its items with semicolons appeared in exactly one place tree-wide, `spec/type-model.md:24-25`, and its own last item already ended in a period. It was punctuation to make consistent rather than the list construction the semicolon exemption protects, which a line-based checker could not see across bullets in any case. ## One adjacent fix, flagged because it widens scope Rewriting `docs/devcontainer.md` and `docs/ssh-signing.md` with a script rather than an editor took both from CRLF to LF wholesale. Every prose and Markdown gate stayed green, and `editorconfig-checker` was the only one that reported it. `OPERATIONS.md` scoped that instruction to a *new* file, so it is widened here to a scripted rewrite of an existing one. Hub-only, `presence` fidelity, no re-vendor owed. Happy to split it out if it does not belong in this batch. ## Verification Run from the repository root: ```text prose_lint.py gating list exit 0 prose_lint.py backlog list 131/15 -> 41/6, the carried six exactly test_prose_lint.py 198 tests OK test_repo_gate.py, test_pr_review.py OK audit.py --selftest, gh-write-guard SELFTEST PASS repo_gate.py, validate.py, jq clean markdownlint-cli2 (44 files) 0 issues editorconfig-checker 0 errors ``` Every prose file changed line for line, with no line-count change in any of the 9, and the full word-diff was read for meaning drift. `TODO.md` carries the updated `Checked` anchor and four new `Settled` lines: the batch figures, the two rejected exemptions, the one-off bullet list, and the CRLF gap. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ptr727
added a commit
that referenced
this pull request
Aug 8, 2026
…606) Takes the last batch of the `The Prose Content Backlog` cluster from [`TODO.md`](./TODO.md), following [#600](#600) (snippets), [#604](#604) (comments) and [#605](#605) (hub-only Markdown). Closes [#519](#519) on the prose, subject to the sweep below. ## The anchor was re-verified first `develop` at `d791930`, where `python3 scripts/prose_lint.py --summary` reports **41 violations across 6 files**, all `semicolon`. That is the figure #605 predicted, and merging it made the figure develop's own rather than a branch's. | File | Findings | Fidelity | | --- | ---: | --- | | `GOVERNANCE.md` | 14 | `intent`, 5 sections `verbatim` | | `WORKFLOW.md` | 14 | `intent`, whole | | `CODESTYLE.md` | 6 | `intent`, whole | | `.github/copilot-instructions.md` | 4 | `intent`, whole | | `repo-config/README.md` | 2 | `intent`, whole | | `HISTORY.md` | 1 | `presence` | **The tree is now at 0 across 0**, from 557 across 45 when the backlog opened. ## The exemption came first, and left the checker alone again Two candidates, both rejected by the corpus. That is the third batch running where the pass ends in "do not touch the checker". **The `*Prevents: a; b.*` tail.** Flagged on 4 lines because the list exemption requires the items to carry commas. The tree already spells the same construct with a comma on **5** lines against **6** semicolon-spelled, so it is a convention half-adopted rather than a construct the rule fails to describe. Two of the six (`D1.6`, `D5.6`) keep their semicolons untouched, because their items *do* carry commas — the rule working, not an exception to it. **A two-example parenthetical**, `(A does X; B does Y)`. The tree already spells this with a comma where the items carry none, `GOVERNANCE.md` "No-op republish guarantee" being the case in point. ## Only 14 of the 41 are actually byte-locked The cluster entry said the carried half "rewrites byte-locked sections". That is true of `GOVERNANCE.md` and of nothing else, which changes what the sweep owes: - **`verbatim`, hash-detected.** All 14 `GOVERNANCE.md` findings sit in five `verbatim` sections: Branching Model, Release Model, Documentation Style Conventions, PR Review Etiquette, Workflow YAML Conventions. Every downstream copy is now byte-mismatched and `spec/audit.py` classifies it **stale** (matches a past hub revision), which is the correct disposition and reaches the fleet without anyone filing anything. - **`intent`, detected by nothing.** `WORKFLOW.md`, `CODESTYLE.md`, `.github/copilot-instructions.md` and `repo-config/README.md` are judged by meaning, so a punctuation-only edit produces no hash and therefore no audit finding at all. These are the half that would be silently missed, which is why they are written down rather than left to the run. - **`presence`.** `HISTORY.md` is each repo's own changelog. Its one fix owes nothing downstream. No rule changed meaning anywhere, so the re-vendor is a **hash refresh rather than a propagation**. A repo still holding the old copy is correct on the rule and wrong on the bytes. The Fleet Sweeps entry "Re-vendor the changed `verbatim` content" grows from **five files to seven** and carries both halves as `Detail` lines. It does not trigger a dedicated sweep — Blog remains the pilot. ## What #519 got wrong, and why it is worth recording The issue states that the governance files were clean and that this was "not a carry problem". That was true of the checker of the day and false of the tree: | Content | Checker | Result | | --- | --- | ---: | | the six files at `69688ec` | that commit's own `prose_lint.py` | **0** | | the six files at `69688ec` | today's `prose_lint.py` | **38** | `semicolon` was in `DEFAULT_RULES` the whole time. What changed is the **unit** the list exemption is judged over: scoping it to a sentence rather than a whole bullet accounts for **37 of the 38**, because a colon anywhere ahead of the first semicolon had been exempting every semicolon after it, however plainly one joined two clauses. So the carry problem was real from the start and invisible — the stale-exemption hazard running in the loose direction, on the most-carried files in the fleet. ## One fix beyond the 41 `GOVERNANCE.md` "Orchestration vs. build" carried a splice the exemption excused only because the **bold label** on that sentence happened to contain a comma (`...globs it; do not switch a single-target repo...`). Same line as a flagged finding, so it is fixed inline rather than stepped around. That is 42 semicolons removed, not 41. ## Verification Run from the repository root: ```text prose_lint.py --summary 41/6 -> 0/0 scripts/ unittest (375 tests) OK spec/audit.py --selftest SELFTEST PASS spec/validate.py 22 cataloged, 0 backlog scripts/repo_gate.py eol 0, sha-pin 0 markdownlint-cli2 (44 files) 0 issues cspell (README.md, HISTORY.md) 0 issues editorconfig-checker 0 on tracked files ``` Every edit is a **within-line** replacement, so all seven CRLF files stayed CRLF — verified by an `\n` versus `\r\n` count per file, not by `file`. The full word-diff was read for meaning drift; the change is 31 lines, 31 insertions and 31 deletions. `editorconfig-checker` reports 221 errors, every one of them under `.artifacts/` or `Tests/obj/` — untracked pre-repurpose build leftovers in the working tree, not tracked files. Pre-existing and untouched here. ## `TODO.md` - The `The Prose Content Backlog` cluster is deleted, per selection rule 9. - [#519](#519) moves to "Verified Complete, Awaiting Close" with both of its questions answered and the checker-versus-tree finding as closing evidence. - The Fleet Sweeps re-vendor entry grows to seven files and gains the two `Detail` lines above. - Four link reference definitions orphaned by the cluster deletion are dropped. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
ptr727
added a commit
that referenced
this pull request
Aug 8, 2026
… that blocks on what it cannot read (#609) Promotes 14 commits from `develop`. Merge with a **merge commit** (`gh pr merge --merge`), never a squash, and **without `--delete-branch`**, since this pull request's head is `develop` itself. Closes #607 through the closing keyword already carried in `530cf71`, which is why it is not repeated here. ## The prose backlog, cleared end to end `#600`, `#604`, `#605`, `#606` took the tree from **557 findings across 45 files to 0 across 0**, in four batches ordered by surface: snippets, comments, hub-only Markdown, then the carried files. Each batch measured the checker's own exemption against the live corpus *before* sweeping, and twice the measured answer was **"do not change the checker"**, which is a result of that pass rather than a skipped one. `#594` added the floor that makes those numbers trustworthy: a diff-scoped run now asserts what it actually scanned, since a check whose scan matches nothing reports zero findings and reads exactly like a pass. One finding from that work is worth carrying up: an exemption that is too **loose** produces silence rather than false positives. #519 recorded the governance files as clean; today's checker reports 38 findings against those same files as they stood at the commit that measured them. ## A review loop that fails closed `#599`, `#601`, `#602`, `#603` and `#608` are one arc on `scripts/pr_review.py`, each removing a shape in which the loop reported a clean pass over a review it had misread: - **`#599`** removed the shape a reply kept failing in, by taking the thread's *words* rather than an id, so there is no argument a hand-typed `PRRT_...` fits in. - **`#602`** made `claims` resolve what a description points at rather than what it looks like. - **`#603`** gave a disproved claim a home the next round reads. - **`#608`** reads the file-coverage line, and then generalizes: every reader keys on a structural marker, so a marker that changes spelling is a section the reader stops finding and reports as absent. The digest now vets headings, `<summary>` texts, metadata labels, coverage wordings and the reviewer login against an inventory measured from **332 review bodies**, and **blocks on anything outside it**, exit `43`, with the remedy stated as filing an issue on the hub. Whether to merge regardless is the maintainer's decision. `GOVERNANCE.md` merge gate went from four preconditions to **five** accordingly. ## Governance and tooling - **`#593`** states which checkout an agent works in and what the hub is, which is the host-wide routing the repositories that most need it cannot carry. - **`#596`** gates the pattern-detectable half of the representative-data rule, honest that no pattern closes the name-shaped case. - **`#598`** declares where a repository states what CI cannot verify. - **`#592`** regrouped `TODO.md` by what ships rather than by what it touches, so a `###` heading is one pull request. - **`#601`** ended a `gh push` argument list at a newline rather than only at `&&`, fixing a write-guard over-block. ## Verification Run on `develop` at `530cf71` immediately before opening this: `test_pr_review.py` (174), `test_prose_lint.py`, `test_repo_gate.py`, `spec/audit.py --selftest`, `gh-write-guard.py --selftest`, `spec/validate.py`, `repo_gate.py`, the prose gate in both CI invocations, markdownlint and editorconfig-checker. All clean. ## Not carried by this promotion - **#519 is complete and still open.** `TODO.md` holds its closing evidence under "Verified Complete, Awaiting Close". Closing it is the maintainer's call, so no keyword for it appears here. - **The re-vendor debt is now nine files.** `#606` queued seven, and `#608` changed `GOVERNANCE.md` "PR Review Etiquette" (`verbatim`) and `.github/copilot-instructions.md` (`intent`) on top. The `intent` half produces no hash and therefore no audit finding, which is why the Fleet Sweeps entry names those files by hand. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This was referenced Aug 8, 2026
ptr727
added a commit
that referenced
this pull request
Aug 8, 2026
Closes the last piece of [#519](#519), which is now closed with its evidence quoted on the issue. ## Why now The prose backlog reached zero at `20916ad`. `semicolon` and `dash` were warn-only because a whole-tree gate on them would have failed every run while several hundred findings sat in the tree. That reason has expired, and a warn-only tier over a clean tree is how the backlog grows back. Measured on this branch before writing the change, and again after: ```text python3 scripts/prose_lint.py . --check charset --check semicolon --check dash --check dupword \ --check spelling --check comment-wrap --check comment-case --check home-path 0 violation(s) across 0 file(s) ``` ## `home-path` gated nothing anywhere, which is the substantive fix `home-path` has been in `DEFAULT_RULES` since it was written, so a bare local run has always included it. It was named by neither CI step, so the rule that catches an absolute home path naming a real account ran on a developer's machine and gated nothing in CI. That is the pattern-detectable sliver of [`GOVERNANCE.md`](https://github.com/ptr727/ProjectTemplate/blob/develop/GOVERNANCE.md) "Representative Data in Agent-Authored Text", the section that exists because real paths carrying real names reached a public comment. [`OPERATIONS.md`](https://github.com/ptr727/ProjectTemplate/blob/develop/OPERATIONS.md) already recorded the hole, correctly and in detail. This closes it and drops the record, rather than leaving a runbook describing a gap that no longer exists. ## What stays warn-only, and why that is not an oversight `charset-unknown` alone. A finding there names a character no tier covers, and classifying one is a fleet-law edit rather than something the change that happened to type it can fix. Blocking on it would make an un-tiered character an unmergeable change instead of a question for the maintainer. The step keeps `continue-on-error: true` and is renamed from "Report prose backlog step" to "Report unclassified characters step", since there is no backlog left for it to report. `sentence-split` remains named by no invocation and stays that way here. It is deliberately outside `DEFAULT_RULES`, so promoting it is a separate decision rather than a consequence of this one, and `OPERATIONS.md` still records it as a gap. ## The composite action is unaffected [`.github/actions/prose-gate`](https://github.com/ptr727/ProjectTemplate/blob/develop/.github/actions/prose-gate/action.yml) runs `python3 "$SCRIPT" --diff "$BASE"` with no `--check` list, so it already gates the full default set, `home-path` included, over the lines a change touches. A downstream caller sees no behavior change from this pull request. Only the hub's own whole-tree steps move. ## Documentation kept level with the change - [`OPERATIONS.md`](https://github.com/ptr727/ProjectTemplate/blob/develop/OPERATIONS.md) carries the two CI invocations verbatim so a local run matches CI rather than exceeding it, so both lines are updated, the three-gap paragraph becomes two, and the sentence describing the second invocation as a backlog report is corrected. - [`scripts/README.md`](https://github.com/ptr727/ProjectTemplate/blob/develop/scripts/README.md) claimed five rules gate and the rest report. It now states the tree is zero and every default rule gates but one. It also names `home-path` for the first time, including the limit that it closes a sliver of its section and nothing more, because the exposure that section exists for was name-shaped and no pattern finds a name. - `TODO.md` loses the #519 entry and its link definition. ## Three corrections the closing comment carries rather than this diff The `TODO.md` entry being removed held three wrong figures, each re-measured before the issue was closed: | Claim in the entry | Measured | | --- | --- | | Fixed by `f7a6a13` (snippets) | Not a valid object in this repository. The snippets batch is `b002fac` (#600). | | 557 across 45 to zero, 184 in snippets | 553 across 44 to zero, batches 181, 241, 90 and 41, with today's checker run at every point | | #573 accounts for 37 of the 38 carried findings | 38 of 38. Pre-#573 checker reports 0 and post-#573 reports 38 over the identical bytes at `69688ec`. | ## Verification | Check | Result | | --- | --- | | New gating invocation, whole tree | 0 violations across 0 files | | `charset-unknown`, whole tree | 0 violations across 0 files | | `python3 scripts/test_prose_lint.py` | 198 tests, OK | | `python3 scripts/repo_gate.py` | `eol` 0, `sha-pin` 0 | | `actionlint` | exit 0 | | `editorconfig-checker` | exit 0 | | `python3 spec/validate.py` | 22 cataloged, 0 backlog repos classify cleanly | The four edited files keep their declared line endings, CRLF for the three Markdown files and LF for the workflow, which `editorconfig-checker` confirms. --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Closes part of #519:
catalog/snippets/is now at zero prose findings. The whole tree goes from 557 across 45 files to 373 across 26.Snippets led because a non-conformant snippet seeds its violations into every repo that adopts it, and the downstream repo is then flagged for content it was handed. That is a seeding-risk ordering rather than a size one: the three biggest files in the tree are not snippets at all.
The exemptions were fixed before the corpus
The findings were read as a hypothesis, not a work list.
prose_lint's comment rules ban a construction rather than a detectable subset of it, so the exemptions carry the whole burden of encoding the legitimate uses, and a stale one hands out a work list that damages correct files. Three of the 184 snippet findings were exemption misses.A comment body that is one token closing on a colon is a key or a heading.
# ignore:heading a commented-out block incodecov.ymlis disabled configuration, so the capitalizationcomment-caseasked for would corrupt the key a repo uncomments. Measured tree-wide, the shape matches exactly two bodies, both a key or a heading. The broader reading of "a body with no whitespace at all" covers 99 and sweeps in every reference URI andv3.2.0marker with them, which is why the narrow shape was taken.A label opening a definition names the thing being defined.
# publish - 'true' when ...documents an output namedpublish, so capitalizing it renames what the workflow declares. This is the comment spelling of the- **Label** - textconstruct the dash rule already exempts.The first design here was wrong, and only the corpus said so. A bare
^word -reading matches six comment bodies, but two of them are wrapped continuations whose dash is parenthetical, which is precisely the construction the dash rule exists to catch. Both continuations follow a line that does not end a sentence, so scoping the exemption to a line that opens a definition excludes them structurally. The corpus chose the unit; a test locks that case.A definition list keyed on a code span needed no checker change at all.
-latest- the current stable release.is flagged becauseLABEL_DASHrequires a**bold**label. Following the finding's own message ("spaced hyphen -> a comma, two sentences, or parentheses") would have destroyed the list.- **latest** - textis already exempt and is the formGOVERNANCE.mdanddocs/devcontainer.mduse, so bolding the label is the fix and the code span survives inside it. 17 such lines exist tree-wide; the 2 in snippets are fixed here.Verdicts diffed in both directions, before any prose was touched
Whole-tree, old against new:
Five tests lock the two new arms, including
test_a_continuation_dash_is_not_read_as_a_label, which is the design that was rejected. Verified against the pre-change checker in an isolated copy: the new tests fail there and pass here.Cost, stated rather than left to be found
The label exemption costs a detection: a comment that genuinely opens a sentence on one word followed by a spaced dash is no longer read as a lowercase opening.
scripts/README.mdrecords this alongside both new exemptions.comment-casestill reports a comment opening on a lowercase identifier (# isinstance guard first: ...,# consumerModel has no defaults fallback ...). That is 23 of the remaining findings and the rule intends them restructured rather than exempted, so nothing here widens to cover them.Two open questions on #519, answered
Neither answer was recorded on the issue, and both are now in
TODO.md:reports/**exempt? Yes, as a generated tree.The issue's own headline numbers (668 total, 119 hand-authored at
69688ec) are stale, computed beforecomment-wrap/comment-casejoinedDEFAULT_RULESand beforereports/became exempt.Verification
Every gate in
OPERATIONS.md"Run the gates the way CI runs them", from this checkout:test_prose_lint.py195 tests OK,test_repo_gate.py23 OK,test_pr_review.py103 OKspec/audit.py --selftestSELFTEST PASS,spec/validate.pyOK,repo_gate.py0 issuescharset/dupword/spelling) exits 0editorconfig-checkerclean,jq emptyclean over every JSON glob--diff origin/developexits 0, so nothing this branch touches carries a findingLine endings were checked explicitly rather than assumed: no file changed EOL style and none has mixed endings. The
git diff --checktrailing-whitespace warnings are pre-existing CR in CRLF files, whichtext: unsetleaves alone.🤖 Generated with Claude Code