repository-scoped dependency graph view profile persistence and interactive exploration features

This commit is contained in:
2026-05-04 11:26:25 +02:00
parent 98a65581ac
commit 4f04491734
11 changed files with 1365 additions and 32 deletions

View File

@@ -263,6 +263,88 @@ def test_dependency_graph_flags_same_layer_edges(tmp_path):
assert same_layer_edges[0].target_key == f"capability:{second_capability_id}"
def test_dependency_graph_enriches_layers_and_filters_with_profiles(tmp_path):
service = make_service(tmp_path)
source = write_python_cli_repo(tmp_path)
repository = service.register_repository(
name="Graph Profile",
url=str(source),
description="Graph profile fixture.",
)
summary = service.analyze_repository(
repository.id,
source_path=str(source),
use_llm_assistance=False,
)
fact = next(item for item in summary.facts if item.kind == "framework")
source_ref = SourceReference(
fact_id=fact.id,
path=fact.path,
kind=fact.kind,
name=fact.name,
)
ability_id = service.add_ability(repository.id, name="Explore Graphs")
capability_id = service.add_capability(
repository.id,
ability_id,
name="Filter Dependency Graph",
)
feature_id = service.store.create_feature(
repository.id,
capability_id,
name="Graph filter control",
type="UI",
location="src/ui.py",
confidence=0.8,
source_refs=[source_ref],
)
service.store.create_evidence(
repository.id,
capability_id,
type="test",
reference="tests/test_ui.py",
strength="strong",
target_kind="feature",
target_id=feature_id,
source_refs=[source_ref],
)
profile = service.create_dependency_graph_profile(
repository.id,
name="Evidence Audit",
description="Blur non-evidence layers.",
default_mode="full",
filter_rules=[
{"name": "blur facts", "action": "blur", "match": {"layer": "fact"}},
{"name": "hide features", "action": "hide", "match": {"layer": "feature"}},
],
manual_overrides={f"feature:{feature_id}": "show", "missing:1": "hide"},
)
payload = service.dependency_graph_elements(repository.id, profile_id=profile.id)
nodes = [
element["data"]
for element in payload["elements"]
if "source" not in element["data"]
]
fact_node = next(node for node in nodes if node["kind"] == "fact")
feature_node = next(node for node in nodes if node["id"] == f"feature:{feature_id}")
evidence_node = next(node for node in nodes if node["kind"] == "evidence")
assert fact_node["layer"] == "fact"
assert fact_node["path"] == fact.path
assert fact_node["displayState"] == "blur"
assert feature_node["displayState"] == "show"
assert feature_node["visibilitySource"] == "manual"
assert evidence_node["layer"] == "evidence"
assert payload["filter"]["orphaned_overrides"] == ["missing:1"]
assert payload["metrics"]["hidden_count"] == 0
assert any(
element["data"].get("target") == f"feature:{feature_id}"
and element["data"].get("sourceKind") == "evidence"
for element in payload["elements"]
)
def test_manual_registry_updates_and_deletes_approved_entries(tmp_path):
service = make_service(tmp_path)
repository = service.register_repository(