GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Fix Go replace target missed in go 1.16 graphs (#1840) by mikolalysenko · Pull Request #1843 · SocketDev/socket-patch Conversation
|
| Issue / case | Test | Without fix | With fix |
|---|---|---|---|
| #1840 repro: fork required only by a dep, versionless and versioned replace | e2e_golang_build::fork_required_only_by_a_dependency_is_a_replace_target |
apply --check exit 0 "Patches are in sync" (build prints PRISTINE) |
refuses / exit 1 / not attested |
| #1840 unit: transitive fork in go 1.16 / no directive | go_build_list::tests::unpruned_replace_of_a_transitive_fork_is_a_replace_target |
fails (Selected) | passes |
| Stale fork replace must not block a working patch (review finding) | e2e_golang_build::stale_fork_replace_keeps_a_transitive_patch |
fails on the first (guess-only) commit: apply refused | apply 0, build PATCHED, check 0 |
| Graph settles raised/shadowed/stale forks; incomplete graph falls back safely | go_build_list::tests::unpruned_module_graph_settles_the_fork_replace, unpruned_root_require_of_another_version_keeps_the_fork_replace, only_a_pruned_go_mod_or_a_complete_graph_proves_a_replace_target, module_graph_is_needed_only_for_an_unpruned_fork_replace |
n/a (new API) | pass |
| Graph walk reaches a dep-only fork | go_workspace::tests::module_graph_reaches_a_fork_only_a_dependency_requires |
n/a | pass |
| Hosted rewriter uses the graph; an unproven guess keeps an existing pin | redirect::tests::golang_go116_module_graph_decides_the_fork_replace, golang_go116_suspected_replace_target_keeps_the_hosted_pin |
n/a | pass |
One existing assertion changed meaning. In inactive_replace_target_keeps_the_zip_as_evidence, the go 1.16 cases "fork not required" and "version-less replace shadowed at go.mod's required version" encoded the bug: go.mod alone can't show the fork is absent, or that a dependency didn't raise it. They now run only for go 1.21. The go 1.16 behavior is covered with and without a graph in unpruned_module_graph_settles_the_fork_replace.
Commands run locally (Linux, go 1.24.7):
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleancargo test -p socket-patch-core --all-features: 6999 passed, 4 failed. The 4 failures are chmod-based write-failure tests (copy_tree, vlt_heal, pypi_poetry, pypi_requirements) that can't fail as root (this container runs as uid 0). They're unrelated to Go, and none of their modules is touched by this PR.cargo test -p socket-patch-cli --all-features --lib plus every Go-touching suite with SOCKET_PATCH_GO_E2E_REQUIRED=1: e2e_golang_build (33), e2e_golang_hosted_build (25), e2e_golang_workspace_build (31), e2e_vendor_golang_build (44), e2e_golang, e2e_golang_hosted_state, e2e_vex, e2e_vex_redirect, e2e_vex_vendor, ecosystem_dispatch_e2e, in_process_*, cli_apply_silent: all pass.cargo test --workspace (189 CLI test binaries) doesn't fit this container's disk, so CI covers the rest.exclude directives aren't applied by the graph walker. That's the same pre-existing limitation as go.work mode. An excluded fork version can only make a patch refused, never falsely attested.project_selection: the graph is read only for a module that an unpruned go.mod's fork replace targets (needs_module_graph), not for every patch.let in_effect = …; in_effect in replaced_module is required: the iterator borrows entries, a local, so it can't be the tail expression (E0597). Clippy is clean.Out of scope: GoWorkspace::selection never returns ReplaceTarget, so the #1823/#1840 shapes inside a go.work workspace aren't detected. That's pre-existing and not part of #1840.
https://claude.ai/code/session_011f9aeNyyce3TLFE4vQrpsJ
Generated by Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Assisted-by: Claude Code:claude-opus-5-5
In a go 1.16 module, when a dependency imports a fork that the root go.mod replaces with the patched upstream module, apply reported the patch applied, apply --check said in sync and vex attested not_affected, while go build linked the unpatched code. The root go.mod of an unpruned graph does not list modules that only a dependency requires, but its replace still applies to them. The replace-target check only trusted a fork listed in the root require, so it missed this shape. Now, in an unpruned graph, such a replace counts as in effect unless go.mod requires the patched module itself. Fixes #1840 Assisted-by: Claude Code:claude-opus-5-5
The first fix guessed that a fork replace in a go 1.16 module is in effect whenever go.mod doesn't list the fork. That refused working patches when go mod tidy kept a replace nothing uses, and the hosted rewriter then removed a working Socket replace. It also missed a fork a dependency raises to the replaced version. Now, when an unpruned go.mod has a module-to-module replace, the module graph is read from the module cache, the same walk go.work projects use, and the fork's selected version decides. apply, apply --check, the hosted rewriter and VEX discovery all use it. When the cache lacks go.mod files, the safe answer stays: the patch is not reported built. Refs #1840 Assisted-by: Claude Code:claude-opus-5-5
Reading the go 1.16 module graph went around the project view, which ended read recording for every project: VEX discovery asked for the raw disk root even with no Go files, so discovery could no longer be reused between passes. Now the graph is read only when go.mod needs it, and the root go.mod and any directory replacement's go.mod are declared as reads, so a change to them still invalidates the cache. Refs #1840 Assisted-by: Claude Code:claude-opus-5-5
Without every go.mod of a go 1.16 module graph in the module cache, a fork replace is only suspected of bypassing the Socket pin. That guess now refuses a new pin but no longer removes an existing one that may be working. A partial graph is no longer trusted as proof that the fork is at a lower version. Socket's own hosted replaces no longer trigger a graph walk. Refs #1840 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Stale Bugbot comment from a previous run.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Burn-down agent: labeled Ready for review at
Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Final review briefWhat it does. In a go 1.16 (unpruned) module, a root Risk: medium. It changes the selection rule that Look here
Verified
Changes I made: none. Open questions: none blocking. The PR body lists known non-goals: Auto-merge (squash) is armed, so approving sends it straight to the merge queue. Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
[agent] Heads-up: #1893 (fix for #1862) is stacked on this branch; it reuses the Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
[agent] Reviewed 4e9eebf6171c934fc22bd3f3672e94156ff33cd4. Traced unpruned Go replacement targets through cached dependency graphs, hosted rewriting, local apply and VEX, including incomplete-graph conservatism. No major correctness issues found. Validation: source and regression-test review plus the available exact-head CI checks; no local test pass is claimed.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
…-replace-target # Conflicts: # crates/socket-patch-cli/tests/e2e_golang_build.rs
|
BugBot review Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 9e958e5. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
[agent] The merge queue dropped this PR on a conflict in Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
[final reviewer] Re-added to the merge queue at Generated by Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
#1843 landed on main with the module-graph plumbing this branch was built on, so the four Go files conflicted. Keep this branch's go.sum aware may_need_module_graph/needs_module_graph and the moved module graph read in vex discover; take main's stage_with(tmp, "1.16") signature in the e2e test and update this branch's two new callers. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
Go apply, apply --check and vex still treat a replace-target module as built when the replaced fork is required only by a dependency (go 1.16 module), so the patch is attested while the build stays unpatched
There was an error while loading. Please reload this page.