Skip to content

Commit fbe5acb

Browse files
hyperpolymathclaude
andcommitted
fix(governance): TypeScript-exemption heading detection must be heading-anchored and accept common variants
The TypeScript exemption-table parser used `re.search(r'TypeScript [Ee]xemptions', line)`, which two distinct ways: 1. It only matched the exact phrase "TypeScript Exemptions" with a single space between the words. Common variants like "### TypeScript / JavaScript Exemptions (Approved)" failed silently. 2. It was unanchored, so prose mentions ("the TypeScript exemptions above") triggered table parsing — picking up whichever table happened to follow that prose line, often the wrong one. Estate impact: any repo whose CLAUDE.md used a heading variant other than the exact "TypeScript Exemptions" got the wrong exemption table parsed — or none at all — and the `Language / package anti-pattern policy` check went red on every PR. This was the case for hyperpolymath/affinescript, whose heading "### TypeScript / JavaScript Exemptions (Approved)" caused the script to fall through to the Runtime Exemptions section's prose mention and parse two JS entries instead of the three TS ones. Replace the search with a heading-anchored regex: ^#{1,4}\s+.*TypeScript.*[Ee]xemption This: - Requires a markdown heading prefix (1-4 #'s + whitespace), so prose mentions never trigger. - Matches "TypeScript" anywhere in the heading text. - Matches both "Exemption" and "Exemptions" (singular/plural). Verified against 9 representative cases: ✓ "### TypeScript Exemptions (Approved)" ✓ "### TypeScript / JavaScript Exemptions (Approved)" ✓ "## TypeScript exemptions" ✓ "# TypeScript Exemption Table" ✓ "#### TypeScript-specific Exemptions" ✗ "The TypeScript exemptions above remain." (prose) ✗ "**Closed exemptions:** for the TypeScript ..." (prose) ✗ "### Runtime Exemptions (Approved)" (off-topic) ✗ "### TypeScript" (no Exemption) Refs hyperpolymath/affinescript PR #374 (downstream repo-local workaround that became unnecessary after this fix). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 431adbb commit fbe5acb

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

.github/workflows/governance-reusable.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,18 @@ jobs:
174174
exemption_patterns = []
175175
claude_md = pathlib.Path('.claude/CLAUDE.md')
176176
if claude_md.exists():
177+
# Locate the TypeScript-exemption section's heading line. The
178+
# regex matches any markdown heading containing both
179+
# "TypeScript" and "Exemption[s]" — accepts variants like
180+
# "### TypeScript Exemptions (Approved)" and
181+
# "### TypeScript / JavaScript Exemptions (Approved)" — and
182+
# is anchored to a heading prefix so prose mentions of the
183+
# phrase elsewhere in the file (e.g. "the TypeScript
184+
# exemptions above") do NOT trigger table parsing.
185+
ts_heading = re.compile(r'^#{1,4}\s+.*TypeScript.*[Ee]xemption')
177186
in_table = False
178187
for line in claude_md.read_text(encoding='utf-8').splitlines():
179-
if re.search(r'TypeScript [Ee]xemptions', line):
188+
if ts_heading.match(line):
180189
in_table = True
181190
continue
182191
if in_table and line.startswith(('### ', '## ', '# ')):

0 commit comments

Comments
 (0)