gabriel / muse public
fix BREAKING main #31 / 55
AI Agent gabriel · 119 days ago · May 8, 2026 · Diff

fix: use canonical MWP wire field names in push O-frames

split_object_into_oc_frames was emitting 'object_id', 'encoding', and 'base_id' — the server push handler reads 'id', 'enc', and 'base' (same names mpack.py has always written for fetch frames). When a delta+zlib object was pushed via the stream path, enc fell through to 'raw', the server hashed the raw delta bytes instead of the reconstructed content, and sha256(delta_bytes) != declared_object_id → hash mismatch.

Also fix client-side fetch receive path: was reading 'base_id' from server O-frames; server writes 'base'.

Add TestSplitObjectIntoOcFrames to pin all three field names as a wire contract so a future rename breaks the tests before it breaks pushes.

sha256:131a9fc3542965349f2ee21922782a57d97e842418b432abc6976064b64426f1 sha
+40 ~10 symbols
sha256:ebe5153947b3d15f5e88bd8b54324d1904e672d482e98ea626b0c0d0dba00575 snapshot
+40
symbols added
~10
symbols modified
0
dead code introduced
Semantic Changes 50 symbols
~ DEBUG_PUSH_HASH_MISMATCH.md .md 32 symbols added
+ Push Hash Mismatch — Debug Log section Push Hash Mismatch — Debug Log L1–199
+ Atomic test plan section Atomic test plan L86–128
+ Level 0 — Unit: server correctly parses an O-frame section Level 0 — Unit: server correctly parses an O-frame L90–100
+ code@L92 variable variable code@L92 L92–97
+ Level 1 — Unit: delta+zlib reconstruction produces correct hash section Level 1 — Unit: delta+zlib reconstruction produces correct hash L100–110
+ code@L102 variable variable code@L102 L102–107
+ Level 2 — Integration: push a single delta object through stream path section Level 2 — Integration: push a single delta object through stream path L110–118
+ code@L112 variable variable code@L112 L112–117
+ Level 3 — End-to-end: muse push staging main with delta objects section Level 3 — End-to-end: muse push staging main with delta objects L118–128
+ code@L120 variable variable code@L120 L120–125
+ Ceiling: presign path latent bug section Ceiling: presign path latent bug L150–192
+ Fix for next ceiling section Fix for next ceiling L170–192
+ code[python]@L177 variable variable code[python]@L177 L177–185
+ code[python]@L186 variable variable code[python]@L186 L186–189
+ What happens on presign path today section What happens on presign path today L154–170
+ code[python]@L161 variable variable code[python]@L161 L161–164
+ Fix section Fix L128–150
+ code[python]@L134 variable variable code[python]@L134 L134–147
+ Root cause: field name mismatch between client and server section Root cause: field name mismatch between client and server L50–86
+ py:273) section Client O-frame (transport.py:273) L52–65
+ code[python]@L54 variable variable code[python]@L54 L54–64
+ py:1749) section Server push handler (musehub_wire.py:1749) L65–77
+ code[python]@L67 variable variable code[python]@L67 L67–73
+ What happens section What happens L77–86
+ Status section Status L192–199
+ What we know section What we know L12–50
+ The object is correct locally section The object is correct locally L14–23
+ code[bash]@L16 variable variable code[bash]@L16 L16–20
+ The push sent delta+zlib objects section The push sent delta+zlib objects L28–37
+ The push used the stream path (not presign) section The push used the stream path (not presign) L23–28
+ The server computed a wrong hash section The server computed a wrong hash L37–50
+ code@L4 variable variable code@L4 L4–7
~ tests/test_core_transport.py .py 8 symbols added, 7 symbols modified
+ TestSplitObjectIntoOcFrames class class TestSplitObjectIntoOcFrames L579–650
+ _make_obj method method _make_obj L587–601
+ test_chunked_object_first_chunk_uses_enc method method test_chunked_object_first_chunk_uses_enc L640–650
+ test_delta_object_uses_base_not_base_id method method test_delta_object_uses_base_not_base_id L621–631
+ test_raw_object_no_base_field method method test_raw_object_no_base_field L633–638
+ test_raw_object_uses_enc_not_encoding method method test_raw_object_uses_enc_not_encoding L613–619
+ test_raw_object_uses_id_not_object_id method method test_raw_object_uses_id_not_object_id L603–611
+ split_object_into_oc_frames import import split_object_into_oc_frames L18–18

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:131a9fc3542965349f2ee21922782a57d97e842418b432abc6976064b64426f1 --body "your comment"