Add consumer alignment review kit

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

View File

@@ -9,6 +9,7 @@ from urllib.parse import parse_qs, urlparse
from .service import (
CanonServiceError,
alignment_template,
artifact_graph,
inspect_canon,
list_artifacts,
@@ -19,6 +20,7 @@ from .service import (
profile_inspect,
profile_validate,
read_view,
review_kit,
validate_canon,
)
@@ -84,6 +86,10 @@ def _route(
return HTTPStatus.OK, list_models(root)
if path == "/standards":
return HTTPStatus.OK, list_standards(root)
if path == "/review-kit":
return HTTPStatus.OK, review_kit(root)
if path == "/alignment-template":
return HTTPStatus.OK, alignment_template(root)
if path == "/validate":
payload = validate_canon(root)
return (HTTPStatus.OK if payload["ok"] else HTTPStatus.BAD_REQUEST), payload

View File

@@ -10,6 +10,7 @@ from typing import Any
from .api import serve
from .service import (
CanonServiceError,
alignment_template,
artifact_graph,
generate_agent_briefs,
generate_indexes,
@@ -23,6 +24,7 @@ from .service import (
profile_inspect,
profile_validate,
read_view,
review_kit,
validate_canon,
write_validation_report,
)
@@ -53,6 +55,18 @@ def build_parser() -> argparse.ArgumentParser:
standards = sub.add_parser("standards", help="List canon standard artifacts")
standards.set_defaults(handler=_standards)
review_kit_cmd = sub.add_parser(
"review-kit",
help="Read the consumer repository alignment review kit",
)
review_kit_cmd.set_defaults(handler=_review_kit)
alignment_template_cmd = sub.add_parser(
"alignment-template",
help="Read the consumer alignment workplan template",
)
alignment_template_cmd.set_defaults(handler=_alignment_template)
validate = sub.add_parser("validate", help="Validate the canon infospace")
validate.add_argument(
"--write",
@@ -145,6 +159,14 @@ def _standards(args: argparse.Namespace) -> dict[str, Any]:
return list_standards(_root(args))
def _review_kit(args: argparse.Namespace) -> dict[str, Any]:
return review_kit(_root(args))
def _alignment_template(args: argparse.Namespace) -> dict[str, Any]:
return alignment_template(_root(args))
def _validate(args: argparse.Namespace) -> dict[str, Any]:
if args.write:
return write_validation_report(args.write, _root(args))

View File

@@ -11,6 +11,10 @@ import yaml
GENERATED_NOTICE = "<!-- GENERATED by info_tech_canon; do not edit by hand. -->"
RETRIEVAL_ARTIFACT_KINDS = {
"access-descriptor-set",
"alignment-review-kit",
"alignment-review-schema",
"alignment-review-workflow",
"alignment-scorecard",
"benefit-analysis",
"benchmark-findings",
"benchmark-workspace",
@@ -21,6 +25,7 @@ RETRIEVAL_ARTIFACT_KINDS = {
"concept-catalog",
"conformance-pack",
"consumer-workplan-brief",
"consumer-workplan-template",
"evaluation-pack",
"evaluation-question-set",
"example",
@@ -31,6 +36,7 @@ RETRIEVAL_ARTIFACT_KINDS = {
"mapping-expectation",
"model",
"model-extension",
"model-selection-guide",
"native-concept-map",
"pattern",
"profile-alignment",
@@ -876,6 +882,14 @@ def _summary_for_artifact(artifact: Any) -> str:
return f"Example artifact for the {artifact.provenance.get('profile', 'unknown')} profile: {artifact.title}."
if artifact.kind == "access-descriptor-set":
return f"Structured CARING access descriptor set: {artifact.title}."
if artifact.kind == "alignment-review-kit":
return f"Reusable kit for consumer repository alignment reviews: {artifact.title}."
if artifact.kind == "alignment-review-schema":
return f"Schema for structured consumer repository alignment reviews: {artifact.title}."
if artifact.kind == "alignment-review-workflow":
return f"Repeatable workflow for canon alignment reviews: {artifact.title}."
if artifact.kind == "alignment-scorecard":
return f"Scorecard dimensions for canon alignment reviews: {artifact.title}."
if artifact.kind == "benefit-analysis":
return f"Consumer benefit analysis against canon surfaces: {artifact.title}."
if artifact.kind == "benchmark-findings":
@@ -896,6 +910,8 @@ def _summary_for_artifact(artifact: Any) -> str:
return f"Machine-readable canon-side conformance support pack: {artifact.title}."
if artifact.kind == "consumer-workplan-brief":
return f"Consumer repo workplan seed brief: {artifact.title}."
if artifact.kind == "consumer-workplan-template":
return f"Template for consumer repository alignment workplans: {artifact.title}."
if artifact.kind == "evaluation-pack":
return f"Machine-readable canon-side evaluation pack: {artifact.title}."
if artifact.kind == "evaluation-question-set":
@@ -912,6 +928,8 @@ def _summary_for_artifact(artifact: Any) -> str:
return f"Expected mappings between consumer graph capture and canon surfaces: {artifact.title}."
if artifact.kind == "model-extension":
return f"Candidate extension to an existing canon model: {artifact.title}."
if artifact.kind == "model-selection-guide":
return f"Guide for choosing canon models, standards, profiles, and benchmarks: {artifact.title}."
if artifact.kind == "native-concept-map":
return f"Native source concept map for assimilation or benchmark work: {artifact.title}."
if artifact.kind == "pattern":

View File

@@ -6,6 +6,8 @@ from pathlib import Path
import json
from typing import Any
import yaml
from . import generation
from . import profiles
from .bench import (
@@ -22,6 +24,15 @@ from .validation import structural_checks
REPO_ROOT = Path(__file__).resolve().parents[2]
DEFAULT_INFOSPACE_ROOT = REPO_ROOT / "infospace"
REVIEW_KIT_COMPONENTS = {
"manifest": "agent/review-kit/review-kit.yaml",
"workflow": "agent/review-kit/review-workflow.yaml",
"scorecard": "agent/review-kit/scorecard.yaml",
"model_selection_guide": "agent/review-kit/model-selection-guide.yaml",
"schema": "schemas/alignment-review.schema.yaml",
}
ALIGNMENT_TEMPLATE_PATH = "agent/templates/consumer-alignment-workplan.template.md"
class CanonServiceError(Exception):
def __init__(
@@ -120,6 +131,45 @@ def list_standards(root: Path | str | None = None) -> dict[str, Any]:
return list_artifacts(root, kind="standard")
def review_kit(root: Path | str | None = None) -> dict[str, Any]:
context = load_context(root)
components = {
name: {
"path": relative,
"content": _read_yaml_component(context.infospace_root, relative),
}
for name, relative in REVIEW_KIT_COMPONENTS.items()
}
template = alignment_template(root)
return {
"ok": True,
"review_kit": components["manifest"]["content"],
"components": components,
"template": {
"path": template["path"],
"content": template["content"],
},
}
def alignment_template(root: Path | str | None = None) -> dict[str, Any]:
context = load_context(root)
path = context.infospace_root / ALIGNMENT_TEMPLATE_PATH
try:
content = path.read_text(encoding="utf-8")
except FileNotFoundError as exc:
raise CanonServiceError(
"missing_alignment_template",
"Consumer alignment workplan template not found.",
{"path": str(path)},
) from exc
return {
"ok": True,
"path": ALIGNMENT_TEMPLATE_PATH,
"content": content,
}
def validate_canon(root: Path | str | None = None) -> dict[str, Any]:
context = load_context(root)
errors: list[dict[str, Any]] = []
@@ -311,6 +361,25 @@ def read_view(name: str, root: Path | str | None = None) -> dict[str, Any]:
) from exc
def _read_yaml_component(infospace_root: Path, relative: str) -> Any:
path = infospace_root / relative
try:
with path.open("r", encoding="utf-8") as handle:
return yaml.safe_load(handle) or {}
except FileNotFoundError as exc:
raise CanonServiceError(
"missing_review_kit_component",
f"Review kit component not found: {relative}",
{"path": str(path)},
) from exc
except yaml.YAMLError as exc:
raise CanonServiceError(
"invalid_review_kit_component",
f"Review kit component is not valid YAML: {relative}",
{"path": str(path), "reason": str(exc)},
) from exc
def _artifact_to_dict(
artifact: KnowledgeArtifact,
infospace_root: Path,

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]],