Repository navigation
Code Analysis Go Rust Investigation Batch
Draft, not merged: #1290, head 021a3898a, base codex/go-rust-batch-baseline (70bdf0227, merge of Go #1285 and Rust #1288). Review order: #1289 merges both baselines; this PR targets that merged branch. Started from the reviewed head ac36a4ab0. No merge, no labs/code-analysis update, no live installation.
This stage reproduces and fixes a wrong Rust target, extends generic field receivers and defaulted owner methods, keeps Go interface evidence for external embedded methods, and re-runs the same 20 real questions on both revisions. Every number below comes from the same query set, sample roots and call positions.
On real Go and Rust changes, does the normal change query answer four things: which definition changed, who directly calls it, which calls only prove an interface/trait declaration, and where can the reader verify the call in source?
| Line | Commit | Meaning |
|---|---|---|
| Batch base | 70bdf0227 |
merge of Go #1285 and Rust #1288 |
| Reviewed head / stage baseline | ac36a4ab0 |
Rust v7 / adapter 7, Go v3 / adapter 6 |
| Candidate | 021a3898a |
Rust v8 / adapter 8, Go v4 / adapter 6 |
Remote state was re-checked at the end of the stage: #1290 Draft, base #1289 still at 70bdf0227 and unmerged; origin/labs/code-analysis still bf0a29e76 (2026-11-04); origin/main advanced only with DSH docs (#1291/#1294) and has no archify/modules/code-analysis change since branch point 654da74e0.
Sample trees are independent git worktree checkouts at fixed base/head commits. No project build or test was executed. Go used Go 1.27.2, default GOOS/GOARCH, cgo disabled. clap, tracing, ripgrep and bytes were read with a generated Cargo.lock because the extractor uses --locked.
Twenty cases and 86 expected call positions: the earlier 12 (still exactly 73 positions, unchanged) plus 8 new/frozen cases (13 positions). New repositories relative to the 12-case batch: spf13/cobra, labstack/echo, urfave/cli, BurntSushi/ripgrep, tokio-rs/bytes. Thirteen new base/head groups plus two regression groups; two questions from one pair count once.
| Group | Cases |
|---|---|
certmagic 16c9db14→1a2275d5
|
certmagic-load, certmagic-store |
certmagic 2d114193→9a56fcd4
|
certmagic-interface, certmagic-interface-load (reserved Go) |
gin 8d0468f7→d75fcd4c
|
gin-close, gin-hijack |
clap b55ebc9f→67202405
|
clap-any-value-parser, clap-typed-value-parser (reserved Rust) |
tracing d3eb109e→f42e7e6d
|
tracing-layer-event-enabled, tracing-subscriber-event-enabled |
raft d3c91249→a2e87783
|
raft-stage-commit-index |
cobra f2878bab→746ef071
|
cobra-get-completions |
echo 4f7bea5d→29682401
|
echo-remove-custom-method (reserved Go) |
cli d854bb40→ca8f45a9
|
cli-wrap-line |
ripgrep 4c2362d3→7155f640
|
ripgrep-file-name |
ripgrep 1752fb78→6892bc2b
|
ripgrep-parent-key |
bytes 002df10b→d5c8ad32
|
bytes-truncate-zero (reserved Rust) |
bytes d5c8ad32→7930d93d
|
bytes-try-get-int |
http c6af28b→3dd9f5e
|
http-insert-occupied-mult (regression) |
rust-base64 a8a60f43→9e9c7abe
|
base64-inner-decode (regression) |
Reserved answers were frozen by reviewers reading only upstream source/diff, before any candidate run. echo-remove-custom-method and bytes-truncate-zero matched other frozen keys.
| Scope | Definitions | Baseline found/wrong/missed | Candidate found/wrong/missed/extras |
|---|---|---|---|
| All 20 cases | 20/20 | 66/1/20 | 78/0/8/2 |
| Go (10) | 10/10 | 57/0/5 | 62/0/0/0 |
| Rust (10) | 10/10 | 9/1/15 | 16/0/8/2 |
| New (14) | 14/14 | 47/1/18 | 58/0/7/1 |
| Regression (2) | 2/2 | 4/0/1 | 5/0/0/1 |
| Reserved Go (2) | 2/2 | 14/0/0 | 14/0/0/0 |
| Reserved Rust (2) | 2/2 | 1/0/1 | 1/0/1/0 |
+13 correct call positions, 1 wrong target removed, missed positions 20 → 8, no previously correct hit lost. Target display moved from 15 determined / 51 candidate / 0 unknown to 16 / 57 / 5; every candidate still carries runtimeTarget: "not-determined". The two extras are source-verified real calls omitted from the frozen keys, not false targets: base64 src/read/decoder.rs:146 calls through E: Engine; tracing tracing-subscriber/src/layer/layered.rs:295 calls through B: Layer<S>.
Remaining misses: clap type-erased parser and ok! argument (2), bytes default-method and &mut B forwarding (2), tracing macro body/closure/try_lock! (3), tracing feature!-gated fmt/mod.rs (1). None points at a wrong target.
fixtures/rust-local-asref is a cargo-checkable pair with a local trait AsRef<T> whose as_ref returns &Other and Wrap: AsRef<First>. The test proves rustc dispatches self.as_ref().enabled() to Other::enabled.
| Query |
ac36a4ab0 (v7) |
Candidate (v8) |
|---|---|---|
change Other::enabled
|
0 references | 2: src/lib.rs:32:9, 37:5 → line 11 |
change First::enabled
|
1 false reference: 32:9 → First::enabled:5
|
0 references |
The extractor now records trait method return hints, substitutes impl arguments, prefers a captured inherent accessor, accepts Deref::Target, and trusts std/core/alloc pointer semantics or aliases only when the path is proven. Otherwise the receiver stays unknown. Tests cover local same-name traits, std paths, aliases, inherent shadowing, Borrow/Deref, unresolved evidence, and renamed/swapped parameters.
-
Defaulted and unsupported generic owners. Impl where-clause bounds and default type parameters are recorded. Structs whose declarations cannot be modelled (defaults, where clauses, lifetimes) expose fields through
Binding::Fields, soHeaderMap<T = u8>andLayered<L, I, S = I>field receivers resolve. Tuple-variant bindings and inherent methods on defaulted owners resolve; direct-caller kind distinguishesfunction,methodandtrait-default-method. -
Go external embedded interfaces.
interfaceCompleteno longer rejects an interface because it embeds an external named interface. go/types still proves the implementation relation; the edge names the external package and method, and the query emits a candidate at each unresolved call site with no target and an explicit reason. Evidence modelcaptured-interface-implementations-v2;go-source-direct-v4/ revision 6. -
Coverage gates. v4/v8 models are accepted by the shared semantics, call-question and change-question gates; the schema accepts external interface edges and the
go-interface-external-methodreason.
-
Go, echo:
*routeMethods.setatrouter.go:226→ direct callrouter.go:860:2in(*node).setHandler(line 859), determinedgo-direct-method. The nil-producing(*DefaultRouter).Removecall atrouter.go:446is one indirect hop away; the tool does not expand transitive callers. -
Rust, bytes:
Bytes::truncateatsrc/bytes.rs:569→self.truncate(0)atsrc/bytes.rs:599:9inBytes::clear(line 598),rust-inherent-source-candidate. -
Go, gin interface:
*responseWriter.Hijackatresponse_writer.go:111→ test calls atresponse_writer_test.go:120:20,190:23,245:23; three interface candidates with no concrete target because the static method is externalnet/http.Hijacker.Hijack. -
Rust, AsRef:
Other::enabledat the fixturesrc/lib.rs:11←32:9,37:5; the baseline path pointed atFirst::enabled:5.
-
echo-remove-custom-method(reserved Go) matched exactly: definitionrouter.go:226, call860:2, callersetHandler:859method. -
bytes-truncate-zero(reserved Rust) matched exactly: definitionsrc/bytes.rs:569, call599:9, callerclear:598method. - Two readers who had not seen answer keys reproduced both keys from CLI output and source alone. Their reported gaps were display limits (no transitive callers, no argument analysis, tests outside the capture profile), not coordinate errors.
- A third reviewer, with no CLI and no answer key, re-froze the bytes reserved case from the two source trees alone: same definition
src/bytes.rs:569, same production call599:9, callerclear:598. Reports:evidence/readers.
-
node --test modules/code-analysis/test/*.test.mjs: 444 pass, 0 fail, 0 skipped. - Counterexamples: baseline 102/104 (two non-discriminative preservation checks on an already-wrong item); candidate 136/136 with all eight kinds covered. Of the candidate checks, 29 were not applicable because the mutation had no record to act on (8 delete-target, 9 promote-candidate, 10 omit-target-file, 2 wrong-declaration); the baseline had 20.
- Canonical ZIP
/tmp/archify-stage2.zip, SHA2565b3ee9f516b19c20004b36f32313f3650a820a446e6ca9d9907f89cb7e18e58e, built with official Node 22 / zlib1.3.1-e00f703, committed asarchify.zipinc10ea384c. - Fresh unpack +
npm cireplayed the AsRef fixture,gin-hijack,echo-remove-custom-methodandtracing-subscriber-event-enabled. Identitiesrust-syn@2.0.119rev 8 /rust-source-direct-v8andgo-parser@1.27.2rev 6 /go-source-direct-v4; positions matched the batch runs.fmt/mod.rs:402remains the documented miss. - Evidence:
evidence/stage2-baseline,stage2-final,comparison,asref-local,stage2-replay,readers; README has per-scope tables and commands. - CI run 42502359214 for head
021a3898acompleted successfully; only deploy jobs were skipped. PR stays Draft and unmerged.
Extend Rust source capture into macro bodies and arguments for calls whose receiver is otherwise identifiable. Four of the eight remaining misses come from macro_rules! layer_impl_body (layer/mod.rs:1609), try_lock! (reload.rs:139), ok!(...) (value_parser.rs:658) and the feature!-gated fmt/mod.rs:402. Source-level token scanning can recover them without a full macro-expansion or type-checking backend; the bytes forwarding misses remain a separate, smaller rule.