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
14 changes: 9 additions & 5 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 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.
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, a `BootReleaseSet` for the recovery/provisioning lane, an `EnrollmentToken` authorizing one-time recovery access, and a `Fingerprint` reporting the realized post-apply state.

```text
connector.json ──► asset.json
Expand Down Expand Up @@ -49,7 +49,7 @@ content_spec.json ──► overlay_bundle.json ──► build_request.json ─
access_profile.json

release_set.json ──► fingerprint.json
release_set.json ──► boot_release_set.json ──► enrollment_token.json ──► fingerprint.json
```

---
Expand All @@ -65,13 +65,15 @@ These examples illustrate the Truth Plane contract additions:

---

## Recent additions — Control-plane lifecycle examples
## Recent additions — Control-plane lifecycle and boot provisioning examples

These examples illustrate the local-first control-plane lifecycle family:
These examples illustrate the local-first control-plane lifecycle and secure boot/recovery 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 |
| `boot_release_set.json` | BootReleaseSet | SourceOS Recovery Environment boot artifact set linked to the assigned ReleaseSet |
| `enrollment_token.json` | EnrollmentToken | One-time recovery authorization token scoped to the M2 demo device and BootReleaseSet |
| `fingerprint.json` | Fingerprint | Post-apply device observation proving the realized state matches the assigned release set |

---
Expand Down Expand Up @@ -118,6 +120,7 @@ These examples illustrate the shared object family used by SourceOS artifact bui
| `agreement.json` | Agreement | Default personal-data agreement |
| `agent_session.json` | AgentSession | An executor session running the obfuscation workflow |
| `asset.json` | PhysicalAsset | Lakehouse asset for curated health observations |
| `boot_release_set.json` | BootReleaseSet | SourceOS Recovery Environment boot artifact set for secure recovery/provisioning |
| `build_request.json` | BuildRequest | SourceOS Workstation build request with agentplane and Katello refs |
| `capability_token.json` | CapabilityToken | Access token scoped to the health dataset export operation |
| `catalog_entry.json` | CatalogEntry | Catalog entry for the SourceOS Workstation dev release |
Expand All @@ -130,6 +133,7 @@ These examples illustrate the shared object family used by SourceOS artifact bui
| `data_sphere.json` | DataSphere | The personal-curated execution environment |
| `delta_surface.json` | DeltaSurface | Truth Plane delta surface example |
| `enrollment_profile.json` | EnrollmentProfile | Katello/Foreman enrollment profile for dev workstation installs |
| `enrollment_token.json` | EnrollmentToken | One-time recovery authorization token for the M2 local-first demo |
| `evidence_bundle.json` | EvidenceBundle | Evidence bundle pointing at agentplane validation/run/replay artifacts |
| `execution_decision.json` | ExecutionDecision | Agent allow-decision for a tool invocation |
| `event_envelope.json` | EventEnvelope | Event published when the run completes |
Expand Down Expand Up @@ -176,7 +180,7 @@ npm install -g ajv-cli
# Validate a single example
ajv validate -s ../schemas/Dataset.json -d dataset.json

# Validate control-plane lifecycle examples
# Validate control-plane lifecycle and boot provisioning examples
make validate-control-plane-examples
```

Expand Down
13 changes: 13 additions & 0 deletions examples/boot_release_set.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"boot_release_set_id": "urn:srcos:boot-release-set:m2-demo-recovery-2026-04-26",
"base_release_set_ref": "urn:srcos:release-set:m2-demo-2026-04-26",
"boot_mode": "recovery",
"status": "ready",
"artifacts": {
"kernel_ref": "urn:srcos:artifact:m2-demo-recovery-kernel-sha256-0f3b6d7f",
"initrd_ref": "urn:srcos:artifact:m2-demo-recovery-initrd-sha256-08f4c82e",
"rootfs_ref": "urn:srcos:artifact:m2-demo-recovery-rootfs-sha256-5f4dcc3b"
},
"created_at": "2026-04-26T14:30:00Z",
"notes": "SourceOS Recovery Environment for the M2 local-first demo. This models the nlboot-evolved recovery path: minimal boot artifacts, signed content-addressed refs, and linkage back to the assigned ReleaseSet."
}
15 changes: 15 additions & 0 deletions examples/enrollment_token.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"token_id": "urn:srcos:enrollment-token:m2-demo-recovery-onetime-2026-04-26",
"purpose": "recovery",
"audience": {
"subject_kind": "device",
"subject_id": "urn:srcos:device:m2-local-demo"
},
"release_set_ref": "urn:srcos:release-set:m2-demo-2026-04-26",
"boot_release_set_ref": "urn:srcos:boot-release-set:m2-demo-recovery-2026-04-26",
"one_time_use": true,
"issued_at": "2026-04-26T14:31:00Z",
"expires_at": "2026-04-26T14:46:00Z",
"status": "issued",
"notes": "Single-use recovery authorization token for the M2 local-first demo. The live/recovery environment redeems this token to authorize the assigned BootReleaseSet and ReleaseSet."
}
24 changes: 13 additions & 11 deletions tools/validate_control_plane_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from __future__ import annotations

import json
import sys
from pathlib import Path

import jsonschema
Expand All @@ -11,22 +10,25 @@
PAIRS = [
(ROOT / "schemas" / "control-plane" / "ReleaseSet.json", ROOT / "examples" / "release_set.json"),
(ROOT / "schemas" / "control-plane" / "Fingerprint.json", ROOT / "examples" / "fingerprint.json"),
(ROOT / "schemas" / "control-plane" / "BootReleaseSet.json", ROOT / "examples" / "boot_release_set.json"),
(ROOT / "schemas" / "control-plane" / "EnrollmentToken.json", ROOT / "examples" / "enrollment_token.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)
legacy_ref = schema.get("allOf", [{}])[0].get("$ref")
validation_schema_path = schema_path.with_name(legacy_ref) if legacy_ref else schema_path
validation_schema = json.loads(validation_schema_path.read_text(encoding="utf-8"))
example = json.loads(example_path.read_text(encoding="utf-8"))
jsonschema.validate(example, validation_schema)


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)
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
Expand Down