generated from coulomb/repo-seed
182 lines
6.0 KiB
Python
182 lines
6.0 KiB
Python
from repo_registry.acceptance import (
|
|
blocking_quality_gate_outcomes,
|
|
evaluate_candidate_capability_quality,
|
|
evaluate_candidate_graph_quality,
|
|
quality_gate_outcome_dicts,
|
|
)
|
|
from repo_registry.core.models import (
|
|
AnalysisRun,
|
|
CandidateAbility,
|
|
CandidateCapability,
|
|
CandidateFeature,
|
|
CandidateGraph,
|
|
Repository,
|
|
SourceReference,
|
|
)
|
|
from repo_registry.core.service import RegistryService
|
|
from repo_registry.repo_ingestion.git import GitIngestionService
|
|
from repo_registry.storage.sqlite import RegistryStore
|
|
|
|
|
|
def source_ref(path="src/app.py", kind="source"):
|
|
return SourceReference(
|
|
fact_id=1,
|
|
path=path,
|
|
kind=kind,
|
|
name=path,
|
|
line=1,
|
|
)
|
|
|
|
|
|
def provider_routing_capability():
|
|
return CandidateCapability(
|
|
id=10,
|
|
name="Route LLM Requests Across Providers",
|
|
description="Routes provider requests.",
|
|
inputs=[],
|
|
outputs=[],
|
|
confidence=0.9,
|
|
status="candidate",
|
|
source_refs=[source_ref("src/providers.py")],
|
|
confidence_label="high",
|
|
primary_class="llm-integration",
|
|
attributes=["utility-owned"],
|
|
features=[
|
|
CandidateFeature(
|
|
id=20,
|
|
name="HTTP API surface",
|
|
type="API",
|
|
location="src/app.py",
|
|
confidence=0.8,
|
|
status="candidate",
|
|
source_refs=[source_ref("src/app.py")],
|
|
confidence_label="high",
|
|
primary_class="API",
|
|
)
|
|
],
|
|
)
|
|
|
|
|
|
def test_quality_gates_flag_known_provider_routing_failure():
|
|
outcomes = evaluate_candidate_capability_quality(provider_routing_capability())
|
|
|
|
outcome_ids = {outcome.criterion_id for outcome in outcomes}
|
|
assert {"RREG-QC-002", "RREG-QC-003"} <= outcome_ids
|
|
assert all(outcome.outcome != "approve" for outcome in outcomes)
|
|
assert blocking_quality_gate_outcomes(outcomes)
|
|
|
|
|
|
def test_quality_gates_flag_circular_scope_evidence():
|
|
capability = CandidateCapability(
|
|
id=11,
|
|
name="Map Repository Scope",
|
|
description="Uses generated scope.",
|
|
inputs=[],
|
|
outputs=[],
|
|
confidence=0.8,
|
|
status="candidate",
|
|
source_refs=[source_ref("SCOPE.md", "generated-scope")],
|
|
confidence_label="high",
|
|
primary_class="scope-generation",
|
|
attributes=["utility-owned"],
|
|
)
|
|
|
|
outcomes = evaluate_candidate_capability_quality(capability)
|
|
|
|
assert outcomes[0].criterion_id == "RREG-QC-005"
|
|
assert outcomes[0].outcome == "rejected"
|
|
|
|
|
|
def test_quality_gate_outcomes_are_serializable_for_assessment_artifacts():
|
|
graph = CandidateGraph(
|
|
repository=Repository(
|
|
id=1,
|
|
name="Repo",
|
|
url=".",
|
|
description=None,
|
|
branch="main",
|
|
status="indexed",
|
|
),
|
|
analysis_run=AnalysisRun(
|
|
id=1,
|
|
repository_id=1,
|
|
snapshot_id=None,
|
|
status="completed",
|
|
started_at="2026-05-15T00:00:00Z",
|
|
completed_at="2026-05-15T00:00:01Z",
|
|
error_message=None,
|
|
scanner_version="deterministic-v1",
|
|
),
|
|
abilities=[
|
|
CandidateAbility(
|
|
id=1,
|
|
name="Support Repo",
|
|
description="Support repo.",
|
|
confidence=0.8,
|
|
status="candidate",
|
|
source_refs=[],
|
|
capabilities=[provider_routing_capability()],
|
|
)
|
|
],
|
|
)
|
|
|
|
payload = quality_gate_outcome_dicts(evaluate_candidate_graph_quality(graph))
|
|
|
|
assert payload
|
|
assert payload[0]["criteria_version"] == "repo-scoping-quality-criteria/v1"
|
|
|
|
|
|
def test_legacy_trusted_auto_approval_skips_quality_gate_blocked_capability(tmp_path):
|
|
store = RegistryStore(tmp_path / "registry.sqlite3")
|
|
store.initialize()
|
|
service = RegistryService(store, ingestion=GitIngestionService(tmp_path / "checkouts"))
|
|
|
|
safe, reason = service._trusted_auto_approve_capability_decision(
|
|
provider_routing_capability()
|
|
)
|
|
|
|
assert safe is False
|
|
assert "quality gates require review" in reason
|
|
assert "RREG-QC-002" in reason
|
|
|
|
|
|
def test_analysis_records_deterministic_gate_review_decision(tmp_path):
|
|
source = tmp_path / "provider-repo"
|
|
source.mkdir()
|
|
(source / "README.md").write_text("# Provider Repo\n", encoding="utf-8")
|
|
(source / "providers.py").write_text(
|
|
"provider_registry = {'openrouter': OpenRouterAdapter}\n",
|
|
encoding="utf-8",
|
|
)
|
|
store = RegistryStore(tmp_path / "registry.sqlite3")
|
|
store.initialize()
|
|
service = RegistryService(store, ingestion=GitIngestionService(tmp_path / "checkouts"))
|
|
repository = service.register_repository(name="Provider Repo", url=str(source))
|
|
|
|
summary = service.analyze_repository(repository.id, use_llm_assistance=False)
|
|
|
|
decisions = service.list_review_decisions(repository.id, summary.analysis_run.id)
|
|
gate_decision = next(
|
|
decision for decision in decisions if decision.action == "quality_gate_evaluation"
|
|
)
|
|
assert gate_decision.reviewer_type == "deterministic-gate"
|
|
assert "RREG-QC-002" in gate_decision.criterion_ids
|
|
assert gate_decision.criteria_version == "repo-scoping-quality-criteria/v1"
|
|
assert "without approving registry truth" in gate_decision.rationale
|
|
assert service.ability_map(repository.id).abilities == []
|
|
|
|
override = service.record_quality_gate_override(
|
|
repository.id,
|
|
summary.analysis_run.id,
|
|
criterion_id="RREG-QC-002",
|
|
element_type="capability",
|
|
element_id=10,
|
|
reason="Curator confirmed this repo now owns provider routing.",
|
|
notes="Future criteria update may be needed.",
|
|
)
|
|
assert override.action == "quality_gate_override"
|
|
assert override.reviewer_type == "human"
|
|
assert override.decision_kind == "override"
|
|
assert override.criterion_ids == ["RREG-QC-002"]
|
|
assert override.rationale == "Curator confirmed this repo now owns provider routing."
|