from __future__ import annotations from typing import Any from pydantic import BaseModel, Field REPOSITORY_EXAMPLE = { "id": 1, "name": "MailRouter", "url": "https://github.com/example/mail-router.git", "description": "Routes incoming customer email.", "branch": "main", "status": "indexed", } ANALYSIS_RUN_EXAMPLE = { "id": 1, "repository_id": 1, "snapshot_id": 1, "status": "completed", "started_at": "2026-04-26T09:00:00Z", "completed_at": "2026-04-26T09:00:03Z", "error_message": None, "scanner_version": "deterministic-v1", } SOURCE_REFERENCE_EXAMPLE = { "fact_id": 12, "path": "src/routes/classify_email.py", "kind": "api_route", "name": "POST /api/classify-email", "line": 42, } class ErrorResponse(BaseModel): detail: str model_config = { "json_schema_extra": { "examples": [ {"detail": "repository 999 was not found"}, {"detail": "target candidate must be different from source"}, ] } } class RepositoryCreate(BaseModel): url: str name: str | None = None description: str | None = None branch: str = "main" access_username: str | None = None access_password: str | None = Field(default=None, repr=False) model_config = { "json_schema_extra": { "examples": [ { "url": "https://github.com/example/repository.git", "name": "Example Repository", "description": "Optional human-readable repository summary.", "branch": "main", "access_username": None, "access_password": None, } ] } } class RepositoryUpdate(BaseModel): name: str | None = None description: str | None = None branch: str | None = None model_config = { "json_schema_extra": { "examples": [ { "name": "Renamed Repository", "description": "Updated curator-facing summary.", "branch": "main", } ] } } class AbilityCreate(BaseModel): name: str description: str = "" confidence: float = Field(default=1.0, ge=0.0, le=1.0) model_config = { "json_schema_extra": { "examples": [ { "name": "Business Email Routing", "description": "Route inbound messages to the right team.", "confidence": 0.92, } ] } } class AbilityUpdate(BaseModel): name: str | None = None description: str | None = None confidence: float | None = Field(default=None, ge=0.0, le=1.0) class CapabilityCreate(BaseModel): ability_id: int name: str description: str = "" inputs: list[str] = Field(default_factory=list) outputs: list[str] = Field(default_factory=list) confidence: float = Field(default=1.0, ge=0.0, le=1.0) model_config = { "json_schema_extra": { "examples": [ { "ability_id": 1, "name": "Classify Incoming Email", "description": "Classify messages by intent.", "inputs": ["subject", "body"], "outputs": ["intent", "confidence"], "confidence": 0.88, } ] } } class CapabilityUpdate(BaseModel): name: str | None = None description: str | None = None inputs: list[str] | None = None outputs: list[str] | None = None confidence: float | None = Field(default=None, ge=0.0, le=1.0) class FeatureCreate(BaseModel): capability_id: int name: str type: str location: str = "" confidence: float = Field(default=1.0, ge=0.0, le=1.0) model_config = { "json_schema_extra": { "examples": [ { "capability_id": 1, "name": "POST /api/classify-email", "type": "REST endpoint", "location": "src/routes/classify_email.py", "confidence": 0.84, } ] } } class FeatureUpdate(BaseModel): name: str | None = None type: str | None = None location: str | None = None confidence: float | None = Field(default=None, ge=0.0, le=1.0) class EvidenceCreate(BaseModel): capability_id: int type: str reference: str strength: str = "medium" target_kind: str = "capability" target_id: int | None = None reference_kind: str = "source" reference_id: int | None = None model_config = { "json_schema_extra": { "examples": [ { "capability_id": 1, "type": "unit_test", "reference": "tests/test_email_classification.py", "strength": "strong", "target_kind": "capability", "reference_kind": "source", } ] } } class EvidenceUpdate(BaseModel): type: str | None = None reference: str | None = None strength: str | None = None target_kind: str | None = None target_id: int | None = None reference_kind: str | None = None reference_id: int | None = None class AnalysisRunCreate(BaseModel): source_path: str | None = None use_cached_checkout: bool = False use_llm_assistance: bool = True agentic_review: bool = Field( default=False, description=( "Request configured agentic review after analysis; candidates remain " "pending when no reviewer is configured." ), ) trusted_auto_approve: bool = Field( default=False, description=( "Deprecated compatibility input. Requests are routed to agentic " "review and do not deterministically approve candidates." ), ) access_username: str | None = None access_password: str | None = Field(default=None, repr=False) model_config = { "json_schema_extra": { "examples": [ {}, {"source_path": "/path/to/local/repository"}, {"use_cached_checkout": True}, {"use_llm_assistance": False}, {"agentic_review": True}, { "access_username": "git-user", "access_password": "access-token", }, ] } } 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 = "" model_config = { "json_schema_extra": { "examples": [{"notes": "Approved after curator review."}] } } class AnalysisRunChangeApproval(BaseModel): notes: str = "" model_config = { "json_schema_extra": { "examples": [{"notes": "Accept target run changes after review."}] } } class CharacteristicRebuildRequest(BaseModel): dry_run: bool = True confirm: bool = False source_path: str | None = None use_cached_checkout: bool = False use_llm_assistance: bool = True class CharacteristicRebuildResponse(BaseModel): repository: RepositoryResponse analysis_run: AnalysisRunResponse dry_run: bool confirmed: bool cleared_approved: bool previous_counts: dict[str, int] previous_ids: dict[str, list[int]] candidate_counts: dict[str, int] class DependencyGraphRule(BaseModel): action: str name: str | None = None match: dict[str, Any] = Field(default_factory=dict) class DependencyGraphAdHocFilters(BaseModel): rules: list[dict[str, Any]] = Field(default_factory=list) manual_overrides: dict[str, str] = Field(default_factory=dict) class DependencyGraphProfileCreate(BaseModel): name: str description: str = "" default_mode: str = "full" filter_rules: list[dict[str, Any]] = Field(default_factory=list) manual_overrides: dict[str, str] = Field(default_factory=dict) class DependencyGraphProfileUpdate(BaseModel): name: str | None = None description: str | None = None default_mode: str | None = None filter_rules: list[dict[str, Any]] | None = None manual_overrides: dict[str, str] | None = None class DependencyGraphProfileDuplicate(BaseModel): name: str | None = None class DependencyGraphProfileResponse(BaseModel): id: int repository_id: int name: str description: str default_mode: str filter_rules: list[dict[str, Any]] manual_overrides: dict[str, str] created_at: str updated_at: str class CandidateRejection(BaseModel): notes: str = "" model_config = { "json_schema_extra": { "examples": [{"notes": "Rejected because the claim is too generic."}] } } class CandidateEdit(BaseModel): name: str description: str = "" confidence: float = Field(default=0.5, ge=0.0, le=1.0) notes: str = "" model_config = { "json_schema_extra": { "examples": [ { "name": "Service Health Monitoring", "description": "Expose health state for operational checks.", "confidence": 0.9, "notes": "Renamed from generated review seed.", } ] } } class CandidateCapabilityRelink(BaseModel): target_ability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ {"target_ability_id": 2, "notes": "Move under operational ability."} ] } } class CandidateLeafRelink(BaseModel): target_capability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ { "target_capability_id": 3, "notes": "Evidence supports a different capability.", } ] } } class CandidateAbilityMerge(BaseModel): target_ability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ {"target_ability_id": 2, "notes": "Duplicate ability wording."} ] } } class CandidateCapabilityMerge(BaseModel): target_capability_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [ {"target_capability_id": 3, "notes": "Duplicate capability."} ] } } class CandidateFeatureMerge(BaseModel): target_feature_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [{"target_feature_id": 4, "notes": "Duplicate route."}] } } class CandidateEvidenceMerge(BaseModel): target_evidence_id: int notes: str = "" model_config = { "json_schema_extra": { "examples": [{"target_evidence_id": 5, "notes": "Duplicate evidence."}] } } class RepositoryResponse(BaseModel): id: int name: str url: str description: str | None branch: str status: str model_config = { "json_schema_extra": { "examples": [REPOSITORY_EXAMPLE], } } class RepositorySnapshotResponse(BaseModel): id: int repository_id: int commit_hash: str branch: str source_path: str file_count: int class AnalysisRunResponse(BaseModel): id: int repository_id: int snapshot_id: int | None status: str started_at: str completed_at: str | None error_message: str | None scanner_version: str class ReviewDecisionResponse(BaseModel): id: int repository_id: int analysis_run_id: int | None action: str notes: str created_at: str reviewer_type: str = "unknown" reviewer_id: str = "" policy_version: str = "" criteria_version: str = "" criterion_ids: list[str] = Field(default_factory=list) evidence_refs: list[str] = Field(default_factory=list) rationale: str = "" accepted_after_edits: bool = False decision_kind: str = "other" class TrustedAutoApprovalMigrationRecordResponse(BaseModel): repository_id: int repository_name: str repository_url: str repository_status: str analysis_run_id: int | None analysis_run_status: str scanner_version: str review_decision_id: int decision_created_at: str notes: str current_approved_ability_count: int recommended_next_step: str class QualityCriterionResponse(BaseModel): id: str title: str category: str severity: str applies_to: list[str] description: str deterministic_action: str deterministic_action_when: str reviewer_guidance: str agentic_guidance: str = "" examples: list[str] = Field(default_factory=list) model_config = { "json_schema_extra": { "examples": [ { "id": "RREG-QC-002", "title": "Native Utility Is Repo-Owned", "category": "native-utility", "severity": "high", "applies_to": ["ability", "capability"], "description": "Owned claims require product evidence.", "deterministic_action": "downgraded", "deterministic_action_when": "Evidence is dependency-only.", "reviewer_guidance": "Check whether the repo owns the utility.", "agentic_guidance": "Approve only with product and source evidence.", "examples": ["Dependency use is not native product behavior."], } ] } } class QualityCriteriaRegistryResponse(BaseModel): schema_version: str criteria_version: str status: str updated_at: str criteria: list[QualityCriterionResponse] class QualityGateOverrideCreate(BaseModel): criterion_id: str element_type: str element_id: int reason: str notes: str = "" class ObservedFactResponse(BaseModel): id: int repository_id: int analysis_run_id: int snapshot_id: int | None kind: str path: str name: str value: str metadata: dict[str, Any] class ContentChunkResponse(BaseModel): id: int repository_id: int analysis_run_id: int snapshot_id: int | None path: str kind: str start_line: int end_line: int text: str metadata: dict[str, Any] class ScanSummaryResponse(BaseModel): analysis_run: AnalysisRunResponse snapshot: RepositorySnapshotResponse | None facts: list[ObservedFactResponse] class SourceReferenceResponse(BaseModel): fact_id: int | None path: str kind: str name: str line: int | None = None class CandidateEvidenceResponse(BaseModel): id: int type: str reference: str strength: str status: str source_refs: list[SourceReferenceResponse] target_kind: str = "capability" target_id: int | None = None reference_kind: str = "source" reference_id: int | None = None class CandidateFeatureResponse(BaseModel): id: int name: str type: str primary_class: str attributes: list[str] location: str confidence: float status: str source_refs: list[SourceReferenceResponse] confidence_label: str class CandidateCapabilityResponse(BaseModel): id: int name: str description: str inputs: list[str] outputs: list[str] primary_class: str attributes: list[str] confidence: float status: str source_refs: list[SourceReferenceResponse] confidence_label: str features: list[CandidateFeatureResponse] evidence: list[CandidateEvidenceResponse] class CandidateAbilityResponse(BaseModel): id: int name: str description: str primary_class: str attributes: list[str] confidence: float status: str source_refs: list[SourceReferenceResponse] confidence_label: str capabilities: list[CandidateCapabilityResponse] class QualityGateOutcomeResponse(BaseModel): criteria_version: str criterion_id: str criterion_title: str severity: str outcome: str element_type: str element_id: int element_name: str reason: str class CandidateGraphResponse(BaseModel): repository: RepositoryResponse analysis_run: AnalysisRunResponse abilities: list[CandidateAbilityResponse] quality_gate_outcomes: list[QualityGateOutcomeResponse] = Field(default_factory=list) model_config = { "json_schema_extra": { "examples": [ { "repository": { **REPOSITORY_EXAMPLE, "status": "reviewing", }, "analysis_run": ANALYSIS_RUN_EXAMPLE, "abilities": [ { "id": 1, "name": "Business Email Routing", "description": "Route inbound messages to the right team.", "confidence": 0.82, "confidence_label": "high", "status": "pending", "source_refs": [SOURCE_REFERENCE_EXAMPLE], "capabilities": [ { "id": 1, "name": "Classify Incoming Email", "description": "Classify messages by intent.", "inputs": ["subject", "body"], "outputs": ["intent", "confidence"], "confidence": 0.78, "confidence_label": "medium", "status": "pending", "source_refs": [SOURCE_REFERENCE_EXAMPLE], "features": [ { "id": 1, "name": "POST /api/classify-email", "type": "REST endpoint", "location": "src/routes/classify_email.py", "confidence": 0.84, "confidence_label": "high", "status": "pending", "source_refs": [SOURCE_REFERENCE_EXAMPLE], } ], "evidence": [ { "id": 1, "type": "unit_test", "reference": "tests/test_email_classification.py", "strength": "strong", "status": "pending", "source_refs": [SOURCE_REFERENCE_EXAMPLE], } ], } ], } ], "quality_gate_outcomes": [], } ] } } class AnalysisRunDiffItemResponse(BaseModel): change_type: str item_type: str key: str base: dict[str, Any] | None = None target: dict[str, Any] | None = None class AnalysisRunDiffSectionResponse(BaseModel): added: list[AnalysisRunDiffItemResponse] removed: list[AnalysisRunDiffItemResponse] changed: list[AnalysisRunDiffItemResponse] weakened: list[AnalysisRunDiffItemResponse] class AnalysisRunDiffResponse(BaseModel): repository: RepositoryResponse base_run: AnalysisRunResponse target_run: AnalysisRunResponse facts: AnalysisRunDiffSectionResponse chunks: AnalysisRunDiffSectionResponse candidates: AnalysisRunDiffSectionResponse approved_entries: AnalysisRunDiffSectionResponse model_config = { "json_schema_extra": { "examples": [ { "repository": REPOSITORY_EXAMPLE, "base_run": {**ANALYSIS_RUN_EXAMPLE, "id": 1}, "target_run": {**ANALYSIS_RUN_EXAMPLE, "id": 2}, "facts": { "added": [ { "change_type": "added", "item_type": "fact", "key": "api_route:src/routes/status.py:GET /status", "target": { "kind": "api_route", "path": "src/routes/status.py", "name": "GET /status", }, } ], "removed": [], "changed": [], "weakened": [], }, "chunks": { "added": [], "removed": [], "changed": [], "weakened": [], }, "candidates": { "added": [], "removed": [], "changed": [], "weakened": [ { "change_type": "weakened", "item_type": "capability", "key": "classify incoming email", "base": {"confidence": 0.9}, "target": {"confidence": 0.62}, } ], }, "approved_entries": { "added": [], "removed": [], "changed": [], "weakened": [], }, } ] } } class EvidenceResponse(BaseModel): id: int type: str reference: str strength: str source_refs: list[SourceReferenceResponse] target_kind: str = "capability" target_id: int | None = None reference_kind: str = "source" reference_id: int | None = None class FeatureResponse(BaseModel): id: int name: str type: str primary_class: str attributes: list[str] location: str confidence: float confidence_label: str source_refs: list[SourceReferenceResponse] class CapabilityResponse(BaseModel): id: int name: str description: str inputs: list[str] outputs: list[str] primary_class: str attributes: list[str] confidence: float confidence_label: str features: list[FeatureResponse] evidence: list[EvidenceResponse] class AbilityResponse(BaseModel): id: int name: str description: str primary_class: str attributes: list[str] confidence: float confidence_label: str capabilities: list[CapabilityResponse] class ScopeResponse(BaseModel): id: int name: str description: str confidence: float confidence_label: str class RepositoryAbilityMapResponse(BaseModel): repository: RepositoryResponse scope: ScopeResponse abilities: list[AbilityResponse] model_config = { "json_schema_extra": { "examples": [ { "repository": REPOSITORY_EXAMPLE, "scope": { "id": 1, "name": "MailRouter", "description": "Scope root for the MailRouter repository.", "confidence": 1.0, "confidence_label": "high", }, "abilities": [ { "id": 1, "name": "Business Email Routing", "description": "Route inbound messages to the right team.", "confidence": 0.92, "confidence_label": "high", "capabilities": [ { "id": 1, "name": "Classify Incoming Email", "description": "Classify messages by intent.", "inputs": ["subject", "body"], "outputs": ["intent", "confidence"], "confidence": 0.88, "confidence_label": "high", "features": [ { "id": 1, "name": "POST /api/classify-email", "type": "REST endpoint", "location": "src/routes/classify_email.py", "confidence": 0.84, "confidence_label": "high", "source_refs": [SOURCE_REFERENCE_EXAMPLE], } ], "evidence": [ { "id": 1, "type": "unit_test", "reference": "tests/test_email_classification.py", "strength": "strong", "source_refs": [SOURCE_REFERENCE_EXAMPLE], } ], } ], } ], } ] } } class RepositoryScopeContextResponse(BaseModel): repo_slug: str = Field( description="Slug requested by the caller after normal slugification." ) capabilities: list[str] = Field( description="Approved capability names from the repository ability map." ) tags: list[str] = Field( description=( "Sorted union of approved ability and capability primary classes " "plus their attributes." ) ) scope_md_exists: bool = Field( description=( "True when repo-scoping can inspect a local or cached checkout and " "root SCOPE.md exists." ) ) scope_summary: str | None = Field( description=( "First non-empty paragraph of root SCOPE.md when available, " "otherwise registry metadata." ) ) model_config = { "extra": "forbid", "json_schema_extra": { "examples": [ { "repo_slug": "repo-scoping", "capabilities": ["Generate SCOPE.md"], "tags": ["api", "generation", "scope"], "scope_md_exists": True, "scope_summary": ( "Repository Scoping maps repositories into reviewable " "scope graphs." ), } ] }, } class IdResponse(BaseModel): id: int class SearchResultResponse(BaseModel): repository_id: int repository_name: str match_type: str match_name: str confidence: float confidence_label: str match_description: str matched_field: str ability_id: int | None = None ability_name: str | None = None capability_id: int | None = None capability_name: str | None = None evidence_level: str | None = None source_reference: str | None = None text_score: float = 0.0 vector_score: float = 0.0 hybrid_score: float = 0.0 model_config = { "json_schema_extra": { "examples": [ { "repository_id": 1, "repository_name": "MailRouter", "match_type": "capability", "match_name": "Classify Incoming Email", "confidence": 0.88, "confidence_label": "high", "match_description": "Classify messages by intent.", "matched_field": "capability.description", "ability_id": 1, "ability_name": "Business Email Routing", "capability_id": 1, "capability_name": "Classify Incoming Email", "evidence_level": None, "source_reference": None, "text_score": 1.0, "vector_score": 0.0, "hybrid_score": 0.88, } ] } } class AbilitySummaryResponse(BaseModel): id: int repository_id: int repository_name: str name: str description: str confidence: float confidence_label: str class CapabilitySummaryResponse(BaseModel): id: int repository_id: int repository_name: str ability_id: int ability_name: str name: str description: str confidence: float confidence_label: str class CapabilityGapRequest(BaseModel): desired_ability: str desired_capabilities: list[str] repository_ids: list[int] | None = None model_config = { "json_schema_extra": { "examples": [ { "desired_ability": "Business Email Routing", "desired_capabilities": [ "Classify Incoming Email", "Route Email to Team", ], "repository_ids": [1, 2], } ] } } class ComparedCapabilityResponse(BaseModel): name: str confidence: float confidence_label: str evidence_count: int class ComparedAbilityRepositoryResponse(BaseModel): repository_id: int repository_name: str confidence: float confidence_label: str capabilities: list[ComparedCapabilityResponse] class ComparedAbilityResponse(BaseModel): name: str repositories: list[ComparedAbilityRepositoryResponse] class UniqueCapabilityResponse(BaseModel): repository_id: int repository_name: str ability_name: str capability_name: str class RepositoryComparisonResponse(BaseModel): repositories: list[RepositoryResponse] abilities: list[ComparedAbilityResponse] unique_capabilities: list[UniqueCapabilityResponse] model_config = { "json_schema_extra": { "examples": [ { "repositories": [ REPOSITORY_EXAMPLE, {**REPOSITORY_EXAMPLE, "id": 2, "name": "InboxWorker"}, ], "abilities": [ { "name": "Business Email Routing", "repositories": [ { "repository_id": 1, "repository_name": "MailRouter", "confidence": 0.92, "confidence_label": "high", "capabilities": [ { "name": "Classify Incoming Email", "confidence": 0.88, "confidence_label": "high", "evidence_count": 2, } ], } ], } ], "unique_capabilities": [ { "repository_id": 1, "repository_name": "MailRouter", "ability_name": "Business Email Routing", "capability_name": "Classify Incoming Email", } ], } ] } } class CapabilityGapMatchResponse(BaseModel): capability: str repositories: list[str] class WeakCapabilityEvidenceResponse(BaseModel): capability: str repository_id: int repository_name: str evidence_count: int strongest_evidence: str | None = None confidence: float confidence_label: str class DuplicateCapabilityResponse(BaseModel): capability: str repositories: list[str] class CapabilityGapResponse(BaseModel): desired_ability: str matched_capabilities: list[CapabilityGapMatchResponse] missing_capabilities: list[str] weakly_evidenced_capabilities: list[WeakCapabilityEvidenceResponse] duplicate_capabilities: list[DuplicateCapabilityResponse] model_config = { "json_schema_extra": { "examples": [ { "desired_ability": "Business Email Routing", "matched_capabilities": [ { "capability": "Classify Incoming Email", "repositories": ["MailRouter"], } ], "missing_capabilities": ["Route Email to Team"], "weakly_evidenced_capabilities": [ { "capability": "Classify Incoming Email", "repository_id": 1, "repository_name": "MailRouter", "evidence_count": 0, "strongest_evidence": None, "confidence": 0.62, "confidence_label": "medium", } ], "duplicate_capabilities": [ { "capability": "Classify Incoming Email", "repositories": ["MailRouter", "InboxWorker"], } ], } ] } }