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(vendor): gem wiring reconstruction, dir-artifact file inventory, per-section lock remotes by mikolalysenko · Pull Request #179 · SocketDev/socket-patch Conversation
|
| Pin (fails without the fix) | Change |
|---|---|
e2e repair_reconstructs_gem_wiring_and_revert_byte_restores — reconstructed state.json byte-equal to the original; revert byte-restores Gemfile+lock, artifact gone (base: "wiring": [], revert exit 0 with stranded pair) |
gem wiring reconstruction |
e2e revert_of_empty_wiring_gem_entry_fails_loudly — exit 1, vendor_wiring_unknown named, artifact + files untouched (base: exit 0, artifact deleted) |
revert guard |
e2e repair_reconstruction_flags_unrecoverable_gem_checksum — vendor_checksum_unrecoverable surfaced; revert leaves exactly the bare CHECKSUMS line (base: no event) |
checksum degradation contract |
e2e repair_gem_dir_tamper_matrix_and_vex_refusal — tampered/deleted/extra file each → VEX refusal (vendor_inventory_mismatch) + repair rebuild; heals byte-exact (base: fileInventory null, everything attested) |
inventory record + verify |
e2e repair_warns_on_legacy_gem_entry_without_inventory — no rebuild + vendor_inventory_missing (base: fails at fixture, no inventory exists) |
backward tolerance + gap warning |
unit gem::tests::reconstruction_reproduces_vendor_wiring_for_pinned_declaration / _for_managed_block — reconstruction == vendor's own records, revert byte-restores |
reconstruction equivalence oracle |
unit gem::tests::reconstruction_degrades_range_constraint_to_exact_pin, _preserves_trailing_options, _flags_unrecoverable_checksum, _refuses_foreign_or_mismatched_wiring |
degradation + fail-closed contracts |
unit gem::tests::revert_refuses_empty_wiring_entry (RED on base: revert succeeded) |
revert guard |
unit gem::tests::vendor_records_dir_file_inventory — hand-pinned sha256s |
inventory recording |
unit verify::tests::dir_inventory_detects_unpatched_tamper_missing_and_extra_files, dir_inventory_refuses_planted_symlink |
inventory verification |
unit state::tests::file_inventory_round_trips_sorted_camel_case |
schema |
unit lock_inventory::tests::gemfile_lock_multi_source_resolves_each_spec_against_its_own_remote (RED on base: second spec inherited the first remote) |
per-section remotes |
unit lock_inventory::tests::gemfile_lock_legacy_multi_remote_section_is_discovery_only (RED on base: guessed first remote) |
multi-remote fail-closed |
unit lock_inventory::recover_tests::gem_recovery_refuses_ambiguous_multi_source_lock (RED on base: guessed) |
recovery ambiguity refusal |
repair_vendor_e2e: 20/20 (15 pre-existing npm rows untouched + 5 new gem rows)e2e_vex_vendor 8, in_process_vendor 27, repair_invariants 20, repair_vendor_flavors_e2e 28, scan_vendor_e2e 18, setup_contract_gaps 10, e2e_gem 8, in_process_gem_apply 7, in_process_gem_multi_platform 4, in_process_scan 24, ecosystem_dispatch_e2e 18, in_process_rollback_all_ecosystems 8docker_e2e_gem 2/2, docker_e2e_vendor_gem 1/1 (fresh image)e2e_vendor_gem_build capstone green under the real host bundler 4.0.15 (vendor → VEX → fresh-checkout frozen install → revert byte-restore)cargo fmt --check clean; cargo clippy --all-targets warning-clean on both cratesVendorArtifact schema addition forced a mechanical file_inventory: None, line in every literal constructor (~34 sites across backends/tests, outside the owned file list but compiler-forced); each is a single line, nothing functional.vendor/mod.rs (artifact_is_file_shaped, compute_dir_inventory) — verify is pub(crate), the CLI needs the symbols.revert_gem's guard and vendor_gem's inventory recording go slightly beyond "export recognizers only" for gem.rs; both are additive, directly serve the mission items, and are covered by the equivalence/guard tests. The alternative placements (dispatch_revert_one / persist_vendor_entry) are outside the owned files.🤖 Generated with Claude Code
Note
Medium Risk
Touches vendor ledger schema, repair/revert paths, and lockfile URL resolution—high test coverage but behavior changes affect gem repair and multi-source locks.
Overview
Closes three vendored-integrity gaps: ledger repair that could not restore gem wiring (revert stranded path: edits), dir-shaped artifacts that only checked patched files, and Gemfile.lock inventory that used the first GEM remote: for every spec.
Repair + gem revert. repair now routes per-ecosystem wiring reconstruction: gems call reconstruct_gem_wiring to rebuild revert-capable Gemfile / Gemfile.lock records from vendor-shaped live files (fail-closed on foreign shapes). Other ecosystems still get empty wiring with an explicit vendor_wiring_unknown warning. revert_gem refuses entries with empty wiring instead of deleting the artifact and leaving broken path: wiring.
Dir artifact integrity. Ledger entries add optional fileInventory (whole-tree path → sha256). vendor_gem records it; verify/repair/VEX compare the full directory (tamper on unpatched files → vendor_inventory_mismatch). Legacy entries without inventory keep member-only checks plus vendor_inventory_missing warnings.
Gem lock remotes. inventory_gemfile_lock resolves each spec against its own GEM section’s remote:; ambiguous multi-remote sections stay discovery-only. Ledger recovery refuses guessed downloads when multiple distinct GEM sources exist.
Reviewed by Cursor Bugbot for commit 0f24244. Configure here.
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.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 0f24244. Configure here.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
Review polish pushed as e5d975e — all 5 findings addressed, none skipped. Major — service-provenance repair loop (repair_vendor.rs): confirmed and fixed at the post-verify seam. A member-verified dir-shaped rebuild of a NON-reconstructed entry that fails only the recorded-inventory comparison now recomputes the inventory from the verified rebuild, persists it, and names the source switch ( Minor — vendor_inventory_missing noise: gated to gem, the one backend that records inventories. Pinned inside Minor — existing empty-wiring entries never healed: pass 1 now backfills full revert-capable wiring via Minor — reconstruction doc wrinkles: both documented on Minor — gem_remotes scheme filter: confirmed empirically against real bundler 4.0.15 (a Gemfile mixing an https source with a Verification: core 2474 green; cli lib 350; 🤖 Generated with Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Bugbot finding (no-ledger restore TOFU hole) — CONFIRMED and fixed in bd4fae8. Verified against the code first: pass 2's Healthy branch ran Fix (mirrors the PR's own
Tests (both verified RED on the pre-fix code): Runs: repair_vendor_e2e 24/24 (incl. G1's byte-identical + revert oracle), repair_vendor_flavors_e2e 28/28, core 🤖 Generated with Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
d063cb1 to
99f9cd0
Compare
bd4fae8 to
914004c
Compare
|
Rebased Conflicts resolved (1):
Verification (all green):
🤖 Generated with Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Pull request was closed
…truction, dir file inventory, per-section lock remotes
Three verified holes in the vendored-gem integrity story, each fixed at
its seam and pinned by tests that fail without the fix.
1. repair's no-ledger reconstruction synthesized entries with EMPTY
wiring; a later `vendor --revert` of such a gem entry deleted the
artifact dir, reported success with zero warnings, and left the
Gemfile `path:` + lock PATH section pointing at the deleted dir
(next `bundle install` hard-fails). Now:
- gem::reconstruct_gem_wiring rebuilds full revert-capable wiring
from the backend's own recognizable pair edit (exact-pin line /
managed fence, PATH section, `!` dependency pin), grammar-strict
and fail-closed; for an exact-pin fixture the reconstructed ledger
is byte-identical to the original. Two documented degradations: a
pre-vendor RANGE constraint restores as the canonical exact pin,
and a CHECKSUMS sha256= token is not offline-recoverable — the
bare entry stays for a plain `bundle install` to refill (bundler
4.0.15 verified: plain install heals it byte-identically, frozen
fails with a self-explanatory message until then), surfaced as
vendor_checksum_unrecoverable.
- repair routes reconstruction per ecosystem (repair_vendor.rs
seam); non-gem ecosystems keep empty wiring — their pre-vendor
originals are registry integrity material no offline source can
reproduce — and the gap now surfaces loudly as
vendor_wiring_unknown instead of silently.
- revert_gem refuses an empty-wiring entry outright
(vendor_wiring_unknown + manual cleanup steps) instead of
stranding the pair edit. The npm-family revert has the same hole
and still 'succeeds' silently — the shared guard belongs in
dispatch_revert_one (outside this PR's scope, see PR body).
2. check_vendored_artifact's whole-file drift cross-check only covered
file-shaped artifacts; a vendored gem DIRECTORY was verified purely
by record.files afterHashes, so tampered/drifted UNPATCHED files
(or the stub gemspec) were blessed Healthy by repair and attested
by VEX. VendorArtifact gains `fileInventory` (relative path →
plain sha256, sorted, camelCase) recorded by vendor_gem at vendor
time and verified whole-tree inside verify_vendored_patch_record
(missing/extra/modified files and planted symlinks all fail;
vendor_inventory_mismatch → Corrupt → repair rebuilds; VEX refuses
while tampered). Backward-tolerant: entries without the field keep
member-only verification and repair names the gap
(vendor_inventory_missing).
3. inventory_gemfile_lock captured the FIRST `remote:` across ALL GEM
sections and resolved every spec against it, so specs under a
second GEM source (private gem server) got a wrong (e.g.
rubygems.org) URL — a 404 at best, a private-gem name leak at
worst. Specs now resolve against their OWN section's remote
(bundler ≥ 2 emits one section per source and hard-errors on
multiple global sources — verified on 4.0.15); a legacy bundler-1.x
section with several remotes is genuinely ambiguous and stays
discovery-only (fail-closed, no guessed URL). gem_remote_base had
the same first-remote assumption in ledger recovery: recovery now
requires the lock's GEM sources to agree on a single remote and
refuses ambiguity.
Verified: core 2474/0, cli lib 350/0, repair_vendor_e2e 20/20 (5 new
gem rows), adjacent vendor/vex/scan suites green, e2e_vendor_gem_build
capstone green under real bundler 4.0.15, clippy+fmt clean.
Co-Authored-By: Claude Fable 5 <[email protected]>
…backfill empty gem wiring, scheme-agnostic remote ambiguity Review follow-ups on the gem vendored-integrity batch: - repair's post-verify no longer deterministic-fails a service-vendored gem entry: a member-verified local rebuild whose tree differs from the recorded fileInventory (the service's converter stub vs the local one) refreshes the inventory from the verified rebuild and persists it, with the provenance named (vendor_inventory_refreshed) — instead of deleting the rebuild, stranding the wired pair on a dead dir, and re-failing every later repair. - pass 1 backfills full revert-capable wiring for EXISTING empty-wiring gem ledger entries (the pre-reconstruction repair population) from the live pair while healthy, so `vendor --revert` stops refusing. - the vendor_inventory_missing nag is gated to gem — the one backend that records inventories; cargo/golang/composer re-vendors record nothing, so the advice was permanent per-run noise there. - gem_remotes collects lock remotes scheme-agnostically before the ambiguity refusal: a mixed http+file:// lock (real bundler 4.0.15 shape, one GEM section per `source "file://…" do` block) no longer collapses to one "agreed" remote and leaks the gem name to the http registry; a lone non-http remote refuses instead of defaulting to rubygems.org. - reconstruct_gem_wiring docs: the trailing-comment loss degradation and the deliberately-conservative bare-CHECKSUMS warning are documented. Co-Authored-By: Claude Fable 5 <[email protected]>
…ger entry The no-ledger restore (pass 2) ran check_vendored_artifact on a synthesized entry with no fileInventory/sha256 — verifying only the patched members — and then filled the fingerprint from the LIVE artifact and persisted it. For anything without an npm-family wired lockfile integrity (gem dirs foremost), a tampered UNPATCHED file was thereby canonized: later repairs enforce the tampered tree and VEX attests it (trust-on-first-use). Healthy-but-unanchored reconstructions are now queued as SOFT rebuild candidates: the ledger entry is restored fingerprint-less first (so the restore survives any rebuild failure and wiring originals carry forward), the untrusted live tree is cleared only once the patch sources and a pristine source are both secured, and the canonical fingerprint derives from the member-verified local rebuild — exactly the dispatch every other rebuild here uses. When no trustworthy pristine source exists (not installed, no recoverable registry fragment, offline, fetch failure) the entry stays in the legacy member-only state with a vendor_inventory_unverified warning — later repairs keep naming the gap (vendor_inventory_missing) instead of enforcing a tampered tree. Anchored file-shaped artifacts (rewired npm-family lock integrity, verified intact) restore as before. Pinned by two gem e2e tests (both verified RED on the pre-fix code): tampered-unpatched-file + lost ledger is healed by the rebuild with the restored ledger byte-identical to the pre-tamper original, and the no-pristine-source variant restores without a fingerprint, warns, and stays in the legacy-warn state. Co-Authored-By: Claude Fable 5 <[email protected]>
914004c to
bf55fa1
Compare
|
Rebased onto main — new tip bf55fa1 (was 914004c). What happened: the CONFLICTING state was the stale stacked base — this PR sat on Verification on the final base:
🤖 Generated with Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Heads-up for reviewers: the red Otherwise green and MERGEABLE after the rebase onto current main. Awaiting an approving review to merge. 🤖 Generated with Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Conflict: crates/socket-patch-core/src/vendor/mod.rs — both sides widened adjacent re-export lines. Resolved as a union: * main (#174) exports state::carry_forward_wiring, the extracted re-vendor ledger reconciliation persist_vendor_entry now calls; * this branch exports verify::artifact_is_file_shaped and verify::compute_dir_inventory, which the CLI needs because verify is pub(crate). Both hunks are kept verbatim; neither side's symbol set changes. The gem sibling (#177) was already in this branch's base, so main brings only pnpm/redirect work. carry_forward_wiring reconciles wiring, pnpm meta and the go-takeover flag and never touches entry.artifact, so the new fileInventory on a re-vendor keeps the freshly computed inventory — no interaction. Main added no VendorArtifact literal, so the mechanical file_inventory field addition stays complete. Verified: core lib 2215/0, cli lib 376/0, repair_vendor_e2e 24/0, in_process_vendor 30/0, e2e_vex_vendor 8/0, setup_contract_gaps 10/0, e2e_gem 8/0, in_process_gem_apply 7/0, e2e_vendor_gem_build 5/0, e2e_vendor_pnpm_build 6/0. vendor/mod.rs is rustfmt-clean. Co-Authored-By: Claude Fable 5 <[email protected]>
Co-Authored-By: Claude Fable 5 <[email protected]>
…ix/gem-vendor-integrity
|
Windows CI update: the 🤖 Generated with Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
The hosted-e2e fix is up: #199 (production publishes zero free gem patches — pin retired, gem canary-ized; live suite 15/0 on that branch). Once #199 merges, a rerun here goes fully green. 🤖 Generated with Claude Code |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
561644b
into
main
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.