From the 2026-09-21 dogfood notes (eleven voice rules over ~1,100 markdown files, measured on the pinned binary).
Adding a second raw: list item to an existence rule silently joined it onto the first pattern, so the new branch never fired and its fail fixture failed. Vale concatenates raw entries into one regex; alternation has to be written inside one entry as (a|b|c).
Wrong (second entry is appended to the first):
extends: existence
raw:
- "\\bstops being\\b[^.!?\\n]{0,80}\\band becomes\\b"
- "[A-Z][^.!?\\n]{3,70}[.!?] (The|That|This|It)('s| is| was) the (problem|twist|point)\\b\\."
Right:
extends: existence
nonword: true
raw:
- "(\\bstops being\\b[^.!?\\n]{0,80}\\band becomes\\b|[A-Z][^.!?\\n]{3,70}[.!?] (The|That|This|It)('s| is| was) the (problem|twist|point)\\b\\.)"
packages/cli/src/agent/create-vale-rule.md never mentions alternation or concatenation and every raw example has one entry.
What to do
- Recipe: a gotcha under the
raw guidance with the wrong/right pair above; topic version bump.
packages/cli/test/vale-vendor-contract.test.ts: pin the join behavior on the vendored binary (two raw entries, a fixture that matches only the second alone, expect no finding) so an engine change surfaces.
taskless verify (schema vale-rule.ts or a verify-time check): warn when raw has more than one entry — "Vale joins these into one pattern; write one entry with (a|b) unless the join is intended".
- No changeset needed for the recipe alone;
patch if the verify warning ships.
From the 2026-09-21 dogfood notes (eleven voice rules over ~1,100 markdown files, measured on the pinned binary).
Adding a second
raw:list item to anexistencerule silently joined it onto the first pattern, so the new branch never fired and its fail fixture failed. Vale concatenatesrawentries into one regex; alternation has to be written inside one entry as(a|b|c).Wrong (second entry is appended to the first):
Right:
packages/cli/src/agent/create-vale-rule.mdnever mentions alternation or concatenation and everyrawexample has one entry.What to do
rawguidance with the wrong/right pair above; topic version bump.packages/cli/test/vale-vendor-contract.test.ts: pin the join behavior on the vendored binary (tworawentries, a fixture that matches only the second alone, expect no finding) so an engine change surfaces.taskless verify(schemavale-rule.tsor a verify-time check): warn whenrawhas more than one entry — "Vale joins these into one pattern; write one entry with(a|b)unless the join is intended".patchif the verify warning ships.