Ghost FTP 0.95.7 — Android SAF cancellation isolation (development candidate)
Not yet published. Latest verified public GitHub release when preparing this branch: v0.95.6, tagged at a25403c78cb8d26e0dd57495c23598d81ed2860f. PR #139 was merged later as 9e1f2cc914f09a613cdaab1a6f49fb01109934a0. Never move or reuse that immutable public tag.
Code changes
- Android
CloudTransferCancellation.cancel()dispatches each SAF provider input/outputclose()independently on a daemon closer. If one provider blocks insideclose(), another watched handle can still be signaled. - A deterministic JVM test asserts the second stream is closed despite a simulated first-provider blocked close. Existing tests for UI-safe cancellation, late stream registration and completed-handle cleanup remain.
- Shared source, Android/Go, Windows/Linux desktop, Rust crates, updater metadata and release docs are advanced to 0.95.7, with
previousVersion=0.95.6andpreviousPublishedVersion=0.95.6.
Required verification before merge and publication
All six exact-head GitHub workflows: Quality (including Rust workspace, dead code and docs checks), Android (JVM tests, lint, APK/AAB build and emulator), macOS, native Windows/Linux build, Windows hardening and FTP/FTPS/SFTP protocol E2E. Verify artifact hashes, expected executable/installable contents, and correctly label unsigned Android AAB and unnotarized macOS preview outputs.
Rust dependency graph and CI hardening
- Prevent auxiliary Cargo refresh workflows from trying to downgrade the exact
tauri = "=2.11.6"manifest pin to an older version. ValidateCargo.lockusingcargo metadata --lockedand assert the actual manifest's Tauri version against its committed lock entry. - No automatic transitive dependency re-resolution or rewriting during routine version synchronization. Any future third-party upgrade requires a separate reviewed lockfile change.
Limits and open acceptance
This is a narrow mitigation for #127, not proof that third-party SAF Binder I/O can always be canceled. Android 8–15 physical-device tests, permission revocation, process kill/rotation, 1 GiB/disk-full and non-atomic SAF cleanup still require proof. #126 requires controlled DNS/rebinding/proxy/VPN and real signed-cloud provider success evidence. #128 requires system-browser OAuth PKCE, protected token storage and real account-backed file operations. macOS FTPS/SFTP, notarization and installed-app 75-screen visual comparisons remain unverified.