refactor(lint): retrofit vale-config to the ADR-0020 context contract

Description 657 -> 244 chars, body 504 -> 342 words, Gotchas 50% -> 24%.
The 50% was the worst ratio in the corpus and a real inverted body, not
the denominator artefact the ratio usually flags: half the body was a
Gotchas section doing duty as reference material.

A clean-context audit caught the split leaving a false statement behind.
Gotcha 1's kernel lost the qualifier that only package styles need
fetching, so it asserted that any style vale sync has not fetched fails
-- contradicting the same file twice, since the built-in Vale style and
any committed custom style are never fetched. An agent adding a custom
style would have added a spurious Packages entry and broken vale sync
outright. The qualifier is restored in the body rather than behind a
fourth reference pointer.

Also corrects the moved fixture's framing, which tabulated a control row
under a heading claiming it came from a multi-line fixture.

Refs #99
This commit is contained in:
2026-08-30 15:07:15 +00:00
parent c59e4bf0c5
commit 45cd26045a
6 changed files with 52 additions and 30 deletions

View File

@@ -19,5 +19,5 @@ Describe what you want configured: initial setup, adding a third-party style pac
| File | Purpose |
|------|---------|
| `SKILL.md` | Skill instructions for agents |
| `references/configuration-reference.md` | Full `.vale.ini` field and rule-header reference |
| `references/configuration-reference.md` | Full `.vale.ini` fields, rule-header fields, and frontmatter-scope behaviour |
| `references/sources.md` | Research sources backing the Vale configuration guidance |

View File

@@ -2,27 +2,22 @@
name: vale-config
description: >
Use when installing or configuring Vale, the cross-platform prose/style linter — setting up
.vale.ini, choosing a StylesPath, adding built-in, third-party, or custom styles, and activating
them per file glob via BasedOnStyles. Covers the setup side of Vale only: getting a project from
"no Vale config" to "vale sync runs clean and BasedOnStyles is wired up correctly". Use even if the
user doesn't say "Vale" explicitly — "set up prose linting", "lint our docs for style", "enforce a
vocabulary/terminology list in markdown" all apply. Do not use when the user wants to actually run
Vale and interpret its output on existing config — use vale-run for that.
Use when installing or configuring Vale, the prose/style linter — writing a `.vale.ini` whose
styles are fetched and actually activated — even when the user says only "set up prose
linting". Not running Vale on an existing config -> `vale-run`.
metadata:
category: lint
version: "0.1.0"
version: "0.1.1"
source_keys:
- context7-websites-vale-sh
---
## Gotchas
- Installing the `vale` binary installs no styles, but only *package* styles need fetching. A fresh `.vale.ini` naming a style in `BasedOnStyles` that is declared in `Packages` will fail or find nothing until `vale sync` downloads it. A built-in style (`Vale`) or a style whose YAML rule files are already committed under `StylesPath` lints immediately, with no `Packages` entry and no sync.
- `.vale.ini` is order-sensitive: global (core) settings first, then the optional `[formats]` section, then glob sections (`[*]`, `[*.md]`, …). Settings in a glob section only apply to files matching that glob.
- `Packages` (top-level, fetched by `vale sync`) and `BasedOnStyles` (per-glob, activates) are separate keys — a style only lints files once it's in both. This is the step people forget.
- A rule scoped to `text.frontmatter.<key>` (e.g. `text.frontmatter.description`) matches reliably when that field's value is a single physical line, and breaks on most — not all — multi-line forms. Confirmed against Vale 3.15.2 with a deliberately-bad fixture: a `>` folded block scalar, plain (unquoted) continuation lines, and single- or double-quoted multi-line scalars each yield 0 findings and exit 0, silently and with no error; a `|` literal block scalar spanning the same 2+ lines lints normally and exits 1. Do not assume `|` and `>` behave alike — reproduce both against your own config before trusting a frontmatter-scoped rule in production. If the field is commonly authored in one of the broken forms, flatten it to one physical line ahead of the `vale` call rather than relying on the scope alone.
- A style in `BasedOnStyles` that is neither built-in nor already under `StylesPath` finds nothing until `vale sync` fetches it — a clean run is not proof anything linted.
- `.vale.ini` is order-sensitive: core settings first, then `[formats]`, then glob sections. Anything written below a glob header applies only to files matching that glob.
- A rule scoped to `text.frontmatter.<key>` silently matches nothing when the field spans multiple lines in most YAML forms. If you scope a rule to frontmatter, read `references/configuration-reference.md` first.
## Setup workflow
@@ -59,4 +54,4 @@ styles/
└── NoJargon.yml
```
Each rule file needs `extends` (the check it implements, e.g. `existence`) and `message` at minimum. Activate the style the same way as any other: add `MyStyle` to `BasedOnStyles` for the relevant glob. See `references/configuration-reference.md` for the full rule header field table.
Each rule file needs `extends` (the check it implements, e.g. `existence`) and `message` at minimum. Activate the style the same way as any other: add `MyStyle` to `BasedOnStyles` for the relevant glob. If a rule needs a field beyond those two, read `references/configuration-reference.md` for the full rule header field table.

View File

@@ -70,9 +70,25 @@ The underlying functions a rule's `extends` field can reference: `existence`, `s
## Built-in Style
Vale ships with a default `Vale` style containing four rules, usable without `vale sync`:
Only *package* styles need fetching. A style whose YAML rule files are already committed under `StylesPath` lints immediately, with no `Packages` entry and no `vale sync`; the same is true of the built-in `Vale` style, which ships with the binary and contains four rules:
- `Vale.Spelling` — spell-checks against Hunspell-compatible dictionaries in `<StylesPath>/config/dictionaries`.
- `Vale.Terms` — enforces the project's accepted vocabulary terms.
- `Vale.Avoid` — enforces the project's rejected vocabulary terms.
- `Vale.Repetition` — flags repeated words (e.g. "the the").
## Frontmatter Scopes
A rule scoped to `text.frontmatter.<key>` (e.g. `text.frontmatter.description`) matches reliably when that field's value is a single physical line, and breaks on most — not all — multi-line forms.
Confirmed against Vale 3.15.2, multi-line forms spanning 2+ lines:
| Frontmatter value form | Result |
|---|---|
| Single physical line (control) | Lints, exits 1 |
| `\|` literal block scalar | Lints, exits 1 |
| `>` folded block scalar | 0 findings, exits 0 |
| Plain (unquoted) continuation lines | 0 findings, exits 0 |
| Single- or double-quoted multi-line scalar | 0 findings, exits 0 |
The silent cases produce no error of any kind, so a passing run is indistinguishable from a clean one. Do not assume a literal block scalar and a folded one behave alike — reproduce both against your own config before trusting a frontmatter-scoped rule in production. If the field is commonly authored in one of the broken forms, flatten it to one physical line ahead of the `vale` call rather than relying on the scope alone.

View File

@@ -19,5 +19,5 @@ Describe what you want configured: initial setup, adding a third-party style pac
| File | Purpose |
|------|---------|
| `SKILL.md` | Skill instructions for agents |
| `references/configuration-reference.md` | Full `.vale.ini` field and rule-header reference |
| `references/configuration-reference.md` | Full `.vale.ini` fields, rule-header fields, and frontmatter-scope behaviour |
| `references/sources.md` | Research sources backing the Vale configuration guidance |

View File

@@ -2,27 +2,22 @@
name: vale-config
description: >
Use when installing or configuring Vale, the cross-platform prose/style linter — setting up
.vale.ini, choosing a StylesPath, adding built-in, third-party, or custom styles, and activating
them per file glob via BasedOnStyles. Covers the setup side of Vale only: getting a project from
"no Vale config" to "vale sync runs clean and BasedOnStyles is wired up correctly". Use even if the
user doesn't say "Vale" explicitly — "set up prose linting", "lint our docs for style", "enforce a
vocabulary/terminology list in markdown" all apply. Do not use when the user wants to actually run
Vale and interpret its output on existing config — use vale-run for that.
Use when installing or configuring Vale, the prose/style linter — writing a `.vale.ini` whose
styles are fetched and actually activated — even when the user says only "set up prose
linting". Not running Vale on an existing config -> `vale-run`.
metadata:
category: lint
version: "0.1.0"
version: "0.1.1"
source_keys:
- context7-websites-vale-sh
---
## Gotchas
- Installing the `vale` binary installs no styles, but only *package* styles need fetching. A fresh `.vale.ini` naming a style in `BasedOnStyles` that is declared in `Packages` will fail or find nothing until `vale sync` downloads it. A built-in style (`Vale`) or a style whose YAML rule files are already committed under `StylesPath` lints immediately, with no `Packages` entry and no sync.
- `.vale.ini` is order-sensitive: global (core) settings first, then the optional `[formats]` section, then glob sections (`[*]`, `[*.md]`, …). Settings in a glob section only apply to files matching that glob.
- `Packages` (top-level, fetched by `vale sync`) and `BasedOnStyles` (per-glob, activates) are separate keys — a style only lints files once it's in both. This is the step people forget.
- A rule scoped to `text.frontmatter.<key>` (e.g. `text.frontmatter.description`) matches reliably when that field's value is a single physical line, and breaks on most — not all — multi-line forms. Confirmed against Vale 3.15.2 with a deliberately-bad fixture: a `>` folded block scalar, plain (unquoted) continuation lines, and single- or double-quoted multi-line scalars each yield 0 findings and exit 0, silently and with no error; a `|` literal block scalar spanning the same 2+ lines lints normally and exits 1. Do not assume `|` and `>` behave alike — reproduce both against your own config before trusting a frontmatter-scoped rule in production. If the field is commonly authored in one of the broken forms, flatten it to one physical line ahead of the `vale` call rather than relying on the scope alone.
- A style in `BasedOnStyles` that is neither built-in nor already under `StylesPath` finds nothing until `vale sync` fetches it — a clean run is not proof anything linted.
- `.vale.ini` is order-sensitive: core settings first, then `[formats]`, then glob sections. Anything written below a glob header applies only to files matching that glob.
- A rule scoped to `text.frontmatter.<key>` silently matches nothing when the field spans multiple lines in most YAML forms. If you scope a rule to frontmatter, read `references/configuration-reference.md` first.
## Setup workflow
@@ -59,4 +54,4 @@ styles/
└── NoJargon.yml
```
Each rule file needs `extends` (the check it implements, e.g. `existence`) and `message` at minimum. Activate the style the same way as any other: add `MyStyle` to `BasedOnStyles` for the relevant glob. See `references/configuration-reference.md` for the full rule header field table.
Each rule file needs `extends` (the check it implements, e.g. `existence`) and `message` at minimum. Activate the style the same way as any other: add `MyStyle` to `BasedOnStyles` for the relevant glob. If a rule needs a field beyond those two, read `references/configuration-reference.md` for the full rule header field table.

View File

@@ -70,9 +70,25 @@ The underlying functions a rule's `extends` field can reference: `existence`, `s
## Built-in Style
Vale ships with a default `Vale` style containing four rules, usable without `vale sync`:
Only *package* styles need fetching. A style whose YAML rule files are already committed under `StylesPath` lints immediately, with no `Packages` entry and no `vale sync`; the same is true of the built-in `Vale` style, which ships with the binary and contains four rules:
- `Vale.Spelling` — spell-checks against Hunspell-compatible dictionaries in `<StylesPath>/config/dictionaries`.
- `Vale.Terms` — enforces the project's accepted vocabulary terms.
- `Vale.Avoid` — enforces the project's rejected vocabulary terms.
- `Vale.Repetition` — flags repeated words (e.g. "the the").
## Frontmatter Scopes
A rule scoped to `text.frontmatter.<key>` (e.g. `text.frontmatter.description`) matches reliably when that field's value is a single physical line, and breaks on most — not all — multi-line forms.
Confirmed against Vale 3.15.2, multi-line forms spanning 2+ lines:
| Frontmatter value form | Result |
|---|---|
| Single physical line (control) | Lints, exits 1 |
| `\|` literal block scalar | Lints, exits 1 |
| `>` folded block scalar | 0 findings, exits 0 |
| Plain (unquoted) continuation lines | 0 findings, exits 0 |
| Single- or double-quoted multi-line scalar | 0 findings, exits 0 |
The silent cases produce no error of any kind, so a passing run is indistinguishable from a clean one. Do not assume a literal block scalar and a folded one behave alike — reproduce both against your own config before trusting a frontmatter-scoped rule in production. If the field is commonly authored in one of the broken forms, flatten it to one physical line ahead of the `vale` call rather than relying on the scope alone.