fix(android): preserve SAF download replacements - #434
Conversation
Obiente previewNC Native · Obiente updates this comment as the preview changes. |
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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a8c0e0147
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1c0faeedc4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 544b61b1e7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2d40a0c839
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b3c120ddd7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b1681c6083
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| require(current?.entry?.revision == expectedLocalRevision) { | ||
| "The local file changed after the sync scan." | ||
| } | ||
| require(current.entry.kind == SyncEntryKind.File) { "The local item changed type." } | ||
| } | ||
| val replacementSnapshot = current?.let(::replacementSnapshot) |
There was a problem hiding this comment.
Preserve scan-time content identity before replacement
When a SAF provider keeps the document ID, timestamp, and size unchanged, a same-size local edit made after the scan but before this method runs passes the revision check, and replacementSnapshot then records the already-edited bytes as its expected state. The later content revalidation therefore succeeds and publication deletes the backup containing the unrecognized edit. Fresh evidence beyond the earlier during-staging finding is that strong content evidence is first captured only after the weak scan-time guard; compare the protected item with scan-time content evidence, or report a conflict when that evidence is unavailable.
AGENTS.md reference: AGENTS.md:L375-L376
Useful? React with 👍 / 👎.
| if (Thread.currentThread().isInterrupted) { | ||
| throw kotlinx.coroutines.CancellationException("Local replacement verification cancelled.") | ||
| } |
There was a problem hiding this comment.
Observe coroutine cancellation while hashing replacements
When a remote file replaces a large local directory and WorkManager cancels during the post-download snapshot, this loop checks only thread interruption. withAndroidFileSyncRunCancellation represents coroutine cancellation in its cancellation token and does not interrupt the worker thread, but that token is not passed here, so hashing can continue and the synchronous publisher can rename and delete the local item after cancellation. Pass the run cancellation predicate into replacement verification so cancellation stops before publication.
AGENTS.md reference: AGENTS.md:L274-L276
Useful? React with 👍 / 👎.
What changed
Validation
AndroidSafDownloadPublicationTestAndroidFileSyncEngineInvariantTest:androidApp:compileDebugKotlinbash tools/check-kotlin-architecture.shbash tools/check-repository.shafter binding this PR number in the changelog fragmentLimits
Found by the code-first reliability audit.