Documentation Infrastructure
Prose governance system
Demonstration piece. Shipped client documentation is under NDA, so this was built to the same standard instead.
3 rules removed and 6 added by a quarterly review of what fires and what gets suppressed.
The sampleOpen Prose governance system- Problem
- Editorial quality that depended on one reviewer's attention, and degraded the moment that attention was elsewhere.
- Insight
- Most prose linters fail by growing. Every plausible rule gets added, the output turns to noise, and writers learn to scroll past all of it.
- Result
- A Vale ruleset and CI pipeline where every rule names the defect it prevents, and the rejected rules are documented alongside.
The full story
Editorial review does not scale. One editor applying good judgment one document at a time is a bottleneck and a single point of failure, and the quality drops the week they are on leave. Encoding the judgments that can be encoded frees that attention for the ones that cannot.
The admission criterion for this ruleset is a single sentence: a proposed rule must complete "without this, a reader will…". A rule that cannot is a preference, and preferences do not belong in a build gate. Every rule carries its defect in the failure message, so a writer who trips one reads the reason, not just the correction, and learns the standard instead of learning to satisfy the tool.
Severity is treated as a real signal, not a strength of feeling. Errors block the merge and are reserved for defects that mislead a reader; warnings report and do not block. There is no third level, because a tier nobody reads trains writers to skim the output, which is how the blocking lines get skimmed too.
Key decisions
- Require every rule to name its defect, and reject the ones that cannot. This kills more proposed rules than any other filter, which is the point.
- Reject passive-voice linting outright. Passive voice is frequently correct in technical writing, and a rule with a high false-positive rate teaches writers to ignore the output, including the parts worth reading.
- Annotate the pull request diff with file and line, never a bare count. A CI failure a writer cannot locate is a CI failure they will route around.
- Keep checks that need more than one file out of Vale. Vale lints the text of one file at a time, so links go to lychee, required front matter to a yq check, and the version rule is generated from versions.yml before Vale runs. A Vale rule written as though it could read another file does not fail loudly; it simply never fires.
- Review suppressions quarterly. A cluster of "vale off" comments around one rule means the rule has false positives, and the fix is the rule, not the suppressions.
What it taught me
Three rules have been removed since this ruleset shipped. One had a false-positive rate high enough that writers were suppressing it by reflex, which is worse than not having it. The quarterly review exists because the natural direction of a ruleset is to grow, and a gate that has grown past its usefulness is one people route around.