Repository navigation
Admit macOS APFS as a production storage platform - #216
Conversation
Route protocol lookups through FilesystemDirectory, which requires each existing name byte-for-byte in a listing of its parent, and select the Darwin adapter. Add a native macOS CI job. No format, dependency, or unsafe change.
|
Important Review skippedToo many files! This PR contains 114 files, which is 14 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.
|
Compare only restart-stable coordinates after a volume reattach, run tests on the APFS variant the runner selected, restore a host-independent child-refusal law, satisfy the crash-matrix workflow contract, and fix Linux-only test code.
9a691fd to
5af6b65
Compare
5af6b65 to
b7f8636
Compare
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Admit macOS APFS as a production storage platform
Problem
Production admission accepted only Linux ext4, so Keep could not store anything on a Mac.
Invariant affected
Keep returns exactly the named bytes or refuses, now also on APFS. A protocol name refers only to an entry stored with exactly that spelling. On default APFS,
headwould otherwise answer a lookup ofHEAD.Approach
PlatformFilesystemboundary separates native observations from shared admission policy, andDarwinFilesystemimplements it.FilesystemDirectoryreplaces direct capability use. Each operation takes one normal component. On macOS, an existing name must also appear byte-for-byte in a listing of its parent, before it is read, reused or mutated.st_dev, and use that value for device and mount. Darwin renumbersst_devwhen a volume is reattached, so the restart check compares only that top bit and the inode.AGENTS.mdrequires.Alternatives rejected
F_GETPATH: it reports a name cached on the vnode, which can belong to another hard link, and publication uses hard links.darwin-filesystem-syscrate:fsidonly repeatsst_devbeside the filesystem type, so the unsafe code bought nothing.Failure modes
st_devthat doesn't fit: refusal..DS_Storeinto a displayed folder, and the store then refuses until it is removed. This fails closed; whether to tolerate the name is an owner decision.Tests
See
docs/testing-evidence/filesystem-platform-adapters.md. Native on pinned Rust 1.96, on both variants with each run asserting its variant: all tests pass, and the crash matrix passes. Clippy passes.darwin_volume_reattachfails when the full device coordinate is compared and passes with the fix.An independent review found that my first "both variants" runs used one volume, because the sandbox ignored
TMPDIR. Those runs are discarded.Calibration: with the spelling check disabled, the three direct spelling laws fail. The public
darwin_store_spellinglaws still pass, because namespace admission refuses independently, so they don't witness the per-lookup check.Weaker or absent on macOS, all listed in the evidence record: the reader-fence law can't observe a queued
flock, and uses a two-second window instead; onlyHEADhas a FIFO law; refusal of non-APFS and read-only volumes is tested at the adapter, not the public boundary.Benchmark impact
On macOS, each existing-entry lookup scans its parent. One release-mode run measured an open at 25 µs plain and 74 µs checked with 10 entries, and 17 µs plain and 3.4 ms checked with 50,000. Store workloads are not measured. Linux is unaffected.
Format/API compatibility
No format change. Public signatures are unchanged. Stores don't move between operating systems while the persisted root binding exists, because the coordinate domains differ.
Recovery implications
Same protocols and crash points. The crash matrix passes on both variants, using its repository admission path rather than the production profile probe, as it does on Linux. Process death isn't power loss, and no power-loss experiment has been run on APFS.
Security implications
No unsafe code or new dependency. Access stays capability-relative and no-follow. CI gains a job that runs repository code on a GitHub-hosted macOS runner, with read-only permissions.
Relationship to the open stack
This is based on
main, ahead of #215 and #200–#204. It touches many of the same files, mostly a one-line import change, so the stack will need to absorb that on rebase. #204 deletesFilesystemPlatformAdmissionand migration, and the root-binding coordinates go with them if that lands.