gabriel / musehub public
feat BREAKING intel task/detect-refactor-intel #1 / 1
AI Agent gabriel · 143 days ago · May 3, 2026 · Diff

feat(intel): detect-refactor page with pure-Python snapshot diff provider

- Migration 0016: add commit_message column + ix_intel_refactor_events_repo_kind composite index - Rewrite DetectRefactorProvider: HEAD-vs-parent snapshot diff using parse_symbols(), no _run_muse Detects: implementation (body_hash change), signature (sig_id change), move (same body, different file), rename (same body, same file, different name) - Add route /intel/refactoring with kind filter (all/implementation/signature/move/rename) and top 20/50/100 - Template intel_detect_refactor.html: spectral stat chips, kind badges, address cell, commit message column - SCSS .rf-* namespace: components/_detect_refactor.scss (visual) + pages/_detect_refactor.scss (layout) - Dashboard card: Detect Refactor card with kind counts and 5-event preview - 34 tests GREEN across 7 tiers (T1 DB, T2 provider, T3 route, T4 HTML, T5 integrity, T6 perf, T7 security)

Closes #22 (staging.musehub.ai)

sha256:edf260ee4878ac9d9b4f0c645f1ebb9d24af436f38fc7dcb8d7b22162807c83c sha
+81 ~4 symbols
sha256:3a5238b13ed7a76e4aacf526b77be2248aa1834b97eed5932a0e266808fbfafa snapshot
+81
symbols added
~4
symbols modified
0
dead code introduced
Semantic Changes 85 symbols
+ branch_labels variable variable branch_labels L19–19
+ depends_on variable variable depends_on L20–20
+ down_revision variable variable down_revision L18–18
+ downgrade function function downgrade L35–40
+ op import import op L14–14
+ sa import import sa L15–15
+ revision variable variable revision L17–17
+ upgrade function function upgrade L23–32
~ tests/test_intel_detect_refactor.py .py 68 symbols added
+ TestDBModel class class TestDBModel L208–239
+ test_T01_model_has_commit_message_column method method test_T01_model_has_commit_message_column L210–213
+ test_T02_commit_message_is_nullable method method test_T02_commit_message_is_nullable L215–218
+ test_T03_model_has_required_columns method method test_T03_model_has_required_columns L220–224
+ test_T04_cascade_delete_configured method method test_T04_cascade_delete_configured L226–233
+ test_T05_composite_index_exists method method test_T05_composite_index_exists L235–239
+ TestDataIntegrity class class TestDataIntegrity L623–708
+ test_T25_upsert_is_idempotent method async_method test_T25_upsert_is_idempotent L626–641
+ test_T26_cross_repo_isolation method async_method test_T26_cross_repo_isolation L644–666
+ test_T27_commit_message_stored method async_method test_T27_commit_message_stored L669–688
+ test_T28_cascade_delete_removes_events method async_method test_T28_cascade_delete_removes_events L691–708
+ TestHTML class class TestHTML L570–616
+ test_T20_kind_badges_appear_in_html method async_method test_T20_kind_badges_appear_in_html L573–580
+ test_T21_address_rendered_in_rows method async_method test_T21_address_rendered_in_rows L583–588
+ test_T22_stat_chip_values_match_db method async_method test_T22_stat_chip_values_match_db L591–598
+ test_T23_dashboard_link_present method async_method test_T23_dashboard_link_present L601–606
+ test_T24_dashboard_card_present method async_method test_T24_dashboard_card_present L609–616
+ TestPerformance class class TestPerformance L715–793
+ test_T29_provider_completes_under_5s method async_method test_T29_provider_completes_under_5s L718–757
+ test_T30_route_responds_under_500ms method async_method test_T30_route_responds_under_500ms L760–768
+ test_T31_bulk_insert_500_events method async_method test_T31_bulk_insert_500_events L771–793
+ TestProvider class class TestProvider L246–494
+ test_T06_provider_uses_no_subprocess method async_method test_T06_provider_uses_no_subprocess L249–260
+ test_T07_provider_detects_implementation_change method async_method test_T07_provider_detects_implementation_change L263–300
+ test_T08_provider_detects_signature_change method async_method test_T08_provider_detects_signature_change L303–339
+ test_T09_provider_detects_move method async_method test_T09_provider_detects_move L342–383
+ test_T10_provider_detects_rename method async_method test_T10_provider_detects_rename L386–423
+ test_T11_provider_returns_empty_when_no_parent method async_method test_T11_provider_returns_empty_when_no_parent L426–457
+ test_T12_provider_is_idempotent method async_method test_T12_provider_is_idempotent L460–494
+ TestRoute class class TestRoute L501–563
+ test_T13_refactor_page_returns_200 method async_method test_T13_refactor_page_returns_200 L504–509
+ test_T14_refactor_page_empty_state method async_method test_T14_refactor_page_empty_state L512–520
+ test_T15_refactor_page_404_for_unknown_repo method async_method test_T15_refactor_page_404_for_unknown_repo L523–528
+ test_T16_kind_filter_limits_results method async_method test_T16_kind_filter_limits_results L531–538
+ test_T17_top_filter_limits_results method async_method test_T17_top_filter_limits_results L541–546
+ test_T18_stat_chips_present_in_html method async_method test_T18_stat_chips_present_in_html L549–555
+ test_T19_invalid_top_does_not_500 method async_method test_T19_invalid_top_does_not_500 L558–563
+ TestSecurity class class TestSecurity L800–838
+ test_T32_xss_in_address_is_escaped method async_method test_T32_xss_in_address_is_escaped L803–819
+ test_T33_sql_injection_in_top_param_returns_200 method async_method test_T33_sql_injection_in_top_param_returns_200 L822–830
+ test_T34_unknown_kind_filter_returns_200 method async_method test_T34_unknown_kind_filter_returns_200 L833–838
+ _CID_A variable variable _CID_A L36–36
+ _CID_B variable variable _CID_B L37–37
+ _OBJ_1 variable variable _OBJ_1 L38–38
+ _OBJ_2 variable variable _OBJ_2 L39–39
+ _REF variable variable _REF L33–33
+ _SNAP_A variable variable _SNAP_A L34–34
+ _SNAP_B variable variable _SNAP_B L35–35
+ _insert_event function async_function _insert_event L46–83
+ _seed_two_commits function async_function _seed_two_commits L86–154
+ _sym function function _sym L157–176
+ AsyncClient import import AsyncClient L26–26
+ AsyncMock import import AsyncMock L20–20
+ AsyncSession import import AsyncSession L28–28
+ annotations import import annotations L16–16
+ create_repo import import create_repo L31–31
+ datetime import import datetime L19–19
+ dbm import import dbm L30–30
+ msgpack import import msgpack L22–22
+ patch import import patch L20–20
+ pg_insert import import pg_insert L27–27
+ pytest import import pytest L23–23
+ pytest_asyncio import import pytest_asyncio L24–24
+ sa import import sa L25–25
+ time import import time L18–18
+ timezone import import timezone L19–19
+ rf_repo function async_function rf_repo L180–201
+ session_insert_snapshot function async_function session_insert_snapshot L845–861
~ musehub/api/routes/musehub/ui_intel.py .py 3 symbols added, 1 symbol modified
+ _VALID_RF_KINDS variable variable _VALID_RF_KINDS L2669–2669
+ _VALID_RF_TOPS variable variable _VALID_RF_TOPS L2668–2668
+ intel_detect_refactor_page function async_function intel_detect_refactor_page L2673–2781
~ musehub/services/musehub_intel_providers.py .py 2 symbols added, 2 symbols modified
+ _is_tracked method method _is_tracked L1972–1978
+ _manifest_symbols method async_method _manifest_symbols L1981–2011
← Older Oldest on task/detect-refactor-intel
All commits
Newer → Latest on task/detect-refactor-intel

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