Detector spec (from hypatia#333 Pattern 1)
Pattern 1 — Brittle regex matching of documentation headings inside inline-python workflow scripts
Severity: high (estate-wide silent gate failure)
Detection (Hypatia.Rules.WorkflowAudit):
- Parse
run: | blocks in workflow YAML.
- Inside Python
python3 << 'PYEOF' … PYEOF blocks, find re.search(r'...') and re.match(r'...') calls whose pattern contains the literal token sequence that names a markdown section heading (e.g. [A-Z][a-z]+ [A-Z][a-z]+).
- Flag any such regex that is not anchored to
^# or ^#{1,4}\s+ — the absence of heading anchoring means the regex will also match prose mentions of the same phrase, which silently swap which table the parser walks.
Worked example (this session):
standards/.github/workflows/governance-reusable.yml:179 — re.search(r'TypeScript [Ee]xemptions', line) was unanchored. Repos with a heading variant like ### TypeScript / JavaScript Exemptions (Approved) (affinescript) didn't match, so the parser fell through to a prose mention of "the TypeScript exemptions above" inside a different section and parsed the wrong table. Every PR in affinescript failed the governance / Language / package anti-pattern policy check for weeks before this session caught it.
- Fix: standards#183 anchored the regex with
^#{1,4}\\s+.*TypeScript.*[Ee]xemption.
Remediation guidance to emit:
Anchor heading-detection regexes to ^#{1,4}\\s+ so prose mentions don't trigger table parsing. Add an inline comment naming the heading shape you intend to match.
Implementation pointers
- Detection algorithm: Parse
run: | blocks; inside python3 << 'PYEOF' heredocs, find re.search(r'...') / re.match(r'...') whose pattern matches a markdown-heading-like token sequence; flag if not anchored to ^# or ^#{1,4}\s+.
- Real-world example:
standards/.github/workflows/governance-reusable.yml:179 — re.search(r'TypeScript [Ee]xemptions', line) unanchored, broke governance / Language / package anti-pattern policy on affinescript for weeks.
- Landed fix (reference): standards#183 (anchored regex to
^#{1,4}\\s+.*TypeScript.*[Ee]xemption).
- Rule statement: Anchor heading-detection regexes to
^#{1,4}\\s+ so prose mentions don't trigger table parsing. Add an inline comment naming the heading shape you intend to match.
Acceptance
Source cohort: hypatia#333.
Detector spec (from hypatia#333 Pattern 1)
Pattern 1 — Brittle regex matching of documentation headings inside inline-python workflow scripts
Severity: high (estate-wide silent gate failure)
Detection (
Hypatia.Rules.WorkflowAudit):run: |blocks in workflow YAML.python3 << 'PYEOF' … PYEOFblocks, findre.search(r'...')andre.match(r'...')calls whose pattern contains the literal token sequence that names a markdown section heading (e.g.[A-Z][a-z]+ [A-Z][a-z]+).^#or^#{1,4}\s+— the absence of heading anchoring means the regex will also match prose mentions of the same phrase, which silently swap which table the parser walks.Worked example (this session):
standards/.github/workflows/governance-reusable.yml:179—re.search(r'TypeScript [Ee]xemptions', line)was unanchored. Repos with a heading variant like### TypeScript / JavaScript Exemptions (Approved)(affinescript) didn't match, so the parser fell through to a prose mention of "the TypeScript exemptions above" inside a different section and parsed the wrong table. Every PR in affinescript failed thegovernance / Language / package anti-pattern policycheck for weeks before this session caught it.^#{1,4}\\s+.*TypeScript.*[Ee]xemption.Remediation guidance to emit:
Implementation pointers
run: |blocks; insidepython3 << 'PYEOF'heredocs, findre.search(r'...')/re.match(r'...')whose pattern matches a markdown-heading-like token sequence; flag if not anchored to^#or^#{1,4}\s+.standards/.github/workflows/governance-reusable.yml:179—re.search(r'TypeScript [Ee]xemptions', line)unanchored, brokegovernance / Language / package anti-pattern policyon affinescript for weeks.^#{1,4}\\s+.*TypeScript.*[Ee]xemption).^#{1,4}\\s+so prose mentions don't trigger table parsing. Add an inline comment naming the heading shape you intend to match.Acceptance
lib/rules/<name>.exif Elixir, or matching the repo's rule DSL)Source cohort: hypatia#333.