Skip to content

Fix dockerfile func_start recall: route to Mode A, not brace search - #1976

Merged
squid-protocol merged 3 commits into
mainfrom
fix/dockerfile-func-start-mode-a-routing
Aug 21, 2026
Merged

Fix dockerfile func_start recall: route to Mode A, not brace search#1976
squid-protocol merged 3 commits into
mainfrom
fix/dockerfile-func-start-mode-a-routing

Conversation

@squid-protocol

Copy link
Copy Markdown
Owner

Summary

Manually verified dockerfile's tri-comparison numbers via the tri-comparison-ledger-sweep skill's manual-verification fallback (dockerfile is one of 5 languages -- abap, dockerfile, jcl, livecode, yaml -- with neither a tree-sitter grammar nor ctags support). Found and fixed a real function-existence recall bug, plus surfaced/filed three narrower follow-ons.

  • The bug: dockerfile has no ScopeParsingRegistry entry and no brace-delimited instruction bodies at all (RUN/CMD/ENTRYPOINT/HEALTHCHECK end at the next instruction, never at {/}), so it silently fell through to Mode_B_Braces in detector.py's _function_slice. That mode only produces a named function when a literal { happens to appear by coincidence within its search window -- in practice almost always an unrelated later instruction's ${VAR} template brace, not anything belonging to the matched instruction's own body.
  • Evidence: the raw func_start regex was 100% correct in isolation (71/71 matches vs. an independent grep, zero discrepancies across the 4-file language-crucible/data/dockerfile/moby/test_targets/ corpus). But the real pipeline's named function list (function_data/function_count) only captured 15/71 of them pre-fix, with bogus body-boundary/impact numbers borrowed from unrelated later lines on top of that.
  • The fix: routes dockerfile to Mode A (_slice_by_labels), the same "greedy to the next func_start match" heuristic already proven for abap/cobol/fortran/assembly (abap's own identical bug shape was detector.py: ABAP unregistered in ScopeParsingRegistry falls through to brace-based function slicing, dropping ~87% of real methods #1899). This is a direct, correct fit -- every Dockerfile instruction, including a RUN <<EOF ... EOF heredoc body, really does span exactly from its own keyword to the next instruction or EOF.

Verification chain

  • dockerfile extraction gauntlet + strict tests: 120 passed
  • core detector tests: 141 passed
  • ruff_audit.py --ci / mypy_audit.py --ci: clean against baseline
  • crucible_check.py against the full ~80-repo corpus: confirmed the fix generalizes -- a 5th real occurrence (shell/brew/Dockerfile, embedded in an unrelated repo whose dominant language is shell) was also corrected, with zero diffs in any other language/file
  • Both golden master fixtures re-blessed (update_golden_master.py --yes, both full_precision and zero_dependency venvs)

Docs / papertrail

  • docs/language_status/dockerfile.md (new) -- full coverage doc + §9 manual-verification writeup, including why there's no class entry in manual_verification.json (dockerfile's class_start raw signal is 100% accurate, but named build-stage extraction doesn't exist yet -- see dockerfile has no named class (build-stage) extraction -- class_start regex captures the FROM keyword, not the stage alias #1974)
  • docs/self_scan/manual_verification.json -- new dockerfile.function entry (71/71 verified), earns dockerfile's **/badge on the tri-comparison chart's Functions Found panel
  • docs/self_scan/tri_comparison_chart.svg / tri_comparison_points_of_interest.md -- regenerated (routine --all --write refresh; only dockerfile's own row and the summary counts changed content-wise, rest is timestamp churn)

Follow-on issues filed (not bundled here -- each has its own, broader blast radius)

🤖 Generated with Claude Code

Dockerfile has no ScopeParsingRegistry entry and no brace-delimited
instruction bodies at all, so it silently fell through to
Mode_B_Braces in detector.py's _function_slice -- which only produced
a named function when a literal `{` happened to appear by coincidence
within its search window (almost always an unrelated LATER
instruction's `${VAR}` template brace, not anything belonging to the
matched RUN/CMD/ENTRYPOINT/HEALTHCHECK's own body). Confirmed via
manual verification against language-crucible/data/dockerfile (dockerfile
has no tree-sitter/ctags comparison tool): the raw func_start regex was
100% correct (71/71 vs. an independent grep), but the real pipeline's
named function list only captured 15/71 of them, with bogus
body/impact numbers on top.

Routes dockerfile to Mode A (_slice_by_labels), the same
greedy-to-next-match heuristic already proven for abap/cobol/fortran/
assembly -- correct here since every Dockerfile instruction really
does end at the next instruction. Verified against the full
~80-repo crucible corpus (function_count now matches struct_func_start
exactly everywhere, including a 5th real occurrence outside the
dockerfile corpus itself), both golden masters re-blessed.

Also updates docs/self_scan/manual_verification.json,
tri_comparison_chart.svg/points_of_interest.md, and adds
docs/language_status/dockerfile.md with the full verification writeup
(including why no `class` entry was added -- named build-stage
extraction doesn't exist yet, tracked as #1974 -- and two narrower
follow-on issues found along the way, #1972 and #1973).

Fixes case found via the tri-comparison-ledger-sweep skill's
manual-verification fallback for gg-only languages.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@squid-protocol
squid-protocol enabled auto-merge (squash) August 21, 2026 00:03
…tart-mode-a-routing

# Conflicts:
#	docs/self_scan/tri_comparison_chart.svg
#	docs/self_scan/tri_comparison_ledger.json
#	docs/self_scan/tri_comparison_points_of_interest.md
#	tests/golden_master_audit.json
#	tests/golden_master_zero_dep_audit.json
…kerfile fix)

Resolves the merge conflict from #1968 landing on main after this
branch forked -- both touched golden_master_audit.json /
golden_master_zero_dep_audit.json / tri_comparison_chart.svg /
tri_comparison_ledger.json / tri_comparison_points_of_interest.md.
Regenerated fresh against the fully merged code (both apex's new
ClassName( exclusion and dockerfile's Mode A routing fix) rather than
hand-merging the generated files. crucible_check.py passes clean
(full_precision + zero_dependency) against the merged state.
@squid-protocol
squid-protocol merged commit b7a9396 into main Aug 21, 2026
26 of 27 checks passed
@squid-protocol
squid-protocol deleted the fix/dockerfile-func-start-mode-a-routing branch August 21, 2026 00:44
@github-actions

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

Severity Count
🔴 Critical 0
🟠 High 0
🟡 Medium 0
🟢 Low 0
ℹ️ Info 3

ℹ️ Info Findings

[checkov] Ensure that a user for the container has been created

File: /docs/language_status/dockerfile.md:1
Rule: CKV_DOCKER_3
Ensure that a user for the container has been created

[checkov] Ensure that HEALTHCHECK instructions have been added to container images

File: /docs/language_status/dockerfile.md:1
Rule: CKV_DOCKER_2
Ensure that HEALTHCHECK instructions have been added to container images

[checkov] Ensure the base image uses a non latest version tag

File: /docs/language_status/dockerfile.md:157
Rule: CKV_DOCKER_7
Ensure the base image uses a non latest version tag

🐦‍⬛ Powered by Muninn · Skald Lab

squid-protocol added a commit that referenced this pull request Aug 21, 2026
…1987)

* Fix jcl and m4 func_start recall: route to Mode A, not brace search

Same bug shape as dockerfile (#1976): jcl and m4 have no
ScopeParsingRegistry entry and no brace-delimited bodies at all, so
they silently fell through to Mode_B_Braces in _function_slice --
which only produces a named function when a literal { happens to
appear by coincidence within its search window.

jcl's func_start matches "// <name> EXEC ..." job-step lines -- JCL is
fixed-column mainframe syntax with no brace concept anywhere. m4's
func_start matches define(...)/m4_define(...)/AC_DEFUN(...) etc. --
macro definitions are parenthesis-delimited with backtick/bracket
quoting, not brace-delimited.

Confirmed via direct measurement (struct_func_start, the raw signal,
vs. function_count, the named list actually reaching consumers):
  jcl: 3 raw matches, 0 reached the named list (0% recall)
  m4:  39 raw matches, 1 reached the named list (2.6% recall)

Routes both to Mode A (_slice_by_labels), the same greedy-to-next-
match heuristic already proven for abap/cobol/fortran/assembly/
dockerfile. Post-fix: both hit 100% recall in the local corpus (3/3,
39/39). makefile was also flagged as a candidate in the same
investigation but its corpus sample was inconclusive (1 match total)
-- deliberately left untouched, not part of this fix's scope.

Verified against the full ~80-repo crucible corpus (both golden
masters re-blessed; drift is real function-count/structural-mass
changes in jcl/m4 files plus expected global spatial-layout ripple
across the corpus, not corruption elsewhere).

Fixes #1975.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Gemini 3.1 Pro <noreply@google.com>

* Regenerate golden masters against merged main (#1985 + jcl/m4 fix)

---------

Co-authored-by: Joe Esquibel <squid-protocol@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Gemini 3.1 Pro <noreply@google.com>
squid-protocol added a commit that referenced this pull request Aug 21, 2026
…#1994)

checkov's Dockerfile checks (CKV_DOCKER_2/3/7 -- missing HEALTHCHECK,
no non-root USER, base image uses :latest) match this file purely
because its filename contains "dockerfile", then parse plain English
documentation prose (describing what GitGalaxy's regex detects, e.g.
the words "HEALTHCHECK"/"USER") as if it were literal Dockerfile
instructions. It's a Markdown coverage doc with no fenced code blocks
at all, added in #1976.

Confirmed as the actual cause of muninn failing on every push to main
since #1976 merged (last green run: 68c2b01 at 23:03:49; first red
run: b7a9396, #1976's own merge commit, at 00:44:19) -- not a
pre-existing, unrelated flakiness as it initially looked.

Co-authored-by: Joe Esquibel <squid-protocol@users.noreply.github.com>
squid-protocol added a commit that referenced this pull request Aug 21, 2026
)

Dockerfile now earns badges on both Functions Found (71/71**, from
#1976) and Classes Found (77/77**, from #1974 -- new manual_verification.json
class entry, independently re-verified against real source: all 6
aliased stages in generate-files.Dockerfile, the 1 unaliased fallback
in syscall.Dockerfile, and the first/last 5 of daemon.Dockerfile's 69
stages). Args Found correctly drops from 52 (the #1973 bug, now fixed)
to 0, matching dockerfile's none-granularity expectation.

Also applies a validated verdict to a new ledger shape the regen
surfaced: fortran/function/args/agree[ctags,tree_sitter]_vs[gitgalaxy]
(init_domain, 1 occurrence) -- the same match.start()-corruption bug
already root-caused and filed as #1982 while investigating #1973,
just now visible in the ledger's own cross-tool tracking. No credit/
debit -- ctags and tree-sitter are both correctly parsing real Fortran
grammar GitGalaxy currently mis-anchors, not corroborating each other
by coincidence.

Updates docs/language_status/dockerfile.md's §9 to reflect all three
follow-on issues (#1972, #1973, #1974) as fixed rather than filed.

Co-authored-by: Joe Esquibel <squid-protocol@users.noreply.github.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