Implement canon conformance and maintenance optimizations
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06e82-3e08-7042-a79d-438ac6eed8db
This commit is contained in:
tegwick 2026-09-05 00:50:09 +02:00
parent a2e7f22d8d
commit b081d39da1
64 changed files with 4491 additions and 373 deletions

View file

@ -9,9 +9,13 @@ from typing import Any
BENCH_PACKAGE = "_info_tech_canon_infospace_bench"
BENCH_SOURCE_ROOT = (
Path(__file__).resolve().parents[3] / "infospace-bench" / "src" / "infospace_bench"
)
_spec = importlib.util.find_spec("infospace_bench")
if _spec is None or not _spec.submodule_search_locations:
raise RuntimeError("Install infospace-bench==0.1.0 before using the canon service")
# The upstream __init__ imports optional database/engine integrations. Resolve
# its installed location without executing that initializer; load only the
# reference-data modules needed here. No sibling checkout is assumed.
BENCH_SOURCE_ROOT = Path(next(iter(_spec.submodule_search_locations)))
def _ensure_package() -> ModuleType:

View file

@ -6,6 +6,7 @@ from pathlib import Path
from typing import Any
import yaml
from .paths import infospace_root
REPO_ROOT = Path(__file__).resolve().parents[2]
CATALOG_PATH = REPO_ROOT / "infospace" / "models" / "capability" / "capabilities.yaml"
@ -33,7 +34,7 @@ MATURITY_ORDER = tuple(f"D{i}" for i in range(8))
def load_catalog(path: Path | None = None) -> dict[str, Any]:
catalog_path = path or CATALOG_PATH
catalog_path = path or infospace_root() / "models/capability/capabilities.yaml"
if not catalog_path.is_file():
raise CapabilityReviewError(
"capability_catalog_missing",

View file

@ -113,6 +113,21 @@ def build_parser() -> argparse.ArgumentParser:
capability_review.add_argument("record")
capability_review.set_defaults(handler=_capability_review)
emission = sub.add_parser("emission-review", help="Validate a source-owned YAML/JSON cadence declaration")
emission.add_argument("record")
emission.set_defaults(handler=_emission_review)
coverage = sub.add_parser("validation-coverage", help="List implemented checks and explicit limits")
coverage.set_defaults(handler=_coverage)
freshness = sub.add_parser("check-generated", help="Check projections without changing source files")
freshness.set_defaults(handler=_check_generated)
inventory = sub.add_parser("scope-inventory", help="Derive scope counts from the artifact registry")
inventory.set_defaults(handler=_scope_inventory)
bundle = sub.add_parser("export-emission-contract", help="Export a content-addressed contract tar")
bundle.add_argument("destination")
bundle.set_defaults(handler=_export_emission)
benchmark = sub.add_parser("benchmark-reads", help="Measure ten uncached inspect calls")
benchmark.set_defaults(handler=_benchmark_reads)
api = sub.add_parser("api", help="Run the read-only local API")
api.add_argument("--host", default="127.0.0.1")
api.add_argument("--port", type=int, default=8765)
@ -207,6 +222,41 @@ def _capability_review(args: argparse.Namespace) -> dict[str, Any]:
return review_capability_record(args.record, _root(args))
def _emission_review(args):
from .contracts import review_emission
return review_emission(args.record, _root(args))
def _coverage(args):
from .contracts import coverage
from .service import load_context
return coverage(load_context(_root(args)))
def _check_generated(args):
from .maintenance import check_generated
from .service import load_context
return check_generated(load_context(_root(args)))
def _scope_inventory(args):
from .maintenance import scope_inventory
from .service import load_context
return dict(scope_inventory(load_context(_root(args))), ok=True)
def _export_emission(args):
from .maintenance import export_emission_bundle
from .paths import infospace_root
return export_emission_bundle(infospace_root(_root(args)), Path(args.destination))
def _benchmark_reads(args):
from .maintenance import benchmark_reads
from .paths import infospace_root
return benchmark_reads(infospace_root(_root(args)))
def _profile_inspect(args: argparse.Namespace) -> dict[str, Any]:
return profile_inspect(args.profile, _root(args))

View file

@ -0,0 +1,82 @@
"""Reusable declaration checks. Shape validity never proves operational truth."""
from collections import Counter
from pathlib import Path
from typing import Any
from jsonschema import Draft202012Validator
from jsonschema.exceptions import SchemaError
import yaml
from .paths import infospace_root
def schema_errors(instance: Any, schema: dict) -> list[dict]:
try:
Draft202012Validator.check_schema(schema)
except SchemaError as exc:
return [{"code": "invalid_schema", "message": exc.message}]
return [
{"code": "schema_violation", "instance_path": "/".join(map(str, e.path)),
"message": e.message}
for e in sorted(Draft202012Validator(schema).iter_errors(instance),
key=lambda e: tuple(map(str, e.path)))
]
def emission_errors(instance: Any, schema: dict) -> list[dict]:
errors = schema_errors(instance, schema)
if isinstance(instance, dict) and isinstance(instance.get("sources"), list):
counts = Counter(entry.get("source_id") for entry in instance["sources"]
if isinstance(entry, dict) and isinstance(entry.get("source_id"), str))
duplicates = sorted(key for key, count in counts.items() if count > 1)
if duplicates:
errors.append({"code": "duplicate_emission_cadence_source_id",
"source_ids": duplicates})
return errors
def review_emission(path: str | Path, root: Path | str | None = None) -> dict:
from .service import CanonServiceError
try:
schema = yaml.safe_load((infospace_root(root) / "schemas/emission-cadence.schema.yaml").read_text())
instance = yaml.safe_load(Path(path).read_text())
except (OSError, yaml.YAMLError) as exc:
raise CanonServiceError("declaration_unreadable", str(exc)) from exc
errors = emission_errors(instance, schema)
return {"ok": not errors, "contract": "emission-cadence/0.1", "errors": errors,
"operational_truth_assessed": False}
def coverage(context: Any) -> dict:
"""Report actual checks and their limits rather than claiming full conformance."""
bindings = {"mapping": "mapping.schema.yaml"}
rows = []
for artifact in sorted(context.infospace.artifacts, key=lambda a: a.id):
schema = bindings.get(artifact.kind)
rows.append({"id": artifact.id, "kind": artifact.kind, "schema": schema,
"checks": "schema-and-references" if schema else "structural-or-specialized"})
return {"ok": True, "artifacts": rows,
"specialized": ["capability catalog/record", "practice pattern",
"emission cadence example", "consumer packs"],
"not_proven": ["ownership of concepts only in prose", "all Markdown links",
"consumer adoption", "cross-version interoperability",
"CARING effective access", "mapping rationale completeness"]}
def bound_artifact_errors(context: Any) -> list[dict]:
errors = []
try:
schema = yaml.safe_load((context.infospace_root / "schemas/mapping.schema.yaml").read_text())
except (OSError, yaml.YAMLError) as exc:
return [{"code": "mapping_schema_unreadable", "message": str(exc)}]
for artifact in context.infospace.artifacts:
if artifact.kind != "mapping":
continue
try:
data = yaml.safe_load((context.infospace_root / artifact.path).read_text())
errors.extend(dict(error, artifact_id=artifact.id) for error in schema_errors(data, schema))
except (OSError, yaml.YAMLError) as exc:
errors.append({"code": "mapping_unreadable", "artifact_id": artifact.id, "message": str(exc)})
return errors

View file

@ -0,0 +1,108 @@
"""Reproducible projections, portable contract exports, and read measurements."""
from collections import Counter
from dataclasses import replace
from datetime import datetime, timezone
import hashlib
import io
import json
from pathlib import Path
import shutil
import statistics
import subprocess
import tarfile
import tempfile
import time
from . import generation
def scope_inventory(context) -> dict:
return {"artifact_count": len(context.infospace.artifacts),
"kinds": dict(sorted(Counter(a.kind for a in context.infospace.artifacts).items())),
"standards": sorted(a.id for a in context.infospace.artifacts if a.kind == "standard"),
"models": sorted(a.id for a in context.infospace.artifacts if a.kind == "model")}
def check_generated(context) -> dict:
"""Render only into a disposable copy; never repair the source as a check."""
with tempfile.TemporaryDirectory(prefix="canon-freshness-") as temporary:
target = Path(temporary) / "infospace"
shutil.copytree(context.infospace_root, target)
copied = replace(context, infospace_root=target)
files = {}
for render in (generation.generate_indexes, generation.generate_tree,
generation.generate_agent_briefs):
for item in render(copied)["files"]:
path = Path(item["path"])
files[str(path.relative_to(target))] = path.read_bytes()
stale = []
for relative, expected in files.items():
original = context.infospace_root / relative
if not original.is_file() or original.read_bytes() != expected:
stale.append(relative)
return {"ok": not stale, "checked": len(files), "stale": sorted(stale)}
def source_evidence(root: Path) -> dict:
digest = hashlib.sha256()
# Include source and generated corpus; exclude reports to avoid self-hashing.
for path in sorted(root.rglob("*")):
if path.is_file() and "validation" not in path.relative_to(root).parts:
digest.update(str(path.relative_to(root)).encode() + b"\0" + path.read_bytes() + b"\0")
def git(*args):
try:
result = subprocess.run(["git", "-C", str(root.parent), *args],
capture_output=True, text=True, check=False)
except FileNotFoundError:
return None
return result.stdout.strip() if result.returncode == 0 else None
status = git("status", "--porcelain")
return {"generated_at": datetime.now(timezone.utc).isoformat(),
"revision": git("rev-parse", "HEAD"),
"dirty": bool(status) if status is not None else None,
"corpus_sha256": digest.hexdigest(),
"digest_scope": "all infospace files except validation reports"}
def export_emission_bundle(root: Path, destination: Path) -> dict:
"""Content-addressed deterministic tar; a changed contract gets a new name."""
paths = ["schemas/emission-cadence.schema.yaml",
"standards/emission-cadence/InfoTechCanonEmissionCadenceStandard.md",
"standards/emission-cadence/examples/qonto-assistant.yaml"]
files = {path: (root / path).read_bytes() for path in paths}
manifest = {"contract": "emission-cadence/0.1", "status": "draft",
"files": {name: hashlib.sha256(data).hexdigest() for name, data in files.items()},
"semantic_checks": ["unique source_id in sources"],
"adoption_evidence": "Two independent source-owned implementations required; example does not count."}
files["manifest.json"] = (json.dumps(manifest, sort_keys=True, indent=2) + "\n").encode()
output = io.BytesIO()
with tarfile.open(fileobj=output, mode="w", format=tarfile.USTAR_FORMAT) as archive:
for name, data in sorted(files.items()):
info = tarfile.TarInfo(name)
info.size = len(data)
info.mode = 0o644
archive.addfile(info, io.BytesIO(data))
data = output.getvalue()
digest = hashlib.sha256(data).hexdigest()
destination.mkdir(parents=True, exist_ok=True)
path = destination / f"emission-cadence-0.1-{digest}.tar"
try:
with path.open("xb") as stream:
stream.write(data)
except FileExistsError:
if path.read_bytes() != data:
raise ValueError(f"Refusing to overwrite different bundle contents: {path}")
return {"ok": True, "path": str(path), "sha256": digest, "manifest": manifest}
def benchmark_reads(root: Path, runs: int = 10) -> dict:
from .service import inspect_canon
samples = []
for _ in range(runs):
started = time.perf_counter()
inspect_canon(root)
samples.append((time.perf_counter() - started) * 1000)
return {"ok": True, "operation": "inspect", "runs": runs,
"median_ms": statistics.median(samples), "max_ms": max(samples),
"cache": "none; benchmark does not establish a production latency requirement"}

View file

@ -0,0 +1,15 @@
"""Corpus location is independent of the installed Python package."""
import os
from pathlib import Path
def infospace_root(root: Path | str | None = None) -> Path:
if root:
return Path(root).resolve()
if os.environ.get("INFO_TECH_CANON_ROOT"):
return Path(os.environ["INFO_TECH_CANON_ROOT"]).resolve()
local = Path.cwd() / "infospace"
if local.is_dir():
return local.resolve()
return Path(__file__).resolve().parents[2] / "infospace"

View file

@ -19,10 +19,11 @@ from .bench import (
run_collection_checks,
)
from .validation import structural_checks
from .paths import infospace_root
REPO_ROOT = Path(__file__).resolve().parents[2]
DEFAULT_INFOSPACE_ROOT = REPO_ROOT / "infospace"
DEFAULT_INFOSPACE_ROOT = infospace_root()
REVIEW_KIT_COMPONENTS = {
"manifest": "agent/review-kit/review-kit.yaml",
@ -65,18 +66,18 @@ class CanonContext:
def load_context(root: Path | str | None = None) -> CanonContext:
infospace_root = Path(root) if root else DEFAULT_INFOSPACE_ROOT
resolved_root = infospace_root(root)
try:
infospace = load_infospace(infospace_root)
infospace = load_infospace(resolved_root)
except Exception as exc:
raise CanonServiceError(
"infospace_load_failed",
f"Unable to load infospace at {infospace_root}",
{"root": str(infospace_root), "reason": str(exc)},
f"Unable to load infospace at {resolved_root}",
{"root": str(resolved_root), "reason": str(exc)},
) from exc
return CanonContext(
repo_root=REPO_ROOT,
infospace_root=infospace_root,
repo_root=resolved_root.parent,
infospace_root=resolved_root,
infospace=infospace,
)
@ -217,6 +218,11 @@ def validate_canon(root: Path | str | None = None) -> dict[str, Any]:
structural = structural_checks(context)
errors.extend(structural["errors"])
warnings.extend(structural["warnings"])
from .contracts import bound_artifact_errors, coverage
errors.extend(bound_artifact_errors(context))
ownership = generation.concept_ownership(context)
errors.extend(dict(item, code="concept_ownership_conflict")
for item in ownership["ownership_conflicts"])
return {
"ok": not errors,
@ -224,6 +230,7 @@ def validate_canon(root: Path | str | None = None) -> dict[str, Any]:
"warnings": warnings,
"metrics": checks.metrics,
"details": checks.details,
"coverage": coverage(context),
}
@ -232,6 +239,8 @@ def write_validation_report(
root: Path | str | None = None,
) -> dict[str, Any]:
payload = validate_canon(root)
from .maintenance import source_evidence
payload["evidence"] = source_evidence(infospace_root(root))
path = Path(destination)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8")
@ -335,7 +344,7 @@ def review_capability_record(
from .capability import CapabilityReviewError, review_path
try:
return review_path(path)
return review_path(path, infospace_root(root) / "models/capability/capabilities.yaml")
except CapabilityReviewError as exc:
raise CanonServiceError(exc.code, exc.message) from exc

View file

@ -56,6 +56,7 @@ REQUIRED_SCHEMAS = (
"capability-record.schema.yaml",
"attribute-value-type.schema.yaml",
"practice-pattern.schema.yaml",
"emission-cadence.schema.yaml",
)
RETRIEVAL_BRIEF_KINDS = {
@ -397,7 +398,8 @@ def structural_checks(context: Any) -> dict[str, list[dict[str, Any]]]:
_check_required_top_level_files(context.repo_root, errors)
_check_required_infospace_dirs(context.infospace_root, errors)
_check_required_schemas(context.infospace_root, errors)
_check_capability_catalog(errors)
_check_capability_catalog(context.infospace_root, errors)
_check_emission_cadence_contract(context.infospace_root, errors)
_check_canon_paths(context.repo_root, context.infospace_root, errors)
_check_artifact_index(context.repo_root, context.infospace_root, errors)
_check_practice_pattern_assets(
@ -599,11 +601,11 @@ def _check_required_infospace_dirs(
)
def _check_capability_catalog(errors: list[dict[str, Any]]) -> None:
from .capability import check_catalog_contract
def _check_capability_catalog(infospace_root: Path, errors: list[dict[str, Any]]) -> None:
from .capability import check_catalog_contract, load_catalog
try:
errors.extend(check_catalog_contract())
errors.extend(check_catalog_contract(load_catalog(infospace_root / "models/capability/capabilities.yaml")))
except Exception as exc: # pragma: no cover - catalog missing is structural
errors.append(
{
@ -613,6 +615,20 @@ def _check_capability_catalog(errors: list[dict[str, Any]]) -> None:
)
def _check_emission_cadence_contract(
infospace_root: Path,
errors: list[dict[str, Any]],
) -> None:
from .contracts import emission_errors
schema = _read_yaml(infospace_root / "schemas/emission-cadence.schema.yaml", errors)
example_path = "standards/emission-cadence/examples/qonto-assistant.yaml"
example = _read_yaml(infospace_root / example_path, errors)
if isinstance(schema, dict):
errors.extend(dict(error, path=example_path)
for error in emission_errors(example, schema))
def _check_required_schemas(
infospace_root: Path,
errors: list[dict[str, Any]],