Implement scope-derived candidate review infrastructure

This commit is contained in:
2026-05-16 00:26:29 +02:00
parent f4d782c997
commit ba2228e889
14 changed files with 1740 additions and 39 deletions

View File

@@ -466,6 +466,12 @@ def test_openapi_contract_snapshot_for_stable_agent_paths():
"/repos/{repository_id}/export": {
"get": {"tags": ["discovery"], "success_schema": "application/x-yaml"}
},
"/repos/{repository_id}/intent/review": {
"get": {"tags": ["scope"], "success_schema": "object"}
},
"/repos/{repository_id}/scope/review": {
"get": {"tags": ["scope"], "success_schema": "object"}
},
"/repos/{repo_slug}/scope": {
"get": {"tags": ["scope"], "success_schema": None}
},
@@ -837,6 +843,62 @@ def test_api_generates_diffs_and_writes_scope_md(tmp_path):
app.dependency_overrides.clear()
def test_api_reviews_intent_and_scope_drafts_without_writing_intent(tmp_path):
source = tmp_path / "draft-repo"
source.mkdir()
(source / "SCOPE.md").write_text(
"# SCOPE\n\n"
"## One-liner\n"
"S5 Workloads and Experience layer.\n\n"
"## Provided Capabilities\n\n"
"```capability\n"
"type: infrastructure\n"
"title: Application workload deployment\n"
"description: Deploy applications as Helm releases.\n"
"keywords: [helm]\n"
"```\n",
encoding="utf-8",
)
def override_settings():
return Settings(
database_path=str(tmp_path / "draft-api.sqlite3"),
checkout_root=str(tmp_path / "checkouts"),
)
app.dependency_overrides[get_settings] = override_settings
client = TestClient(app)
try:
repository = client.post(
"/repos",
json={"name": "Draft Repo", "url": str(source)},
).json()
analysis = client.post(
f"/repos/{repository['id']}/analysis-runs",
json={"source_path": str(source), "use_llm_assistance": False},
).json()
assert analysis["analysis_run"]["status"] == "completed"
intent_review = client.get(f"/repos/{repository['id']}/intent/review")
assert intent_review.status_code == 200
intent_payload = intent_review.json()
assert intent_payload["document"] == "INTENT.md"
assert intent_payload["exists"] is False
assert "Application workload deployment" in intent_payload["draft_content"]
assert "does not write INTENT.md automatically" in intent_payload["write_policy"]
assert not (source / "INTENT.md").exists()
scope_review = client.get(f"/repos/{repository['id']}/scope/review")
assert scope_review.status_code == 200
scope_payload = scope_review.json()
assert scope_payload["exists"] is True
assert "S5 Workloads and Experience layer" in scope_payload["current_content"]
assert "Application workload deployment" in scope_payload["draft_content"]
assert scope_payload["provenance"]["candidate_counts"]["capabilities"] >= 1
finally:
app.dependency_overrides.clear()
def test_api_compare_gap_and_export_use_cases(tmp_path):
def override_settings():
return Settings(
@@ -1550,6 +1612,14 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
f'<a class="button secondary" href="/ui/repos/{repository_id}/dependency-graph">Dependency Graph</a>'
in detail_response.text
)
assert (
f'<a class="button secondary" href="/ui/repos/{repository_id}/scope-review">Scope Draft</a>'
in detail_response.text
)
assert (
f'<a class="button secondary" href="/ui/repos/{repository_id}/intent-review">Intent Draft</a>'
in detail_response.text
)
repo_scope_response = client.get(f"/ui/repos/{repository_id}/scope")
assert repo_scope_response.status_code == 200
@@ -1600,7 +1670,9 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
assert "Content Chunks" in run_detail.text
assert "README.md:1-2" in run_detail.text
assert "ID " in run_detail.text
assert "No review decisions yet." in run_detail.text
assert "quality_gate_evaluation" in run_detail.text
assert "requires_review:" in run_detail.text
assert "without approving registry truth" in run_detail.text
assert "Expectation Gaps" in run_detail.text
assert "Record Gap" in run_detail.text
@@ -1674,7 +1746,7 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
assert "Discovery" in approved_detail.text
assert "Export" in approved_detail.text
assert "Elements" in approved_detail.text
assert "q=Report+Service+Status" in approved_detail.text
assert "q=UI+Repo+Owns+The+Status+Reporting+Scope" in approved_detail.text
graph_response = client.get(f"/repos/{repository_id}/dependency-graph")
assert graph_response.status_code == 200
@@ -1787,7 +1859,7 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
f"/ui/repos/{repository_id}/elements?scope=facts&amp;analysis_run_id={first_run_id}&amp;type=facts"
in approved_detail.text
)
assert "Report Service Status Through API And CLI Entry" in approved_detail.text
assert "UI Repo Owns The Status Reporting Scope" in approved_detail.text
assert "Language: Python" in approved_detail.text
assert "Framework: FastAPI" in approved_detail.text
assert "interface:app.py:3" in approved_detail.text
@@ -1801,7 +1873,7 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
assert "Registry Capabilities" in approved_listing.text
assert "Entry" in approved_listing.text
assert "Approved only" in approved_listing.text
assert "Expose Repository Interface" in approved_listing.text
assert "UI Repo Owns The Status Reporting Scope" in approved_listing.text
assert "Save" in approved_listing.text
assert "Delete" in approved_listing.text
@@ -1964,14 +2036,14 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
filtered_search_response = client.get(
"/ui/search",
params={
"q": "repository",
"status": "indexed",
"language": "Python",
"ability": "Report Service Status",
"capability": "Repository",
},
)
params={
"q": "repository",
"status": "indexed",
"language": "Python",
"ability": "UI Repo",
"capability": "Scope",
},
)
assert filtered_search_response.status_code == 200
assert "UI Repo" in filtered_search_response.text