MultiHarnessStudio / scripts /validate_spine.py
smlflg's picture
Initial public upload from Projekte/MultiHarnessStudio
f2cf4fa verified
Raw History Blame Contribute Delete
5.9 kB
#!/usr/bin/env python3
"""Local consistency checks for the Spine V1 scaffold.
This script does not implement full JSON Schema validation. It validates the
spec bundle at the repository-contract level using only the Python stdlib.
"""
from __future__ import annotations
import json
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
SCHEMAS = ROOT / "schemas"
REGISTRY = ROOT / "registry"
EXAMPLES = ROOT / "examples" / "run_lifecycle"
REQUIRED_SCHEMAS = {
"OperatorContext": "operator_context.schema.json",
"TaskRequest": "task_request.schema.json",
"RoutingDecision": "routing_decision.schema.json",
"RunRecord": "run_record.schema.json",
"ExecutionRequest": "execution_request.schema.json",
"ExecutionStatus": "execution_status.schema.json",
"RouteTrace": "route_trace.schema.json",
"ArtifactManifest": "artifact_manifest.schema.json",
"EvalRecord": "eval_record.schema.json",
"SpineEvent": "spine_event.schema.json",
"SystemManifest": "system_manifest.schema.json",
"HarnessManifest": "harness_manifest.schema.json",
"AdapterManifest": "adapter_manifest.schema.json",
}
def load_json(path: Path):
with path.open("r", encoding="utf-8") as handle:
return json.load(handle)
def require(condition: bool, message: str) -> None:
if not condition:
raise SystemExit(f"VALIDATION FAILED: {message}")
def check_schema_inventory() -> None:
for schema_name, filename in REQUIRED_SCHEMAS.items():
path = SCHEMAS / filename
require(path.exists(), f"missing schema file: {filename}")
data = load_json(path)
require(data["title"] == schema_name, f"{filename} has unexpected title")
def check_registry() -> None:
system_manifest = load_json(REGISTRY / "system_manifest.json")
require(system_manifest["schema_name"] == "SystemManifest", "system manifest schema name mismatch")
require(
sorted(system_manifest["schema_inventory"]) == sorted(REQUIRED_SCHEMAS.keys()),
"system manifest schema inventory is incomplete",
)
harness_ids = set()
for path in sorted((REGISTRY / "harnesses").glob("*.json")):
data = load_json(path)
require(data["schema_name"] == "HarnessManifest", f"{path.name} is not a harness manifest")
require(data["harness_id"] not in harness_ids, f"duplicate harness id: {data['harness_id']}")
harness_ids.add(data["harness_id"])
adapter_ids = set()
for path in sorted((REGISTRY / "adapters").glob("*.json")):
data = load_json(path)
require(data["schema_name"] == "AdapterManifest", f"{path.name} is not an adapter manifest")
require(data["adapter_id"] not in adapter_ids, f"duplicate adapter id: {data['adapter_id']}")
adapter_ids.add(data["adapter_id"])
def check_examples() -> None:
task = load_json(EXAMPLES / "task_request.json")
decision = load_json(EXAMPLES / "routing_decision.json")
run = load_json(EXAMPLES / "run_record.json")
execution = load_json(EXAMPLES / "execution_request.json")
status = load_json(EXAMPLES / "execution_status.json")
trace = load_json(EXAMPLES / "route_trace.json")
artifact = load_json(EXAMPLES / "artifact_manifest.json")
eval_record = load_json(EXAMPLES / "eval_record.json")
events = load_json(EXAMPLES / "events.json")
require(task["schema_name"] == "TaskRequest", "task example schema mismatch")
require(decision["task_id"] == task["task_id"], "decision does not reference task")
require(run["task_id"] == task["task_id"], "run does not reference task")
require(execution["decision_id"] == decision["decision_id"], "execution does not reference decision")
require(execution["run_id"] == run["run_id"], "execution does not reference run")
require(status["execution_id"] == execution["execution_id"], "status does not reference execution")
require(status["run_id"] == run["run_id"], "status does not reference run")
require(trace["execution_id"] == execution["execution_id"], "trace does not reference execution")
require(artifact["run_id"] == run["run_id"], "artifact does not reference run")
require(eval_record["run_id"] == run["run_id"], "eval does not reference run")
require(eval_record["task_id"] == task["task_id"], "eval does not reference task")
require(run["decision_ids"] == [decision["decision_id"]], "run decision ids mismatch")
require(run["execution_ids"] == [execution["execution_id"]], "run execution ids mismatch")
require(run["artifact_ids"] == [artifact["artifact_id"]], "run artifact ids mismatch")
require(run["eval_ids"] == [eval_record["eval_id"]], "run eval ids mismatch")
sequences = [event["sequence"] for event in events]
require(sequences == list(range(1, len(events) + 1)), "event sequence must be contiguous starting at 1")
for event in events:
require(event["schema_name"] == "SpineEvent", f"event {event['event_id']} schema mismatch")
require(event["run_id"] == run["run_id"], f"event {event['event_id']} run id mismatch")
event_ids = [event["event_id"] for event in events]
require(run["event_ids"] == event_ids, "run event ids do not match event log")
def main() -> None:
check_schema_inventory()
check_registry()
check_examples()
print("Spine validation OK")
print(f"Schemas: {len(REQUIRED_SCHEMAS)}")
print(f"Harness manifests: {len(list((REGISTRY / 'harnesses').glob('*.json')))}")
print(f"Adapter manifests: {len(list((REGISTRY / 'adapters').glob('*.json')))}")
print(f"Example files: {len(list(EXAMPLES.glob('*.json')))}")
if __name__ == "__main__":
try:
main()
except SystemExit:
raise
except Exception as exc: # pragma: no cover - defensive catch for local use
raise SystemExit(f"VALIDATION FAILED: unexpected error: {exc}") from exc