Fixed
hashtag-stuffcounted every#word, so ordinary technical prose flagged as a stuffed tag block (#90). A paragraph citing six issue numbers, a palette listing six hex colours, or a C snippet with six#includelines all scored as hashtag stuffing. Found when this repo's own README linked issue #88 and the detector flagged the README. The bug report has the same problem: the prose of #90 cannot describe the rule without triggering it.- Two subtractive changes, so the rule cannot begin firing on anything it did not already fire on.
maskCode()blanks fenced blocks and inline code spans before counting —fenceRanges()existed but was wired only totitle-case-header, so a tag quoted in backticks counted as a tag used.isSocialTag()subtracts all-digit forms (#88), 6- and 8-character hex colours that contain a digit (#1a2b3c,#1a2b3cff), and C preprocessor directives (#include).owner/repo#88, URL fragments, shebangs, and Markdown headings already passed on the rule's own anchor and are untouched. - Recall changes, both deliberate and both worth stating. An unclosed fence masks everything after it, so a trailing tag block below one no longer flags; this follows
fenceRanges' documented run-to-end rule and matches how renderers behave. A stray backtick pairs with a later span's opener and masks the prose between them, which is CommonMark-correct code-span pairing. - Two false negatives were introduced during development and removed before merge, both found by adversarial review. Carving out 3- and 4-digit hex deleted
#b2b,#e2e,#dad,#cafeand#face; the carve-out now needs 6 or 8 characters and a digit, so#decadeand#facadesurvive too. Masking indented blocks silenced any tag block sitting four spaces under a list marker, where four spaces is a paragraph continuation rather than a code block; that pass was dropped entirely rather than patched. Both were the same mistake: buying a false positive with a false negative on the one shape the rule exists to catch. - Ambiguous word tags stay counted on purpose:
#mainas a CSS id and#generalas a channel are the same token as a tag, and separating them needs a guess about intent that costs more precision than it buys. - Nine fixtures, five that must not fire and four that must. Every carve-out and both masking passes are mutation-tested: disabling any one of them fails the suite, as does widening the hex pattern or dropping its 8-character or digit requirement. No new detector
type, so the catalog count stays 61 andCATEGORIES.mdis unchanged.