mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: strip third-party rules; enable per-rule only (#26586)
Closes DOCS-425. ## Summary Collapse `.vale.ini` to load only the Coder rule package. Drop `Packages = Google, alex, write-good`. Replace `BasedOnStyles = Google, write-good, Coder` with `BasedOnStyles = Coder`. Drop every `Google.X`, `write-good.X`, and `alex.X` per-rule line. Add a rule-rollout doctrine under `docs/.style/README.md`. ## Why The previous config carried roughly 12,000 baseline findings across `docs/`: 412 errors / 5380 warnings / 6247 suggestions, almost entirely from third-party rules whose false-positive patterns Vale cannot distinguish from author intent. - `Google.Headings` false-positives on every acronym and product name: VM, AWS, GCP, Coder, Vale, JetBrains, VS Code. - `Google.Will` fires on legitimate event-sequencing prose. - `Google.Acronyms` fires on widely-known terms the audience reads fluently (AWS, RDP, VPC). - `alex.*` rules shipped in DOCS-40 without a corpus cleanup commit. When CI surfaces false positives, engineers stop reading annotations. PR #25501 review surfaced this concretely on `Google.Headings`. The fix is a tight, trustworthy ruleset rather than tuning around individual false positives. ## Doctrine Full text in `docs/.style/README.md`. Summary: | Element | Value | | --- | --- | | PR title | `feat(docs/.style): enable <RuleName>` | | Commits | (1) corpus-wide cleanup, (2) rule enable + `style-guide.md` section + custom YAML if applicable | | Acceptance | zero baseline findings at merge, at the rule's chosen severity | | Severity | deliberate per-rule choice: `error` blocks merge; `warning` and `suggestion` annotate without failing CI | | False-positive policy | one confirmed FP after enable, refine or revert; applies regardless of severity | Applies equally to Coder-authored rules and third-party rules. Third-party rules return through the same per-rule pattern after their corpus is clean. ### Severity ladder The three-severity ladder is deliberate. Some rules catch hard policy where any violation is wrong (brand names, banned first-person pronouns, em-dashes); those ship at `error` and block merge. Other rules catch strong guidance with legitimate human-judgment exceptions (`disabled` as a technical state vs. ableist usage); those ship at `warning` and annotate without failing CI. Soft guidance (noun-as-adjective patterns like `desired state`, wordiness) ships at `suggestion` as a `notice` annotation. The cleanup discipline applies at every severity. A rule landing at `warning` or `suggestion` still ships with zero baseline findings; the rule's purpose is to catch new violations, not to surface a backlog of existing ones. Standing backlogs train contributors to ignore the annotation channel. The `error`-blocks-merge half of this contract lands operationally via PR [#26587](https://github.com/coder/coder/pull/26587) (DOCS-426), which removes `continue-on-error: true` and `vale --no-exit` from the CI step. ## Effect on the corpus baseline | Metric | Before | After | | --- | --- | --- | | Errors | 412 | 0 | | Warnings | 5380 | 0 | | Suggestions | 6247 | 0 | | Files | 465 | 465 | Verified locally with `mise exec aqua:errata-ai/vale -- vale --no-exit docs/`. ## Functional state after merge The CI `Vale prose lint` step stays advisory (`continue-on-error: true`, `--no-exit`) until PR #26587 lands. With no rules loaded except Coder's package (currently empty on `main`), the step is effectively a no-op until `Coder.BrandNames` lands via PR #25501 (DOCS-34). At that point the lint step becomes a `Coder.BrandNames`-only check. Subsequent per-rule PRs extend coverage one rule at a time per the doctrine, each rule choosing the severity that matches its policy strictness. The Makefile target `docs/.style/.vale-synced: .vale.ini` still runs `vale sync`, which is now a no-op because `Packages` is empty. The previously-synced `docs/.style/styles/{Google,alex,write-good}/` directories remain on developers' disks (they're gitignored) but are no longer loaded by Vale. ## Sequencing 1. **This PR merges first** 2. PR #26587 (DOCS-426) installs the CI merge gate and the severity-rendering fix 3. PR #25501 (DOCS-34) rebases onto main, drops its now-redundant `Google.Parens = NO` change, lands `Coder.BrandNames` as the first concrete rule 4. DOCS-424 (Vale rule audit) is complete; per-rule re-enablement work begins per the doctrine <details> <summary>Decision log</summary> - **Strip everything vs. partial disable**: chose full strip because each third-party rule loaded by default is a tacit endorsement. The doctrine requires every enabled rule to be deliberate. A partial disable still loads styles whose other rules haven't been audited. - **`alex.*` rules**: yanked in this PR. They were enabled in DOCS-40 without a corpus cleanup commit. The "audit then keep" call returns them via dedicated per-rule PRs once the audit confirms baseline violation counts and the doctrine accepts them. - **`Packages` directive dropped**: with no third-party rules loaded, `vale sync` had no work to do. Removing the directive avoids implying we intend to re-add packages without a per-rule PR. The directive returns when a future PR opts in a Google or write-good rule. - **Doctrine location**: under `docs/.style/README.md` rather than a dedicated `docs/.style/RULE_ROLLOUT.md`. Keeps the contributor-facing entry point single, and the section sits alongside the existing "Editing the style guide" and "Editing the content guidelines" sections. - **Three-severity ladder vs. error-only**: chose deliberate per-rule severity because the rule catalogue contains rules at different policy strictness. Forcing every rule to `error` would either reject useful warning- and suggestion-level rules (noun-as-adjective patterns, wordiness guidance) or push them onto an inappropriate gate. The CI severity rendering and merge-gate work in PR #26587 was built specifically to support this ladder. </details> --- *Filed via [Coder Agents](https://coder.com/docs/ai-coder/agents) on Nick's behalf.*
This commit is contained in:
@@ -82,3 +82,59 @@ with another style or contributing doc in the repo, it governs.
|
||||
|
||||
Open a PR against `docs/.style/style-guide.md`. Follow-up PRs add each
|
||||
rule and the matching style-guide section together.
|
||||
|
||||
## Adding a Vale rule
|
||||
|
||||
Each rule in the repo-root `.vale.ini` ships clean: zero baseline
|
||||
findings against the current `docs/` corpus.
|
||||
The PR that adds a rule is the rule's complete unit:
|
||||
|
||||
1. **Cleanup commit**: fix every existing-content violation of the new
|
||||
rule so `make lint/prose` reports zero findings for it.
|
||||
The cleanup ships in the same PR as the enable, ordered first.
|
||||
2. **Enable commit**: add the rule to `.vale.ini` at its chosen
|
||||
severity, write a corresponding section under
|
||||
`docs/.style/style-guide.md`, and add the custom rule YAML under
|
||||
`docs/.style/styles/Coder/` if applicable.
|
||||
The rule's `message:` field points at the relevant `style-guide.md`
|
||||
anchor.
|
||||
|
||||
Severity is a deliberate per-rule choice:
|
||||
|
||||
- `error` blocks merge. Use for hard policy where any violation is
|
||||
wrong: brand-name casing, first-person pronouns we ban outright,
|
||||
em-dash bans.
|
||||
- `warning` surfaces an annotation without failing CI. Use for strong
|
||||
guidance with legitimate human-judgment exceptions: terms that need
|
||||
context (`disabled` as a technical state vs. ableist usage),
|
||||
judgment-bound style preferences.
|
||||
- `suggestion` surfaces a `notice` annotation. Use for soft guidance
|
||||
where the right fix is contextual: noun-as-adjective patterns like
|
||||
`desired state`, wordiness, optional sentence reshaping.
|
||||
|
||||
The severity choice and the cleanup discipline are independent. A
|
||||
rule landing at `warning` or `suggestion` still ships with zero
|
||||
baseline findings; the rule's purpose is to catch new violations, not
|
||||
to surface a backlog of existing ones. A rule that surfaces a standing
|
||||
backlog teaches contributors to ignore the annotation channel, which
|
||||
erodes trust in CI regardless of the severity at which the noise
|
||||
arrives.
|
||||
|
||||
PR title: `feat(docs/.style): enable <RuleName>`.
|
||||
|
||||
False-positive policy: one confirmed false positive after enable,
|
||||
either refine the rule or revert.
|
||||
We do not maintain rules that occasionally cry wolf, regardless of
|
||||
severity.
|
||||
|
||||
If a policy is judgment-bound (passive voice, weasel words,
|
||||
sentence-case headings on a corpus with many proper nouns), write a
|
||||
Coder-authored rule with the precision the situation needs instead of
|
||||
accepting an imprecise third-party rule at any severity.
|
||||
|
||||
This applies equally to Coder-authored rules (under
|
||||
`docs/.style/styles/Coder/`) and third-party rules from Google, alex,
|
||||
and write-good.
|
||||
Third-party rules are not loaded by default.
|
||||
Each returns through the same per-rule PR pattern after its corpus is
|
||||
clean.
|
||||
|
||||
Reference in New Issue
Block a user