Add consumer alignment review kit

This commit is contained in:
tegwick 2026-05-23 07:23:48 +02:00
parent f562e2498d
commit 8e591132f8
38 changed files with 2244 additions and 83 deletions

View file

@ -50,10 +50,15 @@ REQUIRED_SCHEMAS = (
"interface-card.schema.yaml",
"agent-brief.schema.yaml",
"workplan.schema.yaml",
"alignment-review.schema.yaml",
)
RETRIEVAL_BRIEF_KINDS = {
"access-descriptor-set",
"alignment-review-kit",
"alignment-review-schema",
"alignment-review-workflow",
"alignment-scorecard",
"benefit-analysis",
"benchmark-findings",
"benchmark-workspace",
@ -64,6 +69,7 @@ RETRIEVAL_BRIEF_KINDS = {
"concept-catalog",
"conformance-pack",
"consumer-workplan-brief",
"consumer-workplan-template",
"evaluation-pack",
"evaluation-question-set",
"example",
@ -73,6 +79,7 @@ RETRIEVAL_BRIEF_KINDS = {
"mapping-expectation",
"model",
"model-extension",
"model-selection-guide",
"native-concept-map",
"pattern",
"profile-alignment",
@ -282,6 +289,62 @@ CARING_K8S_REQUIRED_DESCRIPTOR_CLASSES = {
"induced_access",
}
ALIGNMENT_REVIEW_KIT_ARTIFACT_IDS = {
"review-kit/alignment",
"review-kit/alignment/model-selection-guide",
"review-kit/alignment/schema",
"review-kit/alignment/scorecard",
"review-kit/alignment/workflow",
"review-kit/alignment/workplan-template",
}
ALIGNMENT_REVIEW_REQUIRED_PHASES = {
"intake",
"surface-selection",
"mapping",
"scoring",
"workplan-proposal",
"canon-feedback",
}
ALIGNMENT_REVIEW_SCORECARD_DIMENSIONS = {
"fit",
"gaps",
"conflicts",
"evidence-quality",
"implementation-priority",
"canon-pressure",
"workplan-readiness",
}
ALIGNMENT_REVIEW_REQUIRED_SURFACES = {
"model/purpose-demand-extension",
"pattern/intent-scope-purposes",
"model/access-control",
"model/organization",
"model/governance",
"model/security",
"model/data",
"model/landscape",
"model/devsecops",
"model/network",
"model/observability",
"model/task",
"standard/tagging",
"standard/caring",
"profile/small-saas",
"benchmark/caring/kubernetes-rbac",
}
ALIGNMENT_REVIEW_TEMPLATE_MARKERS = {
"## Current Fit",
"## Target Alignment",
"## Migration Steps",
"## Validation",
"## Open Questions",
"## Canon Feedback",
}
def structural_checks(context: Any) -> dict[str, list[dict[str, Any]]]:
errors: list[dict[str, Any]] = []
@ -314,6 +377,11 @@ def structural_checks(context: Any) -> dict[str, list[dict[str, Any]]]:
context.infospace.artifacts,
errors,
)
_check_alignment_review_kit_assets(
context.infospace_root,
context.infospace.artifacts,
errors,
)
_check_optional_assets(context.infospace_root, warnings)
return {"errors": errors, "warnings": warnings}
@ -578,6 +646,7 @@ def _check_agent_assets(
"agent/retrieval-index.json",
"agent/templates/canon-interface-card.template.yaml",
"agent/templates/consumer-brief.template.md",
"agent/templates/consumer-alignment-workplan.template.md",
"agent/consumer-briefs/user-engine.md",
"agent/consumer-briefs/railiance-fabric.md",
"agent/consumer-briefs/repo-scoping.md",
@ -1421,6 +1490,213 @@ def _check_caring_kubernetes_rbac_benchmark_assets(
)
def _check_alignment_review_kit_assets(
infospace_root: Path,
artifacts: list[Any],
errors: list[dict[str, Any]],
) -> None:
artifact_ids = {artifact.id for artifact in artifacts}
for artifact_id in sorted(ALIGNMENT_REVIEW_KIT_ARTIFACT_IDS - artifact_ids):
errors.append(
{
"code": "missing_alignment_review_kit_artifact",
"artifact_id": artifact_id,
}
)
kit_root = infospace_root / "agent" / "review-kit"
manifest = _read_yaml(kit_root / "review-kit.yaml", errors)
if isinstance(manifest, dict):
components = manifest.get("components") or {}
if not isinstance(components, dict):
errors.append(
{
"code": "invalid_alignment_review_kit_components",
"path": "infospace/agent/review-kit/review-kit.yaml",
}
)
else:
for component in (
"workflow",
"scorecard",
"model_selection_guide",
"schema",
"consumer_workplan_template",
):
if not components.get(component):
errors.append(
{
"code": "missing_alignment_review_kit_component",
"component": component,
}
)
outputs = set(manifest.get("required_outputs") or [])
for output in (
"repository_context",
"selected_canon_surfaces",
"mapping_findings",
"scorecard",
"recommended_workplans",
"canon_feedback",
):
if output not in outputs:
errors.append(
{
"code": "missing_alignment_review_required_output",
"output": output,
}
)
workflow = _read_yaml(kit_root / "review-workflow.yaml", errors)
if isinstance(workflow, dict):
phases = workflow.get("phases") or []
if not isinstance(phases, list):
errors.append(
{
"code": "invalid_alignment_review_workflow_phases",
"path": "infospace/agent/review-kit/review-workflow.yaml",
}
)
else:
phase_ids = {
str(phase.get("id"))
for phase in phases
if isinstance(phase, dict) and phase.get("id")
}
for phase_id in sorted(ALIGNMENT_REVIEW_REQUIRED_PHASES - phase_ids):
errors.append(
{
"code": "missing_alignment_review_workflow_phase",
"phase": phase_id,
}
)
for phase in phases:
if not isinstance(phase, dict):
continue
if not phase.get("questions"):
errors.append(
{
"code": "empty_alignment_review_phase_questions",
"phase": phase.get("id"),
}
)
if not phase.get("outputs"):
errors.append(
{
"code": "empty_alignment_review_phase_outputs",
"phase": phase.get("id"),
}
)
scorecard = _read_yaml(kit_root / "scorecard.yaml", errors)
if isinstance(scorecard, dict):
dimensions = scorecard.get("dimensions") or []
if not isinstance(dimensions, list):
errors.append(
{
"code": "invalid_alignment_review_scorecard_dimensions",
"path": "infospace/agent/review-kit/scorecard.yaml",
}
)
else:
dimension_ids = {
str(dimension.get("id"))
for dimension in dimensions
if isinstance(dimension, dict) and dimension.get("id")
}
for dimension in sorted(
ALIGNMENT_REVIEW_SCORECARD_DIMENSIONS - dimension_ids
):
errors.append(
{
"code": "missing_alignment_review_scorecard_dimension",
"dimension": dimension,
}
)
guide = _read_yaml(kit_root / "model-selection-guide.yaml", errors)
if isinstance(guide, dict):
surfaces = guide.get("surfaces") or []
if not isinstance(surfaces, list):
errors.append(
{
"code": "invalid_alignment_review_selection_surfaces",
"path": "infospace/agent/review-kit/model-selection-guide.yaml",
}
)
else:
surface_ids = {
str(surface.get("id"))
for surface in surfaces
if isinstance(surface, dict) and surface.get("id")
}
for surface_id in sorted(ALIGNMENT_REVIEW_REQUIRED_SURFACES - surface_ids):
errors.append(
{
"code": "missing_alignment_review_selection_surface",
"surface": surface_id,
}
)
for surface in surfaces:
if not isinstance(surface, dict):
continue
if not surface.get("use_when"):
errors.append(
{
"code": "missing_alignment_review_surface_use_when",
"surface": surface.get("id"),
}
)
if not surface.get("review_questions"):
errors.append(
{
"code": "missing_alignment_review_surface_questions",
"surface": surface.get("id"),
}
)
schema = _read_yaml(infospace_root / "schemas" / "alignment-review.schema.yaml", errors)
if isinstance(schema, dict):
required_fields = set(schema.get("required") or [])
for field in (
"repository_context",
"selected_canon_surfaces",
"mapping_findings",
"scorecard",
"recommended_workplans",
"canon_feedback",
):
if field not in required_fields:
errors.append(
{
"code": "missing_alignment_review_schema_required_field",
"field": field,
}
)
template_path = (
infospace_root / "agent" / "templates" / "consumer-alignment-workplan.template.md"
)
try:
template = template_path.read_text(encoding="utf-8")
except FileNotFoundError:
errors.append(
{
"code": "missing_alignment_review_workplan_template",
"path": "infospace/agent/templates/consumer-alignment-workplan.template.md",
}
)
else:
for marker in sorted(ALIGNMENT_REVIEW_TEMPLATE_MARKERS):
if marker not in template:
errors.append(
{
"code": "missing_alignment_review_template_marker",
"marker": marker,
}
)
def _artifact_paths_by_path(
infospace_root: Path,
errors: list[dict[str, Any]],