feat: wire IdentityPushValidator into the real push pipeline (musehub#230)
Audit: #227's own audit table (written for an unrelated naming-collision fix) claimed push_validator.py was "real, wired into wire_push, and actually rejects bad pushes" -- in contrast to quorum.py's dead code (#225). That contrast was wrong: grep for "IdentityPushValidator(" found only the class's own definition and its unit test -- zero production call sites. None of I1 (acyclicity), I2 (root distance), or I3 (authorization) were enforced server-side on any real push.
Design decision (confirmed via AskUserQuestion): wire it in now rather than confirm-and-document-as-deferred, given I3 is a genuine security/ authorization boundary, not just a data-integrity nicety.
Implementation: in wire_push_unpack_mpack (the real wire-push pipeline), after the snapshot-replay loop resolves the head snapshot's full manifest and before any row is committed, detect identity-domain repos (MusehubRepo.domain_id == "identity"), reconstruct the complete identities/relationships record set (reading content from this push's own decompressed blobs, falling back to existing stored objects for unchanged records from earlier commits), run IdentityPushValidator, and raise ValueError (-> HTTP 422 at the route layer, same pattern as the existing zip-bomb/blocked-hash/snapshot-integrity rejections in this function) when the result is invalid.
TDD: wrote an end-to-end test (test_identity_push_validator_wire_integration.py) pushing a real identity-domain commit containing a 2-node cycle (alice spawns bob, bob spawns alice -- an I1 violation) through the actual wire_push_unpack_mpack function, not just unit-testing the validator class directly. Confirmed genuine RED (push succeeded, cycle persisted) before the fix, GREEN after, plus a control test proving a valid acyclic push still succeeds. Re-confirmed via muse-dev shelf save/pop isolation on musehub_wire_push.py alone.
Corrected push_validator.py's own module docstring, which made the same "called by wire_push" claim while it was still false -- now true and cross-referenced to this ticket.
Regression: 329 passed across identity/graph-domain tests plus every existing wire-push test file (root-snapshot integrity, external-parent reconstruction, authz, mwp1-4/8 job-pipeline suites, multi-tip manifest union) -- no regressions in the push pipeline this change touches.
Note: musehub's org-management REST API (musehub_orgs.py, hardened separately in musehub#231) commits identity records via commit_files_to_repo, a server-authored path with its own _assert_org_write_access authorization check -- distinct from the wire push protocol this ticket wires validation into. I1/I2/I3 enforcement via IdentityPushValidator now covers the wire-push (muse CLI `push`) surface, which is this ticket's and push_validator.py's documented scope.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Semantic Changes
31 symbols
Files Changed
+1
~2
1101 in snapshot
0 comments
muse hub commit comment sha256:066f0f58448cc0553bff3c845cbb8e1f7a6bdecf53fce6bc5c2ff5e0ddad3d71 --body "your comment"
No comments yet. Be the first to start the discussion.