Skip to content

Bug: Verify model download integrity before promoting an artifact #113

Closed

Description

@BerryUIKI

Summary

A fixture declared a 100-byte model and an explicit SHA-256; a 13-byte corrupt response was still marked completed. model_downloader.py:171 promotes the partial file without validating the catalog checksum or expected size. Replacing a previous destination first unlinks it.

Environment and evidence

  • Review finding: F13 (2026-10-05 product/technical review).
  • Baseline: Windows, dev at c1c5dbe. The remote dev matched this commit when filing.
  • Evidence: Reproduced.
  • Priority recommendation: P1 - proposed first-release blocker. This is review triage, not a production-incident severity declaration.
  • No real credentials, paid inference, engine installation, or unrelated process termination were used for review probes. Mocked observations establish the stated code behavior, not live-provider/GPU acceptance.

Reproduction or validation

Construct a HubModelRecord declaring size_bytes=100 and an explicit SHA-256. Feed DownloadWorker a mocked 13-byte corrupt HTTP response. Observed: status=completed and a promoted 13-byte destination. No model was downloaded from the network. Also inspect partial-file resume/source switching and replacement of an existing destination.

User impact

Truncated or incorrect models can be offered as usable; replacement can discard a working file before promotion succeeds. Resume/fallback also needs Content-Range and source-identity validation.

Proposed approach

Verify length and checksum where available, reject invalid resumptions, and atomically replace only validated artifacts while preserving the previous version on failure.

Acceptance criteria

  • Validate expected length and checksum where supplied before promotion.
  • Reject incompatible Content-Range, ETag/source identity, or resume responses.
  • Promotion is atomic and preserves a previous valid model on failure.
  • Invalid downloads remain failed/incomplete with actionable diagnostics.

Verification scope

Real GPU inference, paid-provider compatibility, and a clean-machine packaged desktop journey remain unverified. Any follow-up implementation should target dev under the repository's contribution/branching rules.

Activity

  1. added
    bugSomething isn't working
    criticalCritical priority issues that block core functionality or cause vulnerabilities
    backendBackend Python / FastAPI / Engine issues
    on Oct 4, 2026
  2. added a commit that references this issue on Oct 4, 2026
    ae1c278
  3. BerryUIKI commented on Oct 4, 2026

    @BerryUIKI
    OwnerAuthor

    Resolved via PR #151.

    • Validated \Content-Range\ headers upon resume to ensure server resumed from \existing_bytes; if incompatible or HTTP 200 returned, cleanly reset and redownload from byte 0.
    • Added pre-promotion expected size check against declared \model.size_bytes\ or server total.
    • Added SHA-256 integrity verification comparing downloaded chunked hash against \model.sha256.
    • Replaced destructive \ arget_path.unlink()\ with atomic \Path.replace()\ on destination, preserving any prior file if verification or promotion fails.
    • Added regression tests covering size mismatch rejection, SHA-256 mismatch rejection, and atomic replacement preservation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendBackend Python / FastAPI / Engine issuesbugSomething isn't workingcriticalCritical priority issues that block core functionality or cause vulnerabilities

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions