gabriel / musehub public
fix patch musehub#134 fix/wire-push-external-parent-manifest #2 / 4
AI Agent gabriel · 9 days ago · Jul 7, 2026 · Diff

fix(musehub#134): reconstruct external delta-only parent instead of {}

wire_push_unpack_mpack's external-parent resolution only checked manifest_blob directly. When a pushed snapshot's parent was already on the server from an earlier push and stored delta-only (the normal case for any non-root/non-head snapshot), the lookup silently fell back to an empty dict, and the child's manifest permanently dropped every inherited file -- content that can never hash back to its own snapshot_id again. This is the root cause of the staging gabriel/musehub clone corruption blocking aaronrene (musehub#84) and matching the pattern in muse#35.

Two-part fix: 1. When the direct manifest_blob lookup misses, fall back to _reconstruct_manifest_validated (delta-chain walk) instead of {}. 2. Hash-verify every resolved snapshot base against its own snapshot_id before writing. A parent that is genuinely unrecoverable (e.g. a phantom reference with no backing row at all -- confirmed on the real staging RDS instance) now rejects the push loudly instead of silently persisting a manifest that will never verify again.

TDD: tests/test_wire_push_external_parent_reconstruction.py, 2 tests, red-first. Calls wire_push_unpack_mpack directly with a hand-built payload -- the only reliable way to force the external-parent path, since muse push's have-negotiation (literal branch-tip match, no ancestor-closure expansion) makes a CLI-level integration test resend the whole chain, masking the bug (see test_push_delta_only_parent_manifest.py, which passes without exercising it).

Full wire-push regression sweep: 211 passed (42 direct + 169 broader mpack/ push/intel suite).

sha256:281d7e2bfa6d4378354b0287c78e3bf1902581c486d072d3352c9d645ba81f63 sha
+3 ~18 symbols
sha256:aa0d42fd3ec2312635da51795070e21ed5275be900c730ba267891cb0bc85e92 snapshot
+3
symbols added
~18
symbols modified
0
dead code introduced
Semantic Changes 21 symbols
+ test_push_rejected_when_external_parent_is_a_total_phantom function async_function test_push_rejected_when_external_parent_is_a_total_phantom L238–295

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:281d7e2bfa6d4378354b0287c78e3bf1902581c486d072d3352c9d645ba81f63 --body "your comment"