Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 19 additions & 80 deletions .vale.ini
Original file line number Diff line number Diff line change
@@ -1,90 +1,29 @@
# Vale configuration for Coder documentation.
#
# Curated cherry-pick of Google's developer-docs style, write-good (wordiness),
# and a hand-picked subset of alex (inclusive-language). The choice of base
# styles and disabled rules is documented in DOCS-40 and reproducible via
# `make lint/prose`.
# Rule rollout doctrine. Every rule listed below ships clean: zero
# baseline findings across `docs/` at enable time. Severity is a
# deliberate per-rule choice:
#
# Severity policy. Rules sit at a level that reflects two things
# together: false-positive rate against real Coder docs and the gravity of
# the rule. Low FPs plus high gravity argues for `error`; lower gravity or
# more judgment calls argue for `warning` or `suggestion`. v1 lands most
# rules at `warning` and the wordiness rules at `suggestion`. Promote a
# rule to `error` only when (a) its false-positive rate against real
# content is effectively zero and (b) the existing-content violation count
# for that rule is also zero.
# - `error` hard policy; CI blocks merge on violations.
# - `warning` strong guidance; surfaces annotations without
# failing CI.
# - `suggestion` soft guidance; surfaces `notice` annotations.
#
# About Vale's exit code: Vale exits non-zero only when error-level alerts
# are found, regardless of `MinAlertLevel`. The Makefile invokes Vale with
# `--no-exit` to suppress that exit while the un-overridden Google
# error-level rules still produce a baseline error count. Real failures
# (bad config, missing files) still propagate. See
# DOCS-40 for the rollout plan.
# To add a rule, follow the per-rule PR template in
# docs/.style/README.md ("Adding a Vale rule"). Third-party rules
# from Google, alex, and write-good are not enabled by default; each
# returns via the same per-rule PR pattern after its corpus is clean.
#
# The styles themselves live under docs/.style/styles/ after `vale sync`,
# which the Makefile target invokes once per .vale.ini change. They are
# gitignored to keep the repo lean.
# About Vale's exit code: Vale exits non-zero only when error-level
# alerts are found. Warning and suggestion annotate without
# affecting exit. Real runtime failures (bad config, missing files)
# propagate regardless of severity.
#
# The Coder rule package lives under docs/.style/styles/Coder/ and is
# the single source loaded by default.

StylesPath = docs/.style/styles
MinAlertLevel = suggestion

# Packages drives `vale sync`. Pin upstream tags here when reproducibility
# matters more than getting upstream fixes; the unpinned form pulls the
# latest release of each package on `vale sync`.
Packages = Google, alex, write-good

[*.md]
BasedOnStyles = Google, write-good, Coder

# --- Google curation -------------------------------------------------------
# Google.EmDash conflicts with our em-dash ban (see scripts/check_emdash.sh
# and DOCS-44). The repo-level ban covers Unicode U+2014/U+2013 plus the
# ` -- ` ASCII fallback; Google.EmDash would double-flag and use prose
# different from our policy.
Google.EmDash = NO

# Google.Latin flags i.e. and e.g. for non-native readers. Coder docs assume
# a technical audience that reads these fluently; leaving the rule on
# produces noise without value.
Google.Latin = NO

# Soften two high-volume Google rules. The signal-to-noise ratio is low
# at the default warning level.
Google.Parens = suggestion
Google.WordList = warning

# Google.Spacing flags fully-qualified Go type names like
# `codersdk.WorkspaceAgent` as "should have one space." It produces ~4,500
# errors against `docs/reference/api/schemas.md` alone (measured
# 2026-05-18) because codersdk type names match the pattern. The
# architectural decision for generated content is to fix the upstream
# Go generators (clidocgen, apidocgen, auditdocgen, metricsdocgen)
# rather than add Vale path exclusions; this disable buys time until
# those generator changes land. Re-enable then, ideally promoted to
# `error`.
Google.Spacing = NO

# --- write-good curation ---------------------------------------------------
# Passive voice is contextually correct often enough that flagging every
# instance teaches nothing. E-Prime forbids forms of "to be" entirely,
# which is incompatible with normal technical writing.
write-good.Passive = NO
write-good.E-Prime = NO

# Keep the three rules that catch real wordiness problems. Wordiness and
# ThereIs are judgment calls (suggestion); Weasel is sharper (warning).
write-good.TooWordy = suggestion
write-good.Weasel = warning
write-good.ThereIs = suggestion

# --- alex curation ---------------------------------------------------------
# alex is loaded a la carte rather than via BasedOnStyles. ProfanityMaybe
# and ProfanityUnlikely fire on technical terms like `execute`, `kill`,
# `failed`, and `attack`; ProfanityLikely is much more conservative and
# safe to keep on.
alex.Ablist = warning
alex.Condescending = warning
alex.LGBTQ = warning
alex.ProfanityLikely = warning
alex.Race = warning
alex.Suicide = warning
BasedOnStyles = Coder
56 changes: 56 additions & 0 deletions docs/.style/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Loading