fix(fleet): publish without a two-link window on Linux and macOS - #6431
Merged
Hmbown merged 3 commits intoSep 24, 2026
Merged
Conversation
WorkspaceFile::publish linked the temporary into place and then unlinked it. In between, the file has two links, and open_file rejects any link count other than 1, so a reader racing the publication got InvalidData. The loser of two identical tool-image replays reads the winner's evidence back exactly then, which is how tool_media_publication_is_immutable_and_replay_preserves_manifest failed on macOS CI. Linux now uses renameat2(RENAME_NOREPLACE) and macOS renameatx_np(RENAME_EXCL), the Unix side of the no-replace rename the Windows path already does. Any refusal other than an existing target falls back to linkat, so no platform is worse off than before. Signed-off-by: Lstarsky0 <59827030+Lstarsky0@users.noreply.github.com>
This was referenced Sep 24, 2026
timothybrush
pushed a commit
to timothybrush/DeepSeek-TUI
that referenced
this pull request
Sep 24, 2026
The RSS budget and offline eval ran inside Test for every trusted event, assuming the warm self-hosted Mac. With CW_SELF_HOSTED_MAC off, a trusted PR's macOS leg is a cold GitHub-hosted Mac, where Test alone took 77-80 minutes on 2026-09-23 (Hmbown#6431, Hmbown#6417) and the two extra steps would pass the 90-minute limit. Route both steps by runner, not trust: inside Test only on the self-hosted Mac, otherwise in the parallel macos-budget job. Raise Test's timeout to 120 minutes for cold hosted Macs. This makes the existing kill switch safe to use: the single self-hosted runner had 14 queued runs and dropped jobs with "lost communication". Verification: actionlint with CI's flags (-ignore SC2129/SC2221/SC2222) clean. No tests run; workflow-only change, CI is the proof. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Hmbown
pushed a commit
to gaord/CodeWhale
that referenced
this pull request
Sep 24, 2026
Version drift failed on Hmbown#6431, Hmbown#6443 and Hmbown#6456 with `rm: cannot remove '/tmp/tmp.*/checkout': Directory not empty` right after "require-release-tag-checkout tests passed": every assertion held, and only the EXIT trap failed. The fixture commits and pushes, which can spawn a detached `git maintenance run --auto` still writing into .git while the trap deletes it. Disable auto maintenance/gc for every git process in the fixture via GIT_CONFIG_COUNT, and retry the removal once. Verification: the fixture passes locally; shellcheck clean. The race was never reproduced locally, so the root cause is inferred from the log; CI reruns are the proof. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Summary
On Unix,
WorkspaceFile::publishwrote a temporary,linkated it into place, then unlinked the temporary. Between those two calls the published file has two links, andopen_filerejects any link count other than 1, so a reader racing the publication getsInvalidData("Fleet file must be a regular, non-hard-linked file").Two identical tool-image replays hit exactly that: the loser reads the winner's evidence back while it is still double-linked and gives up on the preview. That is the
tool_media_publication_is_immutable_and_replay_preserves_manifestfailure on macOS in this run (line 239: one of the two concurrent projections came back withouttool_media). The previous attempt on the same commit passed.Linux now publishes with
renameat2(RENAME_NOREPLACE)and macOS withrenameatx_np(RENAME_EXCL), the Unix side of the no-replace rename the Windows path already uses. Linux goes through the raw syscall so musl and OHOS don't depend on a libc wrapper. Any refusal other than an existing target falls back to the oldlinkat, so an old kernel, a filesystem that doesn't take the flag, or a seccomp filter is no worse off than today. The link-count check is unchanged.No-Issue: flaky macOS test; the cause and a repro are above and in the new test.
Testing
a_racing_reader_never_sees_a_publication_half_donespins a reader onopen_filewhile each file is published. With the exclusive rename switched off it fails on round 0 in 10 of 10 runs here (macOS); with it, 0 of 20.tool_media_publication_is_immutable_and_replay_preserves_manifest— 50 of 50 locally.cargo fmt --all -- --check— cleancargo clippy -p codewhale-tui --all-targets --all-features --lockedwith the CI allow list — cleancargo nextest run -p codewhale-tui --all-features --profile ci— 13474 passed, 4 failed. The same 4 fail on untouchedmainhere (a local HTTP proxy, and threedoctorsealed-HOME tests that trip on this machine); all four passed on CI's macOS leg.Linux isn't built locally; the Ubuntu leg and the OHOS check cover it.
Checklist