generated from coulomb/repo-seed
Implement scope-derived candidate review infrastructure
This commit is contained in:
@@ -8,6 +8,7 @@ from repo_scoping.acceptance.criteria import (
|
||||
load_quality_criteria,
|
||||
)
|
||||
from repo_scoping.core.models import (
|
||||
CandidateAbility,
|
||||
CandidateCapability,
|
||||
CandidateFeature,
|
||||
CandidateGraph,
|
||||
@@ -39,11 +40,33 @@ def evaluate_candidate_graph_quality(
|
||||
active_registry = registry or load_quality_criteria()
|
||||
outcomes: list[QualityGateOutcome] = []
|
||||
for ability in graph.abilities:
|
||||
outcomes.extend(evaluate_candidate_ability_quality(ability, active_registry))
|
||||
for capability in ability.capabilities:
|
||||
outcomes.extend(evaluate_candidate_capability_quality(capability, active_registry))
|
||||
return outcomes
|
||||
|
||||
|
||||
def evaluate_candidate_ability_quality(
|
||||
ability: CandidateAbility,
|
||||
registry: QualityCriteriaRegistry | None = None,
|
||||
) -> list[QualityGateOutcome]:
|
||||
active_registry = registry or load_quality_criteria()
|
||||
criteria = {criterion.id: criterion for criterion in active_registry.criteria}
|
||||
outcomes: list[QualityGateOutcome] = []
|
||||
if _looks_template_contaminated(ability.name, ability.description):
|
||||
outcomes.append(
|
||||
_outcome(
|
||||
active_registry,
|
||||
criteria["RREG-QC-007"],
|
||||
element_type="ability",
|
||||
element_id=ability.id,
|
||||
element_name=ability.name,
|
||||
reason="Candidate ability appears to be based on template boilerplate.",
|
||||
)
|
||||
)
|
||||
return outcomes
|
||||
|
||||
|
||||
def evaluate_candidate_capability_quality(
|
||||
capability: CandidateCapability,
|
||||
registry: QualityCriteriaRegistry | None = None,
|
||||
@@ -75,6 +98,17 @@ def evaluate_candidate_capability_quality(
|
||||
reason="Candidate is supported only by generated SCOPE.md evidence.",
|
||||
)
|
||||
)
|
||||
elif _has_scope_refs_or_attributes(refs, capability.attributes):
|
||||
outcomes.append(
|
||||
_outcome(
|
||||
active_registry,
|
||||
criteria["RREG-QC-008"],
|
||||
element_type="capability",
|
||||
element_id=capability.id,
|
||||
element_name=capability.name,
|
||||
reason="Candidate is scope-derived and must remain review-only until separated from intent.",
|
||||
)
|
||||
)
|
||||
elif _all_weak_source_refs(refs):
|
||||
outcomes.append(
|
||||
_outcome(
|
||||
@@ -97,6 +131,18 @@ def evaluate_candidate_capability_quality(
|
||||
)
|
||||
)
|
||||
|
||||
if _looks_template_contaminated(capability.name, capability.description):
|
||||
outcomes.append(
|
||||
_outcome(
|
||||
active_registry,
|
||||
criteria["RREG-QC-007"],
|
||||
element_type="capability",
|
||||
element_id=capability.id,
|
||||
element_name=capability.name,
|
||||
reason="Candidate capability appears to be based on template boilerplate.",
|
||||
)
|
||||
)
|
||||
|
||||
if _looks_like_provider_routing(capability):
|
||||
outcomes.append(
|
||||
_outcome(
|
||||
@@ -197,6 +243,25 @@ def _all_generated_scope_refs(refs: list[SourceReference]) -> bool:
|
||||
return bool(refs) and all(ref.path.endswith("SCOPE.md") for ref in refs)
|
||||
|
||||
|
||||
def _has_scope_refs_or_attributes(
|
||||
refs: list[SourceReference],
|
||||
attributes: list[str],
|
||||
) -> bool:
|
||||
return any(ref.path.endswith("SCOPE.md") for ref in refs) or any(
|
||||
attribute in {"scope-derived", "review-required-scope"}
|
||||
for attribute in attributes
|
||||
)
|
||||
|
||||
|
||||
def _looks_template_contaminated(name: str, description: str) -> bool:
|
||||
text = f"{name} {description}".lower()
|
||||
return (
|
||||
"repo-seed" in text
|
||||
or "git repository template to bootstrap" in text
|
||||
or "bootstrap coulomb projects" in text
|
||||
)
|
||||
|
||||
|
||||
def _all_weak_source_refs(refs: list[SourceReference]) -> bool:
|
||||
return bool(refs) and all(_is_weak_source_ref(ref) for ref in refs)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user