mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-09-08 22:22:52 +00:00
Found by a three-agent investigation into an A1 regression. The
regression was the symptom; this is the disease, and it SHIPPED on this
branch.
Go's `@reference.read` pattern matches every `selector_expression` with
no call-position exclusion, so `h.dep.Work()` minted THREE sites:
call Work on the call_expression — the member call
read Work on the outer `h.dep.Work` — PHANTOM, this is the callee
read dep on the inner `h.dep` — the genuine field read
The phantom resolves through `findOwnedMember`, which prefers methods
over fields, and emits an ACCESSES edge to the METHOD duplicating the
CALLS edge at the same position.
MY U8 CLAIM WAS WRONG. I asserted that typing the base made the ACCESSES
"correctly retarget to the property". It did not. The property edge was
always a separate site, and the U8 test passed by ACCIDENT: the row it
asserts on has a pointer receiver whose text-cascade lookup failed for an
unrelated reason. The value-receiver twin was emitting the bad edge the
whole time — verified on the pushed branch:
ACCESSES RunFromValueReceiver -> DoWork:Method
ACCESSES RunLocal -> DoWork:Method
A selector in FUNCTION position is never a read. Dropped at the emitter.
A method VALUE (`f := h.dep.Work`) is not in function position and is
untouched.
Deliberately NOT fixed by gating on `handledSites`: the three co-located
Go sites share one site key, so that would suppress the correct
`RunSamePackage -> dep` edge depending on match order. Nor by flipping
`findOwnedMember` to prefer fields on reads — that is cross-language and
would break legitimate method-value reads.
The weak assertion is replaced by an exact-set check over the whole
fixture, so a new phantom fails even on a row nobody wrote a targeted
assertion for. My first attempt at that check compared `undefined ===
undefined` and would have passed against anything; caught and rewritten.
Numbers:
callDrops 102 -> 102 no call lost
read drops 27 -> 22 five phantoms were being RECORDED AS DROPS
chain-field 61 -> 60 one reclassified...
chain-unwrap 0 -> 1 ...to the real call's shape, because the
phantom and the call share a site key and the
phantom's chain was the one being censused
Baselines: go scope-capture fingerprint and the go capture golden
rebaselined with reasons — fewer capture matches for Go, and go was the
only fingerprint of 15 that moved, which is the check that this touches
Go's emitter alone. 4369 tests green.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| baselines.json | ||
| measure.mjs | ||