Skip to content

Meta: Go / cgo / Go+C extraction — tracking issue #1932

Open

Description

@ilyabrykau-orca

Tracking issue for the Go / cgo / Go+C extraction work. Method: count a construct in source, count the same thing in the graph, treat any mismatch as a defect. Every item was minimised to a dummy fixture before filing, measured on one real Go + C/C++ repository (~1150 Go files, eBPF C probes, a Windows C++ driver — counts only), and carries a SQL detection recipe that works on any indexed repo. Each fix PR ships a reproduce-first test (RED proven before the change) and a fresh field census on the same tree.

Ledger — bugs

Issue Defect PR State Measured effect
#1906 Weak short-name strategies fabricate CALLS for Go selector calls #1907 approved on shape; direction accepted 2026-09-03 on maintainers' k8s census; rebased onto current main (memory-core), suite green suffix_match 3817 → 113, same_module 3267 → 224; weak share of CALLS 36.0% → 12.4%, lsp_* 8481 → 10672 (re-resolved, not deleted)
#1909 Method QNs ignore the receiver — same-name methods collapse onto one node #1913 direction accepted 2026-09-03 (maintainers ran their own k8s census, 150-edge hand-classification); go_lsp caller-QN join gap fixed in-PR; rebasing behind #1907; 377-loss instrument answered on-thread Close methods 15 → 86; stack census: LSP strategies end above baseline (lsp_direct 8896 → 9130), same_module 931 → 117
#1910 Multiple init() per package collapse onto one QN #1915 ordinal suffix implemented on review feedback; rebase held per maintainer until #1907/#1913 land init nodes 7 → 29; stability pinned by test
#1926 cgo's import "C" resolves to an arbitrary project symbol named C #1931 open, CI green; maintainer verified the 27-edge symptom is already gone on main via #1938's Strategy-3 gate — description updated to lead with the import-map effect 27 false IMPORTS (pre-#1938) → 0 on current main; remaining effect: pseudo-package removed from the per-file import map
#1927 field_type_hint binds by receiver variable-name substring, not declared type #1936 open; rebase held per maintainer until #1907/#1913 land; stack census: trims field_type_hint 1205 → 186 on the stack head 1484 → 356; single-char receivers 376 → 0; Go→C/C++ 34 → 0; zero relocation
#1928 USAGE/WRITES/READS never consult the #725 cross-language guard (both resolvers) #1937 merged (fcd8bfc1), issue closed Go→C/C++ WRITES 835 → 0, USAGE 1545 → 0; 6432 cross-language refs dropped, none same-language; CALLS/IMPORTS byte-identical
#1934 A Go import can resolve to a Function/Method (Strategies 1b + 3 are language-blind) #1938 merged (8d7d3892), issue closed IMPORTS targets: Method 85 → 0, Function 4 → 0, Folder 2206 kept
#1935 Go struct fields never extracted (find_class_body stops one level above field_declaration_list) #1940 merged (61de19bb), issue closed 0 → 4533 Field nodes with declared types; blank _ padding skipped
#1942 A bare Go reference binds a struct Field (found field-validating #1940) #1944 merged (20e86c02), issue closed; follow-up #1962 USAGE onto Go fields 21308 → 0, WRITES 5191 → 0
#1962 #1944 guard was a blanket veto (dot-check inert): is_member_access recorded at extraction, guard keys on selector shape #2006 merged (192f2960), issue closed census: Field-ref edges 0 → USAGE 8503 / WRITES 1368, 2220/4497 fields reached

Combined stack (#1937 + #1940 + #1944) vs main: USAGE 29198 → 21035, WRITES 2681 → 774, +4533 field nodes — the graph gets nodes and loses junk edges.

Ledger — design-shaped (awaiting maintainer ack, no PR)

Issue Gap Damage
#1911 Build-tag twin files collide on one QN — draft PR #1946 (τ #-suffix, #495 pattern), ready on design ack 2177 τ-suffixed nodes / 372 files; swallowed-twin files 319 → 281; CALLS +62 — no edge-mass loss
#1929 cgo invisible — draft PR #1947: //export → 22 export_linkage contracts (exact), C.* CALLS 1 → 0, preamble flagged in coverage; C-grammar preamble parse stays open 39 call-shaped C.f( → 0 CALLS; 12 preamble functions → 0 nodes on main
#1930 Go chan/goroutines unmodelled — draft PR #1949: grammar-precise send/receive/select → gochan topology Channel nodes 2 → 205, EMITS 1 → 162, LISTENS_ON 2 → 256 on the measured repo; range/go/element-types deferred

Ledger — CI

Issue Problem PR State
#1952 test-windows-guards setup flake (nodes: None): counts read from list_projects, whose stats publish asynchronously — the index response carries them synchronously #1958 merged, issue closed
#1959 CI never indexes Go end to end — the only binary-level harness fixtures are TS-only, which is where this whole defect family hid #1961 (stacked on #1958) merged, issue closed; polyglot fixture (structs, build-tag twins, cgo, channels) + Go-definition count in the path-equality gate; measured 28/46/12 defs, go=7, equal across ASCII/Latin-1/Cyrillic

Merge order

Cross-cutting theme

One failure mode at every layer: a heuristic binds by name shape and nothing checks the language or what the name can denote. #1906 (CALLS, guarded) → #1927 (field_type_hint, exempted on a false premise) → #1928 (references, never guarded) → #1934 (imports, label-blind) → #1942 (references, label-blind). Guarding one relocates mass to the next unguarded one — which is why every fix PR above now carries negative/exact-count probes (ei_edge_count_is, zero-project-edge assertions, parallel-twin fixtures) rather than floor-only asserts, closing #1932's original test-infra gap in place.

Verified working (audit surface closed, no issues needed)

Generics (receiver-qualified QNs unwrap generic_type; no [ in any QN) · embedding + interface dispatch (lsp_embed_dispatch 42, lsp_interface_dispatch 79, fan-out via 434 IMPLEMENTS) · //go:linkname (body-less decls get nodes; callers bind lsp_direct) · defer/closures (attributed to the enclosing named function) · implicit interface satisfaction + method values (lsp_callable_alias) · TESTS edges and Variable coverage · internal import resolution (2206/~2242 same-module imports → correct package Folder; residual was #1934). Assembly (.s): untested — no fixtures in the measured repo.

Detection recipes (run on any indexed repo)

-- call-graph shape
SELECT json_extract(properties,'$.strategy') AS strategy, count(*) AS n,
       round(avg(json_extract(properties,'$.confidence')), 3) AS conf
FROM edges WHERE type='CALLS' GROUP BY 1 ORDER BY n DESC;

-- node recovery vs source: grep -rc '^func init()' --include='*.go' .
SELECT count(*) FROM nodes WHERE name='init';

-- swallowed twins: a file whose only node is its own __file__
SELECT file_path, count(*) c FROM nodes GROUP BY 1 HAVING c = 1;

-- cross-language reference edges (any Go↔C/C++ row is suspect)
SELECT e.type, count(*) FROM edges e
JOIN nodes s ON s.id=e.source_id JOIN nodes t ON t.id=e.target_id
WHERE s.file_path LIKE '%.go'
  AND (t.file_path LIKE '%.c' OR t.file_path LIKE '%.h'
    OR t.file_path LIKE '%.cpp' OR t.file_path LIKE '%.hpp')
GROUP BY 1;

-- references onto Go fields (must be zero: field access is selector-only)
SELECT e.type, count(*) FROM edges e JOIN nodes t ON t.id=e.target_id
WHERE t.label='Field' AND t.file_path LIKE '%.go'
  AND e.type IN ('READS','WRITES','USAGE') GROUP BY 1;

-- Go import targets (anything not Folder/Module/File is false)
SELECT t.label, count(*) FROM edges e
JOIN nodes s ON s.id=e.source_id JOIN nodes t ON t.id=e.target_id
WHERE e.type='IMPORTS' AND s.file_path LIKE '%.go' GROUP BY 1;

Every census lives inline in its issue's body (and in the fix PR's description); issues in this family are self-contained.

Related work in other ecosystems: #1893 (Swift, method-QN class), #1276 (Python, closed), #495 (Rust cfg twins — the pattern #1911 wants), #725 (cross-language CALLS guard), #1114 (dispatch fan-out), #787 (file attribution).

Activity

  1. added
    taskUmbrella task grouping multiple related issues
    priority/normalStandard review queue; useful PR with ordinary maintainer urgency.
    and removed
    windowsWindows-specific issues
    on Sep 3, 2026
  2. DeusData commented on Sep 3, 2026

    @DeusData
    Owner

    Thank you for maintaining this as an evidence ledger rather than an umbrella implementation.

    I have classified it as a tracking task and removed the unrelated Windows label. The individual issues and PRs remain the authoritative places for design decisions, review, and closure, while this thread can continue to show measured interactions and merge ordering across the Go/cgo work.

    The source counts, graph counts, and negative-edge checks make this genuinely useful coordination material. Thank you for keeping each defect self-contained underneath it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    parsing/qualityGraph extraction bugs, false positives, missing edgespriority/normalStandard review queue; useful PR with ordinary maintainer urgency.taskUmbrella task grouping multiple related issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions