diff --git a/Makefile b/Makefile index f5570ba..68c5be4 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,12 @@ -.PHONY: validate validate-control-plane-examples validate-nlboot-examples validate-lattice-data-governai-examples validate-ops-history-examples validate-runtime-observability-examples validate-interpretability-examples validate-lifecycle-boundary-examples validate-svf-contracts validate-sync-cycle-receipts validate-onboarding-examples validate-runtime-causality-examples +.PHONY: validate validate-control-plane-examples validate-nlboot-examples validate-lattice-data-governai-examples validate-ops-history-examples validate-runtime-observability-examples validate-interpretability-examples validate-lifecycle-boundary-examples validate-svf-contracts validate-sync-cycle-receipts validate-onboarding-examples validate-runtime-causality-examples validate-agentic-os-examples -validate: validate-control-plane-examples validate-nlboot-examples validate-lattice-data-governai-examples validate-ops-history-examples validate-runtime-observability-examples validate-interpretability-examples validate-lifecycle-boundary-examples validate-svf-contracts validate-sync-cycle-receipts validate-onboarding-examples validate-runtime-causality-examples +validate: validate-control-plane-examples validate-nlboot-examples validate-lattice-data-governai-examples validate-ops-history-examples validate-runtime-observability-examples validate-interpretability-examples validate-lifecycle-boundary-examples validate-svf-contracts validate-sync-cycle-receipts validate-onboarding-examples validate-runtime-causality-examples validate-agentic-os-examples @echo "OK: validate" +validate-agentic-os-examples: + python3 -m pip install --user jsonschema >/dev/null + python3 tools/validate_agentic_os_examples.py + validate-control-plane-examples: python3 -m pip install --user jsonschema >/dev/null python3 tools/validate_control_plane_examples.py diff --git a/examples/agent_pod.json b/examples/agent_pod.json new file mode 100644 index 0000000..4a92f2b --- /dev/null +++ b/examples/agent_pod.json @@ -0,0 +1,25 @@ +{ + "id": "urn:srcos:agent-pod:capture-lead", + "type": "AgentPod", + "specVersion": "2.0.0", + "role": "Capture Lead", + "mandate": "Own pursuit strategy, buyer map, milestones, and decisions.", + "inputs": [ + "signals", + "updates", + "Q&A", + "competitive intel" + ], + "outputs": [ + "pursuit plan", + "gate decisions", + "action backlog" + ], + "repoAnchors": [ + "sociosphere", + "socioprophet" + ], + "status": "active", + "choirRole": "governance-sentinel", + "agentSessionRef": "urn:srcos:session:capture-lead-run-01" +} diff --git a/examples/capture_cadence.json b/examples/capture_cadence.json new file mode 100644 index 0000000..3f44537 --- /dev/null +++ b/examples/capture_cadence.json @@ -0,0 +1,33 @@ +{ + "id": "urn:srcos:capture-cadence:standard-8wk", + "type": "CaptureCadence", + "specVersion": "2.0.0", + "name": "Standard 8-week capture sprint", + "currentWeek": 4, + "weeks": [ + { + "week": 0, + "objective": "Intake + normalize", + "portfolioDeliverable": "update OS, partner map, pod coverage", + "cellDeliverable": "opportunity brief + buyer/problem memo", + "minReadiness": 0.2, + "exitDecision": "pursue / watch / pause" + }, + { + "week": 4, + "objective": "Artifact pack v1", + "portfolioDeliverable": "synchronize all cell artifacts", + "cellDeliverable": "30-day artifact pack, storyboard, compliance skeleton", + "minReadiness": 0.5, + "exitDecision": "Gate 1 complete" + }, + { + "week": 8, + "objective": "Delta sprint", + "portfolioDeliverable": "ingest live text and replan in <=72h", + "cellDeliverable": "delta memo, reprioritized backlog, owner resets", + "minReadiness": 0.8, + "exitDecision": "go-forward after delta" + } + ] +} diff --git a/examples/capture_delta.json b/examples/capture_delta.json new file mode 100644 index 0000000..f080015 --- /dev/null +++ b/examples/capture_delta.json @@ -0,0 +1,12 @@ +{ + "id": "urn:srcos:capture-delta:health-devsecops-qa", + "type": "CaptureDelta", + "specVersion": "2.0.0", + "opportunityRef": "urn:srcos:opportunity:health-devsecops", + "kind": "Industry-day Q&A", + "monitorSource": "OIT Industry Day site / VOA", + "expected": "2026-04-17", + "responseSlaHours": 24, + "requiredOutput": "delta memo + requirement updates", + "status": "Watching" +} diff --git a/examples/opportunity.json b/examples/opportunity.json new file mode 100644 index 0000000..ca1b741 --- /dev/null +++ b/examples/opportunity.json @@ -0,0 +1,53 @@ +{ + "id": "urn:srcos:opportunity:health-devsecops", + "type": "Opportunity", + "specVersion": "2.0.0", + "name": "Health Services DevSecOps", + "cluster": "Health", + "missionOwner": "PDS", + "buyingProblem": "Sustain legacy health apps while modernizing safely outside the Oracle Health baseline.", + "priorities": [ + "VistA sustainment", + "modernization", + "MUMPS" + ], + "deliveryPattern": "Continuity-plus-modernization delivery cell; governed DevSecOps; legacy transition discipline.", + "reuseRepos": [ + "prophet-platform", + "prophet-platform-standards", + "agentplane", + "policy-fabric", + "sociosphere" + ], + "podRefs": [ + "urn:srcos:agent-pod:capture-lead", + "urn:srcos:agent-pod:technical-solution", + "urn:srcos:agent-pod:compliance-matrix", + "urn:srcos:agent-pod:evidence-qa" + ], + "sharedLibraryRefs": [ + "urn:srcos:shared-library:canonical-operating-model", + "urn:srcos:shared-library:transition-in", + "urn:srcos:shared-library:release-gates" + ], + "readinessRef": "urn:srcos:readiness-score:health-devsecops", + "deltaRefs": [ + "urn:srcos:capture-delta:health-devsecops-qa" + ], + "partnerLane": "Health IT SI; VistA/MUMPS niche partner", + "winTheme": "We preserve continuity while industrializing governed modernization with low-regret migration paths.", + "status": "Active", + "workroomRef": "workroom://health-devsecops", + "controlRoomRef": "controlroom://health-devsecops", + "telos": { + "objective": "Intelligence serves human flourishing", + "constraints": [ + "non-domination", + "consent", + "dignity" + ] + }, + "evidenceRefs": [ + "urn:srcos:attestation:health-devsecops/win-theme" + ] +} diff --git a/examples/readiness_score.json b/examples/readiness_score.json new file mode 100644 index 0000000..34bd524 --- /dev/null +++ b/examples/readiness_score.json @@ -0,0 +1,29 @@ +{ + "id": "urn:srcos:readiness-score:health-devsecops", + "type": "ReadinessScore", + "specVersion": "2.0.0", + "opportunityRef": "urn:srcos:opportunity:health-devsecops", + "dimensions": { + "buyerProblem": 3, + "solutionHypothesis": 2, + "sharedLibraries": 3, + "agentPod": 2, + "partnerArchetype": 2, + "namedPartnerTargets": 0, + "oemLane": 1, + "artifactPack": 2, + "deltaControl": 2, + "questions": 1, + "pricing": 0, + "pastPerformance": 0 + }, + "total": 18, + "max": 36, + "readinessPct": 50, + "rag": "Amber", + "nextGate": "Gate 1", + "evidenceRefs": [ + "urn:srcos:attestation:health-devsecops/buyer-problem" + ], + "policyRef": "policy://capture/burden-of-proof/gate-1" +} diff --git a/examples/shared_library.json b/examples/shared_library.json new file mode 100644 index 0000000..2a86291 --- /dev/null +++ b/examples/shared_library.json @@ -0,0 +1,13 @@ +{ + "id": "urn:srcos:shared-library:release-gates", + "type": "SharedLibrary", + "specVersion": "2.0.0", + "name": "Quality / release gates", + "standardizes": "Validation, test automation, release readiness, defect policy.", + "repoAnchors": [ + "agentplane", + "prophet-platform-standards", + "sourceos-spec" + ], + "usedBy": "All build/run objectives" +} diff --git a/schemas/AgentPod.json b/schemas/AgentPod.json new file mode 100644 index 0000000..d9dd897 --- /dev/null +++ b/schemas/AgentPod.json @@ -0,0 +1,91 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/AgentPod.json", + "title": "AgentPod", + "description": "A standard agent pod: a named role with a mandate, typed inputs/outputs, and repo anchors. The unit of staffing in the agentic operating system; the pod URN is the same one referenced by AgentMachineReceipt.agentPodRef.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "role", + "mandate", + "inputs", + "outputs", + "repoAnchors" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:agent-pod:", + "description": "Stable URN identifier. Pattern: urn:srcos:agent-pod:" + }, + "type": { + "const": "AgentPod", + "description": "Discriminator constant — always \"AgentPod\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document, e.g. \"2.0.0\"." + }, + "role": { + "type": "string", + "minLength": 1, + "description": "Human role name, e.g. \"Capture Lead\"." + }, + "mandate": { + "type": "string", + "minLength": 1, + "description": "What the pod owns." + }, + "inputs": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Core inputs the pod consumes." + }, + "outputs": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Core artifacts the pod produces." + }, + "repoAnchors": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Estate repositories this pod's patterns anchor to." + }, + "status": { + "type": "string", + "enum": [ + "active", + "shadow", + "paused" + ], + "description": "Operational status of the pod." + }, + "choirRole": { + "type": [ + "string", + "null" + ], + "description": "prophet-mesh agent-choir role this pod aligns to (e.g. \"planning-agent\", \"governance-sentinel\"). The choir is the canonical role vocabulary; this pod is its capture-side projection." + }, + "agentSessionRef": { + "type": [ + "string", + "null" + ], + "pattern": "^urn:srcos:session:", + "description": "The AgentSession URN when this pod is executing (the Perceive→Reason→Act→Verify loop)." + } + } +} diff --git a/schemas/CaptureCadence.json b/schemas/CaptureCadence.json new file mode 100644 index 0000000..cad8787 --- /dev/null +++ b/schemas/CaptureCadence.json @@ -0,0 +1,75 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/CaptureCadence.json", + "title": "CaptureCadence", + "description": "The governed capture cadence: a fixed sprint of weeks, each with objectives, deliverables, a minimum-readiness gate, and an exit decision.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "weeks" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:capture-cadence:", + "description": "Stable URN identifier. Pattern: urn:srcos:capture-cadence:" + }, + "type": { + "const": "CaptureCadence", + "description": "Discriminator constant — always \"CaptureCadence\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document, e.g. \"2.0.0\"." + }, + "name": { + "type": "string" + }, + "weeks": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "week", + "objective", + "minReadiness", + "exitDecision" + ], + "properties": { + "week": { + "type": "integer", + "minimum": 0 + }, + "objective": { + "type": "string" + }, + "portfolioDeliverable": { + "type": "string" + }, + "cellDeliverable": { + "type": "string" + }, + "minReadiness": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "exitDecision": { + "type": "string" + } + } + }, + "description": "Ordered cadence weeks." + }, + "currentWeek": { + "type": "integer", + "minimum": 0, + "description": "Where the portfolio currently sits." + } + } +} diff --git a/schemas/CaptureDelta.json b/schemas/CaptureDelta.json new file mode 100644 index 0000000..4bc4aa7 --- /dev/null +++ b/schemas/CaptureDelta.json @@ -0,0 +1,67 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/CaptureDelta.json", + "title": "CaptureDelta", + "description": "A standing delta-control monitor for an objective: an event source watched under an SLA, with a required response artifact.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "opportunityRef", + "kind", + "monitorSource", + "status", + "requiredOutput" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:capture-delta:", + "description": "Stable URN identifier. Pattern: urn:srcos:capture-delta:" + }, + "type": { + "const": "CaptureDelta", + "description": "Discriminator constant — always \"CaptureDelta\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document, e.g. \"2.0.0\"." + }, + "opportunityRef": { + "type": "string", + "pattern": "^urn:srcos:opportunity:" + }, + "kind": { + "type": "string", + "minLength": 1, + "description": "Delta type, e.g. \"Industry-day Q&A\", \"Draft RFP\", \"Amendment\"." + }, + "monitorSource": { + "type": "string", + "minLength": 1 + }, + "expected": { + "type": "string", + "description": "Expected/observed date (ISO date or \"TBD\")." + }, + "responseSlaHours": { + "type": "number", + "minimum": 0, + "description": "Response SLA in hours once the delta lands." + }, + "requiredOutput": { + "type": "string", + "minLength": 1 + }, + "status": { + "type": "string", + "enum": [ + "Open", + "Watching", + "Ingested" + ] + } + } +} diff --git a/schemas/Opportunity.json b/schemas/Opportunity.json new file mode 100644 index 0000000..f50bc34 --- /dev/null +++ b/schemas/Opportunity.json @@ -0,0 +1,161 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/Opportunity.json", + "title": "Opportunity", + "description": "An objective the agentic operating system pursues: the normalized operating fields for a pursuit, anchored to estate repos, agent pods, shared libraries, a readiness scorecard, and delta monitors.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "name", + "cluster", + "buyingProblem", + "status" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:opportunity:", + "description": "Stable URN identifier. Pattern: urn:srcos:opportunity:" + }, + "type": { + "const": "Opportunity", + "description": "Discriminator constant — always \"Opportunity\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document, e.g. \"2.0.0\"." + }, + "name": { + "type": "string", + "minLength": 1 + }, + "cluster": { + "type": "string", + "minLength": 1, + "description": "Portfolio cluster, e.g. \"Health\", \"Cyber\"." + }, + "missionOwner": { + "type": "string" + }, + "buyingProblem": { + "type": "string", + "minLength": 1 + }, + "priorities": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Priorities / burning issues." + }, + "deliveryPattern": { + "type": "string", + "description": "Primary delivery-excellence pattern." + }, + "reuseRepos": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Adjacent estate repositories to reuse." + }, + "podRefs": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "pattern": "^urn:srcos:agent-pod:" + }, + "description": "Agent pods emphasized for this objective." + }, + "sharedLibraryRefs": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "pattern": "^urn:srcos:shared-library:" + }, + "description": "Shared libraries inherited." + }, + "readinessRef": { + "type": [ + "string", + "null" + ], + "pattern": "^urn:srcos:readiness-score:", + "description": "The readiness scorecard for this objective." + }, + "deltaRefs": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "pattern": "^urn:srcos:capture-delta:" + }, + "description": "Standing delta monitors." + }, + "partnerLane": { + "type": "string" + }, + "winTheme": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "Active", + "Watch", + "Paused" + ] + }, + "workroomRef": { + "type": [ + "string", + "null" + ], + "description": "prophet-workspace ProfessionalWorkroom backing this objective (the objective/pursuit container). Composition, not duplication — the workroom owns context/policy/artifacts/tasks/evidence." + }, + "controlRoomRef": { + "type": [ + "string", + "null" + ], + "description": "prophet-workspace OrgGovControlRoom governing this objective (Objective→Actor→Role→Policy→Asset→Action→Evidence→Review→Outcome→Score→Learning)." + }, + "telos": { + "type": "object", + "additionalProperties": false, + "required": [ + "objective" + ], + "properties": { + "objective": { + "type": "string", + "description": "The end this objective serves, under the Telos layer (e.g. intelligence serves human flourishing)." + }, + "constraints": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Binding constraints that set weights/thresholds and burden-of-proof — e.g. non-domination, consent, dignity. Sets thresholds; does not assert truth." + } + }, + "description": "Telos layer: objective + constraints. Sets the burden of proof; per the governance constitution it cannot assert truth — that is the Truth Engine's role." + }, + "evidenceRefs": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Truth Engine attestation/evidence records (Witness/Attestation → Truth Record) supporting this objective's claims." + } + } +} diff --git a/schemas/ReadinessScore.json b/schemas/ReadinessScore.json new file mode 100644 index 0000000..e099640 --- /dev/null +++ b/schemas/ReadinessScore.json @@ -0,0 +1,159 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/ReadinessScore.json", + "title": "ReadinessScore", + "description": "A 12-dimension readiness scorecard for an objective. Each dimension is 0..3 (0=not started, 3=review-ready with named owner/partner evidence); total 0..36.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "opportunityRef", + "dimensions", + "total", + "rag", + "nextGate" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:readiness-score:", + "description": "Stable URN identifier. Pattern: urn:srcos:readiness-score:" + }, + "type": { + "const": "ReadinessScore", + "description": "Discriminator constant — always \"ReadinessScore\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document, e.g. \"2.0.0\"." + }, + "opportunityRef": { + "type": "string", + "pattern": "^urn:srcos:opportunity:", + "description": "The objective this scorecard grades." + }, + "dimensions": { + "type": "object", + "additionalProperties": false, + "required": [ + "buyerProblem", + "solutionHypothesis", + "sharedLibraries", + "agentPod", + "partnerArchetype", + "namedPartnerTargets", + "oemLane", + "artifactPack", + "deltaControl", + "questions", + "pricing", + "pastPerformance" + ], + "properties": { + "buyerProblem": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "solutionHypothesis": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "sharedLibraries": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "agentPod": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "partnerArchetype": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "namedPartnerTargets": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "oemLane": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "artifactPack": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "deltaControl": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "questions": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "pricing": { + "type": "integer", + "minimum": 0, + "maximum": 3 + }, + "pastPerformance": { + "type": "integer", + "minimum": 0, + "maximum": 3 + } + }, + "description": "The 12 readiness dimensions, each scored 0..3." + }, + "total": { + "type": "integer", + "minimum": 0, + "maximum": 36 + }, + "max": { + "const": 36 + }, + "readinessPct": { + "type": "number", + "minimum": 0, + "maximum": 100 + }, + "rag": { + "type": "string", + "enum": [ + "Red", + "Amber", + "Green" + ] + }, + "nextGate": { + "type": "string", + "description": "The next capture gate, e.g. \"Gate 1\"." + }, + "evidenceRefs": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Truth Engine attestations backing the scored dimensions — a dimension advances only when its claim earns a Truth Record (burden-of-proof gate, not a self-asserted number)." + }, + "policyRef": { + "type": [ + "string", + "null" + ], + "description": "The Da'at policy interface defining what counts as acceptable proof for these gates." + } + } +} diff --git a/schemas/SharedLibrary.json b/schemas/SharedLibrary.json new file mode 100644 index 0000000..fb8413d --- /dev/null +++ b/schemas/SharedLibrary.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/SharedLibrary.json", + "title": "SharedLibrary", + "description": "A shared content/control library standardized once and inherited across objectives.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "name", + "standardizes", + "repoAnchors" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:shared-library:", + "description": "Stable URN identifier. Pattern: urn:srcos:shared-library:" + }, + "type": { + "const": "SharedLibrary", + "description": "Discriminator constant — always \"SharedLibrary\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version of this document, e.g. \"2.0.0\"." + }, + "name": { + "type": "string", + "minLength": 1 + }, + "standardizes": { + "type": "string", + "minLength": 1, + "description": "What the library standardizes." + }, + "repoAnchors": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Primary repositories the library is anchored in." + }, + "usedBy": { + "type": "string", + "description": "Which objective families inherit it." + } + } +} diff --git a/tools/validate_agentic_os_examples.py b/tools/validate_agentic_os_examples.py new file mode 100644 index 0000000..370e86f --- /dev/null +++ b/tools/validate_agentic_os_examples.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 +"""Validate the agentic operating-system contract examples against their schemas. + +Covers the objects the agentic OS coordinates: Opportunity (objective), AgentPod +(the staffing unit whose URN is also referenced by AgentMachineReceipt.agentPodRef), +SharedLibrary, ReadinessScore, CaptureCadence, and CaptureDelta. +""" +from __future__ import annotations + +import json +from pathlib import Path + +import jsonschema + +ROOT = Path(__file__).resolve().parents[1] +PAIRS = [ + (ROOT / "schemas" / "AgentPod.json", ROOT / "examples" / "agent_pod.json"), + (ROOT / "schemas" / "SharedLibrary.json", ROOT / "examples" / "shared_library.json"), + (ROOT / "schemas" / "ReadinessScore.json", ROOT / "examples" / "readiness_score.json"), + (ROOT / "schemas" / "CaptureDelta.json", ROOT / "examples" / "capture_delta.json"), + (ROOT / "schemas" / "CaptureCadence.json", ROOT / "examples" / "capture_cadence.json"), + (ROOT / "schemas" / "Opportunity.json", ROOT / "examples" / "opportunity.json"), +] + + +def validate_pair(schema_path: Path, example_path: Path) -> None: + schema = json.loads(schema_path.read_text(encoding="utf-8")) + jsonschema.validators.validator_for(schema).check_schema(schema) + example = json.loads(example_path.read_text(encoding="utf-8")) + jsonschema.validate(example, schema) + + +def main() -> int: + checks: dict[str, bool] = {} + for schema_path, example_path in PAIRS: + validate_pair(schema_path, example_path) + checks[example_path.name] = True + print(json.dumps({"ok": all(checks.values()), "checks": checks}, indent=2, sort_keys=True)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())