Repository navigation
Fix stale go.work vendor warning for members (#1766) - #1767
Conversation
Assisted-by: Claude Code:claude-opus-5-5
After rollback or remove in a go.work member other than the workspace root, socket-patch stayed silent about the vendor/modules.txt line that `go work vendor` had recorded for the patch. Every workspace build then failed with "inconsistent vendoring" while both commands exited 0. `go work vendor` writes a member's replace relative to the go.work directory (./a/.socket/go-patches/...), and the stale check only treated root-relative .socket paths as socket-owned. The audit now resolves a recorded path against the go.work directory and treats it as ours when it lies under any member's .socket copy directories. A user's replace onto another checkout (../sibling/.socket/...) stays user-owned. Adds unit tests (go-patches and vendored copies, nested and out-of-tree members) and a real-go e2e covering rollback and remove. Fixes #1766 Assisted-by: Claude Code:claude-opus-5-5
Review follow-up. The stale check compared a recorded workspace line with go.mod replaces by path suffix, so a stale ./a/.socket/... line still matched member b's ./.socket/... replace after a rollback in a and an apply in b. Both commands then stayed silent while the build failed "inconsistent vendoring". Each replace is now resolved against its own file's directory and compared with the recorded line resolved against the go.work (or go.mod) directory, as go does. A member whose go.mod cannot be read no longer makes its recorded lines look stale from other members. Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ 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 9376571. Configure here.
|
Ready for review at
Generated by Claude Code |
Final review briefWhat it does. In a Risk: low. The change only reads files and only decides whether an audit warning is emitted. Outside a workspace, Look here
Verified
Changes I made: none. Open questions (non-blocking):
Auto-merge is armed, so approving sends this straight to the merge queue. Generated by Claude Code |
…dor-stale-member # Conflicts: # crates/socket-patch-core/src/vendor/go_consumer_sync.rs
|
BugBot review Generated by Claude Code |
Bugbot is paused — your team has an unpaid invoiceBugbot is paused because your team has an unpaid invoice. Pay it from the billing page in the Cursor dashboard and Bugbot resumes automatically. (requestId: 1a13b573-aab2-4fb1-9eab-55a41a9bbe20) |
Main landed lighter fixes for the same go.work gaps this PR models in full: #1752 (version gate reads every member), #1753 (hosted pins outranked by another member), #1767 (stale go.work vendor warning) and the squashed #1748. Resolve them onto this PR's GoWorkspace model instead of keeping two workspace readers: - go_build_list: keep project_selection on GoWorkspace. Drop main's ModuleEvidence / workspace_selection / other_workspace_members and its three on-disk selection tests: GoWorkspace::selection covers those cases from the module graph (go_workspace tests), and without a module cache it answers Unknown by design. - hosted: drop #1753's go_members plumbing (engine RewriteOptions closure, rewrite_golang argument, CLI wiring). The PR's HostedGoWorkspace already refuses a pin another member outranks. Main's e2e test for it now seeds the module cache the workspace graph reads, and passes, including the rescan that removes the pin. - go_consumer_sync: port #1767's modules.txt audit (per-member replace resolution, member_owned, unreadable members skipped) onto go_workspace::load and its shared same_dir_key / lexical_target. - vex discover, CLI_CONTRACT, e2e_golang_hosted_build: keep the PR's stricter rules (a zip pin is checked against the workspace selection too; sum-file zip lines are no evidence of it). Co-Authored-By: Claude <noreply@anthropic.com>
Brings in the base's main merge (678f90e). It replaced go_consumer_sync's same_replacement with lexical_target comparison (main #1767), so the go.work modules.txt check here now compares the go.work replace and the recorded line the same way, both resolved against the go.work directory. Co-Authored-By: Claude <noreply@anthropic.com>
LLM Description written by Claude Code:claude-opus-5-5
Fixes #1766
Summary
In a
go.workworkspace,rollbackandremovein a member other thanthe root (
use ./a) now warngo_vendor_modules_txt_out_of_sync, andapply --checkexits 1, whenvendor/modules.txtstill records theremoved socket replace. Before this change both commands exited 0 with
no warning, and every workspace build then failed with
"inconsistent vendoring".
Root cause
vendor_modules_txt_issuesonly judged a recorded line stale whenReplaceEntry::socket_owned()held.detect_owneranchors that test atthe project root, by design.
go work vendorrecords a member'sdirectory replace relative to the go.work directory
(
./a/.socket/go-patches/…), so the line read as user-authored and wasnever checked. The forward ("not recorded") check got by on a loose
path-suffix match, and that match also let a stale
./a/…line pass asmember b's
./.socket/…replace.Fix (
crates/socket-patch-core/src/vendor/go_consumer_sync.rs)vendor/(the go.work or go.mod directory). Each go.mod/go.work replace resolves
against its own file's directory, and the two are compared as go joins
them (lexically). This replaces the suffix rule.
lies under any readable
usemember's.socket/go-patches/or.socket/vendor/golang/directory.detect_ownerstays root-anchored,so a user's
../sibling/.socket/…replace stays user-owned.unknown, so its lines are not reported stale from another member.
No docs change:
docs/ecosystems.mdalready documents this warning forgo work vendor. The npm, PyPI and gem wrappers don't touch this code.Test evidence
sub/aand out-of-tree../amembers)vendor::go_consumer_sync::tests::workspace_member_rollback_leaves_modules_txt_stalea .socket/go-patches/…: [], no issue reported)use ./consumer,go work vendor, rollback then remove,apply --check, rebuild)e2e_golang_build::go_work_vendor_member_needs_go_work_vendor_after_rollback_and_removeThe same unit test also covers the review follow-ups: a cross-member
same-spelling collision (a stale
./a/…line next to b's./.socket/…replace) and a member with an unreadable go.mod.
Local gates:
cargo fmt --all -- --check: cleancargo clippy --workspace --all-features -- -D warnings: cleanSOCKET_PATCH_GO_E2E_REQUIRED=1 cargo test -p socket-patch-cli --all-features --test e2e_golang_build: 28 passedcargo test --workspace --all-features: 15,076 passed, 12 failed. All 12 failures are environmental and outside Go code: 3 ine2e_bun_lockbfail identically onmainwith the local bun 1.4.4, and 9 write-failure, unremovable-lock or symlink-root tests (partial_lockfile_write_failure…,repair_cleanup_failure…,copy_tree::relax_loop…,pypi_*::wire_*failure…,vlt_healand similar) can't simulate permission denial because this sandbox runs as root. CI runs them unprivileged./code-review highwas run on the diff. Findings fixed: the suffix-matchfalse negative, the wrong-level ownership heuristic, the absolute-path
exclusion (cross-volume Windows members), false stale reports for
unreadable members, and the per-line clones and normalization. Not
fixed: the claim that the e2e comment is wrong ("rollback dropped the
manifest entry"). Rollback does remove the entry (see
rollback.rs, "remove … from the localmanifest"), and the test showed re-apply discovering 0 patches until the
patch was re-staged.
https://claude.ai/code/session_011f9aeSV7eaqPG4mX6fgBKB
Generated by Claude Code