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

feat(intel): Breakage page — pure-Python BreakageProvider, migration 0017, route, template, SCSS, dashboard card (issue #23)

- Migration 0017: musehub_intel_breakage_issues + musehub_intel_breakage_meta tables - MusehubIntelBreakageIssue + MusehubIntelBreakageMeta ORM models - BreakageProvider: pure-Python stale-import detection (no subprocess) - Pass 1 builds known_symbol_names set from all non-import symbols - Pass 2 flags imports whose module doesn't resolve AND symbol is unknown - Stable issue_id (blob_id hash) makes upserts idempotent - Meta row tracks total/warning/error/file counts for stat chips - intel_breakage_page route at GET /{owner}/{repo_slug}/intel/breakage with ?type and ?top filter params - intel_breakage.html template: 4 stat chips, type/top filter bar, issue list - .bk-* SCSS namespace: components/_breakage.scss (visual) + pages/_breakage.scss (layout) - Dashboard card: Breakage card with severity summary and 5-row preview - 34 tests across 7 tiers: all GREEN

sha256:fa39321be107eb4e11ccf4454be3851d95355eb8233bdd23a0f4b738219ebdcf sha
+82 ~3 symbols
sha256:13984f8bd71c295e13ee04eef1df38be8947c62e902eef021ba7e23c5352b3e9 snapshot
+82
symbols added
~3
symbols modified
0
dead code introduced
Semantic Changes 85 symbols
+ branch_labels variable variable branch_labels L20–20
+ depends_on variable variable depends_on L21–21
+ down_revision variable variable down_revision L19–19
+ downgrade function function downgrade L67–71
+ op import import op L15–15
+ sa import import sa L16–16
+ revision variable variable revision L18–18
+ upgrade function function upgrade L24–64
~ tests/test_intel_breakage.py .py 67 symbols added
+ TestDBModel class class TestDBModel L210–246
+ test_T01_issue_model_has_required_columns method method test_T01_issue_model_has_required_columns L212–216
+ test_T02_meta_model_has_required_columns method method test_T02_meta_model_has_required_columns L218–222
+ test_T03_cascade_delete_on_issue method method test_T03_cascade_delete_on_issue L224–231
+ test_T04_cascade_delete_on_meta method method test_T04_cascade_delete_on_meta L233–240
+ test_T05_composite_index_exists method method test_T05_composite_index_exists L242–246
+ TestDataIntegrity class class TestDataIntegrity L602–665
+ test_T25_upsert_is_idempotent method async_method test_T25_upsert_is_idempotent L605–621
+ test_T26_cross_repo_isolation method async_method test_T26_cross_repo_isolation L624–640
+ test_T27_severity_stored_correctly method async_method test_T27_severity_stored_correctly L643–658
+ test_T28_type_index_exists method async_method test_T28_type_index_exists L661–665
+ TestHTML class class TestHTML L549–595
+ test_T20_severity_badge_in_html method async_method test_T20_severity_badge_in_html L552–557
+ test_T21_stat_chips_rendered method async_method test_T21_stat_chips_rendered L560–567
+ test_T22_file_paths_rendered_in_rows method async_method test_T22_file_paths_rendered_in_rows L570–576
+ test_T23_empty_state_has_helpful_message method async_method test_T23_empty_state_has_helpful_message L579–586
+ test_T24_dashboard_card_links_to_breakage_page method async_method test_T24_dashboard_card_links_to_breakage_page L589–595
+ TestPerformance class class TestPerformance L672–739
+ test_T29_provider_completes_under_5s method async_method test_T29_provider_completes_under_5s L675–704
+ test_T30_route_responds_under_2s method async_method test_T30_route_responds_under_2s L707–715
+ test_T31_bulk_upsert_500_issues method async_method test_T31_bulk_upsert_500_issues L718–739
+ TestProvider class class TestProvider L253–475
+ test_T06_provider_uses_no_subprocess method async_method test_T06_provider_uses_no_subprocess L256–276
+ test_T07_provider_detects_stale_import method async_method test_T07_provider_detects_stale_import L279–317
+ test_T08_known_symbol_bypasses_stale_flag method async_method test_T08_known_symbol_bypasses_stale_flag L320–353
+ test_T09_resolved_module_bypasses_stale_flag method async_method test_T09_resolved_module_bypasses_stale_flag L356–388
+ test_T10_provider_returns_empty_on_empty_manifest method async_method test_T10_provider_returns_empty_on_empty_manifest L391–404
+ test_T11_provider_is_idempotent method async_method test_T11_provider_is_idempotent L407–434
+ test_T12_provider_writes_meta_row method async_method test_T12_provider_writes_meta_row L437–475
+ TestRoute class class TestRoute L482–542
+ test_T13_breakage_page_returns_200 method async_method test_T13_breakage_page_returns_200 L485–490
+ test_T14_breakage_page_empty_state method async_method test_T14_breakage_page_empty_state L493–501
+ test_T15_breakage_page_404_for_unknown_repo method async_method test_T15_breakage_page_404_for_unknown_repo L504–509
+ test_T16_type_filter_limits_results method async_method test_T16_type_filter_limits_results L512–518
+ test_T17_top_filter_limits_results method async_method test_T17_top_filter_limits_results L521–526
+ test_T18_stat_chips_present_in_html method async_method test_T18_stat_chips_present_in_html L529–534
+ test_T19_invalid_top_does_not_500 method async_method test_T19_invalid_top_does_not_500 L537–542
+ TestSecurity class class TestSecurity L746–782
+ test_T32_xss_in_file_path_is_escaped method async_method test_T32_xss_in_file_path_is_escaped L749–766
+ test_T33_sql_injection_in_top_param method async_method test_T33_sql_injection_in_top_param L769–774
+ test_T34_unknown_type_does_not_500 method async_method test_T34_unknown_type_does_not_500 L777–782
+ _CID variable variable _CID L35–35
+ _OBJ_1 variable variable _OBJ_1 L36–36
+ _OBJ_2 variable variable _OBJ_2 L37–37
+ _REF variable variable _REF L33–33
+ _SNAP variable variable _SNAP L34–34
+ _fn_sym function function _fn_sym L168–185
+ _import_sym function function _import_sym L147–165
+ _insert_issue function async_function _insert_issue L44–75
+ _insert_meta function async_function _insert_meta L78–107
+ _seed_commit function async_function _seed_commit L110–144
+ bk_repo function async_function bk_repo L189–203
+ 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
~ musehub/api/routes/musehub/ui_intel.py .py 3 symbols added, 1 symbol modified
+ _VALID_BK_TOPS variable variable _VALID_BK_TOPS L2820–2820
+ _VALID_BK_TYPES variable variable _VALID_BK_TYPES L2821–2821
+ intel_breakage_page function async_function intel_breakage_page L2825–2922
~ musehub/db/musehub_models.py .py 2 symbols added
+ MusehubIntelBreakageIssue class class MusehubIntelBreakageIssue L1870–1902
+ MusehubIntelBreakageMeta class class MusehubIntelBreakageMeta L1905–1932
~ musehub/services/musehub_intel_providers.py .py 2 symbols added, 2 symbols modified
+ BreakageProvider class class BreakageProvider L2216–2403
+ compute method async_method compute L2253–2403
← Older Oldest on task/breakage-intel
All commits
Newer → Latest on task/breakage-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:fa39321be107eb4e11ccf4454be3851d95355eb8233bdd23a0f4b738219ebdcf --body "your comment"