fix(test): unflake the apply_lock orphaned-inode race; extend the hosted gem pin for production's fifth 6.0.3 patch - #232
Merged
Mikola Lysenko (mikolalysenko) merged 2 commits intoAug 25, 2026
Conversation
…te its two benign races waiter_does_not_lock_orphaned_inode_after_lock_file_deleted failed 3/3 attempts on CI's macos-latest (PR #230's runs) in two distinct modes, both scheduler races in the TEST, not the lock: - the waiter's retry landed between remove_file and the test's fresh acquire, while the lock was genuinely free — the waiter is a legitimate sole holder and the fresh try-once .unwrap() panicked (apply_lock.rs:395); - the waiter opened the old inode, was descheduled across repair's drop+unlink, and flocked the orphan — the sanctioned microsecond open->flock window the module docs accept for a fresh acquire (apply_lock.rs:401). The regressed bug (one pre-loop handle re-flocked forever) double-holds on essentially every iteration, while the benign losses need an unlucky deschedule and almost never repeat — so retry the choreography up to 5 times, pass on the first clean iteration (fresh guard held, waiter got Held — unreachable under the bug), and fail only if no iteration is clean. 30 isolated runs + 3 full-suite (2540-test parallel) runs green locally. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…orage 6.0.3 patch hosted-e2e's gem_bundler_hosted_install_proof fails on every PR since 2026-08-21T19:07Z: production extended the activestorage 6.0.3 patch set with a fifth advisory — GHSA-xr9x-r78c-5hrm / CVE-2026-66066 (libvips unfuzzed-operations arbitrary file read / RCE) — and the server-ranked selection now wires its patch 9c2b4925-b413-4a3a-bb3a-9990440fb446, which the pinned any-of set predates. Verified per the pin's own recipe before appending: /patch/view blobs fetched live 2026-08-24 — image_processing_transformer.rb (modified) and NEW lib/active_storage/vips.rb (backports Vips.block_untrusted) both carry the Socket Community Patch header, git-blob-sha256-match their manifest afterHash entries, and contain no unexpected code. The gem leg passes against live production locally with the extended set. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Wenxin Jiang (Wenxin-Jiang)
approved these changes
Aug 25, 2026
Mikola Lysenko (mikolalysenko)
deleted the
fix/apply-lock-orphan-test-race
branch
August 25, 2026 16:40
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two test-only fixes for the two jobs currently failing every PR's CI (each fix alone would still be blocked by the other's failing job, so they ship together):
1.
test (macos-latest): retry the apply_lock orphaned-inode choreographypatch::apply_lock::tests::waiter_does_not_lock_orphaned_inode_after_lock_file_deletedfailed 3/3 attempts on PR #230's CI (a workflows/docs-only PR — Rust identical to main), in two distinct modes:apply_lock.rs:395— the waiter's retry landed in the gap between the test'sremove_fileand its freshacquire, when the lock was genuinely free. The waiter is a legitimate sole holder; the fresh try-once correctly returnedHeldand the test's.unwrap()blew up. Pure choreography bug: the test assumed the main thread always wins a race it can lose.apply_lock.rs:401— the waiter opened the old inode, got descheduled across repair's drop+unlink, and flocked the orphan: the sanctioned microsecond open→flock window the module docs already accept. Re-opening per retry narrows it but can't close it.Both need an unlucky deschedule, so they appear under loaded CI runners (2,540 parallel tests) and never locally in isolation.
Fix: retry the choreography up to 5 times; pass on the first clean iteration (fresh guard held while the waiter got
Held). The clean outcome is unreachable under the regressed bug (a one-pre-loop-handle waiter always flocks its orphaned handle once the holder drops), so the bug still fails all 5 iterations; the benign races almost never repeat. 30 isolated + 3 full-suite parallel runs green locally.2.
hosted-e2e: extendGEM_UUIDSwith production's fifth activestorage 6.0.3 patchgem_bundler_hosted_install_prooffails deterministically since 2026-08-21T19:07Z: production extended the activestorage 6.0.3 set with a fifth advisory — GHSA-xr9x-r78c-5hrm / CVE-2026-66066 (libvips unfuzzed-operations arbitrary file read / RCE, CRITICAL) — and the server-ranked selection now wires its patch9c2b4925-b413-4a3a-bb3a-9990440fb446, which the pinned any-of set predates. (Same class of failure as main's runs on 2026-08-21.)Verified per the pin's own recipe before appending:
/patch/viewblobs fetched live 2026-08-24 —image_processing_transformer.rb(modified) and NEWlib/active_storage/vips.rb(backportsVips.block_untrusted(true)) both carry the Socket Community Patch header, git-blob-sha256-match their manifestafterHashentries, and contain no unexpected code. The gem leg passes against live production locally with the extended set.Unblocks #230 (its
test (macos-latest)check needs a re-run after this merges).🤖 Generated with Claude Code