feat: rename legacy proposalType state_merge to canonical merge (musehub#229)
Follow-up to muse#20's Phase 3 split-out. Migration 0070 canonicalised merge_strategy's legacy values (state_overlay→overlay, state_weave→weave, state_rebase→replay, domain_selective→selective) but never touched the separate proposal_type column — ProposalType.STATE_MERGE was the one member left using the old state_* naming while the other six members already follow the plain-noun convention.
state_merge → merge
New migration 0082: - Backfills existing rows: UPDATE musehub_proposals SET proposal_type = 'merge' WHERE proposal_type = 'state_merge'. - Alters the column's server_default from 'state_merge' to 'merge', mirroring migration 0072's drift-fix pattern for merge_strategy (so future raw inserts default to the canonical value without relying on the application layer).
Enum and model (musehub/models/musehub.py): - ProposalType.STATE_MERGE renamed to ProposalType.MERGE (member name, not just value) — found two additional usages beyond the ticket's own audit (lines 915, 1007) by searching for ProposalType.STATE_MERGE symbol references, not just the string literal. - Two Field(...) defaults/docstrings updated (lines 1397, 1536).
DB model (musehub/db/musehub_social_models.py): column default/server_default updated to match the migration.
Service + MCP (musehub_proposals.py x3, write_tools/proposals.py, dispatcher.py, mcp/tools/musehub.py): all default-value fallbacks and the MCP tool's JSON-schema enum/default updated.
Templates (proposal_rows.html x2, proposal_row_detail.html x2, proposal_detail.html): comparison/fallback literals updated — these drive which type gets an empty "it's the default" badge vs an explicit label.
Fixtures and tests: scripts/seed_local_proposals.py, and six tests/test_proposal_*.py files with hardcoded "state_merge"/STATE_MERGE references updated throughout (including test_proposal_type_badge.py, currently skipped pending the unrelated musehub#96 design decision — still updated so it doesn't carry a stale literal once re-enabled).
Added a new invariant test in test_proposal_reimagination_phase1.py: no ProposalType member may use state_*/domain_* legacy naming, guarding against this exact drift recurring the next time a new type is added.
Deliberately left untouched: alembic/versions/0045_proposal_type_and_merge_strategy.py (the historical migration that originally created the column with server_default="state_merge" — it's a faithful record of what was true at that point in time, not something to rewrite) and two test functions whose names contain "state_merge" as a substring of "state_merged" (proposal *lifecycle* state, unrelated to proposal_type).
Verification: - Grep gate: zero "state_merge"/"STATE_MERGE" occurrences anywhere in the repo except the two deliberate exceptions above. - muse hub proposal list --json against the local dev hub confirms all 3 existing proposals read back as "proposalType": "merge" after running `alembic upgrade head` inside the musehub container. - Confirmed create_proposal's live (container-loaded) signature default is proposal_type: str = "merge" via direct inspection inside the running musehub container, proving the fix is live, not just on disk. - Both musehub and musehub_worker containers restarted and confirmed healthy post-migration (docker ps healthy, /healthz db:true, worker "MuseHub worker started").
Regression: 841 tests passed, 10 skipped (pre-existing, unrelated musehub#96 skip) across the full proposal, MCP dispatcher, and MCP write-tools test suites — no regressions.
Semantic Changes
51 symbols
Files Changed
+1
~16
1098 in snapshot
0 comments
muse hub commit comment sha256:e2af87b322a29648518e056674c1326acbc5ee7c49445ff2a38c0c3d667d62bb --body "your comment"
No comments yet. Be the first to start the discussion.