@@ -12,11 +12,9 @@ settings that pairs a Markdown flavor with a set of
1212style choices. Setting ` convention: ` at the top of
1313your ` .mdsmith.yml ` selects one of the built-in
1414bundles; the rule presets in that bundle are applied
15- as a base layer beneath your own rule config.
16-
17- Conventions answer "what kind of Markdown does this
18- project write?" with one config knob instead of
19- eight.
15+ as a base layer beneath your own rule config. It
16+ answers "what kind of Markdown does this project
17+ write?" with one config knob instead of eight.
2018
2119A convention is distinct from a flavor. Flavor is a
2220property of the * renderer* (CommonMark, GFM,
@@ -36,12 +34,11 @@ convention: portable
3634That single line pins a flavor and a curated set of
3735style-rule settings. ` convention:` is a top-level
3836config key, sibling to `rules:`, `kinds:`, and
39- ` overrides:` . Setting an unknown name is a config
40- error at load time.
37+ ` overrides:` . An unknown name is a config error.
4138
4239Built-in values : ` portable` , `github`, `obsidian`,
43- ` parity` , `plain`. The key is optional; omit it for no
44- convention.
40+ ` parity` , `plain`, `no-llm-tells` . The key is
41+ optional; omit it for no convention.
4542
4643You may also set `flavor:` inside `markdown-flavor`
4744alongside `convention:`. If both are set, they must
@@ -130,16 +127,32 @@ markdownlint-compatible tools (mado, rumdl) check
130127it : ` flavor: gfm` plus every mdsmith-only rule
131128turned off, leaving the structural style class
132129those tools also run. Use it for a like-for-like
133- comparison, or as a fast check-only markdownlint
134- gate before you adopt the cross-file and
135- generated-section layer. The disabled-rule list is
136- generated from the convention so it never drifts —
137- see the [benchmark doc][parity-list]. Unlike the
138- other built-ins, `parity` leaves `markdown-flavor`
130+ comparison, or as a fast markdownlint gate before
131+ you adopt the cross-file and generated-section
132+ layer. The disabled-rule list is generated from the
133+ convention, so it never drifts — see the
134+ [benchmark doc][parity-list]. Unlike the other
135+ built-ins, `parity` leaves `markdown-flavor`
139136(MDS034) opt-in.
140137
141138[parity-list] : ../research/benchmarks/README.md
142139
140+ # ## `no-llm-tells`
141+
142+ Flags mechanical LLM-prose tells in CI. MDS056
143+ blocks vocabulary and phrasal tells; MDS055 blocks
144+ banned sentence openers; MDS023 and MDS024 tighten
145+ readability budgets. Lists are sourced from
146+ [`slop-patterns.md`][slop]; a drift-checker test
147+ keeps the two in sync.
148+
149+ Pins no flavor and does not enable `markdown-flavor`
150+ (MDS034). The `contains` and `starts` lists merge by
151+ **append**: a project's own entries join the
152+ convention's list instead of replacing it.
153+
154+ [slop] : ../../.claude/skills/docs-author/slop-patterns.md
155+
143156# # How presets layer with user config
144157
145158Convention presets sit between built-in defaults
@@ -166,9 +179,8 @@ The `default` and `user` layers come from the same
166179convention so a convention can enable a rule that
167180is opt-in by default (e.g. `convention : portable`
168181turns on MDS034). Without the split, the default's
169- `Enabled : false` would land on top of the
170- convention's `Enabled : true` and silently disable
171- the rule.
182+ `Enabled : false` would override the convention's
183+ `Enabled : true`.
172184
173185For example, the `github` convention sets
174186`no-inline-html.allow : [details, summary]`. To
@@ -199,24 +211,15 @@ rules:
199211 markdown-flavor: false
200212` ` `
201213
202- The `convention:` selector lives at the top level.
203- So the user can disable MDS034 cleanly with a
204- bool-only `markdown-flavor : false` entry in the
205- rules block. The convention preset has already
206- populated the merged config at load time. A
207- bool-only later layer toggles `enabled` without
208- erasing the preset's settings. The rule stays
209- configured but its `Check()` is gated off. The
210- other rules in the preset are untouched.
211-
212- This split keeps MDS034 focused on "what does this
213- renderer interpret as a feature." Conventions
214- orchestrate style separately.
214+ A bool-only `markdown-flavor : false` entry toggles
215+ ` enabled` without erasing the preset's settings. The
216+ rule stays configured but its `Check()` is gated
217+ off. The other rules in the preset are untouched.
215218
216219# # User-defined conventions
217220
218- The three built-in conventions cover common cases.
219- Teams that need something custom define it inline in
221+ The built-in conventions cover common cases. Teams
222+ that need something custom define it inline in
220223` .mdsmith.yml` . The top-level `conventions:` key holds
221224the map :
222225
@@ -260,10 +263,10 @@ convention "our-team" rule "no-inline-html": no-inline-html: unknown setting "al
260263# ## Reserved names
261264
262265The built-in names `portable`, `github`,
263- ` obsidian` , `parity`, and `plain` are reserved.
264- Defining a `conventions.portable` entry is a config
265- error. This keeps the built-in names stable across
266- docs and tutorials.
266+ ` obsidian` , `parity`, `plain`, and `no-llm-tells`
267+ are reserved. Defining a `conventions.portable`
268+ entry is a config error. This keeps the built-in
269+ names stable across docs and tutorials.
267270
268271# ## Resolution order
269272
@@ -274,25 +277,17 @@ is impossible. When neither table matches, the error
274277lists both sets :
275278
276279` ` ` text
277- unknown convention "bogus" (valid: github, obsidian, our-team, parity, plain, portable)
280+ unknown convention "bogus" (valid: github, no-llm-tells, obsidian, our-team, parity, plain, portable)
278281` ` `
279282
280283# ## Interaction with top-level rules
281284
282- User-defined conventions apply as a base layer, exactly
283- like the built-in conventions. A top-level `rules:`
284- entry overrides the convention preset for that rule.
285- The rest of the preset remains.
286-
287- # ## Inspecting user conventions
288-
289- ` mdsmith kinds resolve <file>` labels user convention
290- layers with a `(user)` suffix. Built-in conventions
291- carry no suffix. Example merge-chain output :
292-
293- ` ` ` text
294- convention.our-team (user) set {flavor: gfm}
295- ` ` `
285+ User-defined conventions apply as a base layer, like
286+ the built-in conventions. A top-level `rules:` entry
287+ overrides the convention preset for that rule; the
288+ rest of the preset remains. `mdsmith kinds resolve
289+ <file>` labels user-convention layers with a
290+ ` (user)` suffix.
296291
297292# # Inspecting an effective convention
298293
0 commit comments