fix(assembly): real per-function args count, validate tri-comparison ledger - #1955
Merged
Conversation
…nting Same generic single-.search()-then-split derivation bug as agc_assembly (#1949's fix, PR #1952): assembly's args regex has exactly one capturing group, so every match's text has no comma/whitespace to split on -- every function was capped at a bare 0/1 regardless of how many calling-convention registers it actually referenced (rdi/rsi/rdx/rcx/r8/r9/xmm0-7 for x86-64 SysV, x0-7/w0-7/v0-7 for ARM AAPCS, ax/bx/cx/dx/si/di for legacy 16-bit). Adds _count_assembly_register_args (mirrors _count_agc_register_args's pattern): counts DISTINCT argument-passing registers referenced anywhere in the body via .findall, canonicalizing different-width references to the same physical register (edi/rdi, w3/x3, al/ah/ax) to one slot via _ASSEMBLY_ARG_REG_CANON_RE. Hand-verified against matrixmultneon.s's `main` (args=10: x0, x1, v0-v7 -- confirmed by reading every real register reference in the function body, including inside a .macro definition its call sites expand). Also validates both assembly tri-comparison function-existence ledger shapes. Confirmed mechanisms: a dot-prefix NASM/GAS local-label naming split (both tools find the same real label, ctags strips the leading dot GitGalaxy preserves -- a name-string artifact, not a detection gap); a genuine ctags gap on purely-numeric local labels (.1/.2, neither tagged under any name); the SAME #1949 detector.py bug (RELINT-style truncation / single-line-block discard) independently confirmed live here too (del_command, C, prtstr); a correct-by-design GitGalaxy exclusion for GCC's .L-prefix local-label convention (.Lenv0/.Largv0, both real data labels ctags over-tags); and a genuine GitGalaxy precision gap -- unlike agc_assembly's opcode-coupled func_start, generic assembly's has no following-instruction requirement, so it also matches pure data/constant labels (max_entries, *.ident, str.*) ctags is comparatively more conservative about. No credit/debit either direction -- real wins and real gaps mix within both shapes. ctags legitimately earns its first chart badge on assembly's Func Precision panel as a result (92.6% vs GitGalaxy's 85%) -- an honest result, not forced. Golden master fixtures re-blessed (both venvs); crucible_check.py passes clean; 785 tests pass (assembly's own 231 + core_engine). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
squid-protocol
added a commit
that referenced
this pull request
Aug 20, 2026
* docs(language-status): add assembly coverage doc Documents the generic x86-64/ARMv8 assembly LANGUAGE_DEFINITIONS entry (distinct from the already-documented agc_assembly sibling) following the language-status skill: 42/52 rule keys wired, 231 dedicated test cases, closed hardening work (#856/#936, #940, #574/#745, #1955), two open unresolved bugs found along the way (#1949, #1954), and real-world gitgalaxy-raw-output evidence (HelloSilicon, asm, bootOS, cosmopolitan). Sections 1-8 only -- section 9 (measured tri-comparison accuracy) is being produced by a separate investigation and will be appended later. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(language-status): add assembly §9 tri-comparison writeup Appends the measured tri-comparison section left open for the parallel tri-comparison-ledger-sweep investigation: GitGalaxy vs. ctags (assembly has no tree-sitter grammar). Unlike agc_assembly's fairly clean split, this language's shapes mix real wins and real gaps in both directions -- a dot-prefix naming-convention artifact, a genuine ctags gap on numeric local labels, the same #1949 detector.py bug confirmed live here, a correct-by- design .L-prefix exclusion, and a genuine GitGalaxy precision gap from func_start's intentionally permissive design (the mirror image of agc_assembly's own win). ctags legitimately earned its first chart badge as a result. Also documents the separately-filed #1954 (prism.py Form-Feed line-drift bug) found during the same investigation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Joe Esquibel <squid-protocol@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
.search()-then-split derivation bug as agc_assembly (detector.py _slice_by_labels: assembly_returns truncates real bodies, single-line blocks silently discarded (assembly/cobol/fortran/abap/agc_assembly) #1949's fix, PR fix(agc_assembly): real per-function args count, earn a manual-verification badge #1952):assembly'sargsregex has exactly one capturing group, so every match's text has no comma/whitespace to split on -- every function was capped at a bare 0/1 regardless of how many calling-convention registers it actually referenced._count_assembly_register_args, mirroring_count_agc_register_args's pattern: counts DISTINCT argument-passing registers referenced anywhere in the body via.findall, canonicalizing different-width references to the same physical register (edi/rdi,w3/x3,al/ah/ax) to one slot.assemblytri-comparison function-existence ledger shapes with concrete evidence: a NASM/GAS dot-prefix local-label naming split (cosmetic, not a real gap), a genuine ctags limitation on purely-numeric local labels, the same detector.py _slice_by_labels: assembly_returns truncates real bodies, single-line blocks silently discarded (assembly/cobol/fortran/abap/agc_assembly) #1949 detector.py bug independently confirmed live here, a correct-by-design GitGalaxy exclusion for GCC's.L-prefix convention, and a genuine GitGalaxy precision gap (generic assembly'sfunc_starthas no following-instruction requirement, unlike agc_assembly's, so it also matches pure data/constant labels). No credit/debit either direction.Separately filed (not part of this PR's diff, found during the same investigation)
prism.py's_strip_single_line_commentsusesstr.splitlines(), which splits on Form Feed/vertical tab/other Unicode line-boundary characters beyond\n/\r\n-- confirmed via a real, growing (+1 to +9) line-number drift incosmopolitan/ape.S(which uses\fas a deliberate page-break idiom), exactly matching the file's 9 real Form Feed positions. Affects all 20line_exclusive-family languages in principle; scoped as its own issue since the fix (and verifying it doesn't regress\r\nhandling) is a bigger, separate piece of work.Test plan
pytest tests/extraction/languages/test_assembly.py tests/extraction/languages/test_assembly_strict.py tests/core_engine/-- 785 passed, 1 xfailedcrucible_check.py-- clean on both full-precision and zero-dependency venvsruff_audit.py --ci/mypy_audit.py --ci-- no new findings🤖 Generated with Claude Code