feat: muse#54 item 4 server side — musehub_reflog_entries
Server-side companion to the muse-repo commit implementing remote reflog sharing. Mirrors the existing version-tags precedent (musehub side of muse#57 item 4) rather than the content-addressed mpack format, since reflog entries are per-ref metadata, not content-addressed objects.
- New musehub_reflog_entries table (migration 0080): entry_id is a content hash of every field (repo_id, branch, old_id, new_id, timestamp, author, operation) rather than a mutable (repo_id, branch) pointer like version tags — reflog entries are immutable history, so storage is pure ON CONFLICT DO NOTHING append-only, never DO UPDATE. ix_musehub_reflog_entries_repo_branch composite index since every read is scoped to one branch's log. - musehub/services/musehub_reflog.py: store_reflog_entries()/ list_reflog_entries(), sole owner of the table, same boundary rules as musehub_version_tags.py (no state stores/SSE/LLM imports). - wire_push_reflog (POST /{owner}/{slug}/reflog) / wire_get_reflog (GET, same path) on the existing bare-path wire.py router. No force flag on push — there's nothing to conflict, unlike version tags' force-to-overwrite semantics. - New BranchQueryParam validator in api/validation.py: the existing BranchParam uses fastapi.Path(), which requires {branch} in the URL template; these routes carry branch as a query param instead (the route path has no {branch} segment), so a Query()-based twin with the same regex/length constraints was needed. - wire_get_reflog calls _assert_readable (the version-tags read route doesn't check this today — a gap noted while researching the precedent, deliberately not copied here since reflog entries can reveal private branch activity that repo visibility should still gate). - test_migrations.py: _ALL_REVISIONS/_HEAD bumped to include 0080.
Covered by tests/test_musehub_reflog_service.py (6 cases: round-trip, re-push dedup via content-hash entry_id, per-branch isolation, oldest-first ordering, empty-batch no-op, missing-new_id skipped silently). Full suite run: 80 tests (service + version-tags service + migrations + schema-check) all passing, confirming migration 0080 applies cleanly on top of 0079 and the ORM model matches the DB schema exactly (assert_schema_matches_orm). Containers restarted and verified clean boot (schema check passed, 74 tables; alembic current = 0080 head) before live end-to-end verification from the muse-repo side: pushed reflog entries with --reflog to a scratch repo on the real local hub, confirmed idempotent re-push, pulled into a fresh clone and confirmed the remote-tracking reflog received the correct entries.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Semantic Changes
48 symbols
Files Changed
+3
~4
1094 in snapshot
0 comments
muse hub commit comment sha256:80674069cfe8fe062c526a103e1cd0f855009d1cd06662ca3ae8393e1545a400 --body "your comment"
No comments yet. Be the first to start the discussion.