Status: fix open — PR #1915 (file-stem+line #-suffix QNs for Go init, #495 pattern; stacked on #1913). Post-fix: init nodes 7 → 29, matching source exactly (source count: 29).
Version
codebase-memory-mcp 0.10.8 (also reproduced on a source build @ d706c33)
Platform
macOS (Apple Silicon)
Install channel
Built from source
Binary variant
standard
What happened, and what did you expect?
Go allows any number of func init() per package (several per file included); all run at program start. Every one gets the same QN (proj.pkg.init), so the upsert keeps one node per package and silently drops the rest with their bodies.
Measured: an event-source package registering each decoder in its own file's init() — 21 init functions collapsed into 1 node; repo-wide 29 in source, 7 in the graph. The registration topology (which decoder handles which event) is invisible; the surviving node's edges are a blend of merged bodies.
Reproduction
// a.go
package reg
var handlers = map[string]func(){}
func init() { handlers["a"] = handleA }
func handleA() {}
// b.go
package reg
func init() { handlers["b"] = handleB }
func handleB() {}
Actual: one node reg.init (a.go); b.go's body and its handleB edge gone or misattributed. Expected: two nodes.
Fix (existing #495 pattern)
Rust cfg twins already fold a #-suffix into the QN (rust_cfg_qualified_name); GoogleTest macros derive unique names (#1266). Same move: proj.pkg.init#a.go:L5, mirrored on the call-scope side. Nothing joins on the plain QN — calling init explicitly is illegal in Go — so no resolution path is affected.
Related: #1909, #1911 (same silent-upsert-collapse family); tracked in #1932.
Confirmations
Status: fix open — PR #1915 (file-stem+line
#-suffix QNs for Goinit, #495 pattern; stacked on #1913). Post-fix:initnodes 7 → 29, matching source exactly (source count: 29).Version
codebase-memory-mcp 0.10.8 (also reproduced on a source build @ d706c33)
Platform
macOS (Apple Silicon)
Install channel
Built from source
Binary variant
standard
What happened, and what did you expect?
Go allows any number of
func init()per package (several per file included); all run at program start. Every one gets the same QN (proj.pkg.init), so the upsert keeps one node per package and silently drops the rest with their bodies.Measured: an event-source package registering each decoder in its own file's
init()— 21initfunctions collapsed into 1 node; repo-wide 29 in source, 7 in the graph. The registration topology (which decoder handles which event) is invisible; the surviving node's edges are a blend of merged bodies.Reproduction
Actual: one node
reg.init(a.go); b.go's body and itshandleBedge gone or misattributed. Expected: two nodes.Fix (existing #495 pattern)
Rust cfg twins already fold a
#-suffix into the QN (rust_cfg_qualified_name); GoogleTest macros derive unique names (#1266). Same move:proj.pkg.init#a.go:L5, mirrored on the call-scope side. Nothing joins on the plain QN — callinginitexplicitly is illegal in Go — so no resolution path is affected.Related: #1909, #1911 (same silent-upsert-collapse family); tracked in #1932.
Confirmations