Add self-scoping assessment export command

This commit is contained in:
2026-05-15 12:39:51 +02:00
parent bc08977f85
commit 2796fc5816
10 changed files with 934 additions and 19 deletions

View File

@@ -1,3 +1,5 @@
import json
import pytest
from repo_registry.cli import main
@@ -98,3 +100,34 @@ def test_rebuild_cli_refuses_destructive_all_without_confirm_all(tmp_path):
)
assert exc.value.code == 2
def test_export_assessment_cli_writes_completed_run_artifact(tmp_path):
service = make_service(tmp_path)
source = write_repo(tmp_path)
repository = service.register_repository(name="CLI Export", url=str(source))
summary = service.analyze_repository(repository.id, use_llm_assistance=False)
output_path = tmp_path / "assessment.json"
exit_code = main(
[
"export-assessment",
"--repo",
str(repository.id),
"--analysis-run",
str(summary.analysis_run.id),
"--output",
str(output_path),
"--database-path",
str(tmp_path / "registry.sqlite3"),
"--checkout-root",
str(tmp_path / "checkouts"),
]
)
artifact = json.loads(output_path.read_text(encoding="utf-8"))
assert exit_code == 0
assert artifact["target_repository"]["repo_slug"] == "cli-export"
assert artifact["execution"]["analysis_run_id"] == summary.analysis_run.id
assert artifact["assessment"]["role"] == "challenger"
assert artifact["generated_tree"]["abilities"]

View File

@@ -36,7 +36,11 @@ def test_self_scoping_assessment_schema_requires_release_binding_metadata():
"execution",
"assessment",
"fact_summary",
"content_chunk_summary",
"generated_tree",
"approved_map",
"review_decisions",
"quality_gate_outcomes",
"known_regression_patterns",
} <= required
assert {
@@ -79,6 +83,10 @@ def test_known_bad_self_scoping_artifact_captures_rejected_regression_seed():
assert "Route LLM Requests Across Providers" in capability_names
assert {"RREG-SELF-REG-001", "RREG-SELF-REG-002", "RREG-SELF-REG-003"} <= regression_ids
assert artifact["fact_summary"]["counts_by_kind"]["llm_provider"] == 41
assert "content_chunk_summary" in artifact
assert "approved_map" in artifact
assert artifact["review_decisions"][0]["action"] == "trusted_auto_approve_candidate_graph"
assert artifact["quality_gate_outcomes"] == []
def test_golden_profile_names_expected_native_capabilities_and_forbidden_false_positive():
@@ -109,4 +117,3 @@ def test_golden_profile_names_expected_native_capabilities_and_forbidden_false_p
assert profile["comparison_rules"]["must_not_have_native_capability_names"] == [
"Route LLM Requests Across Providers"
]

View File

@@ -0,0 +1,97 @@
from repo_registry.core.service import RegistryService
from repo_registry.repo_ingestion.git import GitIngestionService
from repo_registry.self_scoping.assessment import export_assessment_artifact
from repo_registry.storage.sqlite import RegistryStore
def make_service(tmp_path):
store = RegistryStore(tmp_path / "registry.sqlite3")
store.initialize()
return RegistryService(store, ingestion=GitIngestionService(tmp_path / "checkouts"))
def write_repo(tmp_path):
source = tmp_path / "repo"
source.mkdir()
(source / "README.md").write_text(
"# Exportable Repo\n\nReports service health.\n",
encoding="utf-8",
)
(source / "app.py").write_text(
'@app.get("/health")\n'
"def health():\n"
" return {}\n",
encoding="utf-8",
)
return source
def test_export_assessment_artifact_binds_analysis_to_engine_identity(tmp_path):
service = make_service(tmp_path)
source = write_repo(tmp_path)
repository = service.register_repository(
name="Exportable Repo",
url=str(source),
)
summary = service.analyze_repository(
repository.id,
use_llm_assistance=False,
)
artifact = export_assessment_artifact(
service,
repository.id,
summary.analysis_run.id,
role="challenger",
outcome="challenger",
reviewer="test",
)
assert artifact["schema_version"] == "self-scoping-assessment/v1"
assert artifact["artifact_id"] == "exportable-repo-challenger-run-1"
assert artifact["target_repository"]["repo_slug"] == "exportable-repo"
assert artifact["target_repository"]["target_commit"]
assert artifact["engine_identity"]["engine_commit"]
assert artifact["engine_identity"]["release_binding_status"] == "complete"
assert artifact["assessment"]["comparison_eligibility"] == "eligible"
assert artifact["execution"]["mode"] == "deterministic-only"
assert artifact["content_chunk_summary"]["total"] > 0
assert artifact["generated_tree"]["abilities"]
assert artifact["approved_map"]["abilities"] == []
assert artifact["review_decisions"] == []
assert artifact["quality_gate_outcomes"] == []
def test_export_assessment_artifact_flags_known_provider_regression(tmp_path):
service = make_service(tmp_path)
source = tmp_path / "repo"
source.mkdir()
(source / "README.md").write_text("# Provider Vocabulary\n", encoding="utf-8")
(source / "providers.py").write_text(
"provider_registry = {'openrouter': OpenRouterAdapter}\n",
encoding="utf-8",
)
repository = service.register_repository(
name="Provider Vocabulary",
url=str(source),
)
summary = service.analyze_repository(
repository.id,
use_llm_assistance=False,
)
artifact = export_assessment_artifact(
service,
repository.id,
summary.analysis_run.id,
role="challenger",
outcome="challenger",
reviewer="test",
)
regression_ids = {item["id"] for item in artifact["known_regression_patterns"]}
assert "RREG-SELF-REG-001" in regression_ids
assert any(
item["path"] == "providers.py"
for item in artifact["fact_summary"]["contamination_sources"]
) is False