Coevolution extension

This commit is contained in:
2026-04-29 01:19:59 +02:00
parent 88afdc09fd
commit 991c34ce52
17 changed files with 764 additions and 4 deletions

View File

@@ -41,6 +41,8 @@ from repo_registry.web_api.schemas import (
EvidenceCreate,
EvidenceUpdate,
ErrorResponse,
ExpectationGapCreate,
ExpectationGapResponse,
FeatureCreate,
FeatureUpdate,
IdResponse,
@@ -288,6 +290,51 @@ def get_analysis_run(
raise HTTPException(status_code=404, detail=str(exc)) from exc
@app.get(
"/repos/{repository_id}/expectation-gaps",
tags=["review"],
response_model=list[ExpectationGapResponse],
)
def list_expectation_gaps(
repository_id: int,
analysis_run_id: int | None = Query(default=None),
service: RegistryService = Depends(get_service),
) -> list[dict[str, object]]:
try:
return [
asdict(gap)
for gap in service.list_expectation_gaps(repository_id, analysis_run_id)
]
except NotFoundError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
@app.post(
"/repos/{repository_id}/expectation-gaps",
status_code=201,
tags=["review"],
response_model=ExpectationGapResponse,
)
def create_expectation_gap(
repository_id: int,
payload: ExpectationGapCreate,
service: RegistryService = Depends(get_service),
) -> dict[str, object]:
try:
return asdict(
service.record_expectation_gap(
repository_id,
analysis_run_id=payload.analysis_run_id,
expected_type=payload.expected_type,
expected_name=payload.expected_name,
source=payload.source,
notes=payload.notes,
)
)
except NotFoundError as exc:
raise HTTPException(status_code=404, detail=str(exc)) from exc
@app.get(
"/repos/{repository_id}/analysis-runs/{base_analysis_run_id}/diff/{target_analysis_run_id}",
tags=["review"],

View File

@@ -225,6 +225,40 @@ class AnalysisRunCreate(BaseModel):
}
class ExpectationGapCreate(BaseModel):
analysis_run_id: int | None = None
expected_type: str
expected_name: str
source: str = "human"
notes: str = ""
model_config = {
"json_schema_extra": {
"examples": [
{
"analysis_run_id": 1,
"expected_type": "capability",
"expected_name": "Use OpenRouter Models",
"source": "human",
"notes": "Expected from README/provider config but absent from candidates.",
}
]
}
}
class ExpectationGapResponse(BaseModel):
id: int
repository_id: int
analysis_run_id: int | None
expected_type: str
expected_name: str
source: str
notes: str
status: str
created_at: str
class CandidateGraphApproval(BaseModel):
notes: str = ""