Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.PHONY: validate validate-control-plane-examples

validate: validate-control-plane-examples
@echo "OK: validate"

validate-control-plane-examples:
python3 -m pip install --user jsonschema >/dev/null
python3 tools/validate_control_plane_examples.py
33 changes: 19 additions & 14 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This directory contains one conforming JSON example payload for each top-level s

## What the examples show

The examples are designed to tell coherent end-to-end stories. The original example set catalogs, governs, transforms, and releases a personal health dataset within an agent session. Newer SourceOS examples show a SourceOS Workstation artifact flowing from content intent through overlays, build request, release manifest, evidence bundle, catalog entry, and access profile.
The examples are designed to tell coherent end-to-end stories. The original example set catalogs, governs, transforms, and releases a personal health dataset within an agent session. Newer SourceOS examples show a SourceOS Workstation artifact flowing from content intent through overlays, build request, release manifest, evidence bundle, catalog entry, and access profile. The control-plane examples add the local-first lifecycle proof path: a `ReleaseSet` assigned to an M2 demo device and a `Fingerprint` reporting the realized post-apply state.

```text
connector.json ──► asset.json
Expand Down Expand Up @@ -48,6 +48,8 @@ content_spec.json ──► overlay_bundle.json ──► build_request.json ─
access_profile.json

release_set.json ──► fingerprint.json
```

---
Expand All @@ -63,6 +65,17 @@ These examples illustrate the Truth Plane contract additions:

---

## Recent additions — Control-plane lifecycle examples

These examples illustrate the local-first control-plane lifecycle family:

| File | Schema type | Description |
|------|------------|-------------|
| `release_set.json` | ReleaseSet | Assigned M2 demo release set with source Git ref, target, profile refs, and boot artifact refs |
| `fingerprint.json` | Fingerprint | Post-apply device observation proving the realized state matches the assigned release set |

---

## Recent additions — Fog Layer examples

The fog example set illustrates the new FogVault / FogCompute contract family:
Expand Down Expand Up @@ -122,6 +135,7 @@ These examples illustrate the shared object family used by SourceOS artifact bui
| `event_envelope.json` | EventEnvelope | Event published when the run completes |
| `experiment_flag.json` | ExperimentFlag | A feature flag for the new obfuscation algorithm |
| `field.json` | Field | The `patient.dateOfBirth` field with PII tags and quality metrics |
| `fingerprint.json` | Fingerprint | Post-apply device observation for a local-first release assignment |
| `frustration_signal.json` | FrustrationSignal | A frustration signal from a repeated-failure condition |
| `glossary.json` | GlossaryTerm | Glossary term for "Date of Birth" |
| `mapping.json` | MappingSpec | A field mapping between two dataset fields |
Expand All @@ -134,6 +148,7 @@ These examples illustrate the shared object family used by SourceOS artifact bui
| `rating.json` | Rating | A 5-star rating on the health observations dataset |
| `release_manifest.json` | ReleaseManifest | Draft release manifest with Katello artifact refs and agentplane evidence refs |
| `release_receipt.json` | ReleaseReceipt | Release receipt for spec version 2.0.0 |
| `release_set.json` | ReleaseSet | Assigned M2 demo release set with source, targets, profile refs, and artifact refs |
| `replication_policy.json` | ReplicationPolicy | Fog topic replication/retention policy example |
| `rollout_policy.json` | RolloutPolicy | Rollout rules for the obfuscation experiment flag |
| `run.json` | RunRecord | The obfuscation workload run record |
Expand All @@ -148,7 +163,7 @@ These examples illustrate the shared object family used by SourceOS artifact bui
| `truth_surface.json` | TruthSurface | Truth Plane truth surface example |
| `workflow_spec.json` | WorkflowSpec | The health-data obfuscation workflow |
| `workorder.json` | WorkOrder | FogCompute work order |
| `usage_receipt.json` | UsageReceipt | FogCompute execution receipt |
| `usage_receipt.json` | FogCompute execution receipt |

---

Expand All @@ -161,18 +176,8 @@ npm install -g ajv-cli
# Validate a single example
ajv validate -s ../schemas/Dataset.json -d dataset.json

# Validate all examples
cd ..
for example in examples/*.json; do
name=$(basename "$example" .json)
python3 - <<EOF
import json
ex = json.load(open("$example"))
t = ex.get("type") or ex.get("title")
if t:
print(f"schemas/{t}.json")
EOF
done
# Validate control-plane lifecycle examples
make validate-control-plane-examples
```

---
Expand Down
25 changes: 25 additions & 0 deletions examples/fingerprint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"fingerprint_id": "urn:srcos:fingerprint:m2-local-demo-2026-04-26T1418Z",
"subject": {
"kind": "device",
"id": "urn:srcos:device:m2-local-demo"
},
"release_set_ref": "urn:srcos:release-set:m2-demo-2026-04-26",
"experience_profile_ref": "urn:srcos:experience-profile:mac-like-gnome-demo",
"isolation_profile_ref": "urn:srcos:isolation-profile:standard-container-demo",
"observed_at": "2026-04-26T14:18:00Z",
"integrity": {
"boot_release_set_ref": "urn:srcos:boot-release-set:m2-demo-recovery-2026-04-26",
"image_ref": "oci://registry.example.invalid/sourceos/m2-system@sha256:8b3f06c9090ccf926fe6ddc6f3b4f49a13d4b8bb4cb4f5cf78e2d12e31b55aa1",
"store_closure_hash": "sha256-4e2b2e2c6a843f8b8cf38f7b47c8f875f1f9e4c4206e1f8e9c9f0ec9a0f7a001",
"boot_entry_label": "SourceOS Recovery Demo"
},
"compliance": {
"status": "compliant",
"notes": "Observed state matches assigned release set, closure hash, and boot recovery reference."
},
"evidence_refs": [
"urn:srcos:prov:m2-demo-apply-2026-04-26",
"urn:srcos:release-receipt:m2-demo-2026-04-26"
]
}
24 changes: 24 additions & 0 deletions examples/release_set.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"release_set_id": "urn:srcos:release-set:m2-demo-2026-04-26",
"release_version": "2026.04.26-demo.1",
"status": "assigned",
"source": {
"git_ref": "refs/heads/main",
"git_commit": "9f49e42af46d84c189b6313f5c8962c6ecd5076b"
},
"targets": [
{
"target_kind": "device",
"target_id": "urn:srcos:device:m2-local-demo"
}
],
"experience_profile_ref": "urn:srcos:experience-profile:mac-like-gnome-demo",
"isolation_profile_ref": "urn:srcos:isolation-profile:standard-container-demo",
"artifacts": {
"store_closure_hash": "sha256-4e2b2e2c6a843f8b8cf38f7b47c8f875f1f9e4c4206e1f8e9c9f0ec9a0f7a001",
"image_ref": "oci://registry.example.invalid/sourceos/m2-system@sha256:8b3f06c9090ccf926fe6ddc6f3b4f49a13d4b8bb4cb4f5cf78e2d12e31b55aa1",
"boot_release_set_ref": "urn:srcos:boot-release-set:m2-demo-recovery-2026-04-26"
},
"created_at": "2026-04-26T14:15:00Z",
"notes": "Local-first M2 demo release assignment produced by the SourceOS control plane."
}
36 changes: 36 additions & 0 deletions tools/validate_control_plane_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env python3
from __future__ import annotations

import json
import sys
from pathlib import Path

import jsonschema

ROOT = Path(__file__).resolve().parents[1]
PAIRS = [
(ROOT / "schemas" / "control-plane" / "ReleaseSet.json", ROOT / "examples" / "release_set.json"),
(ROOT / "schemas" / "control-plane" / "Fingerprint.json", ROOT / "examples" / "fingerprint.json"),
]


def main() -> int:
checks: dict[str, bool] = {}
for schema_path, example_path in PAIRS:
schema = json.loads(schema_path.read_text(encoding="utf-8"))
example = json.loads(example_path.read_text(encoding="utf-8"))
resolver = jsonschema.validators.validator_for(schema)
resolver.check_schema(schema)
validator = resolver(schema, registry=jsonschema.validators.SPECIFICATIONS)
# Resolve local legacy refs by changing cwd-like base through a RefResolver fallback for older jsonschema behavior.
# jsonschema 4.x resolves relative refs against the schema id; these wrapper schemas reference local legacy files.
legacy_schema_path = schema_path.with_name(schema["allOf"][0]["$ref"])
legacy_schema = json.loads(legacy_schema_path.read_text(encoding="utf-8"))
jsonschema.validate(example, legacy_schema)
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())