feat(docs/.style): enable Coder.GerundHeading (#25502)

## Summary

Adds `Coder.GerundHeading`, a `warning`-level Vale rule that flags
headings and titles whose first word ends in `-ing` (a gerund or present
participle used as a verb form, like `Installing` or `Configuring`).

Task headings read better in the imperative (`Install Coder`); concept
headings read better as nouns (`Installation`). The choice is
context-dependent, so the rule is a `warning`: it annotates without
blocking CI.

The style-guide section this rule enforces already lives on `main` at
[`capitalization-and-punctuation.md#no-gerund-leading-headings`](https://github.com/coder/coder/blob/main/docs/.style/style-guide/capitalization-and-punctuation.md#no-gerund-leading-headings).
This PR adds the matching rule and nothing else: the net diff is a
single file.

## What's in this PR

- `docs/.style/styles/Coder/GerundHeading.yml` (new). Heading-scoped
`existence` rule, anchored regex `^[A-Z][a-z]+ing\b`, `level: warning`.
- `exceptions:` mirror the style guide's **Exceptions** section: `-ing`
words that name a feature, category, or attribute (`Logging`,
`Monitoring`, `Networking`, `Tracing`, `Troubleshooting`, `Pricing`,
`Billing`, ...) plus words that only look like gerunds (`Bring`,
`String`, ...).

This branch was rebuilt onto `main`'s restructured `docs/.style/` (the
single `style-guide.md` became a `style-guide/` directory and Vale moved
into `ci.yaml`), which is why the diff is now just the rule.

## Scope: rule only

The rule ships as a `warning`, so it surfaces the existing `-ing` task
headings (~200) as advisory annotations rather than failing CI.
De-gerunding those headings (imperative rewrites plus internal anchor
fixes) is a corpus-wide content change and lands in a dedicated
follow-up PR, tracked separately. Splitting keeps this PR to the rule
and keeps the content churn reviewable on its own.

<details>
<summary>Decision log</summary>

**`existence` + `scope: heading`, not `sequence` + `tag: VBG`.** Vale's
POS-tagging sequence rules are hardcoded to sentence scope and never
reach heading text, so a `VBG` sequence rule fires on paragraphs and
stays silent on H1-H6. Google's and Microsoft's heading rules all use
the existence+regex pattern; this rule follows it.

**Exceptions align to the committed style guide, not the original branch
design.** The first draft of this rule intentionally left concept-noun
gerunds (`Logging`, `Monitoring`, ...) in the flagged set. Since then,
`main`'s style guide declared exactly those as non-violations. The rule
now excepts them so the rule and the guide agree. An excepted first word
is allowed everywhere, which is a deliberate precision trade-off for a
first-word regex: `Monitoring Coder` (a task) is not flagged, but the
standalone concept heading `Monitoring` stays clean.

**Severity = warning.** The imperative-vs-noun choice is judgment-bound,
which is the case the `warning` tier exists for: strong guidance,
legitimate human-judgment exceptions, no CI block.

**Verification.** `make lint/prose` loads the rule cleanly; the excepted
words (`Troubleshooting`, `Monitoring`, `Networking`, `Logging`,
`Contributing`, `Styling`, `Scaling`, `Routing`, `Pricing`, `Billing`,
`Tracing`) each produce zero findings.

</details>

---

*Opened via Coder Agents on @nickvigilante's behalf.*
This commit is contained in:
Nick Vigilante
2026-07-23 20:38:42 +00:00
committed by GitHub
parent 8654b1cec3
commit 66a55e1ebd
@@ -0,0 +1,67 @@
# Coder.GerundHeading - flag titles and headings whose first word ends in
# -ing (a gerund or present participle used as a verb form, e.g.,
# "Installing", "Configuring", "Setting").
#
# Prefer the imperative for task headings ("Install Coder") and the noun for
# concept headings ("Installation"). The full policy, including the exception
# categories mirrored below, lives in the style guide:
# docs/.style/style-guide/capitalization-and-punctuation.md#no-gerund-leading-headings
#
# Implementation: a heading-scoped existence rule with an anchored regex.
# Vale's POS-tagging `sequence` rules are sentence-scoped and never reach
# heading text, so Google's and Microsoft's heading rules use the same
# existence+regex approach. The trade-off is a small exceptions list for
# -ing words that are not verb forms.
#
# The exceptions fall into two groups:
# 1. Words that end in -ing but are not gerunds at all (Bring, String).
# 2. -ing words that name a feature, category, or attribute and read
# correctly as a heading lead (Logging, Monitoring, Networking,
# Troubleshooting). These match the style guide's Exceptions section.
extends: existence
message: "Heading starts with an -ing word ('%s'); prefer the imperative ('Install') or the noun ('Installation'). See capitalization-and-punctuation.md#no-gerund-leading-headings."
link: https://github.com/coder/coder/blob/main/docs/.style/style-guide/capitalization-and-punctuation.md#no-gerund-leading-headings
level: warning
scope: heading
nonword: false
exceptions:
# Not gerunds (verb-base or non-verb nouns).
- Bring
- King
- Ring
- Sing
- Spring
- Sting
- String
- Thing
- Wing
# Feature, category, or attribute nouns that read correctly as a heading
# lead. Mirrors the style guide's "Exceptions" section.
- Autoscaling
- Billing
- Breaking
- Caching
- Contributing
- Formatting
- Guiding
- Heading
- Licensing
- Logging
- Monitoring
- Naming
- Networking
- Ordering
- Pricing
- Provisioning
- Reading
- Rendering
- Routing
- Scaling
- Scheduling
- Styling
- Tracing
- Trailing
- Troubleshooting
- Versioning
tokens:
- '^[A-Z][a-z]+ing\b'