gabriel / musehub public
feat BREAKING dev
AI Agent gabriel · 124 days ago · May 11, 2026 · Diff

feat: bundle content validation (issue #49 phase 2)

Adds per-object sha256 verification, decompression size guard (zip bomb), and object count mismatch detection to process_bundle_index_job. All validation runs before any DB or MinIO writes so failed jobs leave no partial state. Quarantined jobs get status='quarantined' with a reason.

- BundleValidationError exception class (terminal, not retried) - quarantine_job() in musehub_jobs — sets status='quarantined', quarantine_reason - quarantine_reason column on MusehubBackgroundJob - bundle_max_decompressed_bytes config setting (default 4 GB) - declared_objects_count stored in job payload for count mismatch check - put_bundle() and quarantine_bundle() on BlobBackend - 8 new tests in test_bundle_validation_phase2.py

sha256:7189fd2a116a24aa69ce8efd79893929ac75aa42aeb6308678df94d00246a9c7 sha
+52 ~5 symbols
sha256:e8987ab1761e837c443538f467bb5dd86bb26ee10d036506e4f54b38e5fc88aa snapshot
+52
symbols added
~5
symbols modified
0
dead code introduced
Semantic Changes 57 symbols
+ _AUTH_CTX variable variable _AUTH_CTX L50–55
+ _BLOB_SIZE variable variable _BLOB_SIZE L60–60
+ _FILES_CHANGED variable variable _FILES_CHANGED L59–59
+ _N_COMMITS variable variable _N_COMMITS L58–58
+ _N_FILES variable variable _N_FILES L57–57
+ _make_repo function function _make_repo L95–152
+ _make_tampered_bundle function function _make_tampered_bundle L189–206
+ _push_bundle function async_function _push_bundle L155–186
+ client function async_function client L66–80
+ ASGITransport import import ASGITransport L26–26
+ AsyncClient import import AsyncClient L26–26
+ AsyncSession import import AsyncSession L28–28
+ CommitRecord import import CommitRecord L40–40
+ MSignContext import import MSignContext L31–31
+ SnapshotRecord import import SnapshotRecord L40–40
+ annotations import import annotations L16–16
+ app import import app L34–34
+ blob_id import import blob_id L47–47
+ build_mpack import import build_mpack L37–37
+ compute_commit_id import import compute_commit_id L39–39
+ compute_snapshot_id import import compute_snapshot_id L39–39
+ copy import import copy L18–18
+ datetime import import datetime L19–19
+ db import import db L32–32
+ get_db import import get_db L33–33
+ hashlib import import hashlib L20–20
+ msgpack import import msgpack L23–23
+ muse_dir import import muse_dir L38–38
+ optional_signed_request import import optional_signed_request L31–31
+ patch import import patch L29–29
+ pathlib import import pathlib L21–21
+ pytest import import pytest L24–24
+ pytest_asyncio import import pytest_asyncio L25–25
+ require_signed_request import import require_signed_request L31–31
+ select import import select L27–27
+ write_branch_ref import import write_branch_ref L40–40
+ write_commit import import write_commit L40–40
+ write_object import import write_object L36–36
+ write_snapshot import import write_snapshot L40–40
+ repo function async_function repo L84–92
+ test_count_mismatch_raises_bundle_validation_error function async_function test_count_mismatch_raises_bundle_validation_error L268–292
+ test_hash_mismatch_raises_bundle_validation_error function async_function test_hash_mismatch_raises_bundle_validation_error L212–239
+ test_process_bundle_index_job_sets_quarantined_on_validation_error function async_function test_process_bundle_index_job_sets_quarantined_on_validation_error L406–441
+ test_quarantine_job_sets_status_and_reason function async_function test_quarantine_job_sets_status_and_reason L373–402
+ test_valid_bundle_passes_all_validation_checks function async_function test_valid_bundle_passes_all_validation_checks L445–461
+ test_validation_failure_writes_no_commits_to_db function async_function test_validation_failure_writes_no_commits_to_db L337–369
+ test_validation_failure_writes_no_objects_to_minio function async_function test_validation_failure_writes_no_objects_to_minio L296–333
+ test_zip_bomb_raises_bundle_validation_error function async_function test_zip_bomb_raises_bundle_validation_error L243–264
~ musehub/config.py .py 1 symbol modified
~ musehub/services/musehub_jobs.py .py 1 symbol added
+ quarantine_job function async_function quarantine_job L270–288
~ musehub/services/musehub_wire.py .py 1 symbol added, 2 symbols modified
+ BundleValidationError class class BundleValidationError L192–198
~ musehub/storage/backends.py .py 2 symbols added, 1 symbol modified
+ put_bundle method async_method put_bundle L388–400
+ quarantine_bundle method async_method quarantine_bundle L402–424
← Older Oldest on dev
All commits
Newer → Latest on dev

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:7189fd2a116a24aa69ce8efd79893929ac75aa42aeb6308678df94d00246a9c7 --body "your comment"