"""TDD tests for ImplicitEdgeCache — persistent per-file framework-edge cache. Architecture ------------ ``build_implicit_edge_graph`` re-reads every Python blob and re-runs all framework plugins (FastAPI, Flask, Celery) on every invocation: ~10 s for the 779-file muse repo. The result is fully determined by the file content — same bytes always produce the same list of ``ImplicitEntryEdge`` objects. ``ImplicitEdgeCache`` mirrors ``CallGraphCache`` exactly: * Key: SHA-256 of file bytes (``object_id`` from the manifest). * Value: list of ``ImplicitEntryEdge`` dicts for the file (serialised as plain dicts in JSON; restored as dataclass instances on load so callers always receive ``ImplicitEntryEdge`` objects). * File: ``.muse/cache/implicit_edges.json`` (JSON, atomic write). * API: ``load(muse_dir)`` / ``empty()`` / ``get`` / ``put`` / ``prune`` / ``size`` / ``save`` + convenience ``load_implicit_edge_cache(root)``. Coverage matrix --------------- - Memory operations: get/put/dirty/size/prune/empty - Persistence: save creates file; save/load round-trip with full edge fidelity; no-dirty skip; dirty=False after save; second save is no-op; atomic write (no .tmp leftover) - Graceful load: missing file → empty; corrupt → empty; wrong version → empty; invalid entry skipped, valid survive; non-str field skipped - Convenience helper: load_implicit_edge_cache with and without .muse dir - Integration cold: build_implicit_edge_graph produces correct graph without cache - Integration warm: pre-populated cache skips read_object entirely - Integration save: after build, cache populated; build does NOT auto-save - Non-Python files: not cached, not processed - Correctness: warm graph == cold graph (same edges, same metadata) - Performance: warm call ≥ 5× faster than cold; < 200 ms for 30-file repo """ from __future__ import annotations from collections.abc import Mapping import pathlib import textwrap import time from dataclasses import asdict from unittest.mock import patch import pytest from muse.core.object_store import write_object from muse.core.types import Manifest, blob_id from muse.core.paths import muse_dir from muse.plugins.code._framework import ImplicitEntryEdge # --------------------------------------------------------------------------- # Helpers # --------------------------------------------------------------------------- def _muse_dir(tmp_path: pathlib.Path) -> pathlib.Path: d = muse_dir(tmp_path) d.mkdir(exist_ok=True) (d / "cache").mkdir(exist_ok=True) return d def _write_blob(root: pathlib.Path, source: str) -> str: """Write source bytes to the object store; return canonical object_id.""" raw = source.encode() oid = blob_id(raw) write_object(root, oid, raw) return oid def _make_manifest(root: pathlib.Path, files: Mapping[str, str]) -> Manifest: return {rel: _write_blob(root, src) for rel, src in files.items()} def _edge( symbol_address: str = "app.py::handle", framework_id: str = "fastapi", kind: str = "http-route", metadata: dict[str, str] | None = None, ) -> ImplicitEntryEdge: return ImplicitEntryEdge( framework_id=framework_id, symbol_address=symbol_address, kind=kind, metadata=metadata or {"method": "GET", "path": "/"}, ) # --------------------------------------------------------------------------- # TestImplicitEdgeCacheMemory # --------------------------------------------------------------------------- class TestImplicitEdgeCacheMemory: """In-memory get/put/prune/size/empty operations.""" def test_empty_get_miss(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache assert ImplicitEdgeCache.empty().get("no_such_id") is None def test_put_then_get_hit(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() edges = [_edge("app.py::create"), _edge("app.py::delete", kind="http-route")] cache.put("abc123", edges) result = cache.get("abc123") assert result == edges def test_put_marks_dirty(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() assert not cache._dirty cache.put("id1", []) assert cache._dirty def test_different_ids_independent(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() e1 = [_edge("a.py::fn_a")] e2 = [_edge("b.py::fn_b", framework_id="flask")] cache.put("id_a", e1) cache.put("id_b", e2) assert cache.get("id_a") == e1 assert cache.get("id_b") == e2 def test_put_same_id_overwrites(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() cache.put("same", [_edge("a.py::old")]) cache.put("same", [_edge("a.py::new")]) result = cache.get("same") assert result[0].symbol_address == "a.py::new" assert cache.size == 1 def test_size_starts_zero(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache assert ImplicitEdgeCache.empty().size == 0 def test_size_grows_with_put(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() cache.put("x", []) cache.put("y", [_edge()]) assert cache.size == 2 def test_empty_list_is_valid(self) -> None: """Files with no framework entry-points cache an empty list.""" from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() cache.put("plain_file", []) assert cache.get("plain_file") == [] def test_prune_removes_stale(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() cache.put("keep", [_edge()]) cache.put("drop", []) cache.prune({"keep"}) assert cache.get("keep") is not None assert cache.get("drop") is None def test_prune_marks_dirty_when_stale(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() cache.put("drop", []) cache._dirty = False cache.prune(set()) assert cache._dirty def test_prune_no_stale_not_dirty(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() cache.put("keep", []) cache._dirty = False cache.prune({"keep"}) assert not cache._dirty def test_empty_save_is_noop(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() cache.put("id", [_edge()]) cache.save() # muse_dir is None — must not raise assert not any(tmp_path.rglob("implicit_edges.json")) def test_get_returns_implicit_entry_edge_instances(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() e = _edge() cache.put("id", [e]) result = cache.get("id") assert all(isinstance(r, ImplicitEntryEdge) for r in result) def test_metadata_preserved_in_memory(self) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache cache = ImplicitEdgeCache.empty() e = _edge(metadata={"method": "POST", "path": "/items/{id}"}) cache.put("id", [e]) result = cache.get("id") assert result[0].metadata == {"method": "POST", "path": "/items/{id}"} # --------------------------------------------------------------------------- # TestImplicitEdgeCachePersistence # --------------------------------------------------------------------------- class TestImplicitEdgeCachePersistence: """save() / load() round-trip via .muse/cache/implicit_edges.json.""" def test_save_creates_file(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) cache = ImplicitEdgeCache.load(md) cache.put("id1", [_edge()]) cache.save() assert (md / "cache" / "implicit_edges.json").is_file() def test_save_then_load_round_trip(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) edges = [ _edge("routes.py::create_item", kind="http-route", metadata={"method": "POST", "path": "/items"}), _edge("routes.py::list_items", kind="http-route", metadata={"method": "GET", "path": "/items"}), ] oid = "deadbeef" * 8 cache = ImplicitEdgeCache.load(md) cache.put(oid, edges) cache.save() loaded = ImplicitEdgeCache.load(md) result = loaded.get(oid) assert result is not None assert len(result) == 2 assert all(isinstance(e, ImplicitEntryEdge) for e in result) assert result == edges def test_round_trip_preserves_all_fields(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) e = ImplicitEntryEdge( framework_id="celery", symbol_address="tasks.py::send_email", kind="task", metadata={"queue": "emails"}, ) cache = ImplicitEdgeCache.load(md) cache.put("id", [e]) cache.save() loaded = ImplicitEdgeCache.load(md) result = loaded.get("id")[0] assert result.framework_id == "celery" assert result.symbol_address == "tasks.py::send_email" assert result.kind == "task" assert result.metadata == {"queue": "emails"} def test_empty_list_round_trips(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) cache = ImplicitEdgeCache.load(md) cache.put("plain", []) cache.save() loaded = ImplicitEdgeCache.load(md) assert loaded.get("plain") == [] def test_save_no_dirty_skips_write(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) ImplicitEdgeCache.load(md).save() assert not (md / "cache" / "implicit_edges.json").is_file() def test_save_clears_dirty_flag(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) cache = ImplicitEdgeCache.load(md) cache.put("id", []) cache.save() assert not cache._dirty def test_second_save_is_noop(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) cache = ImplicitEdgeCache.load(md) cache.put("id", [_edge()]) cache.save() mtime1 = (md / "cache" / "implicit_edges.json").stat().st_mtime_ns cache.save() mtime2 = (md / "cache" / "implicit_edges.json").stat().st_mtime_ns assert mtime1 == mtime2 def test_atomic_write_no_tmp_leftover(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) cache = ImplicitEdgeCache.load(md) cache.put("id", [_edge()]) cache.save() assert not any((md / "cache").glob("*.tmp")) def test_orphaned_tmp_swept_on_startup(self, tmp_path: pathlib.Path) -> None: """A stale ``.implicit_edges_*.tmp`` left by a crash is removed by the startup sweep.""" from muse.core.repo import _cleanup_muse_dir_temps md = _muse_dir(tmp_path) orphan = md / "cache" / ".implicit_edges_abc123.tmp" orphan.write_bytes(b"stale") _cleanup_muse_dir_temps(md) assert not orphan.exists() def test_multiple_entries_survive_round_trip(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) cache = ImplicitEdgeCache.load(md) entries = { "id_a": [_edge("a.py::fn", "fastapi", "http-route", {"method": "GET", "path": "/"})], "id_b": [], "id_c": [_edge("c.py::task", "celery", "task", {"queue": "default"})], } for oid, edges in entries.items(): cache.put(oid, edges) cache.save() loaded = ImplicitEdgeCache.load(md) for oid, edges in entries.items(): assert loaded.get(oid) == edges # --------------------------------------------------------------------------- # TestImplicitEdgeCacheGracefulLoad # --------------------------------------------------------------------------- class TestImplicitEdgeCacheGracefulLoad: """load() never raises — returns empty cache on any error.""" def test_absent_file_returns_empty(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache assert ImplicitEdgeCache.load(_muse_dir(tmp_path)).size == 0 def test_corrupt_file_returns_empty(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) (md / "cache").mkdir(parents=True, exist_ok=True) (md / "cache" / "implicit_edges.json").write_bytes(b"not valid JSON !!!") assert ImplicitEdgeCache.load(md).size == 0 def test_wrong_version_returns_empty(self, tmp_path: pathlib.Path) -> None: import json as _json from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) doc = {"version": 999, "entries": {}} (md / "cache").mkdir(parents=True, exist_ok=True) (md / "cache" / "implicit_edges.json").write_bytes(_json.dumps(doc).encode()) assert ImplicitEdgeCache.load(md).size == 0 def test_non_dict_entries_returns_empty(self, tmp_path: pathlib.Path) -> None: import json as _json from muse.core.implicit_edge_cache import ImplicitEdgeCache md = _muse_dir(tmp_path) doc = {"version": 1, "entries": "not a dict"} (md / "cache").mkdir(parents=True, exist_ok=True) (md / "cache" / "implicit_edges.json").write_bytes(_json.dumps(doc).encode()) assert ImplicitEdgeCache.load(md).size == 0 def test_invalid_entry_skipped_valid_survive(self, tmp_path: pathlib.Path) -> None: import json as _json from muse.core.implicit_edge_cache import ImplicitEdgeCache, _CACHE_VERSION md = _muse_dir(tmp_path) valid_edge = { "framework_id": "fastapi", "symbol_address": "a.py::fn", "kind": "http-route", "metadata": {"method": "GET", "path": "/"}, } doc = { "version": _CACHE_VERSION, "entries": { "good_id": [valid_edge], "bad_id": "not_a_list", # whole entry is invalid "empty_id": [], # valid — no edges }, } (md / "cache").mkdir(parents=True, exist_ok=True) (md / "cache" / "implicit_edges.json").write_bytes(_json.dumps(doc).encode()) cache = ImplicitEdgeCache.load(md) good = cache.get("good_id") assert good is not None and len(good) == 1 assert isinstance(good[0], ImplicitEntryEdge) assert cache.get("bad_id") is None assert cache.get("empty_id") == [] def test_edge_missing_required_field_skipped(self, tmp_path: pathlib.Path) -> None: import json as _json from muse.core.implicit_edge_cache import ImplicitEdgeCache, _CACHE_VERSION md = _muse_dir(tmp_path) bad_edge = {"framework_id": "fastapi", "symbol_address": "a.py::fn"} # missing kind doc = {"version": _CACHE_VERSION, "entries": {"bad": [bad_edge]}} (md / "cache").mkdir(parents=True, exist_ok=True) (md / "cache" / "implicit_edges.json").write_bytes(_json.dumps(doc).encode()) assert ImplicitEdgeCache.load(md).get("bad") is None def test_edge_non_str_field_skipped(self, tmp_path: pathlib.Path) -> None: import json as _json from muse.core.implicit_edge_cache import ImplicitEdgeCache, _CACHE_VERSION md = _muse_dir(tmp_path) bad_edge = { "framework_id": 123, # must be str "symbol_address": "a.py::fn", "kind": "http-route", "metadata": {}, } doc = {"version": _CACHE_VERSION, "entries": {"bad": [bad_edge]}} (md / "cache").mkdir(parents=True, exist_ok=True) (md / "cache" / "implicit_edges.json").write_bytes(_json.dumps(doc).encode()) assert ImplicitEdgeCache.load(md).get("bad") is None # --------------------------------------------------------------------------- # TestLoadImplicitEdgeCache — convenience helper # --------------------------------------------------------------------------- class TestLoadImplicitEdgeCache: def test_no_muse_dir_returns_empty(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import load_implicit_edge_cache assert load_implicit_edge_cache(tmp_path).size == 0 def test_with_muse_dir_loads_existing(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache, load_implicit_edge_cache md = _muse_dir(tmp_path) seed = ImplicitEdgeCache.load(md) seed.put("myid", [_edge("m.py::fn")]) seed.save() cache = load_implicit_edge_cache(tmp_path) result = cache.get("myid") assert result is not None and result[0].symbol_address == "m.py::fn" def test_with_empty_muse_dir_returns_empty(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import load_implicit_edge_cache _muse_dir(tmp_path) assert load_implicit_edge_cache(tmp_path).size == 0 # --------------------------------------------------------------------------- # TestBuildImplicitEdgeGraphWithCache — integration # --------------------------------------------------------------------------- _FASTAPI_SOURCE = textwrap.dedent("""\ from fastapi import APIRouter router = APIRouter() @router.get("/items") def list_items(): return [] @router.post("/items") def create_item(): return {} """) _NO_FRAMEWORK_SOURCE = textwrap.dedent("""\ def compute(x): return x * 2 def validate(x): return x > 0 """) class TestBuildImplicitEdgeGraphWithCache: """build_implicit_edge_graph accepts an optional ImplicitEdgeCache.""" def _repo(self, tmp_path: pathlib.Path) -> pathlib.Path: _muse_dir(tmp_path) return tmp_path def test_cold_cache_none_correct_graph(self, tmp_path: pathlib.Path) -> None: """Without a cache, the graph is correct.""" root = self._repo(tmp_path) manifest = _make_manifest(root, {"routes.py": _FASTAPI_SOURCE}) from muse.plugins.code._framework import build_implicit_edge_graph graph = build_implicit_edge_graph(root, manifest) assert any("list_items" in addr or "create_item" in addr for addr in graph) def test_explicit_cache_hit_skips_read_object(self, tmp_path: pathlib.Path) -> None: """When the cache has an entry for object_id, read_object is not called.""" from muse.core.implicit_edge_cache import ImplicitEdgeCache from muse.plugins.code._framework import build_implicit_edge_graph root = self._repo(tmp_path) oid = _write_blob(root, _FASTAPI_SOURCE) manifest = {"routes.py": oid} # Pre-populate with a known result cache = ImplicitEdgeCache.empty() cache.put(oid, [_edge("routes.py::list_items")]) with patch("muse.plugins.code._framework.read_object") as mock_read: build_implicit_edge_graph(root, manifest, implicit_cache=cache) mock_read.assert_not_called() def test_cache_miss_calls_read_object(self, tmp_path: pathlib.Path) -> None: """On a cache miss, read_object IS called.""" from muse.core.implicit_edge_cache import ImplicitEdgeCache from muse.plugins.code._framework import build_implicit_edge_graph root = self._repo(tmp_path) oid = _write_blob(root, _FASTAPI_SOURCE) manifest = {"routes.py": oid} cache = ImplicitEdgeCache.empty() with patch( "muse.plugins.code._framework.read_object", wraps=__import__("muse.core.object_store", fromlist=["read_object"]).read_object, ) as mock_read: build_implicit_edge_graph(root, manifest, implicit_cache=cache) assert mock_read.call_count >= 1 def test_cache_populated_after_build(self, tmp_path: pathlib.Path) -> None: """After build, the cache has an entry for each processed Python file.""" from muse.core.implicit_edge_cache import ImplicitEdgeCache from muse.plugins.code._framework import build_implicit_edge_graph root = self._repo(tmp_path) oid = _write_blob(root, _FASTAPI_SOURCE) manifest = {"routes.py": oid} cache = ImplicitEdgeCache.empty() build_implicit_edge_graph(root, manifest, implicit_cache=cache) assert cache.get(oid) is not None def test_no_framework_file_cached_as_empty_list(self, tmp_path: pathlib.Path) -> None: """Plain Python files (no framework) are cached with an empty list.""" from muse.core.implicit_edge_cache import ImplicitEdgeCache from muse.plugins.code._framework import build_implicit_edge_graph root = self._repo(tmp_path) oid = _write_blob(root, _NO_FRAMEWORK_SOURCE) manifest = {"utils.py": oid} cache = ImplicitEdgeCache.empty() build_implicit_edge_graph(root, manifest, implicit_cache=cache) result = cache.get(oid) assert result == [] def test_warm_graph_equals_cold_graph(self, tmp_path: pathlib.Path) -> None: """Warm-cache graph is identical to the cold-path graph.""" from muse.core.implicit_edge_cache import ImplicitEdgeCache from muse.plugins.code._framework import build_implicit_edge_graph root = self._repo(tmp_path) manifest = _make_manifest(root, { "routes.py": _FASTAPI_SOURCE, "utils.py": _NO_FRAMEWORK_SOURCE, }) cold_graph = build_implicit_edge_graph(root, manifest) cache = ImplicitEdgeCache.empty() build_implicit_edge_graph(root, manifest, implicit_cache=cache) # populate warm_graph = build_implicit_edge_graph(root, manifest, implicit_cache=cache) # warm assert set(cold_graph.keys()) == set(warm_graph.keys()) for addr in cold_graph: assert sorted(cold_graph[addr], key=lambda e: e.symbol_address) == \ sorted(warm_graph[addr], key=lambda e: e.symbol_address) def test_non_python_files_not_cached(self, tmp_path: pathlib.Path) -> None: """Non-Python files are skipped and not cached.""" from muse.core.implicit_edge_cache import ImplicitEdgeCache from muse.plugins.code._framework import build_implicit_edge_graph root = self._repo(tmp_path) md_oid = _write_blob(root, "# README\n") py_oid = _write_blob(root, _NO_FRAMEWORK_SOURCE) manifest = {"README.md": md_oid, "utils.py": py_oid} cache = ImplicitEdgeCache.empty() build_implicit_edge_graph(root, manifest, implicit_cache=cache) assert cache.get(md_oid) is None # skipped — not Python assert cache.get(py_oid) is not None # processed def test_build_does_not_call_cache_save(self, tmp_path: pathlib.Path) -> None: """build_implicit_edge_graph must not call save() — caller's responsibility.""" from muse.core.implicit_edge_cache import ImplicitEdgeCache from muse.plugins.code._framework import build_implicit_edge_graph root = self._repo(tmp_path) oid = _write_blob(root, _NO_FRAMEWORK_SOURCE) manifest = {"utils.py": oid} md = _muse_dir(tmp_path) cache = ImplicitEdgeCache.load(md) build_implicit_edge_graph(root, manifest, implicit_cache=cache) assert not (md / "cache" / "implicit_edges.json").is_file() def test_second_call_skips_read_object(self, tmp_path: pathlib.Path) -> None: """On the second call with a warm cache, read_object is never called.""" from muse.core.implicit_edge_cache import ImplicitEdgeCache from muse.plugins.code._framework import build_implicit_edge_graph root = self._repo(tmp_path) oid = _write_blob(root, _FASTAPI_SOURCE) manifest = {"routes.py": oid} cache = ImplicitEdgeCache.empty() build_implicit_edge_graph(root, manifest, implicit_cache=cache) # cold with patch("muse.plugins.code._framework.read_object") as mock_read: build_implicit_edge_graph(root, manifest, implicit_cache=cache) # warm mock_read.assert_not_called() # --------------------------------------------------------------------------- # TestImplicitEdgeCachePerformance # --------------------------------------------------------------------------- class TestImplicitEdgeCachePerformance: """Warm cache must be substantially faster than cold for a multi-file repo.""" def _build_repo(self, tmp_path: pathlib.Path, n_files: int = 30) -> tuple[pathlib.Path, Manifest]: root = tmp_path _muse_dir(root) manifest: Manifest = {} for i in range(n_files): # Alternate between FastAPI files and plain Python files if i % 3 == 0: src = textwrap.dedent(f"""\ from fastapi import APIRouter router = APIRouter() @router.get("/resource_{i}") def get_{i}(): return {{}} @router.post("/resource_{i}") def post_{i}(): return {{}} """) else: src = f"def helper_{i}(x):\n return x * {i}\n" oid = _write_blob(root, src) manifest[f"mod_{i}.py"] = oid return root, manifest def test_warm_cache_at_least_5x_faster(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache from muse.plugins.code._framework import build_implicit_edge_graph root, manifest = self._build_repo(tmp_path, n_files=30) cache = ImplicitEdgeCache.empty() t0 = time.perf_counter() build_implicit_edge_graph(root, manifest, implicit_cache=cache) cold_ms = (time.perf_counter() - t0) * 1000 t1 = time.perf_counter() build_implicit_edge_graph(root, manifest, implicit_cache=cache) warm_ms = (time.perf_counter() - t1) * 1000 assert warm_ms < cold_ms / 5, ( f"Warm ({warm_ms:.1f} ms) should be ≥5× faster than cold ({cold_ms:.1f} ms)" ) def test_warm_under_200ms_for_30_files(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache from muse.plugins.code._framework import build_implicit_edge_graph root, manifest = self._build_repo(tmp_path, n_files=30) cache = ImplicitEdgeCache.empty() build_implicit_edge_graph(root, manifest, implicit_cache=cache) # warm t0 = time.perf_counter() build_implicit_edge_graph(root, manifest, implicit_cache=cache) warm_ms = (time.perf_counter() - t0) * 1000 assert warm_ms < 200, f"Warm call took {warm_ms:.1f} ms — expected < 200 ms" def test_graph_correctness_not_degraded(self, tmp_path: pathlib.Path) -> None: from muse.core.implicit_edge_cache import ImplicitEdgeCache from muse.plugins.code._framework import build_implicit_edge_graph root, manifest = self._build_repo(tmp_path, n_files=10) cold_graph = build_implicit_edge_graph(root, manifest) cache = ImplicitEdgeCache.empty() build_implicit_edge_graph(root, manifest, implicit_cache=cache) warm_graph = build_implicit_edge_graph(root, manifest, implicit_cache=cache) assert set(cold_graph.keys()) == set(warm_graph.keys()), ( f"Keys differ:\n cold={sorted(cold_graph)}\n warm={sorted(warm_graph)}" ) for addr in cold_graph: cold_sorted = sorted(cold_graph[addr], key=lambda e: e.symbol_address) warm_sorted = sorted(warm_graph[addr], key=lambda e: e.symbol_address) assert cold_sorted == warm_sorted