Bench Virtual Rule Mirror Skill
SkillDev toolsMirror a preset virtual rule (selectors under `nodeRules` in preset.html-standard.jsonc and similar) into bench/config.ts so the benchmark exercises it. Use when a new disallowed-element / similar selector lands in a preset and the matching nu fixtures remain stuck at nu-only despite the new rule existing in markuplint. Trigger keywords: virtual rule, nodeRules, disallowed-element, preset html-standard, bench config mirror, rule does not fire on bench, preset rule not exercised.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Bench Virtual Rule Mirror Skill skill
What this skill tells your AI
The instructions your AI receives, as published by markuplint/markuplint in .claude/skills/bench-virtual-rule/SKILL.md and read by ahel’s review.
bench/config.ts does not extends: ['markuplint:html-standard'].
It curates rules explicitly so the bench surface stays scoped to
nu-validator capability. Consequence: any new entry in a preset's
nodeRules[] is invisible to the benchmark until the same selectors
are mirrored into bench/config.ts. Symptom: fixtures the new
virtual rule should detect remain at nu-only and look like a
markuplint coverage gap when the rule already exists.
Procedure
- Add the selector(s) to the relevant preset
(
preset.html-standard.jsoncor similar). - Mirror the same selectors into
bench/config.tsnodeRules[]with a comment naming the source preset rule (e.g.// Mirrors html-standard/no-duplicate-charset). - Run
yarn bench:update:ml. - Verify the target fixtures flipped from
nu-only→match-error. If they didn't, the selectors don't actually match those fixtures — check selector syntax (caveats below). - If the rule does not map onto any nu-validator capability, skip
step 2 and add a
// not mirrored: <reason>comment to the preset rule's JSDoc so the next maintainer knows it was a conscious decision.
Selector caveats
- HTML attribute names are matched ASCII case-insensitively
(
[charset]matches<meta CHARSET>). Use lowercase to match HTML's normative form. - The
iflag (e.g.[name="description" i]) only applies to attribute values — it is unnecessary for the name, which is already case-folded for HTML. - Sibling selectors (
~) only match elements after the anchor. Coexistence-style constraints typically need both directions (a ~ bandb ~ a) so the rule fires regardless of source order.
Signals
- GitHub stars
- 614
- Forks
- 63
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
bench-virtual-rule- Source
- github.com/markuplint/markuplint