Fix rerun assessment and candidate extraction

This commit is contained in:
2026-05-16 00:57:44 +02:00
parent bee770fad7
commit 3e906c1dd4
7 changed files with 227 additions and 12 deletions

View File

@@ -135,6 +135,85 @@ def test_candidate_generator_extracts_intended_capability_blocks_from_intent_chu
assert [ref.path for ref in intent_capability.source_refs] == ["INTENT.md"]
def test_candidate_generator_preserves_unicode_and_normalizes_analysis_names():
repository = Repository(
id=1,
name="VergabeTeilnahme",
url="/tmp/vergabe-teilnahme",
description=None,
branch="main",
status="analyzed",
)
facts = [
fact(
1,
"intent",
"INTENT",
"INTENT.md",
metadata={"source_role": "intent_summary"},
)
]
chunks = [
chunk(
1,
"intent",
"INTENT.md",
"# INTENT\n\n"
"Vollständiger Implementierungsplan in 12 Ralph-Loop-Workplans.\n\n"
"## Intended Capabilities\n\n"
"- Analysis of impact risk and dependency chains.\n",
)
]
graph = CandidateGraphGenerator().generate(repository, facts, chunks)
assert graph[0].name == "Vollständiger Implementierungsplan In 12 Ralph-Loop-Workplans"
assert graph[0].capabilities[0].name == "Analyze Impact Risk And Dependency Chains"
def test_candidate_generator_extracts_primary_outcome_subsections_from_intent():
repository = Repository(
id=1,
name="HelixForge",
url="/tmp/helix-forge",
description=None,
branch="main",
status="analyzed",
)
facts = [
fact(
1,
"intent",
"INTENT",
"INTENT.md",
metadata={"source_role": "intent_summary"},
)
]
chunks = [
chunk(
1,
"intent",
"INTENT.md",
"# INTENT\n\n"
"HelixForge turns intent into structure.\n\n"
"## 4\\. Primary outcomes\n\n"
"### 4.1 Capability discovery\n\n"
"Clarify scope and ownership.\n\n"
"### 4.2 Capability validation\n\n"
"Validate architecture descriptions structurally and semantically.\n\n"
"## Architectural foundation\n\n"
"This section should not become a capability.\n",
)
]
graph = CandidateGraphGenerator().generate(repository, facts, chunks)
capability_names = {capability.name for capability in graph[0].capabilities}
assert "Support Capability Discovery" in capability_names
assert "Validate Capabilities" in capability_names
assert "Architectural Foundation" not in capability_names
def test_candidate_generator_prefers_intent_over_derived_scope_for_ability_name():
repository = Repository(
id=1,
@@ -238,7 +317,7 @@ def test_candidate_generator_extracts_current_capabilities_from_scope_blocks():
"scope",
"SCOPE.md",
"# SCOPE\n\n## One-liner\n"
"S5 Workloads and Experience layer of the Railiance OAS Stack.\n\n"
"S5 Workloads and Experience layer of the Railiance OAS Stack -- owns applications.\n\n"
"## Provided Capabilities\n\n"
"```capability\n"
"type: infrastructure\n"
@@ -255,6 +334,7 @@ def test_candidate_generator_extracts_current_capabilities_from_scope_blocks():
ability = graph[0]
assert ability.name == "S5 Workloads And Experience Layer Of The Railiance OAS Stack"
assert ability.name == "S5 Workloads And Experience Layer Of The Railiance OAS Stack"
capability = ability.capabilities[0]
assert capability.name == "Application workload deployment"
assert capability.primary_class == "infrastructure"

View File

@@ -226,6 +226,19 @@ def test_assess_dataset_cli_reports_sparse_hierarchy_issues(tmp_path):
)
repository = service.register_repository(name="Scope Only", url=str(source))
service.analyze_repository(repository.id, use_llm_assistance=False)
(source / "SCOPE.md").write_text(
"# SCOPE\n\n"
"## One-liner\n"
"Scope-only current behavior.\n\n"
"## Provided Capabilities\n\n"
"```capability\n"
"name: Review Latest Scope Facts\n"
"type: scope-review\n"
"description: Review the latest scope facts instead of stale runs.\n"
"```\n",
encoding="utf-8",
)
latest_summary = service.analyze_repository(repository.id, use_llm_assistance=False)
output_path = tmp_path / "dataset.json"
exit_code = main(
@@ -247,6 +260,7 @@ def test_assess_dataset_cli_reports_sparse_hierarchy_issues(tmp_path):
assert exit_code == 0
assert report["schema_version"] == "repo-scoping-dataset-assessment/v1"
assert repo_report["name"] == "Scope Only"
assert repo_report["latest_analysis_run_id"] == latest_summary.analysis_run.id
assert repo_report["documents"]["SCOPE.md"] is True
assert repo_report["candidate_counts"]["capabilities"] >= 1
assert repo_report["dependency_graph"]["node_count"] > 0

View File

@@ -541,6 +541,50 @@ def test_dependency_graph_renders_candidate_fallback_when_approved_hierarchy_mis
assert any(edge["dependencyType"] == "draft-supports" for edge in edges)
def test_dependency_graph_candidate_fallback_uses_latest_completed_run(tmp_path):
service = make_service(tmp_path)
source = tmp_path / "latest-scope-candidate"
source.mkdir()
(source / "SCOPE.md").write_text(
"# SCOPE\n\n## One-liner\nOld scope summary.\n",
encoding="utf-8",
)
repository = service.register_repository(name="Latest Scope Candidate", url=str(source))
service.analyze_repository(
repository.id,
source_path=str(source),
use_llm_assistance=False,
)
(source / "SCOPE.md").write_text(
"# SCOPE\n\n"
"## One-liner\n"
"Latest scope summary.\n\n"
"## Provided Capabilities\n\n"
"```capability\n"
"type: review\n"
"title: Latest Scope Capability\n"
"description: The second run should drive graph fallback.\n"
"```\n",
encoding="utf-8",
)
latest = service.analyze_repository(
repository.id,
source_path=str(source),
use_llm_assistance=False,
)
payload = service.dependency_graph_elements(repository.id, use_latest_profile=False)
labels = {
element["data"].get("label")
for element in payload["elements"]
if "source" not in element["data"]
}
assert latest.analysis_run.id == service.list_analysis_runs(repository.id)[0].id
assert "Latest Scope Capability" in labels
assert "Old Scope Summary" not in labels
def test_manual_registry_updates_and_deletes_approved_entries(tmp_path):
service = make_service(tmp_path)
repository = service.register_repository(