fix: sha256 verification to prevent corrupt partial download loop#1095
Merged
cjpais merged 8 commits intocjpais:mainfrom Mar 21, 2026
Merged
Conversation
c6bfaee to
95effff
Compare
3 tasks
Fixes issue cjpais#858 — corrupt .partial files caused an infinite loop where a failed/cancelled download would resume from EOF, pass extraction, and loop forever with no way to recover without manual file deletion. Three-part fix: - Add sha2 crate and compute_sha256() helper; verify hash post-download before extraction/rename for all 15 built-in models. Hash mismatch deletes the .partial so the next attempt starts fresh. - Delete .partial on extraction failure (independent of checksums) so corrupt archives can't re-enter the loop via the same path. - Emit model-download-failed event from the command handler so all callers (ModelsSettings, Onboarding) get consistent error feedback via a central store listener rather than per-caller return-value checks. SHA256 hashes hardcoded alongside each model's URL in ModelInfo. Custom models (sha256: None) skip verification silently.
Doc comments on exported specta types propagate into bindings.ts as inline JSDoc — not useful in generated TS. Removing at the source.
Extracts inline verify logic into ModelManager::verify_sha256() and covers all four branches: - None expected hash → skipped (custom models) - Matching hash → ok, file kept - Mismatched hash → error returned, partial file deleted - Unreadable file → error returned Ensures corrupt partial downloads are always cleaned up so the next attempt starts fresh.
…llback cleanup - remove cancel_flags entry on sha256 failure to prevent a stale flag from immediately cancelling the next retry attempt (HIGH) - add fallback state cleanup in modelStore when result.status != ok, so spinner clears even if model-download-failed event is missed (HIGH) - run compute_sha256 in spawn_blocking to avoid stalling the async executor while hashing large model files (up to 1.6 GB) (MEDIUM)
9abc539 to
6f676c7
Compare
Contributor
Author
|
would love any feedback and thoughts @sheeki03 |
DylanBricar
added a commit
to DylanBricar/Phonara
that referenced
this pull request
Mar 20, 2026
- SHA256 download verification to prevent corrupt partial download loops (cjpais#1095) - Secondary transcription shortcut with independent language setting (cjpais#1106) - Double-click tray icon to show main window (cjpais#369) - CLI --auto-submit flag to force enter after transcription (cjpais#1099) - OCR template context via ${OCR} variable in post-processing prompts (cjpais#770)
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.
Before Submitting This PR
Human Written Description
the partial download bug (#858) has been causing infinite loops for a long time — corrupt .partial files survive extraction failures and get resumed on next launch, trapping users with no way out except manually hunting down and deleting the file. i traced the root cause to commit 86a1205 where cancel_download() only flips a flag but doesn't cancel the in-flight request, leaving partial files on disk in unknown states.
sha256 checksums catch corruption regardless of cause (interrupted download, bad resume, anything), and hardcoding them next to each model's url means the fix is transparent and easy to maintain. also deletes .partial on extraction failure as a belt-and-suspenders fix for cases where checksums aren't available (e.g. future custom model support).
Related Issues/Discussions
Fixes #858
Related: #1015
Community Feedback
#858 has been open since feb 2026 with multiple users confirming the bug. this is a complete fix rather than the cleanup-on-failure approach in #1015.
Testing
AI Assistance
If AI was used: