Skip to content

fix(m4): func_start captures the real macro name, not the defun keyword - #1927

Merged
squid-protocol merged 2 commits into
mainfrom
fix/m4-func-start-capture-group
Aug 20, 2026
Merged

fix(m4): func_start captures the real macro name, not the defun keyword#1927
squid-protocol merged 2 commits into
mainfrom
fix/m4-func-start-capture-group

Conversation

@squid-protocol

Copy link
Copy Markdown
Owner

Summary

  • The func_start regex for m4 had no capture group over the macro-name argument, so it matched the defun keyword itself (m4_define/define/AC_DEFUN/AC_DEFUN_ONCE/AU_DEFUN/m4_defun) as the "function name" -- structurally identical to matching def as a Python function's name instead of what follows it. Confirmed via the tri-comparison ledger's m4/function/existence/agree[gitgalaxy]_vs[ctags] shape (GitGalaxy reported a function literally named "AC_DEFUN").
  • Now captures the real first-argument macro name, handling all three real m4 quoting conventions seen in production autoconf code: classic backtick/apostrophe (`name'), bracket ([name] or the more defensive double-bracket [[name]]), and unquoted.
  • Updates test_m4.py's FUNCTION_CASES fixtures, which had baked the old buggy behavior in as "expected" (asserting the captured name equaled the keyword instead of the real macro name).
  • Re-blesses tests/golden_master_audit.json/tests/golden_master_zero_dep_audit.json for the resulting, expected output change on real corpus files (curl/gnucobol autoconf scripts) -- see that commit's message for the verified before/after breakdown.

Important caveat

This fixes the naming bug but does not fully resolve m4/function/existence/agree[ctags]_vs[gitgalaxy] (79 occurrences) -- even with this fix, the live pipeline only ever extracts 1 function total across the whole m4 corpus, while the fixed regex matches dozens when run standalone against the same files. That's a separate, deeper pipeline-level recall gap (prism.py or detector.py segment-routing dropping real matches before they reach the DB) -- currently under a separate Gemini-dispatched investigation, not fixed here.

Verification

  • 94/94 m4 extraction + strict tests pass.
  • Full tests/core_engine/ + tests/extraction/: 6747 passed -- no regressions.
  • python tests/tools/crucible_check.py: full_precision PASS, zero_dependency PASS (after re-blessing the golden masters).
  • Manually verified both golden-master count deltas (24→19, 4→2) against real source: each is exactly 2 m4_define([$0],[]) self-undefine idioms per file correctly excluded now ($0 isn't a valid identifier).
  • ruff_audit.py --ci / mypy_audit.py --ci / ruff format --check: clean.

Test plan

  • Regex behavior verified against real corpus quoting variety (backtick, bracket, double-bracket, unquoted)
  • Golden master diff manually verified line-by-line before blessing, not blindly accepted
  • Full extraction/core_engine suite green
  • crucible_check.py differential scan clean (both venvs, post-reblessing)

🤖 Generated with Claude Code

squid-protocol and others added 2 commits August 20, 2026 12:01
The old pattern had no capture group over the macro-name argument, so it
matched the defun keyword itself (m4_define/define/AC_DEFUN/AC_DEFUN_ONCE/
AU_DEFUN/m4_defun) as the "function name" -- structurally identical to
matching "def" as a Python function's name instead of what follows it.
Confirmed via the tri-comparison ledger's m4/function/existence/
agree[gitgalaxy]_vs[ctags] shape (1 occurrence: GitGalaxy reported a
function literally named "AC_DEFUN").

Now captures the real first-argument macro name, handling all three real
m4 quoting conventions seen in production autoconf code: classic
backtick/apostrophe (`name'), bracket ([name] or the more defensive
double-bracket [[name]]), and unquoted.

Updates test_m4.py's FUNCTION_CASES fixtures, which had baked the old
buggy behavior in as "expected" (asserting the captured name equaled the
keyword, e.g. "AC_DEFUN", instead of the real macro name "TargetFunc").

NOTE: this fixes the naming bug but does NOT fully resolve
m4/function/existence/agree[ctags]_vs[gitgalaxy] (79 occurrences) -- even
with this fix, the live pipeline only ever extracts 1 function total
across the whole m4 corpus, while the fixed regex matches dozens when run
standalone against the same files. That's a separate, deeper pipeline-level
recall gap (prism.py or detector.py segment-routing dropping real matches
before they reach the DB, the same failure class documented in the
tri-comparison-ledger-sweep skill's ABAP saga) -- tracked separately via a
Gemini dispatch, not fixed in this PR.

Verified: 144 m4 extraction/strict tests pass (94 in test_m4.py +
test_m4_strict.py specifically), full core_engine + extraction suite
green (6747 passed), ruff/mypy/format clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Expected diff from the func_start capture-group fix (previous commit):
AC_DEFUN([AC_PROG_F77], []) now correctly names the function
"AC_PROG_F77" (was "AC_DEFUN"); two m4_define([$0],[]) self-undefine
idioms in curl/m4/xc-am-iface.m4 and zz40-xc-ovr.m4 no longer miscount as
named function definitions (2 fewer real matches per file -- $0 isn't a
valid identifier, so it's correctly excluded now). Downstream tech-debt/
risk numbers for gnucobol/configure.ac and the m4 directory group shift
accordingly. Verified both count changes directly against source before
blessing (grep confirmed exactly 2 non-identifier `m4_define([$0],[])`
calls per file, matching the 24->19 and 4->2 deltas exactly).

Regenerated with `python tests/tools/update_golden_master.py` in both
full-precision and zero-dependency venvs; `crucible_check.py` clean on
both after this update.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

✅ No security issues found.

🐦‍⬛ Powered by Muninn · Skald Lab

@squid-protocol
squid-protocol merged commit 72ca96c into main Aug 20, 2026
30 of 31 checks passed
@squid-protocol
squid-protocol deleted the fix/m4-func-start-capture-group branch August 20, 2026 17:06
squid-protocol added a commit that referenced this pull request Aug 20, 2026
…#1930)

Investigates and validates the entire m4 tri-comparison ledger backlog
plus scheme's original recall-gap shape, via the tri-comparison-ledger-
sweep skill:

- m4/function/existence/agree[ctags]_vs[gitgalaxy] (79): clean ctags-side
  limitation, not a GitGalaxy defect -- every sampled occurrence is a real
  AC_DEFINE/AC_DEFINE_UNQUOTED autoconf helper call (emits a C
  preprocessor #define at build time), not an M4 macro definition. ctags'
  M4 parser heuristically over-tags these as function definitions; noted
  in ctags_reader.py alongside the existing C RICHCMP_WRAPPER precedent.
- m4/function/existence/agree[gitgalaxy]_vs[ctags] (1): real GitGalaxy
  false positive (func_start captured the AC_DEFUN keyword itself as a
  function name), fixed in PR #1927.
- m4/class/existence/agree[gitgalaxy]_vs[ctags] (4): real GitGalaxy false
  positive -- m4's class_start is None but detector.py's class-extraction
  fallback doesn't check that, so it matches raw C struct declarations
  embedded as text inside autoconf feature-test macro arguments. Filed as
  #1925 (broader gap, 18 other class_start=None languages not yet
  checked), not fixed in this sweep.
- scheme/function/existence/agree[ctags]_vs[gitgalaxy] (92): confirmed
  catastrophic GitGalaxy engine defect (100% function recall loss for the
  whole language), root-caused and fixed in PR #1929. A smaller residual
  gap remains post-fix (58/92 found) and a new, legitimate GitGalaxy-alone
  shape it surfaces (real nested `define` forms ctags' parser misses) is
  left unvalidated for a future sweep pass.

Also filed #1926 (yacc: both real corpus files silently excluded by
statistical_auditor.py's anomaly sweep, likely an n=2 degenerate-cohort
Z-score issue -- not root-caused to the exact triggering check, flagged
for follow-up).

Regenerated tri_comparison_chart.svg and tri_comparison_points_of_interest.md;
diff confirmed scoped to m4 (asterisks fully cleared) and scheme (0->58/92,
still asterisked since the residual gap is real and not yet fully closed).

Co-authored-by: Joe Esquibel <squid-protocol@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant