fix(extract): give Go build-constrained twin files distinct QNs - #1946
fix(extract): give Go build-constrained twin files distinct QNs#1946ilyabrykau-orca wants to merge 1 commit into
Conversation
|
Thanks for opening this — it has been seen, and it is queued. This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence. Current review status: working through a backlog. What that means for this PR, concretely:
Things that will genuinely speed it up whenever review does happen:
If this fixes a bug, a reproduction we can run is worth more than a description of the symptom. Thanks for contributing, and sorry in advance for the wait. |
Go build-constrained twin files (//go:build lines, GOOS/GOARCH filename suffixes) legally define the same symbols in one package. The indexer ignored the constraints, so the graph upsert kept ONE node per QN by the smallest-file-path rule: a 2-line stub beat the 63-line real implementation and took all 25 inbound CALLS; a bpf2go GOARCH twin pair lost 39 of 40 nodes; parse coverage stayed clean so nothing flagged it. Fold the per-file build constraint tau into Go func/method QNs with the same #-suffix move Rust cfg twins got in DeusData#495: tau is the compacted //go:build expression when present, else the official GOOS/GOARCH filename suffix (cbm_go_build_tau in helpers.c, computed once per file in cbm_extract_file). The scope builder mirrors the def formula (go_tau_scope_qn) so body calls in constrained files stay attributed. Types and vars stay plain, keeping parent_class / DEFINES_METHOD joins intact. Two #-aware seams make the suffixed defs resolvable (both also close a latent gap for Rust cfg twins, which already carry such QNs): - cbm_registry_add indexes the simple name as the part before '#' (identifiers cannot contain one), so callers keep resolving by name. - The LSP registry's exact pkg.name lookup falls back to a SOLE #-suffixed variant (lookup_func_sole_tau_variant) - the dominant real-world shape is a constrained file with no in-tree twin, and its callers must keep their lsp_direct/lsp_strategy_cross_file edges. Two or more variants are genuinely ambiguous without the caller's build configuration and fail closed; tau-aware preference for the caller's own constraint is the declared follow-up. The pipeline's LSP-join leaf gate learns the same rule. Reproduce-first tests: extract_go_buildtag_tau_in_func_qns (//go:build compaction, GOOS_GOARCH and _test filename forms, types stay plain, unconstrained files carry no '#') and pipeline_go_buildtag_twins_both_survive (RED on main: count_nodes_named == 1, expected 2; plus the sole-variant caller edge staying alive). 854 tests green across extraction/pipeline/registry/ lsp probes/go_lsp/parallel suites. Part of DeusData#1911 (minimal PR: QN disambiguation; tau-aware same-module resolution is the follow-up) Signed-off-by: Ilya Brykau <ilya.brykau@orca.security>
|
CI retrigger (no-op amend): |
d4c7f01 to
dcbb7fd
Compare
Part of #1911 — draft implementation-proposal: this changes what gets extracted (Go func/method QNs in build-constrained files), so per CONTRIBUTING it's opened as a draft for design review; the design is the one proposed in the issue body (the #495 Rust-cfg
#-suffix pattern). Will mark ready on a maintainer design ack.What
Build-constrained twin files (
//go:buildlines, GOOS/GOARCH filename suffixes) legally define the same symbols; the upsert kept ONE node per QN by the smallest-file-path rule — a 2-line stub beat the 63-line implementation and took all 25 inbound CALLS; a bpf2go GOARCH twin pair lost 39/40 nodes; coverage stayed silent.How
//go:buildexpression, else the official GOOS/GOARCH filename suffix (cbm_go_build_tau, computed once per file). Folded into func/method QNs (MirrorConfig#unix), mirrored on the call-scope side (go_tau_scope_qn) so body-call attribution stays exact. Types/vars stay plain — parent_class/DEFINES_METHODjoins keep working.#-aware seams make suffixed defs resolvable (both also close a latent gap for Rust cfg twins, whose QNs already carry#):cbm_registry_addindexes the simple name as the part before#(identifiers cannot contain one);pkg.namelookup falls back to a sole#-suffixed variant (lookup_func_sole_tau_variant) — the dominant real-world shape is a constrained file with no in-tree twin, and its callers keep theirlsp_direct/lsp_strategy_cross_fileedges. Two+ variants are genuinely ambiguous without the caller's build configuration and fail closed. The pipeline's LSP-join leaf gate learns the same rule.Scope (deliberately the issue's "minimal PR")
QN disambiguation only. τ-aware resolution (preferring the caller's own constraint, and
module.name#τsame-module keys) is the declared follow-up — unconstrained callers of a genuine twin pair currently resolve as ambiguous rather than binding an arbitrary twin, which is strictly better than today's bind-everyone-to-the-stub.Tests (reproduce-first)
extract_go_buildtag_tau_in_func_qns://go:build linux && amd64→#linux&&amd64,_windows_amd64.go→#windows_amd64,_linux_test.go→#linux, types stay plain, unconstrained files carry no#. RED on main.pipeline_go_buildtag_twins_both_survive: RED on main (count_nodes_named == 1, expected 2); GREEN with both twins as nodes AND a sole-variant caller edge staying alive (UseFlush → FlushDisk#linux,lsp_strategy_cross_file@ 0.92).scripts/test.shvenue leg green;git clang-format --diffclean.Field census
Pending: the validation index of the reference Go+C repo is currently blocked by a live-daemon rendezvous conflict on this machine (isolated-HOME one-shots get
conflicting CBM process is active); numbers (bpf2go twin-pair node recovery 43+1 → ~86,Close63 → 66, CALLS deltas) will follow as a PR comment once it clears. Expected shapes are in #1911's body.#1932 tracks the family.