gabriel / musehub public
perf BREAKING task/symbol-detail-fast-reads #1 / 1
AI Agent gabriel · 129 days ago · May 6, 2026 · Diff

perf: pre-compute symbol vitals+coupling at push time

- Add MusehubSymbolVitals table (first_introduced, change_count, version_count, op breakdown) - Add MusehubSymbolCoupling table (address, co_address, shared_commits) - Add message + commit_branch columns to MusehubSymbolHistoryEntry - Indexer writes all three at push time (build_symbol_index) - Route reads pre-computed rows; drops load_symbol_history(file_path=...) and GROUP BY coupling query - Commit metadata join now only fetches agent_id/model_id/signature (not message/branch/author) - Migration 0031 adds new tables and columns - 31 TDD tests green

sha256:95e4856bafc4f305b745995afc74639c7e59c28e2926147a6958e9f31ba75ef7 sha
+71 ~4 symbols
sha256:5184a4d4505a48bb2db957d60992f4d0de5b469394cc841c830fc73203d9395c snapshot
+71
symbols added
~4
symbols modified
0
dead code introduced
Semantic Changes 75 symbols
+ branch_labels variable variable branch_labels L24–24
+ depends_on variable variable depends_on L25–25
+ down_revision variable variable down_revision L23–23
+ downgrade function function downgrade L62–68
+ annotations import import annotations L17–17
+ op import import op L19–19
+ sa import import sa L20–20
+ revision variable variable revision L22–22
+ upgrade function function upgrade L28–59
+ TestEdgeCases class class TestEdgeCases L887–1006
+ test_D401_no_vitals_row_falls_back_gracefully method async_method test_D401_no_vitals_row_falls_back_gracefully L890–913
+ test_D402_no_coupling_rows_renders_empty_section method async_method test_D402_no_coupling_rows_renders_empty_section L915–938
+ test_D403_coupling_pagination_second_page method async_method test_D403_coupling_pagination_second_page L940–969
+ test_D404_vitals_op_breakdown_correct method async_method test_D404_vitals_op_breakdown_correct L971–980
+ test_D405_coupling_page_beyond_end_returns_200 method async_method test_D405_coupling_page_beyond_end_returns_200 L982–1006
+ TestHistoryEntrySchema class class TestHistoryEntrySchema L149–221
+ test_D101_message_column_exists method async_method test_D101_message_column_exists L152–174
+ test_D102_commit_branch_column_exists method async_method test_D102_commit_branch_column_exists L176–198
+ test_D103_message_and_branch_nullable method async_method test_D103_message_and_branch_nullable L200–221
+ TestIndexerDenormalizesCommitMessage class class TestIndexerDenormalizesCommitMessage L718–785
+ test_D220_history_entry_has_message method async_method test_D220_history_entry_has_message L721–752
+ test_D221_history_entry_has_commit_branch method async_method test_D221_history_entry_has_commit_branch L754–785
+ TestIndexerPopulatesCoupling class class TestIndexerPopulatesCoupling L569–715
+ test_D210_coupling_written_for_co_changed_symbols method async_method test_D210_coupling_written_for_co_changed_symbols L572–605
+ test_D211_coupling_is_symmetric method async_method test_D211_coupling_is_symmetric L607–639
+ test_D212_coupling_count_accumulates_across_commits method async_method test_D212_coupling_count_accumulates_across_commits L641–679
+ test_D213_rebuild_is_idempotent method async_method test_D213_rebuild_is_idempotent L681–715
+ TestIndexerPopulatesVitals class class TestIndexerPopulatesVitals L453–566
+ test_D201_vitals_written_after_index_build method async_method test_D201_vitals_written_after_index_build L456–488
+ test_D202_vitals_change_count_increments_on_rebuild method async_method test_D202_vitals_change_count_increments_on_rebuild L490–527
+ test_D203_vitals_first_introduced_is_earliest_commit method async_method test_D203_vitals_first_introduced_is_earliest_commit L529–566
+ TestRouteUsesPrecomputedData class class TestRouteUsesPrecomputedData L792–880
+ test_D301_page_renders_change_count_from_vitals method async_method test_D301_page_renders_change_count_from_vitals L795–825
+ test_D302_page_renders_coupling_from_coupling_table method async_method test_D302_page_renders_coupling_from_coupling_table L827–853
+ test_D303_history_timeline_needs_no_commit_join method async_method test_D303_history_timeline_needs_no_commit_join L855–880
+ TestSymbolCouplingSchema class class TestSymbolCouplingSchema L329–446
+ test_D120_table_exists method async_method test_D120_table_exists L332–334
+ test_D121_insert_and_fetch method async_method test_D121_insert_and_fetch L336–350
+ test_D122_ordered_by_shared_commits_desc method async_method test_D122_ordered_by_shared_commits_desc L352–370
+ test_D123_pagination_with_limit_offset method async_method test_D123_pagination_with_limit_offset L372–404
+ test_D124_cascade_delete_with_repo method async_method test_D124_cascade_delete_with_repo L406–418
+ test_D125_primary_key_is_repo_address_co_address method async_method test_D125_primary_key_is_repo_address_co_address L420–446
+ TestSymbolVitalsSchema class class TestSymbolVitalsSchema L224–326
+ test_D110_table_exists method async_method test_D110_table_exists L227–229
+ test_D111_insert_and_fetch method async_method test_D111_insert_and_fetch L231–256
+ test_D112_first_introduced_is_datetime method async_method test_D112_first_introduced_is_datetime L258–270
+ test_D113_primary_key_is_repo_and_address method async_method test_D113_primary_key_is_repo_and_address L272–312
+ test_D114_cascade_delete_with_repo method async_method test_D114_cascade_delete_with_repo L314–326
+ _cid function function _cid L62–63
+ _insert_coupling function async_function _insert_coupling L127–142
+ _insert_history function async_function _insert_history L70–95
+ _insert_vitals function async_function _insert_vitals L98–124
+ _lid function function _lid L66–67
+ _now function function _now L58–59
+ AsyncClient import import AsyncClient L45–45
+ AsyncSession import import AsyncSession L47–47
+ _dt import import _dt L40–40
+ annotations import import annotations L38–38
+ blob_id import import blob_id L50–50
+ create_repo import import create_repo L51–51
+ db import import db L49–49
+ long_id import import long_id L50–50
+ pytest import import pytest L44–44
+ secrets import import secrets L41–41
+ select import import select L46–46
+ text import import text L46–46
+ timezone import import timezone L42–42
~ musehub/db/musehub_models.py .py 2 symbols added, 1 symbol modified
+ MusehubSymbolCoupling class class MusehubSymbolCoupling L1124–1143
+ MusehubSymbolVitals class class MusehubSymbolVitals L1097–1121
~ musehub/services/musehub_symbol_indexer.py .py 2 symbols added, 2 symbols modified
+ _upsert_symbol_coupling function async_function _upsert_symbol_coupling L514–566
+ _upsert_symbol_vitals function async_function _upsert_symbol_vitals L442–511
← Older Oldest on task/symbol-detail-fast-reads
All commits
Newer → Latest on task/symbol-detail-fast-reads

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