fix(core): File Provider write probe — OneDriveLocator.probeWritable(at:)

isWritableDirectory (permissions bits) is not enough: a OneDrive
Files-On-Demand directory whose provider domain is signed out can report as
existing and POSIX-writable while an actual write fails. probeWritable
writes a small ".redline-probe-<uuid>" file into the folder via
AtomicFile.write (open+write+fsync+rename+directory-fsync), then removes it;
any failure at write, fsync, or removal means false.

Three unit tests: an ordinary writable directory (true, and no probe file
left behind), a chmod 500 directory (false; permissions restored in
teardown), and a plain file path (false).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012ZiTXPbPCSjzPVsfoweAbp
This commit is contained in:
2026-09-05 09:54:58 +04:00
co-authored by Claude Fable 5.1
parent 70231574c9
commit 723cd7dcea
2 changed files with 63 additions and 0 deletions
@@ -176,4 +176,29 @@ public enum OneDriveLocator {
guard exists, isDirectory.boolValue else { return false }
return fileManager.isWritableFile(atPath: url.path)
}
/// Writes a tiny probe file into `folder`, fsyncs it, then removes it the only
/// reliable way to catch a OneDrive Files-On-Demand directory whose provider domain
/// is signed out: such a directory can report as existing and POSIX-writable
/// (`isWritableDirectory` returns true) while an actual write fails. True only when
/// the write, fsync, AND removal of the probe file all succeed; any failure at any
/// of those steps means false, so the caller treats the folder as unavailable
/// rather than proceeding to compose a real PDF into it.
public static func probeWritable(
at folder: URL,
fileManager: FileManager = .default
) -> Bool {
let probeURL = folder.appendingPathComponent(".redline-probe-\(UUID().uuidString)")
do {
try AtomicFile.write(Data(), to: probeURL)
} catch {
return false
}
do {
try fileManager.removeItem(at: probeURL)
} catch {
return false
}
return true
}
}