test(gem): hermetic hosted capstone + CHECKSUMS/transitive/scan --vendor coverage; gems.rb + CRLF redirect fixes - #177
Conversation
|
Polish pass for the adversarial review findings (commit 8479fb0): Major — gems.rb divergence one-way trap: FIXED. The guard now judges divergence on a redirect-footprint residue ( Minor — TS-twin / golden-fixture coupling: documented, fixtures deliberately NOT landed. depscan's Minor — docs/ecosystems.md gem row: FIXED. Hosted cell now notes gems.rb/gems.locked editing (bundler's preference order) and the fail-closed divergence warning; vendored cell notes the Gemfile-spelling-only asymmetry (a gems.rb project cannot vendor yet). Tests: 🤖 Generated with Claude Code |
8479fb0 to
7195b64
Compare
|
Rebased onto the updated base Conflict resolution (one textual conflict, in
Verification on the rebased tip (union of both sides' behavior):
🤖 Generated with Claude Code |
d063cb1 to
99f9cd0
Compare
…or coverage; gems.rb + CRLF redirect fixes Closes the gem audit's top coverage gaps with hardened, independent-oracle tests, plus the two small redirect fixes the new tests exercise. Redirect fixes (patch/redirect/mod.rs gem section + hosted.rs candidates): - gems.rb/gems.locked support end-to-end: the candidate list now reads the modern pair and the gem rewriter keys on whichever pair bundler reads (gems.rb wins when both spellings exist — verified on bundler 4.0.15; same order as setup::gem). Diverging spellings fail closed with redirect_gem_gemfile_spellings_diverge. Before: a gems.rb project was a silent hosted-mode no-op. - CRLF Gemfile.lock tolerance: the CHECKSUMS matchers accept \r-terminated lines and edits preserve the file's CRLF endings byte-for-byte. Before: a CRLF lock (legal to bundler — verified via bundle check/frozen install) was misdiagnosed as bundler <2.6 (redirect_gem_no_checksums_section). New coverage: - e2e_redirect_gem_build.rs — FULLY HERMETIC hosted gem capstone: authored gems built with real `gem build`, one wiremock playing the upstream compact index, the Socket patch-registry compact index (production's /patch-registry/gem/<token>/<uuid>/ shape, real /versions md5s and /info checksums), and the patches API. scan --mode hosted, then a REAL fresh-checkout `bundle install` (host bundler) pulls the patched .gem: bytes match afterHash, the runtime dep installs because /info declares it, require probe + post-install verified VEX. A gems.rb twin pins the modern spelling end-to-end. A deps red-arm pins the compact-index dependency contract the production server currently violates: a deps-less /info breaks the install with bundler's APIResponseMismatchError (the live-CI signature). A KNOWN-LIMITATION canary pins that on a CHECKSUMS lock (bundler >= 4 default) the current rewrite makes the prescribed unfrozen install fail with "mismatched checksums" (empirically verified; the converged-lock fix shape that a frozen install accepts is documented in the test). - docker_e2e_vendor_gem.rs — lockfile_checksums twin (bundler 2.7 in the image, `bundle lock --add-checksums`): vendor swaps the registry sha256= CHECKSUMS line for bundler's bare path-gem form, a frozen --network none install accepts the rewritten lock byte-stably, and revert restores the registry sha256= line VERBATIM (the exit-16 hazard). - e2e_vendor_gem_build.rs — TRANSITIVE-dep capstone: vendoring rack via a rack-test project appends the managed block + sorted `rack (= v)!` DEPENDENCIES pin, a real frozen fresh-checkout install accepts the pair byte-stably, require probe through the dependent, revert round-trip. - in_process_vendor.rs — gem through `scan --vendor` (mock-proxy API, hermetic bundler layout, no ruby needed): JSON-arm end-to-end (pair edit + artifact + stub gemspec + already_vendored rerun), manifest-drop reconcile byte-restore, and the --detached variant (no manifest, embedded record, vendor --revert exit path). Every rewriter behavior change is pinned by unit tests that fail on the base commit (gems.rb pair routing, diverging-spelling fail-closed, CRLF pin-in-place/insert byte-preservation, CRLF rerun no-op); the gems.rb e2e leg fails without the candidate-list entry. Bundler behaviors (gems.rb preference, lockfile naming, compact-index formats, checksum enforcement, CRLF acceptance) were validated against real bundler 4.0.15 and the image's 2.7.2 before being baked into fixtures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rint residue, not raw bytes Run 1 on byte-identical gems.rb/Gemfile twins edits only gems.rb (the file bundler reads), so the raw-byte divergence guard trapped every later run — the rotated-grant URL refresh included — behind redirect_gem_gemfile_spellings_diverge, a divergence the rewriter itself created. Compare redirect-footprint residues instead: erase the managed Socket source block (rotating grant segments wildcarded) and the dep's own gem declaration line from both spellings before judging. Rebased onto d063cb1 (CRLF-tolerant block recognizer): the residue eraser now accepts `do\r?\n … end\r?` too, mirroring the recognizer — a core.autocrlf checkout rewrites run 1's LF block to CRLF, and a block the recognizer accepts must also be erased here or the re-run is trapped behind the divergence warning before it can reach the recognizer. Pinned by gems_rb_crlf_twins_rerun_is_no_op_and_rotated_grant_refreshes (verified red with an LF-only residue eraser). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
7195b64 to
707bbf8
Compare
|
Rebased Conflicts: none — the rebase applied cleanly with zero textual conflicts and zero content drift (interdiff of old tip vs new tip is exactly the base-side change). The two files both sides touch were checked semantically: Verification (all green):
Pre-existing note (not from this PR): 🤖 Generated with Claude Code |
STACKED on PR #175 (
fix/gem-bundler-audit) — base branch isfix/gem-bundler-audit, not main.Closes the gem audit's top coverage gaps with hardened tests, plus the two small verified redirect fixes the new tests exercise.
Product fixes (both pinned by tests that fail on the base commit)
REDIRECT_CANDIDATE_FILES(clihosted.rs) now reads the modern pair, andrewrite_gemkeys on whichever pair bundler actually reads: gems.rb wins when both spellings exist (verified empirically on bundler 4.0.15, matchingsetup::gem::discover_bundler_project); byte-identical twins proceed on gems.rb; spellings that diverge beyond the redirect's own footprint fail closed with the newredirect_gem_gemfile_spellings_divergewarning. Divergence is judged on a residue (gem_spelling_residue) with Socket's managed source blocks (rotating grant token/uuid wildcarded) and the redirected deps' owngemlines erased — a raw-byte comparison would trap every re-run behind the divergence run 1 itself creates on identical twins, permanently blocking the rotated-grant URL refresh and hosted record refresh (review finding, fixed in the polish commit). Ledger edit paths carry the real filenames. Before:scan --mode hostedwas a silent no-op on gems.rb projects.gems_rb_pair_is_rewritten_with_modern_paths,gems_rb_beats_identical_gemfile,gems_rb_and_gemfile_diverging_fail_closed,gems_rb_identical_twins_rerun_is_a_no_op_not_a_diverge_trap,gems_rb_identical_twins_rerun_refreshes_rotated_grant_url,gems_rb_identical_twins_rerun_after_appended_block_is_no_op,gems_rb_divergence_only_in_redirected_dep_line_proceeds(unit, RED on base / RED on a raw-byte guard) +gem_hosted_gems_rb_spelling_redirects_and_installs(e2e, RED without the candidate-list entry — verified).\r-terminated lines and both the pin-in-place and the insert-after-header edits preserve the file's CRLF endings byte-for-byte (real bundler accepts CRLF locks — verified viabundle check+ frozen install on 4.0.15). Before: a CRLF lock was misdiagnosed as bundler <2.6 (redirect_gem_no_checksums_section) and never pinned.gem_crlf_lock_checksum_pinned_preserving_crlf,gem_crlf_lock_checksums_header_gains_crlf_entry(byte-exact, incl. CRLF rerun no-op; RED on base).New coverage
tests/e2e_redirect_gem_build.rs— hermetic hosted gem capstone (4 tests,#[ignore]-gated likee2e_vendor_gem_build). Fully hermetic: fixture gems authored in-test and built with the realgem build; ONE wiremock plays the upstream compact index, the Socket patch-registry compact index (production's/patch-registry/gem/<token>/<uuid>/base, real per-info md5 digests in/versions,checksum:sha256s in/info), and the patches API. Chain:scan --mode hosted --vex→ fresh checkout → REALbundle install→ installed bytes byte-match afterHash, runtime dep installs, require probe, post-install hash-verified VEX./infodeclares it; the red-arm test (…without_deps_breaks_install_like_production) proves a deps-less/info(today's prod shape:not_builtindex / zero-byte deps API) breaks the install with bundler'sAPIResponseMismatchError … dependencies not in the API— the exact live-CI signature.gem_hosted_checksums_lock_pins_patched_sha_but_bundler_refuses_mixed_state): on a CHECKSUMS lock (bundler ≥ 4 writes one by default), the current rewrite (Gemfile source block + CHECKSUMS pin, GEM section left on upstream) makes the prescribed unfrozen install fail with "Bundler found mismatched checksums" (exit 37) — bundler still attributes the gem to the upstream source and refuses the lockfile-vs-upstream-API disagreement. Empirically verified on 4.0.15; also verified the fix target: the fully converged lock (patch-registry GEM section +name (= ver)!DEPENDENCIES pin + patched CHECKSUMS sha) passes even a FROZEN install. That fix must land in the TS twin + shared golden fixtures together, so it is out of scope here; the canary makes the breakage visible and self-documents the flip when fixed.docker_e2e_vendor_gem.rs— lockfile_checksums twin (replaces the module-doc TODO):bundle lock --add-checksumson the image's bundler 2.7, vendor swaps the registrysha256=line for bundler's bare path-gem CHECKSUMS form, frozen--network nonefresh-checkout install accepts the rewritten lock byte-stably (the exit-16 hazard), revert restores the registrysha256=line VERBATIM, re-vendor re-bares it. Host-side oracle re-asserts from the mounted files. The existing no-CHECKSUMS test is unchanged (both flavors covered).e2e_vendor_gem_build.rs— transitive-dep capstone: rack vendored as a TRANSITIVE dep of rack-test; the managed block (# >>> socket-patch vendor (managed) >>>…) is byte-asserted with hand-pinned marker constants, the DEPENDENCIES pin inserts at bundler's sorted position, and — for the first time — that pair is fed to a REAL frozenbundle install(byte-stable lock, probe through the rack-test require chain), then revert round-trips byte-identically. Lock shape pinned to no-CHECKSUMS on every host (lockfile_checksums false) so bundler 2.5 (CI pin) and 4.x agree; the CHECKSUMS flavor is the docker twin's job.in_process_vendor.rs— gem throughscan --vendor(hermetic bundler layout, no ruby needed): JSON-arm end-to-end (manifest written, pair edit + patched artifact + stub gemspec fromspecifications/, pristine installed tree,already_vendoredrerun) + manifest-drop reconcile byte-restore +--detachedvariant (no manifest, embedded record,vendor --revertexit path).Empirical validation (before baking into fixtures/code)
Against real bundler 4.0.15 (host) and 2.7.2 (docker image): gems.rb-beats-Gemfile + gems.locked naming; compact-index
/versionsmd5 +/infodeps/checksum grammar (a hand-built index accepted by a realbundle install); checksum enforcement (lock pin vs served bytes); CRLF lock acceptance; bundler-4 CHECKSUMS-by-default vs 2.7 opt-in;bundle lock --add-checksumsavailability; the deps-less/infofailure signature; and the converged-lock frozen-install fix shape.Test results
e2e_redirect_gem_build(new): 4 passed (hermetic, ~6s)docker_e2e_vendor_gem: 2 passed (both flavors, real bundler 2.7 in docker)e2e_vendor_gem_build --ignored: 2 passed (incl. new transitive capstone, real bundler 4.0.15)in_process_vendor: 29 passed (2 new gem tests)socket-patch-corefull suite: all green (incl.redirect_golden— classic-spelling output byte-unchanged),patch::redirect73 passedin_process_redirect,in_process_redirect_pnpm,e2e_vex_redirect,scan_vendor_e2e,cli_parse_scan,e2e_redirect_rush_sim --ignored, cli--lib): all greencargo fmt+cargo clippy --all-targets(both crates, with features): cleanFollow-ups / out of scope (not in my owned files)
TS-twin port of this PR's two redirect fixes + the shared golden fixtures (depscan
registry-rewritegem rewriter +golden.test.ts): gems.rb/gems.locked pair routing, the residue-basedredirect_gem_gemfile_spellings_divergeguard (warning-code parity included), and CRLF Gemfile.lock CHECKSUMS tolerance are CLI-side only for now — the backend twin still silently no-ops on a gems.rb project and misdiagnoses a CRLF lock as bundler <2.6. The shared golden cases (gems.rb pair, diverge fail-closed, CRLF lock) must land TOGETHER with the TS port: depscan'sgolden.test.tsruns every fixture case with no skip list (verified), so fixtures added here first would break depscan CI at the next submodule bump. depscan has GitHub issues disabled — needs a depscan PR/internal ticket.ci.yml e2e matrix entry for the new
e2e_redirect_gem_buildsuite (needs setup-ruby with bundler ≥ 2.6 pinned; the existing gem leg pins 2.5 fore2e_vendor_gem_build). Until added, the suite runs only via--ignoredlocally.CHECKSUMS-lock hosted redirect fix (the canary finding): needs the converged-lock rewrite in the gem rewriter + the TS twin + shared golden fixtures moving together. Alternative shapes verified: removing the pinned line also unblocks (bundler re-records the patched sha from the registry API) but loses first-fetch enforcement.
The hosted-production e2e gem leg (
e2e_hosted_production.rs) can adopt theAPIResponseMismatchErrorred-arm once the prod compact index is rebuilt.🤖 Generated with Claude Code
Note
Medium Risk
Changes gem hosted redirect lockfile rewriting (
rewrite_gem), which affects howscan --mode hostededits Gemfiles and locks; risk is mitigated by broad new e2e coverage rather than large unrelated refactors.Overview
Hosted gem redirect now reads
gems.rb/gems.locked(candidate list + rewriter). The rewriter edits the pair bundler actually uses (gems.rbwhen both spellings exist and match); divergingGemfilevsgems.rbcontent fails closed withredirect_gem_gemfile_spellings_diverge. Ledger edit paths use the real filenames. CRLFGemfile.lockis handled for CHECKSUMS pinning without mis-firingredirect_gem_no_checksums_section.Tests close major gem gaps: hermetic
e2e_redirect_gem_build(wiremock compact index +scan --mode hosted→ freshbundle install→ VEX), includinggems.rbspelling, a deps-less/infored-arm (APIResponseMismatchError), and a CHECKSUMS-lock canary documenting today’s mixed-state install failure until a converged-lock rewrite lands. Dockerlockfile_checksumstwin for vendor CHECKSUMS rewrite/revert; host transitive rack vendoring + frozen install; in-processscan --vendorfor gem (reconcile + detached).Reviewed by Cursor Bugbot for commit b17172b. Configure here.